Page MenuHomePhabricator

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/.gitignore b/.gitignore
index dada89ac5e..21fae40622 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,67 +1,69 @@
CMakeLists.txt.user*
.clang_complete
########## Git related
# Patches and similar
*.patch
*.diff
*.rej
*.orig
+!Utilities/qtsingleapplication/*.patch
+
########## IDE specific
## Office
~$*
## vim
Session.vim
*.swp
*.swo
## Emacs
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
.elc
auto-save-list
tramp
.\#*
## Eclipse
.cproject
.project
.settings/
# Org-mode
.org-id-locations
*_archive
########## OS specific
## Windows files to ignore
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
## OSX specific
.DS_Store
.AppleDouble
.LSOverride
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
## Linux
*~
diff --git a/Applications/Diffusion/CMakeLists.txt b/Applications/Diffusion/CMakeLists.txt
index 4aad065532..b5e6589e7e 100644
--- a/Applications/Diffusion/CMakeLists.txt
+++ b/Applications/Diffusion/CMakeLists.txt
@@ -1,81 +1,81 @@
project(MitkDiffusion)
set(DIFFUSIONAPP_NAME MitkDiffusion)
set(_app_options)
if(MITK_SHOW_CONSOLE_WINDOW)
list(APPEND _app_options SHOW_CONSOLE)
endif()
# Create a cache entry for the provisioning file which is used to export
# the file name in the MITKConfig.cmake file. This will keep external projects
# which rely on this file happy.
set(DIFFUSIONIMAGINGAPP_PROVISIONING_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${DIFFUSIONAPP_NAME}.provisioning" CACHE INTERNAL "${DIFFUSIONAPP_NAME} provisioning file" FORCE)
set(_plugins
org.commontk.configadmin
org.commontk.eventadmin
org.blueberry.osgi
org.blueberry.compat
org.blueberry.core.runtime
org.blueberry.core.expressions
org.blueberry.solstice.common
org.blueberry.core.commands
org.blueberry.ui
org.blueberry.ui.qt
org.blueberry.ui.qt.log
org.blueberry.ui.qt.help
org.mitk.core.services
org.mitk.gui.common
org.mitk.planarfigure
org.mitk.core.ext
org.mitk.diffusionimaging
org.mitk.gui.qt.application
org.mitk.gui.qt.ext
org.mitk.gui.qt.diffusionimagingapp
org.mitk.gui.qt.common
org.mitk.gui.qt.stdmultiwidgeteditor
org.mitk.gui.qt.common.legacy
org.mitk.gui.qt.datamanager
org.mitk.gui.qt.measurementtoolbox
org.mitk.gui.qt.segmentation
org.mitk.gui.qt.volumevisualization
org.mitk.gui.qt.diffusionimaging
org.mitk.gui.qt.imagenavigator
org.mitk.gui.qt.moviemaker
org.mitk.gui.qt.basicimageprocessing
org.mitk.gui.qt.registration
org.mitk.gui.qt.properties
- org.mitk.gui.qt.candystore
+ org.mitk.gui.qt.viewnavigator
)
# Plug-ins listed below will not be
# - added as a build-time dependency to the executable
# - listed in the provisioning file for the executable
# - installed if they are external plug-ins
set(_exclude_plugins
org.blueberry.test
org.blueberry.uitest
org.mitk.gui.qt.coreapplication
org.mitk.gui.qt.extapplication
)
FunctionCreateBlueBerryApplication(
NAME ${DIFFUSIONAPP_NAME}
DESCRIPTION "MITK Diffusion"
PLUGINS ${_plugins}
EXCLUDE_PLUGINS ${_exclude_plugins}
${_app_options}
)
mitk_use_modules(TARGET ${DIFFUSIONAPP_NAME} MODULES qtsingleapplication)
# Add meta dependencies (e.g. on auto-load modules from depending modules)
if(ALL_META_DEPENDENCIES)
add_dependencies(${DIFFUSIONAPP_NAME} ${ALL_META_DEPENDENCIES})
endif()
# Add a build time dependency to legacy BlueBerry bundles.
if(MITK_MODULES_ENABLED_PLUGINS)
add_dependencies(${DIFFUSIONAPP_NAME} ${MITK_MODULES_ENABLED_PLUGINS})
endif()
diff --git a/Applications/Diffusion/CPackConfig.cmake.in b/Applications/Diffusion/CPackConfig.cmake.in
index 8dc0b8fb1a..2f8556453c 100644
--- a/Applications/Diffusion/CPackConfig.cmake.in
+++ b/Applications/Diffusion/CPackConfig.cmake.in
@@ -1,31 +1,31 @@
include("@MITK_BINARY_DIR@/MITKCPackOptions.cmake")
if(CPACK_GENERATOR MATCHES "NSIS")
# set the package header icon for MUI
SET(CPACK_PACKAGE_ICON "@MITK_SOURCE_DIR@\\mitk.bmp")
# set the install/unistall icon used for the installer itself
# There is a bug in NSIS that does not handle full unix paths properly.
SET(CPACK_NSIS_MUI_ICON "@MITK_SOURCE_DIR@\\mitk.ico")
SET(CPACK_NSIS_MUI_UNIICON "@MITK_SOURCE_DIR@\\mitk.ico")
set(CPACK_NSIS_DISPLAY_NAME "MITK Diffusion")
# tell cpack to create links to the doc files
SET(CPACK_NSIS_MENU_LINKS
"http://www.mitk.org" "MITK Web Site"
)
# tell cpack the executables you want in the start menu as links
SET(CPACK_PACKAGE_EXECUTABLES "MitkDiffusion;Start MITK Diffusion" CACHE INTERNAL "Collecting windows shortcuts to executables")
- # tell cpack to create a desktop link to MainApp
+ # tell cpack to create a desktop link to mitkDiffusion
SET(CPACK_CREATE_DESKTOP_LINKS "mitkDiffusion")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\mitk.ico")
SET(CPACK_NSIS_HELP_LINK "http:\\\\www.mitk.org")
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\www.mitk.org")
SET(CPACK_NSIS_CONTACT mitk@mitk.org)
SET(CPACK_NSIS_MODIFY_PATH ON)
endif(CPACK_GENERATOR MATCHES "NSIS")
diff --git a/Applications/Diffusion/CPackOptions.cmake b/Applications/Diffusion/CPackOptions.cmake
index 24a3a64f85..c0c47d119b 100644
--- a/Applications/Diffusion/CPackOptions.cmake
+++ b/Applications/Diffusion/CPackOptions.cmake
@@ -1,18 +1,18 @@
# Set Diffusion specific CPack options
set(CPACK_PACKAGE_EXECUTABLES "MitkDiffusion;MITK Diffusion")
set(CPACK_PACKAGE_NAME "MITK-Diffusion")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MITK application for processing of MR diffusion imaging data.")
# Major version is the year of release
-set(CPACK_PACKAGE_VERSION_MAJOR "2012")
+set(CPACK_PACKAGE_VERSION_MAJOR "2014")
# Minor version is the month of release
-set(CPACK_PACKAGE_VERSION_MINOR "12")
+set(CPACK_PACKAGE_VERSION_MINOR "04")
# Patch versioning is not intended to be done
set(CPACK_PACKAGE_VERSION_PATCH "99")
# this should result in names like 2011.09, 2012.06, ...
# version has to be set explicitly to avoid such things as CMake creating the install directory "MITK Diffusion 2011.."
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_PACKAGE_FILE_NAME "MITK-Diffusion-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_ARCH}")
diff --git a/Applications/Diffusion/target_libraries.cmake b/Applications/Diffusion/target_libraries.cmake
index a2e3f20c7c..42abb7cce7 100644
--- a/Applications/Diffusion/target_libraries.cmake
+++ b/Applications/Diffusion/target_libraries.cmake
@@ -1,23 +1,24 @@
# A list of plug-in targets which should be automatically enabled
# (or be available in external projects) for this application.
set(target_libraries
org_blueberry_compat
org_blueberry_ui_qt
org_blueberry_ui_qt_help
org_mitk_diffusionimaging
org_mitk_planarfigure
org_mitk_gui_qt_diffusionimagingapp
org_mitk_gui_qt_common_legacy
org_mitk_gui_qt_ext
org_mitk_gui_qt_datamanager
org_mitk_gui_qt_segmentation
org_mitk_gui_qt_volumevisualization
org_mitk_gui_qt_diffusionimaging
org_mitk_gui_qt_imagenavigator
org_mitk_gui_qt_moviemaker
org_mitk_gui_qt_measurementtoolbox
org_mitk_gui_qt_basicimageprocessing
org_mitk_gui_qt_registration
+ org_mitk_gui_qt_viewnavigator
)
diff --git a/BlueBerry/Bundles/org.blueberry.core.expressions/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.core.expressions/CMakeLists.txt
index d96a425db9..9c6ed4592a 100644
--- a/BlueBerry/Bundles/org.blueberry.core.expressions/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.core.expressions/CMakeLists.txt
@@ -1,4 +1,4 @@
project(org_blueberry_core_expressions)
MACRO_CREATE_CTK_PLUGIN(EXPORT_DIRECTIVE BERRY_EXPRESSIONS
- EXPORTED_INCLUDE_SUFFIXES src src/common)
+ EXPORTED_INCLUDE_SUFFIXES src)
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/org_blueberry_ui_qt_help.qrc b/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/org_blueberry_ui_qt_help.qrc
index 47b457415b..36443f1de3 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/org_blueberry_ui_qt_help.qrc
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/org_blueberry_ui_qt_help.qrc
@@ -1,12 +1,13 @@
<RCC>
<qresource prefix="/org.blueberry.ui.qt.help">
<file>find.png</file>
<file>go-home.png</file>
<file>go-next.png</file>
<file>go-previous.png</file>
<file>zoom-in.png</file>
<file>zoom-out.png</file>
<file>close.png</file>
<file>clear.png</file>
+ <file>print.png</file>
</qresource>
</RCC>
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/print.png b/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/print.png
new file mode 100644
index 0000000000..081e2ebc73
Binary files /dev/null and b/BlueBerry/Bundles/org.blueberry.ui.qt.help/resources/print.png differ
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.cpp
index eb654c6e00..b812128c50 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.cpp
@@ -1,340 +1,342 @@
/*===================================================================
BlueBerry Platform
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "berryHelpEditor.h"
#include "berryHelpEditorInput.h"
#include "berryHelpPluginActivator.h"
#include "berryHelpPerspective.h"
#include "berryHelpWebView.h"
#include "berryQHelpEngineWrapper.h"
#include "berryHelpEditorFindWidget.h"
#include "berryHelpPluginActivator.h"
#include "berryQHelpEngineWrapper.h"
#include <berryUIException.h>
#include <berryPlatformUI.h>
#include <berryIWorkbenchPage.h>
#include <berryIWorkbenchPartConstants.h>
#include <QToolBar>
#include <QHelpEngine>
#include <QVBoxLayout>
namespace berry {
const std::string HelpEditor::EDITOR_ID = "org.blueberry.editors.help";
HelpEditor::HelpEditor()
: m_ToolBar(0)
, m_WebView(0)
{
}
HelpEditor::~HelpEditor()
{
// we need to wrap the RemovePartListener call inside a
// register/unregister block to prevent infinite recursion
// due to the destruction of temporary smartpointer to this
this->Register();
this->GetSite()->GetPage()->RemovePartListener(IPartListener::Pointer(this));
this->GetSite()->GetPage()->GetWorkbenchWindow()->RemovePerspectiveListener(IPerspectiveListener::Pointer(this));
this->UnRegister(false);
}
void HelpEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input)
{
if (input.Cast<HelpEditorInput>().IsNull())
throw PartInitException("Invalid Input: Must be berry::HelpEditorInput");
this->SetSite(site);
site->GetPage()->AddPartListener(IPartListener::Pointer(this));
site->GetPage()->GetWorkbenchWindow()->AddPerspectiveListener(IPerspectiveListener::Pointer(this));
m_WebView = new HelpWebView(site, 0);
connect(m_WebView, SIGNAL(loadFinished(bool)), this, SLOT(InitializeTitle()));
this->DoSetInput(input);
}
void HelpEditor::CreateQtPartControl(QWidget* parent)
{
QVBoxLayout* verticalLayout = new QVBoxLayout(parent);
verticalLayout->setSpacing(0);
verticalLayout->setContentsMargins(0, 0, 0, 0);
m_ToolBar = new QToolBar(parent);
m_ToolBar->setMaximumHeight(32);
verticalLayout->addWidget(m_ToolBar);
m_WebView->setParent(parent);
m_WebView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
verticalLayout->addWidget(m_WebView);
m_FindWidget = new HelpEditorFindWidget(parent);
m_FindWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
verticalLayout->addWidget(m_FindWidget);
m_FindWidget->hide();
connect(m_FindWidget, SIGNAL(findNext()), this, SLOT(findNext()));
connect(m_FindWidget, SIGNAL(findPrevious()), this, SLOT(findPrevious()));
connect(m_FindWidget, SIGNAL(find(QString, bool)), this,
SLOT(find(QString, bool)));
connect(m_FindWidget, SIGNAL(escapePressed()), m_WebView, SLOT(setFocus()));
// Fill the editor toolbar
m_BackAction = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/go-previous.png"), "Go back",
m_WebView, SLOT(backward()));
m_ForwardAction = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/go-next.png"), "Go forward",
m_WebView, SLOT(forward()));
m_HomeAction = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/go-home.png"), "Go home",
m_WebView, SLOT(home()));
+ m_PrintAction = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/print.png"), "Print",
+ m_WebView, SLOT(print()));
m_ToolBar->addSeparator();
m_FindAction = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/find.png"), "Find in text",
this, SLOT(ShowTextSearch()));
m_ToolBar->addSeparator();
m_ZoomIn = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/zoom-in.png"), "Zoom in", m_WebView, SLOT(scaleUp()));
m_ZoomOut = m_ToolBar->addAction(QIcon(":/org.blueberry.ui.qt.help/zoom-out.png"), "Zoom out", m_WebView, SLOT(scaleDown()));
m_ToolBar->addSeparator();
m_OpenHelpMode = m_ToolBar->addAction("Open Help Perspective", this, SLOT(OpenHelpPerspective()));
m_CloseHelpMode = m_ToolBar->addAction("Close Help Perspective", this, SLOT(CloseHelpPerspective()));
IPerspectiveDescriptor::Pointer currPersp = this->GetSite()->GetPage()->GetPerspective();
m_OpenHelpMode->setVisible(!(currPersp.IsNotNull() && currPersp->GetId() == HelpPerspective::ID));
m_CloseHelpMode->setVisible((currPersp.IsNotNull() && currPersp->GetId() == HelpPerspective::ID));
connect(m_WebView, SIGNAL(backwardAvailable(bool)), m_BackAction, SLOT(setEnabled(bool)));
connect(m_WebView, SIGNAL(forwardAvailable(bool)), m_ForwardAction, SLOT(setEnabled(bool)));
m_BackAction->setEnabled(false);
m_ForwardAction->setEnabled(false);
m_HomeAction->setEnabled(!HelpPluginActivator::getInstance()->getQHelpEngine().homePage().isEmpty());
connect(&HelpPluginActivator::getInstance()->getQHelpEngine(), SIGNAL(homePageChanged(QString)),
this, SLOT(HomePageChanged(QString)));
}
void HelpEditor::DoSetInput(IEditorInput::Pointer input)
{
if (input.IsNull())
{
// close editor
class CloseEditorRunnable : public Poco::Runnable
{
private:
IEditorPart::Pointer editor;
public:
CloseEditorRunnable(IEditorPart::Pointer editor)
: editor(editor)
{}
void run()
{
editor->GetSite()->GetPage()->CloseEditor(editor, false);
delete this;
}
};
Display::GetDefault()->AsyncExec(new CloseEditorRunnable(IEditorPart::Pointer(this)));
}
else
{
// an empty url represents the home page
HelpEditorInput::Pointer helpInput = input.Cast<HelpEditorInput>();
QString currHomePage = HelpPluginActivator::getInstance()->getQHelpEngine().homePage();
if (helpInput->GetUrl().isEmpty() && !currHomePage.isEmpty())
{
helpInput = HelpEditorInput::Pointer(new HelpEditorInput(currHomePage));
}
QtEditorPart::SetInput(helpInput);
m_WebView->setSource(helpInput->GetUrl());
}
}
void HelpEditor::SetInputWithNotify(IEditorInput::Pointer input)
{
DoSetInput(input);
FirePropertyChange(IWorkbenchPartConstants::PROP_INPUT);
}
void HelpEditor::SetInput(IEditorInput::Pointer input)
{
SetInputWithNotify(input);
}
void HelpEditor::HomePageChanged(const QString &page)
{
if (page.isEmpty())
{
m_HomeAction->setEnabled(false);
}
m_HomeAction->setEnabled(true);
if (this->GetEditorInput().Cast<HelpEditorInput>()->GetUrl().isEmpty())
{
IEditorInput::Pointer newInput(new HelpEditorInput(page));
DoSetInput(newInput);
}
}
void HelpEditor::OpenHelpPerspective()
{
PlatformUI::GetWorkbench()->ShowPerspective(HelpPerspective::ID, this->GetSite()->GetPage()->GetWorkbenchWindow());
}
void HelpEditor::CloseHelpPerspective()
{
berry::IWorkbenchPage::Pointer
page =
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->ClosePerspective(page->GetPerspective(), true, true);
}
void HelpEditor::InitializeTitle()
{
std::string title = m_WebView->title().toStdString();
this->SetPartName(title);
}
void HelpEditor::ShowTextSearch()
{
m_FindWidget->show();
}
void HelpEditor::SetFocus()
{
m_WebView->setFocus();
enableShortcuts();
}
QWebPage *HelpEditor::GetQWebPage() const
{
return m_WebView->page();
}
IPartListener::Events::Types HelpEditor::GetPartEventTypes() const
{
return IPartListener::Events::DEACTIVATED;
}
void HelpEditor::PartDeactivated(IWorkbenchPartReference::Pointer partRef)
{
if (partRef == GetSite()->GetPage()->GetReference(IWorkbenchPart::Pointer(this)))
disableShortcuts();
}
IPerspectiveListener::Events::Types HelpEditor::GetPerspectiveEventTypes() const
{
return IPerspectiveListener::Events::ACTIVATED | IPerspectiveListener::Events::DEACTIVATED;
}
void HelpEditor::PerspectiveActivated(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective)
{
if (perspective->GetId() == HelpPerspective::ID)
{
m_OpenHelpMode->setVisible(false);
m_CloseHelpMode->setVisible(true);
}
}
void HelpEditor::PerspectiveDeactivated(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective)
{
if (perspective->GetId() == HelpPerspective::ID)
{
m_OpenHelpMode->setVisible(true);
m_CloseHelpMode->setVisible(false);
}
}
void HelpEditor::findNext()
{
find(m_FindWidget->text(), true);
}
void HelpEditor::findPrevious()
{
find(m_FindWidget->text(), false);
}
void HelpEditor::find(const QString &ttf, bool forward)
{
bool found = findInWebPage(ttf, forward);
if (!found && ttf.isEmpty())
found = true; // the line edit is empty, no need to mark it red...
if (!m_FindWidget->isVisible())
m_FindWidget->show();
m_FindWidget->setPalette(found);
}
bool HelpEditor::findInWebPage(const QString &ttf, bool forward)
{
bool found = false;
QWebPage::FindFlags options;
if (!ttf.isEmpty())
{
if (!forward)
options |= QWebPage::FindBackward;
if (m_FindWidget->caseSensitive())
options |= QWebPage::FindCaseSensitively;
found = m_WebView->findText(ttf, options);
if (!found)
{
options |= QWebPage::FindWrapsAroundDocument;
found = m_WebView->findText(ttf, options);
}
}
// force highlighting of all other matches, also when empty (clear)
options = QWebPage::HighlightAllOccurrences;
if (m_FindWidget->caseSensitive())
options |= QWebPage::FindCaseSensitively;
m_WebView->findText(QLatin1String(""), options);
m_WebView->findText(ttf, options);
return found;
}
void HelpEditor::enableShortcuts()
{
m_BackAction->setShortcut(QKeySequence::Back);
m_ForwardAction->setShortcut(QKeySequence::Forward);
m_FindAction->setShortcut(QKeySequence::Find);
m_ZoomIn->setShortcut(QKeySequence::ZoomIn);
m_ZoomOut->setShortcut(QKeySequence::ZoomOut);
}
void HelpEditor::disableShortcuts()
{
m_BackAction->setShortcut(QKeySequence());
m_ForwardAction->setShortcut(QKeySequence());
m_FindAction->setShortcut(QKeySequence());
m_ZoomIn->setShortcut(QKeySequence());
m_ZoomOut->setShortcut(QKeySequence());
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.h b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.h
index 3a8226f61f..5d09a16c13 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpEditor.h
@@ -1,111 +1,112 @@
/*===================================================================
BlueBerry Platform
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef BERRYHELPEDITOR_H_
#define BERRYHELPEDITOR_H_
#include <berryIReusableEditor.h>
#include <berryIPartListener.h>
#include <berryIPerspectiveListener.h>
#include <berryQtEditorPart.h>
class QToolBar;
class QWebPage;
namespace berry {
class HelpWebView;
class HelpEditorFindWidget;
class HelpEditor : public QtEditorPart, public IReusableEditor, public IPartListener, public IPerspectiveListener
{
Q_OBJECT
public:
berryObjectMacro(HelpEditor);
static const std::string EDITOR_ID;
HelpEditor();
~HelpEditor();
void Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input);
void SetFocus();
void DoSave() {}
void DoSaveAs() {}
bool IsDirty() const { return false; }
bool IsSaveAsAllowed() const { return false; }
QWebPage* GetQWebPage() const;
IPartListener::Events::Types GetPartEventTypes() const;
void PartDeactivated(IWorkbenchPartReference::Pointer /*partRef*/);
IPerspectiveListener::Events::Types GetPerspectiveEventTypes() const;
void PerspectiveActivated(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective);
void PerspectiveDeactivated(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective);
protected:
void CreateQtPartControl(QWidget* parent);
void DoSetInput(IEditorInput::Pointer input);
void SetInputWithNotify(IEditorInput::Pointer input);
void SetInput(IEditorInput::Pointer input);
private Q_SLOTS:
void HomePageChanged(const QString& page);
void OpenHelpPerspective();
void CloseHelpPerspective();
void InitializeTitle();
void ShowTextSearch();
void findNext();
void findPrevious();
void find(const QString& ttf, bool forward);
private:
bool findInWebPage(const QString& ttf, bool forward);
void enableShortcuts();
void disableShortcuts();
private:
Q_DISABLE_COPY(HelpEditor)
QToolBar* m_ToolBar;
HelpWebView* m_WebView;
HelpEditorFindWidget* m_FindWidget;
QAction* m_BackAction;
QAction* m_ForwardAction;
QAction* m_FindAction;
QAction* m_ZoomIn;
QAction* m_ZoomOut;
QAction* m_OpenHelpMode;
QAction* m_CloseHelpMode;
QAction* m_HomeAction;
+ QAction* m_PrintAction;
};
} // end namespace berry
#endif /*BERRYHELPEDITOR_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp
index 4fae9329a4..7fd80252bf 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp
@@ -1,527 +1,546 @@
/*===================================================================
BlueBerry Platform
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "berryHelpWebView.h"
#include "berryHelpPluginActivator.h"
#include "berryHelpEditor.h"
#include "berryHelpEditorInput.h"
#include "berryQHelpEngineWrapper.h"
#include <berryIWorkbenchPage.h>
#include <QCoreApplication>
#include <QTimer>
#include <QStringBuilder>
#include <QTemporaryFile>
#include <QDesktopServices>
#include <QWheelEvent>
+#include <QPrinter>
+#include <QPrintDialog>
#include <QWebPage>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
namespace berry {
struct ExtensionMap {
const char *extension;
const char *mimeType;
} extensionMap[] = {
{ ".bmp", "image/bmp" },
{ ".css", "text/css" },
{ ".gif", "image/gif" },
{ ".html", "text/html" },
{ ".htm", "text/html" },
{ ".ico", "image/x-icon" },
{ ".jpeg", "image/jpeg" },
{ ".jpg", "image/jpeg" },
{ ".js", "application/x-javascript" },
{ ".mng", "video/x-mng" },
{ ".pbm", "image/x-portable-bitmap" },
{ ".pgm", "image/x-portable-graymap" },
{ ".pdf", "application/pdf" },
{ ".png", "image/png" },
{ ".ppm", "image/x-portable-pixmap" },
{ ".rss", "application/rss+xml" },
{ ".svg", "image/svg+xml" },
{ ".svgz", "image/svg+xml" },
{ ".text", "text/plain" },
{ ".tif", "image/tiff" },
{ ".tiff", "image/tiff" },
{ ".txt", "text/plain" },
{ ".xbm", "image/x-xbitmap" },
{ ".xml", "text/xml" },
{ ".xpm", "image/x-xpm" },
{ ".xsl", "text/xsl" },
{ ".xhtml", "application/xhtml+xml" },
{ ".wml", "text/vnd.wap.wml" },
{ ".wmlc", "application/vnd.wap.wmlc" },
{ "about:blank", 0 },
{ 0, 0 }
};
const QString HelpWebView::m_PageNotFoundMessage =
QCoreApplication::translate("org.blueberry.ui.qt.help", "<title>Error 404...</title><div "
"align=\"center\"><br><br><h1>The page could not be found</h1><br><h3>'%1'"
"</h3></div>");
class HelpNetworkReply : public QNetworkReply
{
public:
HelpNetworkReply(const QNetworkRequest &request, const QByteArray &fileData,
const QString &mimeType);
virtual void abort();
virtual qint64 bytesAvailable() const
{ return data.length() + QNetworkReply::bytesAvailable(); }
protected:
virtual qint64 readData(char *data, qint64 maxlen);
private:
QByteArray data;
qint64 origLen;
};
HelpNetworkReply::HelpNetworkReply(const QNetworkRequest &request,
const QByteArray &fileData, const QString& mimeType)
: data(fileData), origLen(fileData.length())
{
setRequest(request);
setOpenMode(QIODevice::ReadOnly);
setHeader(QNetworkRequest::ContentTypeHeader, mimeType);
setHeader(QNetworkRequest::ContentLengthHeader, QByteArray::number(origLen));
QTimer::singleShot(0, this, SIGNAL(metaDataChanged()));
QTimer::singleShot(0, this, SIGNAL(readyRead()));
}
void HelpNetworkReply::abort()
{
}
qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen)
{
qint64 len = qMin(qint64(data.length()), maxlen);
if (len) {
memcpy(buffer, data.constData(), len);
data.remove(0, len);
}
if (!data.length())
QTimer::singleShot(0, this, SIGNAL(finished()));
return len;
}
class HelpNetworkAccessManager : public QNetworkAccessManager
{
public:
HelpNetworkAccessManager(QObject *parent);
protected:
virtual QNetworkReply *createRequest(Operation op,
const QNetworkRequest &request,
QIODevice *outgoingData = 0);
};
HelpNetworkAccessManager::HelpNetworkAccessManager(QObject *parent)
: QNetworkAccessManager(parent)
{
}
QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/,
const QNetworkRequest &request,
QIODevice* /*outgoingData*/)
{
QString url = request.url().toString();
QHelpEngine& helpEngine = HelpPluginActivator::getInstance()->getQHelpEngine();
// TODO: For some reason the url to load is already wrong (passed from webkit)
// though the css file and the references inside should work that way. One
// possible problem might be that the css is loaded at the same level as the
// html, thus a path inside the css like (../images/foo.png) might cd out of
// the virtual folder
// if (!helpEngine.findFile(url).isValid()) {
// if (url.startsWith(AbstractHelpWebView::DocPath)) {
// QUrl newUrl = request.url();
// if (!newUrl.path().startsWith(QLatin1String("/qdoc/"))) {
// newUrl.setPath(QLatin1String("qdoc") + newUrl.path());
// url = newUrl.toString();
// }
// }
// }
const QString &mimeType = HelpWebView::mimeFromUrl(url);
const QByteArray &data = helpEngine.findFile(url).isValid()
? helpEngine.fileData(url)
: HelpWebView::m_PageNotFoundMessage.arg(url).toUtf8();
return new HelpNetworkReply(request, data, mimeType.isEmpty()
? QLatin1String("application/octet-stream") : mimeType);
}
class HelpPage : public QWebPage
{
public:
HelpPage(IEditorSite::Pointer editorSite, QObject *parent);
protected:
virtual QWebPage *createWindow(QWebPage::WebWindowType);
virtual void triggerAction(WebAction action, bool checked = false);
virtual bool acceptNavigationRequest(QWebFrame *frame,
const QNetworkRequest &request,
NavigationType type);
private:
IEditorSite::Pointer m_EditorSite;
bool m_CloseNewTabIfNeeded;
friend class HelpWebView;
QUrl m_loadingUrl;
Qt::MouseButtons m_pressedButtons;
Qt::KeyboardModifiers m_keyboardModifiers;
};
HelpPage::HelpPage(IEditorSite::Pointer editorSite, QObject *parent)
: QWebPage(parent)
, m_EditorSite(editorSite)
, m_CloseNewTabIfNeeded(false)
, m_pressedButtons(Qt::NoButton)
, m_keyboardModifiers(Qt::NoModifier)
{
}
QWebPage *HelpPage::createWindow(QWebPage::WebWindowType type)
{
IEditorInput::Pointer input(new HelpEditorInput(QUrl()));
IEditorPart::Pointer editorPart = m_EditorSite->GetPage()->OpenEditor(input, HelpEditor::EDITOR_ID);
HelpEditor::Pointer helpEditor = editorPart.Cast<HelpEditor>();
HelpPage* newPage = static_cast<HelpPage*>(helpEditor->GetQWebPage());
if (newPage)
newPage->m_CloseNewTabIfNeeded = m_CloseNewTabIfNeeded;
m_CloseNewTabIfNeeded = false;
return newPage;
}
void HelpPage::triggerAction(WebAction action, bool checked)
{
switch (action)
{
case OpenLinkInNewWindow:
m_CloseNewTabIfNeeded = true;
default: // fall through
QWebPage::triggerAction(action, checked);
break;
}
}
bool HelpPage::acceptNavigationRequest(QWebFrame *,
const QNetworkRequest &request,
QWebPage::NavigationType type)
{
const bool closeNewTab = m_CloseNewTabIfNeeded;
m_CloseNewTabIfNeeded = false;
// open in an external browser if a http link
const QUrl &url = request.url();
if (url.scheme() == QLatin1String("http"))
{
QDesktopServices::openUrl(url);
return false;
}
// const QUrl &url = request.url();
// if (AbstractHelpWebView::launchWithExternalApp(url))
// {
// if (closeNewTab)
// QMetaObject::invokeMethod(centralWidget, "closeTab");
// return false;
// }
// if (type == QWebPage::NavigationTypeLinkClicked
// && (m_keyboardModifiers & Qt::ControlModifier
// || m_pressedButtons == Qt::MidButton))
// {
// if (centralWidget->newEmptyTab())
// centralWidget->setSource(url);
// m_pressedButtons = Qt::NoButton;
// m_keyboardModifiers = Qt::NoModifier;
// return false;
// }
// m_loadingUrl = url; // because of async page loading, we will hit some kind
// of race condition while using a remote command, like a combination of
// SetSource; SyncContent. SetSource would be called and SyncContents shortly
// afterwards, but the page might not have finished loading and the old url
// would be returned.
return true;
}
// -- HelpWebView
HelpWebView::HelpWebView(IEditorSite::Pointer editorSite, QWidget *parent, qreal zoom)
: QWebView(parent)
//, parentWidget(parent)
, m_LoadFinished(false)
, m_HelpEngine(HelpPluginActivator::getInstance()->getQHelpEngine())
{
setAcceptDrops(false);
setPage(new HelpPage(editorSite, parent));
page()->setNetworkAccessManager(new HelpNetworkAccessManager(this));
QAction* action = pageAction(QWebPage::OpenLinkInNewWindow);
action->setText(tr("Open Link in New Tab"));
if (!parent)
action->setVisible(false);
pageAction(QWebPage::DownloadLinkToDisk)->setVisible(false);
pageAction(QWebPage::DownloadImageToDisk)->setVisible(false);
pageAction(QWebPage::OpenImageInNewWindow)->setVisible(false);
connect(pageAction(QWebPage::Copy), SIGNAL(changed()), this,
SLOT(actionChanged()));
connect(pageAction(QWebPage::Back), SIGNAL(changed()), this,
SLOT(actionChanged()));
connect(pageAction(QWebPage::Forward), SIGNAL(changed()), this,
SLOT(actionChanged()));
connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this,
SIGNAL(highlighted(QString)));
connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl)));
connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted()));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
connect(page(), SIGNAL(printRequested(QWebFrame*)), this, SIGNAL(printRequested()));
setFont(viewerFont());
setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom);
}
HelpWebView::~HelpWebView()
{
}
QFont HelpWebView::viewerFont() const
{
//if (m_HelpEngine.usesBrowserFont())
// return m_HelpEngine.browserFont();
QWebSettings *webSettings = QWebSettings::globalSettings();
return QFont(webSettings->fontFamily(QWebSettings::StandardFont),
webSettings->fontSize(QWebSettings::DefaultFontSize));
}
void HelpWebView::setViewerFont(const QFont &font)
{
QWebSettings *webSettings = settings();
webSettings->setFontFamily(QWebSettings::StandardFont, font.family());
webSettings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize());
}
void HelpWebView::scaleUp()
{
setTextSizeMultiplier(textSizeMultiplier() + 0.1);
}
void HelpWebView::scaleDown()
{
setTextSizeMultiplier(qMax(0.0, textSizeMultiplier() - 0.1));
}
void HelpWebView::resetScale()
{
setTextSizeMultiplier(1.0);
}
bool HelpWebView::handleForwardBackwardMouseButtons(QMouseEvent *e)
{
if (e->button() == Qt::XButton1)
{
triggerPageAction(QWebPage::Back);
return true;
}
if (e->button() == Qt::XButton2)
{
triggerPageAction(QWebPage::Forward);
return true;
}
return false;
}
QUrl HelpWebView::source() const
{
HelpPage *currentPage = static_cast<HelpPage*> (page());
if (currentPage && !hasLoadFinished())
{
// see HelpPage::acceptNavigationRequest(...)
return currentPage->m_loadingUrl;
}
return url();
}
void HelpWebView::setSource(const QUrl &url)
{
if (m_HelpEngine.findFile(url).isValid())
load(url);
else
setHtml(m_PageNotFoundMessage.arg(url.toString()));
}
void HelpWebView::wheelEvent(QWheelEvent *e)
{
if (e->modifiers()& Qt::ControlModifier)
{
e->accept();
e->delta() > 0 ? scaleUp() : scaleDown();
}
else
{
QWebView::wheelEvent(e);
}
}
void HelpWebView::mouseReleaseEvent(QMouseEvent *e)
{
#ifndef Q_OS_LINUX
if (handleForwardBackwardMouseButtons(e))
return;
#endif
QWebView::mouseReleaseEvent(e);
}
void HelpWebView::actionChanged()
{
QAction *a = qobject_cast<QAction *>(sender());
if (a == pageAction(QWebPage::Copy))
emit copyAvailable(a->isEnabled());
else if (a == pageAction(QWebPage::Back))
emit backwardAvailable(a->isEnabled());
else if (a == pageAction(QWebPage::Forward))
emit forwardAvailable(a->isEnabled());
}
void HelpWebView::mousePressEvent(QMouseEvent *event)
{
#ifdef Q_OS_LINUX
if (handleForwardBackwardMouseButtons(event))
return;
#endif
HelpPage *currentPage = static_cast<HelpPage*>(page());
if (currentPage)
{
currentPage->m_pressedButtons = event->buttons();
currentPage->m_keyboardModifiers = event->modifiers();
}
QWebView::mousePressEvent(event);
}
void HelpWebView::setLoadStarted()
{
m_LoadFinished = false;
}
void HelpWebView::setLoadFinished(bool ok)
{
m_LoadFinished = ok;
emit sourceChanged(url());
}
QString HelpWebView::mimeFromUrl(const QUrl &url)
{
const QString &path = url.path();
const int index = path.lastIndexOf(QLatin1Char('.'));
const QByteArray &ext = path.mid(index).toUtf8().toLower();
const ExtensionMap *e = extensionMap;
while (e->extension)
{
if (ext == e->extension)
return QLatin1String(e->mimeType);
++e;
}
return QLatin1String("");
}
bool HelpWebView::canOpenPage(const QString &url)
{
return !mimeFromUrl(url).isEmpty();
}
bool HelpWebView::isLocalUrl(const QUrl &url)
{
const QString &scheme = url.scheme();
return scheme.isEmpty()
|| scheme == QLatin1String("file")
|| scheme == QLatin1String("qrc")
|| scheme == QLatin1String("data")
|| scheme == QLatin1String("qthelp")
|| scheme == QLatin1String("about");
}
bool HelpWebView::launchWithExternalApp(const QUrl &url)
{
if (isLocalUrl(url))
{
const QHelpEngine& helpEngine = HelpPluginActivator::getInstance()->getQHelpEngine();
const QUrl &resolvedUrl = helpEngine.findFile(url);
if (!resolvedUrl.isValid())
return false;
const QString& path = resolvedUrl.path();
if (!canOpenPage(path))
{
QTemporaryFile tmpTmpFile;
if (!tmpTmpFile.open())
return false;
const QString &extension = QFileInfo(path).completeSuffix();
QFile actualTmpFile(tmpTmpFile.fileName() % QLatin1String(".")
% extension);
if (!actualTmpFile.open(QIODevice::ReadWrite | QIODevice::Truncate))
return false;
actualTmpFile.write(helpEngine.fileData(resolvedUrl));
actualTmpFile.close();
return QDesktopServices::openUrl(QUrl(actualTmpFile.fileName()));
}
}
else if (url.scheme() == QLatin1String("http"))
{
return QDesktopServices::openUrl(url);
}
return false;
}
void HelpWebView::home()
{
setSource(m_HelpEngine.homePage());
}
+void HelpWebView::print()
+{
+ QPrinter printer;
+
+ QPrintDialog *dialog = new QPrintDialog(&printer, this);
+ dialog->setWindowTitle(tr("Print Document"));
+ if(hasSelection())
+ {
+ dialog->addEnabledOption(QAbstractPrintDialog::PrintSelection);
+ }
+ if(dialog->exec() == QDialog::Accepted)
+ {
+ QWebView::print(&printer);
+ }
+}
+
+
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.h b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.h
index ae82df26a8..d32ce85039 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.h
@@ -1,108 +1,109 @@
/*===================================================================
BlueBerry Platform
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef BERRYHELPWEBVIEW_H
#define BERRYHELPWEBVIEW_H
#include <QFont>
#include <QAction>
#include <QWebView>
#include <berryIEditorSite.h>
namespace berry {
class QHelpEngineWrapper;
class HelpWebView : public QWebView
{
Q_OBJECT
public:
explicit HelpWebView(IEditorSite::Pointer editorSite, QWidget *parent, qreal zoom = 0.0);
~HelpWebView();
QFont viewerFont() const;
void setViewerFont(const QFont &font);
qreal scale() const { return textSizeMultiplier(); }
bool handleForwardBackwardMouseButtons(QMouseEvent *e);
QUrl source() const;
void setSource(const QUrl &url);
inline QString documentTitle() const
{ return title(); }
inline bool hasSelection() const
{ return !selectedText().isEmpty(); } // ### this is suboptimal
inline void copy()
{ return triggerPageAction(QWebPage::Copy); }
inline bool isForwardAvailable() const
{ return pageAction(QWebPage::Forward)->isEnabled(); }
inline bool isBackwardAvailable() const
{ return pageAction(QWebPage::Back)->isEnabled(); }
inline bool hasLoadFinished() const
{ return m_LoadFinished; }
static QString mimeFromUrl(const QUrl &url);
static bool canOpenPage(const QString &url);
static bool isLocalUrl(const QUrl &url);
static bool launchWithExternalApp(const QUrl &url);
static const QString m_PageNotFoundMessage;
public Q_SLOTS:
void backward() { back(); }
void home();
+ void print();
void scaleUp();
void scaleDown();
void resetScale();
Q_SIGNALS:
void copyAvailable(bool enabled);
void forwardAvailable(bool enabled);
void backwardAvailable(bool enabled);
void highlighted(const QString &);
void sourceChanged(const QUrl &);
void printRequested();
protected:
virtual void wheelEvent(QWheelEvent *);
void mouseReleaseEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *event);
private Q_SLOTS:
void actionChanged();
void setLoadStarted();
void setLoadFinished(bool ok);
private:
bool m_LoadFinished;
QHelpEngineWrapper& m_HelpEngine;
};
}
#endif // BERRYHELPWEBVIEW_H
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h
index eb8a8189fb..02cd24c152 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h
@@ -1,221 +1,226 @@
/*===================================================================
BlueBerry Platform
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef BERRYQTPLATFORMLOGMODEL_H_
#define BERRYQTPLATFORMLOGMODEL_H_
#include "berryLog.h"
#include <QtCore/QAbstractTableModel>
#include <QtCore/QDateTime>
#include "event/berryPlatformEvent.h"
#include "berryMessage.h"
#include <vector>
#include <ctime>
#include <sstream>
#include "berryLog.h"
#include <QMutex>
namespace berry {
/** Documentation
* @brief An object of this class represents a table of logging data.
* The table presentation can be modified by the methods
* SetShowAdvancedFiels() and SetShowCategory().
*/
class QtPlatformLogModel : public QAbstractTableModel
{
Q_OBJECT
public:
QtPlatformLogModel(QObject* parent = 0);
~QtPlatformLogModel();
void SetShowAdvancedFiels( bool showAdvancedFiels );
void SetShowCategory( bool showCategory );
int rowCount(const QModelIndex&) const;
int columnCount(const QModelIndex&) const;
QVariant data(const QModelIndex& index, int) const;
/** Documentation
* @return Retruns the complete table data as string representation.
*/
QString GetDataAsString();
QVariant headerData(int section, Qt::Orientation orientation, int) const;
void addLogEntry(const mbilog::LogMessage &msg);
void addLogEntry(const PlatformEvent& event);
private:
bool m_ShowAdvancedFiels;
bool m_ShowCategory;
/** Documentation
* @brief An object of this struct internally represents a logging message.
* It offers methods to convert the logging data into QVaraint objects
* and also adds time and threadid as logging data. The struct is
* internally used to store logging data in the table data model.
*/
struct ExtendedLogMessage {
mbilog::LogMessage message;
clock_t time;
int threadid;
ExtendedLogMessage(const ExtendedLogMessage &src):message(src.message),time(src.time),threadid(src.threadid)
{
}
ExtendedLogMessage(const mbilog::LogMessage &msg):message(msg),time(std::clock()),threadid(0)
{
}
ExtendedLogMessage operator = (const ExtendedLogMessage& src)
{
return ExtendedLogMessage(src);
}
QVariant getLevel() const
{
switch(this->message.level)
{
default:
case mbilog::Info:
return QVariant(Info);
case mbilog::Warn:
return QVariant(Warn);
case mbilog::Error:
return QVariant(Error);
case mbilog::Fatal:
return QVariant(Fatal);
case mbilog::Debug:
return QVariant(Debug);
}
}
QVariant getMessage() const
{
return QVariant(QString(this->message.message.c_str()));
}
QVariant getCategory() const
{
return QVariant(QString(this->message.category.c_str()));
}
QVariant getModuleName() const
{
return QVariant(QString(this->message.moduleName));
}
QVariant getFunctionName() const
{
return QVariant(QString(this->message.functionName));
}
QVariant getPath() const
{
return QVariant(QString(this->message.filePath));
}
QVariant getLine() const
{
std::stringstream out;
std::locale C("C");
out.imbue(C);
out << this->message.lineNumber;
return QVariant(QString(out.str().c_str()));
}
/** This method is implemented in the cpp file to save includes. */
QVariant getTime() const;
};
typedef MessageDelegate1<QtPlatformLogModel, const PlatformEvent&> PlatformEventDelegate;
class QtLogBackend : public mbilog::BackendBase
{
public:
QtLogBackend(QtPlatformLogModel *_myModel)
{
myModel=_myModel;
deactivated = false;
mbilog::RegisterBackend(this);
BERRY_INFO << "BlueBerry mbilog backend registered";
}
~QtLogBackend()
{
mbilog::UnregisterBackend(this);
}
void ProcessMessage(const mbilog::LogMessage &l )
{
if(!deactivated)
myModel->addLogEntry(l);
}
+ mbilog::OutputType GetOutputType() const
+ {
+ return mbilog::Other;
+ }
+
void Deactivate()
{
deactivated=true;
}
private:
QtPlatformLogModel *myModel;
bool deactivated;
} *myBackend;
std::vector<ExtendedLogMessage> m_Entries;
std::list<ExtendedLogMessage> *m_Active,*m_Pending;
static const QString Error;
static const QString Warn;
static const QString Fatal;
static const QString Info;
static const QString Debug;
QMutex m_Mutex;
signals:
void signalFlushLogEntries();
protected slots:
void slotFlushLogEntries();
};
}
#endif /*BERRYQTPLATFORMLOGMODEL_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt
index 99825e877d..1a06997513 100644
--- a/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt
@@ -1,19 +1,18 @@
project(org_blueberry_ui)
set(PLUGIN_exported_include_suffixes
src
src/application
- src/commands
src/dialogs
src/guitk
src/handlers
src/intro
src/presentations
src/services
src/testing
src/tweaklets
src/util
)
MACRO_CREATE_CTK_PLUGIN(EXPORT_DIRECTIVE BERRY_UI
EXPORTED_INCLUDE_SUFFIXES ${PLUGIN_exported_include_suffixes})
diff --git a/CMake/FindDCMTK.cmake b/CMake/FindDCMTK.cmake
index 1ebd82cb10..7996817cd4 100644
--- a/CMake/FindDCMTK.cmake
+++ b/CMake/FindDCMTK.cmake
@@ -1,180 +1,183 @@
# adapted version of FindDCMTK, better suited for super-builds
# - find DCMTK libraries and applications
#
# DCMTK_INCLUDE_DIRS - Directories to include to use DCMTK
# DCMTK_LIBRARIES - Files to link against to use DCMTK
# DCMTK_FOUND - If false, don't try to use DCMTK
# DCMTK_DIR - (optional) Source directory for DCMTK
#
# DCMTK_DIR can be used to make it simpler to find the various include
# directories and compiled libraries if you've just compiled it in the
# source tree. Just set it to the root of the tree where you extracted
# the source (default to /usr/include/dcmtk/)
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
# Copyright 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com>
# Copyright 2010 Thomas Sondergaard <ts@medical-insight.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
#
# Written for VXL by Amitha Perera.
# Upgraded for GDCM by Mathieu Malaterre.
# Modified for EasyViz by Thomas Sondergaard.
#
# prefer DCMTK_DIR over default system paths like /usr/lib
set(CMAKE_PREFIX_PATH ${DCMTK_DIR}/lib ${CMAKE_PREFIX_PATH}) # this is given to FIND_LIBRARY or FIND_PATH
if(NOT DCMTK_FOUND AND NOT DCMTK_DIR)
set(DCMTK_DIR
"/usr/include/dcmtk/"
CACHE
PATH
"Root of DCMTK source tree (optional).")
mark_as_advanced(DCMTK_DIR)
endif()
# Find all libraries, store debug and release separately
foreach(lib
dcmpstat
dcmsr
dcmsign
dcmtls
dcmqrdb
dcmnet
dcmjpeg
dcmimage
dcmimgle
dcmdata
+ dcmrt
oflog
ofstd
ijg12
ijg16
ijg8
)
# Find Release libraries
find_library(DCMTK_${lib}_LIBRARY_RELEASE
${lib}
PATHS
${DCMTK_DIR}/${lib}/libsrc
${DCMTK_DIR}/${lib}/libsrc/Release
${DCMTK_DIR}/${lib}/Release
${DCMTK_DIR}/lib
${DCMTK_DIR}/lib/Release
${DCMTK_DIR}/dcmjpeg/lib${lib}/Release
NO_DEFAULT_PATH
)
# Find Debug libraries
find_library(DCMTK_${lib}_LIBRARY_DEBUG
${lib}
PATHS
${DCMTK_DIR}/${lib}/libsrc
${DCMTK_DIR}/${lib}/libsrc/Debug
${DCMTK_DIR}/${lib}/Debug
${DCMTK_DIR}/lib
${DCMTK_DIR}/lib/Debug
${DCMTK_DIR}/dcmjpeg/lib${lib}/Debug
NO_DEFAULT_PATH
)
mark_as_advanced(DCMTK_${lib}_LIBRARY_RELEASE)
mark_as_advanced(DCMTK_${lib}_LIBRARY_DEBUG)
# Add libraries to variable according to build type
set(DCMTK_${lib}_LIBRARY)
if(DCMTK_${lib}_LIBRARY_RELEASE)
list(APPEND DCMTK_LIBRARIES optimized ${DCMTK_${lib}_LIBRARY_RELEASE})
list(APPEND DCMTK_${lib}_LIBRARY optimized ${DCMTK_${lib}_LIBRARY_RELEASE})
endif()
if(DCMTK_${lib}_LIBRARY_DEBUG)
list(APPEND DCMTK_LIBRARIES debug ${DCMTK_${lib}_LIBRARY_DEBUG})
list(APPEND DCMTK_${lib}_LIBRARY debug ${DCMTK_${lib}_LIBRARY_DEBUG})
endif()
endforeach()
set(DCMTK_config_TEST_HEADER osconfig.h)
set(DCMTK_dcmdata_TEST_HEADER dctypes.h)
set(DCMTK_dcmimage_TEST_HEADER dicoimg.h)
set(DCMTK_dcmimgle_TEST_HEADER dcmimage.h)
set(DCMTK_dcmjpeg_TEST_HEADER djdecode.h)
set(DCMTK_dcmnet_TEST_HEADER assoc.h)
set(DCMTK_dcmpstat_TEST_HEADER dcmpstat.h)
set(DCMTK_dcmqrdb_TEST_HEADER dcmqrdba.h)
set(DCMTK_dcmsign_TEST_HEADER sicert.h)
set(DCMTK_dcmsr_TEST_HEADER dsrtree.h)
set(DCMTK_dcmtls_TEST_HEADER tlslayer.h)
set(DCMTK_ofstd_TEST_HEADER ofstdinc.h)
+set(DCMTK_dcmrt_TEST_HEADER drtstrct.h)
foreach(dir
config
dcmdata
dcmimage
dcmimgle
dcmjpeg
dcmnet
dcmpstat
dcmqrdb
dcmsign
dcmsr
dcmtls
+ dcmrt
ofstd)
find_path(DCMTK_${dir}_INCLUDE_DIR
${DCMTK_${dir}_TEST_HEADER}
PATHS
${DCMTK_DIR}/${dir}/include
${DCMTK_DIR}/${dir}
${DCMTK_DIR}/include/dcmtk/${dir}
${DCMTK_DIR}/include/${dir})
mark_as_advanced(DCMTK_${dir}_INCLUDE_DIR)
#message("** DCMTKs ${dir} found at ${DCMTK_${dir}_INCLUDE_DIR}")
if(DCMTK_${dir}_INCLUDE_DIR)
list(APPEND
DCMTK_INCLUDE_DIRS
${DCMTK_${dir}_INCLUDE_DIR})
endif()
endforeach()
if(WIN32)
list(APPEND DCMTK_LIBRARIES netapi32 wsock32)
endif()
if(DCMTK_ofstd_INCLUDE_DIR)
get_filename_component(DCMTK_dcmtk_INCLUDE_DIR
${DCMTK_ofstd_INCLUDE_DIR}
PATH
CACHE)
list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_dcmtk_INCLUDE_DIR})
mark_as_advanced(DCMTK_dcmtk_INCLUDE_DIR)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DCMTK DEFAULT_MSG
DCMTK_config_INCLUDE_DIR
DCMTK_ofstd_INCLUDE_DIR
DCMTK_ofstd_LIBRARY
DCMTK_dcmdata_INCLUDE_DIR
DCMTK_dcmdata_LIBRARY
DCMTK_dcmimgle_INCLUDE_DIR
DCMTK_dcmimgle_LIBRARY
)
# Compatibility: This variable is deprecated
set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS})
diff --git a/CMake/FindNumpy.cmake b/CMake/FindNumpy.cmake
new file mode 100644
index 0000000000..057833cc31
--- /dev/null
+++ b/CMake/FindNumpy.cmake
@@ -0,0 +1,32 @@
+# Variables set by this script
+# NUMPY_FOUND
+# NUMPY_INCLUDE_DIR
+find_package(PackageHandleStandardArgs)
+
+if(DEFINED Numpy_DIR AND EXISTS ${Numpy_DIR})
+ set(NUMPY_INCLUDE_DIR ${Numpy_DIR}/core/include)
+ MESSAGE("NUMPY_DIR: " ${Numpy_DIR})
+ MESSAGE("NUMPY_INCLUDE_DIR: " ${NUMPY_INCLUDE_DIR})
+ MESSAGE("PYTHON_EXECUTABLE: " ${PYTHON_EXECUTABLE})
+else()
+ set(_python ${PYTHON_EXECUTABLE})
+ if(UNIX)
+ STRING(REPLACE " " "\ " _python ${PYTHON_EXECUTABLE})
+ endif()
+
+ execute_process (
+ COMMAND ${_python} -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print numpy.distutils.misc_util.get_numpy_include_dirs()[0]"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ if(DEFINED output AND EXISTS ${output} )
+ set (NUMPY_INCLUDE_DIR ${output})
+ endif()
+endif()
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Numpy DEFAULT_MSG NUMPY_INCLUDE_DIR)
+
+MARK_AS_ADVANCED (
+ NUMPY_INCLUDE_DIR
+)
diff --git a/CMake/FindOpenCL.cmake b/CMake/FindOpenCL.cmake
index 34e85fa8d0..e30fb7a484 100644
--- a/CMake/FindOpenCL.cmake
+++ b/CMake/FindOpenCL.cmake
@@ -1,59 +1,89 @@
-set(ENV_ATISTREAMSDKROOT $ENV{ATISTREAMSDKROOT})
-if(ENV_ATISTREAMSDKROOT)
- find_path(
- OpenCL_INCLUDE_DIR
- NAMES CL/cl.h OpenCL/cl.h
- PATHS $ENV{ATISTREAMSDKROOT}/include
- NO_DEFAULT_PATH
- )
+# - Try to find OpenCL
+# This module tries to find an OpenCL implementation on your system. It supports
+# AMD / ATI, Apple and NVIDIA implementations, but should work, too.
+#
+# To set manually the paths, define these environment variables:
+# OpenCL_INCPATH - Include path (e.g. OpenCL_INCPATH=/opt/cuda/4.0/cuda/include)
+# OpenCL_LIBPATH - Library path (e.h. OpenCL_LIBPATH=/usr/lib64/nvidia)
+#
+# Once done this will define
+# OPENCL_FOUND - system has OpenCL
+# OPENCL_INCLUDE_DIRS - the OpenCL include directory
+# OPENCL_LIBRARIES - link these to use OpenCL
+#
+# WIN32 should work, but is untested
- if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
- if(CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(
- OpenCL_LIB_SEARCH_PATH
- ${OpenCL_LIB_SEARCH_PATH}
- $ENV{ATISTREAMSDKROOT}/lib/x86
- )
- else(CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(
- OpenCL_LIB_SEARCH_PATH
- ${OpenCL_LIB_SEARCH_PATH}
- $ENV{ATISTREAMSDKROOT}/lib/x86_64
- )
- endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
- endif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
- find_library(
- OpenCL_LIBRARY
- NAMES OpenCL
- PATHS ${OpenCL_LIB_SEARCH_PATH}
- NO_DEFAULT_PATH
- )
-else(ENV_ATISTREAMSDKROOT)
- find_path(
- OpenCL_INCLUDE_DIR
- NAMES CL/cl.h OpenCL/cl.h
- )
+FIND_PACKAGE(PackageHandleStandardArgs)
+
+SET (OPENCL_VERSION_STRING "0.1.0")
+SET(OPENCL_VERSION_MAJOR 0)
+SET(OPENCL_VERSION_MINOR 1)
+SET(OPENCL_VERSION_PATCH 0)
+
+IF(APPLE)
+
+ FIND_LIBRARY(OPENCL_LIBRARIES OpenCL DOC "OpenCL lib for OSX")
+ FIND_PATH(OPENCL_INCLUDE_DIRS OpenCL/cl.h DOC "Include for OpenCL on OSX")
+ FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS OpenCL/cl.hpp DOC "Include for OpenCL CPP bindings on OSX")
+
+ELSE()
+ IF (WIN32)
+
+ FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h)
+ FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp)
+
+ IF(CMAKE_SIZEOF_VOID_P MATCHES "8")
+ SET(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86_64")
+ if(NOT IS_DIRECTORY ${OPENCL_LIB_DIR})
+ SET(OPENCL_LIB_DIR "$ENV{CUDA_PATH}/lib/x64")
+ endif()
+ ELSE()
+ SET(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86")
+ if(NOT IS_DIRECTORY ${OPENCL_LIB_DIR}) # need to convert path in the cmake style ?
+ SET(OPENCL_LIB_DIR "$ENV{CUDA_PATH}/lib/Win32")
+ endif()
+ ENDIF()
+ file(TO_CMAKE_PATH ${OPENCL_LIB_DIR} OPENCL_LIB_DIR)
+ GET_FILENAME_COMPONENT(OPENCL_LIB_DIR ${OPENCL_LIB_DIR} ABSOLUTE)
+
+ FIND_LIBRARY(OPENCL_LIBRARIES OpenCL.lib PATHS ${OPENCL_LIB_DIR} ENV OpenCL_LIBPATH)
+
+ GET_FILENAME_COMPONENT(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE)
- find_library(
- OpenCL_LIBRARY
- NAMES OpenCL
+ # On Win32 search relative to the library
+ FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h PATHS "${_OPENCL_INC_CAND}" ENV OpenCL_INCPATH)
+ FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS "${_OPENCL_INC_CAND}" ENV OpenCL_INCPATH)
+
+ ELSE (WIN32)
+
+ # Unix style platforms
+ FIND_LIBRARY(OPENCL_LIBRARIES OpenCL
+ PATHS ENV LD_LIBRARY_PATH ENV OpenCL_LIBPATH
+ )
+
+ GET_FILENAME_COMPONENT(OPENCL_LIB_DIR ${OPENCL_LIBRARIES} PATH)
+ GET_FILENAME_COMPONENT(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE)
+
+ # The AMD SDK currently does not place its headers
+ # in /usr/include, therefore also search relative
+ # to the library
+ FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include" "/opt/AMDAPP/include" ENV OpenCL_INCPATH)
+ FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include" "/opt/AMDAPP/include" ENV OpenCL_INCPATH)
+
+ ENDIF (WIN32)
+
+ENDIF (APPLE)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCL DEFAULT_MSG OPENCL_LIBRARIES OPENCL_INCLUDE_DIRS)
+
+IF(_OPENCL_CPP_INCLUDE_DIRS)
+ SET( OPENCL_HAS_CPP_BINDINGS TRUE )
+ LIST( APPEND OPENCL_INCLUDE_DIRS ${_OPENCL_CPP_INCLUDE_DIRS} )
+ # This is often the same, so clean up
+ LIST( REMOVE_DUPLICATES OPENCL_INCLUDE_DIRS )
+ENDIF(_OPENCL_CPP_INCLUDE_DIRS)
+
+MARK_AS_ADVANCED(
+ OPENCL_INCLUDE_DIRS
)
-endif(ENV_ATISTREAMSDKROOT)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
- OpenCL
- DEFAULT_MSG
- OpenCL_LIBRARY OpenCL_INCLUDE_DIR
- )
-
-if(OpenCL_FOUND)
- set(OpenCL_LIBRARIES ${OpenCL_LIBRARY})
-else(OpenCL_FOUND)
- set(OpenCL_LIBRARIES)
-endif(OpenCL_FOUND)
-
-mark_as_advanced(
- OpenCL_INCLUDE_DIR
- OpenCL_LIBRARY
- )
+
diff --git a/CMake/MITKDashboardSetup.cmake b/CMake/MITKDashboardSetup.cmake
index caf521922a..bb45c8e907 100644
--- a/CMake/MITKDashboardSetup.cmake
+++ b/CMake/MITKDashboardSetup.cmake
@@ -1,193 +1,207 @@
# This file is intended to be included at the end of a custom MITKDashboardScript.TEMPLATE.cmake file
list(APPEND CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
#
# Automatically determined properties
#
set(MY_OPERATING_SYSTEM )
if(UNIX)
# Download a utility script
set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/mitkDetectOS.sh;hb=${hb}")
set(dest "${CTEST_SCRIPT_DIRECTORY}/mitkDetectOS.sh")
downloadFile("${url}" "${dest}")
execute_process(COMMAND sh "${dest}"
RESULT_VARIABLE _result OUTPUT_VARIABLE _out
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _result)
set(MY_OPERATING_SYSTEM "${_out}")
endif()
endif()
if(NOT MY_OPERATING_SYSTEM)
set(MY_OPERATING_SYSTEM "${CMAKE_HOST_SYSTEM}") # Windows 7, Linux-2.6.32, Darwin...
endif()
site_name(CTEST_SITE)
if(NOT DEFINED MITK_USE_QT)
set(MITK_USE_QT 1)
endif()
if(MITK_USE_QT)
if(NOT QT_QMAKE_EXECUTABLE)
find_program(QT_QMAKE_EXECUTABLE NAMES qmake qmake-qt4
HINTS ${QT_BINARY_DIR})
endif()
execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} --version
OUTPUT_VARIABLE MY_QT_VERSION
RESULT_VARIABLE qmake_error)
if(qmake_error)
message(FATAL_ERROR "Error when executing ${QT_QMAKE_EXECUTABLE} --version\n${qmake_error}")
endif()
string(REGEX REPLACE ".*Qt version ([0-9.]+) .*" "\\1" MY_QT_VERSION ${MY_QT_VERSION})
endif()
#
# Project specific properties
#
if(NOT CTEST_BUILD_NAME)
if(MITK_USE_QT)
set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} Qt${MY_QT_VERSION} ${CTEST_BUILD_CONFIGURATION}")
else()
set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} ${CTEST_BUILD_CONFIGURATION}")
endif()
endif()
set(PROJECT_BUILD_DIR "MITK-build")
set(CTEST_PATH "$ENV{PATH}")
if(WIN32)
set(ANN_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ANN-build/${CTEST_BUILD_CONFIGURATION}")
set(CPPUNIT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/CppUnit-build/${CTEST_BUILD_CONFIGURATION}")
set(GLUT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLUT-build/${CTEST_BUILD_CONFIGURATION}")
set(GLEW_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLEW-build/${CTEST_BUILD_CONFIGURATION}")
set(TINYXML_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/tinyxml-build/${CTEST_BUILD_CONFIGURATION}")
set(QWT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qwt-build/${CTEST_BUILD_CONFIGURATION}")
set(QXT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qxt-build/${CTEST_BUILD_CONFIGURATION}")
set(VTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/VTK-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(ACVD_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ACVD-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(ITK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ITK-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(BOOST_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Boost-install/lib")
set(GDCM_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GDCM-build/bin/${CTEST_BUILD_CONFIGURATION}")
+ set(DCMTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/DCMTK-install/bin/${CTEST_BUILD_CONFIGURATION}")
set(OPENCV_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/OpenCV-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(POCO_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Poco-install/lib")
set(SOFA_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/SOFA-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(BLUEBERRY_OSGI_DIR "${CTEST_BINARY_DIRECTORY}/MITK-build/bin/BlueBerry/org.blueberry.osgi/bin/${CTEST_BUILD_CONFIGURATION}")
- set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${QXT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}")
+ set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${QXT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${DCMTK_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}")
endif()
set(ENV{PATH} "${CTEST_PATH}")
set(SUPERBUILD_TARGETS "")
# If the dashscript doesn't define a GIT_REPOSITORY variable, let's define it here.
if(NOT DEFINED GIT_REPOSITORY OR GIT_REPOSITORY STREQUAL "")
set(GIT_REPOSITORY "http://git.mitk.org/MITK.git")
endif()
#
# Display build info
#
message("Site name: ${CTEST_SITE}")
message("Build name: ${CTEST_BUILD_NAME}")
message("Script Mode: ${SCRIPT_MODE}")
message("Coverage: ${WITH_COVERAGE}, MemCheck: ${WITH_MEMCHECK}")
#
# Set initial cache options
#
if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
set(CTEST_USE_LAUNCHERS 1)
set(ENV{CTEST_USE_LAUNCHERS_DEFAULT} 1)
endif()
# Remove this if block after all dartclients work
if(DEFINED ADDITIONNAL_CMAKECACHE_OPTION)
message(WARNING "Rename ADDITIONNAL to ADDITIONAL in your dartlclient script: ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
set(ADDITIONAL_CMAKECACHE_OPTION ${ADDITIONNAL_CMAKECACHE_OPTION})
endif()
if(NOT DEFINED MITK_USE_ACVD)
set(MITK_USE_ACVD 1)
endif()
if(NOT DEFINED MITK_USE_Boost)
set(MITK_USE_Boost 1)
endif()
if(NOT DEFINED MITK_USE_OpenCV)
set(MITK_USE_OpenCV 1)
endif()
if(NOT DEFINED MITK_USE_Poco)
set(MITK_USE_Poco 1)
endif()
+if(NOT DEFINED MITK_USE_Python)
+ if(WIN32)
+ set(MITK_USE_Python FALSE)
+ else()
+ set(MITK_USE_Python TRUE)
+ endif()
+endif()
+
if(NOT DEFINED MITK_USE_SOFA)
set(MITK_USE_SOFA 1)
endif()
+if(NOT DEFINED MITK_VTK_DEBUG_LEAKS)
+ set(MITK_VTK_DEBUG_LEAKS 1)
+endif()
if(NOT DEFINED MITK_BUILD_ALL_APPS)
set(MITK_BUILD_ALL_APPS TRUE)
endif()
if(NOT DEFINED BLUEBERRY_BUILD_ALL_PLUGINS)
set(BLUEBERRY_BUILD_ALL_PLUGINS TRUE)
endif()
if(NOT DEFINED MITK_BUILD_ALL_PLUGINS)
set(MITK_BUILD_ALL_PLUGINS TRUE)
endif()
if(NOT DEFINED MITK_BUILD_EXAMPLES)
set(MITK_BUILD_EXAMPLES TRUE)
endif()
if(NOT BUILD_DiffusionMiniApps)
set(BUILD_DiffusionMiniApps TRUE)
endif()
set(INITIAL_CMAKECACHE_OPTIONS "
BLUEBERRY_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS}
MITK_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS}
MITK_BUILD_ALL_APPS:BOOL=${MITK_BUILD_ALL_APPS}
MITK_BUILD_EXAMPLES:BOOL=${MITK_BUILD_EXAMPLES}
SUPERBUILD_EXCLUDE_MITKBUILD_TARGET:BOOL=TRUE
MITK_USE_ACVD:BOOL=${MITK_USE_ACVD}
MITK_USE_Boost:BOOL=${MITK_USE_Boost}
MITK_USE_OpenCV:BOOL=${MITK_USE_OpenCV}
MITK_USE_Poco:BOOL=${MITK_USE_Poco}
+MITK_USE_Python:BOOL=${MITK_USE_Python}
MITK_USE_SOFA:BOOL=${MITK_USE_SOFA}
MITK_USE_QT:BOOL=${MITK_USE_QT}
+MITK_VTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS}
${ADDITIONAL_CMAKECACHE_OPTION}
")
if(MITK_USE_QT)
set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS}
QT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}")
endif()
# Write a cache file for populating the MITK initial cache (not the superbuild cache).
# This can be used to provide variables which are not passed through the
# superbuild process to the MITK configure step)
if(MITK_INITIAL_CACHE)
set(mitk_cache_file "${CTEST_SCRIPT_DIRECTORY}/mitk_initial_cache.txt")
file(WRITE "${mitk_cache_file}" "${MITK_INITIAL_CACHE}")
set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS}
MITK_INITIAL_CACHE_FILE:INTERNAL=${mitk_cache_file}
")
endif()
#
# Download and include dashboard driver script
#
set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/MITKDashboardDriverScript.cmake;hb=${hb}")
set(dest ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}.driver)
downloadFile("${url}" "${dest}")
include(${dest})
diff --git a/CMake/PackageDepends/MITK_Numpy_Config.cmake b/CMake/PackageDepends/MITK_Numpy_Config.cmake
new file mode 100644
index 0000000000..d10c0eaa78
--- /dev/null
+++ b/CMake/PackageDepends/MITK_Numpy_Config.cmake
@@ -0,0 +1,4 @@
+if(MITK_USE_Python)
+ find_package(Numpy REQUIRED)
+ list(APPEND ALL_INCLUDE_DIRECTORIES ${NUMPY_INCLUDE_DIR})
+endif()
diff --git a/CMake/PackageDepends/MITK_OpenCL_Config.cmake b/CMake/PackageDepends/MITK_OpenCL_Config.cmake
index dd1f160d2e..18ba488136 100644
--- a/CMake/PackageDepends/MITK_OpenCL_Config.cmake
+++ b/CMake/PackageDepends/MITK_OpenCL_Config.cmake
@@ -1,8 +1,8 @@
find_package(OpenCL REQUIRED)
-list(APPEND ALL_LIBRARIES ${OpenCL_LIBRARY})
-list(APPEND ALL_INCLUDE_DIRECTORIES ${OpenCL_INCLUDE_DIR})
+list(APPEND ALL_LIBRARIES ${OPENCL_LIBRARIES})
+list(APPEND ALL_INCLUDE_DIRECTORIES ${OPENCL_INCLUDE_DIRS})
# on OS X the linker needs a flag pointing to the OpenCL.framework
if(APPLE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -framework OpenCL")
endif(APPLE)
diff --git a/CMake/PackageDepends/MITK_SimpleITK_Config.cmake b/CMake/PackageDepends/MITK_SimpleITK_Config.cmake
new file mode 100644
index 0000000000..5c1925b95a
--- /dev/null
+++ b/CMake/PackageDepends/MITK_SimpleITK_Config.cmake
@@ -0,0 +1,4 @@
+find_package(SimpleITK REQUIRED CONFIG)
+list(APPEND ALL_INCLUDE_DIRECTORIES ${SimpleITK_INCLUDE_DIRS})
+list(APPEND ALL_LIBRARIES ${SimpleITK_LIBRARIES})
+link_directories(${SimpleITK_LIBRARY_DIRS})
diff --git a/CMake/mitkFunctionCreateModule.cmake b/CMake/mitkFunctionCreateModule.cmake
index d4a4699813..6b56cc13c4 100644
--- a/CMake/mitkFunctionCreateModule.cmake
+++ b/CMake/mitkFunctionCreateModule.cmake
@@ -1,599 +1,602 @@
function(_link_directories_for_packages)
set(ALL_LIBRARY_DIRS )
foreach(package ${ARGN})
if(NOT ${package} MATCHES "^(Qt[45].*|ITK|VTK)$")
foreach(dir ${MODULES_PACKAGE_DEPENDS_DIRS})
if(EXISTS "${dir}/MITK_${package}_Config.cmake")
include("${dir}/MITK_${package}_Config.cmake")
break()
endif()
endforeach()
endif()
endforeach()
if(ALL_LIBRARY_DIRS)
list(REMOVE_DUPLICATES ALL_LIBRARY_DIRS)
link_directories(${ALL_LIBRARY_DIRS})
endif()
endfunction()
##################################################################
#
# mitk_create_module
#
#! Creates a module for the automatic module dependency system within MITK.
#! Configurations are generated in the moduleConf directory.
#!
#! USAGE:
#!
#! \code
#! MITK_CREATE_MODULE([<moduleName>]
#! [INCLUDE_DIRS <include directories>]
#! [INTERNAL_INCLUDE_DIRS <internally used include directories>]
#! [DEPENDS <modules we need>]
#! [PACKAGE_DEPENDS <packages we need, like ITK, VTK, QT>]
#! [TARGET_DEPENDS <list of additional dependencies>
#! [EXPORT_DEFINE <declspec macro name for dll exports>]
#! [QT_MODULE]
#! [HEADERS_ONLY]
#! [WARNINGS_AS_ERRORS]
#! \endcode
#!
#! The <moduleName> parameter specifies the name of the module which is used
#! create a logical target name. The parameter is options in case the
#! MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME variable evaluates to TRUE. The
#! module name will then be derived from the directory name in which this
#! macro is called.
#!
#! If set, the following variables will be used to validate the module name:
#!
#! MITK_MODULE_NAME_REGEX_MATCH The module name must match this regular expression.
#! MITK_MODULE_NAME_REGEX_NOT_MATCH The module name must not match this regular expression.
#!
#! If the MITK_MODULE_NAME_PREFIX variable is set, the module name will be prefixed
#! with its contents.
#!
#! A modules source files are specified in a separate CMake file usually
#! called files.cmake, located in the module root directory. The
#! mitk_create_module() macro evaluates the following CMake variables
#! from the files.cmake file:
#!
#! - CPP_FILES A list of .cpp files
#! - H_FILES A list of .h files without a corresponding .cpp file
#! - TXX_FILES A list of .txx files
#! - RESOURCE_FILES A list of files (resources) which are embedded into the module
#! - MOC_H_FILES A list of Qt header files which should be processed by the MOC
#! - UI_FILES A list of .ui Qt UI files
#! - QRC_FILES A list of .qrc Qt resource files
#! - DOX_FILES A list of .dox Doxygen files
#!
#! List of variables available after the function is called:
#! - MODULE_NAME
#! - MODULE_TARGET
#! - MODULE_IS_ENABLED
#! - MODULE_SUBPROJECTS
#! - ALL_META_DEPENDENCIES
#!
#! \param QT_MODULE deprecated. Just use Qt4 or Qt5 in the PACKAGE_DEPENDS argument.
#! \param HEADERS_ONLY specify this if the modules just contains header files.
##################################################################
function(mitk_create_module)
set(_macro_params
SUBPROJECTS # list of CDash labels
VERSION # module version number, e.g. "1.2.0"
INCLUDE_DIRS # exported include dirs (used in mitkMacroCreateModuleConf.cmake)
INTERNAL_INCLUDE_DIRS # include dirs internal to this module
DEPENDS # list of modules this module depends on
DEPENDS_INTERNAL # list of modules this module internally depends on
PACKAGE_DEPENDS # list of "packages this module depends on (e.g. Qt, VTK, etc.)
TARGET_DEPENDS # list of CMake targets this module should depend on
EXPORT_DEFINE # export macro name for public symbols of this module
AUTOLOAD_WITH # a module target name identifying the module which will trigger the
# automatic loading of this module
ADDITIONAL_LIBS # list of addidtional libraries linked to this module
FILES_CMAKE # file name of a CMake file setting source list variables
# (defaults to files.cmake)
GENERATED_CPP # not used (?)
DEPRECATED_SINCE # marks this modules as deprecated
DESCRIPTION # a description for this module
)
set(_macro_options
QT_MODULE # the module makes use of Qt4 features and needs moc and ui generated files
FORCE_STATIC # force building this module as a static library
HEADERS_ONLY # this module is a headers-only library
GCC_DEFAULT_VISIBILITY # do not use gcc visibility flags - all symbols will be exported
NO_INIT # do not create CppMicroServices initialization code
NO_FEATURE_INFO # do not create a feature info by calling add_feature_info()
WARNINGS_AS_ERRORS # treat all compiler warnings as errors
EXECUTABLE # create an executable; do not use directly, use mitk_create_executable() instead
)
MACRO_PARSE_ARGUMENTS(MODULE "${_macro_params}" "${_macro_options}" ${ARGN})
set(MODULE_NAME ${MODULE_DEFAULT_ARGS})
if(NOT MODULE_NAME)
if(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME)
get_filename_component(MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
else()
message(SEND_ERROR "The module name must not be empty")
endif()
endif()
if(MITK_MODULE_NAME_REGEX_MATCH)
if(NOT ${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_MATCH})
message(SEND_ERROR "The module name \"${MODULE_NAME}\" does not match the regular expression \"${MITK_MODULE_NAME_REGEX_MATCH}\".")
endif()
endif()
if(MITK_MODULE_NAME_REGEX_NOT_MATCH)
if(${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_NOT_MATCH})
message(SEND_ERROR "The module name \"${MODULE_NAME}\" must not match the regular expression \"${MITK_MODULE_NAME_REGEX_NOT_MATCH}\".")
endif()
endif()
if(MITK_MODULE_NAME_PREFIX AND NOT MODULE_NAME MATCHES "^${MITK_MODULE_NAME_PREFIX}.*$")
set(MODULE_NAME "${MITK_MODULE_NAME_PREFIX}${MODULE_NAME}")
endif()
if(NOT MODULE_FILES_CMAKE)
set(MODULE_FILES_CMAKE files.cmake)
endif()
if(NOT IS_ABSOLUTE ${MODULE_FILES_CMAKE})
set(MODULE_FILES_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FILES_CMAKE})
endif()
if (MODULE_QT_MODULE)
message(WARNING "QT_MODULE keyword is deprecated (in module ${MODULE_NAME}). Please use PACKAGE_DEPENDS Qt4|QtCore and/or PACKAGE_DEPENDS Qt5|Core instead")
if (NOT "${MODULE_PACKAGE_DEPENDS}" MATCHES "^.*Qt4.*$")
list(APPEND MODULE_PACKAGE_DEPENDS Qt4|QtGui)
endif()
endif()
if(MODULE_HEADERS_ONLY)
set(MODULE_TARGET )
if(MODULE_AUTOLOAD_WITH)
message(SEND_ERROR "A headers only module cannot be auto-loaded")
endif()
else()
set(MODULE_TARGET ${MODULE_NAME})
endif()
if(MODULE_DEPRECATED_SINCE)
set(MODULE_IS_DEPRECATED 1)
else()
set(MODULE_IS_DEPRECATED 0)
endif()
if(NOT MODULE_SUBPROJECTS)
if(MITK_DEFAULT_SUBPROJECTS)
set(MODULE_SUBPROJECTS ${MITK_DEFAULT_SUBPROJECTS})
endif()
endif()
# check if the subprojects exist as targets
if(MODULE_SUBPROJECTS)
foreach(subproject ${MODULE_SUBPROJECTS})
if(NOT TARGET ${subproject})
message(SEND_ERROR "The subproject ${subproject} does not have a corresponding target")
endif()
endforeach()
endif()
- # check and set-up auto-loading
- if(MODULE_AUTOLOAD_WITH)
- if(NOT TARGET "${MODULE_AUTOLOAD_WITH}")
- message(SEND_ERROR "The module target \"${MODULE_AUTOLOAD_WITH}\" specified as the auto-loading module for \"${MODULE_NAME}\" does not exist")
- endif()
- # create a meta-target if it does not already exist
- set(_module_autoload_meta_target "${MODULE_AUTOLOAD_WITH}-autoload")
- if(NOT TARGET ${_module_autoload_meta_target})
- add_custom_target(${_module_autoload_meta_target})
- endif()
- endif()
-
# assume worst case
set(MODULE_IS_ENABLED 0)
# first we check if we have an explicit module build list
if(MITK_MODULES_TO_BUILD)
list(FIND MITK_MODULES_TO_BUILD ${MODULE_NAME} _MOD_INDEX)
if(_MOD_INDEX EQUAL -1)
set(MODULE_IS_EXCLUDED 1)
endif()
endif()
if(NOT MODULE_IS_EXCLUDED)
# first of all we check for the dependencies
_mitk_parse_package_args(${MODULE_PACKAGE_DEPENDS})
mitk_check_module_dependencies(MODULES ${MODULE_DEPENDS}
PACKAGES ${PACKAGE_NAMES}
MISSING_DEPENDENCIES_VAR _MISSING_DEP
PACKAGE_DEPENDENCIES_VAR PACKAGE_NAMES)
if(_MISSING_DEP)
if(MODULE_NO_FEATURE_INFO)
message("Module ${MODULE_NAME} won't be built, missing dependency: ${_MISSING_DEP}")
endif()
set(MODULE_IS_ENABLED 0)
else()
set(MODULE_IS_ENABLED 1)
# now check for every package if it is enabled. This overlaps a bit with
# MITK_CHECK_MODULE ...
foreach(_package ${PACKAGE_NAMES})
if((DEFINED MITK_USE_${_package}) AND NOT (MITK_USE_${_package}))
message("Module ${MODULE_NAME} won't be built. Turn on MITK_USE_${_package} if you want to use it.")
set(MODULE_IS_ENABLED 0)
break()
endif()
endforeach()
if(MODULE_IS_ENABLED)
# clear variables defined in files.cmake
set(RESOURCE_FILES )
set(CPP_FILES )
set(H_FILES )
set(TXX_FILES )
set(DOX_FILES )
set(UI_FILES )
set(MOC_H_FILES )
set(QRC_FILES )
# clear other variables
set(Q${KITNAME}_GENERATED_CPP )
set(Q${KITNAME}_GENERATED_MOC_CPP )
set(Q${KITNAME}_GENERATED_QRC_CPP )
set(Q${KITNAME}_GENERATED_UI_CPP )
+ # check and set-up auto-loading
+ if(MODULE_AUTOLOAD_WITH)
+ if(NOT TARGET "${MODULE_AUTOLOAD_WITH}")
+ message(SEND_ERROR "The module target \"${MODULE_AUTOLOAD_WITH}\" specified as the auto-loading module for \"${MODULE_NAME}\" does not exist")
+ endif()
+ set(_module_autoload_meta_target "${MODULE_AUTOLOAD_WITH}-autoload")
+ # create a meta-target if it does not already exist
+ if(NOT TARGET ${_module_autoload_meta_target})
+ add_custom_target(${_module_autoload_meta_target})
+ endif()
+ endif()
+
# Convert relative include dirs to absolute dirs
set(_include_dirs . ${MODULE_INCLUDE_DIRS})
set(MODULE_INCLUDE_DIRS)
foreach(dir ${_include_dirs})
get_filename_component(_abs_dir ${dir} ABSOLUTE)
list(APPEND MODULE_INCLUDE_DIRS ${_abs_dir})
endforeach()
list(APPEND MODULE_INCLUDE_DIRS ${MITK_BINARY_DIR} ${MODULES_CONF_DIRS})
# Convert relative internal include dirs to absolute dirs
set(_include_dirs ${MODULE_INTERNAL_INCLUDE_DIRS})
set(MODULE_INTERNAL_INCLUDE_DIRS)
foreach(dir ${_include_dirs})
get_filename_component(_abs_dir ${dir} ABSOLUTE)
list(APPEND MODULE_INTERNAL_INCLUDE_DIRS ${_abs_dir})
endforeach()
# Qt generates headers in the binary tree
list(APPEND MODULE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
# Add the module specific include dirs
include_directories(${MODULE_INCLUDE_DIRS} ${MODULE_INTERNAL_INCLUDE_DIRS})
if(NOT MODULE_EXECUTABLE)
_MITK_CREATE_MODULE_CONF()
endif()
if(NOT MODULE_EXPORT_DEFINE)
set(MODULE_EXPORT_DEFINE ${MODULE_NAME}_EXPORT)
endif(NOT MODULE_EXPORT_DEFINE)
if(MITK_GENERATE_MODULE_DOT)
message("MODULEDOTNAME ${MODULE_NAME}")
foreach(dep ${MODULE_DEPENDS})
message("MODULEDOT \"${MODULE_NAME}\" -> \"${dep}\" ; ")
endforeach(dep)
endif(MITK_GENERATE_MODULE_DOT)
# ok, now create the module itself
include(${MODULE_FILES_CMAKE})
set(module_c_flags )
set(module_c_flags_debug )
set(module_c_flags_release )
set(module_cxx_flags )
set(module_cxx_flags_debug )
set(module_cxx_flags_release )
if(MODULE_GCC_DEFAULT_VISIBILITY)
set(use_visibility_flags 0)
else()
# We only support hidden visibility for gcc for now. Clang 3.0 still has troubles with
# correctly marking template declarations and explicit template instantiations as exported.
# See http://comments.gmane.org/gmane.comp.compilers.clang.scm/50028
# and http://llvm.org/bugs/show_bug.cgi?id=10113
if(CMAKE_COMPILER_IS_GNUCXX)
set(use_visibility_flags 1)
else()
# set(use_visibility_flags 0)
endif()
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
# MinGW does not export all symbols automatically, so no need to set flags.
#
# With gcc < 4.5, RTTI symbols from classes declared in third-party libraries
# which are not "gcc visibility aware" are marked with hidden visibility in
# DSOs which include the class declaration and which are compiled with
# hidden visibility. This leads to dynamic_cast and exception handling problems.
# While this problem could be worked around by sandwiching the include
# directives for the third-party headers between "#pragma visibility push/pop"
# statements, it is generally safer to just use default visibility with
# gcc < 4.5.
if(${GCC_VERSION} VERSION_LESS "4.5" OR MINGW)
set(use_visibility_flags 0)
endif()
endif()
if(use_visibility_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-fvisibility=hidden" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-fvisibility-inlines-hidden" module_c_flags module_cxx_flags)
endif()
configure_file(${MITK_SOURCE_DIR}/CMake/moduleExports.h.in ${CMAKE_BINARY_DIR}/${MODULES_CONF_DIRNAME}/${MODULE_NAME}Exports.h @ONLY)
if(MODULE_WARNINGS_AS_ERRORS)
if(MSVC_VERSION)
mitkFunctionCheckCAndCXXCompilerFlags("/WX" module_c_flags module_cxx_flags)
else()
mitkFunctionCheckCAndCXXCompilerFlags("-Werror" module_c_flags module_cxx_flags)
# The flag "c++0x-static-nonintegral-init" has been renamed in newer Clang
# versions to "static-member-init", see
# http://clang-developers.42468.n3.nabble.com/Wc-0x-static-nonintegral-init-gone-td3999651.html
#
# Also, older Clang and seemingly all gcc versions do not warn if unknown
# "-no-*" flags are used, so CMake will happily append any -Wno-* flag to the
# command line. This may get confusing if unrelated compiler errors happen and
# the error output then additionally contains errors about unknown flags (which
# is not the case if there were no compile errors).
#
# So instead of using -Wno-* we use -Wno-error=*, which will be properly rejected by
# the compiler and if applicable, prints the specific warning as a real warning and
# not as an error (although -Werror was given).
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=c++0x-static-nonintegral-init" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=static-member-init" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unknown-warning" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=gnu" module_c_flags module_cxx_flags)
# VNL headers throw a lot of these, not fixable for us at least in ITK 3
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unused-parameter" module_c_flags module_cxx_flags)
# Some DICOM header file in ITK
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=cast-align" module_c_flags module_cxx_flags)
endif()
endif(MODULE_WARNINGS_AS_ERRORS)
if(MODULE_FORCE_STATIC)
set(_STATIC STATIC)
else()
set(_STATIC )
endif(MODULE_FORCE_STATIC)
+ # create a meta-target for auto-loaded modules
+ add_custom_target(${MODULE_NAME}-autoload)
+
if(NOT MODULE_HEADERS_ONLY)
if(NOT MODULE_NO_INIT)
find_package(CppMicroServices QUIET NO_MODULE REQUIRED)
if(MODULE_EXECUTABLE)
usFunctionGenerateExecutableInit(CPP_FILES
IDENTIFIER ${MODULE_TARGET}
)
else()
usFunctionGenerateModuleInit(CPP_FILES
NAME ${MODULE_NAME}
LIBRARY_NAME ${MODULE_TARGET}
)
endif()
endif()
if(RESOURCE_FILES)
set(res_dir Resources)
set(binary_res_files )
set(source_res_files )
foreach(res_file ${RESOURCE_FILES})
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${res_dir}/${res_file})
list(APPEND binary_res_files "${res_file}")
else()
list(APPEND source_res_files "${res_file}")
endif()
endforeach()
set(res_macro_args )
if(binary_res_files)
list(APPEND res_macro_args ROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${res_dir}
FILES ${binary_res_files})
endif()
if(source_res_files)
list(APPEND res_macro_args ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${res_dir}
FILES ${source_res_files})
endif()
usFunctionEmbedResources(CPP_FILES
LIBRARY_NAME ${MODULE_TARGET}
${res_macro_args})
endif()
endif()
# Qt 4 case
if(MITK_USE_Qt4)
if(UI_FILES)
qt4_wrap_ui(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES})
endif()
if(MOC_H_FILES)
qt4_wrap_cpp(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES} OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
endif()
if(QRC_FILES)
qt4_add_resources(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES})
endif()
endif()
# all the same for Qt 5
if(MITK_USE_Qt5)
if(UI_FILES)
qt5_wrap_ui(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES})
endif()
if(MOC_H_FILES)
qt5_wrap_cpp(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES} OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
endif()
if(QRC_FILES)
qt5_add_resources(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES})
endif()
endif()
set(Q${KITNAME}_GENERATED_CPP ${Q${KITNAME}_GENERATED_CPP} ${Q${KITNAME}_GENERATED_UI_CPP} ${Q${KITNAME}_GENERATED_MOC_CPP} ${Q${KITNAME}_GENERATED_QRC_CPP})
ORGANIZE_SOURCES(SOURCE ${CPP_FILES}
HEADER ${H_FILES}
TXX ${TXX_FILES}
DOC ${DOX_FILES}
UI ${UI_FILES}
QRC ${QRC_FILES}
MOC ${Q${KITNAME}_GENERATED_MOC_CPP}
GEN_QRC ${Q${KITNAME}_GENERATED_QRC_CPP}
GEN_UI ${Q${KITNAME}_GENERATED_UI_CPP})
set(coverage_sources
${CPP_FILES} ${H_FILES} ${GLOBBED__H_FILES} ${CORRESPONDING__H_FILES} ${TXX_FILES}
${TOOL_CPPS} ${TOOL_GUI_CPPS})
if(MODULE_SUBPROJECTS)
set_property(SOURCE ${coverage_sources} APPEND PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK)
endif()
if(NOT MODULE_HEADERS_ONLY)
# We have to include the MITK_<package>_Config.cmake files here because
# some external packages do not provide exported targets with an
# absolute path to link to. So we need to add link directories *before*
# add_library() or add_executable() is called. So far, this is needed only
# for GDCM and ACVD.
_link_directories_for_packages(${PACKAGE_NAMES})
# Apply properties to the module target.
# We cannot use set_target_properties like below since there is no way to
# differentiate C/C++ and Releas/Debug flags using target properties.
# See http://www.cmake.org/Bug/view.php?id=6493
#set_target_properties(${MODULE_TARGET} PROPERTIES
# COMPILE_FLAGS "${module_compile_flags}")
#
# Strangely, we need to set the variables below in the parent scope
# (outside of the function) to be picked up by the target.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${module_c_flags}" PARENT_SCOPE)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${module_c_flags_debug}" PARENT_SCOPE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${module_c_flags_release}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${module_cxx_flags}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${module_cxx_flags_debug}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${module_cxx_flags_release}" PARENT_SCOPE)
if(MODULE_EXECUTABLE)
add_executable(${MODULE_TARGET}
${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP}
${DOX_FILES} ${UI_FILES} ${QRC_FILES})
else()
add_library(${MODULE_TARGET} ${_STATIC}
${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP}
${DOX_FILES} ${UI_FILES} ${QRC_FILES})
endif()
if(MODULE_TARGET_DEPENDS)
add_dependencies(${MODULE_TARGET} ${MODULE_TARGET_DEPENDS})
endif()
if(MODULE_SUBPROJECTS)
set_property(TARGET ${MODULE_TARGET} PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK)
foreach(subproject ${MODULE_SUBPROJECTS})
add_dependencies(${subproject} ${MODULE_TARGET})
endforeach()
endif()
set(DEPENDS "${MODULE_DEPENDS}")
if(NOT MODULE_NO_INIT)
# Add a CppMicroServices dependency implicitly, since it is
# needed for the generated "module initialization" code.
set(DEPENDS "CppMicroServices;${DEPENDS}")
endif()
if(DEPENDS OR MODULE_PACKAGE_DEPENDS)
mitk_use_modules(TARGET ${MODULE_TARGET}
MODULES ${DEPENDS}
PACKAGES ${MODULE_PACKAGE_DEPENDS}
)
endif()
if(MINGW)
target_link_libraries(${MODULE_TARGET} ssp) # add stack smash protection lib
endif()
# Add additional library search directories to a global property which
# can be evaluated by other CMake macros, e.g. our install scripts.
if(MODULE_ADDITIONAL_LIBS)
target_link_libraries(${MODULE_TARGET} ${MODULE_ADDITIONAL_LIBS})
get_property(_mitk_additional_library_search_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
foreach(_lib_filepath ${MODULE_ADDITIONAL_LIBS})
get_filename_component(_search_path "${_lib_filepath}" PATH)
if(_search_path)
list(APPEND _mitk_additional_library_search_paths "${_search_path}")
endif()
endforeach()
if(_mitk_additional_library_search_paths)
list(REMOVE_DUPLICATES _mitk_additional_library_search_paths)
set_property(GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS ${_mitk_additional_library_search_paths})
endif()
endif()
# add the target name to a global property which is used in the top-level
# CMakeLists.txt file to export the target
set_property(GLOBAL APPEND PROPERTY MITK_MODULE_TARGETS ${MODULE_TARGET})
if(MODULE_AUTOLOAD_WITH)
# for auto-loaded modules, adapt the output directory
add_dependencies(${_module_autoload_meta_target} ${MODULE_TARGET})
if(WIN32)
set(_module_output_prop RUNTIME_OUTPUT_DIRECTORY)
else()
set(_module_output_prop LIBRARY_OUTPUT_DIRECTORY)
endif()
set(_module_output_dir ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH})
get_target_property(_module_is_imported ${MODULE_AUTOLOAD_WITH} IMPORTED)
if(NOT _module_is_imported)
# if the auto-loading module is not imported, get its location
# and put the auto-load module relative to it.
get_target_property(_module_output_dir ${MODULE_AUTOLOAD_WITH} ${_module_output_prop})
set_target_properties(${MODULE_TARGET} PROPERTIES
${_module_output_prop} ${_module_output_dir}/${MODULE_AUTOLOAD_WITH})
else()
set_target_properties(${MODULE_TARGET} PROPERTIES
${_module_output_prop} ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH})
endif()
set_target_properties(${MODULE_TARGET} PROPERTIES
MITK_AUTOLOAD_DIRECTORY ${MODULE_AUTOLOAD_WITH})
# add the auto-load module name as a property
set_property(TARGET ${MODULE_AUTOLOAD_WITH} APPEND PROPERTY MITK_AUTOLOAD_TARGETS ${MODULE_TARGET})
endif()
endif()
endif()
endif()
endif()
if(NOT MODULE_IS_ENABLED AND NOT MODULE_EXECUTABLE)
_MITK_CREATE_MODULE_CONF()
endif()
if(_MISSING_DEP)
if(MODULE_DESCRIPTION)
set(MODULE_DESCRIPTION "${MODULE_DESCRIPTION} (missing dependencies: ${_MISSING_DEP})")
else()
set(MODULE_DESCRIPTION "(missing dependencies: ${_MISSING_DEP})")
endif()
endif()
if(NOT MODULE_NO_FEATURE_INFO)
add_feature_info(${MODULE_NAME} MODULE_IS_ENABLED "${MODULE_DESCRIPTION}")
endif()
set(MODULE_NAME ${MODULE_NAME} PARENT_SCOPE)
set(MODULE_TARGET ${MODULE_TARGET} PARENT_SCOPE)
set(MODULE_IS_ENABLED ${MODULE_IS_ENABLED} PARENT_SCOPE)
set(MODULE_SUBPROJECTS ${MODULE_SUBPROJECTS} PARENT_SCOPE)
set(ALL_META_DEPENDENCIES ${ALL_META_DEPENDENCIES} PARENT_SCOPE)
endfunction()
diff --git a/CMake/mitkFunctionExternalPythonBuildStep.cmake b/CMake/mitkFunctionExternalPythonBuildStep.cmake
new file mode 100644
index 0000000000..ad1e3b219f
--- /dev/null
+++ b/CMake/mitkFunctionExternalPythonBuildStep.cmake
@@ -0,0 +1,49 @@
+#! CMake function that runs a python build step from a setup.py script,
+#! e.g. python setup.py build. This is used to build external python
+#! libraries like numpy. The function takes the necessary build steps,
+#! python executable etc. as arguments. The specific build command executed
+#! by the runtime is passed as ARGN.
+#!
+#! params:
+#! proj - The name of the project
+#! step - Buildstep used to label the generated outputs, e.g. configure;build;install
+#! _python_executable - The python executable
+#! _bin_dir - The current binary from where commands are executed relative to it
+#! ARGN - Python command that will be run in the _bin_dir/proj-src folder
+#! e.g. setup.py build --someflags
+#!
+function(mitkFunctionExternalPythonBuildStep proj step _python_executable _bin_dir)
+
+ # the specific python build command run by this step
+ set(_command ${ARGN})
+
+ message("Running ${proj} ${step}:${_python_executable} ${_command}")
+
+ set(_workdir ${_bin_dir}/${proj}-src)
+ set(_prefixdir ${_bin_dir}/${proj}-cmake)
+ set(_python ${_python_executable})
+ # escape spaces
+ if(UNIX)
+ STRING(REPLACE " " "\ " _workdir ${_workdir})
+ STRING(REPLACE " " "\ " _prefixdir ${_prefixdir})
+ STRING(REPLACE " " "\ " _python ${_python})
+ endif()
+
+ execute_process(
+ COMMAND ${_python} ${_command}
+ WORKING_DIRECTORY ${_workdir}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE error
+ )
+ set(output_file "${_prefixdir}/${proj}_${step}_step_output.txt")
+ file(WRITE ${output_file} ${output})
+
+ set(error_file "${_prefixdir}/${proj}_${step}_step_error.txt")
+ file(WRITE ${error_file} ${error})
+
+ if(NOT ${result} EQUAL 0)
+ message(FATAL_ERROR "Error in: ${proj}: ${error}")
+ endif()
+endfunction()
+
diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake
index 6b3c31fb2f..60585b675e 100644
--- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake
+++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake
@@ -1,165 +1,177 @@
function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir)
set(_dir_candidates ${MITK_VTK_LIBRARY_DIRS} ${MITK_ITK_LIBRARY_DIRS}
"${MITK_BINARY_DIR}/bin" "${MITK_BINARY_DIR}/bin/plugins")
# Determine the Qt4/5 library installation prefix
set(_qmake_location )
if(MITK_USE_Qt4)
set(_qmake_location ${QT_QMAKE_EXECUTABLE})
elseif(MITK_USE_Qt5 AND TARGET ${Qt5Core_QMAKE_EXECUTABLE})
get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE}
PROPERTY IMPORT_LOCATION)
endif()
if(_qmake_location)
if(NOT _qt_install_libs)
if(WIN32)
execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS
OUTPUT_VARIABLE _qt_install_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS
OUTPUT_VARIABLE _qt_install_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs)
set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE)
endif()
if(_qt_install_libs)
list(APPEND _dir_candidates ${_qt_install_libs})
endif()
elseif(MITK_USE_QT)
message(WARNING "The qmake executable could not be found.")
endif()
get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
if(_additional_paths)
list(APPEND _dir_candidates ${_additional_paths})
endif()
if(VTK_DIR)
find_package(VTK QUIET)
if(VTK_RUNTIME_LIBRARY_DIRS)
list(APPEND _dir_candidates ${VTK_RUNTIME_LIBRARY_DIRS})
endif()
endif()
# The code below is sub-optimal. It makes assumptions about
# the structure of the build directories, pointed to by
# the *_DIR variables. Instead, we should rely on package
# specific "LIBRARY_DIRS" variables, if they exist.
if(WIN32)
if(DCMTK_DIR)
list(APPEND _dir_candidates "${DCMTK_DIR}/bin")
endif()
if(OpenCV_DIR)
list(APPEND _dir_candidates "${OpenCV_DIR}/bin")
endif()
if(SOFA_DIR)
list(APPEND _dir_candidates "${SOFA_DIR}/bin")
endif()
+ if(Python_DIR)
+ list(APPEND _dir_candidates "${Python_DIR}/bin")
+ endif()
+ if(SimpleITK_DIR)
+ list(APPEND _dir_candidates "${SimpleITK_DIR}/bin")
+ endif()
list(APPEND _dir_candidates "${ITK_DIR}/bin")
else()
if(DCMTK_DIR)
list(APPEND _dir_candidates "${DCMTK_DIR}/lib")
endif()
if(OpenCV_DIR)
list(APPEND _dir_candidates "${OpenCV_DIR}/lib")
endif()
if(SOFA_DIR)
list(APPEND _dir_candidates "${SOFA_DIR}/lib")
endif()
+ if(Python_DIR)
+ list(APPEND _dir_candidates "${Python_DIR}/lib")
+ endif()
+ if(SimpleITK_DIR)
+ list(APPEND _dir_candidates "${SimpleITK_DIR}/lib")
+ endif()
list(APPEND _dir_candidates "${ITK_DIR}/lib")
endif()
if(MITK_USE_Python AND CTK_PYTHONQT_INSTALL_DIR)
list(APPEND _dir_candidates "${CTK_PYTHONQT_INSTALL_DIR}/bin")
endif()
if(MITK_USE_Boost AND MITK_USE_Boost_LIBRARIES AND NOT MITK_USE_SYSTEM_Boost)
list(APPEND _dir_candidates "${Boost_LIBRARY_DIR}")
endif()
if(ACVD_DIR)
list(APPEND _dir_candidates "${ACVD_DIR}/bin")
endif()
if(ANN_DIR)
list(APPEND _dir_candidates "${ANN_DIR}")
endif()
if(CppUnit_DIR)
list(APPEND _dir_candidates "${CppUnit_DIR}")
endif()
if(GLUT_DIR)
list(APPEND _dir_candidates "${GLUT_DIR}")
endif()
if(GDCM_DIR)
list(APPEND _dir_candidates "${GDCM_DIR}/bin")
endif()
if(GLEW_DIR)
list(APPEND _dir_candidates "${GLEW_DIR}")
endif()
if(tinyxml_DIR)
list(APPEND _dir_candidates "${tinyxml_DIR}")
endif()
if(Poco_DIR)
list(APPEND _dir_candidates "${Poco_DIR}/lib")
endif()
if(Qwt_DIR)
list(APPEND _dir_candidates "${Qwt_DIR}")
endif()
if(Qxt_DIR)
list(APPEND _dir_candidates "${Qxt_DIR}")
endif()
if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD)
list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin")
endif()
if(MITK_USE_CTK)
list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}")
foreach(_ctk_library ${CTK_LIBRARIES})
if(${_ctk_library}_LIBRARY_DIRS)
list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}")
endif()
endforeach()
endif()
if(MITK_USE_BLUEBERRY)
if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY)
if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
else()
list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
endif()
endif()
endif()
if(MITK_LIBRARY_DIRS)
list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS})
endif()
list(REMOVE_DUPLICATES _dir_candidates)
set(_search_dirs )
foreach(_dir ${_dir_candidates})
if(EXISTS "${_dir}/${intermediate_dir}")
list(APPEND _search_dirs "${_dir}/${intermediate_dir}")
else()
list(APPEND _search_dirs "${_dir}")
endif()
endforeach()
# Special handling for "internal" search dirs. The intermediate directory
# might not have been created yet, so we can't check for its existence.
# Hence we just add it for Windows without checking.
set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins")
if(WIN32)
foreach(_dir ${_internal_search_dirs})
set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs})
endforeach()
else()
set(_search_dirs ${_internal_search_dirs} ${_search_dirs})
endif()
list(REMOVE_DUPLICATES _search_dirs)
set(${search_path} ${_search_dirs} PARENT_SCOPE)
endfunction()
diff --git a/CMake/mitkFunctionInstallPython.cmake b/CMake/mitkFunctionInstallPython.cmake
new file mode 100644
index 0000000000..d8ea8a74f5
--- /dev/null
+++ b/CMake/mitkFunctionInstallPython.cmake
@@ -0,0 +1,156 @@
+#! This CMake macro installs the python runtime with
+#! all python related libraries and toolkits. Py files are
+#! searched one by one with a globbing expression to generate a list used
+#! by the mac and NSIS installer.
+#!
+#! params:
+#! _python_libs Returns a list of the installed libraries. Used to fixup the bundle.
+#! _python_dirs Returns a list with the directories containig the dependencies
+#! to the installed libs.
+#! _app_bundle App bundle name in case of a Apple bundle.
+#!
+function(mitkFunctionInstallPython _python_libs_out _python_dirs_out _app_bundle)
+
+ # find package sets the python version numbers
+ find_package(PythonLibs REQUIRED)
+ find_package(PythonInterp REQUIRED)
+
+ set(_python_libs )
+ set(_python_dirs )
+ # set the destination bundle
+ set(_destination bin)
+ if(APPLE)
+ set(_destination ${_app_bundle})
+ endif()
+
+ if(UNIX)
+ # apple and linux only supports .so as loadable extension
+ set(PYTHON_LIB_SUFFIX .so)
+ set(_py_include_postfix python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/)
+ set(_python_runtime_dir lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
+ else(WIN32)
+ # windows only supports pyd as loadable extension
+ set(PYTHON_LIB_SUFFIX .pyd)
+ set(_py_include_postfix )
+ set(_python_runtime_dir Lib)
+ endif()
+
+ # install OpenCV python wrapping
+ if(MITK_USE_OpenCV)
+ list(APPEND _python_libs "cv2${PYTHON_LIB_SUFFIX}")
+
+ if(UNIX)
+ install(FILES "${OpenCV_DIR}/lib/cv2${PYTHON_LIB_SUFFIX}" DESTINATION ${_destination})
+ else()
+ install(FILES "${OpenCV_DIR}/lib/Release/cv2${PYTHON_LIB_SUFFIX}" DESTINATION ${_destination})
+ endif()
+
+ if(UNIX AND NOT APPLE)
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/cv2${CMAKE_SHARED_LIBRARY_SUFFIX}\")")
+ endif()
+
+ list(APPEND _python_dirs "${OpenCV_DIR}/lib")
+ endif()
+
+ # install VTK python wrapping
+ find_package(VTK REQUIRED)
+
+ set(_VTK_PYTHON_TARGETS )
+
+ # find all vtk python wrapped targets
+ foreach(_lib ${VTK_LIBRARIES})
+ # exclude system libs
+ if(${_lib} MATCHES "^vtk.+")
+ # use only python wrapped modules ( targets end with PythonD )
+ if(TARGET ${_lib}PythonD)
+ list(APPEND _VTK_PYTHON_TARGETS ${_lib}Python)
+ endif()
+ endif()
+ endforeach()
+
+ # install the python modules and loaders
+ foreach(_target ${_VTK_PYTHON_TARGETS})
+ # get the properties of the python wrapped target
+ if( CMAKE_BUILD_TYPE STREQUAL "Debug")
+ get_target_property(_target_lib "${_target}D" IMPORTED_LOCATION_DEBUG)
+ else()
+ get_target_property(_target_lib "${_target}D" IMPORTED_LOCATION_RELEASE)
+ endif()
+ get_filename_component(_filepath "${_target_lib}" PATH)
+
+ install(FILES "${_filepath}/${_target}${PYTHON_LIB_SUFFIX}" DESTINATION ${_destination})
+
+ if(UNIX AND NOT APPLE )
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/${_target}${PYTHON_LIB_SUFFIX}\")")
+ endif()
+ list(APPEND _python_libs "${_target}${PYTHON_LIB_SUFFIX}")
+ endforeach()
+
+ # install vtk python. This folder contains all *.py and
+ # *.pyc files for VTK module loading.
+ # glob through all files, NSIS can't use directories
+ file(GLOB_RECURSE item RELATIVE "${VTK_DIR}/Wrapping/Python/vtk" "${VTK_DIR}/Wrapping/Python/vtk/*.py*")
+ foreach(f ${item})
+ get_filename_component(_filepath "${f}" PATH)
+ install(FILES "${VTK_DIR}/Wrapping/Python/vtk/${f}" DESTINATION ${_destination}/Python/vtk/${_filepath})
+ endforeach()
+
+ list(APPEND _python_dirs "${VTK_DIR}/lib")
+
+ # install the python runtime from the superbuild
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ if(UNIX)
+ list(APPEND _python_dirs "${Python_DIR}/lib")
+ else() #WIN32
+ list(APPEND _python_dirs "${Python_DIR}/libs")
+ list(APPEND _python_dirs "${Python_DIR}/bin")
+ endif()
+
+ file(GLOB_RECURSE item RELATIVE "${Python_DIR}/${_python_runtime_dir}" "${Python_DIR}/${_python_runtime_dir}/*")
+ foreach(f ${item})
+ get_filename_component(_filepath "${f}" PATH)
+ install(FILES "${Python_DIR}/${_python_runtime_dir}/${f}" DESTINATION ${_destination}/Python/${_python_runtime_dir}/${_filepath})
+ endforeach()
+
+ # config will by read out at runtime
+ install(FILES "${Python_DIR}/include/${_py_include_postfix}pyconfig.h" DESTINATION ${_destination}/Python/include/${_py_include_postfix})
+
+ # add simple itk python wrapping file to the dependency list to resolve linked libraries
+ file(GLOB_RECURSE item RELATIVE "${Python_DIR}/${_python_runtime_dir}" "${Python_DIR}/${_python_runtime_dir}/_SimpleITK${PYTHON_LIB_SUFFIX}")
+ foreach(f ${item})
+ list(APPEND _python_libs "Python/${_python_runtime_dir}/${f}")
+ if(UNIX AND NOT APPLE)
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/Python/${_python_runtime_dir}/${f}\")")
+ endif()
+ endforeach()
+ else()
+ # Deploy the SimpleITK egg into the MITK installer
+ set(_sitk_userbase_install ${SimpleITK_DIR}/Wrapping/PythonPackage/${_python_runtime_dir}/site-packages)
+
+ # install everything in the userbase into Python/SimpleITK
+ file(GLOB_RECURSE item RELATIVE "${_sitk_userbase_install}" "${_sitk_userbase_install}/*")
+ foreach(f ${item})
+ get_filename_component(_filepath "${f}" PATH)
+ install(FILES "${_sitk_userbase_install}/${f}" DESTINATION ${_destination}/Python/SimpleITK/${_filepath})
+ endforeach()
+
+ # find and add the _SimpleITK library to the dependencies
+ file(GLOB_RECURSE item RELATIVE "${_sitk_userbase_install}" "${_sitk_userbase_install}/_SimpleITK${PYTHON_LIB_SUFFIX}")
+ foreach(f ${item})
+ list(APPEND _python_libs "Python/SimpleITK/${f}")
+ if(UNIX AND NOT APPLE)
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/Python/SimpleITK/${f}\")")
+ endif()
+ endforeach()
+ endif()
+
+ list(REMOVE_DUPLICATES _python_dirs)
+
+ set(${_python_libs_out} ${_python_libs} PARENT_SCOPE)
+ set(${_python_dirs_out} ${_python_dirs} PARENT_SCOPE)
+endfunction()
+
diff --git a/CMake/mitkInstallRules.cmake b/CMake/mitkInstallRules.cmake
index 39dde8eb41..e3cf7fbc4e 100644
--- a/CMake/mitkInstallRules.cmake
+++ b/CMake/mitkInstallRules.cmake
@@ -1,103 +1,100 @@
MITK_INSTALL(FILES "${MITK_SOURCE_DIR}/mitk.ico")
MITK_INSTALL(FILES "${MITK_SOURCE_DIR}/mitk.bmp")
# Install CTK Qt (designer) plugins
if(MITK_USE_CTK)
if(EXISTS ${CTK_QTDESIGNERPLUGINS_DIR})
set(_qtplugin_install_destinations)
if(MACOSX_BUNDLE_NAMES)
foreach(bundle_name ${MACOSX_BUNDLE_NAMES})
list(APPEND _qtplugin_install_destinations
${bundle_name}.app/Contents/MacOS/${_install_DESTINATION}/plugins/designer)
endforeach()
else()
list(APPEND _qtplugin_install_destinations bin/plugins/designer)
endif()
+ set(_ctk_qt_plugin_folder_release)
+ set(_ctk_qt_plugin_folder_debug)
if(NOT CMAKE_CFG_INTDIR STREQUAL ".")
- set(_matching_pattern_release FILES_MATCHING PATTERN "*Release*")
- set(_matching_pattern_debug FILES_MATCHING PATTERN "*Debug*")
- else()
- set(_matching_pattern_release )
- set(_matching_pattern_debug )
+ set(_ctk_qt_plugin_folder_release "Release/")
+ set(_ctk_qt_plugin_folder_debug "Debug/")
endif()
foreach(_qtplugin_install_dir ${_qtplugin_install_destinations})
- install(DIRECTORY "${CTK_QTDESIGNERPLUGINS_DIR}/designer/"
+ install(DIRECTORY "${CTK_QTDESIGNERPLUGINS_DIR}/designer/${_ctk_qt_plugin_folder_release}"
DESTINATION ${_qtplugin_install_dir}
CONFIGURATIONS Release
- ${_matching_pattern_release}
)
- install(DIRECTORY "${CTK_QTDESIGNERPLUGINS_DIR}/designer/"
+ install(DIRECTORY "${CTK_QTDESIGNERPLUGINS_DIR}/designer/${_ctk_qt_plugin_folder_debug}"
DESTINATION ${_qtplugin_install_dir}
CONFIGURATIONS Debug
- ${_matching_pattern_debug}
)
endforeach()
endif()
endif()
if(WIN32)
#DCMTK Dlls install target (shared libs on gcc only)
if(MINGW AND DCMTK_ofstd_LIBRARY)
set(_dcmtk_libs
${DCMTK_dcmdata_LIBRARY}
${DCMTK_dcmimgle_LIBRARY}
${DCMTK_dcmnet_LIBRARY}
${DCMTK_ofstd_LIBRARY}
)
foreach(_dcmtk_lib ${_dcmtk_libs})
MITK_INSTALL(FILES ${_dcmtk_lib} )
endforeach()
endif()
#BlueBerry
# Since this file is also included from external projects, you
# can only use variables which are made available through MITKConfig.cmake
if(MITK_USE_BLUEBERRY)
if(MINGW)
MITK_INSTALL(FILES "${MITK_BINARY_DIR}/bin/plugins/liborg_blueberry_osgi.dll")
else()
if(NOT APPLE)
MITK_INSTALL(FILES "${MITK_BINARY_DIR}/bin/plugins/debug/liborg_blueberry_osgi.dll" CONFIGURATIONS Debug)
MITK_INSTALL(FILES "${MITK_BINARY_DIR}/bin/plugins/release/liborg_blueberry_osgi.dll" CONFIGURATIONS Release)
endif(NOT APPLE)
endif()
endif()
#MinGW dll
if(MINGW)
find_library(MINGW_RUNTIME_DLL "mingwm10.dll" HINTS ${CMAKE_FIND_ROOT_PATH}/sys-root/mingw/bin)
if(MINGW_RUNTIME_DLL)
MITK_INSTALL(FILES ${MINGW_RUNTIME_DLL} )
else()
message(SEND_ERROR "Could not find mingwm10.dll which is needed for a proper install")
endif()
find_library(MINGW_GCC_RUNTIME_DLL "libgcc_s_dw2-1.dll" HINTS ${CMAKE_FIND_ROOT_PATH}/sys-root/mingw/bin)
if(MINGW_GCC_RUNTIME_DLL)
MITK_INSTALL(FILES ${MINGW_GCC_RUNTIME_DLL} )
else()
message(SEND_ERROR "Could not find libgcc_s_dw2-1.dll which is needed for a proper install")
endif()
endif()
else()
#DCMTK Dlls install target (shared libs on gcc only)
if(DCMTK_ofstd_LIBRARY)
set(_dcmtk_libs
${DCMTK_dcmdata_LIBRARY}
${DCMTK_dcmimgle_LIBRARY}
${DCMTK_dcmnet_LIBRARY}
${DCMTK_ofstd_LIBRARY}
)
foreach(_dcmtk_lib ${_dcmtk_libs})
#MITK_INSTALL(FILES ${_dcmtk_lib} DESTINATION lib)
endforeach()
endif()
endif()
diff --git a/CMake/mitkMacroInstall.cmake b/CMake/mitkMacroInstall.cmake
index 5efadc76c3..8385998d6b 100644
--- a/CMake/mitkMacroInstall.cmake
+++ b/CMake/mitkMacroInstall.cmake
@@ -1,177 +1,192 @@
#
# MITK specific install macro
#
# On Mac everything is installed for each bundle listed in MACOSX_BUNDLE_NAMES
# by replacing the DESTINATION parameter. Everything else is passed to the CMake INSTALL command
#
# Usage: MITK_INSTALL( )
#
macro(MITK_INSTALL)
set(ARGS ${ARGN})
set(install_directories "")
list(FIND ARGS DESTINATION _destination_index)
# set(_install_DESTINATION "")
if(_destination_index GREATER -1)
message(SEND_ERROR "MITK_INSTALL macro must not be called with a DESTINATION parameter.")
### This code was a try to replace a given DESTINATION
#math(EXPR _destination_index ${_destination_index} + 1)
#list(GET ARGS ${_destination_index} _install_DESTINATION)
#string(REGEX REPLACE ^bin "" _install_DESTINATION ${_install_DESTINATION})
else()
if(NOT MACOSX_BUNDLE_NAMES)
install(${ARGS} DESTINATION bin)
else()
foreach(bundle_name ${MACOSX_BUNDLE_NAMES})
install(${ARGS} DESTINATION ${bundle_name}.app/Contents/MacOS/${_install_DESTINATION})
endforeach()
endif()
endif()
endmacro()
# Fix _target_location
# This is used in several install macros
macro(_fixup_target)
if(NOT intermediate_dir)
if(WIN32 AND NOT MINGW)
set(intermediate_dir Release)
else()
set(intermediate_dir .)
endif()
endif()
+ set(_python_libs )
+ set(_python_dirs )
+ if(MITK_USE_Python)
+ include(mitkFunctionInstallPython)
+ mitkFunctionInstallPython(_python_libs _python_dirs "${_bundle_dest_dir}")
+ endif()
+
mitkFunctionGetLibrarySearchPaths(_search_paths ${intermediate_dir})
install(CODE "
set(_bundle_dest_dir \"${_bundle_dest_dir}\")
if(_bundle_dest_dir)
set(_bin_path \"\${CMAKE_INSTALL_PREFIX}/\${_bundle_dest_dir}\")
else()
set(_bin_path \"\${CMAKE_INSTALL_PREFIX}/bin\")
endif()
macro(gp_item_default_embedded_path_override item default_embedded_path_var)
get_filename_component(_item_name \"\${item}\" NAME)
get_filename_component(_item_path \"\${item}\" PATH)
# We have to fix all path references to build trees for plugins
if(NOT _item_path MATCHES \"\${CMAKE_INSTALL_PREFIX}/${_bundle_dest_dir}\")
# item with relative path or embedded path pointing to some build dir
set(full_path \"full_path-NOTFOUND\")
file(GLOB_RECURSE full_path \${CMAKE_INSTALL_PREFIX}/${_bundle_dest_dir}/\${_item_name} )
list(LENGTH full_path full_path_length)
if(full_path_length GREATER 1)
list(GET full_path 0 full_path)
endif()
get_filename_component(_item_path \"\${full_path}\" PATH)
endif()
set(_plugins_path \"\${_bin_path}/plugins\")
if(_item_path STREQUAL _plugins_path
OR (_item_path MATCHES \"\${_plugins_path}/\" AND _item_name MATCHES \"liborg\") # this is for legacy BlueBerry bundle support
)
# Only fix plugins
message(\"override: \${item}\")
message(\"found file: \${_item_path}/\${_item_name}\")
if(APPLE)
string(REPLACE
\${CMAKE_INSTALL_PREFIX}/${_bundle_dest_dir}
@executable_path \${default_embedded_path_var} \"\${_item_path}\" )
else()
set(\${default_embedded_path_var} \"\${_item_path}\")
endif()
message(\"override result: \${\${default_embedded_path_var}}\")
endif()
endmacro(gp_item_default_embedded_path_override)
macro(gp_resolved_file_type_override file type)
if(NOT APPLE)
get_filename_component(_file_path \"\${file}\" PATH)
get_filename_component(_file_name \"\${file}\" NAME)
if(_file_path MATCHES \"^\${CMAKE_INSTALL_PREFIX}\")
set(\${type} \"local\")
endif()
if(_file_name MATCHES gdiplus)
set(\${type} \"system\")
endif(_file_name MATCHES gdiplus)
endif()
endmacro(gp_resolved_file_type_override)
if(NOT APPLE)
macro(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var)
if(\${item} MATCHES \"blueberry_osgi\")
get_filename_component(_item_name \${item} NAME)
set(\${resolved_item_var} \"\${exepath}/plugins/\${_item_name}\")
set(\${resolved_var} 1)
endif()
endmacro()
endif()
if(\"${_install_GLOB_PLUGINS}\" STREQUAL \"TRUE\")
set(GLOBBED_PLUGINS )
set(_bb_osgi_lib \"\${_bin_path}/liborg_blueberry_osgi${CMAKE_SHARED_LIBRARY_SUFFIX}\")
if(EXISTS \"\${_bb_osgi_lib}\")
list(APPEND GLOBBED_PLUGINS \"\${_bb_osgi_lib}\")
endif()
# Iterate over all sub-directories which contain plug-ins
# (BlueBerry plug-ins, Qt plug-ins, and auto-load modules)
file(GLOB _children \"\${_bin_path}/*\")
foreach(_child \${_children})
if(IS_DIRECTORY \${_child})
set(_plugins )
set(_modules )
file(GLOB_RECURSE _plugins \"\${_child}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
if(_plugins)
list(APPEND GLOBBED_PLUGINS \${_plugins})
endif()
# Now glob for all modules which might have a different extensions.
# E.g. on MacOS plugins could have a .dylib extension as well as a .so extension
if(NOT \"${CMAKE_SHARED_MODULE_SUFFIX}\" STREQUAL \"\" AND NOT \"${CMAKE_SHARED_MODULE_SUFFIX}\" STREQUAL \"${CMAKE_SHARED_LIBRARY_SUFFIX}\")
file(GLOB_RECURSE _modules \"\${_child}/*${CMAKE_SHARED_MODULE_SUFFIX}\")
endif()
if(_modules)
list(APPEND GLOBBED_PLUGINS \${_modules})
endif()
endif()
endforeach()
endif()
set(PLUGINS )
foreach(_plugin ${_install_PLUGINS} \${GLOBBED_PLUGINS})
get_filename_component(_plugin_realpath \${_plugin} REALPATH)
list(APPEND PLUGINS \${_plugin_realpath})
endforeach()
+ foreach(_py_lib ${_python_libs})
+ list(APPEND PLUGINS \"\${_bin_path}/\${_py_lib}\")
+ endforeach()
+
if(PLUGINS)
list(REMOVE_DUPLICATES PLUGINS)
endif(PLUGINS)
message(\"globbed plugins: \${PLUGINS}\")
set(CMAKE_MODULE_PATH ${MITK_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH} )
set(DIRS \"${_search_paths}\")
set(_additional_search_paths ${_install_LIBRARY_DIRS})
if(_additional_search_paths)
set(DIRS \"\${DIRS};\${_additional_search_paths}\")
endif()
foreach(_plugin \${PLUGINS})
get_filename_component(_pluginpath \${_plugin} PATH)
list(APPEND DIRS \"\${_pluginpath}\")
endforeach(_plugin)
+ foreach(_dir ${_python_dirs})
+ list(APPEND DIRS \"\${_dir}\")
+ endforeach()
+
list(REMOVE_DUPLICATES DIRS)
# use custom version of BundleUtilities
include(BundleUtilities)
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${_target_location}\" \"\${PLUGINS}\" \"\${DIRS}\")
")
endmacro()
diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake
index 0cfc835d01..14bd3c0c93 100644
--- a/CMakeExternals/CTK.cmake
+++ b/CMakeExternals/CTK.cmake
@@ -1,95 +1,98 @@
#-----------------------------------------------------------------------------
# CTK
#-----------------------------------------------------------------------------
if(MITK_USE_CTK)
# Sanity checks
if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR})
message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj CTK)
set(proj_DEPENDENCIES )
set(CTK_DEPENDS ${proj})
if(NOT DEFINED CTK_DIR)
- set(revision_tag 1dd16ae7)
+ set(revision_tag fd3ecf96)
#IF(${proj}_REVISION_TAG)
# SET(revision_tag ${${proj}_REVISION_TAG})
#ENDIF()
set(ctk_optional_cache_args )
if(MITK_USE_Python)
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python)
+ endif()
list(APPEND ctk_optional_cache_args
-DCTK_LIB_Scripting/Python/Widgets:BOOL=ON
-DCTK_ENABLE_Python_Wrapping:BOOL=ON
-DCTK_APP_ctkSimplePythonShell:BOOL=ON
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
)
else()
list(APPEND ctk_optional_cache_args
-DCTK_LIB_Scripting/Python/Widgets:BOOL=OFF
-DCTK_ENABLE_Python_Wrapping:BOOL=OFF
-DCTK_APP_ctkSimplePythonShell:BOOL=OFF
)
endif()
if(MITK_USE_DCMTK)
list(APPEND ctk_optional_cache_args
-DDCMTK_DIR:PATH=${DCMTK_DIR}
)
list(APPEND proj_DEPENDENCIES DCMTK)
else()
list(APPEND ctk_optional_cache_args
-DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz
)
endif()
FOREACH(type RUNTIME ARCHIVE LIBRARY)
IF(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY)
LIST(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY})
ENDIF()
ENDFOREACH()
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz
- URL_MD5 03438db5c9a8324deb45d82c8a27784c
+ URL_MD5 a33be5c622fee05179c55e67a7d1b9cf
UPDATE_COMMAND ""
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${ctk_optional_cache_args}
-DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION}
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
-DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}
-DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}
-DCTK_LIB_CommandLineModules/Backend/LocalProcess:BOOL=ON
-DCTK_LIB_CommandLineModules/Frontend/QtGui:BOOL=ON
-DCTK_LIB_PluginFramework:BOOL=ON
-DCTK_LIB_DICOM/Widgets:BOOL=ON
-DCTK_LIB_XNAT/Core:BOOL=ON
-DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON
-DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON
-DCTK_USE_GIT_PROTOCOL:BOOL=OFF
-DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz
-DqRestAPI_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/qRestAPI_5f3a03b1.tar.gz
DEPENDS ${proj_DEPENDENCIES}
)
set(CTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
endif()
diff --git a/CMakeExternals/CableSwig.cmake b/CMakeExternals/CableSwig.cmake
deleted file mode 100644
index 73cc64f959..0000000000
--- a/CMakeExternals/CableSwig.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-#-----------------------------------------------------------------------------
-# CableSwig
-#-----------------------------------------------------------------------------
-
-if(MITK_USE_Python)
-
-# Sanity checks
-if(DEFINED CableSwig_DIR AND NOT EXISTS ${CableSwig_DIR})
- message(FATAL_ERROR "CableSwig_DIR variable is defined but corresponds to non-existing directory")
-endif()
-
-set(proj CableSwig)
-set(proj_DEPENDENCIES )
-set(CableSwig_DEPENDS ${proj})
-
-if(NOT DEFINED CableSwig_DIR)
-
- set(additional_cmake_args )
-
- ExternalProject_Add(${proj}
- SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
- BINARY_DIR ${proj}-build
- PREFIX ${proj}-cmake
- URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CableSwig-ITK-3.20.0-v2.tar.gz
- URL_MD5 893882bf8b4fbfbae3fe8c747a75f7a0
- INSTALL_COMMAND ""
- CMAKE_GENERATOR ${gen}
- CMAKE_ARGS
- ${ep_common_args}
- ${additional_cmake_args}
- -DBUILD_TESTING:BOOL=OFF
- -DSWIG_BUILD_EXAMPLES:BOOL=OFF
- DEPENDS ${proj_DEPENDENCIES}
- )
-
- set(CableSwig_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
-
-else()
-
- mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
-
-endif()
-
-endif()
diff --git a/CMakeExternals/ITK.cmake b/CMakeExternals/ITK.cmake
index 2dde71437d..779cfb7ec8 100644
--- a/CMakeExternals/ITK.cmake
+++ b/CMakeExternals/ITK.cmake
@@ -1,98 +1,72 @@
#-----------------------------------------------------------------------------
# ITK
#-----------------------------------------------------------------------------
# Sanity checks
if(DEFINED ITK_DIR AND NOT EXISTS ${ITK_DIR})
message(FATAL_ERROR "ITK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj ITK)
set(proj_DEPENDENCIES GDCM)
-if(MITK_USE_Python)
- list(APPEND proj_DEPENDENCIES CableSwig)
-endif()
+
if(MITK_USE_OpenCV)
list(APPEND proj_DEPENDENCIES OpenCV)
endif()
set(ITK_DEPENDS ${proj})
if(NOT DEFINED ITK_DIR)
set(additional_cmake_args )
if(MINGW)
set(additional_cmake_args
-DCMAKE_USE_WIN32_THREADS:BOOL=ON
-DCMAKE_USE_PTHREADS:BOOL=OFF)
endif()
- if(MITK_USE_Python)
-
- list(APPEND additional_cmake_args
- -DITK_WRAPPING:BOOL=ON
- -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
- -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
- -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
- -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
- #-DPYTHON_LIBRARIES=${PYTHON_LIBRARY}
- #-DPYTHON_DEBUG_LIBRARIES=${PYTHON_DEBUG_LIBRARIES}
- -DCableSwig_DIR:PATH=${CableSwig_DIR}
- #-DITK_WRAP_JAVA:BOOL=OFF
- -DITK_WRAP_unsigned_char:BOOL=ON
- #-DITK_WRAP_double:BOOL=ON
- -DITK_WRAP_rgb_unsigned_char:BOOL=ON
- #-DITK_WRAP_rgba_unsigned_char:BOOL=ON
- -DITK_WRAP_signed_char:BOOL=ON
- #-DWRAP_signed_long:BOOL=ON
- -DITK_WRAP_signed_short:BOOL=ON
- -DITK_WRAP_short:BOOL=ON
- -DITK_WRAP_unsigned_long:BOOL=ON
- )
- else()
- list(APPEND additional_cmake_args
- -DUSE_WRAP_ITK:BOOL=OFF
- )
- endif()
+ list(APPEND additional_cmake_args
+ -DUSE_WRAP_ITK:BOOL=OFF
+ )
if(MITK_USE_OpenCV)
list(APPEND additional_cmake_args
-DModule_ITKVideoBridgeOpenCV:BOOL=ON
-DOpenCV_DIR:PATH=${OpenCV_DIR}
)
endif()
# Keep the behaviour of ITK 4.3 which by default turned on ITK Review
# see MITK bug #17338
list(APPEND additional_cmake_args
-DModule_ITKReview:BOOL=ON
)
set(ITK_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchITK-4.5.1.cmake)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/InsightToolkit-4.5.1-3e550bf8.tar.gz
URL_MD5 80e433ffc0e81cdc19a03dd02a3c329b
INSTALL_COMMAND ""
PATCH_COMMAND ${ITK_PATCH_COMMAND}
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${additional_cmake_args}
-DBUILD_TESTING:BOOL=OFF
-DBUILD_EXAMPLES:BOOL=OFF
-DITK_USE_SYSTEM_GDCM:BOOL=ON
-DGDCM_DIR:PATH=${GDCM_DIR}
DEPENDS ${proj_DEPENDENCIES}
)
set(ITK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
diff --git a/CMakeExternals/MITKData.cmake b/CMakeExternals/MITKData.cmake
index bee95e81b3..e764edaba2 100644
--- a/CMakeExternals/MITKData.cmake
+++ b/CMakeExternals/MITKData.cmake
@@ -1,36 +1,36 @@
#-----------------------------------------------------------------------------
# MITK Data
#-----------------------------------------------------------------------------
# Sanity checks
if(DEFINED MITK_DATA_DIR AND NOT EXISTS ${MITK_DATA_DIR})
message(FATAL_ERROR "MITK_DATA_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj MITK-Data)
set(proj_DEPENDENCIES)
set(MITK-Data_DEPENDS ${proj})
if(BUILD_TESTING)
- set(revision_tag 3be15a2d)
+ set(revision_tag acedec01)
# ^^^^^^^^ these are just to check correct length of hash part
ExternalProject_Add(${proj}
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/MITK-Data_${revision_tag}.tar.gz
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
DEPENDS ${proj_DEPENDENCIES}
)
set(MITK_DATA_DIR ${ep_source_dir}/${proj})
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif(BUILD_TESTING)
diff --git a/CMakeExternals/Numpy.cmake b/CMakeExternals/Numpy.cmake
new file mode 100644
index 0000000000..dffe0fc642
--- /dev/null
+++ b/CMakeExternals/Numpy.cmake
@@ -0,0 +1,100 @@
+#-----------------------------------------------------------------------------
+# Numpy
+#-----------------------------------------------------------------------------
+if( MITK_USE_Python AND NOT MITK_USE_SYSTEM_PYTHON )
+ # Sanity checks
+ if(DEFINED Numpy_DIR AND NOT EXISTS ${Numpy_DIR})
+ message(FATAL_ERROR "Numpy_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ if( NOT DEFINED Numpy_DIR )
+ set(proj Numpy)
+ set(${proj}_DEPENDENCIES Python)
+ set(Numpy_DEPENDS ${proj})
+
+ # setup build environment and disable fortran, blas and lapack
+ set(_numpy_env
+ "
+ set(ENV{F77} \"\")
+ set(ENV{F90} \"\")
+ set(ENV{FFLAGS} \"\")
+ set(ENV{ATLAS} \"None\")
+ set(ENV{BLAS} \"None\")
+ set(ENV{LAPACK} \"None\")
+ set(ENV{MKL} \"None\")
+ set(ENV{VS_UNICODE_OUTPUT} \"\")
+ set(ENV{CC} \"${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}\")
+ set(ENV{CFLAGS} \"${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}\")
+ set(ENV{CXX} \"${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}\")
+ set(ENV{CXXFLAGS} \"${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}\")
+ set(ENV{LDFLAGS} \"${CMAKE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS_RELEASE}\")
+
+ ")
+
+ set(_numpy_build_step ${MITK_SOURCE_DIR}/CMake/mitkFunctionExternalPythonBuildStep.cmake)
+
+ set(_configure_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_configure_step.cmake)
+ file(WRITE ${_configure_step}
+ "${_numpy_env}
+ include(\"${_numpy_build_step}\")
+ file(WRITE \"${CMAKE_BINARY_DIR}/${proj}-src/site.cfg\" \"\")
+ mitkFunctionExternalPythonBuildStep(${proj} configure \"${PYTHON_EXECUTABLE}\" \"${CMAKE_BINARY_DIR}\" setup.py config)
+ ")
+
+ # build step
+ set(_build_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_build_step.cmake)
+ file(WRITE ${_build_step}
+ "${_numpy_env}
+ include(\"${_numpy_build_step}\")
+ mitkFunctionExternalPythonBuildStep(${proj} build \"${PYTHON_EXECUTABLE}\" \"${CMAKE_BINARY_DIR}\" setup.py build --fcompiler=none)
+ ")
+
+ # install step
+ set(_install_dir "${Python_DIR}")
+ if(WIN32)
+ STRING(REPLACE "/" "\\\\" _install_dir ${Python_DIR})
+ endif()
+ # escape spaces in install path
+ STRING(REPLACE " " "\\ " _install_dir ${_install_dir})
+
+ set(_install_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_install_step.cmake)
+ file(WRITE ${_install_step}
+ "${_numpy_env}
+ include(\"${_numpy_build_step}\")
+ mitkFunctionExternalPythonBuildStep(${proj} install \"${PYTHON_EXECUTABLE}\" \"${CMAKE_BINARY_DIR}\" setup.py install --prefix=${_install_dir})
+ ")
+
+ set(Numpy_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/numpy-1.4.1.tar.gz)
+ set(Numpy_MD5 "5c7b5349dc3161763f7f366ceb96516b")
+
+ # escape spaces
+ if(UNIX)
+ STRING(REPLACE " " "\ " _configure_step ${_configure_step})
+ STRING(REPLACE " " "\ " _build_step ${_build_step})
+ STRING(REPLACE " " "\ " _install_step ${_install_step})
+ endif()
+
+ set(NUMPY_PATCH_COMMAND PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${CMAKE_CURRENT_LIST_DIR}/Patch${proj}.cmake)
+
+ ExternalProject_Add(${proj}
+ URL ${Numpy_URL}
+ URL_MD5 ${Numpy_MD5}
+ SOURCE_DIR ${proj}-src
+ ${NUMPY_PATCH_COMMAND}
+ PREFIX ${proj}-cmake
+ BUILD_IN_SOURCE 1
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -P ${_configure_step}
+ BUILD_COMMAND ${CMAKE_COMMAND} -P ${_build_step}
+ INSTALL_COMMAND ${CMAKE_COMMAND} -P ${_install_step}
+
+ DEPENDS
+ ${${proj}_DEPENDENCIES}
+ )
+
+ set(Numpy_DIR ${MITK_PYTHON_SITE_DIR}/numpy)
+
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+ endif()
+endif()
+
diff --git a/CMakeExternals/OpenCV.cmake b/CMakeExternals/OpenCV.cmake
index 6df5c6522c..77dd1d3942 100644
--- a/CMakeExternals/OpenCV.cmake
+++ b/CMakeExternals/OpenCV.cmake
@@ -1,92 +1,97 @@
#-----------------------------------------------------------------------------
# OpenCV
#-----------------------------------------------------------------------------
if(MITK_USE_OpenCV)
# Sanity checks
if(DEFINED OpenCV_DIR AND NOT EXISTS ${OpenCV_DIR})
message(FATAL_ERROR "OpenCV_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj OpenCV)
set(proj_DEPENDENCIES)
set(OpenCV_DEPENDS ${proj})
if(NOT DEFINED OpenCV_DIR)
set(additional_cmake_args
-DBUILD_opencv_java:BOOL=OFF
-DBUILD_opencv_ts:BOOL=OFF
-DBUILD_PERF_TESTS:BOOL=OFF
)
if(MITK_USE_Python)
#message(STATUS "PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}")
#message(STATUS "PYTHON_DEBUG_LIBRARY: ${PYTHON_DEBUG_LIBRARY}")
#message(STATUS "PYTHON_INCLUDE_DIR: ${PYTHON_INCLUDE_DIR}")
#message(STATUS "PYTHON_LIBRARY: ${PYTHON_LIBRARY}")
-
list(APPEND additional_cmake_args
-DBUILD_opencv_python:BOOL=ON
-DBUILD_NEW_PYTHON_SUPPORT:BOOL=ON
-DPYTHON_DEBUG_LIBRARY:FILEPATH=${PYTHON_DEBUG_LIBRARY}
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
+
#-DPYTHON_LIBRARIES=${PYTHON_LIBRARY}
#-DPYTHON_DEBUG_LIBRARIES=${PYTHON_DEBUG_LIBRARIES}
)
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python Numpy)
+ # export python home
+ set(ENV{PYTHONHOME} "${Python_DIR}")
+ endif()
else()
list(APPEND additional_cmake_args
-DBUILD_opencv_python:BOOL=OFF
-DBUILD_NEW_PYTHON_SUPPORT:BOOL=OFF
)
endif()
# 12-05-02, muellerm, added QT usage by OpenCV if QT is used in MITK
# 12-09-11, muellerm, removed automatic usage again, since this will struggle with the MITK Qt application object
if(MITK_USE_QT)
list(APPEND additional_cmake_args
-DWITH_QT:BOOL=OFF
-DWITH_QT_OPENGL:BOOL=OFF
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
)
endif()
set(OpenCV_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchOpenCV-2.4.8.2.cmake)
set(opencv_url ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/OpenCV-2.4.8.2.tar.gz)
set(opencv_url_md5 07fa7c1d225ea7fe8eeb1270a6b00e69)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${opencv_url}
URL_MD5 ${opencv_url_md5}
INSTALL_COMMAND ""
PATCH_COMMAND ${OpenCV_PATCH_COMMAND}
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
-DBUILD_DOCS:BOOL=OFF
-DBUILD_TESTS:BOOL=OFF
-DBUILD_EXAMPLES:BOOL=OFF
-DBUILD_DOXYGEN_DOCS:BOOL=OFF
-DWITH_CUDA:BOOL=ON
${additional_cmake_args}
DEPENDS ${proj_DEPENDENCIES}
)
set(OpenCV_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
endif()
diff --git a/CMakeExternals/PCRE.cmake b/CMakeExternals/PCRE.cmake
new file mode 100644
index 0000000000..6b2dc67d1d
--- /dev/null
+++ b/CMakeExternals/PCRE.cmake
@@ -0,0 +1,35 @@
+#--------------------------------------------------------------------------
+# PCRE (Perl Compatible Regular Expressions)
+#--------------------------------------------------------------------------
+if(MITK_USE_PCRE)
+ if(DEFINED PCRE_DIR AND NOT EXISTS ${PCRE_DIR})
+ message(FATAL_ERROR "PCRE_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+ if(NOT PCRE_DIR)
+
+ set(proj PCRE)
+ set(${proj}_DEPENDENCIES "")
+ set(PCRE_TARGET_VERSION 8.35)
+
+ ExternalProject_add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/pcre-8.35.tar.gz
+ URL_MD5 "ed58bcbe54d3b1d59e9f5415ef45ce1c"
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build
+ INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install
+ PREFIX ${proj}-cmake
+ CONFIGURE_COMMAND <SOURCE_DIR>/./configure
+ CC=${CMAKE_C_COMPILER}${CMAKE_C_COMPILER_ARG1}
+ LDFLAGS=${CMAKE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS_RELEASE}
+ CXX=${CMAKE_CXX_COMPILER}${CMAKE_CXX_COMPILER_ARG1}
+ --prefix=<INSTALL_DIR>
+ --disable-shared
+ DEPENDS "${${proj}_DEPENDENCIES}"
+ )
+
+ set(PCRE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install)
+
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${${proj}_DEPENDENCIES}")
+ endif()
+endif()
diff --git a/CMakeExternals/PatchNumpy.cmake b/CMakeExternals/PatchNumpy.cmake
new file mode 100644
index 0000000000..44d0f0cc8d
--- /dev/null
+++ b/CMakeExternals/PatchNumpy.cmake
@@ -0,0 +1,7 @@
+if(WIN32)
+ set(path "numpy/core/setup_common.py")
+ file(STRINGS ${path} contents NEWLINE_CONSUME)
+ string(REPLACE "fid = open(filename, 'r')" "fid = open(filename, 'rb')" contents ${contents})
+ set(CONTENTS ${contents})
+ configure_file(${TEMPLATE_FILE} ${path} @ONLY)
+endif()
diff --git a/CMakeExternals/PatchPython.cmake b/CMakeExternals/PatchPython.cmake
new file mode 100644
index 0000000000..770f51c805
--- /dev/null
+++ b/CMakeExternals/PatchPython.cmake
@@ -0,0 +1,19 @@
+#
+# Windows python 2.7.3 patches for the CMake build system
+# https://github.com/davidsansome/python-cmake-buildsystem/tree/master/cmake/patches-win32
+#
+set(path "Lib/distutils/msvc9compiler.py")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "self.manifest_get_embed_info(target_desc, ld_args)" "None" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
+
+set(path "Lib/distutils/cygwinccompiler.py")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "return ['msvcr90']" "return ['msvcr90']
+ elif msc_ver == '1600':
+ return ['msvcr100']
+ elif msc_ver == '1700':
+ return ['msvcr120']" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
diff --git a/CMakeExternals/PatchPythonCMake.cmake b/CMakeExternals/PatchPythonCMake.cmake
new file mode 100644
index 0000000000..5a1349af97
--- /dev/null
+++ b/CMakeExternals/PatchPythonCMake.cmake
@@ -0,0 +1,6 @@
+# fix to build python on i686 and i386 with the python cmake build system, the x86 path must be set as default
+set(path "cmake/extensions/CMakeLists.txt")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "set(_libffi_system_dir \${CMAKE_SYSTEM_PROCESSOR})" "set(_libffi_system_dir \"x86\")" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
diff --git a/CMakeExternals/PatchSimpleITK.cmake b/CMakeExternals/PatchSimpleITK.cmake
new file mode 100644
index 0000000000..185fad393d
--- /dev/null
+++ b/CMakeExternals/PatchSimpleITK.cmake
@@ -0,0 +1,18 @@
+# Called by ITK.cmake (ExternalProject_Add) as a patch for ITK to work with external GDCM 2.2.1
+# and remove all itk video libs to resolve external windows linker errors with opencv
+
+set(path "CMakeLists.txt")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "ITK_LIBRARY_DIRS}\")" "ITK_LIBRARY_DIRS}\" \"\${GDCM_DIR}/bin\")
+ list(REMOVE_ITEM ITK_LIBRARIES ITKVideoBridgeOpenCV ITKVideoCore ITKVideoIO)" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
+
+# fix for double import targets
+set(path "SimpleITKConfig.cmake.in")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "if(NOT ITK_TARGETS_IMPORTED)" "if(NOT TARGET ITKCommon)" contents ${contents})
+set(CONTENTS ${contents})
+string(REPLACE "if(NOT SimpleITK_TARGETS_IMPORTED)" "if(NOT TARGET SimpleITKCommon)" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
diff --git a/CMakeExternals/Python.cmake b/CMakeExternals/Python.cmake
new file mode 100644
index 0000000000..556fc8f946
--- /dev/null
+++ b/CMakeExternals/Python.cmake
@@ -0,0 +1,191 @@
+#----------------------------------------------------------------------
+# Python
+#----------------------------------------------------------------------
+if( MITK_USE_Python AND NOT MITK_USE_SYSTEM_PYTHON )
+ # Sanity checks
+ if(DEFINED Python_DIR AND NOT EXISTS ${Python_DIR})
+ message(FATAL_ERROR "Python_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ if(NOT DEFINED Python_DIR)
+ set(proj Python)
+ set(Python_DEPENDENCIES ZLIB Python-src)
+ set(Python_DEPENDS ${proj})
+
+ set(MITK_PYTHON_MAJOR_VERSION 2)
+ set(MITK_PYTHON_MINOR_VERSION 7)
+ set(MITK_PYTHON_PATCH_VERSION 3)
+
+ set(PYTHON_SOURCE_PACKAGE Python-${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}.${MITK_PYTHON_PATCH_VERSION})
+ set(PYTHON_SOURCE_DIR "${CMAKE_BINARY_DIR}/${PYTHON_SOURCE_PACKAGE}")
+ # patch the VS compiler config
+
+ set(PYTHON_PATCH_COMMAND PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${CMAKE_CURRENT_LIST_DIR}/Patch${proj}.cmake)
+
+ # download the source code
+ ExternalProject_Add(Python-src
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/${PYTHON_SOURCE_PACKAGE}.tgz
+ URL_MD5 "2cf641732ac23b18d139be077bd906cd"
+ PREFIX ${CMAKE_BINARY_DIR}/${PYTHON_SOURCE_PACKAGE}-cmake
+ SOURCE_DIR "${PYTHON_SOURCE_DIR}"
+ ${PYTHON_PATCH_COMMAND}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+
+ set(additional_cmake_cache_args )
+ list(APPEND additional_cmake_cache_args
+ -DBUILTIN_ARRAY:BOOL=ON
+ -DBUILTIN_AUDIOOP:BOOL=ON
+ -DBUILTIN_BINASCII:BOOL=ON
+ -DBUILTIN_BISECT:BOOL=ON
+ -DBUILTIN_BSDB:BOOL=ON
+ -DBUILTIN_BSSDB:BOOL=ON
+ -DBUILTIN_BZ2:BOOL=ON
+ -DBUILTIN_CMATH:BOOL=ON
+ -DBUILTIN_COLLECTIONS:BOOL=ON
+ -DBUILTIN_CODECS_CN:BOOL=ON
+ -DBUILTIN_CODECS_HK:BOOL=ON
+ -DBUILTIN_CODECS_ISO2022:BOOL=ON
+ -DBUILTIN_CODECS_JP:BOOL=ON
+ -DBUILTIN_CODECS_KR:BOOL=ON
+ -DBUILTIN_CODECS_TW:BOOL=ON
+ -DBUILTIN_CPICKLE:BOOL=ON
+ -DBUILTIN_CRYPT:BOOL=ON
+ -DBUILTIN_CSTRINGIO:BOOL=ON
+ -DBUILTIN_CSV:BOOL=ON
+ -DBUILTIN_CTYPES:BOOL=OFF
+ #-DBUILTIN_CTYPES_TEST:BOOL=OFF
+ #-DBUILTIN_CURSES:BOOL=ON
+ -DBUILTIN_DATETIME:BOOL=ON
+ -DBUILTIN_DBM:BOOL=ON
+ -DBUILTIN_ELEMENTTREE:BOOL=ON
+ -DBUILTIN_FCNTL:BOOL=ON
+ -DBUILTIN_FUNCTOOLS:BOOL=ON
+ -DBUILTIN_FUTURE_BUILTINS:BOOL=ON
+ -DBULTIN_GDBM:BOOL=ON
+ -DBUILTIN_GRP:BOOL=ON
+ -DBUILTIN_HASHLIB:BOOL=ON
+ -DBUILTIN_HEAPQ:BOOL=ON
+ -DBUILTIN_HOTSHOT:BOOL=ON
+ -DBUILTIN_IO:BOOL=ON
+ -DBUILTIN_ITERTOOLS:BOOL=ON
+ -DBUILTIN_JSON:BOOL=ON
+ -DBUILTIN_LOCALE:BOOL=ON
+ -DBUILTIN_LSPROF:BOOL=ON
+ -DBUILTIN_MATH:BOOL=ON
+ -DBUILTIN_MMAP:BOOL=ON
+ -DBUILTIN_MULTIBYTECODEC:BOOL=ON
+ -DBUILTIN_MD5:BOOL=ON
+ -DBUILTIN_MULTIPROCESSING:BOOL=ON
+ -DBUILTIN_NIS:BOOL=ON
+ -DBUILTIN_NIT:BOOL=ON
+ -DBUILTIN_OPERATOR:BOOL=ON
+ -DBUILTIN_PARSER:BOOL=ON
+ -DBUILTIN_POSIX:BOOL=ON
+ -DBUILTIN_PWD:BOOL=ON
+ -DBUILTIN_PYEXPAT:BOOL=ON
+ -DBUILTIN_READLINE:BOOL=ON
+ -DBUILTIN_RESOURCE:BOOL=ON
+ -DBULTIN_RANDOM:BOOL=ON
+ -DBUILTIN_SCPROXY:BOOL=OFF
+ -DBUILTIN_SELECT:BOOL=ON
+ -DBUILTIN_SHA:BOOL=ON
+ -DBUILTIN_SHA256:BOOL=ON
+ -DBUILTIN_SHA512:BOOL=ON
+ -DBUILTIN_SOCKET:BOOL=ON
+ -DBUILTIN_SPWD:BOOL=ON
+ -DBUILTIN_SQLITE3:BOOL=OFF
+ -DBUILTIN_SSL:BOOL=ON
+ -DBUILTIN_STROP:BOOL=ON
+ -DBUILTIN_STRUCT:BOOL=ON
+ -DBUILTIN_SUBPROCESS:BOOL=ON
+ -DBUILTIN_SYSLOG:BOOL=ON
+ -DBUILTIN_TERMIOS:BOOL=ON
+ #-DBUILTIN_TESTCAPI:BOOL=OFF
+ -DBUILTIN_TIME:BOOL=ON
+ -DBUILTIN_TKINTER:BOOL=ON
+ -DBUILTIN_UNICODEDATA:BOOL=ON
+ -DBUILTIN_WINREG:BOOL=ON
+ -DBUILTIN_ZLIB:BOOL=OFF
+ -DUSE_SYSTEM_ZLIB:BOOL=ON
+ )
+
+ # CMake build environment for python from:
+ # https://github.com/davidsansome/python-cmake-buildsystem
+ ExternalProject_Add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/python-cmake-buildsystem-47845c55.tar.gz
+ URL_MD5 "6e49d1ed93a5a0fff7621430c163d2d1"
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
+ PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/Patch${proj}CMake.cmake
+ PREFIX ${proj}-cmake
+ BINARY_DIR ${proj}-build
+ INSTALL_DIR ${proj}-install
+ CMAKE_ARGS
+ ${ep_common_args}
+ -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ CMAKE_CACHE_ARGS
+ -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
+ -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
+ #-DBUILD_TESTING:BOOL=OFF
+ -DBUILD_SHARED:BOOL=ON
+ -DBUILD_STATIC:BOOL=OFF
+ -DUSE_SYSTEM_LIBRARIES:BOOL=OFF
+ ${additional_cmake_cache_args}
+ -DZLIB_INCLUDE_DIR:PATH=${ZLIB_INCLUDE_DIR}
+ -DZLIB_LIBRARY:FILEPATH=${ZLIB_LIBRARY}
+ DEPENDS
+ ${Python_DEPENDENCIES}
+ )
+
+ set(Python_DIR "${CMAKE_BINARY_DIR}/${proj}-install")
+
+ if(UNIX)
+ set(PYTHON_EXECUTABLE "${Python_DIR}/bin/python${CMAKE_EXECUTABLE_SUFFIX}")
+ set(PYTHON_INCLUDE_DIR "${Python_DIR}/include/python${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}")
+ set(PYTHON_LIBRARY "${Python_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}python${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ set(MITK_PYTHON_SITE_DIR "${Python_DIR}/lib/python${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}/site-packages")
+
+ # linux custom compile step, set the environment variables and python home to the right
+ # path. Other runtimes can mess up the paths of the installation and the stripped executable
+ # used to compile links to the wrong library in /usr/lib
+ set(_python_compile_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_compile_step.sh)
+ file(WRITE ${_python_compile_step}
+"#!/bin/bash
+export PYTHONHOME=${Python_DIR}
+export LD_LIBRARY_PATH=${Python_DIR}/lib
+${PYTHON_EXECUTABLE} -m compileall
+
+")
+ # pre compile all *.py files in the runtime after install step
+ ExternalProject_Add_Step(${proj} compile_step
+ COMMAND sh ${_python_compile_step}
+ WORKING_DIRECTORY ${Python_DIR}
+ DEPENDEES install
+ )
+
+ # use the python executable in the build dir for unix systems. The stripped
+ # ones will cause conflicts if system libraries are present during the build/configure process
+ # of opencv, since they will try to lookup the sys path first if no lib is directly
+ # linked with it s path into the executable
+ set(PYTHON_EXECUTABLE "${CMAKE_BINARY_DIR}/${proj}-build/bin/python${CMAKE_EXECUTABLE_SUFFIX}")
+ else()
+ set(PYTHON_EXECUTABLE "${Python_DIR}/bin/python${CMAKE_EXECUTABLE_SUFFIX}")
+ set(PYTHON_INCLUDE_DIR "${Python_DIR}/include")
+ set(PYTHON_LIBRARY "${Python_DIR}/libs/python${MITK_PYTHON_MAJOR_VERSION}${MITK_PYTHON_MINOR_VERSION}.lib")
+ set(MITK_PYTHON_SITE_DIR "${Python_DIR}/Lib/site-packages")
+
+ # pre compile all *.py files in the runtime after install step
+ ExternalProject_Add_Step(${proj} compile_step
+ COMMAND ${PYTHON_EXECUTABLE} -m compileall
+ WORKING_DIRECTORY ${Python_DIR}
+ DEPENDEES install
+ )
+ endif()
+
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+ endif()
+endif()
+
diff --git a/CMakeExternals/SimpleITK.cmake b/CMakeExternals/SimpleITK.cmake
new file mode 100644
index 0000000000..5fe9d84828
--- /dev/null
+++ b/CMakeExternals/SimpleITK.cmake
@@ -0,0 +1,131 @@
+#-----------------------------------------------------------------------------
+# SimpleITK
+#-----------------------------------------------------------------------------
+
+if(MITK_USE_SimpleITK)
+
+ # Sanity checks
+ if(DEFINED SimpleITK_DIR AND NOT EXISTS ${SimpleITK_DIR})
+ message(FATAL_ERROR "SimpleITK_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ set(proj SimpleITK)
+ set(proj_DEPENDENCIES ITK GDCM Swig)
+
+ if(MITK_USE_OpenCV)
+ list(APPEND proj_DEPENDENCIES OpenCV)
+ endif()
+
+ set(SimpleITK_DEPENDS ${proj})
+
+ if(NOT DEFINED SimpleITK_DIR)
+
+ set(additional_cmake_args )
+
+ list(APPEND additional_cmake_args
+ -DWRAP_CSHARP:BOOL=OFF
+ -DWRAP_TCL:BOOL=OFF
+ -DWRAP_LUA:BOOL=OFF
+ -DWRAP_PYTHON:BOOL=OFF
+ -DWRAP_JAVA:BOOL=OFF
+ -DWRAP_RUBY:BOOL=OFF
+ -DWRAP_R:BOOL=OFF
+ )
+
+ if(MITK_USE_Python)
+ list(APPEND additional_cmake_args
+ -DWRAP_PYTHON:BOOL=ON
+ -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
+ -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
+ -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
+ -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
+ )
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python)
+ endif()
+ endif()
+
+ #TODO: Installer and testing works only with static libs on MAC
+ set(_build_shared ON)
+ if(APPLE)
+ set(_build_shared OFF)
+ endif()
+
+ set(SimpleITK_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchSimpleITK.cmake)
+
+ ExternalProject_Add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/SimpleITK-0.8.0.tar.gz
+ URL_MD5 "d98f2e5442228e324ef62111febc7446"
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${proj}-build
+ PREFIX ${proj}-cmake
+ INSTALL_DIR ${proj}-install
+ PATCH_COMMAND ${SimpleITK_PATCH_COMMAND}
+ CMAKE_ARGS
+ ${ep_common_args}
+ # -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON
+ CMAKE_CACHE_ARGS
+ ${additional_cmake_args}
+ -DBUILD_SHARED_LIBS:BOOL=${_build_shared}
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${proj}-install
+ -DCMAKE_INSTALL_NAME_DIR:STRING=<INSTALL_DIR>/lib
+ -DSimpleITK_BUILD_DISTRIBUTE:BOOL=ON
+ -DSimpleITK_PYTHON_THREADS:BOOL=ON
+ -DUSE_SYSTEM_ITK:BOOL=ON
+ -DBUILD_TESTING:BOOL=OFF
+ -DBUILD_EXAMPLES:BOOL=OFF
+ -DGDCM_DIR:PATH=${GDCM_DIR}
+ -DITK_DIR:PATH=${ITK_DIR}
+ -DSWIG_DIR:PATH=${SWIG_DIR}
+ -DSWIG_EXECUTABLE:FILEPATH=${SWIG_EXECUTABLE}
+ DEPENDS ${proj_DEPENDENCIES}
+ )
+
+ set(SimpleITK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
+
+ if( MITK_USE_Python )
+ # PythonDir needs to be fixed for the python interpreter by
+ # changing dir delimiter for Windows
+ set(_install_dir ${Python_DIR})
+ if(WIN32)
+ STRING(REPLACE "/" "\\\\" _install_dir ${Python_DIR})
+ else()
+ # escape spaces in the install path for linux
+ STRING(REPLACE " " "\ " _install_dir ${Python_DIR})
+ endif()
+ # Build python distribution with easy install. If a own runtime is used
+ # embedd the egg into the site-package folder of the runtime
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ ExternalProject_Add_Step(${proj} sitk_python_install_step
+ COMMAND ${PYTHON_EXECUTABLE} setup.py install --prefix=${_install_dir}
+ DEPENDEES build
+ WORKING_DIRECTORY ${SimpleITK_DIR}/Wrapping/PythonPackage
+ )
+ # Build egg into custom user base folder and deploy it later into installer
+ # https://pythonhosted.org/setuptools/easy_install.html#use-the-user-option-and-customize-pythonuserbase
+ else()
+ set(_userbase_install ${SimpleITK_DIR}/Wrapping/PythonPackage/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
+ if(WIN32)
+ set(_userbase_install ${SimpleITK_DIR}/Wrapping/PythonPackage/Lib/site-packages)
+ endif()
+ ExternalProject_Add_Step(${proj} sitk_create_userbase_step
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${_userbase_install}
+ DEPENDEES build
+ WORKING_DIRECTORY ${SimpleITK_DIR}/Wrapping/PythonPackage
+ )
+ ExternalProject_Add_Step(${proj} sitk_python_install_step
+ COMMAND PYTHONUSERBASE=${SimpleITK_DIR}/Wrapping/PythonPackage ${PYTHON_EXECUTABLE} setup.py install --user
+ DEPENDEES sitk_create_userbase_step
+ WORKING_DIRECTORY ${SimpleITK_DIR}/Wrapping/PythonPackage
+ )
+ endif()
+ endif()
+
+ else()
+
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+
+ endif()
+
+endif()
+
diff --git a/CMakeExternals/Swig.cmake b/CMakeExternals/Swig.cmake
new file mode 100644
index 0000000000..550680dae7
--- /dev/null
+++ b/CMakeExternals/Swig.cmake
@@ -0,0 +1,64 @@
+#------------------------------------------------------------
+# SWIG (Simple Wrapper Interface Generator)
+#-----------------------------------------------------------
+if(MITK_USE_SWIG)
+ if(DEFINED Swig_DIR AND NOT EXISTS ${Swig_DIR})
+ message(FATAL_ERROR "Swig_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ if(NOT SWIG_DIR)
+ set(SWIG_TARGET_VERSION 3.0.2)
+ set(proj Swig)
+ set(Swig_DEPENDENCIES )
+ set(Swig_DEPENDS )
+
+ # binary SWIG for windows
+ if(WIN32)
+ set(swig_source_dir ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION})
+
+ # swig.exe available as pre-built binary on Windows:
+ ExternalProject_Add(Swig
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/swigwin-${SWIG_TARGET_VERSION}.zip
+ URL_MD5 "3f18de4fc09ab9abb0d3be37c11fbc8f"
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+
+ set(SWIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION}) # path specified as source in ep
+ set(SWIG_EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION}/swig.exe)
+
+ else()
+
+ list(APPEND Swig_DEPENDENCIES PCRE)
+
+ # swig uses bison find it by cmake and pass it down
+ find_package(BISON)
+ set(BISON_FLAGS "" CACHE STRING "Flags used by bison")
+ mark_as_advanced( BISON_FLAGS)
+
+ ExternalProject_add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/swig-${SWIG_TARGET_VERSION}.tar.gz
+ URL_MD5 "62f9b0d010cef36a13a010dc530d0d41"
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build
+ INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install
+ PREFIX ${proj}-cmake
+ CONFIGURE_COMMAND <SOURCE_DIR>/./configure
+ CC=${CMAKE_C_COMPILER}${CMAKE_C_COMPILER_ARG1}
+ LDFLAGS=${CMAKE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS_RELEASE}
+ CXX=${CMAKE_CXX_COMPILER}${CMAKE_CXX_COMPILER_ARG1}
+ --prefix=<INSTALL_DIR>
+ --with-pcre-prefix=${PCRE_DIR}
+ --without-octave
+ --with-python=${PYTHON_EXECUTABLE}
+ DEPENDS ${Swig_DEPENDENCIES}
+ )
+
+ set(SWIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install/share/swig/${SWIG_TARGET_VERSION})
+ set(SWIG_EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install/bin/swig)
+
+ endif()
+ endif(NOT SWIG_DIR)
+endif()
diff --git a/CMakeExternals/VTK.cmake b/CMakeExternals/VTK.cmake
index a3ef5f7bd6..c63146440b 100644
--- a/CMakeExternals/VTK.cmake
+++ b/CMakeExternals/VTK.cmake
@@ -1,94 +1,111 @@
#-----------------------------------------------------------------------------
# VTK
#-----------------------------------------------------------------------------
if(WIN32)
option(VTK_USE_SYSTEM_FREETYPE OFF)
else(WIN32)
option(VTK_USE_SYSTEM_FREETYPE ON)
endif(WIN32)
# Sanity checks
if(DEFINED VTK_DIR AND NOT EXISTS ${VTK_DIR})
message(FATAL_ERROR "VTK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj VTK)
set(proj_DEPENDENCIES )
set(VTK_DEPENDS ${proj})
if(NOT DEFINED VTK_DIR)
set(additional_cmake_args )
if(MINGW)
set(additional_cmake_args
-DCMAKE_USE_WIN32_THREADS:BOOL=ON
-DCMAKE_USE_PTHREADS:BOOL=OFF
-DVTK_USE_VIDEO4WINDOWS:BOOL=OFF # no header files provided by MinGW
)
endif()
+ if(WIN32)
+ # see http://bugs.mitk.org/show_bug.cgi?id=17858
+ list(APPEND additional_cmake_args
+ -DVTK_DO_NOT_DEFINE_OSTREAM_SLL:BOOL=ON
+ -DVTK_DO_NOT_DEFINE_OSTREAM_ULL:BOOL=ON
+ )
+ endif()
+
+ # Optionally enable memory leak checks for any objects derived from vtkObject. This
+ # will force unit tests to fail if they have any of these memory leaks.
+ option(MITK_VTK_DEBUG_LEAKS OFF)
+ mark_as_advanced(MITK_VTK_DEBUG_LEAKS)
+ list(APPEND additional_cmake_args
+ -DVTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS}
+ )
+
if(MITK_USE_Python)
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python)
+ endif()
list(APPEND additional_cmake_args
-DVTK_WRAP_PYTHON:BOOL=ON
-DVTK_USE_TK:BOOL=OFF
-DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
- #-DPYTHON_LIBRARIES=${PYTHON_LIBRARY}
- #-DPYTHON_DEBUG_LIBRARIES=${PYTHON_DEBUG_LIBRARIES}
)
else()
list(APPEND additional_cmake_args
-DVTK_WRAP_PYTHON:BOOL=OFF
-DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF
)
endif()
if(MITK_USE_QT)
list(APPEND additional_cmake_args
-DVTK_QT_VERSION:STRING=${DESIRED_QT_VERSION}
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
-DModule_vtkGUISupportQt:BOOL=ON
-DModule_vtkGUISupportQtWebkit:BOOL=ON
-DModule_vtkGUISupportQtSQL:BOOL=ON
-DModule_vtkRenderingQt:BOOL=ON
-DVTK_Group_Qt:BOOL=ON
)
endif()
set(VTK_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/VTK-6.1.0.tar.gz)
set(VTK_URL_MD5 25e4dfb3bad778722dcaec80cd5dab7d)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${VTK_URL}
URL_MD5 ${VTK_URL_MD5}
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
-DVTK_WRAP_TCL:BOOL=OFF
-DVTK_WRAP_PYTHON:BOOL=OFF
-DVTK_WRAP_JAVA:BOOL=OFF
-DBUILD_SHARED_LIBS:BOOL=ON
-DVTK_USE_SYSTEM_FREETYPE:BOOL=${VTK_USE_SYSTEM_FREETYPE}
-DVTK_LEGACY_REMOVE:BOOL=ON
-DModule_vtkTestingRendering:BOOL=ON
-DVTK_MAKE_INSTANTIATORS:BOOL=ON
${additional_cmake_args}
DEPENDS ${proj_DEPENDENCIES}
)
set(VTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
diff --git a/CMakeExternals/ZLIB.cmake b/CMakeExternals/ZLIB.cmake
new file mode 100644
index 0000000000..57310a059f
--- /dev/null
+++ b/CMakeExternals/ZLIB.cmake
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------
+# ZLIB
+#------------------------------------------------------------------
+if(MITK_USE_ZLIB)
+ if(NOT DEFINED ZLIB_DIR)
+ set(proj ZLIB)
+ set(${proj}_DEPENDENCIES )
+ set(ZLIB_DEPENDS ${proj})
+
+ # Using the ZLIB from CTK:
+ # https://github.com/commontk/zlib
+ ExternalProject_Add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/zlib-66a75305.tar.gz
+ URL_MD5 "4c3f572b487ae7947fd88ec363533bc5"
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${proj}-build
+ PREFIX ${proj}-cmake
+ INSTALL_DIR ${proj}-install
+ CMAKE_ARGS
+ ${ep_common_args}
+ CMAKE_CACHE_ARGS
+ -DBUILD_SHARED_LIBS:BOOL=OFF
+ -DZLIB_MANGLE_PREFIX:STRING=mitk_zlib_
+ -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ DEPENDS
+ ${ZLIB_DEPENDENCIES}
+ )
+ set(ZLIB_DIR ${CMAKE_BINARY_DIR}/${proj}-install)
+ set(ZLIB_INCLUDE_DIR ${ZLIB_DIR}/include)
+ if(WIN32)
+ set(ZLIB_LIBRARY ${ZLIB_DIR}/lib/zlib.lib)
+ else()
+ set(ZLIB_LIBRARY ${ZLIB_DIR}/lib/libzlib.a)
+ endif()
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+ endif()
+endif()
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fbda3fd3e3..9f16412dc7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,1066 +1,1082 @@
set(DESIRED_QT_VERSION 4 CACHE STRING "Pick a version of Qt to use: 4 or 5")
if(DESIRED_QT_VERSION MATCHES "4")
cmake_minimum_required(VERSION 2.8.9)
else()
cmake_minimum_required(VERSION 2.8.12)
endif()
#-----------------------------------------------------------------------------
# Include ctest launchers for dashboard in case of makefile generator
#-----------------------------------------------------------------------------
if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
include(CTestUseLaunchers)
endif()
#-----------------------------------------------------------------------------
# Set a default build type if none was specified
#-----------------------------------------------------------------------------
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
#-----------------------------------------------------------------------------
# Superbuild Option - Enabled by default
#-----------------------------------------------------------------------------
option(MITK_USE_SUPERBUILD "Build MITK and the projects it depends on via SuperBuild.cmake." ON)
if(MITK_USE_SUPERBUILD)
project(MITK-superbuild)
set(MITK_SOURCE_DIR ${PROJECT_SOURCE_DIR})
set(MITK_BINARY_DIR ${PROJECT_BINARY_DIR})
else()
project(MITK)
endif()
#-----------------------------------------------------------------------------
# Warn if source or build path is too long
#-----------------------------------------------------------------------------
if(WIN32)
set(_src_dir_length_max 50)
set(_bin_dir_length_max 50)
if(MITK_USE_SUPERBUILD)
set(_src_dir_length_max 43) # _src_dir_length_max - strlen(ITK-src)
set(_bin_dir_length_max 40) # _bin_dir_length_max - strlen(MITK-build)
endif()
string(LENGTH "${MITK_SOURCE_DIR}" _src_n)
string(LENGTH "${MITK_BINARY_DIR}" _bin_n)
# The warnings should be converted to errors
if(_src_n GREATER _src_dir_length_max)
message(WARNING "MITK source code directory path length is too long (${_src_n} > ${_src_dir_length_max})."
"Please move the MITK source code directory to a directory with a shorter path." )
endif()
if(_bin_n GREATER _bin_dir_length_max)
message(WARNING "MITK build directory path length is too long (${_bin_n} > ${_bin_dir_length_max})."
"Please move the MITK build directory to a directory with a shorter path." )
endif()
endif()
#-----------------------------------------------------------------------------
# See http://cmake.org/cmake/help/cmake-2-8-docs.html#section_Policies for details
#-----------------------------------------------------------------------------
set(project_policies
CMP0001 # NEW: CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.
CMP0002 # NEW: Logical target names must be globally unique.
CMP0003 # NEW: Libraries linked via full path no longer produce linker search paths.
CMP0004 # NEW: Libraries linked may NOT have leading or trailing whitespace.
CMP0005 # NEW: Preprocessor definition values are now escaped automatically.
CMP0006 # NEW: Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.
CMP0007 # NEW: List command no longer ignores empty elements.
CMP0008 # NEW: Libraries linked by full-path must have a valid library file name.
CMP0009 # NEW: FILE GLOB_RECURSE calls should not follow symlinks by default.
CMP0010 # NEW: Bad variable reference syntax is an error.
CMP0011 # NEW: Included scripts do automatic cmake_policy PUSH and POP.
CMP0012 # NEW: if() recognizes numbers and boolean constants.
CMP0013 # NEW: Duplicate binary directories are not allowed.
CMP0014 # NEW: Input directories must have CMakeLists.txt
CMP0020 # NEW: Automatically link Qt executables to qtmain target on Windows
)
foreach(policy ${project_policies})
if(POLICY ${policy})
cmake_policy(SET ${policy} NEW)
endif()
endforeach()
#-----------------------------------------------------------------------------
# Update CMake module path
#------------------------------------------------------------------------------
set(MITK_CMAKE_DIR ${MITK_SOURCE_DIR}/CMake)
set(CMAKE_MODULE_PATH
${MITK_CMAKE_DIR}
${CMAKE_MODULE_PATH}
)
#-----------------------------------------------------------------------------
# CMake function(s) and macro(s)
#-----------------------------------------------------------------------------
include(mitkMacroEmptyExternalProject)
include(mitkFunctionGenerateProjectXml)
include(mitkFunctionSuppressWarnings)
include(mitkFunctionEnableBuildConfiguration)
include(FeatureSummary)
SUPPRESS_VC_DEPRECATED_WARNINGS()
#-----------------------------------------------------------------------------
# Output directories.
#-----------------------------------------------------------------------------
foreach(type LIBRARY RUNTIME ARCHIVE)
# Make sure the directory exists
if(DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY
AND NOT EXISTS ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY})
message("Creating directory MITK_CMAKE_${type}_OUTPUT_DIRECTORY: ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}")
file(MAKE_DIRECTORY "${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}")
endif()
if(MITK_USE_SUPERBUILD)
set(output_dir ${MITK_BINARY_DIR}/bin)
if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY)
set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_BINARY_DIR}/MITK-build/bin)
endif()
else()
if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY)
set(output_dir ${MITK_BINARY_DIR}/bin)
else()
set(output_dir ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY})
endif()
endif()
set(CMAKE_${type}_OUTPUT_DIRECTORY ${output_dir} CACHE INTERNAL "Single output directory for building all libraries.")
mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY)
endforeach()
#-----------------------------------------------------------------------------
# Additional MITK Options (also shown during superbuild)
#-----------------------------------------------------------------------------
option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON)
option(WITH_COVERAGE "Enable/Disable coverage" OFF)
option(BUILD_TESTING "Test the project" ON)
macro(env_option name doc value)
set(_value $ENV{${name}})
if("${_value}" STREQUAL "")
set(_value ${value})
endif()
option(${name} "${doc}" ${_value})
endmacro()
# -----------------------------------------
# Qt version related variables
env_option(MITK_USE_QT "Use Nokia's Qt library" ON)
set(MITK_DESIRED_QT_VERSION ${DESIRED_QT_VERSION})
if(MITK_USE_QT)
# find the package at the very beginning, so that QT4_FOUND is available
if(DESIRED_QT_VERSION MATCHES 4)
set(MITK_QT4_MINIMUM_VERSION 4.7)
find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED)
set(MITK_USE_Qt4 TRUE)
set(MITK_USE_Qt5 FALSE)
endif()
if(DESIRED_QT_VERSION MATCHES 5)
set(MITK_QT5_MINIMUM_VERSION 5.0.0)
set(MITK_USE_Qt4 FALSE)
set(MITK_USE_Qt5 TRUE)
set(QT5_INSTALL_PREFIX "" CACHE PATH "The install location of Qt5")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_INSTALL_PREFIX})
find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
endif()
else()
set(MITK_USE_Qt4 FALSE)
set(MITK_USE_Qt5 FALSE)
endif()
# -----------------------------------------
# MITK_USE_* build variables
env_option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF)
set(MITK_BUILD_TUTORIAL OFF CACHE INTERNAL "Deprecated! Use MITK_BUILD_EXAMPLES instead!")
env_option(MITK_BUILD_EXAMPLES "Build the MITK Examples" ${MITK_BUILD_TUTORIAL})
env_option(MITK_USE_ACVD "Use Approximated Centroidal Voronoi Diagrams" OFF)
env_option(MITK_USE_CppUnit "Use CppUnit for unit tests" ON)
if(BUILD_TESTING AND NOT MITK_USE_CppUnit)
message("> Forcing MITK_USE_CppUnit to ON because BUILD_TESTING=ON")
set(MITK_USE_CppUnit ON CACHE BOOL "Use CppUnit for unit tests" FORCE)
endif()
env_option(MITK_USE_GLEW "Use the GLEW library" ON)
env_option(MITK_USE_Boost "Use the Boost C++ library" OFF)
env_option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ${MITK_USE_Qt4})
env_option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_Qt4})
env_option(MITK_USE_DCMTK "EXPERIMENTAL, superbuild only: Use DCMTK in MITK" ${MITK_USE_CTK})
env_option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF)
env_option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF)
env_option(MITK_USE_Poco "Use the Poco library" ON)
env_option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" OFF)
env_option(MITK_USE_Python "Use Python wrapping in MITK" OFF)
+env_option(MITK_USE_SimpleITK "Use the SimpleITK library" OFF)
set(MITK_USE_CableSwig ${MITK_USE_Python})
option(MITK_ENABLE_PIC_READER "Enable support for reading the DKFZ pic file format." ON)
set(MITK_BUILD_CONFIGURATION "Custom" CACHE STRING "Use pre-defined MITK configurations")
set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS Custom Default All)
mitkFunctionEnableBuildConfiguration()
mark_as_advanced(MITK_BUILD_ALL_APPS
MITK_USE_CppUnit
MITK_USE_GLEW
MITK_USE_CTK
MITK_USE_DCMTK
MITK_ENABLE_PIC_READER
MITK_BUILD_CONFIGURATION
)
if(MITK_USE_Python)
- FIND_PACKAGE(PythonLibs REQUIRED)
- FIND_PACKAGE(PythonInterp REQUIRED)
+ if(APPLE)
+ message(WARNING "Python wrapping is unsuported on mac OSX!")
+ set(MITK_USE_Python OFF CACHE BOOL "Use Python wrapping in MITK" FORCE)
+ else()
+ option(MITK_USE_SYSTEM_PYTHON "Use the system python runtime" OFF)
+ # SimpleITK is required when python is enabled
+ set(MITK_USE_SimpleITK ON CACHE BOOL "Use the SimpleITK library" FORCE)
+ if(MITK_USE_SYSTEM_PYTHON)
+ FIND_PACKAGE(PythonLibs REQUIRED)
+ FIND_PACKAGE(PythonInterp REQUIRED)
+ else()
+ FIND_PACKAGE(PythonLibs)
+ FIND_PACKAGE(PythonInterp)
+ endif()
+ endif()
endif()
if(MITK_USE_Boost)
option(MITK_USE_SYSTEM_Boost "Use the system Boost" OFF)
set(MITK_USE_Boost_LIBRARIES "" CACHE STRING "A semi-colon separated list of required Boost libraries")
endif()
if(MITK_USE_BLUEBERRY AND NOT MITK_USE_Qt4)
message("> Forcing MITK_USE_BLUEBERRY to OFF because Qt4 is not used.")
set(MITK_USE_BLUEBERRY OFF CACHE BOOL "Build the BlueBerry application platform" FORCE)
endif()
if(MITK_USE_CTK AND NOT MITK_USE_Qt4)
message("> Forcing MITK_USE_CTK to OFF because Qt4 is not used.")
set(MITK_USE_CTK OFF CACHE BOOL "Use CTK in MITK" FORCE)
endif()
if(MITK_USE_BLUEBERRY)
option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF)
mark_as_advanced(MITK_BUILD_ALL_PLUGINS)
if(NOT MITK_USE_CTK)
message("> Forcing MITK_USE_CTK to ON because of MITK_USE_BLUEBERRY")
set(MITK_USE_CTK ON CACHE BOOL "Use CTK in MITK" FORCE)
endif()
endif()
if(MITK_USE_CTK AND NOT MITK_USE_DCMTK)
message("> Forcing MITK_USE_DCMTK to ON because of MITK_USE_CTK")
set(MITK_USE_DCMTK ON CACHE BOOL "Use DCMTK in MITK" FORCE)
endif()
if(MITK_USE_SOFA)
# SOFA requires at least CMake 2.8.8
set(SOFA_CMAKE_VERSION 2.8.8)
if(${CMAKE_VERSION} VERSION_LESS ${SOFA_CMAKE_VERSION})
set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE)
message(WARNING "Switched off MITK_USE_SOFA\n Minimum required CMake version: ${SOFA_CMAKE_VERSION}\n Installed CMake version: ${CMAKE_VERSION}")
endif()
# SOFA/ITK combination requires at least MSVC 2010
if(MSVC_VERSION AND MSVC_VERSION LESS 1600)
set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE)
message(WARNING "Switched off MITK_USE_SOFA\n MSVC versions less than 2010 are not supported.")
endif()
# SOFA requires boost library
if(MITK_USE_SOFA AND NOT MITK_USE_Boost)
message("Forcing MITK_USE_Boost to ON because of MITK_USE_SOFA")
set(MITK_USE_Boost ON CACHE BOOL "" FORCE)
endif()
# SOFA requires boost system library
list(FIND MITK_USE_Boost_LIBRARIES system _result)
if(_result LESS 0)
message("Adding 'system' to MITK_USE_Boost_LIBRARIES.")
list(APPEND MITK_USE_Boost_LIBRARIES system)
endif()
# SOFA requires boost thread library
list(FIND MITK_USE_Boost_LIBRARIES thread _result)
if(_result LESS 0)
message("Adding 'thread' to MITK_USE_Boost_LIBRARIES.")
list(APPEND MITK_USE_Boost_LIBRARIES thread)
endif()
+ # Simulation plugin requires boost chrono library
+ list(FIND MITK_USE_Boost_LIBRARIES chrono _result)
+ if(_result LESS 0)
+ message("Adding 'chrono' to MITK_USE_Boost_LIBRARIES.")
+ list(APPEND MITK_USE_Boost_LIBRARIES chrono)
+ endif()
set(MITK_USE_Boost_LIBRARIES ${MITK_USE_Boost_LIBRARIES} CACHE STRING "" FORCE)
# Allow setting external SOFA plugins directory and SOFA plugins
set(MITK_USE_SOFA_PLUGINS_DIR ${MITK_USE_SOFA_PLUGINS_DIR} CACHE PATH "External SOFA plugins directory" FORCE)
set(MITK_USE_SOFA_PLUGINS ${MITK_USE_SOFA_PLUGINS} CACHE PATH "List of semicolon-separated plugin names" FORCE)
endif()
# Customize the default pixel types for multiplex macros
set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES
"int, unsigned int, short, unsigned short, char, unsigned char"
CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros")
set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES
"double, float"
CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros")
set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES
"itk::RGBPixel<unsigned char>, itk::RGBAPixel<unsigned char>"
CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros")
set(MITK_ACCESSBYITK_DIMENSIONS
"2,3"
CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros")
mark_as_advanced(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES
MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES
MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES
MITK_ACCESSBYITK_DIMENSIONS
)
# consistency checks
if(NOT MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES)
set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES
"int, unsigned int, short, unsigned short, char, unsigned char"
CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE)
endif()
if(NOT MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES)
set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES
"double, float"
CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE)
endif()
if(NOT MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES)
set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES
"itk::RGBPixel<unsigned char>, itk::RGBAPixel<unsigned char>"
CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE)
endif()
if(NOT MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES)
string(REPLACE "," ";" _integral_types ${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES})
string(REPLACE "," ";" _floating_types ${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES})
foreach(_scalar_type ${_integral_types} ${_floating_types})
set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES
"${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}itk::VariableLengthVector<${_scalar_type}>,")
endforeach()
string(LENGTH "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" _length)
math(EXPR _length "${_length} - 1")
string(SUBSTRING "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" 0 ${_length} MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES)
set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES ${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}
CACHE STRING "List of vector pixel types used in AccessByItk and InstantiateAccessFunction macros for itk::VectorImage types" FORCE)
endif()
if(NOT MITK_ACCESSBYITK_DIMENSIONS)
set(MITK_ACCESSBYITK_DIMENSIONS
"2,3"
CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros")
endif()
#-----------------------------------------------------------------------------
# Project.xml
#-----------------------------------------------------------------------------
# A list of topologically ordered targets
set(CTEST_PROJECT_SUBPROJECTS)
if(MITK_USE_BLUEBERRY)
list(APPEND CTEST_PROJECT_SUBPROJECTS BlueBerry)
endif()
list(APPEND CTEST_PROJECT_SUBPROJECTS
MITK-Core
MITK-CoreUI
MITK-IGT
MITK-ToF
MITK-DTI
MITK-Registration
MITK-Modules # all modules not contained in a specific subproject
MITK-Plugins # all plugins not contained in a specific subproject
MITK-Examples
Unlabeled # special "subproject" catching all unlabeled targets and tests
)
# Configure CTestConfigSubProject.cmake that could be used by CTest scripts
configure_file(${MITK_SOURCE_DIR}/CTestConfigSubProject.cmake.in
${MITK_BINARY_DIR}/CTestConfigSubProject.cmake)
if(CTEST_PROJECT_ADDITIONAL_TARGETS)
# those targets will be executed at the end of the ctest driver script
# and they also get their own subproject label
set(subproject_list "${CTEST_PROJECT_SUBPROJECTS};${CTEST_PROJECT_ADDITIONAL_TARGETS}")
else()
set(subproject_list "${CTEST_PROJECT_SUBPROJECTS}")
endif()
# Generate Project.xml file expected by the CTest driver script
mitkFunctionGenerateProjectXml(${MITK_BINARY_DIR} MITK "${subproject_list}" ${MITK_USE_SUPERBUILD})
#-----------------------------------------------------------------------------
# Superbuild script
#-----------------------------------------------------------------------------
if(MITK_USE_SUPERBUILD)
include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake")
# Print configuration summary
message("\n\n")
feature_summary(
DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------"
WHAT ALL)
return()
endif()
#*****************************************************************************
#**************************** END OF SUPERBUILD ****************************
#*****************************************************************************
#-----------------------------------------------------------------------------
# CMake function(s) and macro(s)
#-----------------------------------------------------------------------------
include(WriteBasicConfigVersionFile)
include(CheckCXXSourceCompiles)
include(mitkFunctionCheckCompilerFlags)
include(mitkFunctionGetGccVersion)
include(MacroParseArguments)
include(mitkFunctionSuppressWarnings) # includes several functions
include(mitkFunctionOrganizeSources)
include(mitkFunctionGetVersion)
include(mitkFunctionGetVersionDescription)
include(mitkFunctionCreateWindowsBatchScript)
include(mitkFunctionInstallProvisioningFiles)
include(mitkFunctionInstallAutoLoadModules)
include(mitkFunctionGetLibrarySearchPaths)
include(mitkFunctionCompileSnippets)
include(mitkFunctionUseModules)
include(mitkMacroCreateModuleConf)
include(mitkFunctionCheckModuleDependencies)
include(mitkFunctionCreateModule)
include(mitkMacroCreateExecutable)
include(mitkMacroCheckModule)
include(mitkMacroCreateModuleTests)
include(mitkFunctionAddCustomModuleTest)
include(mitkMacroUseModule)
include(mitkMacroMultiplexPicType)
include(mitkMacroInstall)
include(mitkMacroInstallHelperApp)
include(mitkMacroInstallTargets)
include(mitkMacroGenerateToolsLibrary)
include(mitkMacroGetLinuxDistribution)
include(mitkMacroGetPMDPlatformString)
#-----------------------------------------------------------------------------
# Set MITK specific options and variables (NOT available during superbuild)
#-----------------------------------------------------------------------------
# ASK THE USER TO SHOW THE CONSOLE WINDOW FOR CoreApp and mitkWorkbench
option(MITK_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting MITK GUI Applications" ON)
mark_as_advanced(MITK_SHOW_CONSOLE_WINDOW)
# TODO: check if necessary
option(USE_ITKZLIB "Use the ITK zlib for pic compression." ON)
mark_as_advanced(USE_ITKZLIB)
if(NOT MITK_FAST_TESTING)
if(DEFINED MITK_CTEST_SCRIPT_MODE
AND (MITK_CTEST_SCRIPT_MODE STREQUAL "continuous" OR MITK_CTEST_SCRIPT_MODE STREQUAL "experimental") )
set(MITK_FAST_TESTING 1)
endif()
endif()
#-----------------------------------------------------------------------------
# Get MITK version info
#-----------------------------------------------------------------------------
mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK)
mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK)
#-----------------------------------------------------------------------------
# Installation preparation
#
# These should be set before any MITK install macros are used
#-----------------------------------------------------------------------------
# on Mac OSX all BlueBerry plugins get copied into every
# application bundle (.app directory) specified here
if(MITK_USE_BLUEBERRY AND APPLE)
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake")
foreach(mitk_app ${MITK_APPS})
# extract option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 1 option_name)
list(GET target_info_list 0 app_name)
# check if the application is enabled
if(${option_name} OR MITK_BUILD_ALL_APPS)
set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} Mitk${app_name})
endif()
endforeach()
endif()
#-----------------------------------------------------------------------------
# Set symbol visibility Flags
#-----------------------------------------------------------------------------
# MinGW does not export all symbols automatically, so no need to set flags
if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
set(VISIBILITY_CXX_FLAGS ) #"-fvisibility=hidden -fvisibility-inlines-hidden")
endif()
#-----------------------------------------------------------------------------
# Set coverage Flags
#-----------------------------------------------------------------------------
if(WITH_COVERAGE)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG")
set(COVERAGE_CXX_FLAGS ${coverage_flags})
set(COVERAGE_C_FLAGS ${coverage_flags})
endif()
endif()
#-----------------------------------------------------------------------------
# MITK C/CXX Flags
#-----------------------------------------------------------------------------
set(MITK_C_FLAGS "${COVERAGE_C_FLAGS}")
set(MITK_C_FLAGS_DEBUG )
set(MITK_C_FLAGS_RELEASE )
set(MITK_CXX_FLAGS "${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS}")
set(MITK_CXX_FLAGS_DEBUG )
set(MITK_CXX_FLAGS_RELEASE )
set(MITK_EXE_LINKER_FLAGS )
set(MITK_SHARED_LINKER_FLAGS )
if(WIN32)
set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN")
set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} /wd4231") # warning C4231: nonstandard extension used : 'extern' before template explicit instantiation
# the following line should be removed after fixing bug 17637
mitkFunctionCheckCompilerFlags("/wd4316" MITK_CXX_FLAGS) # warning C4316: object alignment on heap
endif()
if(NOT MSVC_VERSION)
foreach(_flag
-Wall
-Wextra
-Wpointer-arith
-Winvalid-pch
-Wcast-align
-Wwrite-strings
-Wno-error=gnu
-Wno-error=unknown-pragmas
# The strict-overflow warning is generated by ITK template code
-Wno-error=strict-overflow
-Woverloaded-virtual
-Wstrict-null-sentinel
#-Wold-style-cast
#-Wsign-promo
# the following two lines should be removed after ITK-3097 has
# been resolved, see also MITK bug 15279
-Wno-unused-local-typedefs
-Wno-array-bounds
-fdiagnostics-show-option
)
mitkFunctionCheckCAndCXXCompilerFlags(${_flag} MITK_C_FLAGS MITK_CXX_FLAGS)
endforeach()
endif()
if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE)
mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" MITK_SHARED_LINKER_FLAGS)
mitkFunctionCheckCompilerFlags("-Wl,--as-needed" MITK_SHARED_LINKER_FLAGS)
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION)
# With older version of gcc supporting the flag -fstack-protector-all, an extra dependency to libssp.so
# is introduced. If gcc is smaller than 4.4.0 and the build type is Release let's not include the flag.
# Doing so should allow to build package made for distribution using older linux distro.
if(${GCC_VERSION} VERSION_GREATER "4.4.0" OR (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${GCC_VERSION} VERSION_LESS "4.4.0"))
mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS)
endif()
if(MINGW)
# suppress warnings about auto imported symbols
set(MITK_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import ${MITK_SHARED_LINKER_FLAGS}")
endif()
set(MITK_CXX_FLAGS_RELEASE "-D_FORTIFY_SOURCE=2 ${MITK_CXX_FLAGS_RELEASE}")
endif()
set(MITK_MODULE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS})
set(MITK_EXE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS})
#-----------------------------------------------------------------------------
# MITK Packages
#-----------------------------------------------------------------------------
set(MITK_MODULES_PACKAGE_DEPENDS_DIR ${MITK_SOURCE_DIR}/CMake/PackageDepends)
set(MODULES_PACKAGE_DEPENDS_DIRS ${MITK_MODULES_PACKAGE_DEPENDS_DIR})
#-----------------------------------------------------------------------------
# Testing
#-----------------------------------------------------------------------------
if(BUILD_TESTING)
enable_testing()
include(CTest)
mark_as_advanced(TCL_TCLSH DART_ROOT)
option(MITK_ENABLE_RENDERING_TESTING OFF "Enable the MITK rendering tests. Requires x-server in Linux.")
#Rendering testing does not work for Linux nightlies, thus it is disabled per default
#and activated for Mac and Windows.
if(WIN32 OR APPLE)
set(MITK_ENABLE_RENDERING_TESTING ON)
endif()
mark_as_advanced( MITK_ENABLE_RENDERING_TESTING )
# Setup file for setting custom ctest vars
configure_file(
CMake/CTestCustom.cmake.in
${MITK_BINARY_DIR}/CTestCustom.cmake
@ONLY
)
# Configuration for the CMake-generated test driver
set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include <stdexcept>")
set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN "
try
{")
set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " }
catch( std::exception & excp )
{
fprintf(stderr,\"%s\\n\",excp.what());
return EXIT_FAILURE;
}
catch( ... )
{
printf(\"Exception caught in the test driver\\n\");
return EXIT_FAILURE;
}
")
set(MITK_TEST_OUTPUT_DIR "${MITK_BINARY_DIR}/test_output")
if(NOT EXISTS ${MITK_TEST_OUTPUT_DIR})
file(MAKE_DIRECTORY ${MITK_TEST_OUTPUT_DIR})
endif()
# Test the external project template
if(MITK_USE_BLUEBERRY)
include(mitkTestProjectTemplate)
endif()
# Test the package target
include(mitkPackageTest)
endif()
configure_file(mitkTestingConfig.h.in ${MITK_BINARY_DIR}/mitkTestingConfig.h)
#-----------------------------------------------------------------------------
# MITK_SUPERBUILD_BINARY_DIR
#-----------------------------------------------------------------------------
# If MITK_SUPERBUILD_BINARY_DIR isn't defined, it means MITK is *NOT* build using Superbuild.
# In that specific case, MITK_SUPERBUILD_BINARY_DIR should default to MITK_BINARY_DIR
if(NOT DEFINED MITK_SUPERBUILD_BINARY_DIR)
set(MITK_SUPERBUILD_BINARY_DIR ${MITK_BINARY_DIR})
endif()
#-----------------------------------------------------------------------------
# Compile Utilities and set-up MITK variables
#-----------------------------------------------------------------------------
include(mitkSetupVariables)
#-----------------------------------------------------------------------------
# Cleanup
#-----------------------------------------------------------------------------
file(GLOB _MODULES_CONF_FILES ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake)
if(_MODULES_CONF_FILES)
file(REMOVE ${_MODULES_CONF_FILES})
endif()
add_subdirectory(Utilities)
if(MITK_USE_BLUEBERRY)
# We need to hack a little bit because MITK applications may need
# to enable certain BlueBerry plug-ins. However, these plug-ins
# are validated separately from the MITK plug-ins and know nothing
# about potential MITK plug-in dependencies of the applications. Hence
# we cannot pass the MITK application list to the BlueBerry
# ctkMacroSetupPlugins call but need to extract the BlueBerry dependencies
# from the applications and set them explicitly.
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake")
foreach(mitk_app ${MITK_APPS})
# extract target_dir and option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 0 target_dir)
list(GET target_info_list 1 option_name)
# check if the application is enabled and if target_libraries.cmake exists
if((${option_name} OR MITK_BUILD_ALL_APPS) AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake")
foreach(_target_dep ${target_libraries})
if(_target_dep MATCHES org_blueberry_)
string(REPLACE _ . _app_bb_dep ${_target_dep})
# explicitly set the build option for the BlueBerry plug-in
set(BLUEBERRY_BUILD_${_app_bb_dep} ON CACHE BOOL "Build the ${_app_bb_dep} plug-in")
endif()
endforeach()
endif()
endforeach()
set(mbilog_DIR "${mbilog_BINARY_DIR}")
if(MITK_BUILD_ALL_PLUGINS)
set(BLUEBERRY_BUILD_ALL_PLUGINS ON)
endif()
set(BLUEBERRY_XPDOC_OUTPUT_DIR ${MITK_DOXYGEN_OUTPUT_DIR}/html/extension-points/html/)
add_subdirectory(BlueBerry)
set(BlueBerry_DIR ${CMAKE_CURRENT_BINARY_DIR}/BlueBerry
CACHE PATH "The directory containing a CMake configuration file for BlueBerry" FORCE)
include(mitkMacroCreateCTKPlugin)
endif()
#-----------------------------------------------------------------------------
# Set C/CXX and linker flags for MITK code
#-----------------------------------------------------------------------------
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MITK_CXX_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MITK_CXX_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MITK_C_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MITK_C_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MITK_EXE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MITK_SHARED_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${MITK_MODULE_LINKER_FLAGS}")
#-----------------------------------------------------------------------------
# Add custom targets representing CDash subprojects
#-----------------------------------------------------------------------------
foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
if(NOT TARGET ${subproject} AND NOT subproject MATCHES "Unlabeled")
add_custom_target(${subproject})
endif()
endforeach()
#-----------------------------------------------------------------------------
# Add subdirectories
#-----------------------------------------------------------------------------
add_subdirectory(Core)
add_subdirectory(Modules)
if(MITK_USE_BLUEBERRY)
find_package(BlueBerry REQUIRED)
set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins)
# Plug-in testing (needs some work to be enabled again)
if(BUILD_TESTING)
include(berryTestingHelpers)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp")
get_target_property(_is_macosx_bundle CoreApp MACOSX_BUNDLE)
if(APPLE AND _is_macosx_bundle)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp.app/Contents/MacOS/CoreApp")
endif()
set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication")
endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake")
set(mitk_plugins_fullpath )
foreach(mitk_plugin ${MITK_EXT_PLUGINS})
list(APPEND mitk_plugins_fullpath Plugins/${mitk_plugin})
endforeach()
if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake)
include(${MITK_PRIVATE_MODULES}/PluginList.cmake)
foreach(mitk_plugin ${MITK_PRIVATE_PLUGINS})
list(APPEND mitk_plugins_fullpath ${MITK_PRIVATE_MODULES}/${mitk_plugin})
endforeach()
endif()
if(MITK_BUILD_EXAMPLES)
include("${CMAKE_CURRENT_SOURCE_DIR}/Examples/Plugins/PluginList.cmake")
set(mitk_example_plugins_fullpath )
foreach(mitk_example_plugin ${MITK_EXAMPLE_PLUGINS})
list(APPEND mitk_example_plugins_fullpath Examples/Plugins/${mitk_example_plugin})
list(APPEND mitk_plugins_fullpath Examples/Plugins/${mitk_example_plugin})
endforeach()
endif()
# Specify which plug-ins belong to this project
macro(GetMyTargetLibraries all_target_libraries varname)
set(re_ctkplugin_mitk "^org_mitk_[a-zA-Z0-9_]+$")
set(re_ctkplugin_bb "^org_blueberry_[a-zA-Z0-9_]+$")
set(_tmp_list)
list(APPEND _tmp_list ${all_target_libraries})
ctkMacroListFilter(_tmp_list re_ctkplugin_mitk re_ctkplugin_bb OUTPUT_VARIABLE ${varname})
endmacro()
# Get infos about application directories and build options
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake")
set(mitk_apps_fullpath )
foreach(mitk_app ${MITK_APPS})
list(APPEND mitk_apps_fullpath "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${mitk_app}")
endforeach()
if (mitk_plugins_fullpath)
ctkMacroSetupPlugins(${mitk_plugins_fullpath}
BUILD_OPTION_PREFIX MITK_BUILD_
APPS ${mitk_apps_fullpath}
BUILD_ALL ${MITK_BUILD_ALL_PLUGINS}
COMPACT_OPTIONS)
endif()
set(MITK_PLUGIN_USE_FILE "${MITK_BINARY_DIR}/MitkPluginUseFile.cmake")
if(${PROJECT_NAME}_PLUGIN_LIBRARIES)
ctkFunctionGeneratePluginUseFile(${MITK_PLUGIN_USE_FILE})
else()
file(REMOVE ${MITK_PLUGIN_USE_FILE})
set(MITK_PLUGIN_USE_FILE )
endif()
# 11.3.13, change, muellerm: activate python bundle if python and blueberry is active
if( MITK_USE_Python )
set(MITK_BUILD_org.mitk.gui.qt.python ON)
endif()
endif()
-#-----------------------------------------------------------------------------
-# Python Wrapping
-#-----------------------------------------------------------------------------
-option(MITK_USE_Python "Build Python integration for MITK (requires CableSwig)." OFF)
-
#-----------------------------------------------------------------------------
# Documentation
#-----------------------------------------------------------------------------
add_subdirectory(Documentation)
#-----------------------------------------------------------------------------
# Installation
#-----------------------------------------------------------------------------
# set MITK cpack variables
# These are the default variables, which can be overwritten ( see below )
include(mitkSetupCPack)
set(use_default_config ON)
# MITK_APPS is set in Applications/AppList.cmake (included somewhere above
# if MITK_USE_BLUEBERRY is set to ON).
if(MITK_APPS)
set(activated_apps_no 0)
list(LENGTH MITK_APPS app_count)
# Check how many apps have been enabled
# If more than one app has been activated, the we use the
# default CPack configuration. Otherwise that apps configuration
# will be used, if present.
foreach(mitk_app ${MITK_APPS})
# extract option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 1 option_name)
# check if the application is enabled
if(${option_name} OR MITK_BUILD_ALL_APPS)
MATH(EXPR activated_apps_no "${activated_apps_no} + 1")
endif()
endforeach()
if(app_count EQUAL 1 AND (activated_apps_no EQUAL 1 OR MITK_BUILD_ALL_APPS))
# Corner case if there is only one app in total
set(use_project_cpack ON)
elseif(activated_apps_no EQUAL 1 AND NOT MITK_BUILD_ALL_APPS)
# Only one app is enabled (no "build all" flag set)
set(use_project_cpack ON)
else()
# Less or more then one app is enabled
set(use_project_cpack OFF)
endif()
foreach(mitk_app ${MITK_APPS})
# extract target_dir and option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 0 target_dir)
list(GET target_info_list 1 option_name)
# check if the application is enabled
if(${option_name} OR MITK_BUILD_ALL_APPS)
# check whether application specific configuration files will be used
if(use_project_cpack)
# use files if they exist
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake")
endif()
if(EXISTS "${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in")
set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/Applications/${target_dir}/CPackConfig.cmake")
configure_file(${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in
${CPACK_PROJECT_CONFIG_FILE} @ONLY)
set(use_default_config OFF)
endif()
endif()
# add link to the list
list(APPEND CPACK_CREATE_DESKTOP_LINKS "${target_dir}")
endif()
endforeach()
endif()
# if no application specific configuration file was used, use default
if(use_default_config)
configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in
${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY)
set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake")
endif()
# include CPack model once all variables are set
include(CPack)
# Additional installation rules
include(mitkInstallRules)
#-----------------------------------------------------------------------------
# Last configuration steps
#-----------------------------------------------------------------------------
set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake")
file(REMOVE ${MITK_EXPORTS_FILE})
set(targets_to_export)
get_property(module_targets GLOBAL PROPERTY MITK_MODULE_TARGETS)
if(module_targets)
list(APPEND targets_to_export ${module_targets})
endif()
if(MITK_USE_BLUEBERRY)
if(MITK_PLUGIN_LIBRARIES)
list(APPEND targets_to_export ${MITK_PLUGIN_LIBRARIES})
endif()
endif()
export(TARGETS ${targets_to_export} APPEND
FILE ${MITK_EXPORTS_FILE})
set(MITK_EXPORTED_TARGET_PROPERTIES )
foreach(target_to_export ${targets_to_export})
get_target_property(autoload_targets ${target_to_export} MITK_AUTOLOAD_TARGETS)
if(autoload_targets)
set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES}
set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_TARGETS \"${autoload_targets}\")")
endif()
get_target_property(autoload_dir ${target_to_export} MITK_AUTOLOAD_DIRECTORY)
if(autoload_dir)
set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES}
set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_DIRECTORY \"${autoload_dir}\")")
endif()
endforeach()
get_property(MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS_CONFIG GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in
${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY)
configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in
${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY)
configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in
${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY)
set(VISIBILITY_AVAILABLE 0)
set(visibility_test_flag "")
mitkFunctionCheckCompilerFlags("-fvisibility=hidden" visibility_test_flag)
if(visibility_test_flag)
# The compiler understands -fvisiblity=hidden (probably gcc >= 4 or Clang)
set(VISIBILITY_AVAILABLE 1)
endif()
configure_file(mitkExportMacros.h.in ${MITK_BINARY_DIR}/mitkExportMacros.h)
configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h)
configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h)
set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc)
set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities)
file(GLOB _MODULES_CONF_FILES RELATIVE ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME} ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake)
set(MITK_MODULE_NAMES)
foreach(_module ${_MODULES_CONF_FILES})
string(REPLACE Config.cmake "" _module_name ${_module})
list(APPEND MITK_MODULE_NAMES ${_module_name})
endforeach()
configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h)
configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY)
write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${MITK_VERSION_STRING} COMPATIBILITY AnyNewerVersion)
# If we are under Windows, create two batch files which correctly
# set up the environment for the application and for Visual Studio
if(WIN32)
include(mitkFunctionCreateWindowsBatchScript)
set(VS_SOLUTION_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.sln")
foreach(VS_BUILD_TYPE debug release)
mitkFunctionCreateWindowsBatchScript("${MITK_SOURCE_DIR}/CMake/StartVS.bat.in"
${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat
${VS_BUILD_TYPE})
endforeach()
endif(WIN32)
#-----------------------------------------------------------------------------
# MITK Applications
#-----------------------------------------------------------------------------
# This must come after MITKConfig.h was generated, since applications
# might do a find_package(MITK REQUIRED).
add_subdirectory(Applications)
#-----------------------------------------------------------------------------
# MITK Examples
#-----------------------------------------------------------------------------
if(MITK_BUILD_EXAMPLES)
# This must come after MITKConfig.h was generated, since applications
# might do a find_package(MITK REQUIRED).
add_subdirectory(Examples)
endif()
#-----------------------------------------------------------------------------
# Print configuration summary
#-----------------------------------------------------------------------------
message("\n\n")
feature_summary(
DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------"
WHAT ALL
)
+
diff --git a/Core/Code/Algorithms/mitkSurfaceToImageFilter.cpp b/Core/Code/Algorithms/mitkSurfaceToImageFilter.cpp
index 7cbb76e444..1da2080147 100644
--- a/Core/Code/Algorithms/mitkSurfaceToImageFilter.cpp
+++ b/Core/Code/Algorithms/mitkSurfaceToImageFilter.cpp
@@ -1,221 +1,221 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSurfaceToImageFilter.h"
#include "mitkTimeHelper.h"
#include "mitkImageWriteAccessor.h"
#include <vtkPolyData.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageStencil.h>
#include <vtkImageData.h>
#include <vtkPolyData.h>
#include <vtkLinearTransform.h>
#include <vtkTriangleFilter.h>
#include <vtkLinearExtrusionFilter.h>
#include <vtkDataSetTriangleFilter.h>
#include <vtkImageThreshold.h>
#include <vtkImageMathematics.h>
#include <vtkPolyDataNormals.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTransform.h>
#include <vtkSmartPointer.h>
#include <mitkImageReadAccessor.h>
mitk::SurfaceToImageFilter::SurfaceToImageFilter()
: m_MakeOutputBinary( false ),
m_BackgroundValue( -10000 )
{
}
mitk::SurfaceToImageFilter::~SurfaceToImageFilter()
{
}
void mitk::SurfaceToImageFilter::GenerateInputRequestedRegion()
{
mitk::Image* output = this->GetOutput();
if((output->IsInitialized()==false) )
return;
GenerateTimeInInputRegion(output, const_cast< mitk::Image * > ( this->GetImage() ));
}
void mitk::SurfaceToImageFilter::GenerateOutputInformation()
{
mitk::Image *inputImage = (mitk::Image*)this->GetImage();
mitk::Image::Pointer output = this->GetOutput();
itkDebugMacro(<<"GenerateOutputInformation()");
if((inputImage == NULL) ||
(inputImage->IsInitialized() == false) ||
(inputImage->GetTimeGeometry() == NULL)) return;
if (m_MakeOutputBinary)
output->Initialize(mitk::MakeScalarPixelType<unsigned char>() , *inputImage->GetTimeGeometry());
else
output->Initialize(inputImage->GetPixelType(), *inputImage->GetTimeGeometry());
output->SetPropertyList(inputImage->GetPropertyList()->Clone());
}
void mitk::SurfaceToImageFilter::GenerateData()
{
mitk::Image::ConstPointer inputImage = this->GetImage();
mitk::Image::Pointer output = this->GetOutput();
if(inputImage.IsNull())
return;
if(output->IsInitialized()==false )
return;
mitk::Image::RegionType outputRegion = output->GetRequestedRegion();
int tstart=outputRegion.GetIndex(3);
int tmax=tstart+outputRegion.GetSize(3);
if ( tmax > 0)
{
int t;
for(t=tstart;t<tmax;++t)
{
Stencil3DImage( t );
}
}
else
{
Stencil3DImage( 0 );
}
}
void mitk::SurfaceToImageFilter::Stencil3DImage(int time)
{
mitk::Image::Pointer output = this->GetOutput();
mitk::Image::Pointer binaryImage = mitk::Image::New();
unsigned int size = sizeof(unsigned char);
if (m_MakeOutputBinary)
binaryImage->Initialize(mitk::MakeScalarPixelType<unsigned char>(), *this->GetImage()->GetTimeGeometry(),1,1);
else
{
binaryImage->Initialize(this->GetImage()->GetPixelType(), *this->GetImage()->GetTimeGeometry(),1,1);
size = this->GetImage()->GetPixelType().GetSize();
}
for (unsigned int i = 0; i < binaryImage->GetDimension(); ++i)
size *= binaryImage->GetDimension(i);
mitk::ImageWriteAccessor accessor( binaryImage );
memset( accessor.GetData(), 1, size );
const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry();
const mitk::TimeGeometry *imageTimeGeometry = GetImage()->GetTimeGeometry();
// Convert time step from image time-frame to surface time-frame
mitk::TimePointType matchingTimePoint = imageTimeGeometry->TimeStepToTimePoint(time);
mitk::TimeStepType surfaceTimeStep = surfaceTimeGeometry->TimePointToTimeStep(matchingTimePoint);
vtkPolyData * polydata = ( (mitk::Surface*)GetInput() )->GetVtkPolyData( surfaceTimeStep );
if(polydata)
{
- vtkSmartPointer<vtkTransformPolyDataFilter> move=vtkTransformPolyDataFilter::New();
+ vtkSmartPointer<vtkTransformPolyDataFilter> move = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
move->SetInputData(polydata);
move->ReleaseDataFlagOn();
- vtkSmartPointer<vtkTransform> transform=vtkTransform::New();
- BaseGeometry* geometry = surfaceTimeGeometry->GetGeometryForTimeStep( surfaceTimeStep );
+ vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
+ BaseGeometry* geometry = surfaceTimeGeometry->GetGeometryForTimeStep( surfaceTimeStep );
if(!geometry)
{
geometry = GetInput()->GetGeometry();
}
transform->PostMultiply();
transform->Concatenate(geometry->GetVtkTransform()->GetMatrix());
// take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below.
- BaseGeometry* imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time);
+ BaseGeometry* imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time);
transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse());
move->SetTransform(transform);
- vtkSmartPointer<vtkPolyDataNormals> normalsFilter = vtkPolyDataNormals::New();
+ vtkSmartPointer<vtkPolyDataNormals> normalsFilter = vtkSmartPointer<vtkPolyDataNormals>::New();
normalsFilter->SetFeatureAngle(50);
normalsFilter->SetConsistency(1);
normalsFilter->SetSplitting(1);
normalsFilter->SetFlipNormals(0);
normalsFilter->ReleaseDataFlagOn();
normalsFilter->SetInputConnection(move->GetOutputPort());
- vtkSmartPointer<vtkPolyDataToImageStencil> surfaceConverter = vtkPolyDataToImageStencil::New();
+ vtkSmartPointer<vtkPolyDataToImageStencil> surfaceConverter = vtkSmartPointer<vtkPolyDataToImageStencil>::New();
surfaceConverter->SetTolerance( 0.0 );
surfaceConverter->ReleaseDataFlagOn();
surfaceConverter->SetInputConnection( normalsFilter->GetOutputPort() );
vtkImageData *image = m_MakeOutputBinary
? binaryImage->GetVtkImageData()
: const_cast<mitk::Image *>(this->GetImage())->GetVtkImageData(time);
// Create stencil and use numerical minimum of pixel type as background value
- vtkSmartPointer<vtkImageStencil> stencil = vtkImageStencil::New();
+ vtkSmartPointer<vtkImageStencil> stencil = vtkSmartPointer<vtkImageStencil>::New();
stencil->SetInputData(image);
stencil->ReverseStencilOff();
stencil->ReleaseDataFlagOn();
stencil->SetStencilConnection(surfaceConverter->GetOutputPort());
stencil->SetBackgroundValue(m_MakeOutputBinary ? 0 : m_BackgroundValue);
stencil->Update();
output->SetVolume( stencil->GetOutput()->GetScalarPointer(), time );
MITK_INFO << "stencil ref count: " << stencil->GetReferenceCount() << std::endl;
}
else
{
memset( accessor.GetData(), 0, size );
output->SetVolume(accessor.GetData(),time);
}
}
const mitk::Surface *mitk::SurfaceToImageFilter::GetInput(void)
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}
return static_cast<const mitk::Surface * >
( this->ProcessObject::GetInput(0) );
}
void mitk::SurfaceToImageFilter::SetInput(const mitk::Surface *input)
{
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput(0,
const_cast< mitk::Surface * >( input ) );
}
void mitk::SurfaceToImageFilter::SetImage(const mitk::Image *source)
{
this->ProcessObject::SetNthInput( 1, const_cast< mitk::Image * >( source ) );
}
const mitk::Image *mitk::SurfaceToImageFilter::GetImage(void)
{
return static_cast< const mitk::Image * >(this->ProcessObject::GetInput(1));
}
diff --git a/Core/Code/Controllers/mitkFocusManager.cpp b/Core/Code/Controllers/mitkFocusManager.cpp
index c4b43a551c..decc262252 100755
--- a/Core/Code/Controllers/mitkFocusManager.cpp
+++ b/Core/Code/Controllers/mitkFocusManager.cpp
@@ -1,145 +1,160 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkFocusManager.h"
mitk::FocusManager::FocusManager()
{
m_Loop = true;//default
m_FocusList.clear();
m_FocElement = NULL;
}
mitk::FocusManager::~FocusManager()
{
}
bool mitk::FocusManager::AddElement(FocusElement* element)
{
// Try find
mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element);
if (position != m_FocusList.end())
return false;
m_FocusList.push_back(element);
if (m_FocElement.GetPointer() == NULL)
m_FocElement = element;
return true;
}
bool mitk::FocusManager::RemoveElement(FocusElement* element)
{
- // Try find
- mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element);
- if (position == m_FocusList.end())
- return false;
- position = m_FocusList.erase(position);
- // first delete the one on the position, and store the one afterewards into position
- if ( m_FocusList.size() == 0 )
+ if (element == m_FocElement)
{
- // no more FocusElements available
- m_FocElement = NULL;
+ this->GoToNext();
}
- else if ( position == m_FocusList.end() )
+
+ // Try to find
+ mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(), m_FocusList.end(), element);
+ if (position == m_FocusList.end())
{
- // deleted was the last in row, then take the one before
- m_FocElement = m_FocusList.back();
+ return false;
}
- else
+
+ m_FocusList.erase(position);
+ if (m_FocusList.empty())
{
- // m_FocElement is equal to the next one in row
- m_FocElement = *position;
+ m_FocElement = NULL;
}
+
return true;
}
mitk::FocusManager::FocusElement* mitk::FocusManager::GetFocused() const
{
return m_FocElement.GetPointer();
}
bool mitk::FocusManager::SetFocused(FocusElement* element)
{
if (m_FocElement == element)
return true;
FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element);
if (position == m_FocusList.end())//not found
return false;
m_FocElement = *position;
((const itk::Object*)this)->InvokeEvent(FocusEvent());
return true;
}
bool mitk::FocusManager::IsLast()
{
return (m_FocElement == m_FocusList.back());
}
bool mitk::FocusManager::IsFirst()
{
return (m_FocElement == m_FocusList.front());
}
const mitk::FocusManager::FocusElement* mitk::FocusManager::GetFirst() const
{
return (m_FocusList.front()).GetPointer();
}
const mitk::FocusManager::FocusElement* mitk::FocusManager::GetLast() const
{
return (m_FocusList.back()).GetPointer();
}
bool mitk::FocusManager::GoToNext()
{
+ if (m_FocusList.empty())
+ {
+ return false;
+ }
+
//find the m_FocElement
- FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),m_FocElement);
- if (position == m_FocusList.end())//not found
+ FocusListIterator position = std::find(m_FocusList.begin(), m_FocusList.end(), m_FocElement);
+ if (position == m_FocusList.end())
+ {
return false;
- else if (*position == m_FocusList.back())//last in row
+ }
+
+ if (m_FocusList.size() == 1)
+ {
+ return true;
+ }
+
+ FocusListIterator nextPosition = position + 1;
+ while(nextPosition != position)
{
- if (m_Loop)
+ if (nextPosition == m_FocusList.end())
{
- m_FocElement = *(m_FocusList.begin());
- return true;
+ if (!m_Loop)
+ {
+ return false;
+ }
+ nextPosition = m_FocusList.begin();
}
- else
+
+ FocusElement* focusElement = *nextPosition;
+ if (focusElement->GetSizeX() > 0 && focusElement->GetSizeY() > 0)
{
- return false;//last in row and loop == false, so GoToNext == false
+ m_FocElement = focusElement;
+ return true;
}
+ ++nextPosition;
}
- else //not last in row
- {
- m_FocElement = *(++position);//increase position and set m_FocElement
- return true;
- }
+
+ m_FocElement = NULL;
return false;
}
//##Documentation
//## returns an iterator, that points to the
//## beginning of the list
mitk::FocusManager::FocusListIterator mitk::FocusManager::GetIter()
{
return m_FocusList.begin();
}
void mitk::FocusManager::SetLoop(bool loop)
{
m_Loop = loop;
}
diff --git a/Core/Code/Controllers/mitkFocusManager.h b/Core/Code/Controllers/mitkFocusManager.h
index 74ef59d3f6..cb5f13ad46 100755
--- a/Core/Code/Controllers/mitkFocusManager.h
+++ b/Core/Code/Controllers/mitkFocusManager.h
@@ -1,150 +1,149 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197
#define MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197
#include <MitkCoreExports.h>
#include "mitkBaseRenderer.h"
#include <vector>
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
namespace mitk {
//##Documentation
//## @brief manages a list of BaseRenderer.
//##
//## A focuspointer can be set and read.
//## GoToNext can be used to switch through the list.
//## if the switch m_Loop is set to true, GetNext loops through the list; after
//## the last it goes to the first.
//## if it is not set, it returnes NULL if it steps behind the last Widget.
//## @ingroup Interaction
class MITK_CORE_EXPORT FocusManager : public itk::Object
{
public:
mitkClassMacro(FocusManager, itk::Object);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
//##Documentation
//##@brief Element, that can be focused and held here.
//##
- //## has to be an itk-Objekct in order to use itk-Smartpointer!
+ //## has to be an itk-Object in order to use itk-Smartpointer!
typedef mitk::BaseRenderer FocusElement;
typedef itk::WeakPointer<FocusElement> FocusElementWeakPointer;
typedef std::vector<FocusElementWeakPointer> FocusElementList;
typedef std::vector<FocusElementWeakPointer>::iterator FocusListIterator;
//##Documentation
//## Destructor
~FocusManager();
//##Documentation
//## Adds the widget into the set of managed Widgets after the focused
//## widget and sets the focus to the added one if the list was empty before
bool AddElement(FocusElement* element);
//##Documentation
//## removes the given widget from the list.
//## true if found and removed, else false
- //## afterwards the focused widget is the one behind the deleted
- //## or if the deleted was the last, then the one before the deleted
- //## that way you can delete sequentialy from the back on or from front to back
+ //## If the focus was on the removed widget then the next widget
+ //## will get the focus, as described in GoToNext().
bool RemoveElement(FocusElement* element);
//##Documentation
//## returns the focused Widget
FocusElement* GetFocused() const;
//##Documentation
//## searches the given Widget in List;
//## if found, sets the focus to this widget and returns true
bool SetFocused(FocusElement* element);
//##Documentation
//## returns, if this focused widget points behind the end of the List
bool IsLast();
//##Documentation
//## returns true, if the focused widget is the first in the list
bool IsFirst();
//##Documentation
//## returns the first widget in list
const FocusElement* GetFirst() const;
//##Documentation
//## returns the last widget in list
const FocusElement* GetLast() const;
//##Documentation
//## sets the focus to the next in list
//## loops the list, if switch loop is true
//## returns true if successful, else false
bool GoToNext();
//##Documentation
//## returns an iterator, that points to the
//## beginning of the list
//## no changes are made to the current focused element
FocusListIterator GetIter();
//##Documentation
//## Sets the LoopMode.
//## if set to true-> the one after the last is the first
void SetLoop(bool loop);
friend class GlobalInteraction;
protected:
//##Documentation
//## Constructor
FocusManager();
private:
//##Documentation
//## stores the Widgets
FocusElementList m_FocusList;
//##Documentation
//## holds the focused Widget
itk::WeakPointer<FocusElement> m_FocElement;
//##Documentation
//## switch which sets the LoopMode.
//## if true, then the next after the last one is the first
bool m_Loop;
};
#pragma GCC visibility push(default)
//##Documentation
//## @brief connect to this Event to get noticed when the focus changes
itkEventMacro( FocusEvent , itk::AnyEvent );
#pragma GCC visibility pop
} // namespace mitk
#endif /* MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197 */
diff --git a/Core/Code/Controllers/mitkSliceNavigationController.cpp b/Core/Code/Controllers/mitkSliceNavigationController.cpp
index 7e0d3aa2b2..0573930541 100644
--- a/Core/Code/Controllers/mitkSliceNavigationController.cpp
+++ b/Core/Code/Controllers/mitkSliceNavigationController.cpp
@@ -1,836 +1,850 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSliceNavigationController.h"
#include "mitkBaseRenderer.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkPlaneGeometry.h"
#include "mitkOperation.h"
#include "mitkOperationActor.h"
#include "mitkStateEvent.h"
#include "mitkCrosshairPositionEvent.h"
#include "mitkPositionEvent.h"
#include "mitkProportionalTimeGeometry.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"
#include "mitkGlobalInteraction.h"
#include "mitkEventMapper.h"
#include "mitkFocusManager.h"
#include "mitkVtkPropRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkInteractionConst.h"
#include "mitkPointOperation.h"
#include "mitkPlaneOperation.h"
#include "mitkUndoController.h"
#include "mitkOperationEvent.h"
#include "mitkNodePredicateDataType.h"
#include "mitkStatusBar.h"
#include "mitkImage.h"
#include "mitkApplyTransformMatrixOperation.h"
#include "mitkMemoryUtilities.h"
#include <itkCommand.h>
namespace mitk {
SliceNavigationController::SliceNavigationController( const char *type )
: BaseController( type ),
m_InputWorldGeometry3D( NULL ),
m_InputWorldTimeGeometry( NULL ),
m_CreatedWorldGeometry( NULL ),
m_ViewDirection( Axial ),
m_DefaultViewDirection( Axial ),
m_RenderingManager( NULL ),
m_Renderer( NULL ),
m_Top( false ),
m_FrontSide( false ),
m_Rotated( false ),
m_BlockUpdate( false ),
m_SliceLocked( false ),
m_SliceRotationLocked( false ),
m_OldPos(0)
{
typedef itk::SimpleMemberCommand< SliceNavigationController > SNCCommandType;
SNCCommandType::Pointer sliceStepperChangedCommand, timeStepperChangedCommand;
sliceStepperChangedCommand = SNCCommandType::New();
timeStepperChangedCommand = SNCCommandType::New();
sliceStepperChangedCommand->SetCallbackFunction(
this, &SliceNavigationController::SendSlice );
timeStepperChangedCommand->SetCallbackFunction(
this, &SliceNavigationController::SendTime );
m_Slice->AddObserver( itk::ModifiedEvent(), sliceStepperChangedCommand );
m_Time->AddObserver( itk::ModifiedEvent(), timeStepperChangedCommand );
m_Slice->SetUnitName( "mm" );
m_Time->SetUnitName( "ms" );
m_Top = false;
m_FrontSide = false;
m_Rotated = false;
}
SliceNavigationController::~SliceNavigationController()
{
}
void
SliceNavigationController::SetInputWorldGeometry3D( const BaseGeometry *geometry )
{
if ( geometry != NULL )
{
if ( const_cast< BoundingBox * >( geometry->GetBoundingBox())
->GetDiagonalLength2() < eps )
{
itkWarningMacro( "setting an empty bounding-box" );
geometry = NULL;
}
}
if ( m_InputWorldGeometry3D != geometry )
{
m_InputWorldGeometry3D = geometry;
m_InputWorldTimeGeometry = NULL;
this->Modified();
}
}
void
SliceNavigationController::SetInputWorldTimeGeometry( const TimeGeometry *geometry )
{
if ( geometry != NULL )
{
if ( const_cast< BoundingBox * >( geometry->GetBoundingBoxInWorld())
->GetDiagonalLength2() < eps )
{
itkWarningMacro( "setting an empty bounding-box" );
geometry = NULL;
}
}
if ( m_InputWorldTimeGeometry != geometry )
{
m_InputWorldTimeGeometry = geometry;
m_InputWorldGeometry3D = NULL;
this->Modified();
}
}
RenderingManager *
SliceNavigationController::GetRenderingManager() const
{
mitk::RenderingManager* renderingManager = m_RenderingManager.GetPointer();
if (renderingManager != NULL)
return renderingManager;
if ( m_Renderer != NULL )
{
renderingManager = m_Renderer->GetRenderingManager();
if (renderingManager != NULL)
return renderingManager;
}
return mitk::RenderingManager::GetInstance();
}
void SliceNavigationController::SetViewDirectionToDefault()
{
m_ViewDirection = m_DefaultViewDirection;
}
const char* SliceNavigationController::GetViewDirectionAsString()
{
const char* viewDirectionString;
switch(m_ViewDirection)
{
case SliceNavigationController::Axial:
viewDirectionString = "Axial";
break;
case SliceNavigationController::Sagittal:
viewDirectionString = "Sagittal";
break;
case SliceNavigationController::Frontal:
viewDirectionString = "Coronal";
break;
case SliceNavigationController::Original:
viewDirectionString = "Original";
break;
default:
viewDirectionString = "No View Direction Available";
break;
}
return viewDirectionString;
}
void SliceNavigationController::Update()
{
if ( !m_BlockUpdate )
{
if ( m_ViewDirection == Axial )
{
this->Update( Axial, false, false, true );
}
else
{
this->Update( m_ViewDirection );
}
}
}
void
SliceNavigationController::Update(
SliceNavigationController::ViewDirection viewDirection,
bool top, bool frontside, bool rotated )
{
TimeGeometry::ConstPointer worldTimeGeometry = m_InputWorldTimeGeometry;
if( m_BlockUpdate ||
( m_InputWorldTimeGeometry.IsNull() && m_InputWorldGeometry3D.IsNull() ) ||
( (worldTimeGeometry.IsNotNull()) && (worldTimeGeometry->CountTimeSteps() == 0) )
)
{
return;
}
m_BlockUpdate = true;
if ( m_InputWorldTimeGeometry.IsNotNull() &&
m_LastUpdateTime < m_InputWorldTimeGeometry->GetMTime() )
{
Modified();
}
if ( m_InputWorldGeometry3D.IsNotNull() &&
m_LastUpdateTime < m_InputWorldGeometry3D->GetMTime() )
{
Modified();
}
this->SetViewDirection( viewDirection );
this->SetTop( top );
this->SetFrontSide( frontside );
this->SetRotated( rotated );
if ( m_LastUpdateTime < GetMTime() )
{
m_LastUpdateTime = GetMTime();
// initialize the viewplane
SlicedGeometry3D::Pointer slicedWorldGeometry = NULL;
BaseGeometry::ConstPointer currentGeometry = NULL;
if (m_InputWorldTimeGeometry.IsNotNull())
if (m_InputWorldTimeGeometry->IsValidTimeStep(GetTime()->GetPos()))
currentGeometry = m_InputWorldTimeGeometry->GetGeometryForTimeStep(GetTime()->GetPos());
else
currentGeometry = m_InputWorldTimeGeometry->GetGeometryForTimeStep(0);
else
currentGeometry = m_InputWorldGeometry3D;
m_CreatedWorldGeometry = NULL;
switch ( viewDirection )
{
case Original:
if ( worldTimeGeometry.IsNotNull())
{
m_CreatedWorldGeometry = worldTimeGeometry->Clone();
worldTimeGeometry = m_CreatedWorldGeometry.GetPointer();
slicedWorldGeometry = dynamic_cast< SlicedGeometry3D * >(
m_CreatedWorldGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() ).GetPointer() );
if ( slicedWorldGeometry.IsNotNull() )
{
break;
}
}
else
{
const SlicedGeometry3D *worldSlicedGeometry =
dynamic_cast< const SlicedGeometry3D * >(
currentGeometry.GetPointer());
if ( worldSlicedGeometry != NULL )
{
slicedWorldGeometry = static_cast< SlicedGeometry3D * >(
currentGeometry->Clone().GetPointer());
break;
}
}
//else: use Axial: no "break" here!!
case Axial:
slicedWorldGeometry = SlicedGeometry3D::New();
slicedWorldGeometry->InitializePlanes(
currentGeometry, PlaneGeometry::Axial,
top, frontside, rotated );
slicedWorldGeometry->SetSliceNavigationController( this );
break;
case Frontal:
slicedWorldGeometry = SlicedGeometry3D::New();
slicedWorldGeometry->InitializePlanes( currentGeometry,
PlaneGeometry::Frontal, top, frontside, rotated );
slicedWorldGeometry->SetSliceNavigationController( this );
break;
case Sagittal:
slicedWorldGeometry = SlicedGeometry3D::New();
slicedWorldGeometry->InitializePlanes( currentGeometry,
PlaneGeometry::Sagittal, top, frontside, rotated );
slicedWorldGeometry->SetSliceNavigationController( this );
break;
default:
itkExceptionMacro("unknown ViewDirection");
}
m_Slice->SetPos( 0 );
m_Slice->SetSteps( (int)slicedWorldGeometry->GetSlices() );
if ( m_CreatedWorldGeometry.IsNull() )
{
// initialize TimeGeometry
m_CreatedWorldGeometry = ProportionalTimeGeometry::New();
}
if ( worldTimeGeometry.IsNull())
{
m_CreatedWorldGeometry = ProportionalTimeGeometry::New();
dynamic_cast<ProportionalTimeGeometry *>(m_CreatedWorldGeometry.GetPointer())->Initialize(slicedWorldGeometry, 1);
m_Time->SetSteps( 0 );
m_Time->SetPos( 0 );
m_Time->InvalidateRange();
}
else
{
m_BlockUpdate = true;
m_Time->SetSteps( worldTimeGeometry->CountTimeSteps() );
m_Time->SetPos( 0 );
const TimeBounds &timeBounds = worldTimeGeometry->GetTimeBounds();
m_Time->SetRange( timeBounds[0], timeBounds[1] );
m_BlockUpdate = false;
assert( worldTimeGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() ).IsNotNull() );
TimePointType minimumTimePoint = worldTimeGeometry->TimeStepToTimePoint(this->GetTime()->GetPos());
TimePointType stepDuration = worldTimeGeometry->TimeStepToTimePoint(this->GetTime()->GetPos()+1)-worldTimeGeometry->TimeStepToTimePoint(this->GetTime()->GetPos());
//@todo implement for non-evenly-timed geometry!
m_CreatedWorldGeometry = ProportionalTimeGeometry::New();
dynamic_cast<ProportionalTimeGeometry *>(m_CreatedWorldGeometry.GetPointer())->Initialize(slicedWorldGeometry, worldTimeGeometry->CountTimeSteps());
dynamic_cast<ProportionalTimeGeometry *>(m_CreatedWorldGeometry.GetPointer())->GetMinimumTimePoint(minimumTimePoint);
dynamic_cast<ProportionalTimeGeometry *>(m_CreatedWorldGeometry.GetPointer())->SetStepDuration(stepDuration);
}
}
// unblock update; we may do this now, because if m_BlockUpdate was already
// true before this method was entered, then we will never come here.
m_BlockUpdate = false;
// Send the geometry. Do this even if nothing was changed, because maybe
// Update() was only called to re-send the old geometry and time/slice data.
this->SendCreatedWorldGeometry();
this->SendSlice();
this->SendTime();
// Adjust the stepper range of slice stepper according to geometry
this->AdjustSliceStepperRange();
}
void
SliceNavigationController::SendCreatedWorldGeometry()
{
// Send the geometry. Do this even if nothing was changed, because maybe
// Update() was only called to re-send the old geometry.
if ( !m_BlockUpdate )
{
this->InvokeEvent( GeometrySendEvent(m_CreatedWorldGeometry, 0) );
}
}
void
SliceNavigationController::SendCreatedWorldGeometryUpdate()
{
if ( !m_BlockUpdate )
{
this->InvokeEvent(
GeometryUpdateEvent(m_CreatedWorldGeometry, m_Slice->GetPos()) );
}
}
void
SliceNavigationController::SendSlice()
{
if ( !m_BlockUpdate )
{
if ( m_CreatedWorldGeometry.IsNotNull() )
{
this->InvokeEvent(
GeometrySliceEvent(m_CreatedWorldGeometry, m_Slice->GetPos()) );
// send crosshair event
crosshairPositionEvent.Send();
// Request rendering update for all views
this->GetRenderingManager()->RequestUpdateAll();
}
}
}
void
SliceNavigationController::SendTime()
{
if ( !m_BlockUpdate )
{
if ( m_CreatedWorldGeometry.IsNotNull() )
{
this->InvokeEvent(
GeometryTimeEvent(m_CreatedWorldGeometry, m_Time->GetPos()) );
// Request rendering update for all views
this->GetRenderingManager()->RequestUpdateAll();
}
}
}
void
SliceNavigationController::SetGeometry( const itk::EventObject & )
{
}
void
SliceNavigationController
::SetGeometryTime( const itk::EventObject &geometryTimeEvent )
{
+ if (m_CreatedWorldGeometry.IsNull())
+ {
+ return;
+ }
+
const SliceNavigationController::GeometryTimeEvent *timeEvent =
dynamic_cast< const SliceNavigationController::GeometryTimeEvent * >(
&geometryTimeEvent);
assert( timeEvent != NULL );
TimeGeometry *timeGeometry = timeEvent->GetTimeGeometry();
assert( timeGeometry != NULL );
- if ( m_CreatedWorldGeometry.IsNotNull() )
- {
- int timeStep = (int) timeEvent->GetPos();
- ScalarType timeInMS;
- timeInMS = timeGeometry->TimeStepToTimePoint( timeStep );
- timeStep = m_CreatedWorldGeometry->TimePointToTimeStep( timeInMS );
- this->GetTime()->SetPos( timeStep );
- }
+ int timeStep = (int) timeEvent->GetPos();
+ ScalarType timeInMS;
+ timeInMS = timeGeometry->TimeStepToTimePoint( timeStep );
+ timeStep = m_CreatedWorldGeometry->TimePointToTimeStep( timeInMS );
+ this->GetTime()->SetPos( timeStep );
}
void
SliceNavigationController
::SetGeometrySlice(const itk::EventObject & geometrySliceEvent)
{
const SliceNavigationController::GeometrySliceEvent* sliceEvent =
dynamic_cast<const SliceNavigationController::GeometrySliceEvent *>(
&geometrySliceEvent);
assert(sliceEvent!=NULL);
this->GetSlice()->SetPos(sliceEvent->GetPos());
}
void
SliceNavigationController::SelectSliceByPoint( const Point3D &point )
{
+ if (m_CreatedWorldGeometry.IsNull())
+ {
+ return;
+ }
+
//@todo add time to PositionEvent and use here!!
SlicedGeometry3D* slicedWorldGeometry = dynamic_cast< SlicedGeometry3D * >(
m_CreatedWorldGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() ).GetPointer() );
if ( slicedWorldGeometry )
{
int bestSlice = -1;
double bestDistance = itk::NumericTraits<double>::max();
int s, slices;
slices = slicedWorldGeometry->GetSlices();
if ( slicedWorldGeometry->GetEvenlySpaced() )
{
mitk::PlaneGeometry *plane = slicedWorldGeometry->GetPlaneGeometry( 0 );
const Vector3D &direction = slicedWorldGeometry->GetDirectionVector();
Point3D projectedPoint;
plane->Project( point, projectedPoint );
// Check whether the point is somewhere within the slice stack volume;
// otherwise, the defualt slice (0) will be selected
if ( direction[0] * (point[0] - projectedPoint[0])
+ direction[1] * (point[1] - projectedPoint[1])
+ direction[2] * (point[2] - projectedPoint[2]) >= 0 )
{
bestSlice = (int)(plane->Distance( point )
/ slicedWorldGeometry->GetSpacing()[2] + 0.5);
}
}
else
{
Point3D projectedPoint;
for ( s = 0; s < slices; ++s )
{
slicedWorldGeometry->GetPlaneGeometry( s )->Project( point, projectedPoint );
Vector3D distance = projectedPoint - point;
ScalarType currentDistance = distance.GetSquaredNorm();
if ( currentDistance < bestDistance )
{
bestDistance = currentDistance;
bestSlice = s;
}
}
}
if ( bestSlice >= 0 )
{
this->GetSlice()->SetPos( bestSlice );
}
else
{
this->GetSlice()->SetPos( 0 );
}
this->SendCreatedWorldGeometryUpdate();
}
}
void
SliceNavigationController::ReorientSlices( const Point3D &point,
const Vector3D &normal )
{
+ if (m_CreatedWorldGeometry.IsNull())
+ {
+ return;
+ }
+
PlaneOperation op( OpORIENT, point, normal );
m_CreatedWorldGeometry->ExecuteOperation( &op );
this->SendCreatedWorldGeometryUpdate();
}
void SliceNavigationController::ReorientSlices(const mitk::Point3D &point,
const mitk::Vector3D &axisVec0, const mitk::Vector3D &axisVec1 )
{
- PlaneOperation op( OpORIENT, point, axisVec0, axisVec1 );
-
- m_CreatedWorldGeometry->ExecuteOperation( &op );
+ if (m_CreatedWorldGeometry)
+ {
+ PlaneOperation op( OpORIENT, point, axisVec0, axisVec1 );
+ m_CreatedWorldGeometry->ExecuteOperation( &op );
- this->SendCreatedWorldGeometryUpdate();
+ this->SendCreatedWorldGeometryUpdate();
+ }
}
mitk::TimeGeometry *
SliceNavigationController::GetCreatedWorldGeometry()
{
return m_CreatedWorldGeometry;
}
const mitk::BaseGeometry *
SliceNavigationController::GetCurrentGeometry3D()
{
if ( m_CreatedWorldGeometry.IsNotNull() )
{
return m_CreatedWorldGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() );
}
else
{
return NULL;
}
}
const mitk::PlaneGeometry *
SliceNavigationController::GetCurrentPlaneGeometry()
{
const mitk::SlicedGeometry3D *slicedGeometry =
dynamic_cast< const mitk::SlicedGeometry3D * >
( this->GetCurrentGeometry3D() );
if ( slicedGeometry )
{
const mitk::PlaneGeometry *planeGeometry =
( slicedGeometry->GetPlaneGeometry(this->GetSlice()->GetPos()) );
return planeGeometry;
}
else
{
return NULL;
}
}
void
SliceNavigationController::SetRenderer( BaseRenderer *renderer )
{
m_Renderer = renderer;
}
BaseRenderer *
SliceNavigationController::GetRenderer() const
{
return m_Renderer;
}
void
SliceNavigationController::AdjustSliceStepperRange()
{
const mitk::SlicedGeometry3D *slicedGeometry =
dynamic_cast< const mitk::SlicedGeometry3D * >
( this->GetCurrentGeometry3D() );
const Vector3D &direction = slicedGeometry->GetDirectionVector();
int c = 0;
int i, k = 0;
for ( i = 0; i < 3; ++i )
{
if ( fabs(direction[i]) < 0.000000001 ) { ++c; }
else { k = i; }
}
if ( c == 2 )
{
ScalarType min = slicedGeometry->GetOrigin()[k];
ScalarType max = min + slicedGeometry->GetExtentInMM( k );
m_Slice->SetRange( min, max );
}
else
{
m_Slice->InvalidateRange();
}
}
void
SliceNavigationController::ExecuteOperation( Operation *operation )
{
// switch on type
// - select best slice for a given point
// - rotate created world geometry according to Operation->SomeInfo()
- if ( !operation )
+ if ( !operation || m_CreatedWorldGeometry.IsNull())
{
return;
}
switch ( operation->GetOperationType() )
{
case OpMOVE: // should be a point operation
{
if ( !m_SliceLocked ) //do not move the cross position
{
// select a slice
PointOperation *po = dynamic_cast< PointOperation * >( operation );
if ( po && po->GetIndex() == -1 )
{
this->SelectSliceByPoint( po->GetPoint() );
}
else if ( po && po->GetIndex() != -1 ) // undo case because index != -1, index holds the old position of this slice
{
this->GetSlice()->SetPos( po->GetIndex() );
}
}
break;
}
case OpRESTOREPLANEPOSITION:
{
m_CreatedWorldGeometry->ExecuteOperation( operation );
this->SendCreatedWorldGeometryUpdate();
break;
}
case OpAPPLYTRANSFORMMATRIX:
{
m_CreatedWorldGeometry->ExecuteOperation( operation );
this->SendCreatedWorldGeometryUpdate();
break;
}
default:
{
// do nothing
break;
}
}
}
mitk::DataNode::Pointer SliceNavigationController::GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes,mitk::Point3D worldposition)
{
mitk::DataNode::Pointer node;
int maxlayer = -32768;
bool isHelper (false);
if(nodes.IsNotNull())
{
for (unsigned int x = 0; x < nodes->size(); x++)
{
nodes->at(x)->GetBoolProperty("helper object", isHelper);
if(nodes->at(x)->GetData()->GetGeometry()->IsInside(worldposition) && isHelper == false)
{
int layer = 0;
if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue;
if(layer > maxlayer)
{
if(static_cast<mitk::DataNode::Pointer>(nodes->at(x))->IsVisible(m_Renderer))
{
node = nodes->at(x);
maxlayer = layer;
}
}
}
}
}
return node;
}
// Relict from the old times, when automous decisions were accepted
// behavior. Remains in here, because some RenderWindows do exist outside
// of StdMultiWidgets.
bool
SliceNavigationController
::ExecuteAction( Action* action, StateEvent const* stateEvent )
{
bool ok = false;
const PositionEvent* posEvent = dynamic_cast< const PositionEvent * >(
stateEvent->GetEvent() );
if ( posEvent != NULL )
{
if ( m_CreatedWorldGeometry.IsNull() )
{
return true;
}
switch (action->GetActionId())
{
case AcMOVE:
{
BaseRenderer *baseRenderer = posEvent->GetSender();
if ( !baseRenderer )
{
baseRenderer = const_cast<BaseRenderer *>(
GlobalInteraction::GetInstance()->GetFocus() );
}
if ( baseRenderer )
if ( baseRenderer->GetMapperID() == 1 )
{
PointOperation doOp(OpMOVE, posEvent->GetWorldPosition());
this->ExecuteOperation( &doOp );
// If click was performed in this render window than we have to update the status bar information about position and pixel value.
if(baseRenderer == m_Renderer)
{
{
std::string statusText;
TNodePredicateDataType<mitk::Image>::Pointer isImageData = TNodePredicateDataType<mitk::Image>::New();
mitk::DataStorage::SetOfObjects::ConstPointer nodes = baseRenderer->GetDataStorage()->GetSubset(isImageData).GetPointer();
mitk::Point3D worldposition = posEvent->GetWorldPosition();
//int maxlayer = -32768;
mitk::Image::Pointer image3D;
mitk::DataNode::Pointer node;
mitk::DataNode::Pointer topSourceNode;
bool isBinary (false);
node = this->GetTopLayerNode(nodes,worldposition);
if(node.IsNotNull())
{
node->GetBoolProperty("binary", isBinary);
if(isBinary)
{
mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = baseRenderer->GetDataStorage()->GetSources(node, NULL, true);
if(!sourcenodes->empty())
{
topSourceNode = this->GetTopLayerNode(sourcenodes,worldposition);
}
if(topSourceNode.IsNotNull())
{
image3D = dynamic_cast<mitk::Image*>(topSourceNode->GetData());
}
else
{
image3D = dynamic_cast<mitk::Image*>(node->GetData());
}
}
else
{
image3D = dynamic_cast<mitk::Image*>(node->GetData());
}
}
std::stringstream stream;
stream.imbue(std::locale::classic());
// get the position and gray value from the image and build up status bar text
if(image3D.IsNotNull())
{
itk::Index<3> p;
image3D->GetGeometry()->WorldToIndex(worldposition, p);
stream.precision(2);
stream<<"Position: <" << std::fixed <<worldposition[0] << ", " << std::fixed << worldposition[1] << ", " << std::fixed << worldposition[2] << "> mm";
stream<<"; Index: <"<<p[0] << ", " << p[1] << ", " << p[2] << "> ";
mitk::ScalarType pixelValue = image3D->GetPixelValueByIndex(p, baseRenderer->GetTimeStep());
if (fabs(pixelValue)>1000000 || fabs(pixelValue) < 0.01)
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: " << std::scientific<< pixelValue <<" ";
}
else
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< pixelValue <<" ";
}
}
else
{
stream << "No image information at this position!";
}
statusText = stream.str();
mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str());
}
}
ok = true;
break;
}
}
default:
ok = true;
break;
}
return ok;
}
const DisplayPositionEvent *displPosEvent =
dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
if ( displPosEvent != NULL )
{
return true;
}
return false;
}
} // namespace
diff --git a/Core/Code/DataManagement/mitkBaseGeometry.cpp b/Core/Code/DataManagement/mitkBaseGeometry.cpp
index 13164835ed..58ad8440a6 100644
--- a/Core/Code/DataManagement/mitkBaseGeometry.cpp
+++ b/Core/Code/DataManagement/mitkBaseGeometry.cpp
@@ -1,1088 +1,1089 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <sstream>
#include <iomanip>
#include "mitkBaseGeometry.h"
#include "mitkVector.h"
#include "mitkMatrixConvert.h"
#include <vtkMatrixToLinearTransform.h>
#include <vtkMatrix4x4.h>
#include "mitkRotationOperation.h"
#include "mitkRestorePlanePositionOperation.h"
#include "mitkApplyTransformMatrixOperation.h"
#include "mitkPointOperation.h"
#include "mitkInteractionConst.h"
#include "mitkModifiedLock.h"
mitk::BaseGeometry::BaseGeometry(): Superclass(), mitk::OperationActor(),
m_FrameOfReferenceID(0), m_IndexToWorldTransformLastModified(0), m_ImageGeometry(false), m_ModifiedLockFlag(false), m_ModifiedCalledFlag(false)
{
m_VtkMatrix = vtkMatrix4x4::New();
m_VtkIndexToWorldTransform = vtkMatrixToLinearTransform::New();
m_VtkIndexToWorldTransform->SetInput(m_VtkMatrix);
Initialize();
}
mitk::BaseGeometry::BaseGeometry(const BaseGeometry& other): Superclass(), mitk::OperationActor(), //m_TimeBounds(other.m_TimeBounds),
m_FrameOfReferenceID(other.m_FrameOfReferenceID), m_IndexToWorldTransformLastModified(other.m_IndexToWorldTransformLastModified), m_Origin(other.m_Origin),
m_ImageGeometry(other.m_ImageGeometry), m_ModifiedLockFlag(false), m_ModifiedCalledFlag(false)
{
m_VtkMatrix = vtkMatrix4x4::New();
m_VtkIndexToWorldTransform = vtkMatrixToLinearTransform::New();
m_VtkIndexToWorldTransform->SetInput(m_VtkMatrix);
other.InitializeGeometry(this);
}
mitk::BaseGeometry::~BaseGeometry()
{
m_VtkMatrix->Delete();
m_VtkIndexToWorldTransform->Delete();
}
const mitk::Point3D& mitk::BaseGeometry::GetOrigin() const
{
return m_Origin;
}
void mitk::BaseGeometry::SetOrigin(const Point3D & origin)
{
mitk::ModifiedLock lock(this);
if(origin!=GetOrigin())
{
m_Origin = origin;
m_IndexToWorldTransform->SetOffset(m_Origin.GetVectorFromOrigin());
Modified();
TransferItkToVtkTransform();
}
}
void mitk::BaseGeometry::TransferItkToVtkTransform()
{
mitk::ModifiedLock lock(this);
// copy m_IndexToWorldTransform into m_VtkIndexToWorldTransform
TransferItkTransformToVtkMatrix(m_IndexToWorldTransform.GetPointer(), m_VtkMatrix);
m_VtkIndexToWorldTransform->Modified();
}
static void CopySpacingFromTransform(mitk::AffineTransform3D* transform, mitk::Vector3D& spacing)
{
mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = transform->GetMatrix().GetVnlMatrix();
spacing[0]=vnlmatrix.get_column(0).magnitude();
spacing[1]=vnlmatrix.get_column(1).magnitude();
spacing[2]=vnlmatrix.get_column(2).magnitude();
}
void mitk::BaseGeometry::Initialize()
{
float b[6] = {0,1,0,1,0,1};
SetFloatBounds(b);
if(m_IndexToWorldTransform.IsNull())
m_IndexToWorldTransform = TransformType::New();
else
m_IndexToWorldTransform->SetIdentity();
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
m_VtkMatrix->Identity();
//m_TimeBounds[0]=ScalarTypeNumericTraits::NonpositiveMin(); m_TimeBounds[1]=ScalarTypeNumericTraits::max();
m_FrameOfReferenceID = 0;
m_ImageGeometry = false;
this->PostInitialize();
}
void mitk::BaseGeometry::PostInitializeGeometry(BaseGeometry * newGeometry) const
{
newGeometry->m_ImageGeometry = m_ImageGeometry;
}
void mitk::BaseGeometry::SetFloatBounds(const float bounds[6])
{
mitk::BoundingBox::BoundsArrayType b;
const float *input = bounds;
int i=0;
for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6 ;++i) *it++ = (mitk::ScalarType)*input++;
SetBounds(b);
}
void mitk::BaseGeometry::SetFloatBounds(const double bounds[6])
{
mitk::BoundingBox::BoundsArrayType b;
const double *input = bounds;
int i=0;
for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6 ;++i) *it++ = (mitk::ScalarType)*input++;
SetBounds(b);
}
/** Initialize the geometry */
void
mitk::BaseGeometry::InitializeGeometry(BaseGeometry* newGeometry) const
{
newGeometry->SetBounds(m_BoundingBox->GetBounds());
// we have to create a new transform!!
//newGeometry->SetTimeBounds(m_TimeBounds);
newGeometry->SetFrameOfReferenceID(GetFrameOfReferenceID());
if(m_IndexToWorldTransform)
{
TransformType::Pointer indexToWorldTransform = m_IndexToWorldTransform->Clone();
newGeometry->SetIndexToWorldTransform(indexToWorldTransform);
}
this->PostInitializeGeometry(newGeometry);
}
void mitk::BaseGeometry::PostInitialize()
{
}
/** Set the bounds */
void mitk::BaseGeometry::SetBounds(const BoundsArrayType& bounds)
{
mitk::ModifiedLock lock(this);
PreSetBounds(bounds);
m_BoundingBox = BoundingBoxType::New();
BoundingBoxType::PointsContainer::Pointer pointscontainer =
BoundingBoxType::PointsContainer::New();
BoundingBoxType::PointType p;
BoundingBoxType::PointIdentifier pointid;
for(pointid=0; pointid<2;++pointid)
{
unsigned int i;
for(i=0; i<m_NDimensions; ++i)
{
p[i] = bounds[2*i+pointid];
}
pointscontainer->InsertElement(pointid, p);
}
m_BoundingBox->SetPoints(pointscontainer);
m_BoundingBox->ComputeBoundingBox();
this->Modified();
}
void mitk::BaseGeometry::PreSetBounds(const BoundsArrayType& /*bounds*/){};
void mitk::BaseGeometry::SetIndexToWorldTransform(mitk::AffineTransform3D* transform)
{
mitk::ModifiedLock lock(this);
PreSetIndexToWorldTransform(transform);
m_IndexToWorldTransform = transform;
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
TransferItkToVtkTransform();
Modified();
PostSetIndexToWorldTransform(transform);
}
void mitk::BaseGeometry::PreSetIndexToWorldTransform(mitk::AffineTransform3D* /*transform*/)
{}
void mitk::BaseGeometry::PostSetIndexToWorldTransform(mitk::AffineTransform3D* /*transform*/)
{}
const mitk::BaseGeometry::BoundsArrayType mitk::BaseGeometry::GetBounds() const
{
assert(m_BoundingBox.IsNotNull());
return m_BoundingBox->GetBounds();
}
bool mitk::BaseGeometry::IsValid() const
{
return true;
}
void mitk::BaseGeometry::SetSpacing(const mitk::Vector3D& aSpacing, bool enforceSetSpacing )
{
PreSetSpacing(aSpacing);
_SetSpacing(aSpacing, enforceSetSpacing);
}
void mitk::BaseGeometry::PreSetSpacing(const mitk::Vector3D& /*aSpacing*/)
{}
void mitk::BaseGeometry::_SetSpacing(const mitk::Vector3D& aSpacing, bool enforceSetSpacing){
if(mitk::Equal(m_Spacing, aSpacing) == false || enforceSetSpacing)
{
assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0);
m_Spacing = aSpacing;
AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = m_IndexToWorldTransform->GetMatrix().GetVnlMatrix();
mitk::VnlVector col;
col = vnlmatrix.get_column(0); col.normalize(); col*=aSpacing[0]; vnlmatrix.set_column(0, col);
col = vnlmatrix.get_column(1); col.normalize(); col*=aSpacing[1]; vnlmatrix.set_column(1, col);
col = vnlmatrix.get_column(2); col.normalize(); col*=aSpacing[2]; vnlmatrix.set_column(2, col);
Matrix3D matrix;
matrix = vnlmatrix;
AffineTransform3D::Pointer transform = AffineTransform3D::New();
transform->SetMatrix(matrix);
transform->SetOffset(m_IndexToWorldTransform->GetOffset());
SetIndexToWorldTransform(transform.GetPointer());
}
}
mitk::Vector3D mitk::BaseGeometry::GetAxisVector(unsigned int direction) const
{
Vector3D frontToBack;
frontToBack.SetVnlVector(m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction));
frontToBack *= GetExtent(direction);
return frontToBack;
}
mitk::ScalarType mitk::BaseGeometry::GetExtent(unsigned int direction) const
{
assert(m_BoundingBox.IsNotNull());
if (direction>=m_NDimensions)
mitkThrow() << "Direction is too big. This geometry is for 3D Data";
BoundsArrayType bounds = m_BoundingBox->GetBounds();
return bounds[direction*2+1]-bounds[direction*2];
}
bool mitk::BaseGeometry::Is2DConvertable()
{
bool isConvertableWithoutLoss = true;
do
{
if (this->GetSpacing()[2] != 1)
{
isConvertableWithoutLoss = false;
break;
}
if (this->GetOrigin()[2] != 0)
{
isConvertableWithoutLoss = false;
break;
}
mitk::Vector3D col0, col1, col2;
col0.SetVnlVector(this->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
col1.SetVnlVector(this->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
col2.SetVnlVector(this->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
if ((col0[2] != 0) || (col1[2] != 0) || (col2[0] != 0) || (col2[1] != 0) || (col2[2] != 1))
{
isConvertableWithoutLoss = false;
break;
}
} while (0);
return isConvertableWithoutLoss;
}
mitk::Point3D mitk::BaseGeometry::GetCenter() const
{
assert(m_BoundingBox.IsNotNull());
return m_IndexToWorldTransform->TransformPoint(m_BoundingBox->GetCenter());
}
double mitk::BaseGeometry::GetDiagonalLength2() const
{
Vector3D diagonalvector = GetCornerPoint()-GetCornerPoint(false, false, false);
return diagonalvector.GetSquaredNorm();
}
//##Documentation
//## @brief Get the length of the diagonal of the bounding-box in mm
//##
double mitk::BaseGeometry::GetDiagonalLength() const
{
return sqrt(GetDiagonalLength2());
}
mitk::Point3D mitk::BaseGeometry::GetCornerPoint(int id) const
{
assert(id >= 0);
assert(this->IsBoundingBoxNull()==false);
BoundingBox::BoundsArrayType bounds = this->GetBoundingBox()->GetBounds();
Point3D cornerpoint;
switch(id)
{
case 0: FillVector3D(cornerpoint, bounds[0],bounds[2],bounds[4]); break;
case 1: FillVector3D(cornerpoint, bounds[0],bounds[2],bounds[5]); break;
case 2: FillVector3D(cornerpoint, bounds[0],bounds[3],bounds[4]); break;
case 3: FillVector3D(cornerpoint, bounds[0],bounds[3],bounds[5]); break;
case 4: FillVector3D(cornerpoint, bounds[1],bounds[2],bounds[4]); break;
case 5: FillVector3D(cornerpoint, bounds[1],bounds[2],bounds[5]); break;
case 6: FillVector3D(cornerpoint, bounds[1],bounds[3],bounds[4]); break;
case 7: FillVector3D(cornerpoint, bounds[1],bounds[3],bounds[5]); break;
default:
{
itkExceptionMacro(<<"A cube only has 8 corners. These are labeled 0-7.");
}
}
if(m_ImageGeometry)
{
// Here i have to adjust the 0.5 offset manually, because the cornerpoint is the corner of the
// bounding box. The bounding box itself is no image, so it is corner-based
FillVector3D(cornerpoint, cornerpoint[0]-0.5, cornerpoint[1]-0.5, cornerpoint[2]-0.5);
}
return this->GetIndexToWorldTransform()->TransformPoint(cornerpoint);
}
mitk::Point3D mitk::BaseGeometry::GetCornerPoint(bool xFront, bool yFront, bool zFront) const
{
assert(this->IsBoundingBoxNull()==false);
BoundingBox::BoundsArrayType bounds = this->GetBoundingBox()->GetBounds();
Point3D cornerpoint;
cornerpoint[0] = (xFront ? bounds[0] : bounds[1]);
cornerpoint[1] = (yFront ? bounds[2] : bounds[3]);
cornerpoint[2] = (zFront ? bounds[4] : bounds[5]);
if(m_ImageGeometry)
{
// Here i have to adjust the 0.5 offset manually, because the cornerpoint is the corner of the
// bounding box. The bounding box itself is no image, so it is corner-based
FillVector3D(cornerpoint, cornerpoint[0]-0.5, cornerpoint[1]-0.5, cornerpoint[2]-0.5);
}
return this->GetIndexToWorldTransform()->TransformPoint(cornerpoint);
}
mitk::ScalarType mitk::BaseGeometry::GetExtentInMM(int direction) const
{
return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction).magnitude()*GetExtent(direction);
}
void mitk::BaseGeometry::SetExtentInMM(int direction, ScalarType extentInMM)
{
mitk::ModifiedLock lock(this);
ScalarType len = GetExtentInMM(direction);
if(fabs(len - extentInMM)>=mitk::eps)
{
AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = m_IndexToWorldTransform->GetMatrix().GetVnlMatrix();
if(len>extentInMM)
vnlmatrix.set_column(direction, vnlmatrix.get_column(direction)/len*extentInMM);
else
vnlmatrix.set_column(direction, vnlmatrix.get_column(direction)*extentInMM/len);
Matrix3D matrix;
matrix = vnlmatrix;
m_IndexToWorldTransform->SetMatrix(matrix);
TransferItkToVtkTransform();
Modified();
}
PostSetExtentInMM(direction,extentInMM);
}
void mitk::BaseGeometry::PostSetExtentInMM(int /*direction*/, ScalarType /*extentInMM*/){};
bool mitk::BaseGeometry::IsInside(const mitk::Point3D& p) const
{
mitk::Point3D index;
WorldToIndex(p, index);
return IsIndexInside(index);
}
bool mitk::BaseGeometry::IsIndexInside(const mitk::Point3D& index) const
{
bool inside = false;
//if it is an image geometry, we need to convert the index to discrete values
//this is done by applying the rounding function also used in WorldToIndex (see line 323)
if (m_ImageGeometry)
{
mitk::Point3D discretIndex;
discretIndex[0]=itk::Math::RoundHalfIntegerUp<mitk::ScalarType>( index[0] );
discretIndex[1]=itk::Math::RoundHalfIntegerUp<mitk::ScalarType>( index[1] );
discretIndex[2]=itk::Math::RoundHalfIntegerUp<mitk::ScalarType>( index[2] );
inside = this->GetBoundingBox()->IsInside(discretIndex);
//we have to check if the index is at the upper border of each dimension,
// because the boundingbox is not centerbased
if (inside)
{
const BoundingBox::BoundsArrayType& bounds = this->GetBoundingBox()->GetBounds();
if((discretIndex[0] == bounds[1]) ||
(discretIndex[1] == bounds[3]) ||
(discretIndex[2] == bounds[5]))
inside = false;
}
}
else
inside = this->GetBoundingBox()->IsInside(index);
return inside;
}
void mitk::BaseGeometry::WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
{
BackTransform(pt_mm, pt_units);
}
void mitk::BaseGeometry::WorldToIndex( const mitk::Vector3D &vec_mm, mitk::Vector3D &vec_units) const
{
BackTransform( vec_mm, vec_units);
}
void mitk::BaseGeometry::BackTransform(const mitk::Vector3D& in, mitk::Vector3D& out) const
{
// Get WorldToIndex transform
if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime())
{
m_InvertedTransform = TransformType::New();
if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() ))
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." );
}
m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime();
}
// Check for valid matrix inversion
const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix();
if(inverse.GetVnlMatrix().has_nans())
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl
<< m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl
<< inverse );
}
// Transform vector
for (unsigned int i = 0; i < 3; i++)
{
out[i] = 0.0;
for (unsigned int j = 0; j < 3; j++)
{
out[i] += inverse[i][j]*in[j];
}
}
}
void mitk::BaseGeometry::BackTransform(const mitk::Point3D &in, mitk::Point3D& out) const
{
ScalarType temp[3];
unsigned int i, j;
const TransformType::OffsetType& offset = m_IndexToWorldTransform->GetOffset();
// Remove offset
for (j = 0; j < 3; j++)
{
temp[j] = in[j] - offset[j];
}
// Get WorldToIndex transform
if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime())
{
m_InvertedTransform = TransformType::New();
if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() ))
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." );
}
m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime();
}
// Check for valid matrix inversion
const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix();
if(inverse.GetVnlMatrix().has_nans())
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl
<< m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl
<< inverse );
}
// Transform point
for (i = 0; i < 3; i++)
{
out[i] = 0.0;
for (j = 0; j < 3; j++)
{
out[i] += inverse[i][j]*temp[j];
}
}
}
mitk::VnlVector mitk::BaseGeometry::GetOriginVnl() const
{
return const_cast<Self*>(this)->m_Origin.GetVnlVector();
}
vtkLinearTransform* mitk::BaseGeometry::GetVtkTransform() const
{
return (vtkLinearTransform*)m_VtkIndexToWorldTransform;
}
void mitk::BaseGeometry::SetIdentity()
{
mitk::ModifiedLock lock(this);
m_IndexToWorldTransform->SetIdentity();
m_Origin.Fill(0);
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing);
Modified();
TransferItkToVtkTransform();
}
void mitk::BaseGeometry::TransferVtkToItkTransform()
{
TransferVtkMatrixToItkTransform(m_VtkMatrix, m_IndexToWorldTransform.GetPointer());
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
TransferItkToVtkTransform();
}
void mitk::BaseGeometry::Compose( const mitk::BaseGeometry::TransformType * other, bool pre )
{
mitk::ModifiedLock lock(this);
m_IndexToWorldTransform->Compose(other, pre);
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
Modified();
TransferItkToVtkTransform();
}
void mitk::BaseGeometry::Compose( const vtkMatrix4x4 * vtkmatrix, bool pre )
{
mitk::BaseGeometry::TransformType::Pointer itkTransform = mitk::BaseGeometry::TransformType::New();
TransferVtkMatrixToItkTransform(vtkmatrix, itkTransform.GetPointer());
Compose(itkTransform, pre);
}
void mitk::BaseGeometry::Translate(const Vector3D & vector)
{
if((vector[0] != 0) || (vector[1] != 0) || (vector[2] != 0))
{
this->SetOrigin(m_Origin + vector);
}
}
void mitk::BaseGeometry::IndexToWorld(const mitk::Point3D &pt_units, mitk::Point3D &pt_mm) const
{
pt_mm = m_IndexToWorldTransform->TransformPoint(pt_units);
}
void mitk::BaseGeometry::IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
{
vec_mm = m_IndexToWorldTransform->TransformVector(vec_units);
}
#include <vtkTransform.h>
void mitk::BaseGeometry::ExecuteOperation(Operation* operation)
{
mitk::ModifiedLock lock(this);
vtkTransform *vtktransform = vtkTransform::New();
vtktransform->SetMatrix(m_VtkMatrix);
switch (operation->GetOperationType())
{
case OpNOTHING:
break;
case OpMOVE:
{
mitk::PointOperation *pointOp = dynamic_cast<mitk::PointOperation *>(operation);
if (pointOp == NULL)
{
//mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000);
return;
}
mitk::Point3D newPos = pointOp->GetPoint();
ScalarType data[3];
vtktransform->GetPosition(data);
vtktransform->PostMultiply();
vtktransform->Translate(newPos[0], newPos[1], newPos[2]);
vtktransform->PreMultiply();
break;
}
case OpSCALE:
{
mitk::PointOperation *pointOp = dynamic_cast<mitk::PointOperation *>(operation);
if (pointOp == NULL)
{
//mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000);
return;
}
mitk::Point3D newScale = pointOp->GetPoint();
ScalarType data[3];
/* calculate new scale: newscale = oldscale * (oldscale + scaletoadd)/oldscale */
data[0] = 1 + (newScale[0] / GetMatrixColumn(0).magnitude());
data[1] = 1 + (newScale[1] / GetMatrixColumn(1).magnitude());
data[2] = 1 + (newScale[2] / GetMatrixColumn(2).magnitude());
mitk::Point3D center = const_cast<mitk::BoundingBox*>(m_BoundingBox.GetPointer())->GetCenter();
ScalarType pos[3];
vtktransform->GetPosition(pos);
vtktransform->PostMultiply();
vtktransform->Translate(-pos[0], -pos[1], -pos[2]);
vtktransform->Translate(-center[0], -center[1], -center[2]);
vtktransform->PreMultiply();
vtktransform->Scale(data[0], data[1], data[2]);
vtktransform->PostMultiply();
vtktransform->Translate(+center[0], +center[1], +center[2]);
vtktransform->Translate(pos[0], pos[1], pos[2]);
vtktransform->PreMultiply();
break;
}
case OpROTATE:
{
mitk::RotationOperation *rotateOp = dynamic_cast<mitk::RotationOperation *>(operation);
if (rotateOp == NULL)
{
//mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000);
return;
}
Vector3D rotationVector = rotateOp->GetVectorOfRotation();
Point3D center = rotateOp->GetCenterOfRotation();
ScalarType angle = rotateOp->GetAngleOfRotation();
vtktransform->PostMultiply();
vtktransform->Translate(-center[0], -center[1], -center[2]);
vtktransform->RotateWXYZ(angle, rotationVector[0], rotationVector[1], rotationVector[2]);
vtktransform->Translate(center[0], center[1], center[2]);
vtktransform->PreMultiply();
break;
}
case OpRESTOREPLANEPOSITION:
{
//Copy necessary to avoid vtk warning
vtkMatrix4x4* matrix = vtkMatrix4x4::New();
TransferItkTransformToVtkMatrix(dynamic_cast<mitk::RestorePlanePositionOperation*>(operation)->GetTransform().GetPointer(), matrix);
vtktransform->SetMatrix(matrix);
+ matrix->Delete();
break;
}
case OpAPPLYTRANSFORMMATRIX:
{
ApplyTransformMatrixOperation *applyMatrixOp = dynamic_cast< ApplyTransformMatrixOperation* >( operation );
vtktransform->SetMatrix(applyMatrixOp->GetMatrix());
break;
}
default:
vtktransform->Delete();
return;
}
m_VtkMatrix->DeepCopy(vtktransform->GetMatrix());
TransferVtkToItkTransform();
Modified();
vtktransform->Delete();
}
mitk::VnlVector mitk::BaseGeometry::GetMatrixColumn(unsigned int direction) const
{
return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction);
}
mitk::BoundingBox::Pointer mitk::BaseGeometry::CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D* transform) const
{
mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New();
mitk::BoundingBox::PointIdentifier pointid=0;
unsigned char i;
if(transform!=NULL)
{
mitk::AffineTransform3D::Pointer inverse = mitk::AffineTransform3D::New();
transform->GetInverse(inverse);
for(i=0; i<8; ++i)
pointscontainer->InsertElement( pointid++, inverse->TransformPoint( GetCornerPoint(i) ));
}
else
{
for(i=0; i<8; ++i)
pointscontainer->InsertElement( pointid++, GetCornerPoint(i) );
}
mitk::BoundingBox::Pointer result = mitk::BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
return result;
}
//void mitk::BaseGeometry::SetTimeBounds(const TimeBounds& timebounds)
//{
// mitk::ModifiedLock lock(this);
//
// if(m_TimeBounds != timebounds)
// {
// m_TimeBounds = timebounds;
// Modified();
// }
// PostSetTimeBounds(timebounds);
//}
//
//void mitk::BaseGeometry::PostSetTimeBounds(const TimeBounds& timebounds)
//{}
const std::string mitk::BaseGeometry::GetTransformAsString( TransformType* transformType )
{
std::ostringstream out;
out << '[';
for( int i=0; i<3; ++i )
{
out << '[';
for( int j=0; j<3; ++j )
out << transformType->GetMatrix().GetVnlMatrix().get(i, j) << ' ';
out << ']';
}
out << "][";
for( int i=0; i<3; ++i )
out << transformType->GetOffset()[i] << ' ';
out << "]\0";
return out.str();
}
void mitk::BaseGeometry::SetIndexToWorldTransformByVtkMatrix(vtkMatrix4x4* vtkmatrix)
{
m_VtkMatrix->DeepCopy(vtkmatrix);
TransferVtkToItkTransform();
}
void mitk::BaseGeometry::WorldToIndex(const mitk::Point3D & /*atPt3d_mm*/, const mitk::Vector3D &vec_mm, mitk::Vector3D &vec_units) const
{
MITK_WARN<<"Warning! Call of the deprecated function BaseGeometry::WorldToIndex(point, vec, vec). Use BaseGeometry::WorldToIndex(vec, vec) instead!";
//BackTransform(atPt3d_mm, vec_mm, vec_units);
this->WorldToIndex(vec_mm, vec_units);
}
void mitk::BaseGeometry::IndexToWorld(const mitk::Point3D &/*atPt3d_units*/, const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
{
MITK_WARN<<"Warning! Call of the deprecated function BaseGeometry::IndexToWorld(point, vec, vec). Use BaseGeometry::IndexToWorld(vec, vec) instead!";
//vec_mm = m_IndexToWorldTransform->TransformVector(vec_units);
this->IndexToWorld(vec_units, vec_mm);
}
void mitk::BaseGeometry::BackTransform(const mitk::Point3D &/*at*/, const mitk::Vector3D &in, mitk::Vector3D& out) const
{
MITK_INFO<<"Warning! Call of the deprecated function BaseGeometry::BackTransform(point, vec, vec). Use BaseGeometry::BackTransform(vec, vec) instead!";
//// Get WorldToIndex transform
//if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime())
//{
// m_InvertedTransform = TransformType::New();
// if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() ))
// {
// itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." );
// }
// m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime();
//}
//// Check for valid matrix inversion
//const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix();
//if(inverse.GetVnlMatrix().has_nans())
//{
// itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl
// << m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl
// << inverse );
//}
//// Transform vector
//for (unsigned int i = 0; i < 3; i++)
//{
// out[i] = 0.0;
// for (unsigned int j = 0; j < 3; j++)
// {
// out[i] += inverse[i][j]*in[j];
// }
//}
this->BackTransform(in, out);
}
vtkMatrix4x4* mitk::BaseGeometry::GetVtkMatrix(){
return m_VtkMatrix;
}
bool mitk::BaseGeometry::IsBoundingBoxNull() const{
return m_BoundingBox.IsNull();
}
bool mitk::BaseGeometry::IsIndexToWorldTransformNull() const{
return m_IndexToWorldTransform.IsNull();
}
void
mitk::BaseGeometry::ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry )
{
// If Geometry is switched to ImageGeometry, you have to put an offset to the origin, because
// imageGeometries origins are pixel-center-based
// ... and remove the offset, if you switch an imageGeometry back to a normal geometry
// For more information please see the Geometry documentation page
if(m_ImageGeometry == isAnImageGeometry)
return;
const BoundingBox::BoundsArrayType& boundsarray =
this->GetBoundingBox()->GetBounds();
Point3D originIndex;
FillVector3D(originIndex, boundsarray[0], boundsarray[2], boundsarray[4]);
if(isAnImageGeometry == true)
FillVector3D( originIndex,
originIndex[0] + 0.5,
originIndex[1] + 0.5,
originIndex[2] + 0.5 );
else
FillVector3D( originIndex,
originIndex[0] - 0.5,
originIndex[1] - 0.5,
originIndex[2] - 0.5 );
Point3D originWorld;
originWorld = GetIndexToWorldTransform()
->TransformPoint( originIndex );
// instead could as well call IndexToWorld(originIndex,originWorld);
SetOrigin(originWorld);
this->SetImageGeometry(isAnImageGeometry);
}
//itk::LightObject::Pointer mitk::BaseGeometry::InternalClone() const
//{
// Self::Pointer newGeometry = new Self(*this);
// newGeometry->UnRegister();
// return newGeometry.GetPointer();
//}
void mitk::BaseGeometry::PrintSelf(std::ostream& os, itk::Indent indent) const
{
os << indent << " IndexToWorldTransform: ";
if(this->IsIndexToWorldTransformNull())
os << "NULL" << std::endl;
else
{
// from itk::MatrixOffsetTransformBase
unsigned int i, j;
os << std::endl;
os << indent << "Matrix: " << std::endl;
for (i = 0; i < 3; i++)
{
os << indent.GetNextIndent();
for (j = 0; j < 3; j++)
{
os << this->GetIndexToWorldTransform()->GetMatrix()[i][j] << " ";
}
os << std::endl;
}
os << indent << "Offset: " << this->GetIndexToWorldTransform()->GetOffset() << std::endl;
os << indent << "Center: " << this->GetIndexToWorldTransform()->GetCenter() << std::endl;
os << indent << "Translation: " << this->GetIndexToWorldTransform()->GetTranslation() << std::endl;
os << indent << "Inverse: " << std::endl;
for (i = 0; i < 3; i++)
{
os << indent.GetNextIndent();
for (j = 0; j < 3; j++)
{
os << this->GetIndexToWorldTransform()->GetInverseMatrix()[i][j] << " ";
}
os << std::endl;
}
// from itk::ScalableAffineTransform
os << indent << "Scale : ";
for (i = 0; i < 3; i++)
{
os << this->GetIndexToWorldTransform()->GetScale()[i] << " ";
}
os << std::endl;
}
os << indent << " BoundingBox: ";
if(this->IsBoundingBoxNull())
os << "NULL" << std::endl;
else
{
os << indent << "( ";
for (unsigned int i=0; i<3; i++)
{
os << this->GetBoundingBox()->GetBounds()[2*i] << "," << this->GetBoundingBox()->GetBounds()[2*i+1] << " ";
}
os << " )" << std::endl;
}
os << indent << " Origin: " << this->GetOrigin() << std::endl;
os << indent << " ImageGeometry: " << this->GetImageGeometry() << std::endl;
os << indent << " Spacing: " << this->GetSpacing() << std::endl;
//os << indent << " TimeBounds: " << this->GetTimeBounds() << std::endl;
}
void mitk::BaseGeometry::Modified() const{
if(!m_ModifiedLockFlag)
Superclass::Modified();
else
m_ModifiedCalledFlag = true;
}
bool mitk::Equal( const mitk::BaseGeometry::BoundingBoxType *leftHandSide, const mitk::BaseGeometry::BoundingBoxType *rightHandSide, ScalarType eps, bool verbose )
{
if(( leftHandSide == NULL) || ( rightHandSide == NULL ))
{
MITK_ERROR << "mitk::Equal( const mitk::Geometry3D::BoundingBoxType *leftHandSide, const mitk::Geometry3D::BoundingBoxType *rightHandSide, ScalarType eps, bool verbose ) does not with NULL pointer input.";
return false;
}
return Equal( *leftHandSide, *rightHandSide, eps, verbose);
}
bool mitk::Equal( const mitk::BaseGeometry::BoundingBoxType& leftHandSide, const mitk::BaseGeometry::BoundingBoxType& rightHandSide, ScalarType eps, bool verbose )
{
bool result = true;
BaseGeometry::BoundsArrayType rightBounds = rightHandSide.GetBounds();
BaseGeometry::BoundsArrayType leftBounds = leftHandSide.GetBounds();
BaseGeometry::BoundsArrayType::Iterator itLeft = leftBounds.Begin();
for( BaseGeometry::BoundsArrayType::Iterator itRight = rightBounds.Begin(); itRight != rightBounds.End(); ++itRight)
{
if(( !mitk::Equal( *itLeft, *itRight, eps )) )
{
if(verbose)
{
MITK_INFO << "[( Geometry3D::BoundingBoxType )] bounds are not equal.";
MITK_INFO << "rightHandSide is " << setprecision(12) << *itRight << " : leftHandSide is " << *itLeft << " and tolerance is " << eps;
}
result = false;
}
itLeft++;
}
return result;
}
bool mitk::Equal(const mitk::BaseGeometry *leftHandSide, const mitk::BaseGeometry *rightHandSide, ScalarType eps, bool verbose)
{
if(( leftHandSide == NULL) || ( rightHandSide == NULL ))
{
MITK_ERROR << "mitk::Equal(const mitk::Geometry3D *leftHandSide, const mitk::Geometry3D *rightHandSide, ScalarType eps, bool verbose) does not with NULL pointer input.";
return false;
}
return Equal( *leftHandSide, *rightHandSide, eps, verbose);
}
bool mitk::Equal(const mitk::BaseGeometry& leftHandSide, const mitk::BaseGeometry& rightHandSide, ScalarType eps, bool verbose)
{
bool result = true;
//Compare spacings
if( !mitk::Equal( leftHandSide.GetSpacing(), rightHandSide.GetSpacing(), eps ) )
{
if(verbose)
{
MITK_INFO << "[( Geometry3D )] Spacing differs.";
MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetSpacing() << " : leftHandSide is " << leftHandSide.GetSpacing() << " and tolerance is " << eps;
}
result = false;
}
//Compare Origins
if( !mitk::Equal( leftHandSide.GetOrigin(), rightHandSide.GetOrigin(), eps ) )
{
if(verbose)
{
MITK_INFO << "[( Geometry3D )] Origin differs.";
MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetOrigin() << " : leftHandSide is " << leftHandSide.GetOrigin() << " and tolerance is " << eps;
}
result = false;
}
//Compare Axis and Extents
for( unsigned int i=0; i<3; ++i)
{
if( !mitk::Equal( leftHandSide.GetAxisVector(i), rightHandSide.GetAxisVector(i), eps))
{
if(verbose)
{
MITK_INFO << "[( Geometry3D )] AxisVector #" << i << " differ";
MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetAxisVector(i) << " : leftHandSide is " << leftHandSide.GetAxisVector(i) << " and tolerance is " << eps;
}
result = false;
}
if( !mitk::Equal( leftHandSide.GetExtent(i), rightHandSide.GetExtent(i), eps) )
{
if(verbose)
{
MITK_INFO << "[( Geometry3D )] Extent #" << i << " differ";
MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetExtent(i) << " : leftHandSide is " << leftHandSide.GetExtent(i) << " and tolerance is " << eps;
}
result = false;
}
}
//Compare ImageGeometry Flag
if( rightHandSide.GetImageGeometry() != leftHandSide.GetImageGeometry() )
{
if(verbose)
{
MITK_INFO << "[( Geometry3D )] GetImageGeometry is different.";
MITK_INFO << "rightHandSide is " << rightHandSide.GetImageGeometry() << " : leftHandSide is " << leftHandSide.GetImageGeometry();
}
result = false;
}
//Compare BoundingBoxes
if( !mitk::Equal( *leftHandSide.GetBoundingBox(), *rightHandSide.GetBoundingBox(), eps, verbose) )
{
result = false;
}
//Compare IndexToWorldTransform Matrix
if( !mitk::Equal( *leftHandSide.GetIndexToWorldTransform(), *rightHandSide.GetIndexToWorldTransform(), eps, verbose) )
{
result = false;
}
return result;
}
bool mitk::Equal(const BaseGeometry::TransformType *leftHandSide, const BaseGeometry::TransformType *rightHandSide, ScalarType eps, bool verbose )
{
if(( leftHandSide == NULL) || ( rightHandSide == NULL ))
{
MITK_ERROR << "mitk::Equal(const Geometry3D::TransformType *leftHandSide, const Geometry3D::TransformType *rightHandSide, ScalarType eps, bool verbose ) does not with NULL pointer input.";
return false;
}
return Equal( *leftHandSide, *rightHandSide, eps, verbose);
}
bool mitk::Equal(const BaseGeometry::TransformType& leftHandSide, const BaseGeometry::TransformType& rightHandSide, ScalarType eps, bool verbose )
{
//Compare IndexToWorldTransform Matrix
if( !mitk::MatrixEqualElementWise( leftHandSide.GetMatrix(),
rightHandSide.GetMatrix() ) )
{
if(verbose)
{
MITK_INFO << "[( Geometry3D::TransformType )] Index to World Transformation matrix differs.";
MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetMatrix() << " : leftHandSide is " << leftHandSide.GetMatrix() << " and tolerance is " << eps;
}
return false;
}
return true;
}
diff --git a/Core/Code/DataManagement/mitkDataNode.cpp b/Core/Code/DataManagement/mitkDataNode.cpp
index e19d714574..faf725fb11 100644
--- a/Core/Code/DataManagement/mitkDataNode.cpp
+++ b/Core/Code/DataManagement/mitkDataNode.cpp
@@ -1,611 +1,610 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkDataNode.h"
#include "mitkCoreObjectFactory.h"
#include <vtkTransform.h>
#include "mitkProperties.h"
#include "mitkStringProperty.h"
#include "mitkGroupTagProperty.h"
#include "mitkSmartPointerProperty.h"
//#include "mitkMaterialProperty.h"
#include "mitkColorProperty.h"
#include "mitkLevelWindowProperty.h"
#include "mitkGeometry3D.h"
#include "mitkRenderingManager.h"
#include "mitkGlobalInteraction.h"
#include "mitkEventMapper.h"
#include "mitkGenericProperty.h"
#include "mitkImageSource.h"
#include "mitkCoreObjectFactory.h"
mitk::Mapper* mitk::DataNode::GetMapper(MapperSlotId id) const
{
if( (id >= m_Mappers.size()) || (m_Mappers[id].IsNull()) )
{
if(id >= m_Mappers.capacity())
{
// int i, size=id-m_Mappers.capacity()+10;
m_Mappers.resize(id+10);
}
m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast<DataNode*>(this),id);
}
return m_Mappers[id];
}
mitk::BaseData* mitk::DataNode::GetData() const
{
return m_Data;
}
mitk::Interactor* mitk::DataNode::GetInteractor() const
{
return m_Interactor;
}
void mitk::DataNode::SetData(mitk::BaseData* baseData)
{
if(m_Data!=baseData)
{
m_Data=baseData;
m_Mappers.clear();
m_Mappers.resize(10);
mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this);
m_DataReferenceChangedTime.Modified();
Modified();
//inform the interactor about the change
if (m_Interactor.IsNotNull())
m_Interactor->DataChanged();
}
}
void mitk::DataNode::SetInteractor(mitk::Interactor* interactor)
{
m_Interactor = interactor;
if(m_Interactor.IsNotNull())
m_Interactor->SetDataNode(this);
}
mitk::DataNode::DataNode() : m_Data(NULL), m_PropertyListModifiedObserverTag(0)
{
m_Mappers.resize(10);
m_PropertyList = PropertyList::New();
// subscribe for modified event
itk::MemberCommand<mitk::DataNode>::Pointer _PropertyListModifiedCommand =
itk::MemberCommand<mitk::DataNode>::New();
_PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified);
m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand);
}
mitk::DataNode::~DataNode()
{
if(m_PropertyList.IsNotNull())
// remove modified event listener
m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag);
Interactor* interactor = this->GetInteractor();
if ( interactor )
{
mitk::GlobalInteraction::GetInstance()->RemoveInteractor( interactor );
}
m_Mappers.clear();
m_Data = NULL;
}
mitk::DataNode& mitk::DataNode::operator=(const DataNode& right)
{
mitk::DataNode* node=mitk::DataNode::New();
node->SetData(right.GetData());
return *node;
}
mitk::DataNode& mitk::DataNode::operator=(mitk::BaseData* right)
{
mitk::DataNode* node=mitk::DataNode::New();
node->SetData(right);
return *node;
}
#if (_MSC_VER > 1200) || !defined(_MSC_VER)
MBI_STD::istream& mitk::operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn )
#endif
#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn )
#endif
{
dtn = mitk::DataNode::New();
//i >> av.get();
return i;
}
#if (_MSC_VER > 1200) || !defined(_MSC_VER)
MBI_STD::ostream& mitk::operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn)
#endif
#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn)
#endif
{
if(dtn->GetData()!=NULL)
o<<dtn->GetData()->GetNameOfClass();
else
o<<"empty data";
return o;
}
void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper* mapper)
{
m_Mappers[id] = mapper;
if (mapper!=NULL)
mapper->SetDataNode(this);
}
void mitk::DataNode::UpdateOutputInformation()
{
if (this->GetSource())
{
this->GetSource()->UpdateOutputInformation();
}
}
void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::DataNode::VerifyRequestedRegion()
{
return true;
}
void mitk::DataNode::SetRequestedRegion( const itk::DataObject * /*data*/)
{
}
void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/)
{
}
-
mitk::PropertyList* mitk::DataNode::GetPropertyList(const mitk::BaseRenderer* renderer) const
{
if(renderer==NULL)
return m_PropertyList;
return this->GetPropertyList(renderer->GetName());
}
mitk::PropertyList* mitk::DataNode::GetPropertyList(const std::string& rendererName) const
{
if (rendererName.empty())
return m_PropertyList;
mitk::PropertyList::Pointer & propertyList = m_MapOfPropertyLists[rendererName];
if(propertyList.IsNull())
propertyList = mitk::PropertyList::New();
assert(m_MapOfPropertyLists[rendererName].IsNotNull());
return propertyList;
}
void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace)
{
m_PropertyList->ConcatenatePropertyList(pList, replace);
}
mitk::BaseProperty* mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer) const
{
if(propertyKey==NULL)
return NULL;
//renderer specified?
if (renderer)
{
std::string rendererName = renderer->GetName();
MapOfPropertyLists::const_iterator it;
//check for the renderer specific property
it=m_MapOfPropertyLists.find(rendererName);
if(it!=m_MapOfPropertyLists.end()) //found
{
mitk::BaseProperty::Pointer property;
property=it->second->GetProperty(propertyKey);
if(property.IsNotNull())//found an enabled property in the render specific list
return property;
else //found a renderer specific list, but not the desired property
return m_PropertyList->GetProperty(propertyKey); //return renderer unspecific property
}
else //didn't find the property list of the given renderer
{
//return the renderer unspecific property if there is one
return m_PropertyList->GetProperty(propertyKey);
}
}
else //no specific renderer given; use the renderer independent one
{
mitk::BaseProperty::Pointer property;
property=m_PropertyList->GetProperty(propertyKey);
if(property.IsNotNull())
return property;
}
//only to satisfy compiler!
return NULL;
}
mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const
{
GroupTagList groups;
const PropertyList::PropertyMap* propertyMap = m_PropertyList->GetMap();
for ( PropertyList::PropertyMap::const_iterator groupIter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here
groupIter != propertyMap->end();
++groupIter )
{
const BaseProperty* bp = groupIter->second;
if ( dynamic_cast<const GroupTagProperty*>(bp) )
{
groups.insert( groupIter->first );
}
}
return groups;
}
-bool mitk::DataNode::GetBoolProperty(const char* propertyKey, bool& boolValue, mitk::BaseRenderer* renderer) const
+bool mitk::DataNode::GetBoolProperty(const char* propertyKey, bool& boolValue, const mitk::BaseRenderer* renderer) const
{
mitk::BoolProperty::Pointer boolprop = dynamic_cast<mitk::BoolProperty*>(GetProperty(propertyKey, renderer));
if(boolprop.IsNull())
return false;
boolValue = boolprop->GetValue();
return true;
}
-bool mitk::DataNode::GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer) const
+bool mitk::DataNode::GetIntProperty(const char* propertyKey, int &intValue, const mitk::BaseRenderer* renderer) const
{
mitk::IntProperty::Pointer intprop = dynamic_cast<mitk::IntProperty*>(GetProperty(propertyKey, renderer));
if(intprop.IsNull())
return false;
intValue = intprop->GetValue();
return true;
}
-bool mitk::DataNode::GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer) const
+bool mitk::DataNode::GetFloatProperty(const char* propertyKey, float &floatValue, const mitk::BaseRenderer* renderer) const
{
mitk::FloatProperty::Pointer floatprop = dynamic_cast<mitk::FloatProperty*>(GetProperty(propertyKey, renderer));
if(floatprop.IsNull())
return false;
floatValue = floatprop->GetValue();
return true;
}
-bool mitk::DataNode::GetDoubleProperty(const char* propertyKey, double &doubleValue, mitk::BaseRenderer* renderer) const
+bool mitk::DataNode::GetDoubleProperty(const char* propertyKey, double &doubleValue, const mitk::BaseRenderer* renderer) const
{
mitk::DoubleProperty::Pointer doubleprop = dynamic_cast<mitk::DoubleProperty*>(GetProperty(propertyKey, renderer));
if(doubleprop.IsNull())
{
// try float instead
float floatValue = 0;
if (this->GetFloatProperty(propertyKey, floatValue, renderer))
{
doubleValue = floatValue;
return true;
}
return false;
}
doubleValue = doubleprop->GetValue();
return true;
}
-bool mitk::DataNode::GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer) const
+bool mitk::DataNode::GetStringProperty(const char* propertyKey, std::string& string, const mitk::BaseRenderer* renderer) const
{
mitk::StringProperty::Pointer stringProp = dynamic_cast<mitk::StringProperty*>(GetProperty(propertyKey, renderer));
if(stringProp.IsNull())
{
return false;
}
else
{
//memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous
string = stringProp->GetValue();
return true;
}
}
-bool mitk::DataNode::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey) const
+bool mitk::DataNode::GetColor(float rgb[3], const mitk::BaseRenderer* renderer, const char* propertyKey) const
{
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetProperty(propertyKey, renderer));
if(colorprop.IsNull())
return false;
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
return true;
}
-bool mitk::DataNode::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey) const
+bool mitk::DataNode::GetOpacity(float &opacity, const mitk::BaseRenderer* renderer, const char* propertyKey) const
{
mitk::FloatProperty::Pointer opacityprop = dynamic_cast<mitk::FloatProperty*>(GetProperty(propertyKey, renderer));
if(opacityprop.IsNull())
return false;
opacity=opacityprop->GetValue();
return true;
}
-bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey) const
+bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer* renderer, const char* propertyKey) const
{
mitk::LevelWindowProperty::Pointer levWinProp = dynamic_cast<mitk::LevelWindowProperty*>(GetProperty(propertyKey, renderer));
if(levWinProp.IsNull())
return false;
levelWindow=levWinProp->GetLevelWindow();
return true;
}
-void mitk::DataNode::SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer, const char* propertyKey)
+void mitk::DataNode::SetColor(const mitk::Color &color, const mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::ColorProperty::Pointer prop;
prop = mitk::ColorProperty::New(color);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
-void mitk::DataNode::SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer, const char* propertyKey)
+void mitk::DataNode::SetColor(float red, float green, float blue, const mitk::BaseRenderer* renderer, const char* propertyKey)
{
float color[3];
color[0]=red;
color[1]=green;
color[2]=blue;
SetColor(color, renderer, propertyKey);
}
-void mitk::DataNode::SetColor(const float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey)
+void mitk::DataNode::SetColor(const float rgb[3], const mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::ColorProperty::Pointer prop;
prop = mitk::ColorProperty::New(rgb);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
-void mitk::DataNode::SetVisibility(bool visible, mitk::BaseRenderer* renderer, const char* propertyKey)
+void mitk::DataNode::SetVisibility(bool visible, const mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::BoolProperty::Pointer prop;
prop = mitk::BoolProperty::New(visible);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
-void mitk::DataNode::SetOpacity(float opacity, mitk::BaseRenderer* renderer, const char* propertyKey)
+void mitk::DataNode::SetOpacity(float opacity, const mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::FloatProperty::Pointer prop;
prop = mitk::FloatProperty::New(opacity);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
-void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey)
+void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::LevelWindowProperty::Pointer prop;
prop = mitk::LevelWindowProperty::New(levelWindow);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
-void mitk::DataNode::SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer)
+void mitk::DataNode::SetIntProperty(const char* propertyKey, int intValue, const mitk::BaseRenderer* renderer)
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue));
}
-void mitk::DataNode::SetBoolProperty( const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer/*=NULL*/ )
+void mitk::DataNode::SetBoolProperty( const char* propertyKey, bool boolValue, const mitk::BaseRenderer* renderer/*=NULL*/ )
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue));
}
-void mitk::DataNode::SetFloatProperty( const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer/*=NULL*/ )
+void mitk::DataNode::SetFloatProperty( const char* propertyKey, float floatValue, const mitk::BaseRenderer* renderer/*=NULL*/ )
{
if (dynamic_cast<DoubleProperty*>(this->GetProperty(propertyKey, renderer)) != NULL)
{
MITK_WARN << "Setting float property " << propertyKey << " although a double property with the same name already exists";
}
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue));
}
-void mitk::DataNode::SetDoubleProperty(const char *propertyKey, float doubleValue, mitk::BaseRenderer *renderer)
+void mitk::DataNode::SetDoubleProperty(const char *propertyKey, float doubleValue, const mitk::BaseRenderer *renderer)
{
if (dynamic_cast<FloatProperty*>(this->GetProperty(propertyKey, renderer)) != NULL)
{
MITK_WARN << "Setting double property " << propertyKey << " although a float property with the same name already exists";
}
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::DoubleProperty::New(doubleValue));
}
-void mitk::DataNode::SetStringProperty( const char* propertyKey, const char* stringValue, mitk::BaseRenderer* renderer/*=NULL*/ )
+void mitk::DataNode::SetStringProperty( const char* propertyKey, const char* stringValue, const mitk::BaseRenderer* renderer/*=NULL*/ )
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue));
}
void mitk::DataNode::SetProperty(const char *propertyKey,
BaseProperty* propertyValue,
const mitk::BaseRenderer* renderer)
{
GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue);
}
void mitk::DataNode::ReplaceProperty(const char *propertyKey,
BaseProperty* propertyValue,
const mitk::BaseRenderer* renderer)
{
GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue);
}
void mitk::DataNode::AddProperty(const char *propertyKey,
BaseProperty* propertyValue,
const mitk::BaseRenderer* renderer,
bool overwrite)
{
if((overwrite) || (GetProperty(propertyKey, renderer) == NULL))
{
SetProperty(propertyKey, propertyValue, renderer);
}
}
vtkLinearTransform* mitk::DataNode::GetVtkTransform(int t) const
{
assert(m_Data.IsNotNull());
mitk::BaseGeometry* geometry = m_Data->GetGeometry(t);
if(geometry == NULL)
return NULL;
return geometry->GetVtkTransform();
}
unsigned long mitk::DataNode::GetMTime() const
{
unsigned long time = Superclass::GetMTime();
if(m_Data.IsNotNull())
{
if((time < m_Data->GetMTime()) ||
((m_Data->GetSource().IsNotNull()) && (time < m_Data->GetSource()->GetMTime()))
)
{
Modified();
return Superclass::GetMTime();
}
}
return time;
}
-void mitk::DataNode::SetSelected(bool selected, mitk::BaseRenderer* renderer)
+void mitk::DataNode::SetSelected(bool selected, const mitk::BaseRenderer* renderer)
{
mitk::BoolProperty::Pointer selectedProperty = dynamic_cast<mitk::BoolProperty*>(GetProperty("selected"));
if ( selectedProperty.IsNull() )
{
selectedProperty = mitk::BoolProperty::New();
selectedProperty->SetValue(false);
SetProperty("selected", selectedProperty, renderer);
}
if( selectedProperty->GetValue() != selected )
{
selectedProperty->SetValue(selected);
itk::ModifiedEvent event;
InvokeEvent( event );
}
}
/*
class SelectedEvent : public itk::ModifiedEvent
{
public:
typedef SelectedEvent Self;
typedef itk::ModifiedEvent Superclass;
SelectedEvent(DataNode* dataNode)
{ m_DataNode = dataNode; };
DataNode* GetDataNode()
{ return m_DataNode; };
virtual const char * GetEventName() const
{ return "SelectedEvent"; }
virtual bool CheckEvent(const ::itk::EventObject* e) const
{ return dynamic_cast<const Self*>(e); }
virtual ::itk::EventObject* MakeObject() const
{ return new Self(m_DataNode); }
private:
DataNode* m_DataNode;
SelectedEvent(const Self& event)
{ m_DataNode = event.m_DataNode; };
void operator=(const Self& event)
{ m_DataNode = event.m_DataNode; }
};
*/
-bool mitk::DataNode::IsSelected(mitk::BaseRenderer* renderer)
+bool mitk::DataNode::IsSelected(const mitk::BaseRenderer* renderer)
{
bool selected;
if ( !GetBoolProperty("selected", selected, renderer) )
return false;
return selected;
}
void mitk::DataNode::SetInteractorEnabled( const bool& enabled )
{
if ( m_Interactor.IsNull() )
{
itkWarningMacro("Interactor is NULL. Couldn't enable or disable interaction.");
return;
}
if ( enabled )
mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor.GetPointer() );
else
mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor.GetPointer() );
}
void mitk::DataNode::EnableInteractor()
{
SetInteractorEnabled( true );
}
void mitk::DataNode::DisableInteractor()
{
SetInteractorEnabled( false );
}
bool mitk::DataNode::IsInteractorEnabled() const
{
return mitk::GlobalInteraction::GetInstance()->InteractorRegistered( m_Interactor.GetPointer() );
}
void mitk::DataNode::SetDataInteractor(const DataInteractor::Pointer& interactor)
{
m_DataInteractor = interactor;
Modified();
// the interactor has changed, so we have ti invoke an InteractorChangedEvent
const mitk::DataNode::InteractorChangedEvent changedEvent;
InvokeEvent( changedEvent );
}
mitk::DataInteractor::Pointer mitk::DataNode::GetDataInteractor() const
{
return m_DataInteractor;
}
void mitk::DataNode::PropertyListModified( const itk::Object* /*caller*/, const itk::EventObject& )
{
Modified();
}
diff --git a/Core/Code/DataManagement/mitkDataNode.h b/Core/Code/DataManagement/mitkDataNode.h
index adef2b8c9e..07cadb6f10 100644
--- a/Core/Code/DataManagement/mitkDataNode.h
+++ b/Core/Code/DataManagement/mitkDataNode.h
@@ -1,602 +1,601 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef DATATREENODE_H_HEADER_INCLUDED_C1E14338
#define DATATREENODE_H_HEADER_INCLUDED_C1E14338
#include "mitkBaseData.h"
//#include "mitkMapper.h"
#include "mitkInteractor.h"
#include "mitkDataInteractor.h"
#ifdef MBI_NO_STD_NAMESPACE
#define MBI_STD
#include <iostream.h>
#include <fstream.h>
#else
#define MBI_STD std
#include <iostream>
#include <fstream>
#endif
#include "mitkStringProperty.h"
#include "mitkColorProperty.h"
#include "mitkPropertyList.h"
//#include "mitkMapper.h"
#include <map>
#include <set>
#include "mitkLevelWindow.h"
class vtkLinearTransform;
namespace mitk {
class BaseRenderer;
class Mapper;
/**
* \brief Class for nodes of the DataTree
*
* Contains the data (instance of BaseData), a list of mappers, which can
* draw the data, a transform (vtkTransform) and a list of properties
* (PropertyList).
* \ingroup DataManagement
*
* \todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced to <tt>bool GetProperty<type>(type&)</tt>
*
* \warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do
* more with properties than just call <tt>SetProperty( "key", new SomeProperty("value") )</tt>.
*/
class MITK_CORE_EXPORT DataNode : public itk::DataObject
{
public:
typedef mitk::Geometry3D::Pointer Geometry3DPointer;
typedef std::vector< itk::SmartPointer< Mapper > > MapperVector;
typedef std::map<std::string, mitk::PropertyList::Pointer> MapOfPropertyLists;
typedef std::set<std::string> GroupTagList;
/**
- *\brief Definition of an itk::Event that is invoked when
+ * \brief Definition of an itk::Event that is invoked when
* a DataInteractor is set on this DataNode.
*/
itkEventMacro(InteractorChangedEvent, itk::AnyEvent);
mitkClassMacro(DataNode, itk::DataObject);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
mitk::Mapper* GetMapper(MapperSlotId id) const;
/**
* \brief Get the data object (instance of BaseData, e.g., an Image)
* managed by this DataNode
*/
BaseData* GetData() const;
/**
* \brief Get the transformation applied prior to displaying the data as
* a vtkTransform
* \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead
*/
vtkLinearTransform* GetVtkTransform(int t=0) const;
/**
* \brief Get the Interactor.
* \deprecatedSince{2013_03} Use DataInteractor and GetDataInteractor instead.
*/
Interactor* GetInteractor() const;
/**
* \brief Set the data object (instance of BaseData, e.g., an Image)
* managed by this DataNode
* \warning the actor-mode of the vtkInteractor does not work any more, if the transform of the
* data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput.
*/
virtual void SetData(mitk::BaseData* baseData);
/**
* \brief Set the Interactor.
* \deprecatedSince{2013_03} Use DataInteractor and SetDataInteractor instead.
*/
virtual void SetInteractor(Interactor* interactor);
virtual void SetDataInteractor(const DataInteractor::Pointer& interactor);
virtual DataInteractor::Pointer GetDataInteractor() const;
mitk::DataNode& operator=(const DataNode& right);
mitk::DataNode& operator=(BaseData* right);
virtual void SetMapper(MapperSlotId id, mitk::Mapper* mapper);
virtual void UpdateOutputInformation();
virtual void SetRequestedRegionToLargestPossibleRegion();
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
virtual bool VerifyRequestedRegion();
virtual void SetRequestedRegion( const itk::DataObject *data);
virtual void CopyInformation(const itk::DataObject *data);
/**
* \brief Set the property (instance of BaseProperty) with key \a propertyKey in the PropertyList
* of the \a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-value.
*
* \warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do
* more with properties than just call <tt>SetProperty( "key", new SomeProperty("value") )</tt>.
*
* \sa GetProperty
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
void SetProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL);
/**
* \brief Replace the property (instance of BaseProperty) with key \a propertyKey in the PropertyList
* of the \a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-reference.
*
* If \a renderer is \a NULL the property is set in the BaseRenderer-independent
* PropertyList of this DataNode.
* \sa GetProperty
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
void ReplaceProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL);
/**
* \brief Add the property (instance of BaseProperty) if it does
* not exist (or always if\a overwrite is\a true)
* with key \a propertyKey in the PropertyList
* of the \a renderer (if NULL, use BaseRenderer-independent
* PropertyList). This is set-by-value.
*
* For\a overwrite ==\a false the property is\em not changed
* if it already exists. For\a overwrite ==\a true the method
* is identical to SetProperty.
*
* \sa SetProperty
* \sa GetProperty
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
void AddProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
/**
* \brief Get the PropertyList of the \a renderer. If \a renderer is \a
* NULL, the BaseRenderer-independent PropertyList of this DataNode
* is returned.
* \sa GetProperty
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
mitk::PropertyList* GetPropertyList(const mitk::BaseRenderer* renderer = NULL) const;
mitk::PropertyList* GetPropertyList(const std::string& rendererName) const;
/**
* \brief Add values from another PropertyList.
*
* Overwrites values in m_PropertyList only when possible (i.e. when types are compatible).
* If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty,
* set the \param replace.
*
* \param replace true: if \param pList contains a property "visible" of type ColorProperty and our m_PropertyList also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects behind the pointer.
*
* \sa SetProperty
* \sa ReplaceProperty
* \sa m_PropertyList
*/
void ConcatenatePropertyList(PropertyList* pList, bool replace = false);
/**
* \brief Get the property (instance of BaseProperty) with key \a propertyKey from the PropertyList
* of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
*
* If \a renderer is \a NULL or the \a propertyKey cannot be found
* in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent
* PropertyList of this DataNode is queried.
* \sa GetPropertyList
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
mitk::BaseProperty* GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const;
/**
* \brief Get the property of type T with key \a propertyKey from the PropertyList
* of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
*
* If \a renderer is \a NULL or the \a propertyKey cannot be found
* in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent
* PropertyList of this DataNode is queried.
* \sa GetPropertyList
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
template <typename T>
bool GetProperty(itk::SmartPointer<T> &property, const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const
{
property = dynamic_cast<T *>(GetProperty(propertyKey, renderer));
return property.IsNotNull();
}
/**
* \brief Get the property of type T with key \a propertyKey from the PropertyList
* of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
*
* If \a renderer is \a NULL or the \a propertyKey cannot be found
* in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent
* PropertyList of this DataNode is queried.
* \sa GetPropertyList
* \sa m_PropertyList
* \sa m_MapOfPropertyLists
*/
template <typename T>
bool GetProperty(T* &property, const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const
{
property = dynamic_cast<T *>(GetProperty(propertyKey, renderer));
return property!=NULL;
}
/**
* \brief Convenience access method for GenericProperty<T> properties
* (T being the type of the second parameter)
* \return \a true property was found
*/
template <typename T>
- bool GetPropertyValue(const char* propertyKey, T & value, mitk::BaseRenderer* renderer=NULL) const
+ bool GetPropertyValue(const char* propertyKey, T & value, const mitk::BaseRenderer* renderer=NULL) const
{
GenericProperty<T>* gp= dynamic_cast<GenericProperty<T>*>(GetProperty(propertyKey, renderer));
if ( gp != NULL )
{
value = gp->GetValue();
return true;
}
return false;
}
/// \brief Get a set of all group tags from this node's property list
GroupTagList GetGroupTags() const;
/**
* \brief Convenience access method for bool properties (instances of
* BoolProperty)
* \return \a true property was found
*/
- bool GetBoolProperty(const char* propertyKey, bool &boolValue, mitk::BaseRenderer* renderer = NULL) const;
+ bool GetBoolProperty(const char* propertyKey, bool &boolValue, const mitk::BaseRenderer* renderer = NULL) const;
/**
* \brief Convenience access method for int properties (instances of
* IntProperty)
* \return \a true property was found
*/
- bool GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer=NULL) const;
+ bool GetIntProperty(const char* propertyKey, int &intValue, const mitk::BaseRenderer* renderer=NULL) const;
/**
* \brief Convenience access method for float properties (instances of
* FloatProperty)
* \return \a true property was found
*/
- bool GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer = NULL) const;
+ bool GetFloatProperty(const char* propertyKey, float &floatValue, const mitk::BaseRenderer* renderer = NULL) const;
/**
* \brief Convenience access method for double properties (instances of
* DoubleProperty)
*
* If there is no DoubleProperty for the given\c propertyKey argument, the method
* looks for a corresponding FloatProperty instance.
*
* \return \a true property was found
*/
- bool GetDoubleProperty(const char* propertyKey, double &doubleValue, mitk::BaseRenderer* renderer = NULL) const;
+ bool GetDoubleProperty(const char* propertyKey, double &doubleValue, const mitk::BaseRenderer* renderer = NULL) const;
/**
* \brief Convenience access method for string properties (instances of
* StringProperty)
* \return \a true property was found
*/
- bool GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer = NULL) const;
+ bool GetStringProperty(const char* propertyKey, std::string& string, const mitk::BaseRenderer* renderer = NULL) const;
/**
* \brief Convenience access method for color properties (instances of
* ColorProperty)
* \return \a true property was found
*/
- bool GetColor(float rgb[3], mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color") const;
+ bool GetColor(float rgb[3], const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color") const;
/**
* \brief Convenience access method for level-window properties (instances of
* LevelWindowProperty)
* \return \a true property was found
*/
- bool GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow") const;
+ bool GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow") const;
/**
* \brief set the node as selected
*/
- void SetSelected(bool selected, mitk::BaseRenderer* renderer=NULL);
+ void SetSelected(bool selected, const mitk::BaseRenderer* renderer=NULL);
/**
* \brief set the node as selected
* \return \a true node is selected
*/
- bool IsSelected(mitk::BaseRenderer* renderer=NULL);
+ bool IsSelected(const mitk::BaseRenderer* renderer=NULL);
/**
* \brief Convenience access method for accessing the name of an object (instance of
* StringProperty with property-key "name")
* \return \a true property was found
*/
- bool GetName(std::string& nodeName, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "name") const
+ bool GetName(std::string& nodeName, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "name") const
{
return GetStringProperty(propertyKey, nodeName, renderer);
}
/**
* \brief Extra convenience access method for accessing the name of an object (instance of
* StringProperty with property-key "name").
*
* This method does not take the renderer specific
* propertylists into account, because the name of an object should never be renderer specific.
* \returns a std::string with the name of the object (content of "name" Property).
* If there is no "name" Property, an empty string will be returned.
*/
virtual std::string GetName() const
{
mitk::StringProperty* sp = dynamic_cast<mitk::StringProperty*>(this->GetProperty("name"));
if (sp == NULL)
return "";
return sp->GetValue();
}
/**
* \brief Extra convenience access method to set the name of an object.
*
* The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name".
*/
virtual void SetName( const char* name)
{
if (name == NULL)
return;
this->SetProperty("name", StringProperty::New(name));
}
-
/**
* \brief Extra convenience access method to set the name of an object.
*
* The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name".
*/
virtual void SetName( const std::string name)
{
this->SetName(name.c_str());
}
/**
* \brief Convenience access method for visibility properties (instances
* of BoolProperty with property-key "visible")
* \return \a true property was found
* \sa IsVisible
*/
- bool GetVisibility(bool &visible, mitk::BaseRenderer* renderer, const char* propertyKey = "visible") const
+ bool GetVisibility(bool &visible, const mitk::BaseRenderer* renderer, const char* propertyKey = "visible") const
{
return GetBoolProperty(propertyKey, visible, renderer);
}
/**
* \brief Convenience access method for opacity properties (instances of
* FloatProperty)
* \return \a true property was found
*/
- bool GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey = "opacity") const;
+ bool GetOpacity(float &opacity, const mitk::BaseRenderer* renderer, const char* propertyKey = "opacity") const;
/**
* \brief Convenience access method for boolean properties (instances
* of BoolProperty). Return value is the value of the property. If the property is
* not found, the value of \a defaultIsOn is returned.
*
* Thus, the return value has a different meaning than in the
* GetBoolProperty method!
* \sa GetBoolProperty
*/
- bool IsOn(const char* propertyKey, mitk::BaseRenderer* renderer, bool defaultIsOn = true) const
+ bool IsOn(const char* propertyKey, const mitk::BaseRenderer* renderer, bool defaultIsOn = true) const
{
if(propertyKey==NULL)
return defaultIsOn;
GetBoolProperty(propertyKey, defaultIsOn, renderer);
return defaultIsOn;
}
/**
* \brief Convenience access method for visibility properties (instances
* of BoolProperty). Return value is the visibility. Default is
* visible==true, i.e., true is returned even if the property (\a
* propertyKey) is not found.
*
* Thus, the return value has a different meaning than in the
* GetVisibility method!
* \sa GetVisibility
* \sa IsOn
*/
- bool IsVisible(mitk::BaseRenderer* renderer, const char* propertyKey = "visible", bool defaultIsOn = true) const
+ bool IsVisible(const mitk::BaseRenderer* renderer, const char* propertyKey = "visible", bool defaultIsOn = true) const
{
return IsOn(propertyKey, renderer, defaultIsOn);
}
/**
* \brief Convenience method for setting color properties (instances of
* ColorProperty)
*/
- void SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
+ void SetColor(const mitk::Color &color, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
/**
* \brief Convenience method for setting color properties (instances of
* ColorProperty)
*/
- void SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
+ void SetColor(float red, float green, float blue, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
/**
* \brief Convenience method for setting color properties (instances of
* ColorProperty)
*/
- void SetColor(const float rgb[3], mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
+ void SetColor(const float rgb[3], const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
/**
* \brief Convenience method for setting visibility properties (instances
* of BoolProperty)
* \param visible If set to true, the data will be rendered. If false, the render will skip this data.
* \param renderer Specify a renderer if the visibility shall be specific to a renderer
* \param propertykey Can be used to specify a user defined name of the visibility propery.
*/
- void SetVisibility(bool visible, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "visible");
+ void SetVisibility(bool visible, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "visible");
/**
* \brief Convenience method for setting opacity properties (instances of
* FloatProperty)
*/
- void SetOpacity(float opacity, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "opacity");
+ void SetOpacity(float opacity, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "opacity");
/**
* \brief Convenience method for setting level-window properties
* (instances of LevelWindowProperty)
*/
- void SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow");
+ void SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow");
/**
* \brief Convenience method for setting int properties (instances of
* IntProperty)
*/
- void SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer=NULL);
+ void SetIntProperty(const char* propertyKey, int intValue, const mitk::BaseRenderer* renderer=NULL);
/**
* \brief Convenience method for setting boolean properties (instances of
* BoolProperty)
*/
- void SetBoolProperty(const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer=NULL);
+ void SetBoolProperty(const char* propertyKey, bool boolValue, const mitk::BaseRenderer* renderer=NULL);
/**
* \brief Convenience method for setting float properties (instances of
* FloatProperty)
*/
- void SetFloatProperty(const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer=NULL);
+ void SetFloatProperty(const char* propertyKey, float floatValue, const mitk::BaseRenderer* renderer=NULL);
/**
* \brief Convenience method for setting double properties (instances of
* DoubleProperty)
*/
- void SetDoubleProperty(const char* propertyKey, float doubleValue, mitk::BaseRenderer* renderer=NULL);
+ void SetDoubleProperty(const char* propertyKey, float doubleValue, const mitk::BaseRenderer* renderer=NULL);
/**
* \brief Convenience method for setting string properties (instances of
* StringProperty)
*/
- void SetStringProperty(const char* propertyKey, const char* string, mitk::BaseRenderer* renderer=NULL);
+ void SetStringProperty(const char* propertyKey, const char* string, const mitk::BaseRenderer* renderer=NULL);
/**
* \brief Get the timestamp of the last change of the contents of this node or
* the referenced BaseData.
*/
virtual unsigned long GetMTime() const;
/**
* \brief Get the timestamp of the last change of the reference to the
* BaseData.
*/
unsigned long GetDataReferenceChangedTime() const
{
return m_DataReferenceChangedTime.GetMTime();
}
/**
* \brief Adds or removes the associated interactor to mitk::GLobalInteraction.
*/
virtual void SetInteractorEnabled( const bool& enabled );
/**
* \brief Adds the interactor to mitk::GlobalInteraction
*/
virtual void EnableInteractor();
/**
* \brief Removes the Interactor from mitk::GlobalInteraction
*/
virtual void DisableInteractor();
/**
* \brief Tests, if the interactor is already added to mitk::GlobalInteraction
*/
virtual bool IsInteractorEnabled() const;
protected:
DataNode();
virtual ~DataNode();
/// Invoked when the property list was modified. Calls Modified() of the DataNode
virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event);
/// \brief Mapper-slots
mutable MapperVector m_Mappers;
/**
* \brief The data object (instance of BaseData, e.g., an Image) managed
* by this DataNode
*/
BaseData::Pointer m_Data;
/**
* \brief BaseRenderer-independent PropertyList
*
* Properties herein can be overwritten specifically for each BaseRenderer
* by the BaseRenderer-specific properties defined in m_MapOfPropertyLists.
*/
PropertyList::Pointer m_PropertyList;
/// \brief Map associating each BaseRenderer with its own PropertyList
mutable MapOfPropertyLists m_MapOfPropertyLists;
/// \brief Interactor, that handles the Interaction
Interactor::Pointer m_Interactor; // TODO: INTERACTION_LEGACY
DataInteractor::Pointer m_DataInteractor;
/// \brief Timestamp of the last change of m_Data
itk::TimeStamp m_DataReferenceChangedTime;
unsigned long m_PropertyListModifiedObserverTag;
};
#if (_MSC_VER > 1200) || !defined(_MSC_VER)
MITK_CORE_EXPORT MBI_STD::istream& operator>>( MBI_STD::istream& i, DataNode::Pointer& dtn );
MITK_CORE_EXPORT MBI_STD::ostream& operator<<( MBI_STD::ostream& o, DataNode::Pointer& dtn);
#endif
} // namespace mitk
#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
MITK_CORE_EXPORT MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn );
MITK_CORE_EXPORT MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn);
#endif
#endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */
diff --git a/Core/Code/DataManagement/mitkDataStorage.cpp b/Core/Code/DataManagement/mitkDataStorage.cpp
index 9ca5dbda84..d3a243cbc7 100644
--- a/Core/Code/DataManagement/mitkDataStorage.cpp
+++ b/Core/Code/DataManagement/mitkDataStorage.cpp
@@ -1,502 +1,502 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateProperty.h"
#include "mitkGroupTagProperty.h"
#include "mitkImage.h"
#include "itkMutexLockHolder.h"
#include "itkCommand.h"
mitk::DataStorage::DataStorage() : itk::Object()
, m_BlockNodeModifiedEvents(false)
{
}
mitk::DataStorage::~DataStorage()
{
///// we can not call GetAll() in destructor, because it is implemented in a subclass
//SetOfObjects::ConstPointer all = this->GetAll();
//for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
// this->RemoveListeners(it->Value());
//m_NodeModifiedObserverTags.clear();
//m_NodeDeleteObserverTags.clear();
}
void mitk::DataStorage::Add(mitk::DataNode* node, mitk::DataNode* parent)
{
mitk::DataStorage::SetOfObjects::Pointer parents = mitk::DataStorage::SetOfObjects::New();
if (parent != NULL) //< Return empty set if parent is null
parents->InsertElement(0, parent);
this->Add(node, parents);
}
void mitk::DataStorage::Remove(const mitk::DataStorage::SetOfObjects* nodes)
{
if (nodes == NULL)
return;
for (mitk::DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); it++)
this->Remove(it.Value());
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::GetSubset(const NodePredicateBase* condition) const
{
mitk::DataStorage::SetOfObjects::ConstPointer result = this->FilterSetOfObjects(this->GetAll(), condition);
return result;
}
mitk::DataNode* mitk::DataStorage::GetNamedNode(const char* name) const
{
if (name == NULL)
return NULL;
mitk::StringProperty::Pointer s(mitk::StringProperty::New(name));
mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("name", s);
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(p);
if (rs->Size() >= 1)
return rs->GetElement(0);
else
return NULL;
}
mitk::DataNode* mitk::DataStorage::GetNode(const NodePredicateBase* condition) const
{
if (condition == NULL)
return NULL;
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(condition);
if (rs->Size() >= 1)
return rs->GetElement(0);
else
return NULL;
}
mitk::DataNode* mitk::DataStorage::GetNamedDerivedNode(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations) const
{
if (name == NULL)
return NULL;
mitk::StringProperty::Pointer s(mitk::StringProperty::New(name));
mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("name", s);
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDerivations(sourceNode, p, onlyDirectDerivations);
if (rs->Size() >= 1)
return rs->GetElement(0);
else
return NULL;
}
void mitk::DataStorage::PrintSelf(std::ostream& os, itk::Indent indent) const
{
//Superclass::PrintSelf(os, indent);
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetAll();
os << indent << "DataStorage " << this << " is managing " << all->Size() << " objects. List of objects:" << std::endl;
for (mitk::DataStorage::SetOfObjects::ConstIterator allIt = all->Begin(); allIt != all->End(); allIt++)
{
std::string name;
allIt.Value()->GetName(name);
std::string datatype;
if (allIt.Value()->GetData() != NULL)
datatype = allIt.Value()->GetData()->GetNameOfClass();
os << indent << " " << allIt.Value().GetPointer() << "<" << datatype << ">: " << name << std::endl;
mitk::DataStorage::SetOfObjects::ConstPointer parents = this->GetSources(allIt.Value());
if (parents->Size() > 0)
{
os << indent << " Direct sources: ";
for (mitk::DataStorage::SetOfObjects::ConstIterator parentIt = parents->Begin(); parentIt != parents->End(); parentIt++)
os << parentIt.Value().GetPointer() << ", ";
os << std::endl;
}
mitk::DataStorage::SetOfObjects::ConstPointer derivations = this->GetDerivations(allIt.Value());
if (derivations->Size() > 0)
{
os << indent << " Direct derivations: ";
for (mitk::DataStorage::SetOfObjects::ConstIterator derivationIt = derivations->Begin(); derivationIt != derivations->End(); derivationIt++)
os << derivationIt.Value().GetPointer() << ", ";
os << std::endl;
}
}
os << std::endl;
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::FilterSetOfObjects(const SetOfObjects* set, const NodePredicateBase* condition) const
{
if (set == NULL)
return NULL;
mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = set->Begin(); it != set->End(); it++)
if (condition == NULL || condition->CheckNode(it.Value()) == true) //alway copy the set, otherwise the iterator in mitk::DataStorage::Remove() will crash
result->InsertElement(result->Size(), it.Value());
return mitk::DataStorage::SetOfObjects::ConstPointer(result);
}
const mitk::DataNode::GroupTagList mitk::DataStorage::GetGroupTags() const
{
DataNode::GroupTagList result;
SetOfObjects::ConstPointer all = this->GetAll();
if (all.IsNull())
return result;
for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = all->Begin(); nodeIt != all->End(); nodeIt++) // for each node
{
mitk::PropertyList* pl = nodeIt.Value()->GetPropertyList();
for (mitk::PropertyList::PropertyMap::const_iterator propIt = pl->GetMap()->begin(); propIt != pl->GetMap()->end(); propIt++)
if (dynamic_cast<mitk::GroupTagProperty*>(propIt->second.GetPointer()) != NULL)
result.insert(propIt->first);
}
return result;
}
void mitk::DataStorage::EmitAddNodeEvent(const mitk::DataNode* node)
{
AddNodeEvent.Send(node);
}
void mitk::DataStorage::EmitRemoveNodeEvent(const mitk::DataNode* node)
{
RemoveNodeEvent.Send(node);
}
void mitk::DataStorage::OnNodeInteractorChanged( itk::Object *caller, const itk::EventObject& )
{
const mitk::DataNode* _Node = dynamic_cast<const mitk::DataNode*>(caller);
if(_Node)
{
InteractorChangedNodeEvent.Send( _Node );
}
}
void mitk::DataStorage::OnNodeModifiedOrDeleted( const itk::Object *caller, const itk::EventObject &event )
{
if( m_BlockNodeModifiedEvents )
return;
const mitk::DataNode* _Node = dynamic_cast<const mitk::DataNode*>(caller);
if(_Node)
{
const itk::ModifiedEvent* modEvent = dynamic_cast<const itk::ModifiedEvent*>(&event);
if(modEvent)
ChangedNodeEvent.Send(_Node);
else
DeleteNodeEvent.Send(_Node);
}
}
void mitk::DataStorage::AddListeners( const mitk::DataNode* _Node )
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_MutexOne);
// node must not be 0 and must not be yet registered
mitk::DataNode* NonConstNode = const_cast<mitk::DataNode*>(_Node);
if(_Node && m_NodeModifiedObserverTags
.find(NonConstNode) == m_NodeModifiedObserverTags.end())
{
itk::MemberCommand<mitk::DataStorage>::Pointer nodeModifiedCommand =
itk::MemberCommand<mitk::DataStorage>::New();
nodeModifiedCommand->SetCallbackFunction(this
, &mitk::DataStorage::OnNodeModifiedOrDeleted);
m_NodeModifiedObserverTags[NonConstNode]
= NonConstNode->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand);
itk::MemberCommand<mitk::DataStorage>::Pointer interactorChangedCommand = itk::MemberCommand<mitk::DataStorage>::New();
interactorChangedCommand->SetCallbackFunction(this, &mitk::DataStorage::OnNodeInteractorChanged);
m_NodeInteractorChangedObserverTags[NonConstNode] = NonConstNode->AddObserver( mitk::DataNode::InteractorChangedEvent(), interactorChangedCommand);
// add itk delete listener on datastorage
itk::MemberCommand<mitk::DataStorage>::Pointer deleteCommand =
itk::MemberCommand<mitk::DataStorage>::New();
deleteCommand->SetCallbackFunction(this, &mitk::DataStorage::OnNodeModifiedOrDeleted);
// add observer
m_NodeDeleteObserverTags[NonConstNode]
= NonConstNode->AddObserver(itk::DeleteEvent(), deleteCommand);
}
}
void mitk::DataStorage::RemoveListeners( const mitk::DataNode* _Node )
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_MutexOne) ;
// node must not be 0 and must be registered
mitk::DataNode* NonConstNode = const_cast<mitk::DataNode*>(_Node);
if(_Node && m_NodeModifiedObserverTags
.find(NonConstNode) != m_NodeModifiedObserverTags.end())
{
// const cast is bad! but sometimes it is necessary. removing an observer does not really
// touch the internal state
NonConstNode->RemoveObserver(m_NodeModifiedObserverTags
.find(NonConstNode)->second);
NonConstNode->RemoveObserver(m_NodeDeleteObserverTags
.find(NonConstNode)->second);
NonConstNode->RemoveObserver(m_NodeInteractorChangedObserverTags
.find(NonConstNode)->second);
m_NodeModifiedObserverTags.erase(NonConstNode);
m_NodeDeleteObserverTags.erase(NonConstNode);
m_NodeInteractorChangedObserverTags.erase(NonConstNode);
}
}
-mitk::TimeGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2) const
+mitk::TimeGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey, const mitk::BaseRenderer* renderer, const char* boolPropertyKey2) const
{
if (input == NULL)
throw std::invalid_argument("DataStorage: input is invalid");
BoundingBox::PointsContainer::Pointer pointscontainer=BoundingBox::PointsContainer::New();
BoundingBox::PointIdentifier pointid=0;
Point3D point;
Vector3D minSpacing;
minSpacing.Fill(itk::NumericTraits<mitk::ScalarType>::max());
ScalarType stmin, stmax;
stmin= itk::NumericTraits<mitk::ScalarType>::NonpositiveMin();
stmax= itk::NumericTraits<mitk::ScalarType>::max();
ScalarType minimalIntervallSize = stmax;
ScalarType minimalTime = stmax;
ScalarType maximalTime = 0;
// Needed for check of zero bounding boxes
mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsZero(nullpoint);
for (SetOfObjects::ConstIterator it = input->Begin(); it != input->End(); ++it)
{
DataNode::Pointer node = it->Value();
if((node.IsNotNull()) && (node->GetData() != NULL) &&
(node->GetData()->IsEmpty()==false) &&
node->IsOn(boolPropertyKey, renderer) &&
node->IsOn(boolPropertyKey2, renderer)
)
{
const TimeGeometry* timeGeometry = node->GetData()->GetUpdatedTimeGeometry();
if (timeGeometry != NULL )
{
// bounding box (only if non-zero)
BoundingBox::BoundsArrayType itkBounds = timeGeometry->GetBoundingBoxInWorld()->GetBounds();
if (itkBounds == itkBoundsZero)
{
continue;
}
unsigned char i;
for(i=0; i<8; ++i)
{
point = timeGeometry->GetCornerPointInWorld(i);
if(point[0]*point[0]+point[1]*point[1]+point[2]*point[2] < large)
pointscontainer->InsertElement( pointid++, point);
else
{
itkGenericOutputMacro( << "Unrealistically distant corner point encountered. Ignored. Node: " << node );
}
}
try
{
// time bounds
// iterate over all time steps
// Attention: Objects with zero bounding box are not respected in time bound calculation
for (TimeStepType i=0; i<timeGeometry->CountTimeSteps(); i++)
{
Vector3D spacing = node->GetData()->GetGeometry(i)->GetSpacing();
for (int axis = 0; axis < 3; ++ axis)
{
if (spacing[axis] < minSpacing[axis]) minSpacing[axis] = spacing[axis];
}
const TimeBounds & curTimeBounds = node->GetData()->GetTimeGeometry()->GetTimeBounds(i);
// get the minimal time of all objects in the DataStorage
if ((curTimeBounds[0]<minimalTime)&&(curTimeBounds[0]>stmin))
{
minimalTime=curTimeBounds[0];
}
// get the maximal time of all objects in the DataStorage
if ((curTimeBounds[1]>maximalTime)&&(curTimeBounds[1]<stmax))
{
maximalTime = curTimeBounds[1];
}
// get the minimal TimeBound of all time steps of the current DataNode
if (curTimeBounds[1]-curTimeBounds[0]<minimalIntervallSize)
{
minimalIntervallSize = curTimeBounds[1]-curTimeBounds[0];
}
}
}
catch(itk::ExceptionObject e)
{
MITK_ERROR << e << std::endl;
}
}
}
}
BoundingBox::Pointer result = BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
// compute the number of time steps
unsigned int numberOfTimeSteps = 1;
if (maximalTime==0) // make sure that there is at least one time sliced geometry in the data storage
{
minimalTime = 0;
maximalTime = 1;
minimalIntervallSize = 1;
}
numberOfTimeSteps = static_cast<unsigned int>((maximalTime-minimalTime)/minimalIntervallSize);
TimeGeometry::Pointer timeGeometry = NULL;
if ( result->GetPoints()->Size()>0 )
{
// Initialize a geometry of a single time step
Geometry3D::Pointer geometry = Geometry3D::New();
geometry->Initialize();
// correct bounding-box (is now in mm, should be in index-coordinates)
// according to spacing
BoundingBox::BoundsArrayType bounds = result->GetBounds();
int i;
for(i = 0; i < 6; ++i)
{
bounds[i] /= minSpacing[i/2];
}
geometry->SetBounds(bounds);
geometry->SetSpacing(minSpacing);
// Initialize the time sliced geometry
timeGeometry = ProportionalTimeGeometry::New();
dynamic_cast<ProportionalTimeGeometry*>(timeGeometry.GetPointer())->Initialize(geometry,numberOfTimeSteps);
dynamic_cast<ProportionalTimeGeometry*>(timeGeometry.GetPointer())->SetFirstTimePoint(minimalTime);
dynamic_cast<ProportionalTimeGeometry*>(timeGeometry.GetPointer())->SetStepDuration(minimalIntervallSize);
}
return timeGeometry;
}
-mitk::TimeGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2) const
+mitk::TimeGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const char* boolPropertyKey, const mitk::BaseRenderer* renderer, const char* boolPropertyKey2) const
{
return this->ComputeBoundingGeometry3D(this->GetAll(), boolPropertyKey, renderer, boolPropertyKey2);
}
-mitk::TimeGeometry::Pointer mitk::DataStorage::ComputeVisibleBoundingGeometry3D( mitk::BaseRenderer* renderer, const char* boolPropertyKey )
+mitk::TimeGeometry::Pointer mitk::DataStorage::ComputeVisibleBoundingGeometry3D( const mitk::BaseRenderer* renderer, const char* boolPropertyKey )
{
return ComputeBoundingGeometry3D( "visible", renderer, boolPropertyKey );
}
-mitk::BoundingBox::Pointer mitk::DataStorage::ComputeBoundingBox( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
+mitk::BoundingBox::Pointer mitk::DataStorage::ComputeBoundingBox( const char* boolPropertyKey, const mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
{
BoundingBox::PointsContainer::Pointer pointscontainer=BoundingBox::PointsContainer::New();
BoundingBox::PointIdentifier pointid=0;
Point3D point;
// Needed for check of zero bounding boxes
mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsZero(nullpoint);
SetOfObjects::ConstPointer all = this->GetAll();
for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
DataNode::Pointer node = it->Value();
if((node.IsNotNull()) && (node->GetData() != NULL) &&
(node->GetData()->IsEmpty()==false) &&
node->IsOn(boolPropertyKey, renderer) &&
node->IsOn(boolPropertyKey2, renderer)
)
{
const TimeGeometry* geometry = node->GetData()->GetUpdatedTimeGeometry();
if (geometry != NULL )
{
// bounding box (only if non-zero)
BoundingBox::BoundsArrayType itkBounds = geometry->GetBoundingBoxInWorld()->GetBounds();
if (itkBounds == itkBoundsZero)
{
continue;
}
unsigned char i;
for(i=0; i<8; ++i)
{
point = geometry->GetCornerPointInWorld(i);
if(point[0]*point[0]+point[1]*point[1]+point[2]*point[2] < large)
pointscontainer->InsertElement( pointid++, point);
else
{
itkGenericOutputMacro( << "Unrealistically distant corner point encountered. Ignored. Node: " << node );
}
}
}
}
}
BoundingBox::Pointer result = BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
return result;
}
-mitk::TimeBounds mitk::DataStorage::ComputeTimeBounds( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
+mitk::TimeBounds mitk::DataStorage::ComputeTimeBounds( const char* boolPropertyKey, const mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
{
TimeBounds timeBounds;
ScalarType stmin, stmax, cur;
stmin= itk::NumericTraits<mitk::ScalarType>::NonpositiveMin();
stmax= itk::NumericTraits<mitk::ScalarType>::max();
timeBounds[0]=stmax; timeBounds[1]=stmin;
SetOfObjects::ConstPointer all = this->GetAll();
for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
DataNode::Pointer node = it->Value();
if((node.IsNotNull()) && (node->GetData() != NULL) &&
(node->GetData()->IsEmpty()==false) &&
node->IsOn(boolPropertyKey, renderer) &&
node->IsOn(boolPropertyKey2, renderer)
)
{
const TimeGeometry* geometry = node->GetData()->GetUpdatedTimeGeometry();
if (geometry != NULL )
{
const TimeBounds & curTimeBounds = geometry->GetTimeBounds();
cur=curTimeBounds[0];
//is it after -infinity, but before everything else that we found until now?
if((cur > stmin) && (cur < timeBounds[0]))
timeBounds[0] = cur;
cur=curTimeBounds[1];
//is it before infinity, but after everything else that we found until now?
if((cur < stmax) && (cur > timeBounds[1]))
timeBounds[1] = cur;
}
}
}
if(!(timeBounds[0] < stmax))
{
timeBounds[0] = stmin;
timeBounds[1] = stmax;
}
return timeBounds;
}
void mitk::DataStorage::BlockNodeModifiedEvents( bool block )
{
m_BlockNodeModifiedEvents = block;
}
diff --git a/Core/Code/DataManagement/mitkDataStorage.h b/Core/Code/DataManagement/mitkDataStorage.h
index f4b84c2a61..a982ee0fef 100644
--- a/Core/Code/DataManagement/mitkDataStorage.h
+++ b/Core/Code/DataManagement/mitkDataStorage.h
@@ -1,414 +1,414 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKDATASTORAGE_H_HEADER_INCLUDED_
#define MITKDATASTORAGE_H_HEADER_INCLUDED_
#include "itkObject.h"
#include <MitkCoreExports.h>
#include "mitkMessage.h"
#include "itkVectorContainer.h"
#include "mitkDataNode.h"
#include "mitkGeometry3D.h"
#include "itkSimpleFastMutexLock.h"
#include <map>
namespace mitk {
class NodePredicateBase;
class DataNode;
class BaseRenderer;
//##Documentation
//## @brief Data management class that handles 'was created by' relations
//##
//## The DataStorage provides data storage and management functionality.
//## It handles a 'was created by' relation by associating each data object with a
//## set of source objects, that this object was created from.
//## Thus, nodes are stored in a noncyclical directed graph data structure.
//## If a new node is added to the DataStorage, AddNodeEvent is emitted.
//## If a node is removed, RemoveNodeEvent is emitted.
//##
//##
//## \ingroup DataStorage
class MITK_CORE_EXPORT DataStorage : public itk::Object
{
public:
mitkClassMacro(DataStorage, itk::Object);
//##Documentation
//## @brief A Container of objects that is used as a result set of GetSubset() query operations (Set of SmartPointers to DataNodes).
typedef itk::VectorContainer<unsigned int, mitk::DataNode::Pointer> SetOfObjects;
//##Documentation
//## @brief Adds a DataNode containing a data object to its internal storage
//##
//## This Method adds a new data object to the DataStorage. The new object is
//## passed in the first parameter. The second parameter is a set
//## of source objects, that were used to create this object. The new object will have
//## a 'was created from' relation to its source objects.
//## the addition of a new object will fire the notification mechanism.
//## If the node parameter is NULL or if the DataNode has already been added,
//## an exception will be thrown.
virtual void Add(mitk::DataNode* node, const mitk::DataStorage::SetOfObjects* parents = NULL) = 0;
//##Documentation
//## @brief Convenience method to add a node that has one parent
//##
void Add(mitk::DataNode* node, mitk::DataNode* parent);
//##Documentation
//## @brief Removes node from the DataStorage
//##
virtual void Remove(const mitk::DataNode* node) = 0;
//##Documentation
//## @brief Checks if a node exists in the DataStorage
//##
virtual bool Exists(const mitk::DataNode* node) const = 0;
//##Documentation
//## @brief Removes a set of nodes from the DataStorage
//##
void Remove(const mitk::DataStorage::SetOfObjects* nodes);
//##Documentation
//## @brief returns a set of data objects that meet the given condition(s)
//##
//## GetSubset returns a set of objects with a specific data type that meet the condition(s)
//## specified in the condition parameter. Conditions can be
//## - data type of the data object
//## - is source object of specific object (e.g. all source objects of node x)
//## - has property with specific value (e.g. OrganType is Liver)
//## - negation of any condition
//## - conjunction of a set of conditions
//## - disjunction of a set of conditions
//## Conditions are implemented as predicates using the Composite Design Pattern
//## (see definition of NodePredicateBase for details).
//## The method returns a set of SmartPointers to the DataNodes that fulfill the
//## conditions. A set of all objects can be retrieved with the GetAll() method;
SetOfObjects::ConstPointer GetSubset(const NodePredicateBase* condition) const;
//##Documentation
//## @brief returns a set of source objects for a given node that meet the given condition(s).
//##
virtual SetOfObjects::ConstPointer GetSources(const mitk::DataNode* node, const NodePredicateBase* condition = NULL, bool onlyDirectSources = true) const = 0;
//##Documentation
//## @brief returns a set of derived objects for a given node.
//##
//## GetDerivations() returns a set of objects that are derived from the DataNode node.
//## This means, that node was used to create the returned objects. If the parameter
//## onlyDirectDerivations is set to true (default value), only objects that directly have
//## node as one of their source objects will be returned. Otherwise, objects that are
//## derived from derivations of node are returned too.
//## The derived objects can be filtered with a predicate object as described in the GetSubset()
//## method by providing a predicate as the condition parameter.
virtual SetOfObjects::ConstPointer GetDerivations(const mitk::DataNode* node, const NodePredicateBase* condition = NULL, bool onlyDirectDerivations = true) const = 0;
//##Documentation
//## @brief returns a set of all data objects that are stored in the data storage
//##
virtual SetOfObjects::ConstPointer GetAll() const = 0;
//##Documentation
//## @brief Convenience method to get the first node that matches the predicate condition
//##
mitk::DataNode* GetNode(const NodePredicateBase* condition = NULL) const;
//##Documentation
//## @brief Convenience method to get the first node with a given name
//##
mitk::DataNode* GetNamedNode(const char* name) const;
//##Documentation
//## @brief Convenience method to get the first node with a given name
//##
mitk::DataNode* GetNamedNode(const std::string name) const
{
return this->GetNamedNode(name.c_str());
}
//##Documentation
//## @brief Convenience method to get the first node with a given name that is derived from sourceNode
//##
mitk::DataNode* GetNamedDerivedNode(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations = true) const;
//##Documentation
//## @brief Convenience method to get the first data object of a given data type with a given name
//##
template <class DataType>
DataType* GetNamedObject(const char* name) const
{
if (name == NULL)
return NULL;
mitk::DataNode* n = this->GetNamedNode(name);
if (n == NULL)
return NULL;
else
return dynamic_cast<DataType*>(n->GetData());
}
//##Documentation
//## @brief Convenience method to get the first data object of a given data type with a given name
//##
template <class DataType>
DataType* GetNamedObject(const std::string name) const
{
return this->GetNamedObject<DataType>(name.c_str());
}
//##Documentation
//## @brief Convenience method to get the first data object of a given data type with a given name that is derived from a specific node
//##
template <class DataType>
DataType* GetNamedDerivedObject(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations = true) const
{
if (name == NULL)
return NULL;
mitk::DataNode* n = this->GetNamedDerivedNode(name, sourceNode, onlyDirectDerivations);
if (n == NULL)
return NULL;
else
return dynamic_cast<DataType*>(n->GetData());
}
//##Documentation
//## @brief Returns a list of used grouptags
//##
const DataNode::GroupTagList GetGroupTags() const;
/*ITK Mutex */
mutable itk::SimpleFastMutexLock m_MutexOne;
/* Public Events */
typedef Message1<const mitk::DataNode*> DataStorageEvent;
//##Documentation
//## @brief AddEvent is emitted whenever a new node has been added to the DataStorage.
//##
//## Observers should register to this event by calling myDataStorage->AddNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage.
//## Observers should unregister by calling myDataStorage->AddNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Note: AddEvents are _not_ emitted if a node is added to DataStorage by adding it to the the underlying DataTree!
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent AddNodeEvent;
//##Documentation
//## @brief RemoveEvent is emitted directly before a node is removed from the DataStorage.
//##
//## Observers should register to this event by calling myDataStorage->RemoveNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage.
//## Observers should unregister by calling myDataStorage->RemoveNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Note: RemoveEvents are also emitted if a node was removed from the DataStorage by deleting it from the underlying DataTree
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent RemoveNodeEvent;
//##Documentation
//## @brief ChangedEvent is emitted directly after a node was changed.
//##
//## Observers should register to this event by calling myDataStorage->ChangedNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called every time a new node has been changed.
//## Observers should unregister by calling myDataStorage->ChangedNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Internally the DataStorage listens to itk::ModifiedEvents on the nodes and forwards them
//## to the listeners of this event.
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent ChangedNodeEvent;
//##Documentation
//## @brief DeleteNodeEvent is emitted directly before a node is deleted.
//##
//## Observers should register to this event by calling myDataStorage->DeleteNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called when a node is deleted.
//## Observers should unregister by calling myDataStorage->DeleteNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Internally the DataStorage listens to itk::DeleteEvents on the nodes and forwards them
//## to the listeners of this event.
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent DeleteNodeEvent;
DataStorageEvent InteractorChangedNodeEvent;
//##Documentation
//## @brief Compute the axis-parallel bounding geometry of the input objects
//##
//## Throws std::invalid_argument exception if input is NULL
//## @param input set of objects of the DataStorage to be included in the bounding geometry
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
- mitk::TimeGeometry::Pointer ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey = NULL, mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL) const;
+ mitk::TimeGeometry::Pointer ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey = NULL, const mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL) const;
//##Documentation
//## @brief Compute the axis-parallel bounding geometry of the data tree
//## (bounding box, minimal spacing of the considered nodes, live-span)
//##
//## it -> an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
- mitk::TimeGeometry::Pointer ComputeBoundingGeometry3D( const char* boolPropertyKey = NULL, mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL) const;
+ mitk::TimeGeometry::Pointer ComputeBoundingGeometry3D( const char* boolPropertyKey = NULL, const mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL) const;
//##Documentation
//## @brief Compute the axis-parallel bounding geometry of all visible parts of the
//## data tree bounding box, minimal spacing of the considered nodes, live-span)
//##
//## Simply calls ComputeBoundingGeometry3D(it, "visible", renderer, boolPropertyKey).
//## it -> an iterator of a data tree structure
//## @param renderer the reference to the renderer
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
- mitk::TimeGeometry::Pointer ComputeVisibleBoundingGeometry3D( mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey = NULL);
+ mitk::TimeGeometry::Pointer ComputeVisibleBoundingGeometry3D( const mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey = NULL);
//##Documentation
//## @brief Compute the bounding box of data tree structure
//## it -> an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
- mitk::BoundingBox::Pointer ComputeBoundingBox( const char* boolPropertyKey = NULL, mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL);
+ mitk::BoundingBox::Pointer ComputeBoundingBox( const char* boolPropertyKey = NULL, const mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL);
//##Documentation
//## \brief Compute the bounding box of all visible parts of the data tree structure, for general
//## rendering or renderer specific visibility property checking
//##
//## Simply calls ComputeBoundingBox(it, "visible", renderer, boolPropertyKey).
//## it -> an iterator of a data tree structure
//## @param renderer the reference to the renderer
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
- mitk::BoundingBox::Pointer ComputeVisibleBoundingBox( mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey = NULL)
+ mitk::BoundingBox::Pointer ComputeVisibleBoundingBox( const mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey = NULL)
{
return ComputeBoundingBox( "visible", renderer, boolPropertyKey);
}
//##Documentation
//## @brief Compute the time-bounds of the contents of a data tree structure
//##
//## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise,
//## all data-objects with infinite live-span are ignored.
//## it -> an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the time-bounds calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
- mitk::TimeBounds ComputeTimeBounds( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2);
+ mitk::TimeBounds ComputeTimeBounds( const char* boolPropertyKey, const mitk::BaseRenderer* renderer, const char* boolPropertyKey2);
//##Documentation
//## @brief Compute the time-bounds of all visible parts of the data tree structure, for general
//## rendering or renderer specific visibility property checking
//##
//## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise,
//## all data-objects with infinite live-span are ignored.
//## Simply calls ComputeTimeBounds(it, "visible", renderer, boolPropertyKey).
//## @param it an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the time-bounds calculation.
//## @param renderer see @a boolPropertyKey
- mitk::TimeBounds ComputeTimeBounds( mitk::BaseRenderer* renderer, const char* boolPropertyKey)
+ mitk::TimeBounds ComputeTimeBounds( const mitk::BaseRenderer* renderer, const char* boolPropertyKey)
{
return ComputeTimeBounds( "visible", renderer, boolPropertyKey);
}
//##Documentation
//## @brief Defines whether or not NodeChangedEvent is invoked .
//##
//## This method can be used to set m_BlockNodeModifiedEvents.
//##
//## If this flag is true, NodeChangedEvent is not invoked when a
//## DataNode is modified. This might be undesired when setting
//## many properties on a datanode and you do not want anyone to
//## react.
void BlockNodeModifiedEvents( bool block );
protected:
//##Documentation
//## @brief EmitAddNodeEvent emits the AddNodeEvent
//##
//## This method should be called by subclasses to emit the AddNodeEvent
void EmitAddNodeEvent(const mitk::DataNode* node);
//##Documentation
//## @brief EmitRemoveNodeEvent emits the RemoveNodeEvent
//##
//## This method should be called by subclasses to emit the RemoveNodeEvent
void EmitRemoveNodeEvent(const mitk::DataNode* node);
void OnNodeInteractorChanged( itk::Object *caller, const itk::EventObject &event );
//##Documentation
//## @brief OnNodeModified listens to modified events of DataNodes.
//##
//## The node is hidden behind the caller parameter, which has to be casted first.
//## If the cast succeeds the ChangedNodeEvent is emitted with this node.
void OnNodeModifiedOrDeleted( const itk::Object *caller, const itk::EventObject &event );
//##Documentation
//## @brief Adds a Modified-Listener to the given Node.
void AddListeners(const mitk::DataNode* _Node);
//##Documentation
//## @brief Removes a Modified-Listener from the given Node.
void RemoveListeners(const mitk::DataNode* _Node);
//##Documentation
//## @brief Saves Modified-Observer Tags for each node in order to remove the event listeners again.
std::map<const mitk::DataNode*, unsigned long> m_NodeModifiedObserverTags;
std::map<const mitk::DataNode*, unsigned long> m_NodeInteractorChangedObserverTags;
//##Documentation
//## @brief Saves Delete-Observer Tags for each node in order to remove the event listeners again.
std::map<const mitk::DataNode*, unsigned long> m_NodeDeleteObserverTags;
//##Documentation
//## @brief If this class changes nodes itself, set this to TRUE in order
//## to suppress NodeChangedEvent to be emitted.
bool m_BlockNodeModifiedEvents;
//##Documentation
//## @brief Standard Constructor for ::New() instantiation
DataStorage();
//##Documentation
//## @brief Standard Destructor
virtual ~DataStorage();
//##Documentation
//## @brief Filters a SetOfObjects by the condition. If no condition is provided, the original set is returned
SetOfObjects::ConstPointer FilterSetOfObjects(const SetOfObjects* set, const NodePredicateBase* condition) const;
//##Documentation
//## @brief Prints the contents of the DataStorage to os. Do not call directly, call ->Print() instead
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
};
} // namespace mitk
#endif /* MITKDATASTORAGE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkImageReadAccessor.cpp b/Core/Code/DataManagement/mitkImageReadAccessor.cpp
index 4a9f7c7fa5..791d366452 100644
--- a/Core/Code/DataManagement/mitkImageReadAccessor.cpp
+++ b/Core/Code/DataManagement/mitkImageReadAccessor.cpp
@@ -1,138 +1,158 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkImageReadAccessor.h"
#include "mitkImage.h"
mitk::ImageReadAccessor::ImageReadAccessor(
ImageConstPointer image,
const mitk::ImageDataItem* iDI,
int OptionFlags)
: ImageAccessorBase(image,iDI,OptionFlags)
, m_Image(image)
{
if(!(OptionFlags & ImageAccessorBase::IgnoreLock))
{
- OrganizeReadAccess();
+ try
+ {
+ OrganizeReadAccess();
+ }
+ catch (...)
+ {
+ delete m_WaitLock;
+ throw;
+ }
}
}
mitk::ImageReadAccessor::ImageReadAccessor(
ImagePointer image,
const mitk::ImageDataItem* iDI,
int OptionFlags)
: ImageAccessorBase(image.GetPointer(), iDI, OptionFlags)
, m_Image(image.GetPointer())
{
if(!(OptionFlags & ImageAccessorBase::IgnoreLock))
{
- OrganizeReadAccess();
+ try
+ {
+ OrganizeReadAccess();
+ }
+ catch (...)
+ {
+ delete m_WaitLock;
+ throw;
+ }
}
}
mitk::ImageReadAccessor::ImageReadAccessor(const mitk::Image* image, const ImageDataItem* iDI)
: ImageAccessorBase(image, iDI, ImageAccessorBase::DefaultBehavior)
, m_Image(image)
{
OrganizeReadAccess();
}
mitk::ImageReadAccessor::~ImageReadAccessor()
{
if(!(m_Options & ImageAccessorBase::IgnoreLock))
{
// Future work: In case of non-coherent memory, copied area needs to be deleted
m_Image->m_ReadWriteLock.Lock();
// delete self from list of ImageReadAccessors in Image
std::vector<ImageAccessorBase*>::iterator it = std::find(m_Image->m_Readers.begin(),m_Image->m_Readers.end(),this);
m_Image->m_Readers.erase(it);
// delete lock, if there are no waiting ImageAccessors
if(m_WaitLock->m_WaiterCount <= 0)
{
m_WaitLock->m_Mutex.Unlock();
delete m_WaitLock;
}
else
{
m_WaitLock->m_Mutex.Unlock();
}
m_Image->m_ReadWriteLock.Unlock();
}
+ else
+ {
+ delete m_WaitLock;
+ }
}
const mitk::Image* mitk::ImageReadAccessor::GetImage() const
{
return m_Image.GetPointer();
}
void mitk::ImageReadAccessor::OrganizeReadAccess()
{
m_Image->m_ReadWriteLock.Lock();
// Check, if there is any Write-Access going on
if(m_Image->m_Writers.size() > 0)
{
// Check for every WriteAccessors, if the Region of this ImageAccessors overlaps
// make sure this iterator is not used, when m_ReadWriteLock is Unlocked!
std::vector<ImageAccessorBase*>::iterator it = m_Image->m_Writers.begin();
for(; it!=m_Image->m_Writers.end(); ++it)
{
ImageAccessorBase* w = *it;
if( Overlap(w) )
{
// An Overlap was detected. There are two possibilities to deal with this situation:
// Throw an exception or wait for the WriteAccessor w until it is released and start again with the request afterwards.
if(!(m_Options & ExceptionIfLocked))
{
PreventRecursiveMutexLock(w);
// WAIT
w->Increment();
m_Image->m_ReadWriteLock.Unlock();
ImageAccessorBase::WaitForReleaseOf(w->m_WaitLock);
//after waiting for the WriteAccessor w, start this method again
OrganizeReadAccess();
return;
}
else
{
// THROW EXCEPTION
m_Image->m_ReadWriteLock.Unlock();
mitkThrowException(mitk::MemoryIsLockedException) << "The image part being ordered by the ImageAccessor is already in use and locked";
return;
}
} // if
} // for
} // if
// Now, we know, that there is no conflict with a Write-Access
// Lock the Mutex in ImageAccessorBase, to make sure that every other ImageAccessor has to wait if it locks the mutex
m_WaitLock->m_Mutex.Lock();
// insert self into readers list in Image
m_Image->m_Readers.push_back(this);
//printf("ReadAccess %d %d\n",(int) m_Image->m_Readers.size(),(int) m_Image->m_Writers.size());
//fflush(0);
m_Image->m_ReadWriteLock.Unlock();
}
diff --git a/Core/Code/DataManagement/mitkLevelWindowManager.cpp b/Core/Code/DataManagement/mitkLevelWindowManager.cpp
index 317fcffc38..ac31dc4cc2 100644
--- a/Core/Code/DataManagement/mitkLevelWindowManager.cpp
+++ b/Core/Code/DataManagement/mitkLevelWindowManager.cpp
@@ -1,478 +1,482 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkLevelWindowManager.h"
#include <itkCommand.h>
#include "mitkDataStorage.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateNot.h"
#include "mitkProperties.h"
#include "mitkMessage.h"
#include "mitkRenderingModeProperty.h"
#include "mitkImage.h"
mitk::LevelWindowManager::LevelWindowManager()
: m_DataStorage(NULL)
, m_LevelWindowProperty(NULL)
, m_AutoTopMost(true)
, m_IsObserverTagSet(false)
, m_CurrentImage(NULL)
, m_IsPropertyModifiedTagSet(false)
{
}
mitk::LevelWindowManager::~LevelWindowManager()
{
if (m_DataStorage.IsNotNull())
{
m_DataStorage->AddNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageAddedNode ));
m_DataStorage->RemoveNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageRemovedNode ));
m_DataStorage = NULL;
}
if (m_IsPropertyModifiedTagSet && m_LevelWindowProperty.IsNotNull())
{
m_LevelWindowProperty->RemoveObserver(m_PropertyModifiedTag);
m_IsPropertyModifiedTagSet = false;
}
//clear both observer maps
this->ClearPropObserverLists();
}
void mitk::LevelWindowManager::SetDataStorage( mitk::DataStorage* ds )
{
if (ds == NULL) return;
/* remove listeners of old DataStorage */
if (m_DataStorage.IsNotNull())
{
m_DataStorage->AddNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageAddedNode ));
m_DataStorage->RemoveNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageRemovedNode ));
}
/* register listener for new DataStorage */
m_DataStorage = ds; // register
m_DataStorage->AddNodeEvent.AddListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageAddedNode ));
m_DataStorage->RemoveNodeEvent.AddListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageRemovedNode ));
this->DataStorageAddedNode(); // update us with new DataStorage
}
void mitk::LevelWindowManager::OnPropertyModified(const itk::EventObject& )
{
Modified();
}
void mitk::LevelWindowManager::SetAutoTopMostImage(bool autoTopMost, const mitk::DataNode* removedNode)
{
m_AutoTopMost = autoTopMost;
if (m_AutoTopMost == false)
return;
if (m_IsPropertyModifiedTagSet && m_LevelWindowProperty.IsNotNull())
{
m_LevelWindowProperty->RemoveObserver(m_PropertyModifiedTag);
m_IsPropertyModifiedTagSet = false;
}
/* search topmost image */
if (m_DataStorage.IsNull())
{
itkExceptionMacro("DataStorage not set");
}
int maxLayer = itk::NumericTraits<int>::min();
m_LevelWindowProperty = NULL;
mitk::DataNode::Pointer topLevelNode;
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetRelevantNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
mitk::DataNode::Pointer node = it->Value();
if (node.IsNull() || (removedNode != NULL && node == removedNode))
continue;
node->SetBoolProperty( "imageForLevelWindow", false );
if (node->IsVisible(NULL) == false)
continue;
int layer = 0;
node->GetIntProperty("layer", layer);
if ( layer < maxLayer )
continue;
mitk::LevelWindowProperty::Pointer levelWindowProperty = dynamic_cast<mitk::LevelWindowProperty*>(node->GetProperty("levelwindow"));
if (levelWindowProperty.IsNull())
continue;
int nonLvlWinMode1 = mitk::RenderingModeProperty::LOOKUPTABLE_COLOR;
int nonLvlWinMode2 = mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR;
mitk::RenderingModeProperty::Pointer mode = dynamic_cast<mitk::RenderingModeProperty*>(node->GetProperty( "Image Rendering.Mode" ));
if( mode.IsNotNull() )
{
int currMode = mode->GetRenderingMode();
if ( currMode == nonLvlWinMode1 || currMode == nonLvlWinMode2 )
{
continue;
}
}
else continue;
m_LevelWindowProperty = levelWindowProperty;
m_CurrentImage = dynamic_cast<mitk::Image*>(node->GetData());
topLevelNode = node;
maxLayer = layer;
}
if (topLevelNode.IsNotNull())
{
topLevelNode->SetBoolProperty( "imageForLevelWindow", true );
}
this->SetLevelWindowProperty( m_LevelWindowProperty );
if ( m_LevelWindowProperty.IsNull() )
{
Modified();
}
// else SetLevelWindowProperty will call Modified();
}
// sets an specific LevelWindowProperty, all changes will affect the image belonging to this property.
void mitk::LevelWindowManager::SetLevelWindowProperty(LevelWindowProperty::Pointer levelWindowProperty)
{
if (levelWindowProperty.IsNull())
return;
if (m_IsPropertyModifiedTagSet) // remove listener for old property
{
m_LevelWindowProperty->RemoveObserver(m_PropertyModifiedTag);
m_IsPropertyModifiedTagSet = false;
}
m_LevelWindowProperty = levelWindowProperty;
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command = itk::ReceptorMemberCommand<LevelWindowManager>::New(); // register listener for new property
command->SetCallbackFunction(this, &LevelWindowManager::OnPropertyModified);
m_PropertyModifiedTag = m_LevelWindowProperty->AddObserver( itk::ModifiedEvent(), command );
m_IsPropertyModifiedTagSet = true;
/* search image than belongs to the property */
mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("levelwindow", m_LevelWindowProperty);
mitk::DataNode* n = m_DataStorage->GetNode(p);
if (n == NULL)
{
mitkThrow() << "No Image in DataStorage that belongs to LevelWindow property" << m_LevelWindowProperty;
}
m_CurrentImage = dynamic_cast<mitk::Image*>(n->GetData());
n->SetBoolProperty( "imageForLevelWindow", true );
this->Modified();
}
// returns the current mitkLevelWindowProperty object from the image that is affected by changes
mitk::LevelWindowProperty::Pointer mitk::LevelWindowManager::GetLevelWindowProperty()
{
return m_LevelWindowProperty;
}
// returns Level/Window values for the current image
const mitk::LevelWindow& mitk::LevelWindowManager::GetLevelWindow()
{
if (m_LevelWindowProperty.IsNotNull())
{
return m_LevelWindowProperty->GetLevelWindow();
}
else
{
itkExceptionMacro("No LevelWindow available!");
}
}
// sets new Level/Window values and informs all listeners about changes
void mitk::LevelWindowManager::SetLevelWindow(const mitk::LevelWindow& levelWindow)
{
if (m_LevelWindowProperty.IsNotNull())
{
m_LevelWindowProperty->SetLevelWindow(levelWindow);
}
this->Modified();
}
void mitk::LevelWindowManager::DataStorageAddedNode( const mitk::DataNode* )
{
//update observers with new data storage
UpdateObservers();
//Initialize LevelWindowsManager to new image
SetAutoTopMostImage(true);
//check if everything is still ok
if ((m_PropObserverToNode.size() != m_PropObserverToNode2.size()) || (m_PropObserverToNode2.size() != this->GetRelevantNodes()->size()))
{mitkThrow() << "Wrong number of observers in Level Window Manager!";}
}
void mitk::LevelWindowManager::DataStorageRemovedNode( const mitk::DataNode* removedNode )
{
//first: check if deleted node is part of relevant nodes. If not, abort method because there is no need change anything.
if ((this->GetRelevantNodes()->size() == 0)) return;
bool removedNodeIsRelevant = false;
/* Iterator code: is crashing, don't know why... so using for loop
for (mitk::DataStorage::SetOfObjects::ConstIterator it = this->GetRelevantNodes()->Begin();
it != this->GetRelevantNodes()->End();
++it)
{if (it->Value() == removedNode) {removedNodeIsRelevant=true;}}*/
for (unsigned int i=0; i<this->GetRelevantNodes()->size(); i++)
{
if (this->GetRelevantNodes()->at(i) == removedNode) {removedNodeIsRelevant=true;}
}
if (!removedNodeIsRelevant) return;
//remember node which will be removed
m_NodeMarkedToDelete = removedNode;
//update observers
UpdateObservers();
/* search image than belongs to the property */
if (m_LevelWindowProperty.IsNull())
{
SetAutoTopMostImage(true, removedNode);
}
else
{
mitk::NodePredicateProperty::Pointer p2 = mitk::NodePredicateProperty::New("levelwindow", m_LevelWindowProperty);
mitk::DataNode* n = m_DataStorage->GetNode(p2);
if (n == NULL || m_AutoTopMost) // if node was deleted, change our behaviour to AutoTopMost, if AutoTopMost is true change level window to topmost node
{
SetAutoTopMostImage(true, removedNode);
}
}
//reset variable
m_NodeMarkedToDelete = NULL;
//check if everything is still ok
if ((m_PropObserverToNode.size() != m_PropObserverToNode2.size()) || (m_PropObserverToNode2.size() != (this->GetRelevantNodes()->size()-1)))
{mitkThrow() << "Wrong number of observers in Level Window Manager!";}
}
void mitk::LevelWindowManager::UpdateObservers()
{
this->ClearPropObserverLists(); //remove old observers
CreatePropObserverLists(); //create new observer lists
}
int mitk::LevelWindowManager::GetNumberOfObservers()
{
return m_PropObserverToNode.size();
}
mitk::DataStorage* mitk::LevelWindowManager::GetDataStorage()
{
return m_DataStorage.GetPointer();
}
// true if changes on slider or line-edits will affect always the topmost layer image
bool mitk::LevelWindowManager::isAutoTopMost()
{
return m_AutoTopMost;
}
void mitk::LevelWindowManager::Update(const itk::EventObject&) // visible property of a image has changed
{
if (m_AutoTopMost)
{
SetAutoTopMostImage(true);
return;
}
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetRelevantNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
mitk::DataNode::Pointer node = it->Value();
if (node.IsNull())
continue;
node->SetBoolProperty( "imageForLevelWindow", false );
if (node->IsVisible(NULL) == false)
continue;
mitk::LevelWindowProperty::Pointer levelWindowProperty = dynamic_cast<mitk::LevelWindowProperty*>(node->GetProperty("levelwindow"));
if (levelWindowProperty.IsNull())
continue;
m_LevelWindowProperty = levelWindowProperty;
m_CurrentImage = dynamic_cast<mitk::Image*>(node->GetData());
node->SetBoolProperty( "imageForLevelWindow", true );
if (m_LevelWindowProperty.IsNull() && m_LevelWindowProperty.GetPointer() == levelWindowProperty) // we found our m_LevelWindowProperty
{
return;
}
}
Modified();
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::LevelWindowManager::GetRelevantNodes()
{
if (m_DataStorage.IsNull())
return mitk::DataStorage::SetOfObjects::ConstPointer(mitk::DataStorage::SetOfObjects::New()); // return empty set
mitk::BoolProperty::Pointer trueProp = mitk::BoolProperty::New(true);
mitk::NodePredicateProperty::Pointer notBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(false));
mitk::NodePredicateProperty::Pointer hasLevelWindow = mitk::NodePredicateProperty::New("levelwindow", NULL);
mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image");
mitk::NodePredicateDataType::Pointer isDImage = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isTImage = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQImage = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer predicateTypes = mitk::NodePredicateOr::New();
predicateTypes->AddPredicate(isImage);
predicateTypes->AddPredicate(isDImage);
predicateTypes->AddPredicate(isTImage);
predicateTypes->AddPredicate(isQImage);
mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New();
predicate->AddPredicate(notBinary);
predicate->AddPredicate(hasLevelWindow);
predicate->AddPredicate(predicateTypes);
mitk::DataStorage::SetOfObjects::ConstPointer relevantNodes = m_DataStorage->GetSubset( predicate );
return relevantNodes;
}
mitk::Image* mitk::LevelWindowManager::GetCurrentImage()
{
return m_CurrentImage;
}
void mitk::LevelWindowManager::ClearPropObserverLists()
{
for( ObserverToPropertyMap::iterator iter = m_PropObserverToNode.begin();
iter != m_PropObserverToNode.end();
++iter )
{
(*iter).second->RemoveObserver((*iter).first.first);
(*iter).second = 0;
}
m_PropObserverToNode.clear();
for( ObserverToPropertyMap::iterator iter = m_PropObserverToNode2.begin();
iter != m_PropObserverToNode2.end();
++iter )
{
(*iter).second->RemoveObserver((*iter).first.first);
(*iter).second = 0;
}
m_PropObserverToNode2.clear();
for( ObserverToPropertyMap::iterator iter = m_PropObserverToNode3.begin();
iter != m_PropObserverToNode3.end();
++iter )
{
(*iter).second->RemoveObserver((*iter).first.first);
(*iter).second = 0;
}
m_PropObserverToNode3.clear();
}
void mitk::LevelWindowManager::CreatePropObserverLists()
{
if (m_DataStorage.IsNull()) //check if data storage is set
{itkExceptionMacro("DataStorage not set");}
/* add observers for all relevant nodes */
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetRelevantNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
if ((it->Value().IsNull()) || (it->Value() == m_NodeMarkedToDelete))
{continue;}
/* register listener for changes in visible property */
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command = itk::ReceptorMemberCommand<LevelWindowManager>::New();
command->SetCallbackFunction(this, &LevelWindowManager::Update);
unsigned long idx = it->Value()->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command );
m_PropObserverToNode[PropDataPair(idx, it->Value())] = it->Value()->GetProperty("visible");
}
/* add observers for all layer properties*/
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
if ((it->Value().IsNull()) || (it->Value() == m_NodeMarkedToDelete))
{continue;}
/* register listener for changes in layer property */
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command2 = itk::ReceptorMemberCommand<LevelWindowManager>::New();
command2->SetCallbackFunction(this, &LevelWindowManager::Update);
unsigned long idx = it->Value()->GetProperty("layer")->AddObserver( itk::ModifiedEvent(), command2 );
m_PropObserverToNode2[PropDataPair(idx, it->Value())] = it->Value()->GetProperty("layer");
}
/* add observers for all Image rendering.mode properties*/
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
if ((it->Value().IsNull()) || (it->Value() == m_NodeMarkedToDelete))
{continue;}
/* register listener for changes in layer property */
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command3 = itk::ReceptorMemberCommand<LevelWindowManager>::New();
command3->SetCallbackFunction(this, &LevelWindowManager::Update);
- unsigned long idx = it->Value()->GetProperty("Image Rendering.Mode")->AddObserver( itk::ModifiedEvent(), command3 );
- m_PropObserverToNode3[PropDataPair(idx, it->Value())] = it->Value()->GetProperty("Image Rendering.Mode");
+ mitk::BaseProperty::Pointer imageRenderingMode = it->Value()->GetProperty("Image Rendering.Mode");
+ if( imageRenderingMode.IsNotNull() )
+ {
+ unsigned long idx = imageRenderingMode->AddObserver( itk::ModifiedEvent(), command3 );
+ m_PropObserverToNode3[PropDataPair(idx, it->Value())] = imageRenderingMode.GetPointer();
+ }
}
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateProperty.cpp b/Core/Code/DataManagement/mitkNodePredicateProperty.cpp
index 555fd9fffb..6c32ddbd22 100644
--- a/Core/Code/DataManagement/mitkNodePredicateProperty.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateProperty.cpp
@@ -1,58 +1,53 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkNodePredicateProperty.h"
#include "mitkDataNode.h"
-mitk::NodePredicateProperty::NodePredicateProperty(const char* propertyName, mitk::BaseProperty* p)
-: NodePredicateBase(), m_ValidProperty(p), m_ValidPropertyName(propertyName)
-{
-}
-
-mitk::NodePredicateProperty::NodePredicateProperty(const char* propertyName)
-: NodePredicateBase(), m_ValidProperty(NULL), m_ValidPropertyName(propertyName)
+mitk::NodePredicateProperty::NodePredicateProperty(const char* propertyName, mitk::BaseProperty* p, const mitk::BaseRenderer *renderer)
+: NodePredicateBase(), m_ValidProperty(p), m_ValidPropertyName(propertyName), m_Renderer(renderer)
{
}
mitk::NodePredicateProperty::~NodePredicateProperty()
{
}
bool mitk::NodePredicateProperty::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateProperty: invalid node");
if (m_ValidPropertyName.empty())
throw std::invalid_argument("NodePredicateProperty: invalid property name");
// check, if any of the properties of node are equal to m_ValidProperty.
if (m_ValidProperty.IsNull())
//if (m_ValidProperty==NULL)
{
- return (node->GetPropertyList()->GetProperty(m_ValidPropertyName.c_str()) != NULL); // search only for name
+ return (node->GetProperty(m_ValidPropertyName.c_str(), m_Renderer) != NULL); // search only for name
}
else
{
- mitk::BaseProperty::Pointer p = node->GetPropertyList()->GetProperty(m_ValidPropertyName.c_str());
+ mitk::BaseProperty::Pointer p = node->GetProperty(m_ValidPropertyName.c_str(), m_Renderer);
if (p.IsNull())
return false;
return (*p == *m_ValidProperty); // search for name and property
}
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateProperty.h b/Core/Code/DataManagement/mitkNodePredicateProperty.h
index 595d70d1f2..cd3837f19f 100644
--- a/Core/Code/DataManagement/mitkNodePredicateProperty.h
+++ b/Core/Code/DataManagement/mitkNodePredicateProperty.h
@@ -1,66 +1,67 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKNODEPREDICATEPROPERTY_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEPROPERTY_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
#include "mitkBaseProperty.h"
#include "mitkWeakPointer.h"
+#include "mitkBaseRenderer.h"
namespace mitk {
//##Documentation
//## @brief Predicate that evaluates if the given DataNode has a specific property.
//## If the second parameter is NULL, it will only be checked whether there is a property with the specified name.
+ //## If a renderer is specified in the third parameter the renderer-specific property will be checked. If this
+ //## parameter is NULL or not specified, then the non-renderer-specific property will be checked.
//##
//##
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateProperty : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateProperty, NodePredicateBase);
mitkNewMacro1Param(NodePredicateProperty, const char*);
mitkNewMacro2Param(NodePredicateProperty, const char*, mitk::BaseProperty*);
+ mitkNewMacro3Param(NodePredicateProperty, const char*, mitk::BaseProperty*, const mitk::BaseRenderer*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateProperty();
//##Documentation
//## @brief Checks, if the nodes contains a property that is equal to m_ValidProperty
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Constructor to check for a named property
- NodePredicateProperty(const char* propertyName, mitk::BaseProperty* p);
-
- //##Documentation
- //## @brief Constructor to check for the existence of a property with a given name
- NodePredicateProperty(const char* propertyName);
+ NodePredicateProperty(const char* propertyName, mitk::BaseProperty* p=0, const mitk::BaseRenderer *renderer=0);
//mitk::WeakPointer<mitk::BaseProperty> m_ValidProperty;
mitk::BaseProperty::Pointer m_ValidProperty;
//mitk::BaseProperty* m_ValidProperty;
std::string m_ValidPropertyName;
+ const mitk::BaseRenderer *m_Renderer;
};
} // namespace mitk
#endif /* MITKNODEPREDICATEPROPERTY_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkPointSet.cpp b/Core/Code/DataManagement/mitkPointSet.cpp
index 3266246244..6f1c7cf49f 100755
--- a/Core/Code/DataManagement/mitkPointSet.cpp
+++ b/Core/Code/DataManagement/mitkPointSet.cpp
@@ -1,880 +1,879 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPointSet.h"
#include "mitkPointOperation.h"
#include "mitkInteractionConst.h"
#include <mitkNumericTypes.h>
#include <iomanip>
-mitk::PointSet::PointSet()
+mitk::PointSet::PointSet() : m_CalculateBoundingBox(true)
{
this->InitializeEmpty();
}
mitk::PointSet::PointSet(const PointSet &other)
: BaseData(other)
, m_PointSetSeries(other.GetPointSetSeriesSize())
, m_CalculateBoundingBox(true)
{
// Copy points
for (std::size_t t = 0; t < m_PointSetSeries.size(); ++t)
{
m_PointSetSeries[t] = DataType::New();
DataType::Pointer otherPts = other.GetPointSet(t);
for (PointsConstIterator i = other.Begin(t);
i != other.End(t); ++i)
{
m_PointSetSeries[t]->SetPoint(i.Index(), i.Value());
PointDataType pointData;
if (otherPts->GetPointData(i.Index(), &pointData))
{
m_PointSetSeries[t]->SetPointData(i.Index(), pointData);
}
}
}
}
mitk::PointSet::~PointSet()
{
this->ClearData();
}
void mitk::PointSet::ClearData()
{
m_PointSetSeries.clear();
Superclass::ClearData();
}
void mitk::PointSet::InitializeEmpty()
{
m_PointSetSeries.resize( 1 );
m_PointSetSeries[0] = DataType::New();
PointDataContainer::Pointer pointData = PointDataContainer::New();
m_PointSetSeries[0]->SetPointData( pointData );
m_CalculateBoundingBox = false;
Superclass::InitializeTimeGeometry(1);
m_Initialized = true;
}
bool mitk::PointSet::IsEmptyTimeStep(unsigned int t) const
{
return IsInitialized() && (GetSize(t) == 0);
}
void mitk::PointSet::Expand( unsigned int timeSteps )
{
// Check if the vector is long enough to contain the new element
// at the given position. If not, expand it with sufficient pre-initialized
// elements.
//
// NOTE: This method will never REDUCE the vector size; it should only
// be used to make sure that the vector has enough elements to include the
// specified time step.
unsigned int oldSize = m_PointSetSeries.size();
if ( timeSteps > oldSize )
{
Superclass::Expand( timeSteps );
m_PointSetSeries.resize( timeSteps );
for ( unsigned int i = oldSize; i < timeSteps; ++i )
{
m_PointSetSeries[i] = DataType::New();
PointDataContainer::Pointer pointData = PointDataContainer::New();
m_PointSetSeries[i]->SetPointData( pointData );
}
//if the size changes, then compute the bounding box
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetExtendTimeRangeEvent() );
}
}
unsigned int mitk::PointSet::GetPointSetSeriesSize() const
{
return m_PointSetSeries.size();
}
int mitk::PointSet::GetSize( unsigned int t ) const
{
if ( t < m_PointSetSeries.size() )
{
return m_PointSetSeries[t]->GetNumberOfPoints();
}
else
{
return 0;
}
}
mitk::PointSet::DataType::Pointer mitk::PointSet::GetPointSet( int t ) const
{
if ( t < (int)m_PointSetSeries.size() )
{
return m_PointSetSeries[t];
}
else
{
return NULL;
}
}
mitk::PointSet::PointsIterator mitk::PointSet::Begin( int t )
{
if (t >= 0 && t < static_cast<int>(m_PointSetSeries.size()))
{
return m_PointSetSeries[t]->GetPoints()->Begin();
}
return PointsIterator();
}
mitk::PointSet::PointsConstIterator mitk::PointSet::Begin(int t) const
{
if (t >= 0 && t < static_cast<int>(m_PointSetSeries.size()))
{
return m_PointSetSeries[t]->GetPoints()->Begin();
}
return PointsConstIterator();
}
mitk::PointSet::PointsIterator mitk::PointSet::End( int t )
{
if (t >= 0 && t < static_cast<int>(m_PointSetSeries.size()))
{
return m_PointSetSeries[t]->GetPoints()->End();
}
return PointsIterator();
}
mitk::PointSet::PointsConstIterator mitk::PointSet::End(int t) const
{
if (t >= 0 && t < static_cast<int>(m_PointSetSeries.size()))
{
return m_PointSetSeries[t]->GetPoints()->End();
}
return PointsConstIterator();
}
int mitk::PointSet::SearchPoint( Point3D point, ScalarType distance, int t ) const
{
if ( t >= (int)m_PointSetSeries.size() )
{
return -1;
}
// Out is the point which is checked to be the searched point
PointType out;
out.Fill( 0 );
PointType indexPoint;
this->GetGeometry( t )->WorldToIndex(point, indexPoint);
// Searching the first point in the Set, that is +- distance far away fro
// the given point
unsigned int i;
PointsContainer::Iterator it, end;
end = m_PointSetSeries[t]->GetPoints()->End();
int bestIndex = -1;
distance = distance * distance;
// To correct errors from converting index to world and world to index
if (distance == 0.0)
{
distance = 0.000001;
}
ScalarType bestDist = distance;
ScalarType dist, tmp;
for ( it = m_PointSetSeries[t]->GetPoints()->Begin(), i = 0;
it != end;
++it, ++i )
{
bool ok = m_PointSetSeries[t]->GetPoints()
->GetElementIfIndexExists( it->Index(), &out );
if ( !ok )
{
return -1;
}
else if ( indexPoint == out ) //if totally equal
{
return it->Index();
}
//distance calculation
tmp = out[0] - indexPoint[0]; dist = tmp * tmp;
tmp = out[1] - indexPoint[1]; dist += tmp * tmp;
tmp = out[2] - indexPoint[2]; dist += tmp * tmp;
if ( dist < bestDist )
{
bestIndex = it->Index();
bestDist = dist;
}
}
return bestIndex;
}
mitk::PointSet::PointType
mitk::PointSet::GetPoint( PointIdentifier id, int t ) const
{
PointType out;
out.Fill(0);
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return out;
}
if ( m_PointSetSeries[t]->GetPoints()->IndexExists(id) )
{
m_PointSetSeries[t]->GetPoint( id, &out );
this->GetGeometry(t)->IndexToWorld( out, out );
return out;
}
else
{
return out;
}
}
bool
mitk::PointSet
::GetPointIfExists( PointIdentifier id, PointType* point, int t ) const
{
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return false;
}
if ( m_PointSetSeries[t]->GetPoints()->GetElementIfIndexExists(id, point) )
{
this->GetGeometry( t )->IndexToWorld( *point, *point );
return true;
}
else
{
return false;
}
}
void mitk::PointSet::SetPoint( PointIdentifier id, PointType point, int t )
{
// Adapt the size of the data vector if necessary
this->Expand( t+1 );
mitk::Point3D indexPoint;
this->GetGeometry( t )->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->SetPoint( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = mitk::PTUNDEFINED;
m_PointSetSeries[t]->SetPointData( id, defaultPointData );
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
void mitk::PointSet::SetPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t )
{
// Adapt the size of the data vector if necessary
this->Expand( t+1 );
mitk::Point3D indexPoint;
this->GetGeometry( t )->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->SetPoint( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = spec;
m_PointSetSeries[t]->SetPointData( id, defaultPointData );
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
void mitk::PointSet::InsertPoint( PointIdentifier id, PointType point, int t )
{
this->InsertPoint(id, point, mitk::PTUNDEFINED, t);
}
void mitk::PointSet::InsertPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t )
{
if ( (unsigned int) t < m_PointSetSeries.size() )
{
mitk::Point3D indexPoint;
mitk::BaseGeometry* tempGeometry = this->GetGeometry( t );
if (tempGeometry == NULL)
{
MITK_INFO<< __FILE__ << ", l." << __LINE__ << ": GetGeometry of "<< t <<" returned NULL!" << std::endl;
return;
}
tempGeometry->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->GetPoints()->InsertElement( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = spec;
m_PointSetSeries[t]->GetPointData()->InsertElement(id, defaultPointData);
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
}
-
bool mitk::PointSet::SwapPointPosition( PointIdentifier id, bool moveUpwards, int t )
{
if(IndexExists(id, t) )
{
PointType point = GetPoint(id,t);
if(moveUpwards)
{//up
if(IndexExists(id-1,t))
{
InsertPoint(id, GetPoint(id - 1, t), t);
InsertPoint(id-1,point,t);
this->Modified();
return true;
}
}
else
{//down
if(IndexExists(id+1,t))
{
InsertPoint(id, GetPoint(id + 1, t), t);
InsertPoint(id+1,point,t);
this->Modified();
return true;
}
}
}
return false;
}
bool mitk::PointSet::IndexExists( int position, int t ) const
{
if ( (unsigned int) t < m_PointSetSeries.size() )
{
return m_PointSetSeries[t]->GetPoints()->IndexExists( position );
}
else
{
return false;
}
}
bool mitk::PointSet::GetSelectInfo( int position, int t ) const
{
if ( this->IndexExists( position, t ) )
{
PointDataType pointData = { 0, false, PTUNDEFINED };
m_PointSetSeries[t]->GetPointData( position, &pointData );
return pointData.selected;
}
else
{
return false;
}
}
void mitk::PointSet::SetSelectInfo( int position, bool selected, int t )
{
if ( this->IndexExists( position, t ) )
{
// timeStep to ms
TimePointType timeInMS = this->GetTimeGeometry()->TimeStepToTimePoint( t );
// point
Point3D point = this->GetPoint( position, t );
std::auto_ptr<PointOperation> op;
if (selected)
{
op.reset(new mitk::PointOperation(OpSELECTPOINT, timeInMS, point, position ));
}
else
{
op.reset(new mitk::PointOperation(OpDESELECTPOINT, timeInMS, point, position ));
}
this->ExecuteOperation( op.get() );
}
}
mitk::PointSpecificationType mitk::PointSet::GetSpecificationTypeInfo( int position, int t ) const
{
if ( this->IndexExists( position, t ) )
{
PointDataType pointData = { 0, false, PTUNDEFINED };
m_PointSetSeries[t]->GetPointData( position, &pointData );
return pointData.pointSpec;
}
else
{
return PTUNDEFINED;
}
}
int mitk::PointSet::GetNumberOfSelected( int t ) const
{
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return 0;
}
int numberOfSelected = 0;
PointDataIterator it;
for ( it = m_PointSetSeries[t]->GetPointData()->Begin();
it != m_PointSetSeries[t]->GetPointData()->End();
it++ )
{
if (it->Value().selected == true)
{
++numberOfSelected;
}
}
return numberOfSelected;
}
int mitk::PointSet::SearchSelectedPoint( int t ) const
{
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return -1;
}
PointDataIterator it;
for ( it = m_PointSetSeries[t]->GetPointData()->Begin();
it != m_PointSetSeries[t]->GetPointData()->End();
it++ )
{
if ( it->Value().selected == true )
{
return it->Index();
}
}
return -1;
}
void mitk::PointSet::ExecuteOperation( Operation* operation )
{
int timeStep = -1;
mitkCheckOperationTypeMacro(PointOperation, operation, pointOp);
if ( pointOp )
{
timeStep = this->GetTimeGeometry()->TimePointToTimeStep( pointOp->GetTimeInMS() );
}
if ( timeStep < 0 )
{
MITK_ERROR << "Time step (" << timeStep << ") outside of PointSet time bounds" << std::endl;
return;
}
switch (operation->GetOperationType())
{
case OpNOTHING:
break;
case OpINSERT://inserts the point at the given position and selects it.
{
int position = pointOp->GetIndex();
PointType pt;
pt.CastFrom(pointOp->GetPoint());
//transfer from world to index coordinates
mitk::BaseGeometry* geometry = this->GetGeometry( timeStep );
if (geometry == NULL)
{
MITK_INFO<<"GetGeometry returned NULL!\n";
return;
}
geometry->WorldToIndex(pt, pt);
m_PointSetSeries[timeStep]->GetPoints()->InsertElement(position, pt);
PointDataType pointData =
{
static_cast<unsigned int>(pointOp->GetIndex()),
pointOp->GetSelected(),
pointOp->GetPointType()
};
m_PointSetSeries[timeStep]->GetPointData()
->InsertElement(position, pointData);
this->Modified();
//boundingbox has to be computed
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetAddEvent() );
this->OnPointSetChange();
}
break;
case OpMOVE://moves the point given by index
{
PointType pt;
pt.CastFrom(pointOp->GetPoint());
//transfer from world to index coordinates
this->GetGeometry( timeStep )->WorldToIndex(pt, pt);
// Copy new point into container
m_PointSetSeries[timeStep]->SetPoint(pointOp->GetIndex(), pt);
// Insert a default point data object to keep the containers in sync
// (if no point data object exists yet)
PointDataType pointData;
if ( !m_PointSetSeries[timeStep]->GetPointData( pointOp->GetIndex(), &pointData ) )
{
m_PointSetSeries[timeStep]->SetPointData( pointOp->GetIndex(), pointData );
}
this->OnPointSetChange();
this->Modified();
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetMoveEvent() );
}
break;
case OpREMOVE://removes the point at given by position
{
m_PointSetSeries[timeStep]->GetPoints()->DeleteIndex((unsigned)pointOp->GetIndex());
m_PointSetSeries[timeStep]->GetPointData()->DeleteIndex((unsigned)pointOp->GetIndex());
this->OnPointSetChange();
this->Modified();
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetRemoveEvent() );
}
break;
case OpSELECTPOINT://select the given point
{
PointDataType pointData = {0, false, PTUNDEFINED};
m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
pointData.selected = true;
m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
this->Modified();
}
break;
case OpDESELECTPOINT://unselect the given point
{
PointDataType pointData = {0, false, PTUNDEFINED};
m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
pointData.selected = false;
m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
this->Modified();
}
break;
case OpSETPOINTTYPE:
{
PointDataType pointData = {0, false, PTUNDEFINED};
m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
pointData.pointSpec = pointOp->GetPointType();
m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
this->Modified();
}
break;
case OpMOVEPOINTUP: // swap content of point with ID pointOp->GetIndex() with the point preceding it in the container // move point position within the pointset
{
PointIdentifier currentID = pointOp->GetIndex();
/* search for point with this id and point that precedes this one in the data container */
PointsContainer::STLContainerType points = m_PointSetSeries[timeStep]->GetPoints()->CastToSTLContainer();
PointsContainer::STLContainerType::iterator it = points.find(currentID);
if (it == points.end()) // ID not found
break;
if (it == points.begin()) // we are at the first element, there is no previous element
break;
/* get and cache current point & pointdata and previous point & pointdata */
--it;
PointIdentifier prevID = it->first;
if (this->SwapPointContents(prevID, currentID, timeStep) == true)
this->Modified();
}
break;
case OpMOVEPOINTDOWN: // move point position within the pointset
{
PointIdentifier currentID = pointOp->GetIndex();
/* search for point with this id and point that succeeds this one in the data container */
PointsContainer::STLContainerType points = m_PointSetSeries[timeStep]->GetPoints()->CastToSTLContainer();
PointsContainer::STLContainerType::iterator it = points.find(currentID);
if (it == points.end()) // ID not found
break;
++it;
if (it == points.end()) // ID is already the last element, there is no succeeding element
break;
/* get and cache current point & pointdata and previous point & pointdata */
PointIdentifier nextID = it->first;
if (this->SwapPointContents(nextID, currentID, timeStep) == true)
this->Modified();
}
break;
default:
itkWarningMacro("mitkPointSet could not understrand the operation. Please check!");
break;
}
//to tell the mappers, that the data is modified and has to be updated
//only call modified if anything is done, so call in cases
//this->Modified();
mitk::OperationEndEvent endevent(operation);
((const itk::Object*)this)->InvokeEvent(endevent);
//*todo has to be done here, cause of update-pipeline not working yet
// As discussed lately, don't mess with the rendering from inside data structures
//mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void mitk::PointSet::UpdateOutputInformation()
{
if ( this->GetSource( ) )
{
this->GetSource( )->UpdateOutputInformation( );
}
//
// first make sure, that the associated time sliced geometry has
// the same number of geometry 3d's as PointSets are present
//
TimeGeometry* timeGeometry = GetTimeGeometry();
if ( timeGeometry->CountTimeSteps() != m_PointSetSeries.size() )
{
itkExceptionMacro(<<"timeGeometry->CountTimeSteps() != m_PointSetSeries.size() -- use Initialize(timeSteps) with correct number of timeSteps!");
}
// This is needed to detect zero objects
mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsNull(nullpoint);
//
// Iterate over the PointSets and update the Geometry
// information of each of the items.
//
if (m_CalculateBoundingBox)
{
for ( unsigned int i = 0 ; i < m_PointSetSeries.size() ; ++i )
{
const DataType::BoundingBoxType *bb = m_PointSetSeries[i]->GetBoundingBox();
BoundingBox::BoundsArrayType itkBounds = bb->GetBounds();
if ( m_PointSetSeries[i].IsNull() || (m_PointSetSeries[i]->GetNumberOfPoints() == 0)
|| (itkBounds == itkBoundsNull) )
{
itkBounds = itkBoundsNull;
continue;
}
// Ensure minimal bounds of 1.0 in each dimension
for ( unsigned int j = 0; j < 3; ++j )
{
if ( itkBounds[j*2+1] - itkBounds[j*2] < 1.0 )
{
BoundingBox::CoordRepType center =
(itkBounds[j*2] + itkBounds[j*2+1]) / 2.0;
itkBounds[j*2] = center - 0.5;
itkBounds[j*2+1] = center + 0.5;
}
}
this->GetGeometry(i)->SetBounds(itkBounds);
}
m_CalculateBoundingBox = false;
}
this->GetTimeGeometry()->Update();
}
void mitk::PointSet::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::PointSet::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::PointSet::VerifyRequestedRegion()
{
return true;
}
void mitk::PointSet::SetRequestedRegion(const DataObject * )
{
}
void mitk::PointSet::PrintSelf( std::ostream& os, itk::Indent indent ) const
{
Superclass::PrintSelf(os, indent);
os << indent << "Number timesteps: " << m_PointSetSeries.size() << "\n";
unsigned int i = 0;
for (PointSetSeries::const_iterator it = m_PointSetSeries.begin(); it != m_PointSetSeries.end(); ++it)
{
os << indent << "Timestep " << i++ << ": \n";
MeshType::Pointer ps = *it;
itk::Indent nextIndent = indent.GetNextIndent();
ps->Print(os, nextIndent);
MeshType::PointsContainer* points = ps->GetPoints();
MeshType::PointDataContainer* datas = ps->GetPointData();
MeshType::PointDataContainer::Iterator dataIterator = datas->Begin();
for (MeshType::PointsContainer::Iterator pointIterator = points->Begin();
pointIterator != points->End();
++pointIterator, ++dataIterator)
{
os << nextIndent << "Point " << pointIterator->Index() << ": [";
os << pointIterator->Value().GetElement(0);
for (unsigned int i = 1; i < PointType::GetPointDimension(); ++i)
{
os << ", " << pointIterator->Value().GetElement(i);
}
os << "]";
os << ", selected: " << dataIterator->Value().selected << ", point spec: " << dataIterator->Value().pointSpec << "\n";
}
}
}
bool mitk::PointSet::SwapPointContents(PointIdentifier id1, PointIdentifier id2, int timeStep)
{
/* search and cache contents */
PointType p1;
if (m_PointSetSeries[timeStep]->GetPoint(id1, &p1) == false)
return false;
PointDataType data1;
if (m_PointSetSeries[timeStep]->GetPointData(id1, &data1) == false)
return false;
PointType p2;
if (m_PointSetSeries[timeStep]->GetPoint(id2, &p2) == false)
return false;
PointDataType data2;
if (m_PointSetSeries[timeStep]->GetPointData(id2, &data2) == false)
return false;
/* now swap contents */
m_PointSetSeries[timeStep]->SetPoint(id1, p2);
m_PointSetSeries[timeStep]->SetPointData(id1, data2);
m_PointSetSeries[timeStep]->SetPoint(id2, p1);
m_PointSetSeries[timeStep]->SetPointData(id2, data1);
return true;
}
bool mitk::PointSet::PointDataType::operator ==(const mitk::PointSet::PointDataType &other) const
{
return id == other.id && selected == other.selected && pointSpec == other.pointSpec;
}
bool mitk::Equal( const mitk::PointSet* leftHandSide, const mitk::PointSet* rightHandSide, mitk::ScalarType eps, bool verbose )
{
if((leftHandSide == NULL) || (rightHandSide == NULL))
{
MITK_ERROR << "mitk::Equal( const mitk::PointSet* leftHandSide, const mitk::PointSet* rightHandSide, mitk::ScalarType eps, bool verbose ) does not work with NULL pointer input.";
return false;
}
return Equal( *leftHandSide, *rightHandSide, eps, verbose);
}
bool mitk::Equal( const mitk::PointSet& leftHandSide, const mitk::PointSet& rightHandSide, mitk::ScalarType eps, bool verbose )
{
bool result = true;
if( !mitk::Equal( *leftHandSide.GetGeometry(), *rightHandSide.GetGeometry(), eps, verbose) )
{
if(verbose)
MITK_INFO << "[( PointSet )] Geometries differ.";
result = false;
}
if ( leftHandSide.GetSize() != rightHandSide.GetSize())
{
if(verbose)
MITK_INFO << "[( PointSet )] Number of points differ.";
result = false;
}
else
{
//if the size is equal, we compare the point values
mitk::Point3D pointLeftHandSide;
mitk::Point3D pointRightHandSide;
int numberOfIncorrectPoints = 0;
//Iterate over both pointsets in order to compare all points pair-wise
mitk::PointSet::PointsConstIterator end = leftHandSide.End();
for( mitk::PointSet::PointsConstIterator pointSetIteratorLeft = leftHandSide.Begin(), pointSetIteratorRight = rightHandSide.Begin();
pointSetIteratorLeft != end; ++pointSetIteratorLeft, ++pointSetIteratorRight) //iterate simultaneously over both sets
{
pointLeftHandSide = pointSetIteratorLeft.Value();
pointRightHandSide = pointSetIteratorRight.Value();
if( !mitk::Equal( pointLeftHandSide, pointRightHandSide, eps, verbose ) )
{
if(verbose)
MITK_INFO << "[( PointSet )] Point values are different.";
result = false;
numberOfIncorrectPoints++;
}
}
if((numberOfIncorrectPoints > 0) && verbose)
{
MITK_INFO << numberOfIncorrectPoints <<" of a total of " << leftHandSide.GetSize() << " points are different.";
}
}
return result;
}
diff --git a/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp b/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp
index 444ccc7523..457e5018bd 100644
--- a/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp
+++ b/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp
@@ -1,1036 +1,1026 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSlicedGeometry3D.h"
#include "mitkPlaneGeometry.h"
#include "mitkRotationOperation.h"
#include "mitkPlaneOperation.h"
#include "mitkRestorePlanePositionOperation.h"
#include "mitkApplyTransformMatrixOperation.h"
#include "mitkInteractionConst.h"
#include "mitkSliceNavigationController.h"
#include "mitkAbstractTransformGeometry.h"
const mitk::ScalarType PI = 3.14159265359;
mitk::SlicedGeometry3D::SlicedGeometry3D()
: m_EvenlySpaced( true ),
m_Slices( 0 ),
m_ReferenceGeometry( NULL ),
m_SliceNavigationController( NULL )
{
m_DirectionVector.Fill(0);
this->InitializeSlicedGeometry( m_Slices );
}
mitk::SlicedGeometry3D::SlicedGeometry3D(const SlicedGeometry3D& other)
: Superclass(other),
m_EvenlySpaced( other.m_EvenlySpaced ),
m_Slices( other.m_Slices ),
m_ReferenceGeometry( other.m_ReferenceGeometry ),
m_SliceNavigationController( other.m_SliceNavigationController )
{
m_DirectionVector.Fill(0);
SetSpacing( other.GetSpacing() );
SetDirectionVector( other.GetDirectionVector() );
if ( m_EvenlySpaced )
{
PlaneGeometry::Pointer geometry = other.m_PlaneGeometries[0]->Clone();
- PlaneGeometry* geometry2D = dynamic_cast<PlaneGeometry*>(geometry.GetPointer());
- assert(geometry2D!=NULL);
- SetPlaneGeometry(geometry2D, 0);
+ assert(geometry.IsNotNull());
+ SetPlaneGeometry(geometry, 0);
}
else
{
unsigned int s;
for ( s = 0; s < other.m_Slices; ++s )
{
if ( other.m_PlaneGeometries[s].IsNull() )
{
assert(other.m_EvenlySpaced);
m_PlaneGeometries[s] = NULL;
}
else
{
PlaneGeometry* geometry2D = other.m_PlaneGeometries[s]->Clone();
assert(geometry2D!=NULL);
SetPlaneGeometry(geometry2D, s);
}
}
}
}
mitk::SlicedGeometry3D::~SlicedGeometry3D()
{
}
mitk::PlaneGeometry *
mitk::SlicedGeometry3D::GetPlaneGeometry( int s ) const
{
mitk::PlaneGeometry::Pointer geometry2D = NULL;
if ( this->IsValidSlice(s) )
{
geometry2D = m_PlaneGeometries[s];
// If (a) m_EvenlySpaced==true, (b) we don't have a PlaneGeometry stored
// for the requested slice, and (c) the first slice (s=0)
// is a PlaneGeometry instance, then we calculate the geometry of the
// requested as the plane of the first slice shifted by m_Spacing[2]*s
// in the direction of m_DirectionVector.
if ( (m_EvenlySpaced) && (geometry2D.IsNull()) )
{
- PlaneGeometry *firstSlice = dynamic_cast< PlaneGeometry * > (
- m_PlaneGeometries[0].GetPointer() );
+ PlaneGeometry *firstSlice = m_PlaneGeometries[0];
if ( firstSlice != NULL && dynamic_cast<AbstractTransformGeometry*>(m_PlaneGeometries[0].GetPointer() )==NULL)
{
if ( (m_DirectionVector[0] == 0.0)
&& (m_DirectionVector[1] == 0.0)
&& (m_DirectionVector[2] == 0.0) )
{
m_DirectionVector = firstSlice->GetNormal();
m_DirectionVector.Normalize();
}
Vector3D direction;
direction = m_DirectionVector * this->GetSpacing()[2];
mitk::PlaneGeometry::Pointer requestedslice;
requestedslice = static_cast< mitk::PlaneGeometry * >(
firstSlice->Clone().GetPointer() );
requestedslice->SetOrigin(
requestedslice->GetOrigin() + direction * s );
geometry2D = requestedslice;
m_PlaneGeometries[s] = geometry2D;
}
}
return geometry2D;
}
else
{
return NULL;
}
}
const mitk::BoundingBox *
mitk::SlicedGeometry3D::GetBoundingBox() const
{
assert(this->IsBoundingBoxNull()==false);
return Superclass::GetBoundingBox();
}
bool
mitk::SlicedGeometry3D::SetPlaneGeometry( mitk::PlaneGeometry *geometry2D, int s )
{
if ( this->IsValidSlice(s) )
{
m_PlaneGeometries[s] = geometry2D;
m_PlaneGeometries[s]->SetReferenceGeometry( m_ReferenceGeometry );
return true;
}
return false;
}
void
mitk::SlicedGeometry3D::InitializeSlicedGeometry( unsigned int slices )
{
Superclass::Initialize();
m_Slices = slices;
PlaneGeometry::Pointer gnull = NULL;
m_PlaneGeometries.assign( m_Slices, gnull );
Vector3D spacing;
spacing.Fill( 1.0 );
this->SetSpacing( spacing );
m_DirectionVector.Fill( 0 );
}
void
mitk::SlicedGeometry3D::InitializeEvenlySpaced(
mitk::PlaneGeometry* geometry2D, unsigned int slices, bool flipped )
{
assert( geometry2D != NULL );
this->InitializeEvenlySpaced(
geometry2D, geometry2D->GetExtentInMM(2)/geometry2D->GetExtent(2),
slices, flipped );
}
void
mitk::SlicedGeometry3D::InitializeEvenlySpaced(
mitk::PlaneGeometry* geometry2D, mitk::ScalarType zSpacing,
unsigned int slices, bool flipped )
{
assert( geometry2D != NULL );
assert( geometry2D->GetExtent(0) > 0 );
assert( geometry2D->GetExtent(1) > 0 );
geometry2D->Register();
Superclass::Initialize();
m_Slices = slices;
BoundingBox::BoundsArrayType bounds = geometry2D->GetBounds();
bounds[4] = 0;
bounds[5] = slices;
// clear and reserve
PlaneGeometry::Pointer gnull = NULL;
m_PlaneGeometries.assign( m_Slices, gnull );
Vector3D directionVector = geometry2D->GetAxisVector(2);
directionVector.Normalize();
directionVector *= zSpacing;
if ( flipped == false )
{
// Normally we should use the following four lines to create a copy of
// the transform contrained in geometry2D, because it may not be changed
// by us. But we know that SetSpacing creates a new transform without
// changing the old (coming from geometry2D), so we can use the fifth
// line instead. We check this at (**).
//
// AffineTransform3D::Pointer transform = AffineTransform3D::New();
// transform->SetMatrix(geometry2D->GetIndexToWorldTransform()->GetMatrix());
// transform->SetOffset(geometry2D->GetIndexToWorldTransform()->GetOffset());
// SetIndexToWorldTransform(transform);
this->SetIndexToWorldTransform( const_cast< AffineTransform3D * >(
geometry2D->GetIndexToWorldTransform() ));
}
else
{
directionVector *= -1.0;
this->SetIndexToWorldTransform( AffineTransform3D::New());
this->GetIndexToWorldTransform()->SetMatrix(
geometry2D->GetIndexToWorldTransform()->GetMatrix() );
AffineTransform3D::OutputVectorType scaleVector;
FillVector3D(scaleVector, 1.0, 1.0, -1.0);
this->GetIndexToWorldTransform()->Scale(scaleVector, true);
this->GetIndexToWorldTransform()->SetOffset(
geometry2D->GetIndexToWorldTransform()->GetOffset() );
}
mitk::Vector3D spacing;
FillVector3D( spacing,
geometry2D->GetExtentInMM(0) / bounds[1],
geometry2D->GetExtentInMM(1) / bounds[3],
zSpacing );
this->SetDirectionVector( directionVector );
this->SetBounds( bounds );
this->SetPlaneGeometry( geometry2D, 0 );
this->SetSpacing( spacing ,true);
this->SetEvenlySpaced();
//this->SetTimeBounds( geometry2D->GetTimeBounds() );
assert(this->GetIndexToWorldTransform()
!= geometry2D->GetIndexToWorldTransform()); // (**) see above.
this->SetFrameOfReferenceID( geometry2D->GetFrameOfReferenceID() );
this->SetImageGeometry( geometry2D->GetImageGeometry() );
geometry2D->UnRegister();
}
void
mitk::SlicedGeometry3D::InitializePlanes(
const mitk::BaseGeometry *geometry3D,
mitk::PlaneGeometry::PlaneOrientation planeorientation,
bool top, bool frontside, bool rotated )
{
m_ReferenceGeometry = const_cast< BaseGeometry * >( geometry3D );
PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
planeGeometry->InitializeStandardPlane(
geometry3D, top, planeorientation, frontside, rotated );
ScalarType viewSpacing = 1;
unsigned int slices = 1;
switch ( planeorientation )
{
case PlaneGeometry::Axial:
viewSpacing = geometry3D->GetSpacing()[2];
slices = (unsigned int) geometry3D->GetExtent( 2 );
break;
case PlaneGeometry::Frontal:
viewSpacing = geometry3D->GetSpacing()[1];
slices = (unsigned int) geometry3D->GetExtent( 1 );
break;
case PlaneGeometry::Sagittal:
viewSpacing = geometry3D->GetSpacing()[0];
slices = (unsigned int) geometry3D->GetExtent( 0 );
break;
default:
itkExceptionMacro("unknown PlaneOrientation");
}
mitk::Vector3D normal = this->AdjustNormal( planeGeometry->GetNormal() );
ScalarType directedExtent =
std::abs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
+ std::abs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
+ std::abs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );
if ( directedExtent >= viewSpacing )
{
slices = static_cast< int >(directedExtent / viewSpacing + 0.5);
}
else
{
slices = 1;
}
bool flipped = (top == false);
if ( frontside == false )
{
flipped = !flipped;
}
if ( planeorientation == PlaneGeometry::Frontal )
{
flipped = !flipped;
}
this->InitializeEvenlySpaced( planeGeometry, viewSpacing, slices, flipped );
}
void
mitk::SlicedGeometry3D
::ReinitializePlanes( const Point3D &center, const Point3D &referencePoint )
{
// Need a reference frame to align the rotated planes
if ( !m_ReferenceGeometry )
{
return;
}
// Get first plane of plane stack
- PlaneGeometry *firstPlane =
- dynamic_cast< PlaneGeometry * >( m_PlaneGeometries[0].GetPointer() );
+ PlaneGeometry *firstPlane = m_PlaneGeometries[0];
// If plane stack is empty, exit
- if ( firstPlane == NULL || dynamic_cast<AbstractTransformGeometry*>( m_PlaneGeometries[0].GetPointer() )!=NULL)
+ if ( !firstPlane || dynamic_cast<AbstractTransformGeometry*>(firstPlane) )
{
return;
}
// Calculate the "directed" spacing when taking the plane (defined by its axes
// vectors and normal) as the reference coordinate frame.
//
// This is done by calculating the radius of the ellipsoid defined by the
// original volume spacing axes, in the direction of the respective axis of the
// reference frame.
mitk::Vector3D axis0 = firstPlane->GetAxisVector(0);
mitk::Vector3D axis1 = firstPlane->GetAxisVector(1);
mitk::Vector3D normal = firstPlane->GetNormal();
normal.Normalize();
Vector3D spacing;
spacing[0] = this->CalculateSpacing( axis0 );
spacing[1] = this->CalculateSpacing( axis1 );
spacing[2] = this->CalculateSpacing( normal );
Superclass::SetSpacing( spacing );
// Now we need to calculate the number of slices in the plane's normal
// direction, so that the entire volume is covered. This is done by first
// calculating the dot product between the volume diagonal (the maximum
// distance inside the volume) and the normal, and dividing this value by
// the directed spacing calculated above.
ScalarType directedExtent =
std::abs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
+ std::abs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
+ std::abs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );
if ( directedExtent >= spacing[2] )
{
m_Slices = static_cast< unsigned int >(directedExtent / spacing[2] + 0.5);
}
else
{
m_Slices = 1;
}
// The origin of our "first plane" needs to be adapted to this new extent.
// To achieve this, we first calculate the current distance to the volume's
// center, and then shift the origin in the direction of the normal by the
// difference between this distance and half of the new extent.
double centerOfRotationDistance =
firstPlane->SignedDistanceFromPlane( center );
if ( centerOfRotationDistance > 0 )
{
firstPlane->SetOrigin( firstPlane->GetOrigin()
+ normal * (centerOfRotationDistance - directedExtent / 2.0)
);
m_DirectionVector = normal;
}
else
{
firstPlane->SetOrigin( firstPlane->GetOrigin()
+ normal * (directedExtent / 2.0 + centerOfRotationDistance)
);
m_DirectionVector = -normal;
}
// Now we adjust this distance according with respect to the given reference
// point: we need to make sure that the point is touched by one slice of the
// new slice stack.
double referencePointDistance =
firstPlane->SignedDistanceFromPlane( referencePoint );
int referencePointSlice = static_cast< int >(
referencePointDistance / spacing[2]);
double alignmentValue =
referencePointDistance / spacing[2] - referencePointSlice;
firstPlane->SetOrigin(
firstPlane->GetOrigin() + normal * alignmentValue * spacing[2] );
// Finally, we can clear the previous geometry stack and initialize it with
// our re-initialized "first plane".
m_PlaneGeometries.assign( m_Slices, PlaneGeometry::Pointer( NULL ) );
if ( m_Slices > 0 )
{
m_PlaneGeometries[0] = firstPlane;
}
// Reinitialize SNC with new number of slices
m_SliceNavigationController->GetSlice()->SetSteps( m_Slices );
this->Modified();
}
double
mitk::SlicedGeometry3D::CalculateSpacing( const mitk::Vector3D &d ) const
{
// Need the spacing of the underlying dataset / geometry
if ( !m_ReferenceGeometry )
{
return 1.0;
}
const mitk::Vector3D &spacing = m_ReferenceGeometry->GetSpacing();
return SlicedGeometry3D::CalculateSpacing( spacing, d );
}
double mitk::SlicedGeometry3D::CalculateSpacing( const mitk::Vector3D spacing, const mitk::Vector3D &d )
{
// The following can be derived from the ellipsoid equation
//
// 1 = x^2/a^2 + y^2/b^2 + z^2/c^2
//
// where (a,b,c) = spacing of original volume (ellipsoid radii)
// and (x,y,z) = scaled coordinates of vector d (according to ellipsoid)
//
double scaling = d[0]*d[0] / (spacing[0] * spacing[0])
+ d[1]*d[1] / (spacing[1] * spacing[1])
+ d[2]*d[2] / (spacing[2] * spacing[2]);
scaling = sqrt( scaling );
return ( sqrt( d[0]*d[0] + d[1]*d[1] + d[2]*d[2] ) / scaling );
}
mitk::Vector3D
mitk::SlicedGeometry3D::AdjustNormal( const mitk::Vector3D &normal ) const
{
TransformType::Pointer inverse = TransformType::New();
m_ReferenceGeometry->GetIndexToWorldTransform()->GetInverse( inverse );
Vector3D transformedNormal = inverse->TransformVector( normal );
transformedNormal.Normalize();
return transformedNormal;
}
void
mitk::SlicedGeometry3D::SetImageGeometry( const bool isAnImageGeometry )
{
Superclass::SetImageGeometry( isAnImageGeometry );
mitk::BaseGeometry* geometry;
unsigned int s;
for ( s = 0; s < m_Slices; ++s )
{
geometry = m_PlaneGeometries[s];
if ( geometry!=NULL )
{
geometry->SetImageGeometry( isAnImageGeometry );
}
}
}
void
mitk::SlicedGeometry3D::ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry )
{
mitk::BaseGeometry* geometry;
unsigned int s;
for ( s = 0; s < m_Slices; ++s )
{
geometry = m_PlaneGeometries[s];
if ( geometry!=NULL )
{
geometry->ChangeImageGeometryConsideringOriginOffset( isAnImageGeometry );
}
}
Superclass::ChangeImageGeometryConsideringOriginOffset( isAnImageGeometry );
}
bool
mitk::SlicedGeometry3D::IsValidSlice( int s ) const
{
return ((s >= 0) && (s < (int)m_Slices));
}
void
mitk::SlicedGeometry3D::SetReferenceGeometry( BaseGeometry *referenceGeometry )
{
m_ReferenceGeometry = referenceGeometry;
std::vector<PlaneGeometry::Pointer>::iterator it;
for ( it = m_PlaneGeometries.begin(); it != m_PlaneGeometries.end(); ++it )
{
(*it)->SetReferenceGeometry( referenceGeometry );
}
}
void
mitk::SlicedGeometry3D::PreSetSpacing( const mitk::Vector3D &aSpacing )
{
bool hasEvenlySpacedPlaneGeometry = false;
mitk::Point3D origin;
mitk::Vector3D rightDV, bottomDV;
BoundingBox::BoundsArrayType bounds;
assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0);
// In case of evenly-spaced data: re-initialize instances of PlaneGeometry,
// since the spacing influences them
if ((m_EvenlySpaced) && (m_PlaneGeometries.size() > 0))
{
- mitk::PlaneGeometry::ConstPointer firstGeometry =
- m_PlaneGeometries[0].GetPointer();
+ const PlaneGeometry *planeGeometry = m_PlaneGeometries[0];
- const PlaneGeometry *planeGeometry =
- dynamic_cast< const PlaneGeometry * >( firstGeometry.GetPointer() );
-
- if (planeGeometry != NULL && dynamic_cast<AbstractTransformGeometry*>( m_PlaneGeometries[0].GetPointer() )==NULL)
+ if ( planeGeometry && !dynamic_cast<const AbstractTransformGeometry*>( planeGeometry ) )
{
this->WorldToIndex( planeGeometry->GetOrigin(), origin );
this->WorldToIndex( planeGeometry->GetAxisVector(0), rightDV );
this->WorldToIndex( planeGeometry->GetAxisVector(1), bottomDV );
bounds = planeGeometry->GetBounds();
hasEvenlySpacedPlaneGeometry = true;
}
}
_SetSpacing(aSpacing);
mitk::PlaneGeometry::Pointer firstGeometry;
// In case of evenly-spaced data: re-initialize instances of PlaneGeometry,
// since the spacing influences them
if ( hasEvenlySpacedPlaneGeometry )
{
//create planeGeometry according to new spacing
this->IndexToWorld( origin, origin );
this->IndexToWorld( rightDV, rightDV );
this->IndexToWorld( bottomDV, bottomDV );
mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
planeGeometry->SetImageGeometry( this->GetImageGeometry() );
planeGeometry->SetReferenceGeometry( m_ReferenceGeometry );
//Store spacing, as Initialize... needs a pointer
mitk::Vector3D lokalSpacing = this->GetSpacing();
planeGeometry->InitializeStandardPlane(
rightDV.GetVnlVector(), bottomDV.GetVnlVector(), &lokalSpacing );
planeGeometry->SetOrigin(origin);
planeGeometry->SetBounds(bounds);
firstGeometry = planeGeometry;
}
else if ( (m_EvenlySpaced) && (m_PlaneGeometries.size() > 0) )
{
firstGeometry = m_PlaneGeometries[0].GetPointer();
}
//clear and reserve
PlaneGeometry::Pointer gnull=NULL;
m_PlaneGeometries.assign(m_Slices, gnull);
if ( m_Slices > 0 )
{
m_PlaneGeometries[0] = firstGeometry;
}
this->Modified();
}
void
mitk::SlicedGeometry3D
::SetSliceNavigationController( SliceNavigationController *snc )
{
m_SliceNavigationController = snc;
}
mitk::SliceNavigationController *
mitk::SlicedGeometry3D::GetSliceNavigationController()
{
return m_SliceNavigationController;
}
void
mitk::SlicedGeometry3D::SetEvenlySpaced(bool on)
{
if(m_EvenlySpaced!=on)
{
m_EvenlySpaced=on;
this->Modified();
}
}
void
mitk::SlicedGeometry3D
::SetDirectionVector( const mitk::Vector3D& directionVector )
{
Vector3D newDir = directionVector;
newDir.Normalize();
if ( newDir != m_DirectionVector )
{
m_DirectionVector = newDir;
this->Modified();
}
}
//void
//mitk::SlicedGeometry3D::SetTimeBounds( const mitk::TimeBounds& timebounds )
//{
// Superclass::SetTimeBounds( timebounds );
//
// unsigned int s;
// for ( s = 0; s < m_Slices; ++s )
// {
// if(m_Geometry2Ds[s].IsNotNull())
// {
// m_Geometry2Ds[s]->SetTimeBounds( timebounds );
// }
// }
// m_TimeBounds = timebounds;
//}
itk::LightObject::Pointer
mitk::SlicedGeometry3D::InternalClone() const
{
Self::Pointer newGeometry = new SlicedGeometry3D(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
void
mitk::SlicedGeometry3D::PrintSelf( std::ostream& os, itk::Indent indent ) const
{
Superclass::PrintSelf(os,indent);
os << indent << " EvenlySpaced: " << m_EvenlySpaced << std::endl;
if ( m_EvenlySpaced )
{
os << indent << " DirectionVector: " << m_DirectionVector << std::endl;
}
os << indent << " Slices: " << m_Slices << std::endl;
os << std::endl;
os << indent << " GetPlaneGeometry(0): ";
if ( this->GetPlaneGeometry(0) == NULL )
{
os << "NULL" << std::endl;
}
else
{
this->GetPlaneGeometry(0)->Print(os, indent);
}
}
void
mitk::SlicedGeometry3D::ExecuteOperation(Operation* operation)
{
switch ( operation->GetOperationType() )
{
case OpNOTHING:
break;
case OpROTATE:
if ( m_EvenlySpaced )
{
// Need a reference frame to align the rotation
if ( m_ReferenceGeometry )
{
// Clear all generated geometries and then rotate only the first slice.
// The other slices will be re-generated on demand
// Save first slice
PlaneGeometry::Pointer geometry2D = m_PlaneGeometries[0];
RotationOperation *rotOp = dynamic_cast< RotationOperation * >( operation );
// Generate a RotationOperation using the dataset center instead of
// the supplied rotation center. This is necessary so that the rotated
// zero-plane does not shift away. The supplied center is instead used
// to adjust the slice stack afterwards.
Point3D center = m_ReferenceGeometry->GetCenter();
RotationOperation centeredRotation(
rotOp->GetOperationType(),
center,
rotOp->GetVectorOfRotation(),
rotOp->GetAngleOfRotation()
);
// Rotate first slice
geometry2D->ExecuteOperation( &centeredRotation );
// Clear the slice stack and adjust it according to the center of
// the dataset and the supplied rotation center (see documentation of
// ReinitializePlanes)
this->ReinitializePlanes( center, rotOp->GetCenterOfRotation() );
geometry2D->SetSpacing(this->GetSpacing());
if ( m_SliceNavigationController )
{
m_SliceNavigationController->SelectSliceByPoint(
rotOp->GetCenterOfRotation() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
BaseGeometry::ExecuteOperation( &centeredRotation );
}
else
{
// we also have to consider the case, that there is no reference geometry available.
if ( m_PlaneGeometries.size() > 0 )
{
// Reach through to all slices in my container
for (std::vector<PlaneGeometry::Pointer>::iterator iter = m_PlaneGeometries.begin();
iter != m_PlaneGeometries.end();
++iter)
{
// Test for empty slices, which can happen if evenly spaced geometry
if ((*iter).IsNotNull())
{
(*iter)->ExecuteOperation(operation);
}
}
// rotate overall geometry
RotationOperation *rotOp = dynamic_cast< RotationOperation * >( operation );
BaseGeometry::ExecuteOperation( rotOp);
}
}
}
else
{
// Reach through to all slices
for (std::vector<PlaneGeometry::Pointer>::iterator iter = m_PlaneGeometries.begin();
iter != m_PlaneGeometries.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
}
break;
case OpORIENT:
if ( m_EvenlySpaced )
{
// get operation data
PlaneOperation *planeOp = dynamic_cast< PlaneOperation * >( operation );
// Get first slice
- PlaneGeometry::Pointer geometry2D = m_PlaneGeometries[0];
- PlaneGeometry *planeGeometry = dynamic_cast< PlaneGeometry * >(
- geometry2D.GetPointer() );
+ PlaneGeometry::Pointer planeGeometry = m_PlaneGeometries[0];
// Need a PlaneGeometry, a PlaneOperation and a reference frame to
// carry out the re-orientation. If not all avaialble, stop here
- if ( !m_ReferenceGeometry || (!planeGeometry || dynamic_cast<AbstractTransformGeometry*>( m_PlaneGeometries[0].GetPointer() )!=NULL) || !planeOp )
+ if ( !m_ReferenceGeometry ||
+ ( !planeGeometry || dynamic_cast<AbstractTransformGeometry*>(planeGeometry.GetPointer()) ) ||
+ !planeOp )
{
break;
}
// General Behavior:
// Clear all generated geometries and then rotate only the first slice.
// The other slices will be re-generated on demand
//
// 1st Step: Reorient Normal Vector of first plane
//
Point3D center = planeOp->GetPoint(); //m_ReferenceGeometry->GetCenter();
mitk::Vector3D currentNormal = planeGeometry->GetNormal();
mitk::Vector3D newNormal;
if (planeOp->AreAxisDefined())
{
// If planeOp was defined by one centerpoint and two axis vectors
newNormal = CrossProduct(planeOp->GetAxisVec0(), planeOp->GetAxisVec1());
}
else
{
// If planeOp was defined by one centerpoint and one normal vector
newNormal = planeOp->GetNormal();
}
// Get Rotation axis und angle
currentNormal.Normalize();
newNormal.Normalize();
ScalarType rotationAngle = angle(currentNormal.GetVnlVector(),newNormal.GetVnlVector());
rotationAngle *= 180.0 / vnl_math::pi; // from rad to deg
Vector3D rotationAxis = itk::CrossProduct( currentNormal, newNormal );
if (std::abs(rotationAngle-180) < mitk::eps )
{
// current Normal and desired normal are not linear independent!!(e.g 1,0,0 and -1,0,0).
// Rotation Axis should be ANY vector that is 90� to current Normal
mitk::Vector3D helpNormal;
helpNormal = currentNormal;
helpNormal[0] += 1;
helpNormal[1] -= 1;
helpNormal[2] += 1;
helpNormal.Normalize();
rotationAxis = itk::CrossProduct( helpNormal, currentNormal );
}
RotationOperation centeredRotation(
mitk::OpROTATE,
center,
rotationAxis,
rotationAngle
);
// Rotate first slice
- geometry2D->ExecuteOperation( &centeredRotation );
+ planeGeometry->ExecuteOperation( &centeredRotation );
// Reinitialize planes and select slice, if my rotations are all done.
if (!planeOp->AreAxisDefined())
{
// Clear the slice stack and adjust it according to the center of
// rotation and plane position (see documentation of ReinitializePlanes)
this->ReinitializePlanes( center, planeOp->GetPoint() );
if ( m_SliceNavigationController )
{
m_SliceNavigationController->SelectSliceByPoint( planeOp->GetPoint() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
}
// Also apply rotation on the slicedGeometry - Geometry3D (Bounding geometry)
BaseGeometry::ExecuteOperation( &centeredRotation );
//
// 2nd step. If axis vectors were defined, rotate the plane around its normal to fit these
//
if (planeOp->AreAxisDefined())
{
mitk::Vector3D vecAxixNew = planeOp->GetAxisVec0();
vecAxixNew.Normalize();
- mitk::Vector3D VecAxisCurr = geometry2D->GetAxisVector(0);
+ mitk::Vector3D VecAxisCurr = planeGeometry->GetAxisVector(0);
VecAxisCurr.Normalize();
ScalarType rotationAngle = angle(VecAxisCurr.GetVnlVector(),vecAxixNew.GetVnlVector());
rotationAngle = rotationAngle * 180 / PI; // Rad to Deg
// we rotate around the normal of the plane, but we do not know, if we need to rotate clockwise
// or anti-clockwise. So we rotate around the crossproduct of old and new Axisvector.
// Since both axis vectors lie in the plane, the crossproduct is the planes normal or the negative planes normal
rotationAxis = itk::CrossProduct( VecAxisCurr, vecAxixNew );
if (std::abs(rotationAngle-180) < mitk::eps )
{
// current axisVec and desired axisVec are not linear independent!!(e.g 1,0,0 and -1,0,0).
// Rotation Axis can be just plane Normal. (have to rotate by 180�)
rotationAxis = newNormal;
}
// Perfom Rotation
mitk::RotationOperation op(mitk::OpROTATE, center, rotationAxis, rotationAngle);
- geometry2D->ExecuteOperation( &op );
+ planeGeometry->ExecuteOperation( &op );
// Apply changes on first slice to whole slice stack
this->ReinitializePlanes( center, planeOp->GetPoint() );
if ( m_SliceNavigationController )
{
m_SliceNavigationController->SelectSliceByPoint( planeOp->GetPoint() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
// Also apply rotation on the slicedGeometry - Geometry3D (Bounding geometry)
BaseGeometry::ExecuteOperation( &op );
}
}
else
{
// Reach through to all slices
for (std::vector<PlaneGeometry::Pointer>::iterator iter = m_PlaneGeometries.begin();
iter != m_PlaneGeometries.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
}
break;
case OpRESTOREPLANEPOSITION:
if ( m_EvenlySpaced )
{
// Save first slice
- PlaneGeometry::Pointer geometry2D = m_PlaneGeometries[0];
-
- PlaneGeometry* planeGeometry = dynamic_cast< PlaneGeometry * >(
- geometry2D.GetPointer() );
+ PlaneGeometry::Pointer planeGeometry = m_PlaneGeometries[0];
RestorePlanePositionOperation *restorePlaneOp = dynamic_cast< RestorePlanePositionOperation* >( operation );
// Need a PlaneGeometry, a PlaneOperation and a reference frame to
// carry out the re-orientation
- if ( m_ReferenceGeometry && (planeGeometry && dynamic_cast<AbstractTransformGeometry*>( m_PlaneGeometries[0].GetPointer() )==NULL) && restorePlaneOp )
+ if ( m_ReferenceGeometry && (planeGeometry && dynamic_cast<AbstractTransformGeometry*>(planeGeometry.GetPointer()) == NULL) && restorePlaneOp )
{
// Clear all generated geometries and then rotate only the first slice.
// The other slices will be re-generated on demand
// Rotate first slice
- geometry2D->ExecuteOperation( restorePlaneOp );
+ planeGeometry->ExecuteOperation( restorePlaneOp );
m_DirectionVector = restorePlaneOp->GetDirectionVector();
double centerOfRotationDistance =
planeGeometry->SignedDistanceFromPlane( m_ReferenceGeometry->GetCenter() );
if ( centerOfRotationDistance > 0 )
{
m_DirectionVector = m_DirectionVector;
}
else
{
m_DirectionVector = -m_DirectionVector;
}
Vector3D spacing = restorePlaneOp->GetSpacing();
Superclass::SetSpacing( spacing );
// /*Now we need to calculate the number of slices in the plane's normal
// direction, so that the entire volume is covered. This is done by first
// calculating the dot product between the volume diagonal (the maximum
// distance inside the volume) and the normal, and dividing this value by
// the directed spacing calculated above.*/
ScalarType directedExtent =
std::abs( m_ReferenceGeometry->GetExtentInMM( 0 ) * m_DirectionVector[0] )
+ std::abs( m_ReferenceGeometry->GetExtentInMM( 1 ) * m_DirectionVector[1] )
+ std::abs( m_ReferenceGeometry->GetExtentInMM( 2 ) * m_DirectionVector[2] );
if ( directedExtent >= spacing[2] )
{
m_Slices = static_cast< unsigned int >(directedExtent / spacing[2] + 0.5);
}
else
{
m_Slices = 1;
}
m_PlaneGeometries.assign( m_Slices, PlaneGeometry::Pointer( NULL ) );
if ( m_Slices > 0 )
{
- m_PlaneGeometries[0] = geometry2D;
+ m_PlaneGeometries[0] = planeGeometry;
}
m_SliceNavigationController->GetSlice()->SetSteps( m_Slices );
this->Modified();
//End Reinitialization
if ( m_SliceNavigationController )
{
m_SliceNavigationController->GetSlice()->SetPos( restorePlaneOp->GetPos() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
BaseGeometry::ExecuteOperation(restorePlaneOp);
}
}
else
{
// Reach through to all slices
for (std::vector<PlaneGeometry::Pointer>::iterator iter = m_PlaneGeometries.begin();
iter != m_PlaneGeometries.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
}
break;
case OpAPPLYTRANSFORMMATRIX:
// Clear all generated geometries and then transform only the first slice.
// The other slices will be re-generated on demand
// Save first slice
PlaneGeometry::Pointer geometry2D = m_PlaneGeometries[0];
ApplyTransformMatrixOperation *applyMatrixOp = dynamic_cast< ApplyTransformMatrixOperation* >( operation );
// Apply transformation to first plane
geometry2D->ExecuteOperation( applyMatrixOp );
// Generate a ApplyTransformMatrixOperation using the dataset center instead of
// the supplied rotation center. The supplied center is instead used to adjust the
// slice stack afterwards (see OpROTATE).
Point3D center = m_ReferenceGeometry->GetCenter();
// Clear the slice stack and adjust it according to the center of
// the dataset and the supplied rotation center (see documentation of
// ReinitializePlanes)
this->ReinitializePlanes( center, applyMatrixOp->GetReferencePoint() );
BaseGeometry::ExecuteOperation( applyMatrixOp );
break;
}
this->Modified();
}
diff --git a/Core/Code/IO/mitkIOUtil.cpp b/Core/Code/IO/mitkIOUtil.cpp
index bf01ca9c70..3357456fa6 100644
--- a/Core/Code/IO/mitkIOUtil.cpp
+++ b/Core/Code/IO/mitkIOUtil.cpp
@@ -1,768 +1,774 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-
#include "mitkIOUtil.h"
#include "mitkDataNodeFactory.h"
#include "mitkImageWriter.h"
#include "mitkPointSetWriter.h"
#include "mitkSurfaceVtkWriter.h"
#include <usGetModuleContext.h>
#include <usModuleContext.h>
#include <mitkStandaloneDataStorage.h>
#include <mitkIDataNodeReader.h>
#include <mitkProgressBar.h>
#include <mitkExceptionMacro.h>
#include <mitkCoreObjectFactory.h>
//ITK
#include <itksys/SystemTools.hxx>
//VTK
#include <vtkPolyData.h>
#include <vtkTriangleFilter.h>
#include <vtkSmartPointer.h>
#include <cerrno>
#include <cstdlib>
static std::string GetLastErrorStr()
{
#ifdef US_PLATFORM_POSIX
return std::string(strerror(errno));
#else
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
std::string errMsg((LPCTSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
return errMsg;
#endif
}
#ifdef US_PLATFORM_WINDOWS
#include <io.h>
#include <direct.h>
// make the posix flags point to the obsolte bsd types on windows
#define S_IRUSR S_IREAD
#define S_IWUSR S_IWRITE
#else
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
// A cross-platform version of the mkstemps function
static int mkstemps_compat(char* tmpl, int suffixlen)
{
static unsigned long long value = 0;
int savedErrno = errno;
// Lower bound on the number of temporary files to attempt to generate.
#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary file. To
- conform to POSIX, this must be no smaller than TMP_MAX. */
+ conform to POSIX, this must be no smaller than TMP_MAX. */
#if ATTEMPTS_MIN < TMP_MAX
const unsigned int attempts = TMP_MAX;
#else
const unsigned int attempts = ATTEMPTS_MIN;
#endif
const int len = strlen(tmpl);
if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6))
{
errno = EINVAL;
return -1;
}
/* This is where the Xs start. */
char* XXXXXX = &tmpl[len - 6 - suffixlen];
/* Get some more or less random data. */
#ifdef US_PLATFORM_WINDOWS
{
SYSTEMTIME stNow;
FILETIME ftNow;
// get system time
GetSystemTime(&stNow);
stNow.wMilliseconds = 500;
if (!SystemTimeToFileTime(&stNow, &ftNow))
{
errno = -1;
return -1;
}
unsigned long long randomTimeBits = ((static_cast<unsigned long long>(ftNow.dwHighDateTime) << 32)
- | static_cast<unsigned long long>(ftNow.dwLowDateTime));
+ | static_cast<unsigned long long>(ftNow.dwLowDateTime));
value = randomTimeBits ^ static_cast<unsigned long long>(GetCurrentThreadId());
}
#else
{
struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long long randomTimeBits = ((static_cast<unsigned long long>(tv.tv_usec) << 32)
- | static_cast<unsigned long long>(tv.tv_sec));
+ | static_cast<unsigned long long>(tv.tv_sec));
value = randomTimeBits ^ static_cast<unsigned long long>(getpid());
}
#endif
for (unsigned int count = 0; count < attempts; value += 7777, ++count)
{
unsigned long long v = value;
/* Fill in the random bits. */
XXXXXX[0] = validLetters[v % 62];
v /= 62;
XXXXXX[1] = validLetters[v % 62];
v /= 62;
XXXXXX[2] = validLetters[v % 62];
v /= 62;
XXXXXX[3] = validLetters[v % 62];
v /= 62;
XXXXXX[4] = validLetters[v % 62];
v /= 62;
XXXXXX[5] = validLetters[v % 62];
int fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd >= 0)
{
errno = savedErrno;
return fd;
}
else if (errno != EEXIST)
{
return -1;
}
}
/* We got out of the loop because we ran out of combinations to try. */
errno = EEXIST;
return -1;
}
// A cross-platform version of the POSIX mkdtemp function
static char* mkdtemps_compat(char* tmpl, int suffixlen)
{
static unsigned long long value = 0;
int savedErrno = errno;
// Lower bound on the number of temporary dirs to attempt to generate.
#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary dir. To
- conform to POSIX, this must be no smaller than TMP_MAX. */
+ conform to POSIX, this must be no smaller than TMP_MAX. */
#if ATTEMPTS_MIN < TMP_MAX
const unsigned int attempts = TMP_MAX;
#else
const unsigned int attempts = ATTEMPTS_MIN;
#endif
const int len = strlen(tmpl);
if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6))
{
errno = EINVAL;
return NULL;
}
/* This is where the Xs start. */
char* XXXXXX = &tmpl[len - 6 - suffixlen];
/* Get some more or less random data. */
#ifdef US_PLATFORM_WINDOWS
{
SYSTEMTIME stNow;
FILETIME ftNow;
// get system time
GetSystemTime(&stNow);
stNow.wMilliseconds = 500;
if (!SystemTimeToFileTime(&stNow, &ftNow))
{
errno = -1;
return NULL;
}
unsigned long long randomTimeBits = ((static_cast<unsigned long long>(ftNow.dwHighDateTime) << 32)
- | static_cast<unsigned long long>(ftNow.dwLowDateTime));
+ | static_cast<unsigned long long>(ftNow.dwLowDateTime));
value = randomTimeBits ^ static_cast<unsigned long long>(GetCurrentThreadId());
}
#else
{
struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long long randomTimeBits = ((static_cast<unsigned long long>(tv.tv_usec) << 32)
- | static_cast<unsigned long long>(tv.tv_sec));
+ | static_cast<unsigned long long>(tv.tv_sec));
value = randomTimeBits ^ static_cast<unsigned long long>(getpid());
}
#endif
unsigned int count = 0;
for (; count < attempts; value += 7777, ++count)
{
unsigned long long v = value;
/* Fill in the random bits. */
XXXXXX[0] = validLetters[v % 62];
v /= 62;
XXXXXX[1] = validLetters[v % 62];
v /= 62;
XXXXXX[2] = validLetters[v % 62];
v /= 62;
XXXXXX[3] = validLetters[v % 62];
v /= 62;
XXXXXX[4] = validLetters[v % 62];
v /= 62;
XXXXXX[5] = validLetters[v % 62];
#ifdef US_PLATFORM_WINDOWS
int fd = _mkdir (tmpl); //, _S_IREAD | _S_IWRITE | _S_IEXEC);
#else
int fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
#endif
if (fd >= 0)
{
errno = savedErrno;
return tmpl;
}
else if (errno != EEXIST)
{
return NULL;
}
}
/* We got out of the loop because we ran out of combinations to try. */
errno = EEXIST;
return NULL;
}
//#endif
namespace mitk {
-
-const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd";
-const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl";
-const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps";
+ const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd";
+ const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl";
+ const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps";
#ifdef US_PLATFORM_WINDOWS
-std::string IOUtil::GetProgramPath()
-{
- char path[512];
- std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of('\\');
- return std::string(path, index);
-}
+ std::string IOUtil::GetProgramPath()
+ {
+ char path[512];
+ std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of('\\');
+ return std::string(path, index);
+ }
#elif defined(US_PLATFORM_APPLE)
#include <mach-o/dyld.h>
-std::string IOUtil::GetProgramPath()
-{
- char path[512];
- uint32_t size = sizeof(path);
- if (_NSGetExecutablePath(path, &size) == 0)
+ std::string IOUtil::GetProgramPath()
{
- std::size_t index = std::string(path).find_last_of('/');
- std::string strPath = std::string(path, index);
- //const char* execPath = strPath.c_str();
- //mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false);
- return strPath;
+ char path[512];
+ uint32_t size = sizeof(path);
+ if (_NSGetExecutablePath(path, &size) == 0)
+ {
+ std::size_t index = std::string(path).find_last_of('/');
+ std::string strPath = std::string(path, index);
+ //const char* execPath = strPath.c_str();
+ //mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false);
+ return strPath;
+ }
+ return std::string();
}
- return std::string();
-}
#else
#include <sys/types.h>
#include <unistd.h>
#include <sstream>
-std::string IOUtil::GetProgramPath()
-{
- std::stringstream ss;
- ss << "/proc/" << getpid() << "/exe";
- char proc[512] = {0};
- ssize_t ch = readlink(ss.str().c_str(), proc, 512);
- if (ch == -1) return std::string();
- std::size_t index = std::string(proc).find_last_of('/');
- return std::string(proc, index);
-}
+ std::string IOUtil::GetProgramPath()
+ {
+ std::stringstream ss;
+ ss << "/proc/" << getpid() << "/exe";
+ char proc[512] = {0};
+ ssize_t ch = readlink(ss.str().c_str(), proc, 512);
+ if (ch == -1) return std::string();
+ std::size_t index = std::string(proc).find_last_of('/');
+ return std::string(proc, index);
+ }
#endif
-std::string IOUtil::GetTempPath()
-{
- static std::string result;
- if (result.empty())
+ std::string IOUtil::GetTempPath()
{
-#ifdef US_PLATFORM_WINDOWS
- char tempPathTestBuffer[1];
- DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer);
- if (bufferLength == 0)
+ static std::string result;
+ if (result.empty())
{
- mitkThrow() << GetLastErrorStr();
- }
- std::vector<char> tempPath(bufferLength);
- bufferLength = ::GetTempPath(bufferLength, &tempPath[0]);
- if (bufferLength == 0)
- {
- mitkThrow() << GetLastErrorStr();
- }
- result.assign(tempPath.begin(), tempPath.begin() + static_cast<std::size_t>(bufferLength));
+#ifdef US_PLATFORM_WINDOWS
+ char tempPathTestBuffer[1];
+ DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer);
+ if (bufferLength == 0)
+ {
+ mitkThrow() << GetLastErrorStr();
+ }
+ std::vector<char> tempPath(bufferLength);
+ bufferLength = ::GetTempPath(bufferLength, &tempPath[0]);
+ if (bufferLength == 0)
+ {
+ mitkThrow() << GetLastErrorStr();
+ }
+ result.assign(tempPath.begin(), tempPath.begin() + static_cast<std::size_t>(bufferLength));
#else
- result = "/tmp/";
+ result = "/tmp/";
#endif
- }
-
- return result;
-}
-
-std::string IOUtil::CreateTemporaryFile(const std::string& templateName, std::string path)
-{
- ofstream tmpOutputStream;
- std::string returnValue = CreateTemporaryFile(tmpOutputStream,templateName,path);
- tmpOutputStream.close();
- return returnValue;
-}
-
-std::string IOUtil::CreateTemporaryFile(std::ofstream& f, const std::string& templateName, std::string path)
-{
- return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path);
-}
+ }
-std::string IOUtil::CreateTemporaryFile(std::ofstream& f, std::ios_base::openmode mode, const std::string& templateName, std::string path)
-{
- if (path.empty())
- {
- path = GetTempPath();
+ return result;
}
- path += "/" + templateName;
- std::vector<char> dst_path(path.begin(), path.end());
- dst_path.push_back('\0');
-
- std::size_t lastX = path.find_last_of('X');
- std::size_t firstX = path.find_last_not_of('X', lastX);
- int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
- while (lastX != std::string::npos && (lastX - firstNonX) < 6)
+ std::string IOUtil::CreateTemporaryFile(const std::string& templateName, std::string path)
{
- lastX = path.find_last_of('X', firstX);
- firstX = path.find_last_not_of('X', lastX);
- firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
+ ofstream tmpOutputStream;
+ std::string returnValue = CreateTemporaryFile(tmpOutputStream,templateName,path);
+ tmpOutputStream.close();
+ return returnValue;
}
- std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
- int fd = mkstemps_compat(&dst_path[0], suffixlen);
- if(fd != -1)
+ char IOUtil::GetDirectorySeparator()
{
- path.assign(dst_path.begin(), dst_path.end() - 1);
- f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc);
- close(fd);
+#ifdef US_PLATFORM_WINDOWS
+ return '\\';
+#else
+ return '/';
+#endif
}
- else
+
+ std::string IOUtil::CreateTemporaryFile(std::ofstream& f, const std::string& templateName, std::string path)
{
- mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr();
+ return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path);
}
- return path;
-}
-std::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path)
-{
- if (path.empty())
+ std::string IOUtil::CreateTemporaryFile(std::ofstream& f, std::ios_base::openmode mode, const std::string& templateName, std::string path)
{
- path = GetTempPath();
- }
+ if (path.empty())
+ {
+ path = GetTempPath();
+ }
- path += "/" + templateName;
- std::vector<char> dst_path(path.begin(), path.end());
- dst_path.push_back('\0');
+ path += GetDirectorySeparator() + templateName;
+ std::vector<char> dst_path(path.begin(), path.end());
+ dst_path.push_back('\0');
- std::size_t lastX = path.find_last_of('X');
- std::size_t firstX = path.find_last_not_of('X', lastX);
- int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
- while (lastX != std::string::npos && (lastX - firstNonX) < 6)
- {
- lastX = path.find_last_of('X', firstX);
- firstX = path.find_last_not_of('X', lastX);
- firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
+ std::size_t lastX = path.find_last_of('X');
+ std::size_t firstX = path.find_last_not_of('X', lastX);
+ int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
+ while (lastX != std::string::npos && (lastX - firstNonX) < 6)
+ {
+ lastX = path.find_last_of('X', firstX);
+ firstX = path.find_last_not_of('X', lastX);
+ firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
+ }
+ std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
+
+ int fd = mkstemps_compat(&dst_path[0], suffixlen);
+ if(fd != -1)
+ {
+ path.assign(dst_path.begin(), dst_path.end() - 1);
+ f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc);
+ close(fd);
+ }
+ else
+ {
+ mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr();
+ }
+ return path;
}
- std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
- if(mkdtemps_compat(&dst_path[0], suffixlen) == NULL)
+ std::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path)
{
- mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr();
- }
+ if (path.empty())
+ {
+ path = GetTempPath();
+ }
- path.assign(dst_path.begin(), dst_path.end() - 1);
- return path;
-}
+ path += GetDirectorySeparator() + templateName;
+ std::vector<char> dst_path(path.begin(), path.end());
+ dst_path.push_back('\0');
-int IOUtil::LoadFiles(const std::vector<std::string> &fileNames, DataStorage &ds)
-{
+ std::size_t lastX = path.find_last_of('X');
+ std::size_t firstX = path.find_last_not_of('X', lastX);
+ int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
+ while (lastX != std::string::npos && (lastX - firstNonX) < 6)
+ {
+ lastX = path.find_last_of('X', firstX);
+ firstX = path.find_last_not_of('X', lastX);
+ firstNonX = firstX == std::string::npos ? - 1 : firstX - 1;
+ }
+ std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
+
+ if(mkdtemps_compat(&dst_path[0], suffixlen) == NULL)
+ {
+ mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr();
+ }
+
+ path.assign(dst_path.begin(), dst_path.end() - 1);
+ return path;
+ }
+
+ int IOUtil::LoadFiles(const std::vector<std::string> &fileNames, DataStorage &ds)
+ {
// Get the set of registered mitk::IDataNodeReader services
us::ModuleContext* context = us::GetModuleContext();
const std::vector<us::ServiceReference<IDataNodeReader> > refs = context->GetServiceReferences<IDataNodeReader>();
std::vector<IDataNodeReader*> services;
services.reserve(refs.size());
for (std::vector<us::ServiceReference<IDataNodeReader> >::const_iterator i = refs.begin();
- i != refs.end(); ++i)
+ i != refs.end(); ++i)
{
- IDataNodeReader* s = context->GetService(*i);
- if (s != 0)
- {
- services.push_back(s);
- }
+ IDataNodeReader* s = context->GetService(*i);
+ if (s != 0)
+ {
+ services.push_back(s);
+ }
}
mitk::ProgressBar::GetInstance()->AddStepsToDo(2*fileNames.size());
// Iterate over all file names and use the IDataNodeReader services
// to load them.
int nodesRead = 0;
for (std::vector<std::string>::const_iterator i = fileNames.begin();
- i != fileNames.end(); ++i)
+ i != fileNames.end(); ++i)
{
- for (std::vector<IDataNodeReader*>::const_iterator readerIt = services.begin();
- readerIt != services.end(); ++readerIt)
+ for (std::vector<IDataNodeReader*>::const_iterator readerIt = services.begin();
+ readerIt != services.end(); ++readerIt)
+ {
+ try
+ {
+ int n = (*readerIt)->Read(*i, ds);
+ nodesRead += n;
+ if (n > 0) break;
+ }
+ catch (const std::exception& e)
{
- try
- {
- int n = (*readerIt)->Read(*i, ds);
- nodesRead += n;
- if (n > 0) break;
- }
- catch (const std::exception& e)
- {
- MITK_WARN << e.what();
- }
+ MITK_WARN << e.what();
}
- mitk::ProgressBar::GetInstance()->Progress(2);
+ }
+ mitk::ProgressBar::GetInstance()->Progress(2);
}
for (std::vector<us::ServiceReference<IDataNodeReader> >::const_iterator i = refs.begin();
- i != refs.end(); ++i)
+ i != refs.end(); ++i)
{
- context->UngetService(*i);
+ context->UngetService(*i);
}
return nodesRead;
-}
+ }
-DataStorage::Pointer IOUtil::LoadFiles(const std::vector<std::string>& fileNames)
-{
+ DataStorage::Pointer IOUtil::LoadFiles(const std::vector<std::string>& fileNames)
+ {
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
LoadFiles(fileNames, *ds);
return ds.GetPointer();
-}
+ }
-BaseData::Pointer IOUtil::LoadBaseData(const std::string& path)
-{
- return LoadDataNode(path)->GetData();
-}
+ BaseData::Pointer IOUtil::LoadBaseData(const std::string& path)
+ {
+ return LoadDataNode(path)->GetData();
+ }
-DataNode::Pointer IOUtil::LoadDataNode(const std::string& path)
-{
+ DataNode::Pointer IOUtil::LoadDataNode(const std::string& path)
+ {
mitk::DataNodeFactory::Pointer reader = mitk::DataNodeFactory::New();
try
{
- reader->SetFileName( path );
- reader->Update();
+ reader->SetFileName( path );
+ reader->Update();
- if((reader->GetNumberOfOutputs()<1))
- {
- MITK_ERROR << "Could not find data '" << path << "'";
- mitkThrow() << "An exception occured during loading the file " << path << ". Exception says could not find data.";
- }
+ if((reader->GetNumberOfOutputs()<1))
+ {
+ MITK_ERROR << "Could not find data '" << path << "'";
+ mitkThrow() << "An exception occured during loading the file " << path << ". Exception says could not find data.";
+ }
- mitk::DataNode::Pointer node = reader->GetOutput();
+ mitk::DataNode::Pointer node = reader->GetOutput();
- if(node.IsNull())
- {
- MITK_ERROR << "Could not find path: '" << path << "'" << " datanode is NULL" ;
- mitkThrow() << "An exception occured during loading the file " << path << ". Exception says datanode is NULL.";
- }
+ if(node.IsNull())
+ {
+ MITK_ERROR << "Could not find path: '" << path << "'" << " datanode is NULL" ;
+ mitkThrow() << "An exception occured during loading the file " << path << ". Exception says datanode is NULL.";
+ }
- return reader->GetOutput( 0 );
- }
+ return reader->GetOutput( 0 );
+ }
catch ( itk::ExceptionObject & e )
{
- MITK_ERROR << "Exception occured during load data of '" << path << "': Exception: " << e.what();
- mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: " << e.what();
+ MITK_ERROR << "Exception occured during load data of '" << path << "': Exception: " << e.what();
+ mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: " << e.what();
}
-}
+ }
-Image::Pointer IOUtil::LoadImage(const std::string& path)
-{
+ Image::Pointer IOUtil::LoadImage(const std::string& path)
+ {
mitk::DataNode::Pointer node = LoadDataNode(path);
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNull())
{
- MITK_ERROR << "Image is NULL '" << path << "'";
- mitkThrow() << "An exception occured during loading the image " << path << ". Exception says: Image is NULL.";
+ MITK_ERROR << "Image is NULL '" << path << "'";
+ mitkThrow() << "An exception occured during loading the image " << path << ". Exception says: Image is NULL.";
}
return image;
-}
+ }
-Surface::Pointer IOUtil::LoadSurface(const std::string& path)
-{
+ Surface::Pointer IOUtil::LoadSurface(const std::string& path)
+ {
mitk::DataNode::Pointer node = LoadDataNode(path);
mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface*>(node->GetData());
if(surface.IsNull())
{
- MITK_ERROR << "Surface is NULL '" << path << "'";
- mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Surface is NULL.";
+ MITK_ERROR << "Surface is NULL '" << path << "'";
+ mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Surface is NULL.";
}
return surface;
-}
+ }
-PointSet::Pointer IOUtil::LoadPointSet(const std::string& path)
-{
+ PointSet::Pointer IOUtil::LoadPointSet(const std::string& path)
+ {
mitk::DataNode::Pointer node = LoadDataNode(path);
mitk::PointSet::Pointer pointset = dynamic_cast<mitk::PointSet*>(node->GetData());
if(pointset.IsNull())
{
- MITK_ERROR << "PointSet is NULL '" << path << "'";
- mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Pointset is NULL.";
+ MITK_ERROR << "PointSet is NULL '" << path << "'";
+ mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Pointset is NULL.";
}
return pointset;
-}
+ }
-bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string& path)
-{
+ bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string& path)
+ {
std::string dir = itksys::SystemTools::GetFilenamePath( path );
std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path );
std::string extension = itksys::SystemTools::GetFilenameExtension( path );
if (dir == "")
dir = ".";
std::string finalFileName = dir + "/" + baseFilename;
mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New();
//check if an extension is given, else use the defaul extension
if( extension == "" )
{
- MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
- << DEFAULTIMAGEEXTENSION;
- extension = DEFAULTIMAGEEXTENSION;
+ MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
+ << DEFAULTIMAGEEXTENSION;
+ extension = DEFAULTIMAGEEXTENSION;
}
// check if extension is suitable for writing image data
if (!imageWriter->IsExtensionValid(extension))
{
- MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName
- << DEFAULTIMAGEEXTENSION;
- extension = DEFAULTIMAGEEXTENSION;
+ MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName
+ << DEFAULTIMAGEEXTENSION;
+ extension = DEFAULTIMAGEEXTENSION;
}
try
{
- //write the data
- imageWriter->SetInput(image);
- imageWriter->SetFileName(finalFileName.c_str());
- imageWriter->SetExtension(extension.c_str());
- imageWriter->Write();
+ //write the data
+ imageWriter->SetInput(image);
+ imageWriter->SetFileName(finalFileName.c_str());
+ imageWriter->SetExtension(extension.c_str());
+ imageWriter->Write();
}
catch ( std::exception& e )
{
- MITK_ERROR << " during attempt to write '" << finalFileName + extension << "' Exception says:";
- MITK_ERROR << e.what();
- mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
+ MITK_ERROR << " during attempt to write '" << finalFileName + extension << "' Exception says:";
+ MITK_ERROR << e.what();
+ mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
}
return true;
-}
+ }
-bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string& path)
-{
+ bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string& path)
+ {
std::string dir = itksys::SystemTools::GetFilenamePath( path );
std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path );
std::string extension = itksys::SystemTools::GetFilenameLastExtension( path );
if (dir == "")
dir = ".";
std::string finalFileName = dir + "/" + baseFilename;
if (extension == "") // if no extension has been set we use the default extension
{
- MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
- << DEFAULTSURFACEEXTENSION;
- extension = DEFAULTSURFACEEXTENSION;
+ MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
+ << DEFAULTSURFACEEXTENSION;
+ extension = DEFAULTSURFACEEXTENSION;
}
try
{
- finalFileName += extension;
- if(extension == ".stl" )
- {
- mitk::SurfaceVtkWriter<vtkSTLWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkSTLWriter>::New();
-
- // check if surface actually consists of triangles; if not, the writer will not do anything; so, convert to triangles...
- vtkPolyData* polys = surface->GetVtkPolyData();
- if( polys->GetNumberOfStrips() > 0 )
- {
- vtkSmartPointer<vtkTriangleFilter> triangleFilter = vtkSmartPointer<vtkTriangleFilter>::New();
- triangleFilter->SetInputData(polys);
- triangleFilter->Update();
- polys = triangleFilter->GetOutput();
- polys->Register(NULL);
- surface->SetVtkPolyData(polys);
- }
- surfaceWriter->SetInput( surface );
- surfaceWriter->SetFileName( finalFileName.c_str() );
- surfaceWriter->GetVtkWriter()->SetFileTypeToBinary();
- surfaceWriter->Write();
- }
- else if(extension == ".vtp")
- {
- mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::New();
- surfaceWriter->SetInput( surface );
- surfaceWriter->SetFileName( finalFileName.c_str() );
- surfaceWriter->GetVtkWriter()->SetDataModeToBinary();
- surfaceWriter->Write();
- }
- else if(extension == ".vtk")
- {
- mitk::SurfaceVtkWriter<vtkPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkPolyDataWriter>::New();
- surfaceWriter->SetInput( surface );
- surfaceWriter->SetFileName( finalFileName.c_str() );
- surfaceWriter->Write();
- }
- else
+ finalFileName += extension;
+ if(extension == ".stl" )
+ {
+ mitk::SurfaceVtkWriter<vtkSTLWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkSTLWriter>::New();
+
+ // check if surface actually consists of triangles; if not, the writer will not do anything; so, convert to triangles...
+ vtkPolyData* polys = surface->GetVtkPolyData();
+ if( polys->GetNumberOfStrips() > 0 )
{
- // file extension not suitable for writing specified data type
- MITK_ERROR << "File extension is not suitable for writing'" << finalFileName;
- mitkThrow() << "An exception occured during writing the file " << finalFileName <<
- ". File extension " << extension << " is not suitable for writing.";
+ vtkSmartPointer<vtkTriangleFilter> triangleFilter = vtkSmartPointer<vtkTriangleFilter>::New();
+ triangleFilter->SetInputData(polys);
+ triangleFilter->Update();
+ polys = triangleFilter->GetOutput();
+ polys->Register(NULL);
+ surface->SetVtkPolyData(polys);
}
+ surfaceWriter->SetInput( surface );
+ surfaceWriter->SetFileName( finalFileName.c_str() );
+ surfaceWriter->GetVtkWriter()->SetFileTypeToBinary();
+ surfaceWriter->Write();
+ }
+ else if(extension == ".vtp")
+ {
+ mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::New();
+ surfaceWriter->SetInput( surface );
+ surfaceWriter->SetFileName( finalFileName.c_str() );
+ surfaceWriter->GetVtkWriter()->SetDataModeToBinary();
+ surfaceWriter->Write();
+ }
+ else if(extension == ".vtk")
+ {
+ mitk::SurfaceVtkWriter<vtkPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkPolyDataWriter>::New();
+ surfaceWriter->SetInput( surface );
+ surfaceWriter->SetFileName( finalFileName.c_str() );
+ surfaceWriter->Write();
+ }
+ else
+ {
+ // file extension not suitable for writing specified data type
+ MITK_ERROR << "File extension is not suitable for writing'" << finalFileName;
+ mitkThrow() << "An exception occured during writing the file " << finalFileName <<
+ ". File extension " << extension << " is not suitable for writing.";
+ }
}
catch(std::exception& e)
{
- MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
- MITK_ERROR << e.what();
- mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
+ MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
+ MITK_ERROR << e.what();
+ mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
}
return true;
-}
+ }
-bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string& path)
-{
+ bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string& path)
+ {
mitk::PointSetWriter::Pointer pointSetWriter = mitk::PointSetWriter::New();
std::string dir = itksys::SystemTools::GetFilenamePath( path );
std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path );
std::string extension = itksys::SystemTools::GetFilenameLastExtension( path );
if (dir == "")
dir = ".";
std::string finalFileName = dir + "/" + baseFilename;
if (extension == "") // if no extension has been entered manually into the filename
{
- MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
- << DEFAULTPOINTSETEXTENSION;
- extension = DEFAULTPOINTSETEXTENSION;
+ MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
+ << DEFAULTPOINTSETEXTENSION;
+ extension = DEFAULTPOINTSETEXTENSION;
}
// check if extension is valid
if (!pointSetWriter->IsExtensionValid(extension))
{
- MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName
- << DEFAULTPOINTSETEXTENSION;
- extension = DEFAULTPOINTSETEXTENSION;
+ MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName
+ << DEFAULTPOINTSETEXTENSION;
+ extension = DEFAULTPOINTSETEXTENSION;
}
try
{
- pointSetWriter->SetInput( pointset );
- finalFileName += extension;
- pointSetWriter->SetFileName( finalFileName.c_str() );
- pointSetWriter->Update();
+ pointSetWriter->SetInput( pointset );
+ finalFileName += extension;
+ pointSetWriter->SetFileName( finalFileName.c_str() );
+ pointSetWriter->Update();
}
catch( std::exception& e )
{
- MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
- MITK_ERROR << e.what();
- mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
+ MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
+ MITK_ERROR << e.what();
+ mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
}
return true;
-}
+ }
-bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path )
-{
- if (data == NULL || path.empty()) return false;
+ bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path )
+ {
+ if (data == NULL || path.empty()) return false;
- std::string dir = itksys::SystemTools::GetFilenamePath( path );
- std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path );
- std::string extension = itksys::SystemTools::GetFilenameExtension( path );
- if (dir == "")
- dir = ".";
- std::string fileNameWithoutExtension = dir + "/" + baseFilename;
+ std::string dir = itksys::SystemTools::GetFilenamePath( path );
+ std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path );
+ std::string extension = itksys::SystemTools::GetFilenameExtension( path );
+ if (dir == "")
+ dir = ".";
+ std::string fileNameWithoutExtension = dir + "/" + baseFilename;
- mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters();
+ mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters();
- for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it)
- {
- if ( (*it)->CanWriteBaseDataType(data) )
+ for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it)
{
- // Ensure a valid filename
- if(baseFilename=="")
- {
- baseFilename = (*it)->GetDefaultFilename();
- }
- // Check if an extension exists already and if not, append the default extension
- if (extension=="" )
+ if ( (*it)->CanWriteBaseDataType(data) )
{
- extension=(*it)->GetDefaultExtension();
- }
- else
- {
- if (!(*it)->IsExtensionValid(extension))
+ // Ensure a valid filename
+ if(baseFilename=="")
{
- MITK_WARN << extension << " extension is unknown";
- continue;
+ baseFilename = (*it)->GetDefaultFilename();
+ }
+ // Check if an extension exists already and if not, append the default extension
+ if (extension=="" )
+ {
+ extension=(*it)->GetDefaultExtension();
+ }
+ else
+ {
+ if (!(*it)->IsExtensionValid(extension))
+ {
+ MITK_WARN << extension << " extension is unknown";
+ continue;
+ }
}
- }
- std::string finalFileName = fileNameWithoutExtension + extension;
- try
- {
- (*it)->SetFileName( finalFileName.c_str() );
- (*it)->DoWrite( data );
- return true;
- }
- catch( const std::exception& e )
- {
- MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
- MITK_ERROR << e.what();
- mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
+ std::string finalFileName = fileNameWithoutExtension + extension;
+ try
+ {
+ (*it)->SetFileName( finalFileName.c_str() );
+ (*it)->DoWrite( data );
+ return true;
+ }
+ catch( const std::exception& e )
+ {
+ MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
+ MITK_ERROR << e.what();
+ mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
+ }
}
}
- }
-
- return false;
-}
-}
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Core/Code/IO/mitkIOUtil.h b/Core/Code/IO/mitkIOUtil.h
index 215111d810..8627de973a 100644
--- a/Core/Code/IO/mitkIOUtil.h
+++ b/Core/Code/IO/mitkIOUtil.h
@@ -1,267 +1,271 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-
#ifndef MITKIOUTIL_H
#define MITKIOUTIL_H
#include <MitkCoreExports.h>
#include <mitkDataStorage.h>
#include <mitkSurface.h>
#include <mitkPointSet.h>
#include <mitkImage.h>
#include <fstream>
namespace mitk {
/**
* \ingroup IO
*
* \brief A utility class to load and save data from/to the local file system.
*
* This method LoadFiles queries the MITK Micro Services registry for registered mitk::IDataNodeReader service
* instances. The service instance with the highest ranking will be asked first to load the
* given file. On error (exception thrown) or if no mitk::DataNode was constructed, the next
* service instance is used.
*
* The methods LoadImage, LoadSurface, and LoadPointSet are convenience methods for general loading of
* the three main data types in MITK. They all use the more generic method LoadDataNode.
*
* The methods SaveImage, SaveSurface, and SurfacePointSet are also meant for convenience (e.g. during testing).
* Currently, there is no generic way to save a generic DataNode with an appropriate format. Thus, every method
* initializes the corresponding instance of the special writer for the data type.
*
* \see mitk::IDataNodeReader
*/
class MITK_CORE_EXPORT IOUtil
{
public:
/**
* Get the file system path where the running executable is located.
*
* @return The location of the currently running executable, without the filename.
*/
static std::string GetProgramPath();
/**
* Get the default temporary path.
*
* @return The default path for temporary data.
*/
static std::string GetTempPath();
+ /**
+ * Returns the Directory Seperator for the current OS.
+ *
+ * @return the Directory Seperator for the current OS, i.e. "\\" for Windows and "/" otherwise.
+ */
+ static char GetDirectorySeparator();
+
/**
* Create and open a temporary file.
*
* This method generates a unique temporary filename from \c templateName, creates
* and opens the file using the output stream \c tmpStream and returns the name of
* the newly create file.
*
* The \c templateName argument must contain six consective 'X' characters ("XXXXXX")
* and these are replaced with a string that makes the filename unique.
*
* The file is created with read and write permissions for owner only.
*
* @param tmpStream The output stream for writing to the temporary file.
* @param templateName An optional template for the filename.
* @param path An optional path where the temporary file should be created. Defaults
* to the default temp path as returned by GetTempPath().
* @return The filename of the created temporary file.
*
* @throw mitk::Exception if the temporary file could not be created.
*/
static std::string CreateTemporaryFile(std::ofstream& tmpStream, const std::string& templateName = "XXXXXX", std::string path = std::string());
/**
* Create and open a temporary file.
*
* This method generates a unique temporary filename from \c templateName, creates
* and opens the file using the output stream \c tmpStream and the specified open
* mode \c mode and returns the name of the newly create file. The open mode is always
* OR'd with \begin{code}std::ios_base::out | std::ios_base::trunc\end{code}.
*
* The \c templateName argument must contain six consective 'X' characters ("XXXXXX")
* and these are replaced with a string that makes the filename unique.
*
* The file is created with read and write permissions for owner only.
*
* @param tmpStream The output stream for writing to the temporary file.
* @param mode The open mode for the temporary file stream.
* @param templateName An optional template for the filename.
* @param path An optional path where the temporary file should be created. Defaults
* to the default temp path as returned by GetTempPath().
* @return The filename of the created temporary file.
*
* @throw mitk::Exception if the temporary file could not be created.
*/
static std::string CreateTemporaryFile(std::ofstream& tmpStream, std::ios_base::openmode mode,
const std::string& templateName = "XXXXXX",
std::string path = std::string());
/**
* Creates an empty temporary file.
*
* This method generates a unique temporary filename from \c templateName and creates
* this file.
*
* The file is created with read and write permissions for owner only.
*
* ---
* This version is potentially unsafe because the created temporary file is not kept open
* and could be used by another process between calling this method and opening the returned
* file path for reading or writing.
* ---
*
* @return The filename of the created temporary file.
* @param templateName An optional template for the filename.
* @param path An optional path where the temporary file should be created. Defaults
* to the default temp path as returned by GetTempPath().
* @throw mitk::Exception if the temporary file could not be created.
*/
static std::string CreateTemporaryFile(const std::string& templateName = "XXXXXX",
std::string path = std::string());
/**
* Create a temporary directory.
*
* This method generates a uniquely named temporary directory from \c templateName.
* The last set of six consecutive 'X' characters in \c templateName is replaced
* with a string that makes the directory name unique.
*
* The directory is created with read, write and executable permissions for owner only.
*
* @param templateName An optional template for the directory name.
* @param path An optional path where the temporary directory should be created. Defaults
* to the default temp path as returned by GetTempPath().
* @return The filename of the created temporary file.
*
* @throw mitk::Exception if the temporary directory could not be created.
*/
static std::string CreateTemporaryDirectory(const std::string& templateName = "XXXXXX", std::string path = std::string());
/**
* Load a files in <code>fileNames</code> and add the constructed mitk::DataNode instances
* to the mitk::DataStorage <code>storage</code>
*
* \param fileNames A list (vector) of absolute file name paths.
* \param storage The data storage to which the constructed data nodes are added.
* \return The number of added mitk::DataNode instances.
*/
static int LoadFiles(const std::vector<std::string>&fileNames, DataStorage& storage);
/**
* This method will create a new mitk::DataStorage instance and pass it to
* LoadFiles(std::vector<std::string>,DataStorage).
*
* \param fileNames A list (vector) of absolute file name paths.
* \return The new mitk::DataStorage containing the constructed data nodes.
*
* \see LoadFiles(std::vector<std::string>,DataStorage)
*/
static DataStorage::Pointer LoadFiles(const std::vector<std::string>& fileNames);
/**
* @brief Create a BaseData object from the given file.
* @param path The path to the file including file name and file extension.
* @throws mitk::Exception In case of an error when reading the file.
* @return Returns the created BaseData object.
*/
static mitk::BaseData::Pointer LoadBaseData(const std::string& path);
/**
* @brief LoadDataNode Method to load an arbitrary DataNode.
* @param path The path to the file including file name and file extension.
* @throws mitk::Exception This exception is thrown when the DataNodeFactory is not able to read/find the file
* or the DataNode is NULL.
* @return Returns the DataNode.
*/
static mitk::DataNode::Pointer LoadDataNode(const std::string& path);
/**
* @brief LoadImage Convenience method to load an arbitrary mitkImage.
* @param path The path to the image including file name and file extension.
* @throws mitk::Exception This exception is thrown when the Image is NULL.
* @return Returns the mitkImage.
*/
static mitk::Image::Pointer LoadImage(const std::string& path);
/**
* @brief LoadSurface Convenience method to load an arbitrary mitkSurface.
* @param path The path to the surface including file name and file extension.
* @throws mitk::Exception This exception is thrown when the Surface is NULL.
* @return Returns the mitkSurface.
*/
static mitk::Surface::Pointer LoadSurface(const std::string& path);
/**
* @brief LoadPointSet Convenience method to load an arbitrary mitkPointSet.
* @param path The path to the pointset including file name and file extension (currently, only .mps is supported).
* @throws mitk::Exception This exception is thrown when the PointSet is NULL.
* @return Returns the mitkPointSet.
*/
static mitk::PointSet::Pointer LoadPointSet(const std::string& path);
/**
* @brief SaveImage Convenience method to save an arbitrary mitkImage.
* @param path The path to the image including file name and file extension.
* If not extention is set, the default value (defined in DEFAULTIMAGEEXTENSION) is used.
* @param image The image to save.
* @throws mitk::Exception This exception is thrown when the writer is not able to write the image.
* @return Returns true for success else false.
*/
static bool SaveImage(mitk::Image::Pointer image, const std::string& path);
/**
* @brief SaveBaseData Convenience method to save arbitrary baseData.
* @param path The path to the image including file name and file extension.
* If not extention is set, the default value (defined in DEFAULTIMAGEEXTENSION) is used.
* @param data The data to save.
* @throws mitk::Exception This exception is thrown when the writer is not able to write the image.
* @return Returns true for success else false.
*/
static bool SaveBaseData(mitk::BaseData* data, const std::string& path);
/**
* @brief SaveSurface Convenience method to save an arbitrary mitkSurface.
* @param path The path to the surface including file name and file extension.
* If not extention is set, the default value (defined in DEFAULTSURFACEEXTENSION) is used.
* @throws mitk::Exception This exception is thrown when the writer is not able to write the surface.
* or if the fileextension is not suitable for writing.
* @return Returns true for success else false.
*/
static bool SaveSurface(mitk::Surface::Pointer surface, const std::string& path);
/**
* @brief SavePointSet Convenience method to save an mitkPointSet.
* @param path The path to the pointset including file name and file extension (currently, only .mps is supported).
* If not extention is set, the default value (defined in DEFAULTPOINTSETEXTENSION) is used.
* @throws mitk::Exception This exception is thrown when the writer is not able to write the pointset.
* @return Returns true for success else false.
*/
static bool SavePointSet(mitk::PointSet::Pointer pointset, const std::string& path);
static const std::string DEFAULTIMAGEEXTENSION;
static const std::string DEFAULTSURFACEEXTENSION;
static const std::string DEFAULTPOINTSETEXTENSION;
-
};
-
}
#endif // MITKIOUTIL_H
diff --git a/Core/Code/IO/mitkLog.cpp b/Core/Code/IO/mitkLog.cpp
index 620d12e585..8aae1adde5 100644
--- a/Core/Code/IO/mitkLog.cpp
+++ b/Core/Code/IO/mitkLog.cpp
@@ -1,234 +1,239 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkLog.h>
#include <mitkLogMacros.h>
#include <mitkExceptionMacro.h>
#include <itkSimpleFastMutexLock.h>
#include <itkOutputWindow.h>
#include <iostream>
#include <fstream>
#include <cstdio>
static itk::SimpleFastMutexLock logMutex;
static mitk::LoggingBackend *mitkLogBackend = 0;
static std::ofstream *logFile = 0;
static std::string logFileName = "";
static std::stringstream *outputWindow = 0;
static bool logOutputWindow = false;
void mitk::LoggingBackend::EnableAdditionalConsoleWindow(bool enable)
{
logOutputWindow = enable;
}
void mitk::LoggingBackend::ProcessMessage(const mbilog::LogMessage& l )
{
logMutex.Lock();
#ifdef _WIN32
FormatSmart( l, (int)GetCurrentThreadId() );
#else
FormatSmart( l );
#endif
if(logFile)
{
#ifdef _WIN32
FormatFull( *logFile, l, (int)GetCurrentThreadId() );
#else
FormatFull( *logFile, l );
#endif
}
if(logOutputWindow)
{
if(outputWindow == NULL)
{ outputWindow = new std::stringstream();}
outputWindow->str("");
outputWindow->clear();
#ifdef _WIN32
FormatFull( *outputWindow, l, (int)GetCurrentThreadId() );
#else
FormatFull( *outputWindow, l );
#endif
itk::OutputWindow::GetInstance()->DisplayText(outputWindow->str().c_str());
}
logMutex.Unlock();
}
void mitk::LoggingBackend::Register()
{
if(mitkLogBackend)
return;
mitkLogBackend = new mitk::LoggingBackend();
mbilog::RegisterBackend( mitkLogBackend );
}
void mitk::LoggingBackend::Unregister()
{
if(mitkLogBackend)
{
SetLogFile(0);
mbilog::UnregisterBackend( mitkLogBackend );
delete mitkLogBackend;
mitkLogBackend=0;
}
}
void mitk::LoggingBackend::SetLogFile(const char *file)
{
// closing old logfile
{
bool closed = false;
std::string closedFileName;
logMutex.Lock();
if(logFile)
{
closed = true;
closedFileName = logFileName;
logFile->close();
delete logFile;
logFile = 0;
logFileName = "";
}
logMutex.Unlock();
if(closed)
{
MITK_INFO << "closing logfile (" << closedFileName << ")" ;
}
}
// opening new logfile
if(file)
{
logMutex.Lock();
logFileName = file;
logFile = new std::ofstream( );
logFile->open( file, std::ios_base::out | std::ios_base::app );
if(logFile->good())
{
logMutex.Unlock();
MITK_INFO << "Logfile: " << logFileName ;
}
else
{
delete logFile;
logFile = 0;
logMutex.Unlock();
MITK_WARN << "opening logfile '" << file << "' for writing failed";
}
// mutex is now unlocked
}
}
std::string mitk::LoggingBackend::GetLogFile()
{
return logFileName;
}
void mitk::LoggingBackend::CatchLogFileCommandLineParameter(int &argc,char **argv)
{
int r;
for(r=1;r<argc;r++)
{
if(std::string(argv[r])=="--logfile")
{
if(r+1>=argc)
{
--argc;
MITK_ERROR << "--logfile parameter found, but no file given";
return;
}
mitk::LoggingBackend::SetLogFile(argv[r+1]);
for(r+=2;r<argc;r++)
argv[r-2]=argv[r];
argc-=2;
return;
}
}
}
void mitk::LoggingBackend::RotateLogFiles(const std::string& prefixPath)
{
static const int numLogFiles = 10;
std::string newEmptyLogFileName;
//first: rotate the old log files to get a new, free logfile name
newEmptyLogFileName = IncrementLogFileNames(prefixPath,numLogFiles);
//now: use the new empty logfile name as name for this run
mitk::LoggingBackend::SetLogFile(newEmptyLogFileName.c_str());
}
std::string mitk::LoggingBackend::IncrementLogFileNames(const std::string& prefixPath, int numLogFiles)
{
// delete last one
{
std::stringstream s;
s << prefixPath.c_str() << "-" << numLogFiles-1 << ".log";
//check if the file exists
if (CheckIfFileExists(s.str())) //if yes: delete it
{
int retVal = ::remove(s.str().c_str());
if (retVal!=0) {mitkThrow() << "Problem while deleting the oldest log file. Maybe the access to this files is blocked. Aborting!";}
}
}
// rename the others
for( int r = numLogFiles-1 ; r >= 1 ; r-- )
{
std::stringstream dst;
dst << prefixPath.c_str() << "-" << r << ".log";
std::stringstream src;
src << prefixPath.c_str() << "-" << r-1 << ".log";
//check if the source exists
if (CheckIfFileExists(src.str())) //if yes: rename it
{
int retVal = ::rename( src.str().c_str(), dst.str().c_str() );
if (retVal!=0) {mitkThrow() << "Problem while renaming the log files. Maybe the access to this files is blocked. Aborting!";}
}
}
//create new empty name and return it
{
std::stringstream s;
s << prefixPath.c_str() << "-0.log";
return s.str();
}
}
bool mitk::LoggingBackend::CheckIfFileExists(const std::string& filename)
{
bool returnValue = false;
std::ifstream File(filename.c_str());
if (File.good()) {returnValue = true;}
else {returnValue = false;}
File.close();
return returnValue;
}
+
+mbilog::OutputType mitk::LoggingBackend::GetOutputType() const
+{
+ return mbilog::Console;
+}
diff --git a/Core/Code/IO/mitkLog.h b/Core/Code/IO/mitkLog.h
index 8efe212ef3..d567dc6818 100644
--- a/Core/Code/IO/mitkLog.h
+++ b/Core/Code/IO/mitkLog.h
@@ -1,105 +1,107 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_LOG_H
#define _MITK_LOG_H
#include <MitkCoreExports.h>
#include <mbilog.h>
namespace mitk
{
/*!
\brief mbilog backend implementation for mitk
*/
class MITK_CORE_EXPORT LoggingBackend : public mbilog::TextBackendBase
{
public:
/** \brief overloaded method for receiving log message from mbilog
*/
void ProcessMessage(const mbilog::LogMessage& );
/** \brief registers MITK logging backend at mbilog
*/
static void Register();
/** \brief Unregisters MITK logging backend at mbilog
*/
static void Unregister();
/** \brief Sets extra log file path (additionally to the console log)
*/
static void SetLogFile(const char *file);
/** @brief Activates and handles a rolling log file with the given prefix and path.
* This method handles 10 log files with a given prefix, e.g. "myLogFile".
* The 10 log files will then look like this:
* myLogFile-0.log (current file)
* myLogFile-1.log (last file)
* myLogFile-2.log
* [...]
* myLogFile-9.log
*
* Everytime this method this called, normally when MITK is started, then
* all log files are copied one file below (0 to 1, 1 to 2, and so on).
* The oldes logfile (number 9) is always deleted. So users have access to
* the log files of the last 10 runs.
* @throws mitk::Exception Throws an exception if there is a problem with renaming the logfiles, e.g., because of file access problems.
* @param prefixPath Should hold the prefix of the logfile together with its path. E.g., "C:/programs/mitk/myLogFile".
*/
static void RotateLogFiles(const std::string& prefixPath);
/** @brief Increments the names of logfiles with the given prefixPath.
* This means, if the prefixPath is "myLogFile" myLogFile-0.log
* is renamed to myLogFile-1.log, myLogFile-1.log to myLogFile-2.log,
* and so on. The oldest logfile is deleted. The number of log files is
* defined by the parameter "numLogFiles". The first logfile name is
* "free" (e.g., [prefix]-0.log) again. This name is retured.
* @param prefixPath Should hold the prefix of the logfile together with its path. E.g., "C:/programs/mitk/myLogFile".
* @param numLogFiles Sets the number of logfiles. Default value is 10. This means logfiles from [prefix]-0.log
* to [prefix]-1.log are stored.
* @return Returns a new logfile name which is free again because the old first log file was renamed.
* @throws mitk::Exception Throws an exception if there is a problem with renaming the logfiles, e.g., because of file access problems.
*/
static std::string IncrementLogFileNames(const std::string& prefixPath, int numLogFiles = 10);
/** @return Returns the log file if there is one. Returns an empty string
* if no log file is active.
*/
static std::string GetLogFile();
/** \brief Enables an additional logging output window by means of itk::outputwindow
* This might be relevant for showing log output in applications with no default output console
*/
static void EnableAdditionalConsoleWindow(bool enable);
/** \brief Automatically extracts and removes the "--logfile <file>" parameters from the standard C main(argc,argv) parameter list and calls SetLogFile if needed
*/
static void CatchLogFileCommandLineParameter(int &argc,char **argv);
+ virtual mbilog::OutputType GetOutputType() const;
+
protected:
/** Checks if a file exists.
* @return Returns true if the file exists, false if not.
*/
static bool CheckIfFileExists(const std::string& filename);
};
}
#endif
diff --git a/Core/Code/IO/mitkOperationActor.h b/Core/Code/IO/mitkOperationActor.h
index b126595144..45660f5325 100644
--- a/Core/Code/IO/mitkOperationActor.h
+++ b/Core/Code/IO/mitkOperationActor.h
@@ -1,51 +1,52 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef OPERATIONACTOR_H_HEADER_INCLUDED_C16E28BD
#define OPERATIONACTOR_H_HEADER_INCLUDED_C16E28BD
#include <MitkCoreExports.h>
+/** Macro for checking the type of an operation */
+#define mitkCheckOperationTypeMacro(OperationType, operation, newOperationName) \
+OperationType *newOperationName = dynamic_cast<OperationType *>(operation); \
+if (newOperationName == NULL) \
+{ \
+ itkWarningMacro("Recieved wrong type of operation!"); \
+ return; \
+}
+
namespace mitk
{
- class Operation;
- class OperationEvent;
+class Operation;
+class OperationEvent;
- /** Macro for checking the type of an operation*/
-#define mitkCheckOperationTypeMacro(OperationType, operation, newOperationName) \
- mitk::OperationType *newOperationName= dynamic_cast<mitk::OperationType *>(operation);\
- if (newOperationName == NULL)\
- {\
- itkWarningMacro("Recieved wrong type of operation!");\
- return;\
- }\
-
- //##Documentation
- //## @brief abstract class, that can be used by Undo to undo an operation.
- //##
- //## @ingroup Undo
- class MITK_CORE_EXPORT OperationActor
- {
- public:
- virtual ~OperationActor() {};
- virtual void ExecuteOperation(Operation* operation) = 0;
- };
-}
+/**
+ * \brief abstract class, that can be used by Undo to undo an operation.
+ *
+ * \ingroup Undo
+ */
+class MITK_CORE_EXPORT OperationActor
+{
+public:
+ virtual ~OperationActor() {}
+ virtual void ExecuteOperation(Operation* operation) = 0;
+};
+}
#endif /* OPERATIONACTOR_H_HEADER_INCLUDED_C16E28BD */
diff --git a/Core/Code/Interactions/mitkEventRecorder.cpp b/Core/Code/Interactions/mitkEventRecorder.cpp
index 7421412fb7..b260013615 100644
--- a/Core/Code/Interactions/mitkEventRecorder.cpp
+++ b/Core/Code/Interactions/mitkEventRecorder.cpp
@@ -1,164 +1,171 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkEventRecorder.h"
#include "mitkEventFactory.h"
#include "mitkInteractionEvent.h"
#include "mitkInteractionEventConst.h"
#include "mitkBaseRenderer.h"
static void WriteEventXMLHeader(std::ofstream& stream)
{
stream << mitk::InteractionEventConst::xmlHead() << "\n";
}
static void WriteEventXMLConfig(std::ofstream& stream)
{
// <config>
stream << " <" << mitk::InteractionEventConst::xmlTagConfigRoot() << ">\n";
//write renderer config
//for all registered 2D renderers write name and viewdirection.
mitk::BaseRenderer::BaseRendererMapType::iterator rendererIterator = mitk::BaseRenderer::baseRendererMap.begin();
mitk::BaseRenderer::BaseRendererMapType::iterator end = mitk::BaseRenderer::baseRendererMap.end();
for(; rendererIterator != end; rendererIterator++)
{
std::string rendererName = (*rendererIterator).second->GetName();
+
mitk::SliceNavigationController::ViewDirection viewDirection = (*rendererIterator).second->GetSliceNavigationController()->GetDefaultViewDirection();
mitk::BaseRenderer::MapperSlotId mapperID = (*rendererIterator).second->GetMapperID();
- // <renderer RendererName="stdmulti.widget2" ViewDirection="1" MapperID="1"/>
- stream << " <" << mitk::InteractionEventConst::xmlTagRenderer() << " " << mitk::InteractionEventConst::xmlEventPropertyRendererName() << "=\"" << rendererName << "\" " << mitk::InteractionEventConst::xmlEventPropertyViewDirection() << "=\"" << viewDirection << "\" " << mitk::InteractionEventConst::xmlEventPropertyMapperID() << "=\"" << mapperID << "\"/>\n";
+ // <renderer RendererName="stdmulti.widget2" ViewDirection="1" MapperID="1" SizeX="200" SizeY="200" SizeZ="1"/>
+ stream << " <" << mitk::InteractionEventConst::xmlTagRenderer() << " "
+ << mitk::InteractionEventConst::xmlEventPropertyRendererName() << "=\""<< rendererName << "\" "
+ << mitk::InteractionEventConst::xmlEventPropertyViewDirection() << "=\""<< viewDirection << "\" "
+ << mitk::InteractionEventConst::xmlEventPropertyMapperID() << "=\"" << mapperID << "\" "
+ << mitk::InteractionEventConst::xmlRenderSizeX() << "=\"" << (*rendererIterator).second->GetSize()[0] << "\" "
+ << mitk::InteractionEventConst::xmlRenderSizeY() << "=\"" << (*rendererIterator).second->GetSize()[1] << "\" "
+ << mitk::InteractionEventConst::xmlRenderSizeZ() << "=\"" << (*rendererIterator).second->GetSize()[2] << "\" "
+ << "/>\n";
}
// </config>
stream << " </" << mitk::InteractionEventConst::xmlTagConfigRoot() << ">\n";
}
static void WriteEventXMLEventsOpen(std::ofstream& stream)
{
stream << " <" << mitk::InteractionEventConst::xmlTagEvents() << ">\n";
}
static void WriteEventXMLEventsClose(std::ofstream& stream)
{
stream << " </" << mitk::InteractionEventConst::xmlTagEvents() << ">\n";
}
static void WriteEventXMLInteractionsOpen(std::ofstream& stream)
{
stream << "<" << mitk::InteractionEventConst::xmlTagInteractions() << ">\n";
}
static void WriteEventXMLInteractionsClose(std::ofstream& stream)
{
stream << "</" << mitk::InteractionEventConst::xmlTagInteractions() << ">";
}
static void WriteEventXMLClose(std::ofstream& stream)
{
WriteEventXMLEventsClose(stream);
WriteEventXMLInteractionsClose(stream);
}
mitk::EventRecorder::EventRecorder()
: m_Active(false)
{
}
mitk::EventRecorder::~EventRecorder()
{
if (m_FileStream.is_open())
{
m_FileStream.flush();
m_FileStream.close();
}
}
void mitk::EventRecorder::Notify(mitk::InteractionEvent *interactionEvent, bool /*isHandled*/)
{
- std::cout << EventFactory::EventToXML(interactionEvent) << "\n";
if (m_FileStream.is_open())
m_FileStream << EventFactory::EventToXML(interactionEvent) << "\n";
}
void mitk::EventRecorder::SetEventIgnoreList(std::vector<std::string> list)
{
m_IgnoreList = list;
}
void mitk::EventRecorder::StartRecording()
{
if (m_FileName == "")
{
MITK_ERROR << "EventRecorder::StartRecording - Filename needs to be set first.";
return;
}
if (m_FileStream.is_open())
{
MITK_ERROR << "EventRecorder::StartRecording - Still recording. Stop recording before starting it again.";
return;
}
m_FileStream.open(m_FileName.c_str(), std::ofstream::out );
if ( !m_FileStream.good() )
{
MITK_ERROR << "File " << m_FileName << " could not be opened!";
m_FileStream.close();
return;
}
m_Active = true;
//write head and config
// <?xml version="1.0"?>
// <interactions>
// <config>
// <renderer RendererName="stdmulti.widget2" ViewDirection="1"/>
// <renderer RendererName="stdmulti.widget1" ViewDirection="0"/>
// ...
// </config>
// <events>
WriteEventXMLHeader(m_FileStream);
WriteEventXMLInteractionsOpen(m_FileStream);
WriteEventXMLConfig(m_FileStream);
WriteEventXMLEventsOpen(m_FileStream);
}
void mitk::EventRecorder::StopRecording()
{
if (m_FileStream.is_open())
{
//write end tag
// </events>
// </interactions>
WriteEventXMLClose(m_FileStream);
m_FileStream.flush();
m_FileStream.close();
m_Active =false;
}
}
diff --git a/Core/Code/Interactions/mitkEventStateMachine.h b/Core/Code/Interactions/mitkEventStateMachine.h
index 14d35daeca..8fba466cbe 100644
--- a/Core/Code/Interactions/mitkEventStateMachine.h
+++ b/Core/Code/Interactions/mitkEventStateMachine.h
@@ -1,254 +1,253 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKEVENTSTATEMACHINE_H_
#define MITKEVENTSTATEMACHINE_H_
#include "itkObject.h"
#include "mitkCommon.h"
#include "mitkMessage.h"
#include "mitkInteractionEventHandler.h"
#include <MitkCoreExports.h>
#include <string>
+/**
+ * Macro that can be used to connect a StateMachineAction with a function.
+ * It assumes that there is a typedef Classname Self in classes that use
+ * this macro, as is provided by e.g. mitkClassMacro
+ */
+#define CONNECT_FUNCTION(a, f) \
+ ::mitk::EventStateMachine::AddActionFunction(a, ::mitk::MessageDelegate2<Self, ::mitk::StateMachineAction*, ::mitk::InteractionEvent*, bool>(this, &Self::f));
+
+#define CONNECT_CONDITION(a, f) \
+ ::mitk::EventStateMachine::AddConditionFunction(a, ::mitk::MessageDelegate1<Self,const ::mitk::InteractionEvent*, bool>(this, &Self::f));
+
+
namespace us {
class Module;
}
namespace mitk
{
class StateMachineTransition;
class StateMachineContainer;
class StateMachineAction;
class StateMachineCondition;
class InteractionEvent;
class StateMachineState;
class DataNode;
class UndoController;
/**
* \class TActionFunctor
* \brief Base class of ActionFunctors, to provide an easy to connect actions with functions.
*
* \deprecatedSince{2013_03} Use mitk::Message classes instead.
*/
class TActionFunctor
{
public:
virtual bool DoAction(StateMachineAction*, InteractionEvent*)=0;
virtual ~TActionFunctor()
{
}
};
/**
* \class TSpecificActionFunctor
* Specific implementation of ActionFunctor class, implements a reference to the function which is to be executed. It takes two arguments:
* StateMachineAction - the action by which the function call is invoked, InteractionEvent - the event that caused the transition.
*/
template<class T>
class DEPRECATED() TSpecificActionFunctor : public TActionFunctor
{
public:
TSpecificActionFunctor(T* object, bool (T::*memberFunctionPointer)(StateMachineAction*, InteractionEvent*)) :
m_Object(object), m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~TSpecificActionFunctor()
{
}
virtual bool DoAction(StateMachineAction* action, InteractionEvent* event)
{
return (*m_Object.*m_MemberFunctionPointer)(action, event);// executes member function
}
private:
T* m_Object;
bool (T::*m_MemberFunctionPointer)(StateMachineAction*, InteractionEvent*);
};
- /** Macro that can be used to connect a StateMachineAction with a function.
- * It assumes that there is a typedef Classname Self in classes that use this macro, as is provided by e.g. mitkClassMacro
- */
-#define CONNECT_FUNCTION(a, f) \
- EventStateMachine::AddActionFunction(a, MessageDelegate2<Self, StateMachineAction*, InteractionEvent*, bool>(this, &Self::f));
-
-#define CONNECT_CONDITION(a, f) \
- EventStateMachine::AddConditionFunction(a, MessageDelegate1<Self,const InteractionEvent*, bool>(this, &Self::f));
-
-
/**
* \class EventStateMachine
*
* \brief Super-class that provides the functionality of a StateMachine to DataInteractors.
*
* A state machine is created by loading a state machine pattern. It consists of states, transitions and action.
* The state represent the current status of the interaction, transitions are means to switch between states. Each transition
* is triggered by an event and it is associated with actions that are to be executed when the state change is performed.
*
*/
-
class MITK_CORE_EXPORT EventStateMachine : public mitk::InteractionEventHandler
{
public:
mitkClassMacro(EventStateMachine, InteractionEventHandler)
typedef std::map<std::string, TActionFunctor*> DEPRECATED(ActionFunctionsMapType);
typedef itk::SmartPointer<StateMachineState> StateMachineStateType;
/**
* @brief Loads XML resource
*
* Loads a XML resource file from the given module.
* Default is the Mitk module (core).
* The files have to be placed in the Resources/Interaction folder of their respective module.
**/
bool LoadStateMachine(const std::string& filename, const us::Module* module = NULL);
/**
* Receives Event from Dispatcher.
* Event is mapped using the EventConfig Object to a variant, then it is checked if the StateMachine is listening for
* such an Event. If this is the case, the transition to the next state it performed and all actions associated with the transition executed,
* and true is returned to the caller.
* If the StateMachine can't handle this event false is returned.
* Attention:
* If a transition is associated with multiple actions - "true" is returned if one action returns true,
* and the event is treated as HANDLED even though some actions might not have been executed! So be sure that all actions that occur within
* one transitions have the same conditions.
*/
bool HandleEvent(InteractionEvent* event, DataNode* dataNode);
/**
* @brief Enables or disabled Undo.
**/
void EnableUndo(bool enable)
{
m_UndoEnabled = enable;
}
-
/**
* @brief Enables/disables the state machine. In un-enabled state it won't react to any events.
**/
void EnableInteraction(bool enable)
{
m_IsActive = enable;
}
-
protected:
EventStateMachine();
virtual ~EventStateMachine();
typedef MessageAbstractDelegate2<StateMachineAction*, InteractionEvent*, bool> ActionFunctionDelegate;
typedef MessageAbstractDelegate1<const InteractionEvent*, bool> ConditionFunctionDelegate;
/**
* Connects action from StateMachine (String in XML file) with a function that is called when this action is to be executed.
*/
DEPRECATED(void AddActionFunction(const std::string& action, TActionFunctor* functor));
void AddActionFunction(const std::string& action, const ActionFunctionDelegate& delegate);
void AddConditionFunction(const std::string& condition, const ConditionFunctionDelegate& delegate);
StateMachineState* GetCurrentState() const;
/**
* @brief ResetToStartState Reset state machine to it initial starting state.
*/
void ResetToStartState();
/**
* Is called after loading a statemachine.
* Overwrite this function in specific interactor implementations.
* Connect actions and functions using the CONNECT_FUNCTION macro within this function.
*/
virtual void ConnectActionsAndFunctions();
virtual bool CheckCondition( const StateMachineCondition& condition, const InteractionEvent* interactionEvent );
/**
* Looks up function that is associated with action and executes it.
* To implement your own execution scheme overwrite this in your DataInteractor.
*/
virtual bool ExecuteAction(StateMachineAction* action, InteractionEvent* interactionEvent);
/**
* Implements filter scheme for events.
* Standard implementation accepts events from 2d and 3d windows,
* and rejects events if DataNode is not visible.
* \return true if event is accepted, else false
*
* Overwrite this function to adapt for your own needs, for example to filter out events from
* 3d windows like this:
\code
bool mitk::EventStateMachine::FilterEvents(InteractionEvent* interactionEvent, DataNode*dataNode)
{
return interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D; // only 2D mappers
}
\endcode
* or to enforce that the interactor only reacts when the corresponding DataNode is selected in the DataManager view..
*/
virtual bool FilterEvents(InteractionEvent* interactionEvent, DataNode* dataNode);
/**
* \brief Returns the executable transition for the given event.
*
* This method takes a list of transitions that correspond to the given
* event from the current state.
*
* This method iterates through all transitions and checks all
* corresponding conditions. The results of each condition in stored in
* map, as other transitions may need the same condition again.
*
* As soon as a transition is found for which all conditions are
* fulfilled, this instance is returned.
*
* If a transition has no condition, it is automatically returned.
* If no executable transition is found, NULL is returned.
*/
StateMachineTransition* GetExecutableTransition( InteractionEvent* event );
// Determines if state machine reacts to events
bool m_IsActive;
// Undo/Redo
UndoController* m_UndoController;
bool m_UndoEnabled;
private:
typedef std::map<std::string, ActionFunctionDelegate*> ActionDelegatesMapType;
typedef std::map<std::string, ConditionFunctionDelegate*> ConditionDelegatesMapType;
StateMachineContainer* m_StateMachineContainer; // storage of all states, action, transitions on which the statemachine operates.
std::map<std::string, TActionFunctor*> m_ActionFunctionsMap; // stores association between action string
ActionDelegatesMapType m_ActionDelegatesMap;
ConditionDelegatesMapType m_ConditionDelegatesMap;
StateMachineStateType m_CurrentState;
};
} /* namespace mitk */
#endif /* MITKEVENTSTATEMACHINE_H_ */
diff --git a/Core/Code/Interactions/mitkInteractionEventConst.cpp b/Core/Code/Interactions/mitkInteractionEventConst.cpp
index a61354c688..7615c30aaf 100644
--- a/Core/Code/Interactions/mitkInteractionEventConst.cpp
+++ b/Core/Code/Interactions/mitkInteractionEventConst.cpp
@@ -1,165 +1,183 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkInteractionEventConst.h"
namespace mitk {
const std::string InteractionEventConst::xmlHead()
{
static const std::string xmlHead = "<?xml version='1.0'?>";
return xmlHead;
}
const std::string InteractionEventConst::xmlTagConfigRoot()
{
static const std::string xmlTagConfigRoot = "config";
return xmlTagConfigRoot;
}
const std::string InteractionEventConst::xmlTagEvents()
{
static const std::string xmlTagEvents = "events";
return xmlTagEvents;
}
const std::string InteractionEventConst::xmlTagInteractions()
{
static const std::string xmlTagInteractions = "interactions";
return xmlTagInteractions;
}
const std::string InteractionEventConst::xmlTagRenderer()
{
static const std::string xmlTagRenderer = "renderer";
return xmlTagRenderer;
}
const std::string InteractionEventConst::xmlTagParam()
{
static const std::string xmlTagParam = "param";
return xmlTagParam;
}
const std::string InteractionEventConst::xmlTagEventVariant()
{
static const std::string xmlTagEventVariant = "event_variant";
return xmlTagEventVariant;
}
const std::string InteractionEventConst::xmlTagAttribute()
{
static const std::string xmlTagAttribute = "attribute";
return xmlTagAttribute;
}
const std::string InteractionEventConst::xmlParameterName()
{
static const std::string xmlParameterName = "name";
return xmlParameterName;
}
const std::string InteractionEventConst::xmlParameterValue()
{
static const std::string xmlParameterValue = "value";
return xmlParameterValue;
}
const std::string InteractionEventConst::xmlParameterEventVariant()
{
static const std::string xmlParameterEventVariant = "event_variant";
return xmlParameterEventVariant;
}
const std::string InteractionEventConst::xmlParameterEventClass()
{
static const std::string xmlParameterEventClass = "class";
return xmlParameterEventClass;
}
const std::string InteractionEventConst::xmlEventPropertyModifier()
{
static const std::string xmlEventPropertyModifier = "Modifiers";
return xmlEventPropertyModifier;
}
const std::string InteractionEventConst::xmlEventPropertyEventButton()
{
static const std::string xmlEventPropertyEventButton = "EventButton";
return xmlEventPropertyEventButton;
}
const std::string InteractionEventConst::xmlEventPropertyButtonState()
{
static const std::string xmlEventPropertyButtonState = "ButtonState";
return xmlEventPropertyButtonState;
}
const std::string InteractionEventConst::xmlEventPropertyPositionInWorld()
{
static const std::string xmlEventPropertyPosition = "PositionInWorld";
return xmlEventPropertyPosition;
}
const std::string InteractionEventConst::xmlEventPropertyPositionOnScreen()
{
static const std::string xmlEventPropertyPosition = "PositionOnScreen";
return xmlEventPropertyPosition;
}
const std::string InteractionEventConst::xmlEventPropertyKey()
{
static const std::string xmlEventPropertyKey = "Key";
return xmlEventPropertyKey;
}
const std::string InteractionEventConst::xmlEventPropertyScrollDirection()
{
static const std::string xmlEventPropertyScrollDirection = "ScrollDirection";
return xmlEventPropertyScrollDirection;
}
const std::string InteractionEventConst::xmlEventPropertyWheelDelta()
{
static const std::string xmlEventPropertyWheelDelta = "WheelDelta";
return xmlEventPropertyWheelDelta;
}
const std::string InteractionEventConst::xmlEventPropertySignalName()
{
static const std::string xmlEventPropertySignalName = "SignalName";
return xmlEventPropertySignalName;
}
const std::string InteractionEventConst::xmlEventPropertyRendererName()
{
static const std::string xmlEventPropertyRendererName = "RendererName";
return xmlEventPropertyRendererName;
}
const std::string InteractionEventConst::xmlEventPropertyViewDirection()
{
static const std::string xmlEventPropertyViewDirection = "ViewDirection";
return xmlEventPropertyViewDirection;
}
const std::string InteractionEventConst::xmlEventPropertyMapperID()
{
static const std::string xmlEventPropertyMapperID = "MapperID";
return xmlEventPropertyMapperID;
}
+const std::string mitk::InteractionEventConst::xmlRenderSizeX()
+{
+ static const std::string xmlSize = "RenderSizeX";
+ return xmlSize;
+}
+
+const std::string mitk::InteractionEventConst::xmlRenderSizeY()
+{
+ static const std::string xmlSize = "RenderSizeY";
+ return xmlSize;
+}
+
+const std::string mitk::InteractionEventConst::xmlRenderSizeZ()
+{
+ static const std::string xmlSize = "RenderSizeZ";
+ return xmlSize;
+}
+
}
diff --git a/Core/Code/Interactions/mitkInteractionEventConst.h b/Core/Code/Interactions/mitkInteractionEventConst.h
index 02589cac20..137aaf0552 100644
--- a/Core/Code/Interactions/mitkInteractionEventConst.h
+++ b/Core/Code/Interactions/mitkInteractionEventConst.h
@@ -1,64 +1,68 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKINTERACTEVENTCONST_H
#define MITKINTERACTEVENTCONST_H
#include <string>
#include <MitkCoreExports.h>
namespace mitk
{
/**
* @brief Constants to describe Mouse Events and special Key Events.
*/
struct MITK_CORE_EXPORT InteractionEventConst
{
static const std::string xmlHead(); // = "<?xml version='1.0'?>";
// XML Tags
static const std::string xmlTagConfigRoot(); // = "config";
static const std::string xmlTagEvents(); // = "events";
static const std::string xmlTagInteractions(); // = "interactions";
static const std::string xmlTagParam(); // = "param";
static const std::string xmlTagEventVariant(); // = "event_variant";
static const std::string xmlTagAttribute(); // = "attribute";
static const std::string xmlTagRenderer(); // = "renderer";
// XML Param
static const std::string xmlParameterName(); // = "name";
static const std::string xmlParameterValue(); // = "value";
static const std::string xmlParameterEventVariant(); // = "event_variant";
static const std::string xmlParameterEventClass(); // = "class";
// Event Description
static const std::string xmlEventPropertyModifier(); // = "Modifiers";
static const std::string xmlEventPropertyEventButton(); // = "EventButton";
static const std::string xmlEventPropertyButtonState(); // = "ButtonState";
static const std::string xmlEventPropertyPositionInWorld(); // = "PositionInWorld";
static const std::string xmlEventPropertyPositionOnScreen(); // = "PositionOnScreen";
static const std::string xmlEventPropertyKey(); // = "Key";
static const std::string xmlEventPropertyScrollDirection(); // = "ScrollDirection";
static const std::string xmlEventPropertyWheelDelta(); // = "WheelDelta";
static const std::string xmlEventPropertySignalName(); // = "SignalName";
static const std::string xmlEventPropertyRendererName(); // = "RendererName";
static const std::string xmlEventPropertyViewDirection(); // = "ViewDirection";
static const std::string xmlEventPropertyMapperID(); // = "MapperID";
+
+ static const std::string xmlRenderSizeX(); // = "RenderSizeX";
+ static const std::string xmlRenderSizeY(); // = "RenderSizeY";
+ static const std::string xmlRenderSizeZ(); // = "RenderSizeZ";
};
} //namespace mitk
#endif //ifndef MITKINTERACTEVENTCONST_H
diff --git a/Core/Code/Interactions/mitkMessage.h b/Core/Code/Interactions/mitkMessage.h
index 1799a1b76f..c7c190de18 100644
--- a/Core/Code/Interactions/mitkMessage.h
+++ b/Core/Code/Interactions/mitkMessage.h
@@ -1,801 +1,802 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkMessageHIncluded
#define mitkMessageHIncluded
#include <vector>
#include <functional>
#include <itkSimpleFastMutexLock.h>
/**
* Adds a Message<> variable and methods to add/remove message delegates to/from
* this variable.
*/
#define mitkNewMessageMacro(msgHandleObject) \
private: ::mitk::Message<> m_##msgHandleObject##Message; \
public: \
inline void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<>& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
inline void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<>& delegate) \
{ m_##msgHandleObject##Message -= delegate; } \
#define mitkNewMessageWithReturnMacro(msgHandleObject, returnType) \
private: ::mitk::Message<returnType> m_##msgHandleObject##Message; \
public: \
inline void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<returnType>& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
inline void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<returnType>& delegate) \
{ m_##msgHandleObject##Message -= delegate; } \
#define mitkNewMessage1Macro(msgHandleObject, type1) \
private: ::mitk::Message1< type1 > m_##msgHandleObject##Message; \
public: \
void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate1< type1 >& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate1< type1 >& delegate) \
{ m_##msgHandleObject##Message -= delegate; }
#define mitkNewMessage2Macro(msgHandleObject, type1, type2) \
private: ::mitk::Message2< type1, type2 > m_##msgHandleObject##Message; \
public: \
void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate2< type1, type2 >& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate2< type1, type2 >& delegate) \
{ m_##msgHandleObject##Message -= delegate; }
namespace mitk {
template<typename A = void>
class MessageAbstractDelegate
{
public:
virtual ~MessageAbstractDelegate()
{
}
virtual A Execute() const = 0;
virtual bool operator==(const MessageAbstractDelegate* cmd) const = 0;
virtual MessageAbstractDelegate* Clone() const = 0;
};
template <typename T, typename A = void>
class MessageAbstractDelegate1
{
public:
virtual ~MessageAbstractDelegate1()
{
}
virtual A Execute(T t) const = 0;
virtual bool operator==(const MessageAbstractDelegate1* cmd) const = 0;
virtual MessageAbstractDelegate1* Clone() const = 0;
};
template <typename T, typename U, typename A = void>
class MessageAbstractDelegate2
{
public:
virtual ~MessageAbstractDelegate2()
{
}
virtual A Execute(T t, U u) const = 0;
virtual bool operator==(const MessageAbstractDelegate2* cmd) const = 0;
virtual MessageAbstractDelegate2* Clone() const = 0;
};
template <typename T, typename U, typename V, typename A = void>
class MessageAbstractDelegate3
{
public:
virtual ~MessageAbstractDelegate3()
{
}
virtual A Execute(T t, U u, V v) const = 0;
virtual bool operator==(const MessageAbstractDelegate3* cmd) const = 0;
virtual MessageAbstractDelegate3* Clone() const = 0;
};
template <typename T, typename U, typename V, typename W, typename A = void>
class MessageAbstractDelegate4
{
public:
virtual ~MessageAbstractDelegate4()
{
}
virtual A Execute(T t, U u, V v, W w) const = 0;
virtual bool operator==(const MessageAbstractDelegate4* cmd) const = 0;
virtual MessageAbstractDelegate4* Clone() const = 0;
};
/**
* This class essentially wraps a function pointer with signature
* A(R::*function)(). A is the return type of your callback function
* and R the type of the class implementing the function.
*
* Use this class to add a callback function to
* messages without parameters.
*/
template <class R, typename A = void>
class MessageDelegate : public MessageAbstractDelegate<A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate(R* object, A(R::*memberFunctionPointer)())
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate()
{
}
// override function "Call"
virtual A Execute() const
{
return (m_Object->*m_MemberFunctionPointer)(); // execute member function
}
bool operator==(const MessageAbstractDelegate<A>* c) const
{
const MessageDelegate<R,A>* cmd = dynamic_cast<const MessageDelegate<R,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate<A>* Clone() const
{
return new MessageDelegate(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(); // pointer to member function
};
/**
* This class essentially wraps a function pointer with signature
* A(R::*function)(T). A is the return type of your callback function,
* R the type of the class implementing the function and T the type
* of the argument.
*
* Use this class to add a callback function to
* messages with one parameter.
*
* If you need more parameters, use MessageDelegate2 etc.
*/
template <class R, typename T, typename A = void>
class MessageDelegate1 : public MessageAbstractDelegate1<T,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate1(R* object, A(R::*memberFunctionPointer)(T))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate1()
{
}
// override function "Call"
virtual A Execute(T t) const
{
return (m_Object->*m_MemberFunctionPointer)(t); // execute member function
}
bool operator==(const MessageAbstractDelegate1<T,A>* c) const
{
const MessageDelegate1<R,T,A>* cmd = dynamic_cast<const MessageDelegate1<R,T,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate1<T,A>* Clone() const
{
return new MessageDelegate1(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T); // pointer to member function
};
template <class R, typename T, typename U, typename A = void>
class MessageDelegate2 : public MessageAbstractDelegate2<T,U,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate2(R* object, A(R::*memberFunctionPointer)(T, U))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate2()
{
}
// override function "Call"
virtual A Execute(T t, U u) const
{
return (m_Object->*m_MemberFunctionPointer)(t,u); // execute member function
}
bool operator==(const MessageAbstractDelegate2<T,U,A>* c) const
{
const MessageDelegate2<R,T,U,A>* cmd = dynamic_cast<const MessageDelegate2<R,T,U,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate2<T,U,A>* Clone() const
{
return new MessageDelegate2(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T, U); // pointer to member function
};
template <class R, typename T, typename U, typename V, typename A = void>
class MessageDelegate3 : public MessageAbstractDelegate3<T,U,V,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate3(R* object, A(R::*memberFunctionPointer)(T, U, V))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate3()
{
}
// override function "Call"
virtual A Execute(T t, U u, V v) const
{
return (m_Object->*m_MemberFunctionPointer)(t,u,v); // execute member function
}
bool operator==(const MessageAbstractDelegate3<T,U,V,A>* c) const
{
const MessageDelegate3<R,T,U,V,A>* cmd = dynamic_cast<const MessageDelegate3<R,T,U,V,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate3<T,U,V,A>* Clone() const
{
return new MessageDelegate3(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T, U, V); // pointer to member function
};
template <class R, typename T, typename U, typename V, typename W, typename A = void>
class MessageDelegate4 : public MessageAbstractDelegate4<T,U,V,W,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate4(R* object, A(R::*memberFunctionPointer)(T, U, V, W))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate4()
{
}
// override function "Call"
virtual A Execute(T t, U u, V v, W w) const
{
return (m_Object->*m_MemberFunctionPointer)(t,u,v,w); // execute member function
}
bool operator==(const MessageAbstractDelegate4<T,U,V,W,A>* c) const
{
const MessageDelegate4<R,T,U,V,W,A>* cmd = dynamic_cast<const MessageDelegate4<R,T,U,V,W,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate4<T,U,V,W,A>* Clone() const
{
return new MessageDelegate4(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T, U, V, W); // pointer to member function
};
template<typename AbstractDelegate>
class MessageBase
{
public:
typedef std::vector<AbstractDelegate* > ListenerList;
virtual ~MessageBase() {
for (typename ListenerList::iterator iter = m_Listeners.begin();
iter != m_Listeners.end(); ++iter )
{
delete *iter;
}
}
MessageBase() {}
MessageBase(const MessageBase& o)
{
for (typename ListenerList::iterator iter = o.m_Listeners.begin();
iter != o.m_Listeners.end(); ++iter )
{
m_Listeners.push_back((*iter)->Clone());
}
}
MessageBase& operator=(const MessageBase& o)
{
MessageBase tmp(o);
std::swap(tmp.m_Listeners, this->m_Listeners);
+ return *this;
}
void AddListener( const AbstractDelegate& delegate ) const
{
AbstractDelegate* msgCmd = delegate.Clone();
m_Mutex.Lock();
for (typename ListenerList::iterator iter = m_Listeners.begin();
iter != m_Listeners.end();
++iter )
{
if ((*iter)->operator==(msgCmd)) {
delete msgCmd;
m_Mutex.Unlock();
return;
}
}
m_Listeners.push_back(msgCmd);
m_Mutex.Unlock();
}
void operator += ( const AbstractDelegate& delegate ) const
{
this->AddListener(delegate);
}
void RemoveListener( const AbstractDelegate& delegate ) const
{
m_Mutex.Lock();
for (typename ListenerList::iterator iter = m_Listeners.begin();
iter != m_Listeners.end();
++iter )
{
if ((*iter)->operator==(&delegate))
{
delete *iter;
m_Listeners.erase( iter );
m_Mutex.Unlock();
return;
}
}
m_Mutex.Unlock();
}
void operator -= ( const AbstractDelegate& delegate) const
{
this->RemoveListener(delegate);
}
const ListenerList& GetListeners() const
{
return m_Listeners;
}
bool HasListeners() const
{
return !m_Listeners.empty();
}
bool IsEmpty() const
{
return m_Listeners.empty();
}
protected:
/**
* \brief List of listeners.
*
* This is declared mutable for a reason: Imagine an object that sends out notifications, e.g.
*
* \code
class Database {
public:
Message Modified;
};
* \endcode
*
* Now imaginge someone gets a <tt>const Database</tt> object, because he/she should not write to the
* database. He/she should anyway be able to register for notifications about changes in the database
* -- this is why AddListener and RemoveListener are declared <tt>const</tt>. m_Listeners must be
* mutable so that AddListener and RemoveListener can modify it regardless of the object's constness.
*/
mutable ListenerList m_Listeners;
mutable itk::SimpleFastMutexLock m_Mutex;
};
/**
* \brief Event/message/notification class.
*
* \sa mitk::BinaryThresholdTool
* \sa QmitkBinaryThresholdToolGUI
*
* This totally ITK, Qt, VTK, whatever toolkit independent class
* allows one class to send out messages and another class to
* receive these message. This class is templated over the
* return type (A) of the callback functions.
* There are variations of this class
* (Message1, Message2, etc.) for sending
* one, two or more parameters along with the messages.
*
* This is an implementation of the Observer pattern.
*
* \li There is no guarantee about the order of which observer is notified first. At the moment the observers which register first will be notified first.
* \li Notifications are <b>synchronous</b>, by direct method calls. There is no support for asynchronous messages.
*
* To conveniently add methods for registering/unregistering observers
* to Message variables of your class, you can use the mitkNewMessageMacro
* macros.
*
* Here is an example how to use the macros and templates:
*
* \code
*
* // An object to be send around
* class Law
* {
* private:
* std::string m_Description;
*
* public:
*
* Law(const std::string law) : m_Description(law)
* { }
*
* std::string GetDescription() const
* {
* return m_Description;
* }
* };
*
* // The NewtonMachine will issue specific events
* class NewtonMachine
* {
* mitkNewMessageMacro(AnalysisStarted);
* mitkNewMessage1Macro(AnalysisStopped, bool);
* mitkNewMessage1Macro(LawDiscovered, const Law&);
*
* public:
*
* void StartAnalysis()
* {
* // send the "started" signal
* m_AnalysisStartedMessage();
*
* // we found a new law of nature by creating one :-)
* Law massLaw("F=ma");
* m_LawDiscoveredMessage(massLaw);
* }
*
* void StopAnalysis()
* {
* // send the "stop" message with false, indicating
* // that no error occured
* m_AnalysisStoppedMessage(false);
* }
* };
*
* class Observer
* {
* private:
*
* NewtonMachine* m_Machine;
*
* public:
*
* Observer(NewtonMachine* machine) : m_Machine(machine)
* {
* // Add "observers", i.e. function pointers to the machine
* m_Machine->AddAnalysisStartedListener(
* ::mitk::MessageDelegate<Observer>(this, &Observer::MachineStarted));
* m_Machine->AddAnalysisStoppedListener(
* ::mitk::MessageDelegate1<Observer, bool>(this, &Observer::MachineStopped));
* m_Machine->AddLawDiscoveredListener(
* ::mitk::MessageDelegate1<Observer, const Law&>(this, &Observer::LawDiscovered));
* }
*
* ~Observer()
* {
* // Always remove your observers when finished
* m_Machine->RemoveAnalysisStartedListener(
* ::mitk::MessagDelegate<Observer>(this, &Observer::MachineStarted));
* m_Machine->RemoveAnalysisStoppedListener(
* ::mitk::MessageDelegate1<Observer, bool>(this, &Observer::MachineStopped));
* m_Machine->RemoveLawDiscoveredListener(
* ::mitk::MessageDelegate1<Observer, const Law&>(this, &Observer::LawDiscovered));
* }
*
* void MachineStarted()
* {
* std::cout << "Observed machine has started" << std::endl;
* }
*
* void MachineStopped(bool error)
* {
* std::cout << "Observed machine stopped " << (error ? "with an error" : "") << std::endl;
* }
*
* void LawDiscovered(const Law& law)
* {
* std::cout << "New law of nature discovered: " << law.GetDescription() << std::endl;
* }
* };
*
* NewtonMachine newtonMachine;
* Observer observer(&newtonMachine);
*
* // This will send two events to registered observers
* newtonMachine.StartAnalysis();
* // This will send one event to registered observers
* newtonMachine.StopAnalysis();
*
* \endcode
*
* Another example of how to use these message classes can be
* found in the directory Testing, file mitkMessageTest.cpp
*
*/
template<typename A = void>
class Message : public MessageBase< MessageAbstractDelegate<A> >
{
public:
typedef MessageBase< MessageAbstractDelegate<A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send()
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for (typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute();
}
}
void operator()()
{
this->Send();
}
};
// message with 1 parameter and return type
template <typename T, typename A = void>
class Message1 : public MessageBase< MessageAbstractDelegate1<T,A> >
{
public:
typedef MessageBase< MessageAbstractDelegate1<T,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t);
}
}
void operator()(T t)
{
this->Send(t);
}
};
// message with 2 parameters and return type
template <typename T, typename U, typename A = void>
class Message2 : public MessageBase< MessageAbstractDelegate2<T,U,A> >
{
public:
typedef MessageBase< MessageAbstractDelegate2<T,U,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t, U u)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t,u);
}
}
void operator()(T t, U u)
{
this->Send(t, u);
}
};
// message with 3 parameters and return type
template <typename T, typename U, typename V, typename A = void>
class Message3 : public MessageBase< MessageAbstractDelegate3<T,U,V,A> >
{
public:
typedef MessageBase< MessageAbstractDelegate3<T,U,V,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t, U u, V v)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t,u,v);
}
}
void operator()(T t, U u, V v)
{
this->Send(t, u, v);
}
};
// message with 4 parameters and return type
template <typename T, typename U, typename V, typename W, typename A = void>
class Message4 : public MessageBase< MessageAbstractDelegate4<T,U,V,W> >
{
public:
typedef MessageBase< MessageAbstractDelegate4<T,U,V,W,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t, U u, V v, W w)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t,u,v,w);
}
}
void operator()(T t, U u, V v, W w)
{
this->Send(t, u, v, w);
}
};
} // namespace
#endif
diff --git a/Core/Code/Rendering/mitkBaseRenderer.cpp b/Core/Code/Rendering/mitkBaseRenderer.cpp
index 493306c976..667358ad0e 100644
--- a/Core/Code/Rendering/mitkBaseRenderer.cpp
+++ b/Core/Code/Rendering/mitkBaseRenderer.cpp
@@ -1,876 +1,904 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkBaseRenderer.h"
#include "mitkMapper.h"
#include "mitkResliceMethodProperty.h"
#include "mitkKeyEvent.h"
// Geometries
#include "mitkPlaneGeometry.h"
#include "mitkSlicedGeometry3D.h"
// Controllers
#include "mitkCameraController.h"
#include "mitkSliceNavigationController.h"
#include "mitkCameraRotationController.h"
#include "mitkVtkInteractorCameraController.h"
#ifdef MITK_USE_TD_MOUSE
#include "mitkTDMouseVtkCameraController.h"
#else
#include "mitkCameraController.h"
#endif
#include "mitkVtkLayerController.h"
// Events // TODO: INTERACTION_LEGACY
#include "mitkEventMapper.h"
#include "mitkGlobalInteraction.h"
#include "mitkPositionEvent.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkProperties.h"
#include "mitkWeakPointerProperty.h"
#include "mitkInteractionConst.h"
#include "mitkOverlayManager.h"
// VTK
#include <vtkLinearTransform.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::baseRendererMap;
mitk::BaseRenderer* mitk::BaseRenderer::GetInstance(vtkRenderWindow * renWin)
{
for (BaseRendererMapType::iterator mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); mapit++)
{
if ((*mapit).first == renWin)
return (*mapit).second;
}
return NULL;
}
void mitk::BaseRenderer::AddInstance(vtkRenderWindow* renWin, BaseRenderer* baseRenderer)
{
if (renWin == NULL || baseRenderer == NULL)
return;
// ensure that no BaseRenderer is managed twice
mitk::BaseRenderer::RemoveInstance(renWin);
baseRendererMap.insert(BaseRendererMapType::value_type(renWin, baseRenderer));
}
void mitk::BaseRenderer::RemoveInstance(vtkRenderWindow* renWin)
{
BaseRendererMapType::iterator mapit = baseRendererMap.find(renWin);
if (mapit != baseRendererMap.end())
baseRendererMap.erase(mapit);
}
mitk::BaseRenderer* mitk::BaseRenderer::GetByName(const std::string& name)
{
for (BaseRendererMapType::iterator mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); mapit++)
{
if ((*mapit).second->m_Name == name)
return (*mapit).second;
}
return NULL;
}
vtkRenderWindow* mitk::BaseRenderer::GetRenderWindowByName(const std::string& name)
{
for (BaseRendererMapType::iterator mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); mapit++)
{
if ((*mapit).second->m_Name == name)
return (*mapit).first;
}
return NULL;
}
-mitk::BaseRenderer::BaseRenderer(const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm,RenderingMode::Type renderingMode) :
- m_RenderWindow(NULL), m_VtkRenderer(NULL), m_MapperID(defaultMapper), m_DataStorage(NULL), m_RenderingManager(rm), m_LastUpdateTime(0), m_CameraController(
- NULL), m_SliceNavigationController(NULL), m_CameraRotationController(NULL), /*m_Size(),*/
- m_Focused(false), m_WorldGeometry(NULL), m_WorldTimeGeometry(NULL), m_CurrentWorldGeometry(NULL), m_CurrentWorldPlaneGeometry(NULL), m_DisplayGeometry(
- NULL), m_Slice(0), m_TimeStep(), m_CurrentWorldPlaneGeometryUpdateTime(), m_DisplayGeometryUpdateTime(), m_TimeStepUpdateTime(), m_WorldGeometryData(
- NULL), m_DisplayGeometryData(NULL), m_CurrentWorldPlaneGeometryData(NULL), m_WorldGeometryNode(NULL), m_DisplayGeometryNode(NULL), m_CurrentWorldPlaneGeometryNode(
- NULL), m_DisplayGeometryTransformTime(0), m_CurrentWorldPlaneGeometryTransformTime(0), m_Name(name), /*m_Bounds(),*/m_EmptyWorldGeometry(
- true), m_NumberOfVisibleLODEnabledMappers(0)
+mitk::BaseRenderer::BaseRenderer(const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm,RenderingMode::Type renderingMode)
+ : m_RenderWindow(NULL)
+ , m_VtkRenderer(NULL)
+ , m_MapperID(defaultMapper)
+ , m_DataStorage(NULL)
+ , m_RenderingManager(rm)
+ , m_LastUpdateTime(0)
+ , m_CameraController(NULL)
+ , m_SliceNavigationController(NULL)
+ , m_CameraRotationController(NULL)
+ /*, m_Size()*/
+ , m_Focused(false)
+ , m_WorldGeometry(NULL)
+ , m_WorldTimeGeometry(NULL)
+ , m_CurrentWorldGeometry(NULL)
+ , m_CurrentWorldPlaneGeometry(NULL)
+ , m_DisplayGeometry(NULL)
+ , m_Slice(0)
+ , m_TimeStep()
+ , m_CurrentWorldPlaneGeometryUpdateTime()
+ , m_DisplayGeometryUpdateTime()
+ , m_TimeStepUpdateTime()
+ , m_KeepDisplayedRegion(true)
+ , m_WorldGeometryData(NULL)
+ , m_DisplayGeometryData(NULL)
+ , m_CurrentWorldPlaneGeometryData(NULL)
+ , m_WorldGeometryNode(NULL)
+ , m_DisplayGeometryNode(NULL)
+ , m_CurrentWorldPlaneGeometryNode(NULL)
+ , m_DisplayGeometryTransformTime(0)
+ , m_CurrentWorldPlaneGeometryTransformTime(0)
+ , m_Name(name)
+ /*, m_Bounds()*/
+ , m_EmptyWorldGeometry(true)
+ , m_NumberOfVisibleLODEnabledMappers(0)
{
m_Bounds[0] = 0;
m_Bounds[1] = 0;
m_Bounds[2] = 0;
m_Bounds[3] = 0;
m_Bounds[4] = 0;
m_Bounds[5] = 0;
if (name != NULL)
{
m_Name = name;
}
else
{
m_Name = "unnamed renderer";
itkWarningMacro(<< "Created unnamed renderer. Bad for serialization. Please choose a name.");
}
if (renWin != NULL)
{
m_RenderWindow = renWin;
m_RenderWindow->Register(NULL);
}
else
{
itkWarningMacro(<< "Created mitkBaseRenderer without vtkRenderWindow present.");
}
m_Size[0] = 0;
m_Size[1] = 0;
//instances.insert( this );
//adding this BaseRenderer to the List of all BaseRenderer
// TODO: INTERACTION_LEGACY
m_RenderingManager->GetGlobalInteraction()->AddFocusElement(this);
m_BindDispatcherInteractor = new mitk::BindDispatcherInteractor( GetName() );
WeakPointerProperty::Pointer rendererProp = WeakPointerProperty::New((itk::Object*) this);
m_CurrentWorldPlaneGeometry = mitk::PlaneGeometry::New();
m_CurrentWorldPlaneGeometryData = mitk::PlaneGeometryData::New();
m_CurrentWorldPlaneGeometryData->SetPlaneGeometry(m_CurrentWorldPlaneGeometry);
m_CurrentWorldPlaneGeometryNode = mitk::DataNode::New();
m_CurrentWorldPlaneGeometryNode->SetData(m_CurrentWorldPlaneGeometryData);
m_CurrentWorldPlaneGeometryNode->GetPropertyList()->SetProperty("renderer", rendererProp);
m_CurrentWorldPlaneGeometryNode->GetPropertyList()->SetProperty("layer", IntProperty::New(1000));
m_CurrentWorldPlaneGeometryNode->SetProperty("reslice.thickslices", mitk::ResliceMethodProperty::New());
m_CurrentWorldPlaneGeometryNode->SetProperty("reslice.thickslices.num", mitk::IntProperty::New(1));
m_CurrentWorldPlaneGeometryTransformTime = m_CurrentWorldPlaneGeometryNode->GetVtkTransform()->GetMTime();
m_DisplayGeometry = mitk::DisplayGeometry::New();
m_DisplayGeometry->SetWorldGeometry(m_CurrentWorldPlaneGeometry);
m_DisplayGeometryData = mitk::PlaneGeometryData::New();
m_DisplayGeometryData->SetPlaneGeometry(m_DisplayGeometry);
m_DisplayGeometryNode = mitk::DataNode::New();
m_DisplayGeometryNode->SetData(m_DisplayGeometryData);
m_DisplayGeometryNode->GetPropertyList()->SetProperty("renderer", rendererProp);
m_DisplayGeometryTransformTime = m_DisplayGeometryNode->GetVtkTransform()->GetMTime();
mitk::SliceNavigationController::Pointer sliceNavigationController = mitk::SliceNavigationController::New("navigation");
sliceNavigationController->SetRenderer(this);
sliceNavigationController->ConnectGeometrySliceEvent(this);
sliceNavigationController->ConnectGeometryUpdateEvent(this);
sliceNavigationController->ConnectGeometryTimeEvent(this, false);
m_SliceNavigationController = sliceNavigationController;
m_CameraRotationController = mitk::CameraRotationController::New();
m_CameraRotationController->SetRenderWindow(m_RenderWindow);
m_CameraRotationController->AcquireCamera();
//if TD Mouse Interaction is activated, then call TDMouseVtkCameraController instead of VtkInteractorCameraController
#ifdef MITK_USE_TD_MOUSE
m_CameraController = mitk::TDMouseVtkCameraController::New();
#else
m_CameraController = mitk::CameraController::New(NULL);
#endif
m_VtkRenderer = vtkRenderer::New();
if( renderingMode == RenderingMode::DepthPeeling )
{
m_VtkRenderer->SetUseDepthPeeling(1);
m_VtkRenderer->SetMaximumNumberOfPeels(8);
m_VtkRenderer->SetOcclusionRatio(0.0);
}
if (mitk::VtkLayerController::GetInstance(m_RenderWindow) == NULL)
{
mitk::VtkLayerController::AddInstance(m_RenderWindow, m_VtkRenderer);
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer);
}
else
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer);
}
mitk::BaseRenderer::~BaseRenderer()
{
if (m_OverlayManager.IsNotNull())
{
m_OverlayManager->RemoveBaseRenderer(this);
}
if (m_VtkRenderer != NULL)
{
m_VtkRenderer->Delete();
m_VtkRenderer = NULL;
}
if (m_CameraController.IsNotNull())
m_CameraController->SetRenderer(NULL);
m_RenderingManager->GetGlobalInteraction()->RemoveFocusElement(this);
mitk::VtkLayerController::RemoveInstance(m_RenderWindow);
RemoveAllLocalStorages();
m_DataStorage = NULL;
if (m_BindDispatcherInteractor != NULL)
{
delete m_BindDispatcherInteractor;
}
if (m_RenderWindow != NULL)
{
m_RenderWindow->Delete();
m_RenderWindow = NULL;
}
+
}
void mitk::BaseRenderer::RemoveAllLocalStorages()
{
this->InvokeEvent(mitk::BaseRenderer::RendererResetEvent());
std::list<mitk::BaseLocalStorageHandler*>::iterator it;
for (it = m_RegisteredLocalStorageHandlers.begin(); it != m_RegisteredLocalStorageHandlers.end(); it++)
(*it)->ClearLocalStorage(this, false);
m_RegisteredLocalStorageHandlers.clear();
}
void mitk::BaseRenderer::RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh)
{
m_RegisteredLocalStorageHandlers.push_back(lsh);
}
mitk::Dispatcher::Pointer mitk::BaseRenderer::GetDispatcher() const
{
return m_BindDispatcherInteractor->GetDispatcher();
}
mitk::Point3D mitk::BaseRenderer::Map2DRendererPositionTo3DWorldPosition(const Point2D& mousePosition) const
{
Point2D p_mm;
Point3D position;
-
if (m_MapperID == 1)
{
GetDisplayGeometry()->DisplayToWorld(mousePosition, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
}
else if (m_MapperID == 2)
{
PickWorldPoint(mousePosition, position);
}
return position;
}
void mitk::BaseRenderer::UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh)
{
m_RegisteredLocalStorageHandlers.remove(lsh);
}
void mitk::BaseRenderer::SetDataStorage(DataStorage* storage)
{
if (storage != NULL)
{
m_DataStorage = storage;
m_BindDispatcherInteractor->SetDataStorage(m_DataStorage);
this->Modified();
}
}
const mitk::BaseRenderer::MapperSlotId mitk::BaseRenderer::defaultMapper = 1;
void mitk::BaseRenderer::Paint()
{
}
void mitk::BaseRenderer::Initialize()
{
}
void mitk::BaseRenderer::Resize(int w, int h)
{
m_Size[0] = w;
m_Size[1] = h;
if (m_CameraController)
m_CameraController->Resize(w, h); //(formerly problematic on windows: vtkSizeBug)
- GetDisplayGeometry()->SetSizeInDisplayUnits(w, h);
+ GetDisplayGeometry()->SetSizeInDisplayUnits(w, h, m_KeepDisplayedRegion);
}
void mitk::BaseRenderer::InitRenderer(vtkRenderWindow* renderwindow)
{
if (m_RenderWindow != NULL)
{
m_RenderWindow->Delete();
}
m_RenderWindow = renderwindow;
if (m_RenderWindow != NULL)
{
m_RenderWindow->Register(NULL);
}
RemoveAllLocalStorages();
if (m_CameraController.IsNotNull())
{
m_CameraController->SetRenderer(this);
}
+
}
void mitk::BaseRenderer::InitSize(int w, int h)
{
m_Size[0] = w;
m_Size[1] = h;
GetDisplayGeometry()->SetSizeInDisplayUnits(w, h, false);
GetDisplayGeometry()->Fit();
}
void mitk::BaseRenderer::SetSlice(unsigned int slice)
{
if (m_Slice != slice)
{
m_Slice = slice;
if (m_WorldTimeGeometry.IsNotNull())
{
SlicedGeometry3D* slicedWorldGeometry = dynamic_cast<SlicedGeometry3D*>(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer());
if (slicedWorldGeometry != NULL)
{
if (m_Slice >= slicedWorldGeometry->GetSlices())
m_Slice = slicedWorldGeometry->GetSlices() - 1;
SetCurrentWorldPlaneGeometry(slicedWorldGeometry->GetPlaneGeometry(m_Slice));
SetCurrentWorldGeometry(slicedWorldGeometry);
}
}
else
Modified();
}
}
void mitk::BaseRenderer::SetOverlayManager(itk::SmartPointer<OverlayManager> overlayManager)
{
if(overlayManager.IsNull())
return;
if(this->m_OverlayManager.IsNotNull())
{
if(this->m_OverlayManager.GetPointer() == overlayManager.GetPointer())
{
return;
}
else
{
this->m_OverlayManager->RemoveBaseRenderer(this);
}
}
this->m_OverlayManager = overlayManager;
this->m_OverlayManager->AddBaseRenderer(this); //TODO
}
itk::SmartPointer<mitk::OverlayManager> mitk::BaseRenderer::GetOverlayManager()
{
if(this->m_OverlayManager.IsNull())
{
m_OverlayManager = mitk::OverlayManager::New();
m_OverlayManager->AddBaseRenderer(this);
}
return this->m_OverlayManager;
}
void mitk::BaseRenderer::SetTimeStep(unsigned int timeStep)
{
if (m_TimeStep != timeStep)
{
m_TimeStep = timeStep;
m_TimeStepUpdateTime.Modified();
if (m_WorldTimeGeometry.IsNotNull())
{
if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps())
m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1;
SlicedGeometry3D* slicedWorldGeometry = dynamic_cast<SlicedGeometry3D*>(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer());
if (slicedWorldGeometry != NULL)
{
SetCurrentWorldPlaneGeometry(slicedWorldGeometry->GetPlaneGeometry(m_Slice));
SetCurrentWorldGeometry(slicedWorldGeometry);
}
}
else
Modified();
}
}
int mitk::BaseRenderer::GetTimeStep(const mitk::BaseData* data) const
{
if ((data == NULL) || (data->IsInitialized() == false))
{
return -1;
}
return data->GetTimeGeometry()->TimePointToTimeStep(GetTime());
}
mitk::ScalarType mitk::BaseRenderer::GetTime() const
{
if (m_WorldTimeGeometry.IsNull())
{
return 0;
}
else
{
ScalarType timeInMS = m_WorldTimeGeometry->TimeStepToTimePoint(GetTimeStep());
if (timeInMS == itk::NumericTraits<mitk::ScalarType>::NonpositiveMin())
return 0;
else
return timeInMS;
}
}
void mitk::BaseRenderer::SetWorldTimeGeometry(mitk::TimeGeometry* geometry)
{
assert(geometry != NULL);
itkDebugMacro("setting WorldTimeGeometry to " << geometry);
if (m_WorldTimeGeometry != geometry)
{
if (geometry->GetBoundingBoxInWorld()->GetDiagonalLength2() == 0)
return;
m_WorldTimeGeometry = geometry;
itkDebugMacro("setting WorldTimeGeometry to " << m_WorldTimeGeometry);
if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps())
m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1;
BaseGeometry* geometry3d;
geometry3d = m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep);
SetWorldGeometry3D(geometry3d);
}
}
void mitk::BaseRenderer::SetWorldGeometry3D(mitk::BaseGeometry* geometry)
{
itkDebugMacro("setting WorldGeometry3D to " << geometry);
if (m_WorldGeometry != geometry)
{
if (geometry->GetBoundingBox()->GetDiagonalLength2() == 0)
return;
m_WorldGeometry = geometry;
SlicedGeometry3D* slicedWorldGeometry;
slicedWorldGeometry = dynamic_cast<SlicedGeometry3D*>(geometry);
PlaneGeometry::Pointer geometry2d;
if (slicedWorldGeometry != NULL)
{
if (m_Slice >= slicedWorldGeometry->GetSlices() && (m_Slice != 0))
m_Slice = slicedWorldGeometry->GetSlices() - 1;
geometry2d = slicedWorldGeometry->GetPlaneGeometry(m_Slice);
if (geometry2d.IsNull())
{
PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
plane->InitializeStandardPlane(slicedWorldGeometry);
geometry2d = plane;
}
SetCurrentWorldGeometry(slicedWorldGeometry);
}
else
{
geometry2d = dynamic_cast<PlaneGeometry*>(geometry);
if (geometry2d.IsNull())
{
PlaneGeometry::Pointer plane = PlaneGeometry::New();
plane->InitializeStandardPlane(geometry);
geometry2d = plane;
}
SetCurrentWorldGeometry(geometry);
}
SetCurrentWorldPlaneGeometry(geometry2d); // calls Modified()
}
if (m_CurrentWorldPlaneGeometry.IsNull())
itkWarningMacro("m_CurrentWorldPlaneGeometry is NULL");
}
void mitk::BaseRenderer::SetDisplayGeometry(mitk::DisplayGeometry* geometry2d)
{
itkDebugMacro("setting DisplayGeometry to " << geometry2d);
if (m_DisplayGeometry != geometry2d)
{
m_DisplayGeometry = geometry2d;
m_DisplayGeometryData->SetPlaneGeometry(m_DisplayGeometry);
m_DisplayGeometryUpdateTime.Modified();
Modified();
}
}
void mitk::BaseRenderer::SetCurrentWorldPlaneGeometry(mitk::PlaneGeometry* geometry2d)
{
if (m_CurrentWorldPlaneGeometry != geometry2d)
{
m_CurrentWorldPlaneGeometry = geometry2d;
m_CurrentWorldPlaneGeometryData->SetPlaneGeometry(m_CurrentWorldPlaneGeometry);
m_DisplayGeometry->SetWorldGeometry(m_CurrentWorldPlaneGeometry);
m_CurrentWorldPlaneGeometryUpdateTime.Modified();
Modified();
}
}
void mitk::BaseRenderer::SendUpdateSlice()
{
m_DisplayGeometryUpdateTime.Modified();
m_CurrentWorldPlaneGeometryUpdateTime.Modified();
}
void mitk::BaseRenderer::SetCurrentWorldGeometry(mitk::BaseGeometry* geometry)
{
m_CurrentWorldGeometry = geometry;
if (geometry == NULL)
{
m_Bounds[0] = 0;
m_Bounds[1] = 0;
m_Bounds[2] = 0;
m_Bounds[3] = 0;
m_Bounds[4] = 0;
m_Bounds[5] = 0;
m_EmptyWorldGeometry = true;
return;
}
BoundingBox::Pointer boundingBox = m_CurrentWorldGeometry->CalculateBoundingBoxRelativeToTransform(NULL);
const BoundingBox::BoundsArrayType& worldBounds = boundingBox->GetBounds();
m_Bounds[0] = worldBounds[0];
m_Bounds[1] = worldBounds[1];
m_Bounds[2] = worldBounds[2];
m_Bounds[3] = worldBounds[3];
m_Bounds[4] = worldBounds[4];
m_Bounds[5] = worldBounds[5];
if (boundingBox->GetDiagonalLength2() <= mitk::eps)
m_EmptyWorldGeometry = true;
else
m_EmptyWorldGeometry = false;
}
void mitk::BaseRenderer::UpdateOverlays()
{
if(m_OverlayManager.IsNotNull())
{
m_OverlayManager->UpdateOverlays(this);
}
}
void mitk::BaseRenderer::SetGeometry(const itk::EventObject & geometrySendEvent)
{
const SliceNavigationController::GeometrySendEvent* sendEvent =
dynamic_cast<const SliceNavigationController::GeometrySendEvent *>(&geometrySendEvent);
assert(sendEvent!=NULL);
SetWorldTimeGeometry(sendEvent->GetTimeGeometry());
}
void mitk::BaseRenderer::UpdateGeometry(const itk::EventObject & geometryUpdateEvent)
{
const SliceNavigationController::GeometryUpdateEvent* updateEvent =
dynamic_cast<const SliceNavigationController::GeometryUpdateEvent*>(&geometryUpdateEvent);
if (updateEvent == NULL)
return;
if (m_CurrentWorldGeometry.IsNotNull())
{
SlicedGeometry3D* slicedWorldGeometry = dynamic_cast<SlicedGeometry3D*>(m_CurrentWorldGeometry.GetPointer());
if (slicedWorldGeometry)
{
PlaneGeometry* geometry2D = slicedWorldGeometry->GetPlaneGeometry(m_Slice);
SetCurrentWorldPlaneGeometry(geometry2D); // calls Modified()
}
}
}
void mitk::BaseRenderer::SetGeometrySlice(const itk::EventObject & geometrySliceEvent)
{
const SliceNavigationController::GeometrySliceEvent* sliceEvent =
dynamic_cast<const SliceNavigationController::GeometrySliceEvent *>(&geometrySliceEvent);
assert(sliceEvent!=NULL);
SetSlice(sliceEvent->GetPos());
}
void mitk::BaseRenderer::SetGeometryTime(const itk::EventObject & geometryTimeEvent)
{
const SliceNavigationController::GeometryTimeEvent * timeEvent =
dynamic_cast<const SliceNavigationController::GeometryTimeEvent *>(&geometryTimeEvent);
assert(timeEvent!=NULL);
SetTimeStep(timeEvent->GetPos());
}
const double* mitk::BaseRenderer::GetBounds() const
{
return m_Bounds;
}
void mitk::BaseRenderer::MousePressEvent(mitk::MouseEvent *me)
{
//set the Focus on the renderer
/*bool success =*/m_RenderingManager->GetGlobalInteraction()->SetFocus(this);
/*
if (! success)
mitk::StatusBar::GetInstance()->DisplayText("Warning! from mitkBaseRenderer.cpp: Couldn't focus this BaseRenderer!");
*/
//if (m_CameraController)
//{
// if(me->GetButtonState()!=512) // provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine
// m_CameraController->MousePressEvent(me);
//}
if (m_MapperID == 1)
{
Point2D p(me->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction());
}
else if (m_MapperID > 1) //==2 for 3D and ==5 for stencil
{
Point2D p(me->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
me->SetDisplayPosition(p);
mitk::EventMapper::MapEvent(me, m_RenderingManager->GetGlobalInteraction());
}
}
void mitk::BaseRenderer::MouseReleaseEvent(mitk::MouseEvent *me)
{
//if (m_CameraController)
//{
// if(me->GetButtonState()!=512) // provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine
// m_CameraController->MouseReleaseEvent(me);
//}
if (m_MapperID == 1)
{
Point2D p(me->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction());
}
else if (m_MapperID == 2)
{
Point2D p(me->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
me->SetDisplayPosition(p);
mitk::EventMapper::MapEvent(me, m_RenderingManager->GetGlobalInteraction());
}
}
void mitk::BaseRenderer::MouseMoveEvent(mitk::MouseEvent *me)
{
//if (m_CameraController)
//{
// if((me->GetButtonState()<=512) || (me->GetButtonState()>=516))// provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine
// m_CameraController->MouseMoveEvent(me);
//}
if (m_MapperID == 1)
{
Point2D p(me->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction());
}
else if (m_MapperID == 2)
{
Point2D p(me->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
me->SetDisplayPosition(p);
mitk::EventMapper::MapEvent(me, m_RenderingManager->GetGlobalInteraction());
}
}
void mitk::BaseRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const
{
mitk::Point2D worldPoint2D;
GetDisplayGeometry()->DisplayToWorld(displayPoint, worldPoint2D);
GetDisplayGeometry()->Map(worldPoint2D, worldPoint);
}
void mitk::BaseRenderer::WheelEvent(mitk::WheelEvent * we)
{
if (m_MapperID == 1)
{
Point2D p(we->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, we->GetType(), we->GetButton(), we->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent(we, m_RenderingManager->GetGlobalInteraction());
mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction());
}
else if (m_MapperID == 2)
{
Point2D p(we->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
we->SetDisplayPosition(p);
mitk::EventMapper::MapEvent(we, m_RenderingManager->GetGlobalInteraction());
}
}
void mitk::BaseRenderer::KeyPressEvent(mitk::KeyEvent *ke)
{
if (m_MapperID == 1)
{
Point2D p(ke->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::KeyEvent event(this, ke->GetType(), ke->GetButton(), ke->GetButtonState(), ke->GetKey(), ke->GetText(), p);
mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction());
}
else if (m_MapperID == 2)
{
Point2D p(ke->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p, p);
ke->SetDisplayPosition(p);
mitk::EventMapper::MapEvent(ke, m_RenderingManager->GetGlobalInteraction());
}
}
void mitk::BaseRenderer::DrawOverlayMouse(mitk::Point2D& itkNotUsed(p2d))
{
MITK_INFO<<"BaseRenderer::DrawOverlayMouse()- should be inconcret implementation OpenGLRenderer."<<std::endl;
}
void mitk::BaseRenderer::RequestUpdate()
{
m_RenderingManager->RequestUpdate(this->m_RenderWindow);
}
void mitk::BaseRenderer::ForceImmediateUpdate()
{
m_RenderingManager->ForceImmediateUpdate(this->m_RenderWindow);
}
unsigned int mitk::BaseRenderer::GetNumberOfVisibleLODEnabledMappers() const
{
return m_NumberOfVisibleLODEnabledMappers;
}
mitk::RenderingManager* mitk::BaseRenderer::GetRenderingManager() const
{
return m_RenderingManager.GetPointer();
}
/*!
Sets the new Navigation controller
*/
void mitk::BaseRenderer::SetSliceNavigationController(mitk::SliceNavigationController *SlicenavigationController)
{
if (SlicenavigationController == NULL)
return;
//disconnect old from globalinteraction
m_RenderingManager->GetGlobalInteraction()->RemoveListener(SlicenavigationController);
//copy worldgeometry
SlicenavigationController->SetInputWorldTimeGeometry(SlicenavigationController->GetCreatedWorldGeometry());
SlicenavigationController->Update();
//set new
m_SliceNavigationController = SlicenavigationController;
m_SliceNavigationController->SetRenderer(this);
if (m_SliceNavigationController.IsNotNull())
{
m_SliceNavigationController->ConnectGeometrySliceEvent(this);
m_SliceNavigationController->ConnectGeometryUpdateEvent(this);
m_SliceNavigationController->ConnectGeometryTimeEvent(this, false);
}
}
/*!
Sets the new camera controller and deletes the vtkRenderWindowInteractor in case of the VTKInteractorCameraController
*/
void mitk::BaseRenderer::SetCameraController(CameraController* cameraController)
{
mitk::VtkInteractorCameraController::Pointer vtkInteractorCameraController =
dynamic_cast<mitk::VtkInteractorCameraController*>(cameraController);
if (vtkInteractorCameraController.IsNotNull())
MITK_INFO<<"!!!WARNING!!!: RenderWindow interaction events are no longer handled via CameraController (See Bug #954)."<<std::endl;
m_CameraController->SetRenderer(NULL);
m_CameraController = NULL;
m_CameraController = cameraController;
m_CameraController->SetRenderer(this);
}
void mitk::BaseRenderer::PrintSelf(std::ostream& os, itk::Indent indent) const
{
os << indent << " MapperID: " << m_MapperID << std::endl;
os << indent << " Slice: " << m_Slice << std::endl;
os << indent << " TimeStep: " << m_TimeStep << std::endl;
os << indent << " WorldGeometry: ";
if (m_WorldGeometry.IsNull())
os << "NULL" << std::endl;
else
m_WorldGeometry->Print(os, indent);
os << indent << " CurrentWorldPlaneGeometry: ";
if (m_CurrentWorldPlaneGeometry.IsNull())
os << "NULL" << std::endl;
else
m_CurrentWorldPlaneGeometry->Print(os, indent);
os << indent << " CurrentWorldPlaneGeometryUpdateTime: " << m_CurrentWorldPlaneGeometryUpdateTime << std::endl;
os << indent << " CurrentWorldPlaneGeometryTransformTime: " << m_CurrentWorldPlaneGeometryTransformTime << std::endl;
os << indent << " DisplayGeometry: ";
if (m_DisplayGeometry.IsNull())
os << "NULL" << std::endl;
else
m_DisplayGeometry->Print(os, indent);
os << indent << " DisplayGeometryTransformTime: " << m_DisplayGeometryTransformTime << std::endl;
Superclass::PrintSelf(os, indent);
}
diff --git a/Core/Code/Rendering/mitkBaseRenderer.h b/Core/Code/Rendering/mitkBaseRenderer.h
index d12156613e..67b5814c5b 100644
--- a/Core/Code/Rendering/mitkBaseRenderer.h
+++ b/Core/Code/Rendering/mitkBaseRenderer.h
@@ -1,663 +1,674 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
#define BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
#include "mitkDataStorage.h"
#include "mitkPlaneGeometry.h"
#include "mitkTimeGeometry.h"
#include "mitkDisplayGeometry.h"
#include "mitkPlaneGeometryData.h"
#include "mitkCameraController.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkWheelEvent.h"
//#include "mitkMapper.h"
#include "mitkSliceNavigationController.h"
#include "mitkCameraController.h"
#include "mitkCameraRotationController.h"
#include "mitkBindDispatcherInteractor.h"
#include "mitkDispatcher.h"
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <map>
#include <set>
// DEPRECATED
#include <mitkTimeSlicedGeometry.h>
namespace mitk
{
class NavigationController;
class SliceNavigationController;
class CameraRotationController;
class CameraController;
class DataStorage;
class Mapper;
class BaseLocalStorageHandler;
class OverlayManager;
//##Documentation
//## @brief Organizes the rendering process
//##
//## Organizes the rendering process. A Renderer contains a reference to a
//## DataStorage and asks the mappers of the data objects to render
//## the data into the renderwindow it is associated to.
//##
//## \#Render() checks if rendering is currently allowed by calling
//## RenderWindow::PrepareRendering(). Initialization of a rendering context
//## can also be performed in this method.
//##
//## The actual rendering code has been moved to \#Repaint()
//## Both \#Repaint() and \#Update() are declared protected now.
//##
//## Note: Separation of the Repaint and Update processes (rendering vs
//## creating a vtk prop tree) still needs to be worked on. The whole
//## rendering process also should be reworked to use VTK based classes for
//## both 2D and 3D rendering.
//## @ingroup Renderer
class MITK_CORE_EXPORT BaseRenderer: public itk::Object
{
public:
/** \brief This rendering mode enumeration is specified at various constructors
* of the Renderer and RenderWindow classes, which autoconfigures the
* respective VTK objects. This has to be done at construction time because later
* configuring turns out to be not working on most platforms.
*/
struct RenderingMode
{
enum Type {
Standard = 0, // no multi-sampling, no depth-peeling
MultiSampling, // multi-sampling (antialiasing), no depth-peeling
DepthPeeling // no multi-sampling, depth-peeling is on (order-independant transparency)
};
};
typedef std::map<vtkRenderWindow*, BaseRenderer*> BaseRendererMapType;
static BaseRendererMapType baseRendererMap;
static BaseRenderer* GetInstance(vtkRenderWindow * renWin);
static void AddInstance(vtkRenderWindow* renWin, BaseRenderer* baseRenderer);
static void RemoveInstance(vtkRenderWindow* renWin);
static BaseRenderer* GetByName(const std::string& name);
static vtkRenderWindow* GetRenderWindowByName(const std::string& name);
#pragma GCC visibility push(default)
itkEventMacro( RendererResetEvent, itk::AnyEvent );
#pragma GCC visibility pop
/** Standard class typedefs. */
mitkClassMacro(BaseRenderer, itk::Object);
BaseRenderer(const char* name = NULL, vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm = NULL,RenderingMode::Type mode = RenderingMode::Standard);
//##Documentation
//## @brief MapperSlotId defines which kind of mapper (e.g., 2D or 3D) shoud be used.
typedef int MapperSlotId;
enum StandardMapperSlot
{
Standard2D = 1, Standard3D = 2
};
virtual void SetDataStorage(DataStorage* storage); ///< set the datastorage that will be used for rendering
//##Documentation
//## return the DataStorage that is used for rendering
virtual DataStorage::Pointer GetDataStorage() const
{
return m_DataStorage.GetPointer();
}
//##Documentation
//## @brief Access the RenderWindow into which this renderer renders.
vtkRenderWindow* GetRenderWindow() const
{
return m_RenderWindow;
}
vtkRenderer* GetVtkRenderer() const
{
return m_VtkRenderer;
}
//##Documentation
//## @brief Returns the Dispatcher which handles Events for this BaseRenderer
Dispatcher::Pointer GetDispatcher() const;
//##Documentation
//## @brief Default mapper id to use.
static const MapperSlotId defaultMapper;
//##Documentation
//## @brief Do the rendering and flush the result.
virtual void Paint();
//##Documentation
//## @brief Initialize the RenderWindow. Should only be called from RenderWindow.
virtual void Initialize();
//##Documentation
//## @brief Called to inform the renderer that the RenderWindow has been resized.
virtual void Resize(int w, int h);
//##Documentation
//## @brief Initialize the renderer with a RenderWindow (@a renderwindow).
virtual void InitRenderer(vtkRenderWindow* renderwindow);
//##Documentation
//## @brief Set the initial size. Called by RenderWindow after it has become
//## visible for the first time.
virtual void InitSize(int w, int h);
//##Documentation
//## @brief Draws a point on the widget.
//## Should be used during conferences to show the position of the remote mouse
virtual void DrawOverlayMouse(Point2D& p2d);
//##Documentation
//## @brief Set/Get the WorldGeometry (m_WorldGeometry) for 3D and 2D rendering, that describing the
//## (maximal) area to be rendered.
//##
//## Depending of the type of the passed BaseGeometry more or less information can be extracted:
//## \li if it is a PlaneGeometry (which is a sub-class of BaseGeometry), m_CurrentWorldPlaneGeometry is
//## also set to point to it. m_WorldTimeGeometry is set to NULL.
//## \li if it is a TimeGeometry, m_WorldTimeGeometry is also set to point to it.
//## If m_WorldTimeGeometry contains instances of SlicedGeometry3D, m_CurrentWorldPlaneGeometry is set to
//## one of geometries stored in the SlicedGeometry3D according to the value of m_Slice; otherwise
//## a PlaneGeometry describing the top of the bounding-box of the BaseGeometry is set as the
//## m_CurrentWorldPlaneGeometry.
//## \li otherwise a PlaneGeometry describing the top of the bounding-box of the BaseGeometry
//## is set as the m_CurrentWorldPlaneGeometry. m_WorldTimeGeometry is set to NULL.
//## @todo add calculation of PlaneGeometry describing the top of the bounding-box of the BaseGeometry
//## when the passed BaseGeometry is not sliced.
//## \sa m_WorldGeometry
//## \sa m_WorldTimeGeometry
//## \sa m_CurrentWorldPlaneGeometry
virtual void SetWorldGeometry3D(BaseGeometry* geometry);
virtual void SetWorldTimeGeometry(mitk::TimeGeometry* geometry);
/**
* \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
*/
DEPRECATED(void SetWorldGeometry3D(TimeSlicedGeometry* geometry));
itkGetConstObjectMacro(WorldGeometry, BaseGeometry)
itkGetObjectMacro(WorldGeometry, BaseGeometry)
itkGetConstObjectMacro(WorldTimeGeometry, TimeGeometry)
itkGetObjectMacro(WorldTimeGeometry, TimeGeometry)
//##Documentation
//## @brief Get the current 3D-worldgeometry (m_CurrentWorldGeometry) used for 3D-rendering
itkGetConstObjectMacro(CurrentWorldGeometry, BaseGeometry)
//##Documentation
//## @brief Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering
itkGetConstObjectMacro(CurrentWorldPlaneGeometry, PlaneGeometry)
/**
* \deprecatedSince{2014_06} Please use GetCurrentWorldPlaneGeometry
*/
DEPRECATED(const PlaneGeometry* GetCurrentWorldGeometry2D()){return GetCurrentWorldPlaneGeometry();};
//##Documentation
//## Calculates the bounds of the DataStorage (if it contains any valid data),
//## creates a geometry from these bounds and sets it as world geometry of the renderer.
//##
//## Call this method to re-initialize the renderer to the current DataStorage
//## (e.g. after loading an additional dataset), to ensure that the view is
//## aligned correctly.
//## \warn This is not implemented yet.
virtual bool SetWorldGeometryToDataStorageBounds()
{
return false;
}
//##Documentation
//## @brief Set/Get the DisplayGeometry (for 2D rendering)
//##
//## The DisplayGeometry describes which part of the PlaneGeometry m_CurrentWorldPlaneGeometry
//## is displayed.
virtual void SetDisplayGeometry(DisplayGeometry* geometry2d);
itkGetConstObjectMacro(DisplayGeometry, DisplayGeometry)
itkGetObjectMacro(DisplayGeometry, DisplayGeometry)
//##Documentation
//## @brief Set/Get m_Slice which defines together with m_TimeStep the 2D geometry
//## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry
//##
//## \sa m_Slice
virtual void SetSlice(unsigned int slice);
//##Documentation
//## @brief Sets an OverlayManager which is used to add various Overlays to this
//## renderer. If an OverlayManager was already set it will be overwritten.
void SetOverlayManager(itk::SmartPointer<OverlayManager> overlayManager);
//##Documentation
//## @brief Get the OverlayManager registered with this renderer
//## if none was set, it will be created at this point.
itk::SmartPointer<OverlayManager> GetOverlayManager();
itkGetConstMacro(Slice, unsigned int)
//##Documentation
//## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry
//## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry
//##
//## \sa m_TimeStep
virtual void SetTimeStep(unsigned int timeStep);
itkGetConstMacro(TimeStep, unsigned int)
//##Documentation
//## @brief Get the time-step of a BaseData object which
//## exists at the time of the currently displayed content
//##
//## Returns -1 or mitk::BaseData::m_TimeSteps if there
//## is no data at the current time.
//## \sa GetTimeStep, m_TimeStep
int GetTimeStep(const BaseData* data) const;
//##Documentation
//## @brief Get the time in ms of the currently displayed content
//##
//## \sa GetTimeStep, m_TimeStep
ScalarType GetTime() const;
//##Documentation
//## @brief SetWorldGeometry is called according to the geometrySliceEvent,
//## which is supposed to be a SliceNavigationController::GeometrySendEvent
virtual void SetGeometry(const itk::EventObject & geometrySliceEvent);
//##Documentation
//## @brief UpdateWorldGeometry is called to re-read the 2D geometry from the
//## slice navigation controller
virtual void UpdateGeometry(const itk::EventObject & geometrySliceEvent);
//##Documentation
//## @brief SetSlice is called according to the geometrySliceEvent,
//## which is supposed to be a SliceNavigationController::GeometrySliceEvent
virtual void SetGeometrySlice(const itk::EventObject & geometrySliceEvent);
//##Documentation
//## @brief SetTimeStep is called according to the geometrySliceEvent,
//## which is supposed to be a SliceNavigationController::GeometryTimeEvent
virtual void SetGeometryTime(const itk::EventObject & geometryTimeEvent);
//##Documentation
//## @brief Get a data object containing the DisplayGeometry (for 2D rendering)
itkGetObjectMacro(DisplayGeometryData, PlaneGeometryData)
//##Documentation
//## @brief Get a data object containing the WorldGeometry (for 2D rendering)
itkGetObjectMacro(WorldGeometryData, PlaneGeometryData)
//##Documentation
//## @brief Get a DataNode pointing to a data object containing the WorldGeometry (3D and 2D rendering)
itkGetObjectMacro(WorldGeometryNode, DataNode)
//##Documentation
//## @brief Get a DataNode pointing to a data object containing the DisplayGeometry (for 2D rendering)
itkGetObjectMacro(DisplayGeometryNode, DataNode)
//##Documentation
//## @brief Get a DataNode pointing to a data object containing the current 2D-worldgeometry m_CurrentWorldPlaneGeometry (for 2D rendering)
itkGetObjectMacro(CurrentWorldPlaneGeometryNode, DataNode)
/**
* \deprecatedSince{2014_06} Please use GetCurrentWorldPlaneGeometryNode
*/
DEPRECATED(DataNode* GetCurrentWorldGeometry2DNode()){return GetCurrentWorldPlaneGeometryNode();};
//##Documentation
//## @brief Sets timestamp of CurrentWorldPlaneGeometry and DisplayGeometry and forces so reslicing in that renderwindow
void SendUpdateSlice();
//##Documentation
//## @brief Get timestamp of last call of SetCurrentWorldPlaneGeometry
unsigned long GetCurrentWorldPlaneGeometryUpdateTime()
{
return m_CurrentWorldPlaneGeometryUpdateTime;
}
/**
* \deprecatedSince{2014_06} Please use GetCurrentWorldPlaneGeometryUpdateTime
*/
DEPRECATED(unsigned long GetCurrentWorldGeometry2DUpdateTime()){return GetCurrentWorldPlaneGeometryUpdateTime();};
//##Documentation
//## @brief Get timestamp of last call of SetDisplayGeometry
unsigned long GetDisplayGeometryUpdateTime()
{
return m_CurrentWorldPlaneGeometryUpdateTime;
}
//##Documentation
//## @brief Get timestamp of last change of current TimeStep
unsigned long GetTimeStepUpdateTime()
{
return m_TimeStepUpdateTime;
}
//##Documentation
//## @brief Perform a picking: find the x,y,z world coordinate of a
//## display x,y coordinate.
//## @warning Has to be overwritten in subclasses for the 3D-case.
//##
//## Implemented here only for 2D-rendering by using
//## m_DisplayGeometry
virtual void PickWorldPoint(const Point2D& diplayPosition, Point3D& worldPosition) const;
/** \brief Determines the object (mitk::DataNode) closest to the current
* position by means of picking
*
* \warning Implementation currently empty for 2D rendering; intended to be
* implemented for 3D renderers */
virtual DataNode* PickObject(const Point2D& /*displayPosition*/, Point3D& /*worldPosition*/) const
{
return NULL;
}
//##Documentation
//## @brief Get the MapperSlotId to use.
itkGetMacro(MapperID, MapperSlotId)
- itkGetConstMacro(MapperID, MapperSlotId)
+ itkGetConstMacro(MapperID, MapperSlotId)
- //##Documentation
- //## @brief Set the MapperSlotId to use.
- itkSetMacro(MapperID, MapperSlotId)
+ //##Documentation
+ //## @brief Set the MapperSlotId to use.
+ itkSetMacro(MapperID, MapperSlotId)
- //##Documentation
- //## @brief Has the renderer the focus?
- itkGetMacro(Focused, bool)
- //##Documentation
- //## @brief Tell the renderer that it is focused. The caller is responsible for focus management,
- //## not the renderer itself.
- itkSetMacro(Focused, bool)
+ //##Documentation
+ //## @brief Has the renderer the focus?
+ itkGetMacro(Focused, bool)
+ //##Documentation
+ //## @brief Tell the renderer that it is focused. The caller is responsible for focus management,
+ //## not the renderer itself.
+ itkSetMacro(Focused, bool)
- itkGetMacro(Size, int*)
+ itkGetMacro(Size, int*)
- void SetSliceNavigationController(SliceNavigationController* SlicenavigationController);
+ void SetSliceNavigationController(SliceNavigationController* SlicenavigationController);
void SetCameraController(CameraController* cameraController);
itkGetObjectMacro(CameraController, CameraController)
- itkGetObjectMacro(SliceNavigationController, SliceNavigationController)
- itkGetObjectMacro(CameraRotationController, CameraRotationController)
+ itkGetObjectMacro(SliceNavigationController, SliceNavigationController)
+ itkGetObjectMacro(CameraRotationController, CameraRotationController)
- itkGetMacro(EmptyWorldGeometry, bool)
+ itkGetMacro(EmptyWorldGeometry, bool)
+
+ //##Documentation
+ //## @brief Tells if the displayed region is shifted and rescaled if the render window is resized.
+ itkGetMacro(KeepDisplayedRegion, bool)
+ //##Documentation
+ //## @brief Tells if the displayed region should be shifted and rescaled if the render window is resized.
+ itkSetMacro(KeepDisplayedRegion, bool)
- //##Documentation
- //## @brief Mouse event dispatchers
- //## @note for internal use only. preliminary.
- virtual void MousePressEvent(MouseEvent*);
+ //##Documentation
+ //## @brief Mouse event dispatchers
+ //## @note for internal use only. preliminary.
+ virtual void MousePressEvent(MouseEvent*);
//##Documentation
//## @brief Mouse event dispatchers
//## @note for internal use only. preliminary.
virtual void MouseReleaseEvent(MouseEvent*);
//##Documentation
//## @brief Mouse event dispatchers
//## @note for internal use only. preliminary.
virtual void MouseMoveEvent(MouseEvent*);
//##Documentation
//## @brief Wheel event dispatcher
//## @note for internal use only. preliminary.
virtual void WheelEvent(mitk::WheelEvent* we);
//##Documentation
//## @brief Key event dispatcher
//## @note for internal use only. preliminary.
virtual void KeyPressEvent(KeyEvent*);
//##Documentation
//## @brief get the name of the Renderer
//## @note
const char * GetName() const
{
return m_Name.c_str();
}
//##Documentation
//## @brief get the x_size of the RendererWindow
//## @note
int GetSizeX() const
{
return m_Size[0];
}
//##Documentation
//## @brief get the y_size of the RendererWindow
//## @note
int GetSizeY() const
{
return m_Size[1];
}
const double* GetBounds() const;
void RequestUpdate();
void ForceImmediateUpdate();
/** Returns number of mappers which are visible and have level-of-detail
* rendering enabled */
unsigned int GetNumberOfVisibleLODEnabledMappers() const;
///**
//* \brief Setter for the RenderingManager that handles this instance of BaseRenderer
//*/
//void SetRenderingManager( mitk::RenderingManager* );
/**
* \brief Getter for the RenderingManager that handles this instance of BaseRenderer
*/
virtual mitk::RenderingManager* GetRenderingManager() const;
/**
* \brief Provides (1) world coordinates for a given mouse position and (2)
* translates mousePosition to Display coordinates
*/
virtual Point3D Map2DRendererPositionTo3DWorldPosition(const Point2D& mousePosition) const;
/**
* \deprecatedSince{2014_03} Please use Map2DRendererPositionTo3DWorldPosition(const Point2D& mousePosition) const
*/
DEPRECATED(Point3D Map2DRendererPositionTo3DWorldPosition(Point2D* mousePosition) const);
protected:
virtual ~BaseRenderer();
//##Documentation
//## @brief Call update of all mappers. To be implemented in subclasses.
virtual void Update() = 0;
vtkRenderWindow* m_RenderWindow;
vtkRenderer* m_VtkRenderer;
//##Documentation
//## @brief MapperSlotId to use. Defines which kind of mapper (e.g., 2D or 3D) shoud be used.
MapperSlotId m_MapperID;
//##Documentation
//## @brief The DataStorage that is used for rendering.
DataStorage::Pointer m_DataStorage;
//##Documentation
//## @brief The RenderingManager that manages this instance
RenderingManager::Pointer m_RenderingManager;
//##Documentation
//## @brief Timestamp of last call of Update().
unsigned long m_LastUpdateTime;
//##Documentation
//## @brief CameraController for 3D rendering
//## @note preliminary.
CameraController::Pointer m_CameraController;
SliceNavigationController::Pointer m_SliceNavigationController;
CameraRotationController::Pointer m_CameraRotationController;
//##Documentation
//## @brief Size of the RenderWindow.
int m_Size[2];
//##Documentation
//## @brief Contains whether the renderer that it is focused. The caller of
//## SetFocused is responsible for focus management, not the renderer itself.
//## is doubled because of mitk::FocusManager in GlobalInteraction!!! (ingmar)
bool m_Focused;
//##Documentation
//## @brief Sets m_CurrentWorldPlaneGeometry
virtual void SetCurrentWorldPlaneGeometry(PlaneGeometry* geometry2d);
/**
* \deprecatedSince{2014_06} Please use SetCurrentWorldPlaneGeometry
*/
DEPRECATED(void SetCurrentWorldGeometry2D(PlaneGeometry* geometry2d)){SetCurrentWorldPlaneGeometry(geometry2d);};
//##Documentation
//## @brief Sets m_CurrentWorldGeometry
virtual void SetCurrentWorldGeometry(BaseGeometry* geometry);
//##Documentation
//## @brief This method is called during the rendering process to update or render the Overlays
//## which are stored in the OverlayManager
void UpdateOverlays();
private:
//##Documentation
//## Pointer to the worldgeometry, describing the maximal area to be rendered
//## (3D as well as 2D).
//## It is const, since we are not allowed to change it (it may be taken
//## directly from the geometry of an image-slice and thus it would be
//## very strange when suddenly the image-slice changes its geometry).
//## \sa SetWorldGeometry
BaseGeometry::Pointer m_WorldGeometry;
itk::SmartPointer<OverlayManager> m_OverlayManager;
//##Documentation
//## m_WorldTimeGeometry is set by SetWorldGeometry if the passed BaseGeometry is a
//## TimeGeometry (or a sub-class of it). If it contains instances of SlicedGeometry3D,
//## m_Slice and m_TimeStep (set via SetSlice and SetTimeStep, respectively) define
//## which 2D geometry stored in m_WorldTimeGeometry (if available)
//## is used as m_CurrentWorldPlaneGeometry.
//## \sa m_CurrentWorldPlaneGeometry
TimeGeometry::Pointer m_WorldTimeGeometry;
//##Documentation
//## Pointer to the current 3D-worldgeometry.
BaseGeometry::Pointer m_CurrentWorldGeometry;
//##Documentation
//## Pointer to the current 2D-worldgeometry. The 2D-worldgeometry
//## describes the maximal area (2D manifold) to be rendered in case we
//## are doing 2D-rendering. More precisely, a subpart of this according
//## to m_DisplayGeometry is displayed.
//## It is const, since we are not allowed to change it (it may be taken
//## directly from the geometry of an image-slice and thus it would be
//## very strange when suddenly the image-slice changes its geometry).
PlaneGeometry::Pointer m_CurrentWorldPlaneGeometry;
//##Documentation
//## Pointer to the displaygeometry. The displaygeometry describes the
//## geometry of the \em visible area in the window controlled by the renderer
//## in case we are doing 2D-rendering.
//## It is const, since we are not allowed to change it.
DisplayGeometry::Pointer m_DisplayGeometry;
//##Documentation
//## Defines together with m_Slice which 2D geometry stored in m_WorldTimeGeometry
//## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep).
//## \sa m_WorldTimeGeometry
unsigned int m_Slice;
//##Documentation
//## Defines together with m_TimeStep which 2D geometry stored in m_WorldTimeGeometry
//## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep).
//## \sa m_WorldTimeGeometry
unsigned int m_TimeStep;
//##Documentation
//## @brief timestamp of last call of SetWorldGeometry
itk::TimeStamp m_CurrentWorldPlaneGeometryUpdateTime;
//##Documentation
//## @brief timestamp of last call of SetDisplayGeometry
itk::TimeStamp m_DisplayGeometryUpdateTime;
//##Documentation
//## @brief timestamp of last change of the current time step
itk::TimeStamp m_TimeStepUpdateTime;
//##Documentation
//## @brief Helper class which establishes connection between Interactors and Dispatcher via a common DataStorage.
BindDispatcherInteractor* m_BindDispatcherInteractor;
+ //##Documentation
+ //## @brief Tells if the displayed region should be shifted or rescaled if the render window is resized.
+ bool m_KeepDisplayedRegion;
+
protected:
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
//##Documentation
//## Data object containing the m_WorldGeometry defined above.
PlaneGeometryData::Pointer m_WorldGeometryData;
//##Documentation
//## Data object containing the m_DisplayGeometry defined above.
PlaneGeometryData::Pointer m_DisplayGeometryData;
//##Documentation
//## Data object containing the m_CurrentWorldPlaneGeometry defined above.
PlaneGeometryData::Pointer m_CurrentWorldPlaneGeometryData;
//##Documentation
//## DataNode objects containing the m_WorldGeometryData defined above.
DataNode::Pointer m_WorldGeometryNode;
//##Documentation
//## DataNode objects containing the m_DisplayGeometryData defined above.
DataNode::Pointer m_DisplayGeometryNode;
//##Documentation
//## DataNode objects containing the m_CurrentWorldPlaneGeometryData defined above.
DataNode::Pointer m_CurrentWorldPlaneGeometryNode;
//##Documentation
//## @brief test only
unsigned long m_DisplayGeometryTransformTime;
//##Documentation
//## @brief test only
unsigned long m_CurrentWorldPlaneGeometryTransformTime;
std::string m_Name;
double m_Bounds[6];
bool m_EmptyWorldGeometry;
typedef std::set<Mapper *> LODEnabledMappersType;
/** Number of mappers which are visible and have level-of-detail
* rendering enabled */
unsigned int m_NumberOfVisibleLODEnabledMappers;
// Local Storage Handling for mappers
protected:
std::list<mitk::BaseLocalStorageHandler*> m_RegisteredLocalStorageHandlers;
public:
void RemoveAllLocalStorages();
void RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh);
void UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh);
};
} // namespace mitk
#endif /* BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 */
diff --git a/Core/Code/Rendering/mitkImageVtkMapper2D.cpp b/Core/Code/Rendering/mitkImageVtkMapper2D.cpp
index ce7a9a10da..1919dbe1fa 100644
--- a/Core/Code/Rendering/mitkImageVtkMapper2D.cpp
+++ b/Core/Code/Rendering/mitkImageVtkMapper2D.cpp
@@ -1,1079 +1,1082 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//MITK
#include <mitkAbstractTransformGeometry.h>
#include <mitkDataNode.h>
#include <mitkDataNodeFactory.h>
#include <mitkImageSliceSelector.h>
#include <mitkLevelWindowProperty.h>
#include <mitkLookupTableProperty.h>
#include <mitkPlaneGeometry.h>
#include <mitkProperties.h>
#include <mitkResliceMethodProperty.h>
#include <mitkVtkResliceInterpolationProperty.h>
#include <mitkPixelType.h>
//#include <mitkTransferFunction.h>
#include <mitkTransferFunctionProperty.h>
#include "mitkImageStatisticsHolder.h"
#include "mitkPlaneClipping.h"
//MITK Rendering
#include "mitkImageVtkMapper2D.h"
#include "vtkMitkThickSlicesFilter.h"
#include "vtkMitkLevelWindowFilter.h"
#include "vtkNeverTranslucentTexture.h"
//VTK
#include <vtkProperty.h>
#include <vtkTransform.h>
#include <vtkMatrix4x4.h>
#include <vtkLookupTable.h>
#include <vtkImageData.h>
#include <vtkPoints.h>
#include <vtkGeneralTransform.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageReslice.h>
#include <vtkImageChangeInformation.h>
#include <vtkPlaneSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkCellArray.h>
#include <vtkCamera.h>
#include <vtkColorTransferFunction.h>
//ITK
#include <itkRGBAPixel.h>
#include <mitkRenderingModeProperty.h>
mitk::ImageVtkMapper2D::ImageVtkMapper2D()
{
}
mitk::ImageVtkMapper2D::~ImageVtkMapper2D()
{
//The 3D RW Mapper (PlaneGeometryDataVtkMapper3D) is listening to this event,
//in order to delete the images from the 3D RW.
this->InvokeEvent( itk::DeleteEvent() );
}
//set the two points defining the textured plane according to the dimension and spacing
void mitk::ImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, double planeBounds[6])
{
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
float depth = this->CalculateLayerDepth(renderer);
//Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct
//plane size in crosshair rotation and swivel mode.
localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth);
//These two points define the axes of the plane in combination with the origin.
//Point 1 is the x-axis and point 2 the y-axis.
//Each plane is transformed according to the view (axial, coronal and saggital) afterwards.
localStorage->m_Plane->SetPoint1(planeBounds[1] , planeBounds[2], depth); //P1: (xMax, yMin, depth)
localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); //P2: (xMin, yMax, depth)
}
float mitk::ImageVtkMapper2D::CalculateLayerDepth(mitk::BaseRenderer* renderer)
{
//get the clipping range to check how deep into z direction we can render images
double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1];
//Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined
float depth = -maxRange*0.01; // divide by 100
int layer = 0;
GetDataNode()->GetIntProperty( "layer", layer, renderer);
//add the layer property for each image to render images with a higher layer on top of the others
depth += layer*10; //*10: keep some room for each image (e.g. for QBalls in between)
if(depth > 0.0f) {
depth = 0.0f;
MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead.";
}
return depth;
}
const mitk::Image* mitk::ImageVtkMapper2D::GetInput( void )
{
return static_cast< const mitk::Image * >( GetDataNode()->GetData() );
}
vtkProp* mitk::ImageVtkMapper2D::GetVtkProp(mitk::BaseRenderer* renderer)
{
//return the actor corresponding to the renderer
return m_LSH.GetLocalStorage(renderer)->m_Actors;
}
void mitk::ImageVtkMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
{
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() );
mitk::DataNode* datanode = this->GetDataNode();
if ( input == NULL || input->IsInitialized() == false )
{
return;
}
//check if there is a valid worldGeometry
const PlaneGeometry *worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
if( ( worldGeometry == NULL ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->HasReferenceGeometry() ))
{
return;
}
input->Update();
// early out if there is no intersection of the current rendering geometry
// and the geometry of the image that is to be rendered.
if ( !RenderingGeometryIntersectsImage( worldGeometry, input->GetSlicedGeometry() ) )
{
// set image to NULL, to clear the texture in 3D, because
// the latest image is used there if the plane is out of the geometry
// see bug-13275
localStorage->m_ReslicedImage = NULL;
localStorage->m_Mapper->SetInputData( localStorage->m_EmptyPolyData );
return;
}
//set main input for ExtractSliceFilter
localStorage->m_Reslicer->SetInput(input);
localStorage->m_Reslicer->SetWorldGeometry(worldGeometry);
localStorage->m_Reslicer->SetTimeStep( this->GetTimestep() );
//set the transformation of the image to adapt reslice axis
localStorage->m_Reslicer->SetResliceTransformByGeometry( input->GetTimeGeometry()->GetGeometryForTimeStep( this->GetTimestep() ) );
//is the geometry of the slice based on the input image or the worldgeometry?
bool inPlaneResampleExtentByGeometry = false;
datanode->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer);
localStorage->m_Reslicer->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry);
// Initialize the interpolation mode for resampling; switch to nearest
// neighbor if the input image is too small.
if ( (input->GetDimension() >= 3) && (input->GetDimension(2) > 1) )
{
VtkResliceInterpolationProperty *resliceInterpolationProperty;
datanode->GetProperty(
- resliceInterpolationProperty, "reslice interpolation" );
+ resliceInterpolationProperty, "reslice interpolation", renderer );
int interpolationMode = VTK_RESLICE_NEAREST;
if ( resliceInterpolationProperty != NULL )
{
interpolationMode = resliceInterpolationProperty->GetInterpolation();
}
switch ( interpolationMode )
{
case VTK_RESLICE_NEAREST:
localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
break;
case VTK_RESLICE_LINEAR:
localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_LINEAR);
break;
case VTK_RESLICE_CUBIC:
localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_CUBIC);
break;
}
}
else
{
localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
}
//set the vtk output property to true, makes sure that no unneeded mitk image convertion
//is done.
localStorage->m_Reslicer->SetVtkOutputRequest(true);
//Thickslicing
int thickSlicesMode = 0;
int thickSlicesNum = 1;
// Thick slices parameters
if( input->GetPixelType().GetNumberOfComponents() == 1 ) // for now only single component are allowed
{
DataNode *dn=renderer->GetCurrentWorldPlaneGeometryNode();
if(dn)
{
ResliceMethodProperty *resliceMethodEnumProperty=0;
- if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty )
+ if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices", renderer ) && resliceMethodEnumProperty )
thickSlicesMode = resliceMethodEnumProperty->GetValueAsId();
IntProperty *intProperty=0;
- if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty )
+ if( dn->GetProperty( intProperty, "reslice.thickslices.num", renderer ) && intProperty )
{
thickSlicesNum = intProperty->GetValue();
if(thickSlicesNum < 1) thickSlicesNum=1;
}
}
else
{
MITK_WARN << "no associated widget plane data tree node found";
}
}
const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( worldGeometry );
if(thickSlicesMode > 0)
{
double dataZSpacing = 1.0;
Vector3D normInIndex, normal;
const mitk::AbstractTransformGeometry* abstractGeometry = dynamic_cast< const AbstractTransformGeometry * >(worldGeometry);
if(abstractGeometry != NULL)
normal = abstractGeometry->GetPlane()->GetNormal();
else{
if ( planeGeometry != NULL ){
normal = planeGeometry->GetNormal();
}
else
return; //no fitting geometry set
}
normal.Normalize();
input->GetTimeGeometry()->GetGeometryForTimeStep( this->GetTimestep() )->WorldToIndex( normal, normInIndex );
dataZSpacing = 1.0 / normInIndex.GetNorm();
localStorage->m_Reslicer->SetOutputDimensionality( 3 );
localStorage->m_Reslicer->SetOutputSpacingZDirection(dataZSpacing);
localStorage->m_Reslicer->SetOutputExtentZDirection( -thickSlicesNum, 0+thickSlicesNum );
// Do the reslicing. Modified() is called to make sure that the reslicer is
// executed even though the input geometry information did not change; this
// is necessary when the input /em data, but not the /em geometry changes.
localStorage->m_TSFilter->SetThickSliceMode( thickSlicesMode-1 );
localStorage->m_TSFilter->SetInputData( localStorage->m_Reslicer->GetVtkOutput() );
//vtkFilter=>mitkFilter=>vtkFilter update mechanism will fail without calling manually
localStorage->m_Reslicer->Modified();
localStorage->m_Reslicer->Update();
localStorage->m_TSFilter->Modified();
localStorage->m_TSFilter->Update();
localStorage->m_ReslicedImage = localStorage->m_TSFilter->GetOutput();
}
else
{
//this is needed when thick mode was enable bevore. These variable have to be reset to default values
localStorage->m_Reslicer->SetOutputDimensionality( 2 );
localStorage->m_Reslicer->SetOutputSpacingZDirection(1.0);
localStorage->m_Reslicer->SetOutputExtentZDirection( 0, 0 );
localStorage->m_Reslicer->Modified();
//start the pipeline with updating the largest possible, needed if the geometry of the input has changed
localStorage->m_Reslicer->UpdateLargestPossibleRegion();
localStorage->m_ReslicedImage = localStorage->m_Reslicer->GetVtkOutput();
}
// Bounds information for reslicing (only reuqired if reference geometry
// is present)
//this used for generating a vtkPLaneSource with the right size
double sliceBounds[6];
for ( int i = 0; i < 6; ++i )
{
sliceBounds[i] = 0.0;
}
localStorage->m_Reslicer->GetClippedPlaneBounds(sliceBounds);
//get the spacing of the slice
localStorage->m_mmPerPixel = localStorage->m_Reslicer->GetOutputSpacing();
// calculate minimum bounding rect of IMAGE in texture
{
double textureClippingBounds[6];
for ( int i = 0; i < 6; ++i )
{
textureClippingBounds[i] = 0.0;
}
// Calculate the actual bounds of the transformed plane clipped by the
// dataset bounding box; this is required for drawing the texture at the
// correct position during 3D mapping.
mitk::PlaneClipping::CalculateClippedPlaneBounds( input->GetGeometry(), planeGeometry, textureClippingBounds );
textureClippingBounds[0] = static_cast< int >( textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5 );
textureClippingBounds[1] = static_cast< int >( textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5 );
textureClippingBounds[2] = static_cast< int >( textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5 );
textureClippingBounds[3] = static_cast< int >( textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5 );
//clipping bounds for cutting the image
localStorage->m_LevelWindowFilter->SetClippingBounds(textureClippingBounds);
}
//get the number of scalar components to distinguish between different image types
int numberOfComponents = localStorage->m_ReslicedImage->GetNumberOfScalarComponents();
//get the binary property
bool binary = false;
bool binaryOutline = false;
datanode->GetBoolProperty( "binary", binary, renderer );
if(binary) //binary image
{
datanode->GetBoolProperty( "outline binary", binaryOutline, renderer );
if(binaryOutline) //contour rendering
{
if ( input->GetPixelType().GetBpe() <= 8 )
{
//generate contours/outlines
localStorage->m_OutlinePolyData = CreateOutlinePolyData(renderer);
float binaryOutlineWidth(1.0);
if ( datanode->GetFloatProperty( "outline width", binaryOutlineWidth, renderer ) )
{
if ( localStorage->m_Actors->GetNumberOfPaths() > 1 )
{
float binaryOutlineShadowWidth(1.5);
datanode->GetFloatProperty( "outline shadow width", binaryOutlineShadowWidth, renderer );
dynamic_cast<vtkActor*>(localStorage->m_Actors->GetParts()->GetItemAsObject(0))
->GetProperty()->SetLineWidth( binaryOutlineWidth * binaryOutlineShadowWidth );
}
localStorage->m_Actor->GetProperty()->SetLineWidth( binaryOutlineWidth );
}
}
else
{
binaryOutline = false;
this->ApplyLookuptable(renderer);
MITK_WARN << "Type of all binary images should be (un)signed char. Outline does not work on other pixel types!";
}
}
else //standard binary image
{
if(numberOfComponents != 1)
{
MITK_ERROR << "Rendering Error: Binary Images with more then 1 component are not supported!";
}
}
}
this->ApplyOpacity( renderer );
this->ApplyRenderingMode(renderer);
// do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter)
localStorage->m_Texture->MapColorScalarsThroughLookupTableOff();
int displayedComponent = 0;
if (datanode->GetIntProperty("Image.Displayed Component", displayedComponent, renderer) && numberOfComponents > 1)
{
localStorage->m_VectorComponentExtractor->SetComponents(displayedComponent);
localStorage->m_VectorComponentExtractor->SetInputData(localStorage->m_ReslicedImage);
localStorage->m_LevelWindowFilter->SetInputConnection(localStorage->m_VectorComponentExtractor->GetOutputPort(0));
}
else
{
//connect the input with the levelwindow filter
localStorage->m_LevelWindowFilter->SetInputData(localStorage->m_ReslicedImage);
}
// check for texture interpolation property
bool textureInterpolation = false;
GetDataNode()->GetBoolProperty( "texture interpolation", textureInterpolation, renderer );
//set the interpolation modus according to the property
localStorage->m_Texture->SetInterpolate(textureInterpolation);
// connect the texture with the output of the levelwindow filter
localStorage->m_Texture->SetInputConnection(localStorage->m_LevelWindowFilter->GetOutputPort());
this->TransformActor( renderer );
vtkActor* contourShadowActor = dynamic_cast<vtkActor*> (localStorage->m_Actors->GetParts()->GetItemAsObject(0));
if(binary && binaryOutline) //connect the mapper with the polyData which contains the lines
{
//We need the contour for the binary outline property as actor
localStorage->m_Mapper->SetInputData(localStorage->m_OutlinePolyData);
localStorage->m_Actor->SetTexture(NULL); //no texture for contours
bool binaryOutlineShadow( false );
datanode->GetBoolProperty( "outline binary shadow", binaryOutlineShadow, renderer );
if ( binaryOutlineShadow )
contourShadowActor->SetVisibility( true );
else
contourShadowActor->SetVisibility( false );
}
else
{ //Connect the mapper with the input texture. This is the standard case.
//setup the textured plane
this->GeneratePlane( renderer, sliceBounds );
//set the plane as input for the mapper
localStorage->m_Mapper->SetInputConnection(localStorage->m_Plane->GetOutputPort());
//set the texture for the actor
localStorage->m_Actor->SetTexture(localStorage->m_Texture);
contourShadowActor->SetVisibility( false );
}
// We have been modified => save this for next Update()
localStorage->m_LastUpdateTime.Modified();
}
void mitk::ImageVtkMapper2D::ApplyLevelWindow(mitk::BaseRenderer *renderer)
{
LocalStorage *localStorage = this->GetLocalStorage( renderer );
LevelWindow levelWindow;
this->GetDataNode()->GetLevelWindow( levelWindow, renderer, "levelwindow" );
localStorage->m_LevelWindowFilter->GetLookupTable()->SetRange( levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound() );
mitk::LevelWindow opacLevelWindow;
if( this->GetDataNode()->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) )
{
//pass the opaque level window to the filter
localStorage->m_LevelWindowFilter->SetMinOpacity(opacLevelWindow.GetLowerWindowBound());
localStorage->m_LevelWindowFilter->SetMaxOpacity(opacLevelWindow.GetUpperWindowBound());
}
else
{
//no opaque level window
localStorage->m_LevelWindowFilter->SetMinOpacity(0.0);
localStorage->m_LevelWindowFilter->SetMaxOpacity(255.0);
}
}
void mitk::ImageVtkMapper2D::ApplyColor( mitk::BaseRenderer* renderer )
{
LocalStorage *localStorage = this->GetLocalStorage( renderer );
float rgb[3]= { 1.0f, 1.0f, 1.0f };
// check for color prop and use it for rendering if it exists
// binary image hovering & binary image selection
bool hover = false;
bool selected = false;
+ bool binary = false;
GetDataNode()->GetBoolProperty("binaryimage.ishovering", hover, renderer);
GetDataNode()->GetBoolProperty("selected", selected, renderer);
- if(hover && !selected)
+ GetDataNode()->GetBoolProperty("binary", binary, renderer);
+ if(binary && hover && !selected)
{
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
("binaryimage.hoveringcolor", renderer));
if(colorprop.IsNotNull())
{
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
}
else
{
GetDataNode()->GetColor( rgb, renderer, "color" );
}
}
- if(selected)
+ if(binary && selected)
{
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
("binaryimage.selectedcolor", renderer));
if(colorprop.IsNotNull()) {
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
}
else
{
GetDataNode()->GetColor(rgb, renderer, "color");
}
}
- if(!hover && !selected)
+ if(!binary || (!hover && !selected))
{
GetDataNode()->GetColor( rgb, renderer, "color" );
}
double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK
dynamic_cast<vtkActor*> (localStorage->m_Actors->GetParts()->GetItemAsObject(0))->GetProperty()->SetColor(rgbConv);
localStorage->m_Actor->GetProperty()->SetColor(rgbConv);
if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 )
{
float rgb[3]= { 1.0f, 1.0f, 1.0f };
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
("outline binary shadow color", renderer));
if(colorprop.IsNotNull())
{
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
}
double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK
dynamic_cast<vtkActor*>( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetColor(rgbConv);
}
}
void mitk::ImageVtkMapper2D::ApplyOpacity( mitk::BaseRenderer* renderer )
{
LocalStorage* localStorage = this->GetLocalStorage( renderer );
float opacity = 1.0f;
// check for opacity prop and use it for rendering if it exists
GetDataNode()->GetOpacity( opacity, renderer, "opacity" );
//set the opacity according to the properties
localStorage->m_Actor->GetProperty()->SetOpacity(opacity);
if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 )
{
dynamic_cast<vtkActor*>( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetOpacity(opacity);
}
}
void mitk::ImageVtkMapper2D::ApplyRenderingMode( mitk::BaseRenderer* renderer )
{
LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
bool binary = false;
this->GetDataNode()->GetBoolProperty( "binary", binary, renderer );
if(binary) // is it a binary image?
{
//for binary images, we always use our default LuT and map every value to (0,1)
//the opacity of 0 will always be 0.0. We never a apply a LuT/TfF nor a level window.
localStorage->m_LevelWindowFilter->SetLookupTable(localStorage->m_BinaryLookupTable);
}
else
{
//all other image types can make use of the rendering mode
int renderingMode = mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR;
mitk::RenderingModeProperty::Pointer mode = dynamic_cast<mitk::RenderingModeProperty*>(this->GetDataNode()->GetProperty( "Image Rendering.Mode", renderer ));
if(mode.IsNotNull())
{
renderingMode = mode->GetRenderingMode();
}
switch(renderingMode)
{
case mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR:
MITK_DEBUG << "'Image Rendering.Mode' = LevelWindow_LookupTable_Color";
this->ApplyLookuptable( renderer );
this->ApplyLevelWindow( renderer );
break;
case mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_LEVELWINDOW_COLOR:
MITK_DEBUG << "'Image Rendering.Mode' = LevelWindow_ColorTransferFunction_Color";
this->ApplyColorTransferFunction( renderer );
this->ApplyLevelWindow( renderer );
break;
case mitk::RenderingModeProperty::LOOKUPTABLE_COLOR:
MITK_DEBUG << "'Image Rendering.Mode' = LookupTable_Color";
this->ApplyLookuptable( renderer );
break;
case mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR:
MITK_DEBUG << "'Image Rendering.Mode' = ColorTransferFunction_Color";
this->ApplyColorTransferFunction( renderer );
break;
default:
MITK_ERROR << "No valid 'Image Rendering.Mode' set. Using LOOKUPTABLE_LEVELWINDOW_COLOR instead.";
this->ApplyLookuptable( renderer );
this->ApplyLevelWindow( renderer );
break;
}
}
//we apply color for all images (including binaries).
this->ApplyColor( renderer );
}
void mitk::ImageVtkMapper2D::ApplyLookuptable( mitk::BaseRenderer* renderer )
{
LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
vtkLookupTable* usedLookupTable = localStorage->m_ColorLookupTable;
// If lookup table or transferfunction use is requested...
mitk::LookupTableProperty::Pointer lookupTableProp = dynamic_cast<mitk::LookupTableProperty*>(this->GetDataNode()->GetProperty("LookupTable"));
if( lookupTableProp.IsNotNull() ) // is a lookuptable set?
{
usedLookupTable = lookupTableProp->GetLookupTable()->GetVtkLookupTable();
}
else
{
//"Image Rendering.Mode was set to use a lookup table but there is no property 'LookupTable'.
//A default (rainbow) lookup table will be used.
//Here have to do nothing. Warning for the user has been removed, due to unwanted console output
//in every interation of the rendering.
}
localStorage->m_LevelWindowFilter->SetLookupTable(usedLookupTable);
}
void mitk::ImageVtkMapper2D::ApplyColorTransferFunction(mitk::BaseRenderer *renderer)
{
mitk::TransferFunctionProperty::Pointer transferFunctionProp = dynamic_cast<mitk::TransferFunctionProperty*>(this->GetDataNode()->GetProperty("Image Rendering.Transfer Function",renderer ));
if( transferFunctionProp.IsNull() )
{
MITK_ERROR << "'Image Rendering.Mode'' was set to use a color transfer function but there is no property 'Image Rendering.Transfer Function'. Nothing will be done.";
return;
}
LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
//pass the transfer function to our level window filter
localStorage->m_LevelWindowFilter->SetLookupTable(transferFunctionProp->GetValue()->GetColorTransferFunction());
+ localStorage->m_LevelWindowFilter->SetOpacityPiecewiseFunction(transferFunctionProp->GetValue()->GetScalarOpacityFunction());
}
void mitk::ImageVtkMapper2D::Update(mitk::BaseRenderer* renderer)
{
bool visible = true;
GetDataNode()->GetVisibility(visible, renderer, "visible");
if ( !visible )
{
return;
}
mitk::Image* data = const_cast<mitk::Image *>( this->GetInput() );
if ( data == NULL )
{
return;
}
// Calculate time step of the input data for the specified renderer (integer value)
this->CalculateTimeStep( renderer );
// Check if time step is valid
const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry();
if ( ( dataTimeGeometry == NULL )
|| ( dataTimeGeometry->CountTimeSteps() == 0 )
|| ( !dataTimeGeometry->IsValidTimeStep( this->GetTimestep() ) ) )
{
return;
}
const DataNode *node = this->GetDataNode();
data->UpdateOutputInformation();
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
//check if something important has changed and we need to rerender
if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified?
|| (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified?
|| (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) //was the geometry modified?
|| (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime())
|| (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
|| (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
{
this->GenerateDataForRenderer( renderer );
}
// since we have checked that nothing important has changed, we can set
// m_LastUpdateTime to the current time
localStorage->m_LastUpdateTime.Modified();
}
void mitk::ImageVtkMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
// Properties common for both images and segmentations
node->AddProperty( "depthOffset", mitk::FloatProperty::New( 0.0 ), renderer, overwrite );
node->AddProperty( "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite );
node->AddProperty( "outline width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite );
node->AddProperty( "outline binary shadow", mitk::BoolProperty::New( false ), renderer, overwrite );
node->AddProperty( "outline binary shadow color", ColorProperty::New(0.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "outline shadow width", mitk::FloatProperty::New( 1.5 ), renderer, overwrite );
if(image->IsRotated()) node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_CUBIC) );
else node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() );
node->AddProperty( "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) ); // set to user configurable default value (see global options)
node->AddProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( false ) );
node->AddProperty( "bounding box", mitk::BoolProperty::New( false ) );
mitk::RenderingModeProperty::Pointer renderingModeProperty = mitk::RenderingModeProperty::New();
node->AddProperty( "Image Rendering.Mode", renderingModeProperty);
// Set default grayscale look-up table
mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New();
mitkLut->SetType(mitk::LookupTable::GRAYSCALE);
mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New();
mitkLutProp->SetLookupTable(mitkLut);
node->SetProperty("LookupTable", mitkLutProp);
std::string photometricInterpretation; // DICOM tag telling us how pixel values should be displayed
if ( node->GetStringProperty( "dicom.pixel.PhotometricInterpretation", photometricInterpretation ) )
{
// modality provided by DICOM or other reader
if ( photometricInterpretation.find("MONOCHROME1") != std::string::npos ) // meaning: display MINIMUM pixels as WHITE
{
// Set inverse grayscale look-up table
mitkLut->SetType(mitk::LookupTable::INVERSE_GRAYSCALE);
mitkLutProp->SetLookupTable(mitkLut);
node->SetProperty( "LookupTable", mitkLutProp );
renderingModeProperty->SetValue( mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR ); // USE lookuptable
}
// Otherwise do nothing - the default grayscale look-up table has already been set
}
bool isBinaryImage(false);
if ( ! node->GetBoolProperty("binary", isBinaryImage) )
{
// ok, property is not set, use heuristic to determine if this
// is a binary image
mitk::Image::Pointer centralSliceImage;
ScalarType minValue = 0.0;
ScalarType maxValue = 0.0;
ScalarType min2ndValue = 0.0;
ScalarType max2ndValue = 0.0;
mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New();
sliceSelector->SetInput(image);
sliceSelector->SetSliceNr(image->GetDimension(2)/2);
sliceSelector->SetTimeNr(image->GetDimension(3)/2);
sliceSelector->SetChannelNr(image->GetDimension(4)/2);
sliceSelector->Update();
centralSliceImage = sliceSelector->GetOutput();
if ( centralSliceImage.IsNotNull() && centralSliceImage->IsInitialized() )
{
minValue = centralSliceImage->GetStatistics()->GetScalarValueMin();
maxValue = centralSliceImage->GetStatistics()->GetScalarValueMax();
min2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMin();
max2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMax();
}
if ((maxValue == min2ndValue && minValue == max2ndValue) || minValue == maxValue)
{
// centralSlice is strange, lets look at all data
minValue = image->GetStatistics()->GetScalarValueMin();
maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
}
isBinaryImage = ( maxValue == min2ndValue && minValue == max2ndValue );
}
// some more properties specific for a binary...
if (isBinaryImage)
{
node->AddProperty( "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite );
node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.selectedcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.selectedannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.hoveringcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.hoveringannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binary", mitk::BoolProperty::New( true ), renderer, overwrite );
node->AddProperty("layer", mitk::IntProperty::New(10), renderer, overwrite);
}
else //...or image type object
{
node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite );
node->AddProperty( "color", ColorProperty::New(1.0,1.0,1.0), renderer, overwrite );
node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite );
node->AddProperty("layer", mitk::IntProperty::New(0), renderer, overwrite);
std::string className = image->GetNameOfClass();
if (className != "TensorImage" && className != "QBallImage")
{
PixelType pixelType = image->GetPixelType();
size_t numComponents = pixelType.GetNumberOfComponents();
if ((pixelType.GetPixelType() == itk::ImageIOBase::VECTOR && numComponents > 1) ||
numComponents == 2 || numComponents > 4)
{
node->AddProperty("Image.Displayed Component", mitk::IntProperty::New(0), renderer, overwrite);
}
}
}
if(image.IsNotNull() && image->IsInitialized())
{
if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL))
{
/* initialize level/window from DICOM tags */
std::string sLevel;
std::string sWindow;
if ( image->GetPropertyList()->GetStringProperty( "dicom.voilut.WindowCenter", sLevel )
&& image->GetPropertyList()->GetStringProperty( "dicom.voilut.WindowWidth", sWindow ) )
{
float level = atof( sLevel.c_str() );
float window = atof( sWindow.c_str() );
mitk::LevelWindow contrast;
std::string sSmallestPixelValueInSeries;
std::string sLargestPixelValueInSeries;
if ( image->GetPropertyList()->GetStringProperty( "dicom.series.SmallestPixelValueInSeries", sSmallestPixelValueInSeries )
&& image->GetPropertyList()->GetStringProperty( "dicom.series.LargestPixelValueInSeries", sLargestPixelValueInSeries ) )
{
float smallestPixelValueInSeries = atof( sSmallestPixelValueInSeries.c_str() );
float largestPixelValueInSeries = atof( sLargestPixelValueInSeries.c_str() );
contrast.SetRangeMinMax( smallestPixelValueInSeries-1, largestPixelValueInSeries+1 ); // why not a little buffer?
// might remedy some l/w widget challenges
}
else
{
contrast.SetAuto( static_cast<mitk::Image*>(node->GetData()), false, true ); // we need this as a fallback
}
contrast.SetLevelWindow( level, window, true );
node->SetProperty( "levelwindow", LevelWindowProperty::New( contrast ), renderer );
}
}
if(((overwrite) || (node->GetProperty("opaclevelwindow", renderer)==NULL))
&& (image->GetPixelType().GetPixelType() == itk::ImageIOBase::RGBA)
&& (image->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR) )
{
mitk::LevelWindow opaclevwin;
opaclevwin.SetRangeMinMax(0,255);
opaclevwin.SetWindowBounds(0,255);
mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin);
node->SetProperty( "opaclevelwindow", prop, renderer );
}
}
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
mitk::ImageVtkMapper2D::LocalStorage* mitk::ImageVtkMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer)
{
return m_LSH.GetLocalStorage(renderer);
}
vtkSmartPointer<vtkPolyData> mitk::ImageVtkMapper2D::CreateOutlinePolyData(mitk::BaseRenderer* renderer ){
LocalStorage* localStorage = this->GetLocalStorage(renderer);
//get the min and max index values of each direction
int* extent = localStorage->m_ReslicedImage->GetExtent();
int xMin = extent[0];
int xMax = extent[1];
int yMin = extent[2];
int yMax = extent[3];
int* dims = localStorage->m_ReslicedImage->GetDimensions(); //dimensions of the image
int line = dims[0]; //how many pixels per line?
int x = xMin; //pixel index x
int y = yMin; //pixel index y
char* currentPixel;
//get the depth for each contour
float depth = CalculateLayerDepth(renderer);
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); //the points to draw
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); //the lines to connect the points
// We take the pointer to the first pixel of the image
currentPixel = static_cast<char*>(localStorage->m_ReslicedImage->GetScalarPointer() );
while (y <= yMax)
{
//if the current pixel value is set to something
if ((currentPixel) && (*currentPixel != 0))
{
//check in which direction a line is necessary
//a line is added if the neighbor of the current pixel has the value 0
//and if the pixel is located at the edge of the image
//if vvvvv not the first line vvvvv
if (y > yMin && *(currentPixel-line) == 0)
{ //x direction - bottom edge of the pixel
//add the 2 points
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
//add the line between both points
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv not the last line vvvvv
if (y < yMax && *(currentPixel+line) == 0)
{ //x direction - top edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv not the first pixel vvvvv
if ( (x > xMin || y > yMin) && *(currentPixel-1) == 0)
{ //y direction - left edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv not the last pixel vvvvv
if ( (y < yMax || (x < xMax) ) && *(currentPixel+1) == 0)
{ //y direction - right edge of the pixel
vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
/* now consider pixels at the edge of the image */
//if vvvvv left edge of image vvvvv
if (x == xMin)
{ //draw left edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv right edge of image vvvvv
if (x == xMax)
{ //draw right edge of the pixel
vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv bottom edge of image vvvvv
if (y == yMin)
{ //draw bottom edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv top edge of image vvvvv
if (y == yMax)
{ //draw top edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
}//end if currentpixel is set
x++;
if (x > xMax)
{ //reached end of line
x = xMin;
y++;
}
// Increase the pointer-position to the next pixel.
// This is safe, as the while-loop and the x-reset logic above makes
// sure we do not exceed the bounds of the image
currentPixel++;
}//end of while
// Create a polydata to store everything in
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
// Add the points to the dataset
polyData->SetPoints(points);
// Add the lines to the dataset
polyData->SetLines(lines);
return polyData;
}
void mitk::ImageVtkMapper2D::TransformActor(mitk::BaseRenderer* renderer)
{
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
//get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital
vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_Reslicer->GetResliceAxes();
trans->SetMatrix(matrix);
//transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital)
localStorage->m_Actor->SetUserTransform(trans);
//transform the origin to center based coordinates, because MITK is center based.
localStorage->m_Actor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0);
if ( localStorage->m_Actors->GetNumberOfPaths() > 1 )
{
vtkActor* secondaryActor = dynamic_cast<vtkActor*>( localStorage->m_Actors->GetParts()->GetItemAsObject(0) );
secondaryActor->SetUserTransform(trans);
secondaryActor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0);
}
}
bool mitk::ImageVtkMapper2D::RenderingGeometryIntersectsImage( const PlaneGeometry* renderingGeometry, SlicedGeometry3D* imageGeometry )
{
// if either one of the two geometries is NULL we return true
// for safety reasons
if ( renderingGeometry == NULL || imageGeometry == NULL )
return true;
// get the distance for the first cornerpoint
ScalarType initialDistance = renderingGeometry->SignedDistance( imageGeometry->GetCornerPoint( 0 ) );
for( int i=1; i<8; i++ )
{
mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint( i );
// get the distance to the other cornerpoints
ScalarType distance = renderingGeometry->SignedDistance( cornerPoint );
// if it has not the same signing as the distance of the first point
if ( initialDistance * distance < 0 )
{
// we have an intersection and return true
return true;
}
}
// all distances have the same sign, no intersection and we return false
return false;
}
mitk::ImageVtkMapper2D::LocalStorage::~LocalStorage()
{
}
mitk::ImageVtkMapper2D::LocalStorage::LocalStorage()
: m_VectorComponentExtractor(vtkSmartPointer<vtkImageExtractComponents>::New())
{
m_LevelWindowFilter = vtkSmartPointer<vtkMitkLevelWindowFilter>::New();
//Do as much actions as possible in here to avoid double executions.
m_Plane = vtkSmartPointer<vtkPlaneSource>::New();
m_Texture = vtkSmartPointer<vtkNeverTranslucentTexture>::New().GetPointer();
m_DefaultLookupTable = vtkSmartPointer<vtkLookupTable>::New();
m_BinaryLookupTable = vtkSmartPointer<vtkLookupTable>::New();
m_ColorLookupTable = vtkSmartPointer<vtkLookupTable>::New();
m_Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
m_Actor = vtkSmartPointer<vtkActor>::New();
m_Actors = vtkSmartPointer<vtkPropAssembly>::New();
m_Reslicer = mitk::ExtractSliceFilter::New();
m_TSFilter = vtkSmartPointer<vtkMitkThickSlicesFilter>::New();
m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
m_ReslicedImage = vtkSmartPointer<vtkImageData>::New();
m_EmptyPolyData = vtkSmartPointer<vtkPolyData>::New();
//the following actions are always the same and thus can be performed
//in the constructor for each image (i.e. the image-corresponding local storage)
m_TSFilter->ReleaseDataFlagOn();
mitk::LookupTable::Pointer mitkLUT = mitk::LookupTable::New();
//built a default lookuptable
mitkLUT->SetType(mitk::LookupTable::GRAYSCALE);
m_DefaultLookupTable = mitkLUT->GetVtkLookupTable();
mitkLUT->SetType(mitk::LookupTable::LEGACY_BINARY);
m_BinaryLookupTable = mitkLUT->GetVtkLookupTable();
mitkLUT->SetType(mitk::LookupTable::LEGACY_RAINBOW_COLOR);
m_ColorLookupTable = mitkLUT->GetVtkLookupTable();
//do not repeat the texture (the image)
m_Texture->RepeatOff();
//set the mapper for the actor
m_Actor->SetMapper( m_Mapper );
vtkSmartPointer<vtkActor> outlineShadowActor = vtkSmartPointer<vtkActor>::New();
outlineShadowActor->SetMapper( m_Mapper );
m_Actors->AddPart( outlineShadowActor );
m_Actors->AddPart( m_Actor );
}
diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp b/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp
index c95952a41d..1f13787b5e 100644
--- a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp
+++ b/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp
@@ -1,534 +1,545 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkGL.h>
#include "mitkSurfaceGLMapper2D.h"
#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkSurface.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkVtkScalarModeProperty.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkLookupTableProperty.h"
#include <vtkPolyData.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkLinearTransform.h>
#include <vtkAbstractMapper.h>
#include <vtkPKdTree.h>
#include <vtkStripper.h>
mitk::SurfaceGLMapper2D::SurfaceGLMapper2D()
: m_Plane( vtkPlane::New() ),
m_Cutter( vtkCutter::New() ),
m_LUT( vtkLookupTable::New() ),
m_PointLocator( vtkPKdTree::New() ),
m_Stripper( vtkStripper::New() ),
m_DrawNormals(false),
m_FrontNormalLengthInPixels(10.0),
m_BackNormalLengthInPixels(10.0)
{
// default for normals on front side = green
m_FrontSideColor[0] = 0.0;
m_FrontSideColor[1] = 1.0;
m_FrontSideColor[2] = 0.0;
m_FrontSideColor[3] = 1.0;
// default for normals on back side = red
m_BackSideColor[0] = 1.0;
m_BackSideColor[1] = 0.0;
m_BackSideColor[2] = 0.0;
m_BackSideColor[3] = 1.0;
// default for line color = yellow
m_LineColor[0] = 1.0;
m_LineColor[1] = 1.0;
m_LineColor[2] = 0.0;
m_LineColor[3] = 1.0;
m_Cutter->SetCutFunction(m_Plane);
m_Cutter->GenerateValues(1,0,1);
m_LUT->SetTableRange(0,255);
m_LUT->SetNumberOfColors(255);
m_LUT->SetRampToLinear();
m_LUT->Build();
}
mitk::SurfaceGLMapper2D::~SurfaceGLMapper2D()
{
m_Plane->Delete();
m_Cutter->Delete();
m_LUT->Delete();
m_PointLocator->Delete();
m_Stripper->Delete();
}
const mitk::Surface *mitk::SurfaceGLMapper2D::GetInput(void)
{
if(m_Surface.IsNotNull())
return m_Surface;
return static_cast<const Surface * > ( GetDataNode()->GetData() );
}
void mitk::SurfaceGLMapper2D::SetDataNode( mitk::DataNode* node )
{
Superclass::SetDataNode( node );
bool useCellData;
if (dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring")) == NULL)
useCellData = false;
else
useCellData = dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring"))->GetValue();
if (!useCellData)
{
// search min/max point scalars over all time steps
double dataRange[2] = {0,0};
double range[2];
Surface::Pointer input = const_cast< Surface* >(dynamic_cast<const Surface*>( this->GetDataNode()->GetData() ));
if(input.IsNull()) return;
const TimeGeometry::Pointer inputTimeGeometry = input->GetTimeGeometry();
if(( inputTimeGeometry.IsNull() ) || ( inputTimeGeometry->CountTimeSteps() == 0 ) ) return;
for (unsigned int timestep=0; timestep<inputTimeGeometry->CountTimeSteps(); timestep++)
{
vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) continue;
vtkDataArray *vpointscalars = vtkpolydata->GetPointData()->GetScalars();
- if (vpointscalars) {
- vpointscalars->GetRange( range, 0 );
- if (dataRange[0]==0 && dataRange[1]==0) {
- dataRange[0] = range[0];
- dataRange[1] = range[1];
+ if (vpointscalars)
+ {
+ if(vpointscalars->GetLookupTable())
+ {
+ // load vtk lookup table if there is one for the scalar data
+ m_LUT->DeepCopy(vpointscalars->GetLookupTable());
}
- else {
- if (range[0] < dataRange[0]) dataRange[0] = range[0];
- if (range[1] > dataRange[1]) dataRange[1] = range[1];
+ else
+ {
+ vpointscalars->GetRange( range, 0 );
+ if (dataRange[0]==0 && dataRange[1]==0)
+ {
+ dataRange[0] = range[0];
+ dataRange[1] = range[1];
+ }
+ else
+ {
+ if (range[0] < dataRange[0]) dataRange[0] = range[0];
+ if (range[1] > dataRange[1]) dataRange[1] = range[1];
+ }
}
}
}
if (dataRange[1] - dataRange[0] > 0) {
m_LUT->SetTableRange( dataRange );
m_LUT->Build();
}
}
}
void mitk::SurfaceGLMapper2D::Paint(mitk::BaseRenderer * renderer)
{
bool visible = true;
GetDataNode()->GetVisibility(visible, renderer, "visible");
if(!visible) return;
Surface::Pointer input = const_cast<Surface*>(this->GetInput());
if(input.IsNull())
return;
//
// get the TimeGeometry of the input object
//
const TimeGeometry* inputTimeGeometry = input->GetTimeGeometry();
if(( inputTimeGeometry == NULL ) || ( inputTimeGeometry->CountTimeSteps() == 0 ) )
return;
m_LineWidth = 1;
GetDataNode()->GetIntProperty("line width", m_LineWidth, renderer);
//
// get the world time
//
ScalarType time =renderer->GetTime();
int timestep=0;
if( time > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() )
timestep = inputTimeGeometry->TimePointToTimeStep( time );
// int timestep = this->GetTimestep();
if( inputTimeGeometry->IsValidTimeStep( timestep ) == false )
return;
vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 ))
return;
//apply color and opacity read from the PropertyList
this->ApplyAllProperties(renderer);
if (m_DrawNormals)
{
m_PointLocator->SetDataSet( vtkpolydata );
m_PointLocator->BuildLocatorFromPoints( vtkpolydata->GetPoints() );
}
if(vtkpolydata!=NULL)
{
Point3D point;
Vector3D normal;
//Check if Lookup-Table is already given, else use standard one.
double* scalarLimits = m_LUT->GetTableRange();
double scalarsMin = scalarLimits[0], scalarsMax = scalarLimits[1];
vtkLookupTable *lut;
LookupTableProperty::Pointer lookupTableProp;
this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer);
if (lookupTableProp.IsNotNull() )
{
lut = lookupTableProp->GetLookupTable()->GetVtkLookupTable();
GetDataNode()->GetDoubleProperty("ScalarsRangeMinimum", scalarsMin, renderer);
GetDataNode()->GetDoubleProperty("ScalarsRangeMaximum", scalarsMax, renderer);
// check if the scalar range has been changed, e.g. manually, for the data tree node, and rebuild the LUT if necessary.
double* oldRange = lut->GetTableRange();
if( oldRange[0] != scalarsMin || oldRange[1] != scalarsMax )
{
lut->SetTableRange(scalarsMin, scalarsMax);
lut->Build();
}
}
else
{
lut = m_LUT;
}
vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(timestep);
PlaneGeometry::ConstPointer worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
assert( worldGeometry.IsNotNull() );
if (worldGeometry.IsNotNull())
{
// set up vtkPlane according to worldGeometry
point=worldGeometry->GetOrigin();
normal=worldGeometry->GetNormal(); normal.Normalize();
m_Plane->SetTransform((vtkAbstractTransform*)NULL);
}
else
{
AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldPlaneGeometry());
if(worldAbstractGeometry.IsNotNull())
{
AbstractTransformGeometry::ConstPointer surfaceAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(input->GetTimeGeometry()->GetGeometryForTimeStep(0).GetPointer());
if(surfaceAbstractGeometry.IsNotNull()) //@todo substitude by operator== after implementation, see bug id 28
{
PaintCells(renderer, vtkpolydata, worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut);
return;
}
else
{
//@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "flat plane" into a "curved plane"?
return;
// set up vtkPlane according to worldGeometry
point=const_cast<BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
FillVector3D(normal, 0, 0, 1);
m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
}
}
else
return;
}
double vp[3], vnormal[3];
vnl2vtk(point.GetVnlVector(), vp);
vnl2vtk(normal.GetVnlVector(), vnormal);
//normally, we would need to transform the surface and cut the transformed surface with the cutter.
//This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
//@todo It probably does not work for scaling operations yet:scaling operations have to be
//dealed with after the cut is performed by scaling the contour.
vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();
inversetransform->TransformPoint(vp, vp);
inversetransform->TransformNormalAtPoint(vp, vnormal, vnormal);
m_Plane->SetOrigin(vp);
m_Plane->SetNormal(vnormal);
//set data into cutter
m_Cutter->SetInputData(vtkpolydata);
m_Cutter->Update();
// m_Cutter->GenerateCutScalarsOff();
// m_Cutter->SetSortByToSortByCell();
if (m_DrawNormals)
{
m_Stripper->SetInputData( m_Cutter->GetOutput() );
// calculate the cut
m_Stripper->Update();
PaintCells(renderer, m_Stripper->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
}
else
{
PaintCells(renderer, m_Cutter->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
}
}
}
void mitk::SurfaceGLMapper2D::PaintCells(mitk::BaseRenderer* renderer, vtkPolyData* contour,
const PlaneGeometry* worldGeometry,
const DisplayGeometry* displayGeometry,
vtkLinearTransform * vtktransform,
vtkLookupTable *lut,
vtkPolyData* original3DObject)
{
// deprecated settings
bool usePointData = false;
bool useCellData = false;
this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", useCellData, renderer);
bool scalarVisibility = false;
this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility, renderer);
if(scalarVisibility)
{
VtkScalarModeProperty* scalarMode;
if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer))
{
if( (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA) ||
(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT) )
{
usePointData = true;
}
if(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA)
{
useCellData = true;
}
}
else
{
usePointData = true;
}
}
vtkPoints *vpoints = contour->GetPoints();
vtkDataArray *vpointscalars = contour->GetPointData()->GetScalars();
vtkCellArray *vlines = contour->GetLines();
vtkDataArray* vcellscalars = contour->GetCellData()->GetScalars();
Point3D p; Point2D p2d, last;
int i, j;
int numberOfLines = vlines->GetNumberOfCells();
glLineWidth( m_LineWidth );
glBegin (GL_LINES);
glColor4fv(m_LineColor);
double distanceSinceLastNormal(0.0);
vlines->InitTraversal();
for(i=0;i<numberOfLines;++i)
{
vtkIdType *cell(NULL);
vtkIdType cellSize(0);
double vp[3];
vlines->GetNextCell(cellSize, cell);
vpoints->GetPoint(cell[0], vp);
//take transformation via vtktransform into account
vtktransform->TransformPoint(vp, vp);
vtk2itk(vp, p);
//convert 3D point (in mm) to 2D point on slice (also in mm)
worldGeometry->Map(p, p2d);
//convert point (until now mm and in world coordinates) to display coordinates (units )
displayGeometry->WorldToDisplay(p2d, p2d);
last=p2d;
for(j=1; j<cellSize; ++j)
{
vpoints->GetPoint(cell[j], vp);
Point3D originalPoint;
vtk2itk(vp, originalPoint);
//take transformation via vtktransform into account
vtktransform->TransformPoint(vp, vp);
vtk2itk(vp, p);
//convert 3D point (in mm) to 2D point on slice (also in mm)
worldGeometry->Map(p, p2d);
//convert point (until now mm and in world coordinates) to display coordinates (units )
displayGeometry->WorldToDisplay(p2d, p2d);
double color[3];
if (useCellData && vcellscalars != NULL )
{
// color each cell according to cell data
lut->GetColor( vcellscalars->GetComponent(i,0),color);
glColor3f(color[0],color[1],color[2]);
glVertex2f(last[0], last[1]);
glVertex2f(p2d[0], p2d[1]);
}
else if (usePointData && vpointscalars != NULL )
{
lut->GetColor( vpointscalars->GetComponent(cell[j-1],0),color);
glColor3f(color[0],color[1],color[2]);
glVertex2f(last[0], last[1]);
lut->GetColor( vpointscalars->GetComponent(cell[j],0),color);
glColor3f(color[0],color[1],color[2]);
glVertex2f(p2d[0], p2d[1]);
}
else
{
glVertex2f(last[0], last[1]);
glVertex2f(p2d[0], p2d[1]);
// draw normals ?
if (m_DrawNormals && original3DObject)
{
distanceSinceLastNormal += sqrt((p2d[0]-last[0])*(p2d[0]-last[0]) + (p2d[1]-last[1])*(p2d[1]-last[1]));
if (distanceSinceLastNormal >= 5.0)
{
distanceSinceLastNormal = 0.0;
vtkPointData* pointData = original3DObject->GetPointData();
if (!pointData) break;
vtkDataArray* normalsArray = pointData->GetNormals();
if (!normalsArray) break;
// find 3D point closest to the currently drawn point
double distance(0.0);
vtkIdType closestPointId = m_PointLocator->FindClosestPoint(originalPoint[0], originalPoint[1], originalPoint[2], distance);
if (closestPointId >= 0)
{
// find normal of 3D object at this 3D point
double* normal = normalsArray->GetTuple3(closestPointId);
double transformedNormal[3];
vtktransform->TransformNormal(normal, transformedNormal);
Vector3D normalITK;
vtk2itk(transformedNormal, normalITK);
normalITK.Normalize();
// calculate a point (point from the cut 3D object) + (normal vector of closest point)
Point3D tip3D = p + normalITK;
// map this point into our 2D coordinate system
Point2D tip2D;
worldGeometry->Map(tip3D, tip2D);
displayGeometry->WorldToDisplay(tip2D, tip2D);
// calculate 2D vector from point to point+normal, normalize it to standard length
Vector2D tipVectorGLFront = tip2D - p2d;
tipVectorGLFront.Normalize();
tipVectorGLFront *= m_FrontNormalLengthInPixels;
Vector2D tipVectorGLBack = p2d - tip2D;
tipVectorGLBack.Normalize();
tipVectorGLBack *= m_BackNormalLengthInPixels;
Point2D tipPoint2D = p2d + tipVectorGLFront;
Point2D backTipPoint2D = p2d + tipVectorGLBack;
// draw normalized mapped normal vector
glColor4f(m_BackSideColor[0], m_BackSideColor[1], m_BackSideColor[2], m_BackSideColor[3]); // red backside
glVertex2f(p2d[0], p2d[1]);
glVertex2f(tipPoint2D[0], tipPoint2D[1]);
glColor4f(m_FrontSideColor[0], m_FrontSideColor[1], m_FrontSideColor[2], m_FrontSideColor[3]); // green backside
glVertex2f(p2d[0], p2d[1]);
glVertex2f(backTipPoint2D[0], backTipPoint2D[1]);
glColor4fv(m_LineColor); // back to line color
}
}
}
}
last=p2d;
}
}
glEnd();
glLineWidth(1.0);
}
void mitk::SurfaceGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "line width", IntProperty::New(2), renderer, overwrite );
node->AddProperty( "scalar mode", VtkScalarModeProperty::New(), renderer, overwrite );
node->AddProperty( "draw normals 2D", BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "invert normals", BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "front color", ColorProperty::New(0.0, 1.0, 0.0), renderer, overwrite );
node->AddProperty( "back color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite );
node->AddProperty( "front normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite );
node->AddProperty( "back normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite );
node->AddProperty( "layer", mitk::IntProperty::New(100), renderer, overwrite);
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
void mitk::SurfaceGLMapper2D::ApplyAllProperties(mitk::BaseRenderer* renderer)
{
ApplyColorAndOpacityProperties(renderer);
DataNode * node = GetDataNode();
if(node == NULL)
{
return;
}
node->GetBoolProperty("draw normals 2D", m_DrawNormals, renderer);
// check for color and opacity properties, use it for rendering if they exists
node->GetColor(m_LineColor, renderer, "color");
node->GetOpacity(m_LineColor[3], renderer, "opacity");
bool invertNormals(false);
node->GetBoolProperty("invert normals", invertNormals, renderer);
if (!invertNormals)
{
node->GetColor(m_FrontSideColor, renderer, "front color");
node->GetOpacity(m_FrontSideColor[3], renderer, "opacity");
node->GetColor(m_BackSideColor, renderer, "back color");
node->GetOpacity(m_BackSideColor[3], renderer, "opacity");
node->GetFloatProperty( "front normal lenth (px)", m_FrontNormalLengthInPixels, renderer );
node->GetFloatProperty( "back normal lenth (px)", m_BackNormalLengthInPixels, renderer );
}
else
{
node->GetColor(m_FrontSideColor, renderer, "back color");
node->GetOpacity(m_FrontSideColor[3], renderer, "opacity");
node->GetColor(m_BackSideColor, renderer, "front color");
node->GetOpacity(m_BackSideColor[3], renderer, "opacity");
node->GetFloatProperty( "back normal lenth (px)", m_FrontNormalLengthInPixels, renderer );
node->GetFloatProperty( "front normal lenth (px)", m_BackNormalLengthInPixels, renderer );
}
}
diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.cpp b/Core/Code/Rendering/mitkVtkPropRenderer.cpp
index 0805f2639a..653d5d0a88 100644
--- a/Core/Code/Rendering/mitkVtkPropRenderer.cpp
+++ b/Core/Code/Rendering/mitkVtkPropRenderer.cpp
@@ -1,978 +1,1007 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkVtkPropRenderer.h"
// MAPPERS
#include "mitkMapper.h"
#include "mitkImageVtkMapper2D.h"
#include "mitkVtkMapper.h"
#include "mitkGLMapper.h"
#include "mitkPlaneGeometryDataVtkMapper3D.h"
#include "mitkImageSliceSelector.h"
#include "mitkRenderingManager.h"
#include "mitkGL.h"
#include "mitkGeometry3D.h"
#include "mitkDisplayGeometry.h"
#include "mitkLevelWindow.h"
#include "mitkCameraController.h"
#include "mitkVtkInteractorCameraController.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
#include "mitkSurface.h"
#include "mitkNodePredicateDataType.h"
#include "mitkVtkInteractorStyle.h"
#include "mitkAbstractTransformGeometry.h"
// VTK
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkLight.h>
#include <vtkLightKit.h>
#include <vtkRenderWindow.h>
#include <vtkLinearTransform.h>
#include <vtkCamera.h>
#include <vtkWorldPointPicker.h>
#include <vtkPointPicker.h>
#include <vtkCellPicker.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkProp.h>
#include <vtkAssemblyPath.h>
#include <vtkAssemblyNode.h>
#include <vtkMapper.h>
#include <vtkSmartPointer.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
mitk::VtkPropRenderer::VtkPropRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm, mitk::BaseRenderer::RenderingMode::Type renderingMode )
: BaseRenderer(name,renWin, rm, renderingMode ),
m_VtkMapperPresent(false),
m_CameraInitializedForMapperID(0)
{
didCount=false;
m_WorldPointPicker = vtkWorldPointPicker::New();
m_PointPicker = vtkPointPicker::New();
m_PointPicker->SetTolerance( 0.0025 );
m_CellPicker = vtkCellPicker::New();
m_CellPicker->SetTolerance( 0.0025 );
mitk::PlaneGeometryDataVtkMapper3D::Pointer geometryMapper = mitk::PlaneGeometryDataVtkMapper3D::New();
m_CurrentWorldPlaneGeometryMapper = geometryMapper;
m_CurrentWorldPlaneGeometryNode->SetMapper(2, geometryMapper);
m_LightKit = vtkLightKit::New();
m_LightKit->AddLightsToRenderer(m_VtkRenderer);
m_PickingMode = WorldPointPicking;
m_TextRenderer = vtkRenderer::New();
m_TextRenderer->SetRenderWindow(renWin);
m_TextRenderer->SetInteractive(0);
m_TextRenderer->SetErase(0);
}
/*!
\brief Destructs the VtkPropRenderer.
*/
mitk::VtkPropRenderer::~VtkPropRenderer()
{
// Workaround for GLDisplayList Bug
{
m_MapperID=0;
checkState();
}
if (m_LightKit != NULL)
m_LightKit->Delete();
if (m_VtkRenderer!=NULL)
{
m_CameraController = NULL;
m_VtkRenderer->Delete();
m_VtkRenderer = NULL;
}
else
m_CameraController = NULL;
if (m_WorldPointPicker != NULL)
m_WorldPointPicker->Delete();
if (m_PointPicker != NULL)
m_PointPicker->Delete();
if (m_CellPicker != NULL)
m_CellPicker->Delete();
if (m_TextRenderer != NULL)
m_TextRenderer->Delete();
}
void mitk::VtkPropRenderer::SetDataStorage( mitk::DataStorage* storage )
{
if ( storage == NULL )
return;
BaseRenderer::SetDataStorage(storage);
static_cast<mitk::PlaneGeometryDataVtkMapper3D*>(m_CurrentWorldPlaneGeometryMapper.GetPointer())->SetDataStorageForTexture( m_DataStorage.GetPointer() );
// Compute the geometry from the current data tree bounds and set it as world geometry
this->SetWorldGeometryToDataStorageBounds();
}
bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds()
{
if ( m_DataStorage.IsNull() )
return false;
//initialize world geometry
mitk::TimeGeometry::Pointer geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D( NULL, "includeInBoundingBox" );
if ( geometry.IsNull() )
return false;
this->SetWorldTimeGeometry(geometry);
//this->GetDisplayGeometry()->SetSizeInDisplayUnits( this->m_TextRenderer->GetRenderWindow()->GetSize()[0], this->m_TextRenderer->GetRenderWindow()->GetSize()[1] );
this->GetDisplayGeometry()->Fit();
this->GetVtkRenderer()->ResetCamera();
this->Modified();
return true;
}
/*!
\brief
Called by the vtkMitkRenderProp in order to start MITK rendering process.
*/
int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type)
{
// Do we have objects to render?
if ( this->GetEmptyWorldGeometry())
return 0;
if ( m_DataStorage.IsNull())
return 0;
// Update mappers and prepare mapper queue
if (type == VtkPropRenderer::Opaque)
this->PrepareMapperQueue();
//go through the generated list and let the sorted mappers paint
bool lastVtkBased = true;
//bool sthVtkBased = false;
for(MappersMapType::iterator it = m_MappersMap.begin(); it != m_MappersMap.end(); it++)
{
Mapper * mapper = (*it).second;
VtkMapper* vtkmapper = dynamic_cast<VtkMapper*>(mapper);
if(vtkmapper)
{
//sthVtkBased = true;
if(!lastVtkBased)
{
Disable2DOpenGL();
lastVtkBased = true;
}
}
else if(lastVtkBased)
{
Enable2DOpenGL();
lastVtkBased = false;
}
mapper->MitkRender(this, type);
}
this->UpdateOverlays();
if (lastVtkBased == false)
Disable2DOpenGL();
// Render text
if (type == VtkPropRenderer::Overlay)
{
if (m_TextCollection.size() > 0)
{
m_TextRenderer->SetViewport( this->GetVtkRenderer()->GetViewport() );
for (TextMapType::iterator it = m_TextCollection.begin(); it != m_TextCollection.end() ; it++)
m_TextRenderer->AddViewProp((*it).second);
m_TextRenderer->Render();
}
}
return 1;
}
/*!
\brief PrepareMapperQueue iterates the datatree
PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer.
*/
void mitk::VtkPropRenderer::PrepareMapperQueue()
{
// variable for counting LOD-enabled mappers
m_NumberOfVisibleLODEnabledMappers = 0;
// Do we have to update the mappers ?
if ( m_LastUpdateTime < GetMTime() || m_LastUpdateTime < GetDisplayGeometry()->GetMTime() ) {
Update();
}
else if (m_MapperID>=1 && m_MapperID < 6)
Update();
// remove all text properties before mappers will add new ones
m_TextRenderer->RemoveAllViewProps();
for ( unsigned int i=0; i<m_TextCollection.size(); i++ )
{
m_TextCollection[i]->Delete();
}
m_TextCollection.clear();
// clear priority_queue
m_MappersMap.clear();
int mapperNo = 0;
//DataStorage
if( m_DataStorage.IsNull() )
return;
DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll();
for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it)
{
DataNode::Pointer node = it->Value();
if ( node.IsNull() )
continue;
mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID);
if ( mapper.IsNull() )
continue;
bool visible = true;
node->GetVisibility(visible, this, "visible");
// The information about LOD-enabled mappers is required by RenderingManager
if ( mapper->IsLODEnabled( this ) && visible )
{
++m_NumberOfVisibleLODEnabledMappers;
}
// mapper without a layer property get layer number 1
int layer = 1;
node->GetIntProperty("layer", layer, this);
int nr = (layer<<16) + mapperNo;
m_MappersMap.insert( std::pair< int, Mapper * >( nr, mapper ) );
mapperNo++;
}
}
/*!
\brief
Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection)
*/
void mitk::VtkPropRenderer::Enable2DOpenGL()
{
GLint iViewport[4];
// Get a copy of the viewport
glGetIntegerv( GL_VIEWPORT, iViewport );
// Save a copy of the projection matrix so that we can restore it
// when it's time to do 3D rendering again.
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
// Set up the orthographic projection
const DisplayGeometry* displayGeometry = this->GetDisplayGeometry();
float displayGeometryWidth = displayGeometry->GetSizeInDisplayUnits()[0];
float displayGeometryHeight = displayGeometry->GetSizeInDisplayUnits()[1];
float viewportWidth = iViewport[2];
float viewportHeight = iViewport[3];
/*
The following makes OpenGL mappers draw into the same viewport
that is used by VTK when someone calls vtkRenderer::SetViewport().
The parameters of glOrtho describe what "input" coordinates
(display coordinates generated by the OpenGL mappers) are transformed
into the region defined by the viewport. The call has to consider
that the scene is fit vertically and centered horizontally.
Problem: this is a crude first step towards rendering into viewports.
- mitkViewportRenderingTest demonstrates the non-interactive rendering
that is now possible
- interactors that measure mouse movement in pixels will
probably run into problems with display-to-world transformation
A proper solution should probably modify the DisplayGeometry to
correctly describe the viewport.
*/
// iViewport is (x,y,width,height)
// glOrtho expects (left,right,bottom,top,znear,zfar)
glOrtho( 0
- 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight
+ 0.5 * (displayGeometryWidth - displayGeometryHeight)
,
displayGeometryWidth
+ 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight
- 0.5 * (displayGeometryWidth - displayGeometryHeight)
,
0, displayGeometryHeight,
-1.0, 1.0
);
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
// Make sure depth testing and lighting are disabled for 2D rendering until
// we are finished rendering in 2D
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
// disable the texturing here so crosshair is painted in the correct colors
// vtk will reenable texturing every time it is needed
glDisable( GL_TEXTURE_1D );
glDisable( GL_TEXTURE_2D );
glLineWidth(1.0);
}
/*!
\brief Initialize the VtkPropRenderer
Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection)
*/
void mitk::VtkPropRenderer::Disable2DOpenGL()
{
glPopAttrib();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
void mitk::VtkPropRenderer::Update(mitk::DataNode* datatreenode)
{
if(datatreenode!=NULL)
{
mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID);
if(mapper.IsNotNull())
{
GLMapper* glmapper=dynamic_cast<GLMapper*>(mapper.GetPointer());
if(GetDisplayGeometry()->IsValid())
{
if(glmapper != NULL)
{
glmapper->Update(this);
m_VtkMapperPresent=false;
}
else
{
VtkMapper* vtkmapper=dynamic_cast<VtkMapper*>(mapper.GetPointer());
if(vtkmapper != NULL)
{
vtkmapper->Update(this);
vtkmapper->UpdateVtkTransform(this);
m_VtkMapperPresent=true;
}
}
}
}
}
}
void mitk::VtkPropRenderer::Update()
{
if( m_DataStorage.IsNull() )
return;
m_VtkMapperPresent = false;
mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
Update(it->Value());
Modified();
m_LastUpdateTime = GetMTime();
}
/*!
\brief
This method is called from the two Constructors
*/
void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow* renderWindow)
{
BaseRenderer::InitRenderer(renderWindow);
if(renderWindow == NULL)
{
m_InitNeeded = false;
m_ResizeNeeded = false;
return;
}
m_InitNeeded = true;
m_ResizeNeeded = true;
m_LastUpdateTime = 0;
}
/*!
\brief Resize the OpenGL Window
*/
void mitk::VtkPropRenderer::Resize(int w, int h)
{
BaseRenderer::Resize(w, h);
m_RenderingManager->RequestUpdate(this->GetRenderWindow());
}
void mitk::VtkPropRenderer::InitSize(int w, int h)
{
m_RenderWindow->SetSize(w,h);
Superclass::InitSize(w, h);
Modified();
Update();
if(m_VtkRenderer!=NULL)
{
int w=vtkObject::GetGlobalWarningDisplay();
vtkObject::GlobalWarningDisplayOff();
m_VtkRenderer->ResetCamera();
vtkObject::SetGlobalWarningDisplay(w);
}
}
void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId)
{
if(m_MapperID != mapperId)
Superclass::SetMapperID(mapperId);
// Workaround for GL Displaylist Bug
checkState();
}
/*!
\brief Activates the current renderwindow.
*/
void mitk::VtkPropRenderer::MakeCurrent()
{
if(m_RenderWindow!=NULL)
m_RenderWindow->MakeCurrent();
}
void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const
{
if(m_VtkMapperPresent)
{
//m_WorldPointPicker->SetTolerance (0.0001);
switch ( m_PickingMode )
{
case (WorldPointPicking) :
{
m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer);
vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint);
break;
}
case (PointPicking) :
{
// create a new vtkRenderer
// give it all necessary information (camera position, etc.)
// get all surfaces from datastorage, get actors from them
// add all those actors to the new renderer
// give this new renderer to pointpicker
/*
vtkRenderer* pickingRenderer = vtkRenderer::New();
pickingRenderer->SetActiveCamera( );
DataStorage* dataStorage = m_DataStorage;
TNodePredicateDataType<Surface> isSurface;
DataStorage::SetOfObjects::ConstPointer allSurfaces = dataStorage->GetSubset( isSurface );
MITK_INFO << "in picking: got " << allSurfaces->size() << " surfaces." << std::endl;
for (DataStorage::SetOfObjects::const_iterator iter = allSurfaces->begin();
iter != allSurfaces->end();
++iter)
{
const DataNode* currentNode = *iter;
VtkMapper3D* baseVtkMapper3D = dynamic_cast<VtkMapper3D*>( currentNode->GetMapper( BaseRenderer::Standard3D ) );
if ( baseVtkMapper3D )
{
vtkActor* actor = dynamic_cast<vtkActor*>( baseVtkMapper3D->GetViewProp() );
if (actor)
{
MITK_INFO << "a" << std::flush;
pickingRenderer->AddActor( actor );
}
}
}
MITK_INFO << ";" << std::endl;
*/
m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer);
vtk2itk(m_PointPicker->GetPickPosition(), worldPoint);
break;
}
case(CellPicking) :
{
m_CellPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer);
vtk2itk(m_CellPicker->GetPickPosition(), worldPoint);
break;
}
}
}
else
{
Superclass::PickWorldPoint(displayPoint, worldPoint);
}
}
mitk::DataNode *
mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const
{
if ( m_VtkMapperPresent )
{
m_CellPicker->InitializePickList();
// Iterate over all DataStorage objects to determine all vtkProps intended
// for picking
DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll();
for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin();
it != allObjects->End();
++it )
{
DataNode *node = it->Value();
if ( node == NULL )
continue;
bool pickable = false;
node->GetBoolProperty( "pickable", pickable );
if ( !pickable )
continue;
VtkMapper *mapper = dynamic_cast < VtkMapper * > ( node->GetMapper( m_MapperID ) );
if ( mapper == NULL )
continue;
vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this );
if ( prop == NULL )
continue;
m_CellPicker->AddPickList( prop );
}
// Do the picking and retrieve the picked vtkProp (if any)
m_CellPicker->PickFromListOn();
m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer );
m_CellPicker->PickFromListOff();
vtk2itk( m_CellPicker->GetPickPosition(), worldPosition );
vtkProp *prop = m_CellPicker->GetViewProp();
if ( prop == NULL )
{
return NULL;
}
// Iterate over all DataStorage objects to determine if the retrieved
// vtkProp is owned by any associated mapper.
for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin();
it != allObjects->End();
++it)
{
DataNode::Pointer node = it->Value();
if ( node.IsNull() )
continue;
mitk::Mapper * mapper = node->GetMapper( m_MapperID );
if ( mapper == NULL)
continue;
mitk::VtkMapper * vtkmapper = dynamic_cast< VtkMapper * >(mapper);
if(vtkmapper){
//if vtk-based, then ...
if ( vtkmapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) )
{
return node;
}
}
}
return NULL;
}
else
{
return Superclass::PickObject( displayPosition, worldPosition );
}
};
/*!
\brief Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function
in order to get a vtkTextProperty. This property enables the setup of font, font size, etc.
*/
int mitk::VtkPropRenderer::WriteSimpleText(std::string text, double posX, double posY, double color1, double color2, double color3, float opacity)
{
if(!text.empty())
{
Point2D p;
p[0] = posX;
p[1] = posY;
p = TransformOpenGLPointToViewport(p);
vtkTextActor* textActor = vtkTextActor::New();
textActor->SetPosition(p[0], p[1]);
textActor->SetInput(text.c_str());
textActor->SetTextScaleModeToNone();
textActor->GetTextProperty()->SetColor(color1, color2, color3); //TODO: Read color from node property
textActor->GetTextProperty()->SetOpacity( opacity );
int text_id = m_TextCollection.size();
m_TextCollection.insert(TextMapType::value_type(text_id,textActor));
return text_id;
}
else
{
return -1;
}
}
/*!
\brief Can be used in order to get a vtkTextProperty for a specific text_id. This property enables the setup of font, font size, etc.
*/
vtkTextProperty* mitk::VtkPropRenderer::GetTextLabelProperty(int text_id)
{
return this->m_TextCollection[text_id]->GetTextProperty();
}
void mitk::VtkPropRenderer::InitPathTraversal()
{
if (m_DataStorage.IsNotNull())
{
m_PickingObjects = m_DataStorage->GetAll();
m_PickingObjectsIterator = m_PickingObjects->begin();
}
}
+int mitk::VtkPropRenderer::GetNumberOfPaths()
+{
+ if (m_DataStorage.IsNull()) {
+ return 0;
+ }
+
+ int nPaths = 0;
+ DataStorage::SetOfObjects::ConstPointer objects = m_DataStorage->GetAll();
+ for (DataStorage::SetOfObjects::const_iterator iter = objects->begin(); iter != objects->end(); ++iter) {
+ Mapper* mapper = (*iter)->GetMapper(BaseRenderer::Standard3D);
+ if (mapper)
+ {
+ VtkMapper* vtkmapper = dynamic_cast<VtkMapper*>(mapper);
+ if (vtkmapper)
+ {
+ vtkProp* prop = vtkmapper->GetVtkProp(this);
+ if (prop && prop->GetVisibility())
+ {
+ ++nPaths;
+ }
+ }
+ }
+ }
+
+ return nPaths;
+}
+
vtkAssemblyPath* mitk::VtkPropRenderer::GetNextPath()
{
if (m_DataStorage.IsNull() )
{
return NULL;
}
if ( m_PickingObjectsIterator == m_PickingObjects->end() )
{
return NULL;
}
vtkAssemblyPath* returnPath = vtkAssemblyPath::New();
//returnPath->Register(NULL);
bool success = false;
while (!success)
{
// loop until AddNode can be called successfully
const DataNode* node = *m_PickingObjectsIterator;
if (node)
{
Mapper* mapper = node->GetMapper( BaseRenderer::Standard3D );
if (mapper)
{
VtkMapper* vtkmapper = dynamic_cast<VtkMapper*>( mapper );
if (vtkmapper)
{
vtkProp* prop = vtkmapper->GetVtkProp(this);
if ( prop && prop->GetVisibility() )
{
// add to assembly path
returnPath->AddNode( prop, prop->GetMatrix() );
success = true;
}
}
}
}
++m_PickingObjectsIterator;
if ( m_PickingObjectsIterator == m_PickingObjects->end() ) break;
}
if ( success )
{
return returnPath;
}
else
{
return NULL;
}
}
void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow* /*renWin*/)
{
if( m_DataStorage.IsNull() )
return;
DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll();
for (DataStorage::SetOfObjects::const_iterator iter = allObjects->begin(); iter != allObjects->end(); ++iter)
{
DataNode::Pointer node = *iter;
if ( node.IsNull() )
continue;
Mapper * mapper = node->GetMapper(m_MapperID);
if (mapper)
{
VtkMapper* vtkmapper = dynamic_cast<VtkMapper*>( mapper );
if(vtkmapper)
vtkmapper->ReleaseGraphicsResources(this);
}
}
}
const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const
{
return m_WorldPointPicker;
}
const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const
{
return m_PointPicker;
}
const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const
{
return m_CellPicker;
}
mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const
{
return m_MappersMap;
}
// Workaround for GL Displaylist bug
static int glWorkAroundGlobalCount = 0;
bool mitk::VtkPropRenderer::useImmediateModeRendering()
{
return glWorkAroundGlobalCount>1;
}
void mitk::VtkPropRenderer::checkState()
{
if (m_MapperID == Standard3D)
{
if (!didCount)
{
didCount = true;
glWorkAroundGlobalCount++;
if (glWorkAroundGlobalCount == 2)
{
MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers";
// vtkMapper::GlobalImmediateModeRenderingOn();
}
//MITK_INFO << "GLOBAL 3D INCREASE " << glWorkAroundGlobalCount << "\n";
}
}
else
{
if(didCount)
{
didCount=false;
glWorkAroundGlobalCount--;
if(glWorkAroundGlobalCount==1)
{
MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers";
// vtkMapper::GlobalImmediateModeRenderingOff();
}
//MITK_INFO << "GLOBAL 3D DECREASE " << glWorkAroundGlobalCount << "\n";
}
}
}
//### Contains all methods which are neceassry before each VTK Render() call
void mitk::VtkPropRenderer::PrepareRender()
{
if ( this->GetMapperID() != m_CameraInitializedForMapperID )
{
Initialize2DvtkCamera(); //Set parallel projection etc.
}
AdjustCameraToScene(); //Prepare camera for 2D render windows
}
bool mitk::VtkPropRenderer::Initialize2DvtkCamera()
{
if ( this->GetMapperID() == Standard3D )
{
//activate parallel projection for 2D
this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false);
- this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( vtkInteractorStyleTrackballCamera::New() );
+ vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
+ this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
m_CameraInitializedForMapperID = Standard3D;
}
else if( this->GetMapperID() == Standard2D)
{
//activate parallel projection for 2D
this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true);
//turn the light out in the scene in order to render correct grey values.
//TODO Implement a property for light in the 2D render windows (in another method)
this->GetVtkRenderer()->RemoveAllLights();
- this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( mitkVtkInteractorStyle::New() );
+ vtkSmartPointer<mitkVtkInteractorStyle> style = vtkSmartPointer<mitkVtkInteractorStyle>::New();
+ this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
m_CameraInitializedForMapperID = Standard2D;
}
return true;
}
void mitk::VtkPropRenderer::AdjustCameraToScene(){
if(this->GetMapperID() == Standard2D)
{
const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry();
double objectHeightInMM = this->GetCurrentWorldPlaneGeometry()->GetExtentInMM(1);//the height of the current object slice in mm
double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in)
double zoomFactor = objectHeightInMM/displayHeightInMM; //displayGeometry->GetScaleFactorMMPerDisplayUnit()
//determine how much of the object can be displayed
Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin)
Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2)
//Scale the rendered object:
//The image is scaled by a single factor, because in an orthographic projection sizes
//are preserved (so you cannot scale X and Y axis with different parameters). The
//parameter sets the size of the total display-volume. If you set this to the image
//height, the image plus a border with the size of the image will be rendered.
//Therefore, the size is imageHeightInMM / 2.
this->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(objectHeightInMM*0.5 );
//zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely.
this->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor);
//the center of the view-plane
double viewPlaneCenter[3];
viewPlaneCenter[0] = displayGeometryCenterInMM[0];
viewPlaneCenter[1] = displayGeometryCenterInMM[1];
viewPlaneCenter[2] = 0.0; //the view-plane is located in the XY-plane with Z=0.0
//define which direction is "up" for the ciamera (like default for vtk (0.0, 1.0, 0.0)
double cameraUp[3];
cameraUp[0] = 0.0;
cameraUp[1] = 1.0;
cameraUp[2] = 0.0;
//the position of the camera (center[0], center[1], 900000)
double cameraPosition[3];
cameraPosition[0] = viewPlaneCenter[0];
cameraPosition[1] = viewPlaneCenter[1];
cameraPosition[2] = 900000.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker.
//set the camera corresponding to the textured plane
vtkSmartPointer<vtkCamera> camera = this->GetVtkRenderer()->GetActiveCamera();
if (camera)
{
camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal)
camera->SetFocalPoint( viewPlaneCenter ); //set the focal point to the center of the textured plane
camera->SetViewUp( cameraUp ); //set the view-up for the camera
// double distance = sqrt((cameraPosition[2]-viewPlaneCenter[2])*(cameraPosition[2]-viewPlaneCenter[2]));
// camera->SetClippingRange(distance-50, distance+50); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker.
camera->SetClippingRange(0.1, 1000000); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker.
}
const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( this->GetCurrentWorldPlaneGeometry() );
const AbstractTransformGeometry *abstractTransformGeometry = dynamic_cast< const AbstractTransformGeometry * >( planeGeometry );
if ( planeGeometry != NULL && !abstractTransformGeometry)
{
//Transform the camera to the current position (transveral, coronal and saggital plane).
//This is necessary, because the SetUserTransform() method does not manipulate the vtkCamera.
//(Without not all three planes would be visible).
vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
Point3D origin;
Vector3D right, bottom, normal;
origin = planeGeometry->GetOrigin();
right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace)
bottom = planeGeometry->GetAxisVector( 1 );
normal = planeGeometry->GetNormal();
right.Normalize();
bottom.Normalize();
normal.Normalize();
matrix->SetElement(0, 0, right[0]);
matrix->SetElement(1, 0, right[1]);
matrix->SetElement(2, 0, right[2]);
matrix->SetElement(0, 1, bottom[0]);
matrix->SetElement(1, 1, bottom[1]);
matrix->SetElement(2, 1, bottom[2]);
matrix->SetElement(0, 2, normal[0]);
matrix->SetElement(1, 2, normal[1]);
matrix->SetElement(2, 2, normal[2]);
matrix->SetElement(0, 3, origin[0]);
matrix->SetElement(1, 3, origin[1]);
matrix->SetElement(2, 3, origin[2]);
matrix->SetElement(3, 0, 0.0);
matrix->SetElement(3, 1, 0.0);
matrix->SetElement(3, 2, 0.0);
matrix->SetElement(3, 3, 1.0);
trans->SetMatrix(matrix);
//Transform the camera to the current position (transveral, coronal and saggital plane).
this->GetVtkRenderer()->GetActiveCamera()->ApplyTransform(trans);
}
}
}
mitk::Point2D mitk::VtkPropRenderer::TransformOpenGLPointToViewport( mitk::Point2D point )
{
GLint iViewport[4];
// Get a copy of the viewport
glGetIntegerv( GL_VIEWPORT, iViewport );
const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry();
float displayGeometryWidth = displayGeometry->GetSizeInDisplayUnits()[0];
float displayGeometryHeight = displayGeometry->GetSizeInDisplayUnits()[1];
float viewportWidth = iViewport[2];
float viewportHeight = iViewport[3]; // seemingly right
float zoom = viewportHeight / displayGeometryHeight;
// see glOrtho call above for more explanation
point[0] +=
0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight
- 0.5 * (displayGeometryWidth - displayGeometryHeight)
;
point[0] *= zoom;
point[1] *= zoom;
return point;
}
diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.h b/Core/Code/Rendering/mitkVtkPropRenderer.h
index 31024e0f8c..14b82fde55 100644
--- a/Core/Code/Rendering/mitkVtkPropRenderer.h
+++ b/Core/Code/Rendering/mitkVtkPropRenderer.h
@@ -1,256 +1,258 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D
#define MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D
#include <MitkCoreExports.h>
#include "mitkBaseRenderer.h"
#include "mitkDataStorage.h"
#include "mitkRenderingManager.h"
#include <itkCommand.h>
#include <map>
#include <utility>
class vtkRenderWindow;
class vtkLight;
class vtkLightKit;
class vtkWorldPointPicker;
class vtkPointPicker;
class vtkCellPicker;
class vtkTextActor;
class vtkTextProperty;
class vtkAssemblyPath;
namespace mitk
{
class Mapper;
/*!
\brief VtkPropRenderer
VtkPropRenderer organizes the MITK rendering process. The MITK rendering process is completely integrated into the VTK rendering pipeline.
The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes.
VtkPropRenderer replaces the old OpenGLRenderer.
\sa rendering
\ingroup rendering
*/
class MITK_CORE_EXPORT VtkPropRenderer : public BaseRenderer
{
// Workaround for Displaylistbug
private:
bool didCount;
void checkState();
// Workaround END
public:
mitkClassMacro(VtkPropRenderer,BaseRenderer);
mitkNewMacro3Param(VtkPropRenderer, const char*, vtkRenderWindow *, mitk::RenderingManager* );
mitkNewMacro4Param(VtkPropRenderer, const char*, vtkRenderWindow *, mitk::RenderingManager*, mitk::BaseRenderer::RenderingMode::Type );
typedef std::map<int,Mapper*> MappersMapType;
// Render - called by vtkMitkRenderProp, returns the number of props rendered
enum RenderType{Opaque,Translucent,Overlay,Volumetric};
int Render(RenderType type);
/** \brief This methods contains all method neceassary before a VTK Render() call */
virtual void PrepareRender();
// Active current renderwindow
virtual void MakeCurrent();
virtual void SetDataStorage( mitk::DataStorage* storage ); ///< set the datastorage that will be used for rendering
virtual void InitRenderer(vtkRenderWindow* renderwindow);
virtual void Update(mitk::DataNode* datatreenode);
virtual void SetMapperID(const MapperSlotId mapperId);
// Size
virtual void InitSize(int w, int h);
virtual void Resize(int w, int h);
// Picking
enum PickingMode{ WorldPointPicking, PointPicking, CellPicking};
/** \brief Set the picking mode.
This method is used to set the picking mode for 3D object picking. The user can select one of
the three options WorldPointPicking, PointPicking and CellPicking. The first option uses the zBuffer
from graphics rendering, the second uses the 3D points from the closest surface mesh, and the third
option uses the cells of that mesh. The last option is the slowest, the first one the fastest.
However, the first option cannot use transparent data object and the tolerance of the picked position
to the selected point should be considered. PointPicking also need a tolerance around the picking
position to select the closest point in the mesh. The CellPicker performs very well, if the
foreground surface part (i.e. the surfacepart that is closest to the scene's cameras) needs to be
picked. */
itkSetEnumMacro( PickingMode, PickingMode );
itkGetEnumMacro( PickingMode, PickingMode );
virtual void PickWorldPoint(const Point2D& displayPoint, Point3D& worldPoint) const;
virtual mitk::DataNode *PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const;
// Simple text rendering method
int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0, float opacity = 1.0);
vtkTextProperty * GetTextLabelProperty(int text_id);
// Initialization / geometry handling
/** This method calculates the bounds of the DataStorage (if it contains any
* valid data), creates a geometry from these bounds and sets it as world
* geometry of the renderer.
*
* Call this method to re-initialize the renderer to the current DataStorage
* (e.g. after loading an additional dataset), to ensure that the view is
* aligned correctly.
*/
virtual bool SetWorldGeometryToDataStorageBounds();
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
void InitPathTraversal();
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
vtkAssemblyPath* GetNextPath();
+ int GetNumberOfPaths();
+
const vtkWorldPointPicker *GetWorldPointPicker() const;
const vtkPointPicker *GetPointPicker() const;
const vtkCellPicker *GetCellPicker() const;
/**
* \brief Release vtk-based graphics resources. Called by
* vtkMitkRenderProp::ReleaseGraphicsResources.
*/
virtual void ReleaseGraphicsResources(vtkWindow *renWin);
MappersMapType GetMappersMap() const;
static bool useImmediateModeRendering();
protected:
VtkPropRenderer( const char* name = "VtkPropRenderer", vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm = NULL, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard );
virtual ~VtkPropRenderer();
virtual void Update();
/**
\brief Convert display geometry coordinates to VTK coordinates.
For use within WriteSimpleText: the input is display geometry coordinates
but the text actor needs positions that fit in a specified viewport.
Conversion is done in this method.
*/
mitk::Point2D TransformOpenGLPointToViewport( mitk::Point2D point );
private:
/** \brief This method sets up the camera on the actor (e.g. an image) of all
* 2D vtkRenderWindows. The view is centered; zooming and panning of VTK are called inside.
*
* \image html ImageMapperdisplayGeometry.png
*
* Similar to the textured plane of an image
* (cf. void mitkImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer,
* double planeBounds[6])), the mitkDisplayGeometry defines a view plane (or
* projection plane). This plane is used to set the camera parameters. The view plane
* center (VC) is important for camera positioning (cf. the image above).
*
* The following figure shows the combination of the textured plane and the view plane.
*
* \image html cameraPositioning.png
*
* The view plane center (VC) is the center of the textured plane (C) and the focal point
* (FP) at the same time. The FP defines the direction the camera faces. Since
* the textured plane is always in the XY-plane and orthographic projection is applied, the
* distance between camera and plane is theoretically irrelevant (because in the orthographic
* projection the center of projection is at infinity and the size of objects depends only on
* a scaling parameter). As a consequence, the direction of projection (DOP) is (0; 0; -1).
* The camera up vector is always defined as (0; 1; 0).
*
* \warning Due to a VTK clipping bug the distance between textured plane and camera is really huge.
* Otherwise, VTK would clip off some slices. Same applies for the clipping range size.
*
* \note The camera position is defined through the mitkDisplayGeometry.
* This facilitates zooming and panning, because the display
* geometry changes and the textured plane does not.
*
* \image html scaling.png
*
* The textured plane is scaled to fill the render window via
* camera->SetParallelScale( imageHeightInMM / 2). In the orthographic projection all extends,
* angles and sizes are preserved. Therefore, the image is scaled by one parameter which defines
* the size of the rendered image. A higher value will result in smaller images. In order to render
* just the whole image, the scale is set to half of the image height in worldcoordinates
* (cf. the picture above).
*
* For zooming purposes, a factor is computed as follows:
* factor = image height / display height (in worldcoordinates).
* When the display geometry gets smaller (zoom in), the factor becomes bigger. When the display
* geometry gets bigger (zoom out), the factor becomes smaller. The used VTK method
* camera->Zoom( factor ) also works with an inverse scale.
*/
void AdjustCameraToScene();
// switch between orthogonal opengl projection (2D rendering via mitk::GLMapper2D) and perspective projection (3D rendering)
void Enable2DOpenGL();
void Disable2DOpenGL();
// prepare all mitk::mappers for rendering
void PrepareMapperQueue();
/** \brief Set parallel projection, remove the interactor and the lights of VTK. */
bool Initialize2DvtkCamera();
bool m_InitNeeded;
bool m_ResizeNeeded;
bool m_VtkMapperPresent;
MapperSlotId m_CameraInitializedForMapperID;
// Picking
vtkWorldPointPicker * m_WorldPointPicker;
vtkPointPicker * m_PointPicker;
vtkCellPicker * m_CellPicker;
PickingMode m_PickingMode;
// Explicit use of SmartPointer to avoid circular #includes
itk::SmartPointer< mitk::Mapper > m_CurrentWorldPlaneGeometryMapper;
vtkLightKit* m_LightKit;
// sorted list of mappers
MappersMapType m_MappersMap;
// rendering of text
vtkRenderer * m_TextRenderer;
typedef std::map<unsigned int,vtkTextActor*> TextMapType;
TextMapType m_TextCollection;
DataStorage::SetOfObjects::ConstPointer m_PickingObjects;
DataStorage::SetOfObjects::const_iterator m_PickingObjectsIterator;
};
} // namespace mitk
#endif /* MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D */
diff --git a/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp b/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp
index 32ef77485d..c6176a37ee 100644
--- a/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp
+++ b/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp
@@ -1,609 +1,612 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "vtkMitkLevelWindowFilter.h"
#include <vtkImageData.h>
#include <vtkImageIterator.h>
#include <vtkLookupTable.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include "vtkObjectFactory.h"
#include <vtkInformation.h>
#include <vtkInformationVector.h>
#include <vtkStreamingDemandDrivenPipeline.h>
//used for acos etc.
#include <cmath>
//used for PI
#include <itkMath.h>
#include <mitkLogMacros.h>
static const double PI = itk::Math::pi;
vtkStandardNewMacro(vtkMitkLevelWindowFilter);
-vtkMitkLevelWindowFilter::vtkMitkLevelWindowFilter(): m_LookupTable(NULL), m_OpacityFunction(NULL), m_MinOpacity(0.0), m_MaxOpacity(255.0)
+vtkMitkLevelWindowFilter::vtkMitkLevelWindowFilter()
+ : m_LookupTable(NULL)
+ , m_OpacityFunction(NULL)
+ , m_MinOpacity(0.0)
+ , m_MaxOpacity(255.0)
{
//MITK_INFO << "mitk level/window filter uses " << GetNumberOfThreads() << " thread(s)";
}
vtkMitkLevelWindowFilter::~vtkMitkLevelWindowFilter()
{
}
unsigned long int vtkMitkLevelWindowFilter::GetMTime()
{
unsigned long mTime=this->vtkObject::GetMTime();
unsigned long time;
if ( this->m_LookupTable != NULL )
{
time = this->m_LookupTable->GetMTime();
mTime = ( time > mTime ? time : mTime );
}
return mTime;
}
void vtkMitkLevelWindowFilter::SetLookupTable(vtkScalarsToColors *lookupTable)
{
if (m_LookupTable != lookupTable)
{
m_LookupTable = lookupTable;
this->Modified();
}
}
vtkScalarsToColors* vtkMitkLevelWindowFilter::GetLookupTable()
{
return m_LookupTable;
}
void vtkMitkLevelWindowFilter::SetOpacityPiecewiseFunction(vtkPiecewiseFunction *opacityFunction)
{
if (m_OpacityFunction != opacityFunction)
{
m_OpacityFunction = opacityFunction;
this->Modified();
}
}
//This code was copied from the iil. The template works only for float and double.
//Internal method which should never be used anywhere else and should not be in th header.
// Convert color pixels from (R,G,B) to (H,S,I).
// Reference: "Digital Image Processing, 2nd. edition", R. Gonzalez and R. Woods. Prentice Hall, 2002.
template<class T>
void RGBtoHSI(T* RGB, T* HSI)
{
T R = RGB[0],
G = RGB[1],
B = RGB[2],
nR = (R<0?0:(R>255?255:R))/255,
nG = (G<0?0:(G>255?255:G))/255,
nB = (B<0?0:(B>255?255:B))/255,
m = nR<nG?(nR<nB?nR:nB):(nG<nB?nG:nB),
theta = (T)(std::acos(0.5f*((nR-nG)+(nR-nB))/std::sqrt(std::pow(nR-nG,2)+(nR-nB)*(nG-nB)))*180/PI),
sum = nR + nG + nB;
T H = 0, S = 0, I = 0;
if (theta>0) H = (nB<=nG)?theta:360-theta;
if (sum>0) S = 1 - 3/sum*m;
I = sum/3;
HSI[0] = (T)H;
HSI[1] = (T)S;
HSI[2] = (T)I;
}
//This code was copied from the iil. The template works only for float and double.
//Internal method which should never be used anywhere else and should not be in th header.
// Convert color pixels from (H,S,I) to (R,G,B).
template<class T>
void HSItoRGB(T* HSI, T* RGB)
{
T H = (T)HSI[0],
S = (T)HSI[1],
I = (T)HSI[2],
a = I*(1-S),
R = 0, G = 0, B = 0;
if (H<120) {
B = a;
R = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180)));
G = 3*I-(R+B);
} else if (H<240) {
H-=120;
R = a;
G = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180)));
B = 3*I-(R+G);
} else {
H-=240;
G = a;
B = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180)));
R = 3*I-(G+B);
}
R*=255; G*=255; B*=255;
RGB[0] = (T)(R<0?0:(R>255?255:R));
RGB[1] = (T)(G<0?0:(G>255?255:G));
RGB[2] = (T)(B<0?0:(B>255?255:B));
}
//Internal method which should never be used anywhere else and should not be in th header.
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkApplyLookupTableOnRGBA(vtkMitkLevelWindowFilter* self,
vtkImageData* inData,
vtkImageData* outData,
int outExt[6],
double* clippingBounds,
T*)
{
vtkImageIterator<T> inputIt(inData, outExt);
vtkImageIterator<T> outputIt(outData, outExt);
vtkLookupTable* lookupTable;
const int maxC = inData->GetNumberOfScalarComponents();
double tableRange[2];
lookupTable = dynamic_cast<vtkLookupTable*>(self->GetLookupTable());
lookupTable->GetTableRange(tableRange);
//parameters for RGB level window
double scale = (tableRange[1] -tableRange[0] > 0 ? 255.0 / (tableRange[1] - tableRange[0]) : 0.0);
double bias = tableRange[0] * scale;
//parameters for opaque level window
double scaleOpac = (self->GetMaxOpacity() -self->GetMinOpacity() > 0 ? 255.0 / (self->GetMaxOpacity() - self->GetMinOpacity()) : 0.0);
double biasOpac = self->GetMinOpacity() * scaleOpac;
int y = outExt[2];
// Loop through ouput pixels
while (!outputIt.IsAtEnd())
{
T* inputSI = inputIt.BeginSpan();
T* outputSI = outputIt.BeginSpan();
T* outputSIEnd = outputIt.EndSpan();
if( y >= clippingBounds[2] && y < clippingBounds[3] )
{
int x = outExt[0];
while (outputSI != outputSIEnd)
{
if ( x >= clippingBounds[0] && x < clippingBounds[1])
{
double rgb[3], alpha, hsi[3];
// level/window mechanism for intensity in HSI space
rgb[0] = static_cast<double>(*inputSI); inputSI++;
rgb[1] = static_cast<double>(*inputSI); inputSI++;
rgb[2] = static_cast<double>(*inputSI); inputSI++;
RGBtoHSI<double>(rgb,hsi);
hsi[2] = hsi[2] * 255.0 * scale - bias;
hsi[2] = (hsi[2] > 255.0 ? 255 : (hsi[2] < 0.0 ? 0 : hsi[2]));
hsi[2] /= 255.0;
HSItoRGB<double>(hsi,rgb);
*outputSI = static_cast<T>(rgb[0]); outputSI++;
*outputSI = static_cast<T>(rgb[1]); outputSI++;
*outputSI = static_cast<T>(rgb[2]); outputSI++;
unsigned char finalAlpha = 255;
//RGBA case
if(maxC >= 4)
{
// level/window mechanism for opacity
alpha = static_cast<double>(*inputSI); inputSI++;
alpha = alpha * scaleOpac - biasOpac;
if(alpha > 255.0)
{
alpha = 255.0;
}
else if(alpha < 0.0)
{
alpha = 0.0;
}
finalAlpha = static_cast<unsigned char>(alpha);
for( int c = 4; c < maxC; c++ )
inputSI++;
}
*outputSI = static_cast<T>(finalAlpha); outputSI++;
}
else
{
inputSI+=maxC;
*outputSI = 0; outputSI++;
*outputSI = 0; outputSI++;
*outputSI = 0; outputSI++;
*outputSI = 0; outputSI++;
}
x++;
}
}
else
{
while (outputSI != outputSIEnd)
{
*outputSI = 0; outputSI++;
*outputSI = 0; outputSI++;
*outputSI = 0; outputSI++;
*outputSI = 0; outputSI++;
}
}
inputIt.NextSpan();
outputIt.NextSpan();
y++;
}
}
//Internal method which should never be used anywhere else and should not be in th header.
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkApplyLookupTableOnScalarsFast(vtkMitkLevelWindowFilter *self,
vtkImageData *inData,
vtkImageData *outData,
int outExt[6],
T *)
{
vtkImageIterator<T> inputIt(inData, outExt);
vtkImageIterator<unsigned char> outputIt(outData, outExt);
double tableRange[2];
// access vtkLookupTable
vtkLookupTable* lookupTable = dynamic_cast<vtkLookupTable*>(self->GetLookupTable());
lookupTable->GetTableRange(tableRange);
// access elements of the vtkLookupTable
int * realLookupTable = reinterpret_cast<int*>(lookupTable->GetTable()->GetPointer(0));
int maxIndex = lookupTable->GetNumberOfColors() - 1;
float scale = (tableRange[1] -tableRange[0] > 0 ? (maxIndex + 1) / (tableRange[1] - tableRange[0]) : 0.0);
// ensuring that starting point is zero
float bias = - tableRange[0] * scale;
// due to later conversion to int for rounding
bias += 0.5f;
// Loop through ouput pixels
while (!outputIt.IsAtEnd())
{
unsigned char* outputSI = outputIt.BeginSpan();
unsigned char* outputSIEnd = outputIt.EndSpan();
T* inputSI = inputIt.BeginSpan();
while (outputSI != outputSIEnd)
{
// map to an index
int idx = static_cast<int>( *inputSI * scale + bias );
if (idx < 0)
idx = 0;
else if (idx > maxIndex)
idx = maxIndex;
* reinterpret_cast<int*>(outputSI) = realLookupTable[idx];
inputSI++;
outputSI+=4;
}
inputIt.NextSpan();
outputIt.NextSpan();
}
}
//Internal method which should never be used anywhere else and should not be in th header.
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkApplyLookupTableOnScalars(vtkMitkLevelWindowFilter *self,
vtkImageData *inData,
vtkImageData *outData,
int outExt[6],
double* clippingBounds,
T *)
{
vtkImageIterator<T> inputIt(inData, outExt);
vtkImageIterator<unsigned char> outputIt(outData, outExt);
vtkScalarsToColors* lookupTable = self->GetLookupTable();
int y = outExt[2];
// Loop through ouput pixels
while (!outputIt.IsAtEnd())
{
unsigned char* outputSI = outputIt.BeginSpan();
unsigned char* outputSIEnd = outputIt.EndSpan();
// do we iterate over the inner vertical clipping bounds
if( y >= clippingBounds[2] && y < clippingBounds[3] )
{
T* inputSI = inputIt.BeginSpan();
int x= outExt[0];
while (outputSI != outputSIEnd)
{
// is this pixel within horizontal clipping bounds
if ( x >= clippingBounds[0] && x < clippingBounds[1])
{
// fetching original value
double grayValue = static_cast<double>(*inputSI);
// applying lookuptable - copy the 4 (RGBA) chars as a single int
*reinterpret_cast<int*>(outputSI) = *reinterpret_cast<int *>(lookupTable->MapValue( grayValue ));
}
else
{
// outer horizontal clipping bounds - write a transparent RGBA pixel as a single int
*reinterpret_cast<int*>(outputSI) = 0;
}
inputSI++;
outputSI+=4;
x++;
}
}
else
{
// outer vertical clipping bounds - write a transparent RGBA line as ints
while (outputSI != outputSIEnd)
{
*reinterpret_cast<int*>(outputSI) = 0;
outputSI+=4;
}
}
inputIt.NextSpan();
outputIt.NextSpan();
y++;
}
}
//Internal method which should never be used anywhere else and should not be in th header.
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkApplyLookupTableOnScalarsCTF(vtkMitkLevelWindowFilter *self,
vtkImageData *inData,
vtkImageData *outData,
int outExt[6],
double* clippingBounds,
T *)
{
vtkImageIterator<T> inputIt(inData, outExt);
vtkImageIterator<unsigned char> outputIt(outData, outExt);
vtkColorTransferFunction* lookupTable = dynamic_cast<vtkColorTransferFunction*>(self->GetLookupTable());
vtkPiecewiseFunction* opacityFunction = self->GetOpacityPiecewiseFunction();
int y = outExt[2];
// Loop through ouput pixels
while (!outputIt.IsAtEnd())
{
unsigned char* outputSI = outputIt.BeginSpan();
unsigned char* outputSIEnd = outputIt.EndSpan();
// do we iterate over the inner vertical clipping bounds
if( y >= clippingBounds[2] && y < clippingBounds[3] )
{
T* inputSI = inputIt.BeginSpan();
int x= outExt[0];
while (outputSI != outputSIEnd)
{
// is this pixel within horizontal clipping bounds
if ( x >= clippingBounds[0] && x < clippingBounds[1])
{
// fetching original value
double grayValue = static_cast<double>(*inputSI);
// applying directly colortransferfunction
// because vtkColorTransferFunction::MapValue is not threadsafe
double rgba[4];
lookupTable->GetColor( grayValue, rgba ); // RGB mapping
rgba[3] = 1.0;
if (opacityFunction)
rgba[3] = opacityFunction->GetValue(grayValue); // Alpha mapping
for (int i = 0; i < 4; ++i)
{
outputSI[i] = static_cast<unsigned char>(255.0*rgba[i] + 0.5);
}
}
else
{
// outer horizontal clipping bounds - write a transparent RGBA pixel as a single int
*reinterpret_cast<int*>(outputSI) = 0;
}
inputSI++;
outputSI+=4;
x++;
}
}
else
{
// outer vertical clipping bounds - write a transparent RGBA line as ints
while (outputSI != outputSIEnd)
{
*reinterpret_cast<int*>(outputSI) = 0;
outputSI+=4;
}
}
inputIt.NextSpan();
outputIt.NextSpan();
y++;
}
}
int vtkMitkLevelWindowFilter::RequestInformation(vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
vtkInformation* outInfo = outputVector->GetInformationObject(0);
// do nothing except copy scalar type info
this->CopyInputArrayAttributesToOutput(request,inputVector,outputVector);
vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR, 4);
return 1;
-
}
//Method to run the filter in different threads.
void vtkMitkLevelWindowFilter::ThreadedExecute(vtkImageData *inData,
vtkImageData *outData,
int extent[6], int /*id*/)
{
if(inData->GetNumberOfScalarComponents() > 2)
{
switch (inData->GetScalarType())
{
vtkTemplateMacro(
vtkApplyLookupTableOnRGBA( this,
inData,
outData,
extent,
m_ClippingBounds,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
else
{
bool dontClip =
extent[2] >= m_ClippingBounds[2]
&& extent[3] <= m_ClippingBounds[3]
&& extent[0] >= m_ClippingBounds[0]
&& extent[1] <= m_ClippingBounds[1];
if(this->GetLookupTable())
this->GetLookupTable()->Build();
vtkLookupTable *vlt = dynamic_cast<vtkLookupTable*>(this->GetLookupTable());
vtkColorTransferFunction *ctf = dynamic_cast<vtkColorTransferFunction*>(this->GetLookupTable());
bool linearLookupTable = vlt && vlt->GetScale() == VTK_SCALE_LINEAR;
bool useFast = dontClip && linearLookupTable;
if(ctf)
{
switch (inData->GetScalarType())
{
vtkTemplateMacro(
vtkApplyLookupTableOnScalarsCTF( this,
inData,
outData,
extent,
m_ClippingBounds,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
else if(useFast)
{
switch (inData->GetScalarType())
{
vtkTemplateMacro(
vtkApplyLookupTableOnScalarsFast( this,
inData,
outData,
extent,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
else
{
switch (inData->GetScalarType())
{
vtkTemplateMacro(
vtkApplyLookupTableOnScalars( this,
inData,
outData,
extent,
m_ClippingBounds,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
}
}
//void vtkMitkLevelWindowFilter::ExecuteInformation(
// vtkImageData *vtkNotUsed(inData), vtkImageData *vtkNotUsed(outData))
//{
//}
void vtkMitkLevelWindowFilter::SetMinOpacity(double minOpacity)
{
m_MinOpacity = minOpacity;
}
inline double vtkMitkLevelWindowFilter::GetMinOpacity() const
{
return m_MinOpacity;
}
void vtkMitkLevelWindowFilter::SetMaxOpacity(double maxOpacity)
{
m_MaxOpacity = maxOpacity;
}
inline double vtkMitkLevelWindowFilter::GetMaxOpacity() const
{
return m_MaxOpacity;
}
void vtkMitkLevelWindowFilter::SetClippingBounds(double* bounds) // TODO does double[4] work??
{
for (unsigned int i = 0 ; i < 4; ++i)
m_ClippingBounds[i] = bounds[i];
}
diff --git a/Core/Code/Rendering/vtkMitkLevelWindowFilter.h b/Core/Code/Rendering/vtkMitkLevelWindowFilter.h
index 4c9dba5dda..0f41a656a2 100644
--- a/Core/Code/Rendering/vtkMitkLevelWindowFilter.h
+++ b/Core/Code/Rendering/vtkMitkLevelWindowFilter.h
@@ -1,105 +1,104 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef __vtkMitkLevelWindowFilter_h
#define __vtkMitkLevelWindowFilter_h
class vtkScalarsToColors;
class vtkPiecewiseFunction;
#include <vtkImageData.h>
#include <vtkThreadedImageAlgorithm.h>
#include <MitkCoreExports.h>
/** Documentation
* \brief Applies the grayvalue or color/opacity level window to scalar or RGB(A) images.
*
* This filter is used to apply the color level window to RGB images (e.g.
* diffusion tensor images). Therefore, the RGB channels are converted to
* the HSI color space, where the level window can be applied. Afterwards,
* the HSI values transformed back to the RGB space.
*
* The filter is also able to apply an opacity level window to RGBA images.
*
* \ingroup Renderer
*/
class MITK_CORE_EXPORT vtkMitkLevelWindowFilter : public vtkThreadedImageAlgorithm
{
public:
vtkTypeMacro(vtkMitkLevelWindowFilter,vtkThreadedImageAlgorithm);
static vtkMitkLevelWindowFilter *New();
virtual unsigned long int GetMTime();
/** \brief Get the lookup table for the RGB level window */
vtkScalarsToColors* GetLookupTable();
/** \brief Set the lookup table for the RGB level window */
void SetLookupTable(vtkScalarsToColors *lookupTable);
/** \brief Get the piecewise function used to map scalar to alpha component value (only
* used when the lookupTable is a vtkColorTransferFunction) */
vtkPiecewiseFunction* GetOpacityPiecewiseFunction()
{ return m_OpacityFunction; }
/** \brief Set the piecewise function used to map scalar to alpha component value (only
* used when the lookupTable is a vtkColorTransferFunction) */
void SetOpacityPiecewiseFunction(vtkPiecewiseFunction *opacityFunction);
/** \brief Get/Set the lower window opacity for the alpha level window */
void SetMinOpacity(double minOpacity);
inline double GetMinOpacity() const;
/** \brief Get/Set the upper window opacity for the alpha level window */
void SetMaxOpacity(double maxOpacity);
inline double GetMaxOpacity() const;
/** \brief Set clipping bounds for the opaque part of the resliced 2d image */
void SetClippingBounds(double*);
protected:
/** Default constructor. */
vtkMitkLevelWindowFilter();
/** Default deconstructor. */
~vtkMitkLevelWindowFilter();
-
/** \brief Method for threaded execution of the filter.
* \param *inData: The input.
* \param *outData: The output of the filter.
* \param extent: Specifies the region of the image to be updated inside this thread.
* It is a six-component array of the form (xmin, xmax, ymin, ymax, zmin, zmax).
* \param id: The thread id.
*/
void ThreadedExecute(vtkImageData *inData, vtkImageData *outData,int extent[6], int id);
// /** Standard VTK filter method to apply the filter. See VTK documentation.*/
int RequestInformation(vtkInformation* request,vtkInformationVector** inputVector, vtkInformationVector* outputVector);
// /** Standard VTK filter method to apply the filter. See VTK documentation. Not used at the moment.*/
// void ExecuteInformation(vtkImageData *vtkNotUsed(inData), vtkImageData *vtkNotUsed(outData));
private:
/** m_LookupTable contains the lookup table for the RGB level window.*/
vtkScalarsToColors* m_LookupTable;
/** The transfer function to map the scalar to alpha (4th component of the RGBA output value) */
vtkPiecewiseFunction* m_OpacityFunction;
/** m_MinOpacity contains the lower bound for the alpha level window.*/
double m_MinOpacity;
/** m_MaxOpacity contains the upper bound for the alpha level window.*/
double m_MaxOpacity;
double m_ClippingBounds[4];
};
#endif
diff --git a/Core/Code/Rendering/vtkMitkRenderProp.cpp b/Core/Code/Rendering/vtkMitkRenderProp.cpp
index 59d4c6bf9d..f696f2c7ea 100644
--- a/Core/Code/Rendering/vtkMitkRenderProp.cpp
+++ b/Core/Code/Rendering/vtkMitkRenderProp.cpp
@@ -1,107 +1,113 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "vtkMitkRenderProp.h"
#include <vtkObjectFactory.h>
#include <vtkLODProp3D.h>
#include <vtkPropAssembly.h>
#include "mitkVtkMapper.h"
#include "mitkGLMapper.h"
vtkStandardNewMacro(vtkMitkRenderProp);
vtkMitkRenderProp::vtkMitkRenderProp()
{
}
vtkMitkRenderProp::~vtkMitkRenderProp()
{
}
double *vtkMitkRenderProp::GetBounds()
{
return const_cast<double*>(m_VtkPropRenderer->GetBounds());
}
void vtkMitkRenderProp::SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer)
{
this->m_VtkPropRenderer = propRenderer;
}
int vtkMitkRenderProp::RenderOpaqueGeometry(vtkViewport* /*viewport*/)
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Opaque);
}
int vtkMitkRenderProp::RenderOverlay(vtkViewport* /*viewport*/)
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Overlay);
}
void vtkMitkRenderProp::ReleaseGraphicsResources(vtkWindow* window)
{
m_VtkPropRenderer->ReleaseGraphicsResources(window);
}
void vtkMitkRenderProp::InitPathTraversal()
{
m_VtkPropRenderer->InitPathTraversal();
}
vtkAssemblyPath* vtkMitkRenderProp::GetNextPath()
{
return m_VtkPropRenderer->GetNextPath();
}
+
+int vtkMitkRenderProp::GetNumberOfPaths()
+{
+ return m_VtkPropRenderer->GetNumberOfPaths();
+}
+
//BUG (#1551) added method depth peeling
int vtkMitkRenderProp::HasTranslucentPolygonalGeometry()
{
typedef std::map<int,mitk::Mapper*> MappersMapType;
MappersMapType mappersMap = m_VtkPropRenderer->GetMappersMap();
for(MappersMapType::iterator it = mappersMap.begin(); it != mappersMap.end(); it++)
{
mitk::Mapper * mapper = (*it).second;
mitk::VtkMapper::Pointer vtkMapper = dynamic_cast<mitk::VtkMapper*>(mapper);
if(vtkMapper)
{
// Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly
// manually (see issue #8186 committed to VTK's Mantis issue tracker)
// --> VTK bug resolved on 2008-12-01
vtkPropAssembly *propAssembly = dynamic_cast< vtkPropAssembly * >(
vtkMapper->GetVtkProp(m_VtkPropRenderer) );
if ( propAssembly )
{
propAssembly->InitPathTraversal();
}
if (vtkMapper->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1)
return 1;
}
}
return 0;
}
int vtkMitkRenderProp::RenderTranslucentPolygonalGeometry( vtkViewport * )
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Translucent);
}
int vtkMitkRenderProp::RenderVolumetricGeometry( vtkViewport * )
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Volumetric);
}
diff --git a/Core/Code/Rendering/vtkMitkRenderProp.h b/Core/Code/Rendering/vtkMitkRenderProp.h
index 4ac689567c..eae984c909 100644
--- a/Core/Code/Rendering/vtkMitkRenderProp.h
+++ b/Core/Code/Rendering/vtkMitkRenderProp.h
@@ -1,75 +1,77 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723
#define VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723
#include "vtkProp.h"
#include "mitkVtkPropRenderer.h"
/*!
\brief vtkMitkRenderProp
The MITK rendering process is completely integrated into the VTK rendering pipeline.
The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes.
\sa rendering
\ingroup rendering
*/
class MITK_CORE_EXPORT vtkMitkRenderProp : public vtkProp
{
public:
static vtkMitkRenderProp *New();
vtkTypeMacro(vtkMitkRenderProp,vtkProp);
void SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer);
int RenderOpaqueGeometry(vtkViewport* viewport);
int RenderOverlay(vtkViewport* viewport);
double *GetBounds();
void ReleaseGraphicsResources(vtkWindow* window);
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
virtual void InitPathTraversal();
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
virtual vtkAssemblyPath* GetNextPath();
+ virtual int GetNumberOfPaths();
+
//BUG (#1551) added method for depth peeling support
virtual int HasTranslucentPolygonalGeometry();
virtual int RenderTranslucentPolygonalGeometry( vtkViewport *);
virtual int RenderVolumetricGeometry( vtkViewport *);
protected:
vtkMitkRenderProp();
~vtkMitkRenderProp();
mitk::VtkPropRenderer::Pointer m_VtkPropRenderer;
};
#endif /* VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723 */
diff --git a/Core/Code/Testing/CMakeLists.txt b/Core/Code/Testing/CMakeLists.txt
index 28540255ff..cedfa5ffa5 100644
--- a/Core/Code/Testing/CMakeLists.txt
+++ b/Core/Code/Testing/CMakeLists.txt
@@ -1,272 +1,242 @@
# The core tests need relaxed compiler flags...
# TODO fix core tests to compile without these additional no-error flags
if(MSVC_VERSION)
# disable deprecated warnings (they would lead to errors)
mitkFunctionCheckCAndCXXCompilerFlags("/wd4996" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
else()
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated-declarations" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
MITK_CREATE_MODULE_TESTS(LABELS MITK-Core)
mitk_use_modules(TARGET ${TESTDRIVER} PACKAGES ITK|ITKThresholding)
mitkAddCustomModuleTest(mitkVolumeCalculatorTest_Png2D-bw mitkVolumeCalculatorTest
${MITK_DATA_DIR}/Png2D-bw.png
${MITK_DATA_DIR}/Pic2DplusT.nrrd
)
mitkAddCustomModuleTest(mitkEventMapperTest_Test1And2 mitkEventMapperTest
${MITK_DATA_DIR}/TestStateMachine1.xml
${MITK_DATA_DIR}/TestStateMachine2.xml
)
mitkAddCustomModuleTest(mitkEventConfigTest_CreateObjectInDifferentWays mitkEventConfigTest
${MITK_SOURCE_DIR}/Core/Code/Testing/Resources/Interactions/StatemachineConfigTest.xml
)
mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest
${MITK_DATA_DIR}/Pic3D.nrrd
${MITK_DATA_DIR}/BallBinary30x30x30.nrrd
)
mitkAddCustomModuleTest(mitkDataStorageTest_US4DCyl mitkDataStorageTest
${MITK_DATA_DIR}/US4DCyl.nrrd
)
mitkAddCustomModuleTest(mitkStateMachineFactoryTest_TestStateMachine1_2 mitkStateMachineFactoryTest
${MITK_DATA_DIR}/TestStateMachine1.xml
${MITK_DATA_DIR}/TestStateMachine2.xml
)
mitkAddCustomModuleTest(mitkDicomSeriesReaderTest_CTImage mitkDicomSeriesReaderTest
${MITK_DATA_DIR}/TinyCTAbdomen
${MITK_DATA_DIR}/DICOMReader/Broken-Series
)
mitkAddCustomModuleTest(mitkPointSetReaderTest mitkPointSetReaderTest
${MITK_DATA_DIR}/PointSetReaderTestData.mps
)
mitkAddCustomModuleTest(mitkImageTest_4DImageData mitkImageTest
${MITK_DATA_DIR}/US4DCyl.nrrd
)
mitkAddCustomModuleTest(mitkImageTest_2D+tImageData mitkImageTest
${MITK_DATA_DIR}/Pic2DplusT.nrrd
)
mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageTest
${MITK_DATA_DIR}/Pic3D.nrrd
)
mitkAddCustomModuleTest(mitkImageEqualTest mitkImageEqualTest)
mitkAddCustomModuleTest(mitkImageTest_brainImage mitkImageTest
${MITK_DATA_DIR}/brain.mhd
)
mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageGeneratorTest
${MITK_DATA_DIR}/Pic3D.nrrd
)
mitkAddCustomModuleTest(mitkLevelWindowManagerTest mitkLevelWindowManagerTest
${MITK_DATA_DIR}/Pic3D.nrrd
)
mitkAddCustomModuleTest(mitkMultiComponentImageDataComparisonFilterTest mitkMultiComponentImageDataComparisonFilterTest
${MITK_DATA_DIR}/NrrdWritingTestImage.jpg
)
mitkAddCustomModuleTest(mitkImageToItkTest mitkImageToItkTest
${MITK_DATA_DIR}/Pic3D.nrrd
)
mitkAddCustomModuleTest(mitkImageSliceSelectorTest mitkImageSliceSelectorTest
${MITK_DATA_DIR}/Pic2DplusT.nrrd
)
if(MITK_ENABLE_RENDERING_TESTING) ### since the rendering test's do not run in ubuntu, yet, we build them only for other systems or if the user explicitly sets the variable MITK_ENABLE_RENDERING_TESTING
mitkAddCustomModuleTest(mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2DTest
${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png #input image to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/rgbaImage640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice
${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3d640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2DColorTest #test for color property (=blue) Pic3D sagittal slice
${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dColorBlue640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2DLevelWindowTest #test for levelwindow property (=blood) #Pic3D sagittal slice
${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dLevelWindowBlood640x480REF.png #corresponding reference #screenshot
)
#mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dOpacity640x480 mitkImageVtkMapper2DOpacityTest #test for opacity (=0.5) Pic3D coronal slice
# ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage
# -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dOpacity640x480REF.png corresponding reference screenshot
#)
mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DSwivelTest #test for a randomly chosen Pic3D swivelled slice
${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dSwivel640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2DTest
${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAlone640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2DImageTest
${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/PointSetForPic3D.mps #input point set and image to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Pic3DPointSetForPic3D640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2DGlyphTypeTest
${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneGlyphType640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 mitkPointSetVtkMapper2DTransformedPointsTest
${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneTransformedPoints640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkSurfaceDepthSortingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthSortingTest
${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthSorting640x480REF.png
)
if(NOT APPLE)
mitkAddCustomModuleTest(mitkSurfaceDepthPeelingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthPeelingTest
${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthPeeling640x480REF.png #corresponding reference screenshot
)
endif()
#Test reslice interpolation
#note: nearest mode is already tested by swivel test
mitkAddCustomModuleTest(ResliceInterpolationIsLinear mitkImageVtkMapper2DResliceInterpolationPropertyTest
1 #linear
${MITK_DATA_DIR}/Pic3D.nrrd
-V
${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefLinear.png #corresponding reference screenshot LINEAR
)
mitkAddCustomModuleTest(ResliceInterpolationIsCubic mitkImageVtkMapper2DResliceInterpolationPropertyTest
3 #cubic
${MITK_DATA_DIR}/Pic3D.nrrd
-V
${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefCubic.png #corresponding reference screenshot CUBIC
)
#End test reslice interpolation
-#Overlays
-mitkAddCustomModuleTest(mitkLabelOverlay3DRendering2DTest mitkLabelOverlay3DRendering2DTest #OverlayTest
- -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkLabelOverlay3DRendering2DTest.png #corresponding reference screenshot
-)
-
-mitkAddCustomModuleTest(mitkLabelOverlay3DRendering3DTest mitkLabelOverlay3DRendering3DTest #OverlayTest
- -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkLabelOverlay3DRendering3DTest.png #corresponding reference screenshot
-)
-
-mitkAddCustomModuleTest(mitkTextOverlay2DRenderingTest_ball mitkTextOverlay2DRenderingTest #OverlayTest
- ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
- -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay2DRenderingTest_ball.png #corresponding reference screenshot
-)
-
-#mitkAddCustomModuleTest(mitkTextOverlay2DLayouterRenderingTest_ball mitkTextOverlay2DLayouterRenderingTest #OverlayTest
-# ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
-# -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay2DLayouterRenderingTest_ball.png #corresponding reference screenshot
-#)
-
-mitkAddCustomModuleTest(mitkTextOverlay3DRendering2DTest_ball mitkTextOverlay3DRendering2DTest #OverlayTest
- ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
- -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay3DRendering2DTest_ball.png #corresponding reference screenshot
-)
-
-mitkAddCustomModuleTest(mitkTextOverlay3DRendering3DTest_ball mitkTextOverlay3DRendering3DTest #OverlayTest
- ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
- -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay3DRendering3DTest_ball.png #corresponding reference screenshot
-)
-
-mitkAddCustomModuleTest(mitkTextOverlay3DColorRenderingTest_ball mitkTextOverlay3DColorRenderingTest #OverlayTest
- ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
- -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay3DColorRenderingTest_ball.png #corresponding reference screenshot
-)
-#End of overlayTests
-
# Testing of the rendering of binary images
#mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImage640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice
# ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage
# -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImage640x480REF.png #corresponding reference screenshot
#)
#mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImageWithRef640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice
# ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage
# -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImageWithRef640x480REF.png #corresponding reference screenshot
#)
# End of binary image tests
mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTest_TextureProperty mitkSurfaceVtkMapper3DTest
${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom.vtp
${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom_RGBImage.nrrd
-V
${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedLiver640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DTransferFunctionTest
${MITK_DATA_DIR}/Png2D-bw.png
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-TransferFunctionRGBImage640x480REF.png #corresponding reference screenshot
)
+mitkAddCustomModuleTest(mitkImageVtkMapper2DOpacityTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DOpacityTransferFunctionTest
+ ${MITK_DATA_DIR}/Png2D-bw.png
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-OpacityTransferFunctionRGBImage640x480REF.png #corresponding reference screenshot
+)
+
mitkAddCustomModuleTest(mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceGLMapper2DColorTest
${MITK_DATA_DIR}/ball.stl
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/ballColorRed640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest
${MITK_DATA_DIR}/binary.stl
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryColorRed640x480REF.png #corresponding reference screenshot
)
mitkAddCustomModuleTest(mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DOpacityTest #opacity = 50% (0.5)
${MITK_DATA_DIR}/ball.stl
-V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/ballOpacity640x480REF.png #corresponding reference screenshot
)
############################## DISABLED TESTS
#Removed due to high rendering error.
#mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTexturedSphereTest_Football mitkSurfaceVtkMapper3DTexturedSphereTest
# ${MITK_DATA_DIR}/RenderingTestData/texture.jpg #input texture
# -V
# ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedSphere640x480REF.png corresponding reference screenshot
#)
#mitkAddCustomModuleTest(mitkImageVtkMapper2DLookupTableTest_Png2D-bw mitkImageVtkMapper2DLookupTableTest
# ${MITK_DATA_DIR}/Png2D-bw.png
# -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-LookupTableRGBImage640x480REF.png #corresponding reference screenshot
#)
#mitkAddCustomModuleTest(mitkImageTest_color2DImage mitkImageTest
# ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg
#)
#mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest
# ${MITK_DATA_DIR}/Pic3D.pic.gz ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz
#)
SET_PROPERTY(TEST mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw
# mitkImageVtkMapper2D_pic3dOpacity640x480
mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceVtkMapper3DTest_TextureProperty mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 #mitkSurfaceVtkMapper3DTexturedSphereTest_Football
PROPERTY RUN_SERIAL TRUE)
endif()
add_test(mitkPointSetLocaleTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkPointSetLocaleTest ${MITK_DATA_DIR}/pointSet.mps)
set_property(TEST mitkPointSetLocaleTest PROPERTY LABELS MITK-Core)
add_test(mitkImageWriterTest_nrrdImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg)
add_test(mitkImageWriterTest_2DPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/Png2D-bw.png)
add_test(mitkImageWriterTest_rgbPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/RenderingTestData/rgbImage.png)
add_test(mitkImageWriterTest_rgbaPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png)
set_property(TEST mitkImageWriterTest_nrrdImage PROPERTY LABELS MITK-Core)
set_property(TEST mitkImageWriterTest_2DPNGImage PROPERTY LABELS MITK-Core)
set_property(TEST mitkImageWriterTest_rgbPNGImage PROPERTY LABELS MITK-Core)
set_property(TEST mitkImageWriterTest_rgbaPNGImage PROPERTY LABELS MITK-Core)
add_subdirectory(DCMTesting)
diff --git a/Core/Code/Testing/files.cmake b/Core/Code/Testing/files.cmake
index a52d414985..0ecd2a832c 100644
--- a/Core/Code/Testing/files.cmake
+++ b/Core/Code/Testing/files.cmake
@@ -1,209 +1,205 @@
# tests with no extra command line parameter
set(MODULE_TESTS
# IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code.
#
# Example: #mitkMyTest #this test is commented out because of bug 12345
#
# It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that
# no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and
# mark it as critical.
################## DISABLED TESTS #################################################
#mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesnt exist any more
#mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529
#mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more
#mitkSegmentationInterpolationTest.cpp #file doesn't exist!
#mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist!
#mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK
#mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more
#mitkTestUtilSharedLibrary.cpp #Linker problem with this test...
#mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details.
################# RUNNING TESTS ###################################################
mitkAccessByItkTest.cpp
mitkCoreObjectFactoryTest.cpp
mitkDataNodeTest.cpp
mitkMaterialTest.cpp
mitkActionTest.cpp
mitkDispatcherTest.cpp
mitkEnumerationPropertyTest.cpp
mitkEventTest.cpp
mitkFocusManagerTest.cpp
mitkGenericPropertyTest.cpp
mitkGeometry3DTest.cpp
mitkGeometry3DEqualTest.cpp
mitkGeometryDataToSurfaceFilterTest.cpp
mitkGlobalInteractionTest.cpp
mitkImageCastTest.cpp
mitkImageEqualTest.cpp
mitkImageDataItemTest.cpp
mitkImageGeneratorTest.cpp
mitkIOUtilTest.cpp
mitkBaseDataTest.cpp
mitkImportItkImageTest.cpp
mitkGrabItkImageMemoryTest.cpp
mitkInstantiateAccessFunctionTest.cpp
mitkInteractorTest.cpp
mitkLevelWindowTest.cpp
mitkMessageTest.cpp
mitkPixelTypeTest.cpp
mitkPlaneGeometryTest.cpp
mitkPointSetTest.cpp
mitkPointSetEqualTest.cpp
mitkPointSetFileIOTest.cpp
mitkPointSetOnEmptyTest.cpp
mitkPointSetWriterTest.cpp
mitkPointSetReaderTest.cpp
mitkPointSetInteractorTest.cpp
mitkPointSetPointOperationsTest.cpp
+ mitkProgressBarTest.cpp
mitkPropertyTest.cpp
mitkPropertyListTest.cpp
mitkSlicedGeometry3DTest.cpp
mitkSliceNavigationControllerTest.cpp
mitkStateMachineTest.cpp
mitkStateTest.cpp
mitkSurfaceTest.cpp
mitkSurfaceEqualTest.cpp
mitkSurfaceToSurfaceFilterTest.cpp
mitkTimeGeometryTest.cpp
+ mitkProportionalTimeGeometryTest.cpp
mitkTransitionTest.cpp
mitkUndoControllerTest.cpp
mitkVtkWidgetRenderingTest.cpp
mitkVerboseLimitedLinearUndoTest.cpp
mitkWeakPointerTest.cpp
mitkTransferFunctionTest.cpp
mitkStepperTest.cpp
mitkRenderingManagerTest.cpp
vtkMitkThickSlicesFilterTest.cpp
mitkNodePredicateSourceTest.cpp
mitkVectorTest.cpp
mitkClippedSurfaceBoundsCalculatorTest.cpp
mitkExceptionTest.cpp
mitkExtractSliceFilterTest.cpp
mitkLogTest.cpp
mitkImageDimensionConverterTest.cpp
mitkLoggingAdapterTest.cpp
mitkUIDGeneratorTest.cpp
mitkShaderRepositoryTest.cpp
mitkPlanePositionManagerTest.cpp
mitkAffineTransformBaseTest.cpp
mitkPropertyAliasesTest.cpp
mitkPropertyDescriptionsTest.cpp
mitkPropertyExtensionsTest.cpp
mitkPropertyFiltersTest.cpp
mitkTinyXMLTest.cpp
mitkRawImageFileReaderTest.cpp
mitkInteractionEventTest.cpp
mitkLookupTableTest.cpp
mitkSTLFileReaderTest.cpp
mitkPointTypeConversionTest.cpp
mitkVectorTypeConversionTest.cpp
mitkMatrixTypeConversionTest.cpp
mitkArrayTypeConversionTest.cpp
mitkSurfaceToImageFilterTest.cpp
mitkBaseGeometryTest.cpp
mitkImageToSurfaceFilterTest.cpp
mitkEqualTest.cpp
mitkLineTest.cpp
)
if(MITK_ENABLE_RENDERING_TESTING) #since mitkInteractionTestHelper is currently creating a vtkRenderWindow
set(MODULE_TESTS
${MODULE_TESTS}
mitkPointSetDataInteractorTest.cpp
)
endif()
# test with image filename as an extra command line parameter
set(MODULE_IMAGE_TESTS
mitkImageTimeSelectorTest.cpp #only runs on images
mitkImageAccessorTest.cpp #only runs on images
mitkDataNodeFactoryTest.cpp #runs on all types of data
)
set(MODULE_SURFACE_TESTS
mitkSurfaceVtkWriterTest.cpp #only runs on surfaces
mitkDataNodeFactoryTest.cpp #runs on all types of data
)
# list of images for which the tests are run
set(MODULE_TESTIMAGES
US4DCyl.nrrd
Pic3D.nrrd
Pic2DplusT.nrrd
BallBinary30x30x30.nrrd
Png2D-bw.png
)
set(MODULE_TESTSURFACES
binary.stl
ball.stl
)
set(MODULE_CUSTOM_TESTS
mitkDataStorageTest.cpp
mitkDicomSeriesReaderTest.cpp
mitkDICOMLocaleTest.cpp
mitkEventMapperTest.cpp
mitkEventConfigTest.cpp
mitkNodeDependentPointSetInteractorTest.cpp
mitkStateMachineFactoryTest.cpp
mitkPointSetLocaleTest.cpp
mitkImageTest.cpp
mitkImageWriterTest.cpp
mitkImageVtkMapper2DTest.cpp
mitkImageVtkMapper2DLevelWindowTest.cpp
mitkImageVtkMapper2DOpacityTest.cpp
mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp
mitkImageVtkMapper2DColorTest.cpp
mitkImageVtkMapper2DSwivelTest.cpp
mitkImageVtkMapper2DTransferFunctionTest.cpp
+ mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp
mitkImageVtkMapper2DLookupTableTest.cpp
mitkSurfaceVtkMapper3DTest
mitkSurfaceVtkMapper3DTexturedSphereTest.cpp
mitkSurfaceGLMapper2DColorTest.cpp
mitkSurfaceGLMapper2DOpacityTest.cpp
mitkVolumeCalculatorTest.cpp
mitkLevelWindowManagerTest.cpp
mitkPointSetVtkMapper2DTest.cpp
mitkPointSetVtkMapper2DImageTest.cpp
mitkPointSetVtkMapper2DGlyphTypeTest.cpp
mitkPointSetVtkMapper2DTransformedPointsTest.cpp
- mitkLabelOverlay3DRendering2DTest.cpp
- mitkLabelOverlay3DRendering3DTest.cpp
- mitkTextOverlay2DRenderingTest.cpp
- mitkTextOverlay2DLayouterRenderingTest.cpp
- mitkTextOverlay3DRendering2DTest.cpp
- mitkTextOverlay3DRendering3DTest.cpp
- mitkTextOverlay3DColorRenderingTest.cpp
mitkVTKRenderWindowSizeTest.cpp
mitkMultiComponentImageDataComparisonFilterTest.cpp
mitkImageToItkTest.cpp
mitkImageSliceSelectorTest.cpp
mitkSurfaceDepthPeelingTest.cpp
mitkSurfaceDepthSortingTest.cpp
)
set(MODULE_RESOURCE_FILES
Interactions/AddAndRemovePoints.xml
Interactions/globalConfig.xml
Interactions/StatemachineTest.xml
Interactions/StatemachineConfigTest.xml
)
# Create an artificial module initializing class for
# the usServiceListenerTest.cpp
usFunctionGenerateExecutableInit(testdriver_init_file
IDENTIFIER ${MODULE_NAME}TestDriver
)
# Embed the resources
set(testdriver_resources )
usFunctionEmbedResources(testdriver_resources
EXECUTABLE_NAME ${MODULE_NAME}TestDriver
ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Resources
FILES ${MODULE_RESOURCE_FILES}
)
set(TEST_CPP_FILES ${testdriver_init_file} ${testdriver_resources})
diff --git a/Core/Code/Testing/mitkAffineTransformBaseTest.cpp b/Core/Code/Testing/mitkAffineTransformBaseTest.cpp
index 2766b1dc67..97e5ffbff7 100644
--- a/Core/Code/Testing/mitkAffineTransformBaseTest.cpp
+++ b/Core/Code/Testing/mitkAffineTransformBaseTest.cpp
@@ -1,185 +1,196 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkNumericTypes.h"
#include "itkScalableAffineTransform.h"
#include "mitkMatrixConvert.h"
#include "mitkTestingMacros.h"
using namespace mitk;
static Vector3D offset;
static Matrix3D rotation;
static Point3D originalPoint;
static double originalPointDouble[4];
-static vtkMatrix4x4* homogenMatrix;
+static vtkMatrix4x4* homogenMatrix = 0;
-static vtkMatrix4x4* expectedHomogenousMatrix;
+static vtkMatrix4x4* expectedHomogenousMatrix = 0;
static const double expectedPointAfterTransformation[] = {2, 4, 4, 1};
static void Setup()
{
originalPoint[0] = 1.0; originalPoint[1] = 0.0; originalPoint[2] = 0.0;
for (int i = 0; i < 3; i++)
originalPointDouble[i] = originalPoint[i]; // same point as the Point3D version
originalPointDouble[3] = 1; // homogenous extension
offset[0] = 2.0; offset[1] = 3.0; offset[2] = 4.0;
// 90� rotation
rotation.Fill(0);
rotation[0][1] = -1;
rotation[1][0] = 1;
// prepare a Matrix which shall be set later to a specific
// homogen matrix by TransferItkTransformToVtkMatrix
// this makes sure, that the initialization to the identity does not
// overshadow any bugs in TransferItkTransformToVtkMatrix
// (it actually did that by "helping out" TransferItkTransformToVtkMatrix
// by setting the (3,3) element to 1).
homogenMatrix = vtkMatrix4x4::New();
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
homogenMatrix->SetElement(i,j, i+j*j); // just some not trivial value
// set the expected homogenous matrix result
expectedHomogenousMatrix = vtkMatrix4x4::New();
expectedHomogenousMatrix->Zero();
expectedHomogenousMatrix->SetElement(0,1,-1);
expectedHomogenousMatrix->SetElement(1,0,1);
expectedHomogenousMatrix->SetElement(0,3,2);
expectedHomogenousMatrix->SetElement(1,3,3);
expectedHomogenousMatrix->SetElement(2,3,4);
expectedHomogenousMatrix->SetElement(3,3,1);
}
+static void TearDown()
+{
+ if (homogenMatrix) homogenMatrix->Delete();
+ if (expectedHomogenousMatrix) expectedHomogenousMatrix->Delete();
+}
+
/**
* This first test basically assures that we understand the usage of AffineTransform3D correct.
* Meaning that the rotation is set by SetMatrix and the translation is set by SetOffset
*/
static void testIfPointIsTransformedAsExpected(void)
{
Setup();
/** construct the transformation */
AffineTransform3D::Pointer transform = AffineTransform3D::New();
transform->SetOffset(offset);
transform->SetMatrix(rotation);
TransferItkTransformToVtkMatrix(transform.GetPointer(), homogenMatrix);
/** Let a point be transformed by the AffineTransform3D */
Point3D pointTransformedByAffineTransform3D = transform->TransformPoint(originalPoint);
/** assert that the transformation was successful */
bool pointCorrect = true;
for (int i = 0; i < 3; i++) // only first three since no homogenous coordinates
pointCorrect &= Equal(pointTransformedByAffineTransform3D[i], expectedPointAfterTransformation[i]);
MITK_TEST_CONDITION(pointCorrect, "Point has been correctly transformed by AffineTranform3D")
+
+ TearDown();
}
/**
* This test ensures that the function TransferItkTransformToVtkMatrix translates the AffineTransform3D
* correctly to a VtkMatrix4x4
*/
static void testTransferItkTransformToVtkMatrix(void)
{
Setup();
AffineTransform3D::Pointer transform = AffineTransform3D::New();
transform->SetOffset(offset);
transform->SetMatrix(rotation);
TransferItkTransformToVtkMatrix(transform.GetPointer(), homogenMatrix);
bool allElementsEqual = true;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
allElementsEqual &= Equal(homogenMatrix->GetElement(i,j), expectedHomogenousMatrix->GetElement(i,j));
MITK_TEST_CONDITION(allElementsEqual, "Homogenous Matrix is set as expected")
+
+ TearDown();
}
/**
* This test basically is just a sanity check and should be PASSED exactly when both
* testTransferItkTransformToVtkMatrix and testIfPointIsTransformedAsExpected are PASSED.
* Tests if we get the same
* result by using the AffineTransform3D to transform a point or the vtkMatrix4x4 which we got by applying
* the TransferItkTransformToVtkMatrix function. This test e.g. ensures we made no mistake in our
* reference results.
*
*/
static void testIfBothTransformationsProduceSameResults(void)
{
Setup();
/**
* create both a AffineTransform3D
* and let this AffineTransform describe also a homogenous 4x4 Matrix vtkMatrix
* by using our transfer method
*/
AffineTransform3D::Pointer transform = AffineTransform3D::New();
transform->SetOffset(offset);
transform->SetMatrix(rotation);
TransferItkTransformToVtkMatrix(transform.GetPointer(), homogenMatrix);
/** Let a point be transformed by the AffineTransform3D and by homogenMatrix */
Point3D pointTransformedByAffineTransform3D = transform->TransformPoint(originalPoint);
double* pointTransformedByHomogenous= homogenMatrix->MultiplyDoublePoint(originalPointDouble);
/* check if results match */
bool pointsMatch = true;
for (int i = 0; i < 3; i++) // only first three since no homogenous coordinates
pointsMatch &= Equal(pointTransformedByAffineTransform3D[i], pointTransformedByHomogenous[i]);
bool homogenousComponentCorrect = Equal(1, pointTransformedByHomogenous[3]);
MITK_TEST_CONDITION(pointsMatch
&& homogenousComponentCorrect, "Point transformed by AffineTransform and homogenous coordinates match")
+ TearDown();
}
/**
* This test shall ensure and document the basic functionality of the
* itk AffineTransformation functionality and test some basic transformation functionalities provided by mitk.
*/
int mitkAffineTransformBaseTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("AffineTransformationBaseTest");
testIfPointIsTransformedAsExpected();
testTransferItkTransformToVtkMatrix();
testIfBothTransformationsProduceSameResults();
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkBaseGeometryTest.cpp b/Core/Code/Testing/mitkBaseGeometryTest.cpp
index cd7e9b205e..ba6996bca2 100644
--- a/Core/Code/Testing/mitkBaseGeometryTest.cpp
+++ b/Core/Code/Testing/mitkBaseGeometryTest.cpp
@@ -1,1250 +1,1253 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkTestingConfig.h>
#include <mitkTestFixture.h>
#include <mitkBaseGeometry.h>
#include <MitkCoreExports.h>
#include <mitkCommon.h>
#include "mitkOperationActor.h"
#include <itkBoundingBox.h>
#include "mitkVector.h"
#include <itkAffineGeometryFrame.h>
#include <itkQuaternionRigidTransform.h>
#include "itkScalableAffineTransform.h"
#include <itkIndex.h>
#include <vtkMatrixToLinearTransform.h>
#include <vtkMatrix4x4.h>
#include "mitkRotationOperation.h"
#include "mitkInteractionConst.h"
#include <mitkMatrixConvert.h>
#include <mitkImageCast.h>
class vtkMatrix4x4;
class vtkMatrixToLinearTransform;
class vtkLinearTransform;
typedef itk::BoundingBox<unsigned long, 3, mitk::ScalarType> BoundingBox;
typedef itk::BoundingBox<unsigned long, 3, mitk::ScalarType> BoundingBoxType;
typedef BoundingBoxType::BoundsArrayType BoundsArrayType;
typedef BoundingBoxType::Pointer BoundingBoxPointer;
// Dummy instance of abstract base class
class DummyTestClass : public mitk::BaseGeometry
{
public:
DummyTestClass(){};
DummyTestClass(const DummyTestClass& other) : BaseGeometry(other){};
~DummyTestClass(){};
mitkClassMacro(DummyTestClass, mitk::BaseGeometry);
itkNewMacro(Self);
mitkNewMacro1Param(Self, const Self&);
itk::LightObject::Pointer InternalClone() const
{
Self::Pointer newGeometry = new Self(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const{};
};
class mitkBaseGeometryTestSuite : public mitk::TestFixture
{
// List of Tests
CPPUNIT_TEST_SUITE(mitkBaseGeometryTestSuite);
//Constructor
MITK_TEST(TestConstructors);
MITK_TEST(TestInitialize);
//Set
MITK_TEST(TestSetOrigin);
MITK_TEST(TestSetBounds);
MITK_TEST(TestSetFloatBounds);
MITK_TEST(TestSetFloatBoundsDouble);
MITK_TEST(TestSetFrameOfReferenceID);
MITK_TEST(TestSetIndexToWorldTransform);
MITK_TEST(TestSetIndexToWorldTransform_WithPointerToSameTransform);
MITK_TEST(TestSetSpacing);
MITK_TEST(TestTransferItkToVtkTransform);
MITK_TEST(TestSetIndexToWorldTransformByVtkMatrix);
MITK_TEST(TestSetIdentity);
MITK_TEST(TestSetImageGeometry);
//Equal
MITK_TEST(Equal_CloneAndOriginal_ReturnsTrue);
MITK_TEST(Equal_DifferentOrigin_ReturnsFalse);
MITK_TEST(Equal_DifferentIndexToWorldTransform_ReturnsFalse);
MITK_TEST(Equal_DifferentSpacing_ReturnsFalse);
MITK_TEST(Equal_InputIsNull_ReturnsFalse);
MITK_TEST(Equal_DifferentBoundingBox_ReturnsFalse);
//other Functions
MITK_TEST(TestComposeTransform);
MITK_TEST(TestComposeVtkMatrix);
MITK_TEST(TestTranslate);
MITK_TEST(TestIndexToWorld);
MITK_TEST(TestExecuteOperation);
MITK_TEST(TestCalculateBoundingBoxRelToTransform);
//MITK_TEST(TestSetTimeBounds);
MITK_TEST(TestIs2DConvertable);
MITK_TEST(TestGetCornerPoint);
MITK_TEST(TestExtentInMM);
MITK_TEST(TestGetAxisVector);
MITK_TEST(TestGetCenter);
MITK_TEST(TestGetDiagonalLength);
MITK_TEST(TestGetExtent);
MITK_TEST(TestIsInside);
MITK_TEST(TestGetMatrixColumn);
CPPUNIT_TEST_SUITE_END();
// Used Variables
private:
mitk::Point3D aPoint;
float aFloatSpacing[3];
mitk::Vector3D aSpacing;
mitk::AffineTransform3D::Pointer aTransform;
BoundingBoxPointer aBoundingBox;
mitk::AffineTransform3D::MatrixType aMatrix;
mitk::Point3D anotherPoint;
mitk::Vector3D anotherSpacing;
BoundingBoxPointer anotherBoundingBox;
BoundingBoxPointer aThirdBoundingBox;
mitk::AffineTransform3D::Pointer anotherTransform;
mitk::AffineTransform3D::Pointer aThirdTransform;
mitk::AffineTransform3D::MatrixType anotherMatrix;
mitk::AffineTransform3D::MatrixType aThirdMatrix;
DummyTestClass::Pointer aDummyGeometry;
DummyTestClass::Pointer anotherDummyGeometry;
public:
// Set up for variables
void setUp()
{
mitk::FillVector3D(aFloatSpacing, 1,1,1);
mitk::FillVector3D(aSpacing, 1,1,1);
mitk::FillVector3D(aPoint, 0,0,0);
//Transform
aTransform = mitk::AffineTransform3D::New();
aTransform->SetIdentity();
aMatrix.SetIdentity();
anotherTransform = mitk::AffineTransform3D::New();
anotherMatrix.SetIdentity();
anotherMatrix(1,1) = 2;
anotherTransform->SetMatrix( anotherMatrix );
aThirdTransform = mitk::AffineTransform3D::New();
aThirdMatrix.SetIdentity();
aThirdMatrix(1,1) = 7;
aThirdTransform->SetMatrix( aThirdMatrix );
//Bounding Box
float bounds[6] = {0,1,0,1,0,1};
mitk::BoundingBox::BoundsArrayType b;
const float *input = bounds;
int j=0;
for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); j < 6 ;++j) *it++ = (mitk::ScalarType)*input++;
aBoundingBox = BoundingBoxType::New();
BoundingBoxType::PointsContainer::Pointer pointscontainer = BoundingBoxType::PointsContainer::New();
BoundingBoxType::PointType p;
BoundingBoxType::PointIdentifier pointid;
for(pointid=0; pointid<2;++pointid)
{
unsigned int i;
for(i=0; i<3; ++i)
{
p[i] = bounds[2*i+pointid];
}
pointscontainer->InsertElement(pointid, p);
}
aBoundingBox->SetPoints(pointscontainer);
aBoundingBox->ComputeBoundingBox();
anotherBoundingBox = BoundingBoxType::New();
p[0]=11;
p[1]=12;
p[2]=13;
pointscontainer->InsertElement(1, p);
anotherBoundingBox->SetPoints(pointscontainer);
anotherBoundingBox->ComputeBoundingBox();
aThirdBoundingBox = BoundingBoxType::New();
p[0]=22;
p[1]=23;
p[2]=24;
pointscontainer->InsertElement(1, p);
aThirdBoundingBox->SetPoints(pointscontainer);
aThirdBoundingBox->ComputeBoundingBox();
mitk::FillVector3D(anotherPoint, 2,3,4);
mitk::FillVector3D(anotherSpacing, 5,6.5,7);
aDummyGeometry = DummyTestClass::New();
aDummyGeometry->Initialize();
anotherDummyGeometry = aDummyGeometry->Clone();
}
void tearDown()
{
aDummyGeometry = NULL;
anotherDummyGeometry = NULL;
}
// Test functions
void TestSetOrigin()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetOrigin(anotherPoint);
CPPUNIT_ASSERT(mitk::Equal(anotherPoint,dummy->GetOrigin()));
//undo changes, new and changed object need to be the same!
dummy->SetOrigin(aPoint);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetImageGeometry()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetImageGeometry(true);
CPPUNIT_ASSERT(dummy->GetImageGeometry());
//undo changes, new and changed object need to be the same!
dummy->SetImageGeometry(false);
CPPUNIT_ASSERT(dummy->GetImageGeometry()==false);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetFloatBounds(){
float bounds[6] = {0,11,0,12,0,13};
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, true));
//Wrong bounds, test needs to fail
bounds[1]=7;
dummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT((mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, false))==false);
//undo changes, new and changed object need to be the same!
float originalBounds[6] = {0,1,0,1,0,1};
dummy->SetFloatBounds(originalBounds);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetBounds(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetBounds(anotherBoundingBox->GetBounds());
CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, true));
//Test needs to fail now
dummy->SetBounds(aThirdBoundingBox->GetBounds());
CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, false)==false);
//undo changes, new and changed object need to be the same!
dummy->SetBounds(aBoundingBox->GetBounds());
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetFloatBoundsDouble(){
double bounds[6] = {0,11,0,12,0,13};
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, true));
//Test needs to fail now
bounds[3]=7;
dummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, false)==false);
//undo changes, new and changed object need to be the same!
double originalBounds[6] = {0,1,0,1,0,1};
dummy->SetFloatBounds(originalBounds);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetFrameOfReferenceID()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetFrameOfReferenceID(5);
CPPUNIT_ASSERT(dummy->GetFrameOfReferenceID()==5);
//undo changes, new and changed object need to be the same!
dummy->SetFrameOfReferenceID(0);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetIndexToWorldTransform()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(anotherTransform);
CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,true));
//Test needs to fail now
dummy->SetIndexToWorldTransform(aThirdTransform);
CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,false)==false);
//undo changes, new and changed object need to be the same!
dummy->SetIndexToWorldTransform(aTransform);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetIndexToWorldTransform_WithPointerToSameTransform()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetOrigin(anotherPoint);
dummy->SetIndexToWorldTransform(anotherTransform);
dummy->SetSpacing(anotherSpacing);
mitk::AffineTransform3D::Pointer testTransfrom = dummy->GetIndexToWorldTransform();
mitk::Vector3D modifiedPoint = anotherPoint.GetVectorFromOrigin() *2.;
testTransfrom->SetOffset(modifiedPoint);
dummy->SetIndexToWorldTransform(testTransfrom);
CPPUNIT_ASSERT(mitk::Equal(modifiedPoint, dummy->GetOrigin().GetVectorFromOrigin()));
}
void TestSetIndexToWorldTransformByVtkMatrix()
{
vtkMatrix4x4* vtkmatrix;
vtkmatrix = vtkMatrix4x4::New();
vtkmatrix->Identity();
vtkmatrix->SetElement(1,1,2);
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransformByVtkMatrix(vtkmatrix);
CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,true));
//test needs to fail now
vtkmatrix->SetElement(1,1,7);
dummy->SetIndexToWorldTransformByVtkMatrix(vtkmatrix);
CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,false)==false);
//undo changes, new and changed object need to be the same!
vtkmatrix->SetElement(1,1,1);
dummy->SetIndexToWorldTransformByVtkMatrix(vtkmatrix);
+ vtkmatrix->Delete();
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetIdentity()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
//Change IndextoWorldTransform and Origin
dummy->SetIndexToWorldTransform(anotherTransform);
dummy->SetOrigin(anotherPoint);
//Set Identity should reset ITWT and Origin
dummy->SetIdentity();
CPPUNIT_ASSERT(mitk::Equal(aTransform,dummy->GetIndexToWorldTransform(),mitk::eps,true));
CPPUNIT_ASSERT(mitk::Equal(aPoint,dummy->GetOrigin()));
CPPUNIT_ASSERT(mitk::Equal(aSpacing,dummy->GetSpacing()));
//new and changed object need to be the same!
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestSetSpacing()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetSpacing(anotherSpacing);
CPPUNIT_ASSERT(mitk::Equal(anotherSpacing,dummy->GetSpacing()));
//undo changes, new and changed object need to be the same!
dummy->SetSpacing(aSpacing);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestTransferItkToVtkTransform()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(anotherTransform); //calls TransferItkToVtkTransform
mitk::AffineTransform3D::Pointer dummyTransform = dummy->GetIndexToWorldTransform();
CPPUNIT_ASSERT(mitk::MatrixEqualElementWise( anotherMatrix, dummyTransform->GetMatrix() ));
}
void TestConstructors()
{
//test standard constructor
DummyTestClass::Pointer dummy1 = DummyTestClass::New();
bool test = dummy1->IsValid();
CPPUNIT_ASSERT(test == true);
CPPUNIT_ASSERT(dummy1->GetFrameOfReferenceID() == 0);
CPPUNIT_ASSERT(dummy1->GetIndexToWorldTransformLastModified() == 0);
CPPUNIT_ASSERT(mitk::Equal(dummy1->GetSpacing(), aSpacing));
CPPUNIT_ASSERT(mitk::Equal(dummy1->GetOrigin(), aPoint));
CPPUNIT_ASSERT(dummy1->GetImageGeometry()==false);
CPPUNIT_ASSERT(mitk::Equal( dummy1->GetIndexToWorldTransform(), aTransform, mitk::eps, true));
CPPUNIT_ASSERT(mitk::Equal( dummy1->GetBoundingBox(), aBoundingBox, mitk::eps, true));
DummyTestClass::Pointer dummy2 = DummyTestClass::New();
dummy2->SetOrigin(anotherPoint);
float bounds[6] = {0,11,0,12,0,13};
dummy2->SetFloatBounds(bounds);
dummy2->SetIndexToWorldTransform(anotherTransform);
dummy2->SetSpacing(anotherSpacing);
DummyTestClass::Pointer dummy3 = DummyTestClass::New(*dummy2);
CPPUNIT_ASSERT(mitk::Equal(dummy3,dummy2,mitk::eps,true));
}
//Equal Tests
void Equal_CloneAndOriginal_ReturnsTrue()
{
CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,true));
}
void Equal_DifferentOrigin_ReturnsFalse()
{
anotherDummyGeometry->SetOrigin(anotherPoint);
CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false);
}
void Equal_DifferentIndexToWorldTransform_ReturnsFalse()
{
anotherDummyGeometry->SetIndexToWorldTransform(anotherTransform);
CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false);
}
void Equal_DifferentSpacing_ReturnsFalse()
{
anotherDummyGeometry->SetSpacing(anotherSpacing);
CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false);
}
void Equal_InputIsNull_ReturnsFalse()
{
DummyTestClass::Pointer geometryNull = NULL;
MITK_INFO<<"Test, if a Null pointer throws an error. The next line needs to display an error.";
CPPUNIT_ASSERT( mitk::Equal(geometryNull, anotherDummyGeometry, mitk::eps,false)==false);
}
void Equal_DifferentBoundingBox_ReturnsFalse()
{
//create different bounds to make the comparison false
mitk::ScalarType bounds[ ] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
anotherDummyGeometry->SetBounds(bounds);
CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false);
}
void TestComposeTransform(){
//Create Transformations to set and compare
mitk::AffineTransform3D::Pointer transform1;
transform1 = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType matrix1;
matrix1.SetIdentity();
matrix1(1,1) = 2;
transform1->SetMatrix( matrix1 ); //Spacing = 2
mitk::AffineTransform3D::Pointer transform2;
transform2 = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType matrix2;
matrix2.SetIdentity();
matrix2(1,1) = 2;
transform2->SetMatrix( matrix2 ); //Spacing = 2
mitk::AffineTransform3D::Pointer transform3;
transform3 = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType matrix3;
matrix3.SetIdentity();
matrix3(1,1) = 4;
transform3->SetMatrix( matrix3 ); //Spacing = 4
mitk::AffineTransform3D::Pointer transform4;
transform4 = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType matrix4;
matrix4.SetIdentity();
matrix4(1,1) = 0.25;
transform4->SetMatrix( matrix4 ); //Spacing = 0.25
//Vector to compare spacing
mitk::Vector3D expectedSpacing;
expectedSpacing.Fill(1.0);
expectedSpacing[1] = 4;
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(transform1); //Spacing = 2
dummy->Compose(transform2); //Spacing = 4
CPPUNIT_ASSERT(mitk::Equal(dummy->GetSpacing(), expectedSpacing));
CPPUNIT_ASSERT(mitk::Equal(transform3,dummy->GetIndexToWorldTransform(),mitk::eps,true)); // 4=4
//undo changes, new and changed object need to be the same!
dummy->Compose(transform4); //Spacing = 1
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); // 1=1
}
void TestComposeVtkMatrix(){
//Create Transformations to set and compare
mitk::AffineTransform3D::Pointer transform1;
transform1 = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType matrix1;
matrix1.SetIdentity();
matrix1(1,1) = 2;
transform1->SetMatrix( matrix1 ); //Spacing = 2
vtkMatrix4x4* vtkmatrix2;
vtkmatrix2 = vtkMatrix4x4::New();
vtkmatrix2->Identity();
vtkmatrix2->SetElement(1,1,2); //Spacing = 2
mitk::AffineTransform3D::Pointer transform3;
transform3 = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType matrix3;
matrix3.SetIdentity();
matrix3(1,1) = 4;
transform3->SetMatrix( matrix3 ); //Spacing = 4
vtkMatrix4x4* vtkmatrix4;
vtkmatrix4 = vtkMatrix4x4::New();
vtkmatrix4->Identity();
vtkmatrix4->SetElement(1,1,0.25); //Spacing = 0.25
//Vector to compare spacing
mitk::Vector3D expectedSpacing;
expectedSpacing.Fill(1.0);
expectedSpacing[1] = 4;
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(transform1); //Spacing = 2
dummy->Compose(vtkmatrix2); //Spacing = 4
+ vtkmatrix2->Delete();
CPPUNIT_ASSERT(mitk::Equal(transform3,dummy->GetIndexToWorldTransform(),mitk::eps,true)); // 4=4
CPPUNIT_ASSERT(mitk::Equal(dummy->GetSpacing(), expectedSpacing));
//undo changes, new and changed object need to be the same!
dummy->Compose(vtkmatrix4); //Spacing = 1
+ vtkmatrix4->Delete();
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); // 1=1
}
void TestTranslate(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetOrigin(anotherPoint);
CPPUNIT_ASSERT(mitk::Equal(anotherPoint,dummy->GetOrigin()));
//use some random values for translation
mitk::Vector3D translationVector;
translationVector.SetElement(0, 17.5f);
translationVector.SetElement(1, -32.3f);
translationVector.SetElement(2, 4.0f);
//compute ground truth
mitk::Point3D tmpResult = anotherPoint + translationVector;
dummy->Translate(translationVector);
CPPUNIT_ASSERT( mitk::Equal( dummy->GetOrigin(), tmpResult ));
//undo changes
translationVector*=-1;
dummy->Translate(translationVector);
CPPUNIT_ASSERT( mitk::Equal( dummy->GetOrigin(), anotherPoint ));
//undo changes, new and changed object need to be the same!
translationVector.SetElement(0, -1 * anotherPoint[0]);
translationVector.SetElement(1, -1 * anotherPoint[1]);
translationVector.SetElement(2, -1 * anotherPoint[2]);
dummy->Translate(translationVector);
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
// a part of the test requires axis-parallel coordinates
int testIndexAndWorldConsistency(DummyTestClass::Pointer dummyGeometry)
{
//Testing consistency of index and world coordinate systems
mitk::Point3D origin = dummyGeometry->GetOrigin();
mitk::Point3D dummyPoint;
//Testing index->world->index conversion consistency
dummyGeometry->WorldToIndex(origin, dummyPoint);
dummyGeometry->IndexToWorld(dummyPoint, dummyPoint);
CPPUNIT_ASSERT(mitk::EqualArray(dummyPoint, origin, 3, mitk::eps, true));
//Testing WorldToIndex(origin, mitk::Point3D)==(0,0,0)
mitk::Point3D globalOrigin;
mitk::FillVector3D(globalOrigin, 0,0,0);
mitk::Point3D originContinuousIndex;
dummyGeometry->WorldToIndex(origin, originContinuousIndex);
CPPUNIT_ASSERT(mitk::EqualArray(originContinuousIndex, globalOrigin, 3, mitk::eps, true));
//Testing WorldToIndex(origin, itk::Index)==(0,0,0)
itk::Index<3> itkindex;
dummyGeometry->WorldToIndex(origin, itkindex);
itk::Index<3> globalOriginIndex;
mitk::vtk2itk(globalOrigin, globalOriginIndex);
CPPUNIT_ASSERT(mitk::EqualArray(itkindex, globalOriginIndex, 3, mitk::eps, true));
//Testing WorldToIndex(origin-0.5*spacing, itk::Index)==(0,0,0)
mitk::Vector3D halfSpacingStep = dummyGeometry->GetSpacing()*0.5;
mitk::Matrix3D rotation;
mitk::Point3D originOffCenter = origin-halfSpacingStep;
dummyGeometry->WorldToIndex(originOffCenter, itkindex);
CPPUNIT_ASSERT(mitk::EqualArray(itkindex, globalOriginIndex, 3, mitk::eps, true));
//Testing WorldToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)
originOffCenter = origin+halfSpacingStep;
originOffCenter -= 0.0001;
dummyGeometry->WorldToIndex( originOffCenter, itkindex);
CPPUNIT_ASSERT(mitk::EqualArray(itkindex, globalOriginIndex, 3, mitk::eps, true));
//Testing WorldToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)");
originOffCenter = origin+halfSpacingStep;
itk::Index<3> global111;
mitk::FillVector3D(global111, 1,1,1);
dummyGeometry->WorldToIndex( originOffCenter, itkindex);
CPPUNIT_ASSERT(mitk::EqualArray(itkindex, global111, 3, mitk::eps, true));
//Testing WorldToIndex(GetCenter())==BoundingBox.GetCenter
mitk::Point3D center = dummyGeometry->GetCenter();
mitk::Point3D centerContIndex;
dummyGeometry->WorldToIndex(center, centerContIndex);
mitk::BoundingBox::ConstPointer boundingBox = dummyGeometry->GetBoundingBox();
mitk::BoundingBox::PointType centerBounds = boundingBox->GetCenter();
CPPUNIT_ASSERT(mitk::Equal(centerContIndex,centerBounds));
//Testing GetCenter()==IndexToWorld(BoundingBox.GetCenter)
center = dummyGeometry->GetCenter();
mitk::Point3D centerBoundsInWorldCoords;
dummyGeometry->IndexToWorld(centerBounds, centerBoundsInWorldCoords);
CPPUNIT_ASSERT(mitk::Equal(center,centerBoundsInWorldCoords));
//Test using random point,
//Testing consistency of index and world coordinate systems
mitk::Point3D point;
mitk::FillVector3D(point,3.5,-2,4.6);
//Testing index->world->index conversion consistency
dummyGeometry->WorldToIndex(point, dummyPoint);
dummyGeometry->IndexToWorld(dummyPoint, dummyPoint);
CPPUNIT_ASSERT(mitk::EqualArray(dummyPoint, point, 3, mitk::eps, true));
return EXIT_SUCCESS;
}
int testIndexAndWorldConsistencyForVectors(DummyTestClass::Pointer dummyGeometry)
{
//Testing consistency of index and world coordinate systems for vectors
mitk::Vector3D xAxisMM = dummyGeometry->GetAxisVector(0);
mitk::Vector3D xAxisContinuousIndex;
mitk::Point3D p, pIndex, origin;
origin = dummyGeometry->GetOrigin();
p[0] = xAxisMM[0]+origin[0];
p[1] = xAxisMM[1]+origin[1];
p[2] = xAxisMM[2]+origin[2];
dummyGeometry->WorldToIndex(p,pIndex);
dummyGeometry->WorldToIndex(xAxisMM,xAxisContinuousIndex);
CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[0], pIndex[0]));
CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[1], pIndex[1]));
CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[2], pIndex[2]));
dummyGeometry->IndexToWorld(xAxisContinuousIndex,xAxisContinuousIndex);
dummyGeometry->IndexToWorld(pIndex,p);
CPPUNIT_ASSERT(xAxisContinuousIndex == xAxisMM);
CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[0], p[0]-origin[0]));
CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[1], p[1]-origin[1]));
CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[2], p[2]-origin[2]));
//Test consictency for random vector
mitk::Vector3D vector;
mitk::FillVector3D(vector, 2.5,-3.2,8.1);
mitk::Vector3D vectorContinuousIndex;
p[0] = vector[0]+origin[0];
p[1] = vector[1]+origin[1];
p[2] = vector[2]+origin[2];
dummyGeometry->WorldToIndex(p,pIndex);
dummyGeometry->WorldToIndex(vector,vectorContinuousIndex);
CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[0], pIndex[0]));
CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[1], pIndex[1]));
CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[2], pIndex[2]));
dummyGeometry->IndexToWorld(vectorContinuousIndex,vectorContinuousIndex);
dummyGeometry->IndexToWorld(pIndex,p);
CPPUNIT_ASSERT(vectorContinuousIndex == vector);
CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[0], p[0]-origin[0]));
CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[1], p[1]-origin[1]));
CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[2], p[2]-origin[2]));
return EXIT_SUCCESS;
}
int testIndexAndWorldConsistencyForIndex(DummyTestClass::Pointer dummyGeometry)
{
//Testing consistency of index and world coordinate systems
// creating testing data
itk::Index<4> itkIndex4, itkIndex4b;
itk::Index<3> itkIndex3, itkIndex3b;
itk::Index<2> itkIndex2, itkIndex2b;
itk::Index<3> mitkIndex, mitkIndexb;
itkIndex4[0] = itkIndex4[1] = itkIndex4[2] = itkIndex4[3] = 4;
itkIndex3[0] = itkIndex3[1] = itkIndex3[2] = 6;
itkIndex2[0] = itkIndex2[1] = 2;
mitkIndex[0] = mitkIndex[1] = mitkIndex[2] = 13;
// check for constistency
mitk::Point3D point;
dummyGeometry->IndexToWorld(itkIndex2,point);
dummyGeometry->WorldToIndex(point,itkIndex2b);
CPPUNIT_ASSERT(
((itkIndex2b[0] == itkIndex2[0]) &&
(itkIndex2b[1] == itkIndex2[1])));
//Testing itk::index<2> for IndexToWorld/WorldToIndex consistency
dummyGeometry->IndexToWorld(itkIndex3,point);
dummyGeometry->WorldToIndex(point,itkIndex3b);
CPPUNIT_ASSERT(
((itkIndex3b[0] == itkIndex3[0]) &&
(itkIndex3b[1] == itkIndex3[1]) &&
(itkIndex3b[2] == itkIndex3[2])));
//Testing itk::index<3> for IndexToWorld/WorldToIndex consistency
dummyGeometry->IndexToWorld(itkIndex4,point);
dummyGeometry->WorldToIndex(point,itkIndex4b);
CPPUNIT_ASSERT(
((itkIndex4b[0] == itkIndex4[0]) &&
(itkIndex4b[1] == itkIndex4[1]) &&
(itkIndex4b[2] == itkIndex4[2]) &&
(itkIndex4b[3] == 0)));
//Testing itk::index<3> for IndexToWorld/WorldToIndex consistency
dummyGeometry->IndexToWorld(mitkIndex,point);
dummyGeometry->WorldToIndex(point,mitkIndexb);
CPPUNIT_ASSERT(
((mitkIndexb[0] == mitkIndex[0]) &&
(mitkIndexb[1] == mitkIndex[1]) &&
(mitkIndexb[2] == mitkIndex[2])));
//Testing mitk::Index for IndexToWorld/WorldToIndex consistency
return EXIT_SUCCESS;
}
void TestIndexToWorld(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
testIndexAndWorldConsistency(dummy);
testIndexAndWorldConsistencyForVectors(dummy);
testIndexAndWorldConsistencyForIndex(dummy);
//Geometry must not have changed
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
//Test with other geometries
dummy->SetOrigin(anotherPoint);
testIndexAndWorldConsistency(dummy);
testIndexAndWorldConsistencyForVectors(dummy);
testIndexAndWorldConsistencyForIndex(dummy);
dummy->SetIndexToWorldTransform(anotherTransform);
testIndexAndWorldConsistency(dummy);
testIndexAndWorldConsistencyForVectors(dummy);
testIndexAndWorldConsistencyForIndex(dummy);
dummy->SetOrigin(anotherPoint);
testIndexAndWorldConsistency(dummy);
testIndexAndWorldConsistencyForVectors(dummy);
testIndexAndWorldConsistencyForIndex(dummy);
dummy->SetSpacing(anotherSpacing);
testIndexAndWorldConsistency(dummy);
testIndexAndWorldConsistencyForVectors(dummy);
testIndexAndWorldConsistencyForIndex(dummy);
}
void TestExecuteOperation(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
//Do same Operations with new Dummy and compare
DummyTestClass::Pointer newDummy = DummyTestClass::New();
//Test operation Nothing
mitk::Operation* opN = new mitk::Operation(mitk::OpNOTHING);
dummy->ExecuteOperation(opN);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
//Test operation Move
mitk::PointOperation* opP = new mitk::PointOperation(mitk::OpMOVE,anotherPoint);
dummy->ExecuteOperation(opP);
CPPUNIT_ASSERT(mitk::Equal(anotherPoint,dummy->GetOrigin()));
newDummy->SetOrigin(anotherPoint);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
//Test operation Scale, Scale sets spacing to scale+1
mitk::Point3D spacing;
spacing[0]=anotherSpacing[0]-1.;
spacing[1]=anotherSpacing[1]-1.;
spacing[2]=anotherSpacing[2]-1.;
mitk::PointOperation* opS = new mitk::PointOperation(mitk::OpSCALE,spacing);
dummy->ExecuteOperation(opS);
CPPUNIT_ASSERT(mitk::Equal(anotherSpacing,dummy->GetSpacing()));
newDummy->SetSpacing(anotherSpacing);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
//change Geometry to test more cases
dummy->SetIndexToWorldTransform(anotherTransform);
dummy->SetSpacing(anotherSpacing);
//Testing a rotation of the geometry
double angle = 35.0;
mitk::Vector3D rotationVector; mitk::FillVector3D( rotationVector, 1, 0, 0 );
mitk::Point3D center = dummy->GetCenter();
mitk::RotationOperation* opR = new mitk::RotationOperation( mitk::OpROTATE, center, rotationVector, angle );
dummy->ExecuteOperation(opR);
mitk::Matrix3D rotation;
mitk::GetRotation(dummy, rotation);
mitk::Vector3D voxelStep=rotation*anotherSpacing;
mitk::Vector3D voxelStepIndex;
dummy->WorldToIndex(voxelStep, voxelStepIndex);
mitk::Vector3D expectedVoxelStepIndex;
expectedVoxelStepIndex.Fill(1);
CPPUNIT_ASSERT(mitk::Equal(voxelStepIndex,expectedVoxelStepIndex));
delete opR;
delete opN;
delete opS;
delete opP;
}
void TestCalculateBoundingBoxRelToTransform(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetExtentInMM(0,15);
dummy->SetExtentInMM(1,20);
dummy->SetExtentInMM(2,8);
mitk::BoundingBox::Pointer dummyBoundingBox = dummy->CalculateBoundingBoxRelativeToTransform(anotherTransform);
mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New();
mitk::BoundingBox::PointIdentifier pointid=0;
unsigned char i;
mitk::AffineTransform3D::Pointer inverse = mitk::AffineTransform3D::New();
anotherTransform->GetInverse(inverse);
for(i=0; i<8; ++i)
pointscontainer->InsertElement( pointid++, inverse->TransformPoint( dummy->GetCornerPoint(i) ));
mitk::BoundingBox::Pointer result = mitk::BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
CPPUNIT_ASSERT(mitk::Equal(result,dummyBoundingBox,mitk::eps,true));
//dummy still needs to be unchanged, except for extend
DummyTestClass::Pointer newDummy = DummyTestClass::New();
newDummy->SetExtentInMM(0,15);
newDummy->SetExtentInMM(1,20);
newDummy->SetExtentInMM(2,8);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
//void TestSetTimeBounds(){
// mitk::TimeBounds timeBounds;
// timeBounds[0] = 1;
// timeBounds[1] = 9;
// DummyTestClass::Pointer dummy = DummyTestClass::New();
// dummy->SetTimeBounds(timeBounds);
// mitk::TimeBounds timeBounds2 = dummy->GetTimeBounds();
// CPPUNIT_ASSERT(timeBounds[0]==timeBounds2[0]);
// CPPUNIT_ASSERT(timeBounds[1]==timeBounds2[1]);
// //undo changes, new and changed object need to be the same!
// timeBounds[0]=mitk::ScalarTypeNumericTraits::NonpositiveMin();
// timeBounds[1]=mitk::ScalarTypeNumericTraits::max();
// DummyTestClass::Pointer newDummy = DummyTestClass::New();
// CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
//}
void TestIs2DConvertable(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
//new initialized geometry is 2D convertable
CPPUNIT_ASSERT(dummy->Is2DConvertable());
//Wrong Spacing needs to fail
dummy->SetSpacing(anotherSpacing);
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
//undo
dummy->SetSpacing(aSpacing);
CPPUNIT_ASSERT(dummy->Is2DConvertable());
//Wrong Origin needs to fail
dummy->SetOrigin(anotherPoint);
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
//undo
dummy->SetOrigin(aPoint);
CPPUNIT_ASSERT(dummy->Is2DConvertable());
//third dimension must not be transformed
mitk::AffineTransform3D::Pointer dummyTransform = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType dummyMatrix;
dummyMatrix.SetIdentity();
dummyTransform->SetMatrix( dummyMatrix );
dummy->SetIndexToWorldTransform(dummyTransform);
//identity matrix is 2DConvertable
CPPUNIT_ASSERT(dummy->Is2DConvertable());
dummyMatrix(0,2) = 3;
dummyTransform->SetMatrix( dummyMatrix );
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
dummyMatrix.SetIdentity();
dummyMatrix(1,2) = 0.4;
dummyTransform->SetMatrix( dummyMatrix );
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
dummyMatrix.SetIdentity();
dummyMatrix(2,2) = 3;
dummyTransform->SetMatrix( dummyMatrix );
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
dummyMatrix.SetIdentity();
dummyMatrix(2,1) = 3;
dummyTransform->SetMatrix( dummyMatrix );
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
dummyMatrix.SetIdentity();
dummyMatrix(2,0) = 3;
dummyTransform->SetMatrix( dummyMatrix );
CPPUNIT_ASSERT(dummy->Is2DConvertable()==false);
//undo changes, new and changed object need to be the same!
dummyMatrix.SetIdentity();
dummyTransform->SetMatrix( dummyMatrix );
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestGetCornerPoint(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(anotherTransform);
double bounds[6] = {0,11,0,12,0,13};
dummy->SetFloatBounds(bounds);
mitk::Point3D corner, refCorner;
//Corner 0
mitk::FillVector3D(refCorner,bounds[0],bounds[2],bounds[4]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(0);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(true,true,true);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 1
mitk::FillVector3D(refCorner,bounds[0],bounds[2],bounds[5]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(1);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(true,true,false);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 2
mitk::FillVector3D(refCorner,bounds[0],bounds[3],bounds[4]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(2);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(true,false,true);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 3
mitk::FillVector3D(refCorner,bounds[0],bounds[3],bounds[5]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(3);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(true,false,false);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 4
mitk::FillVector3D(refCorner,bounds[1],bounds[2],bounds[4]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(4);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(false,true,true);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 5
mitk::FillVector3D(refCorner,bounds[1],bounds[2],bounds[5]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(5);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(false,true,false);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 6
mitk::FillVector3D(refCorner,bounds[1],bounds[3],bounds[4]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(6);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(false,false,true);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Corner 7
mitk::FillVector3D(refCorner,bounds[1],bounds[3],bounds[5]);
refCorner = anotherTransform->TransformPoint(refCorner);
corner=dummy->GetCornerPoint(7);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
corner=dummy->GetCornerPoint(false,false,false);
CPPUNIT_ASSERT(mitk::Equal(refCorner,corner));
//Wrong Corner needs to fail
CPPUNIT_ASSERT_THROW(dummy->GetCornerPoint(20),itk::ExceptionObject);
//dummy geometry must not have changed!
DummyTestClass::Pointer newDummy = DummyTestClass::New();
newDummy->SetIndexToWorldTransform(anotherTransform);
newDummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestExtentInMM()
{
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetExtentInMM(0,50);
CPPUNIT_ASSERT(mitk::Equal(50.,dummy->GetExtentInMM(0)));
//Vnl Matrix has changed. The next line only works because the spacing is 1!
CPPUNIT_ASSERT(mitk::Equal(50.,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).magnitude()));
//Smaller extent than original
dummy->SetExtentInMM(0,5);
CPPUNIT_ASSERT(mitk::Equal(5.,dummy->GetExtentInMM(0)));
CPPUNIT_ASSERT(mitk::Equal(5.,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).magnitude()));
dummy->SetExtentInMM(1,4);
CPPUNIT_ASSERT(mitk::Equal(4.,dummy->GetExtentInMM(1)));
CPPUNIT_ASSERT(mitk::Equal(4.,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1).magnitude()));
dummy->SetExtentInMM(2,2.5);
CPPUNIT_ASSERT(mitk::Equal(2.5,dummy->GetExtentInMM(2)));
CPPUNIT_ASSERT(mitk::Equal(2.5,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2).magnitude()));
}
void TestGetAxisVector(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(anotherTransform);
double bounds[6] = {0,11,0,12,0,13};
dummy->SetFloatBounds(bounds);
mitk::Vector3D vector;
mitk::FillVector3D(vector,bounds[1],0,0);
dummy->IndexToWorld(vector,vector);
CPPUNIT_ASSERT(mitk::Equal(dummy->GetAxisVector(0),vector));
mitk::FillVector3D(vector,0,bounds[3],0);
dummy->IndexToWorld(vector,vector);
CPPUNIT_ASSERT(mitk::Equal(dummy->GetAxisVector(1),vector));
mitk::FillVector3D(vector,0,0,bounds[5]);
dummy->IndexToWorld(vector,vector);
CPPUNIT_ASSERT(mitk::Equal(dummy->GetAxisVector(2),vector));
}
void TestGetCenter(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(anotherTransform);
double bounds[6] = {0,11,2,12,1,13};
dummy->SetFloatBounds(bounds);
mitk::Point3D refCenter;
for( int i=0;i<3;i++)
refCenter.SetElement(i,( bounds[2 * i] + bounds[2 * i + 1] ) / 2.0);
dummy->IndexToWorld(refCenter,refCenter);
CPPUNIT_ASSERT(mitk::Equal(dummy->GetCenter(),refCenter));
}
void TestGetDiagonalLength(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
double bounds[6] = {1,3,5,8,7.5,11.5};
dummy->SetFloatBounds(bounds);
//3-1=2, 8-5=3, 11.5-7.5=4; 2^2+3^2+4^2 = 29
double expectedLength = sqrt(29.);
CPPUNIT_ASSERT(mitk::Equal(expectedLength, dummy->GetDiagonalLength(), mitk::eps, true));
CPPUNIT_ASSERT(mitk::Equal(29., dummy->GetDiagonalLength2(), mitk::eps, true));
//dummy must not have changed
DummyTestClass::Pointer newDummy = DummyTestClass::New();
newDummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestGetExtent(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
double bounds[6] = {1,3,5,8,7.5,11.5};
dummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal(2.,dummy->GetExtent(0)));
CPPUNIT_ASSERT(mitk::Equal(3.,dummy->GetExtent(1)));
CPPUNIT_ASSERT(mitk::Equal(4.,dummy->GetExtent(2)));
//dummy must not have changed
DummyTestClass::Pointer newDummy = DummyTestClass::New();
newDummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestIsInside(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
double bounds[6] = {1,3,5,8,7.5,11.5};
dummy->SetFloatBounds(bounds);
mitk::Point3D insidePoint;
mitk::Point3D outsidePoint;
mitk::FillVector3D(insidePoint,2,6,7.6);
mitk::FillVector3D(outsidePoint,0,9,8.2);
CPPUNIT_ASSERT(dummy->IsIndexInside(insidePoint));
CPPUNIT_ASSERT(false==dummy->IsIndexInside(outsidePoint));
dummy->IndexToWorld(insidePoint,insidePoint);
dummy->IndexToWorld(outsidePoint,outsidePoint);
CPPUNIT_ASSERT(dummy->IsInside(insidePoint));
CPPUNIT_ASSERT(false==dummy->IsInside(outsidePoint));
//dummy must not have changed
DummyTestClass::Pointer newDummy = DummyTestClass::New();
newDummy->SetFloatBounds(bounds);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
void TestInitialize()
{
//test standard constructor
DummyTestClass::Pointer dummy1 = DummyTestClass::New();
DummyTestClass::Pointer dummy2 = DummyTestClass::New();
dummy2->SetOrigin(anotherPoint);
dummy2->SetBounds(anotherBoundingBox->GetBounds());
//mitk::TimeBounds timeBounds;
//timeBounds[0] = 1;
//timeBounds[1] = 9;
//dummy2->SetTimeBounds(timeBounds);
dummy2->SetIndexToWorldTransform(anotherTransform);
dummy2->SetSpacing(anotherSpacing);
dummy1->InitializeGeometry(dummy2);
CPPUNIT_ASSERT(mitk::Equal(dummy1,dummy2,mitk::eps,true));
dummy1->Initialize();
DummyTestClass::Pointer dummy3 = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy3,dummy1,mitk::eps,true));
}
void TestGetMatrixColumn(){
DummyTestClass::Pointer dummy = DummyTestClass::New();
dummy->SetIndexToWorldTransform(anotherTransform);
mitk::Vector3D testVector,refVector;
testVector.SetVnlVector(dummy->GetMatrixColumn(0));
mitk::FillVector3D(refVector,1,0,0);
CPPUNIT_ASSERT(testVector==refVector);
testVector.SetVnlVector(dummy->GetMatrixColumn(1));
mitk::FillVector3D(refVector,0,2,0);
CPPUNIT_ASSERT(testVector==refVector);
testVector.SetVnlVector(dummy->GetMatrixColumn(2));
mitk::FillVector3D(refVector,0,0,1);
CPPUNIT_ASSERT(testVector==refVector);
//dummy must not have changed
DummyTestClass::Pointer newDummy = DummyTestClass::New();
newDummy->SetIndexToWorldTransform(anotherTransform);
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
/*
void (){
DummyTestClass::Pointer dummy = DummyTestClass::New();
CPPUNIT_ASSERT();
//undo changes, new and changed object need to be the same!
DummyTestClass::Pointer newDummy = DummyTestClass::New();
CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true));
}
*/
};//end class mitkBaseGeometryTestSuite
MITK_TEST_SUITE_REGISTRATION(mitkBaseGeometry)
diff --git a/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp b/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp
index 21f4f3d702..fc1c9c2a0b 100644
--- a/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp
+++ b/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp
@@ -1,484 +1,485 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTestingMacros.h"
#include <iostream>
#include "mitkClippedSurfaceBoundsCalculator.h"
#include "mitkGeometry3D.h"
#include "mitkPlaneGeometry.h"
#include "mitkNumericTypes.h"
static void CheckPlanesInsideBoundingBoxOnlyOnOneSlice(mitk::BaseGeometry::Pointer geometry3D)
{
//Check planes which are inside the bounding box
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer image = mitk::Image::New();
image->Initialize( mitk::MakePixelType<int, int, 1>(), *(geometry3D.GetPointer()) );
//Check planes which are only on one slice:
//Slice 0
mitk::Point3D origin;
origin[0] = 511;
origin[1] = 0;
origin[2] = 0;
mitk::Vector3D normal;
mitk::FillVector3D(normal, 0, 0, 1);
mitk::PlaneGeometry::Pointer planeOnSliceZero = mitk::PlaneGeometry::New();
planeOnSliceZero->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceZero , image);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 0, "Check if plane is on slice 0");
//Slice 3
origin[2] = 3;
mitk::PlaneGeometry::Pointer planeOnSliceThree = mitk::PlaneGeometry::New();
planeOnSliceThree->InitializePlane(origin, normal);
planeOnSliceThree->SetImageGeometry(false);
calculator->SetInput( planeOnSliceThree , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 3 && minMax.second == 3, "Check if plane is on slice 3");
//Slice 17
origin[2] = 17;
mitk::PlaneGeometry::Pointer planeOnSliceSeventeen = mitk::PlaneGeometry::New();
planeOnSliceSeventeen->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceSeventeen , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 17 && minMax.second == 17, "Check if plane is on slice 17");
//Slice 20
origin[2] = 19;
mitk::PlaneGeometry::Pointer planeOnSliceTwenty = mitk::PlaneGeometry::New();
planeOnSliceTwenty->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceTwenty , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 19 && minMax.second == 19, "Check if plane is on slice 19");
delete calculator;
}
static void CheckPlanesInsideBoundingBox(mitk::BaseGeometry::Pointer geometry3D)
{
//Check planes which are inside the bounding box
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer image = mitk::Image::New();
image->Initialize( mitk::MakePixelType<int, int, 1>(), *(geometry3D.GetPointer()) );
//Check planes which are only on one slice:
//Slice 0
mitk::Point3D origin;
origin[0] = 511; // Set to 511.9 so that the intersection point is inside the bounding box
origin[1] = 0;
origin[2] = 0;
mitk::Vector3D normal;
mitk::FillVector3D(normal, 1, 0, 0);
mitk::PlaneGeometry::Pointer planeSagittalOne = mitk::PlaneGeometry::New();
planeSagittalOne->InitializePlane(origin, normal);
calculator->SetInput( planeSagittalOne , image);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
//Slice 3
origin[0] = 256;
MITK_INFO << "Case1 origin: " << origin;
mitk::PlaneGeometry::Pointer planeSagittalTwo = mitk::PlaneGeometry::New();
planeSagittalTwo->InitializePlane(origin, normal);
MITK_INFO << "PlaneNormal: " << planeSagittalTwo->GetNormal();
MITK_INFO << "PlaneOrigin: " << planeSagittalTwo->GetOrigin();
calculator->SetInput( planeSagittalTwo , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
//Slice 17
origin[0] = 0; // Set to 0.1 so that the intersection point is inside the bounding box
mitk::PlaneGeometry::Pointer planeOnSliceSeventeen = mitk::PlaneGeometry::New();
planeOnSliceSeventeen->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceSeventeen , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
//Crooked planes:
origin[0] = 0;
origin[1] = 507;
origin[2] = 0;
normal[0] = 1;
normal[1] = -1;
normal[2] = 1;
mitk::PlaneGeometry::Pointer planeCrookedOne = mitk::PlaneGeometry::New();
planeCrookedOne->InitializePlane(origin, normal);
calculator->SetInput( planeCrookedOne , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 4, "Check if plane is from slice 0 to slice 4 with inclined plane");
origin[0] = 512;
origin[1] = 0;
origin[2] = 16;
mitk::PlaneGeometry::Pointer planeCrookedTwo = mitk::PlaneGeometry::New();
planeCrookedTwo->InitializePlane(origin, normal);
calculator->SetInput( planeCrookedTwo , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 17 && minMax.second == 19, "Check if plane is from slice 17 to slice 19 with inclined plane");
origin[0] = 511;
origin[1] = 0;
origin[2] = 0;
normal[1] = 0;
normal[2] = 0.04;
mitk::PlaneGeometry::Pointer planeCrookedThree = mitk::PlaneGeometry::New();
planeCrookedThree->InitializePlane(origin, normal);
calculator->SetInput( planeCrookedThree , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19 with inclined plane");
delete calculator;
}
static void CheckPlanesOutsideOfBoundingBox(mitk::BaseGeometry::Pointer geometry3D)
{
//Check planes which are outside of the bounding box
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer image = mitk::Image::New();
image->Initialize( mitk::MakePixelType<int, int, 1>(), *(geometry3D.GetPointer()) );
//In front of the bounding box
mitk::Point3D origin;
origin[0] = 511;
origin[1] = 0;
origin[2] = -5;
mitk::Vector3D normal;
mitk::FillVector3D(normal, 0, 0, 1);
mitk::PlaneGeometry::Pointer planeInFront = mitk::PlaneGeometry::New();
planeInFront->InitializePlane(origin, normal);
calculator->SetInput( planeInFront , image);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Behind the bounding box
origin[2] = 515;
mitk::PlaneGeometry::Pointer planeBehind = mitk::PlaneGeometry::New();
planeBehind->InitializePlane(origin, normal);
calculator->SetInput( planeBehind , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Above
origin[1] = 515;
mitk::FillVector3D(normal, 0, 1, 0);
mitk::PlaneGeometry::Pointer planeAbove = mitk::PlaneGeometry::New();
planeAbove->InitializePlane(origin, normal);
calculator->SetInput( planeAbove , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Below
origin[1] = -5;
mitk::PlaneGeometry::Pointer planeBelow = mitk::PlaneGeometry::New();
planeBelow->InitializePlane(origin, normal);
calculator->SetInput( planeBelow , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Left side
origin[0] = -5;
mitk::FillVector3D(normal, 1, 0, 0);
mitk::PlaneGeometry::Pointer planeLeftSide = mitk::PlaneGeometry::New();
planeLeftSide->InitializePlane(origin, normal);
calculator->SetInput( planeLeftSide , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Right side
origin[1] = 515;
mitk::PlaneGeometry::Pointer planeRightSide = mitk::PlaneGeometry::New();
planeRightSide->InitializePlane(origin, normal);
calculator->SetInput( planeRightSide , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
delete calculator;
}
static void CheckIntersectionPointsOfTwoGeometry3D(mitk::BaseGeometry::Pointer firstGeometry3D, mitk::BaseGeometry::Pointer secondGeometry3D)
{
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer firstImage = mitk::Image::New();
firstImage->Initialize( mitk::MakePixelType<int, int, 1>(), *(firstGeometry3D.GetPointer()) );
calculator->SetInput( secondGeometry3D, firstImage);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
+ delete calculator;
}
static void CheckIntersectionWithPointCloud( mitk::BaseGeometry::Pointer geometry3D )
{
//Check planes which are inside the bounding box
mitk::Image::Pointer image = mitk::Image::New();
image->Initialize( mitk::MakePixelType<int, int, 1>(), *(geometry3D.GetPointer()) );
{
mitk::Point3D pnt1, pnt2;
pnt1[0] = 3;
pnt1[1] = 5;
pnt1[2] = 3;
pnt2[0] = 8;
pnt2[1] = 3;
pnt2[2] = 8;
mitk::ClippedSurfaceBoundsCalculator::PointListType pointlist;
pointlist.push_back( pnt1 );
pointlist.push_back( pnt2 );
mitk::ClippedSurfaceBoundsCalculator calculator;
calculator.SetInput( pointlist, image );
calculator.Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxZ = calculator.GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMaxZ.first == 3 && minMaxZ.second == 8, "Check if points span from slice 3 to slice 8 in axial");
mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxX = calculator.GetMinMaxSpatialDirectionX();
MITK_TEST_CONDITION(minMaxX.first == 3 && minMaxX.second == 5, "Check if points span from slice 3 to slice 5 in sagittal");
}
{
mitk::Point3D pnt1, pnt2;
pnt1.Fill( -3 );
pnt2.Fill( 600 );
mitk::ClippedSurfaceBoundsCalculator::PointListType pointlist;
pointlist.push_back( pnt1 );
pointlist.push_back( pnt2 );
mitk::ClippedSurfaceBoundsCalculator calculator;
calculator.SetInput( pointlist, image );
calculator.Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxZ = calculator.GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMaxZ.first == 0 && minMaxZ.second == 19, "Check if points are correctly clipped to slice 0 and slice 19 in axial");
mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxX = calculator.GetMinMaxSpatialDirectionX();
MITK_TEST_CONDITION(minMaxX.first == 0 && minMaxX.second == 511, "Check if points are correctly clipped to slice 0 and slice 511 in sagittal");
}
}
int mitkClippedSurfaceBoundsCalculatorTest(int, char* [])
{
// always start with this!
MITK_TEST_BEGIN("ClippedSurfaceBoundsCalculator");
/** The class mitkClippedSurfaceBoundsCalculator calculates the intersection points of a PlaneGeometry and a Geometry3D.
* This unittest checks if the correct min and max values for the three spatial directions (x, y, z)
* are calculated. To test this we define artifical PlaneGeometries and Geometry3Ds and test different
* scenarios:
*
* 1. planes which are inside the bounding box of a 3D geometry but only on one slice
* 2. planes which are outside of the bounding box
* 3. planes which are inside the bounding box but over more than one slice
*
* Note: Currently rotated geometries are not tested!
*/
/********************* Define Geometry3D ***********************/
//Define origin:
mitk::Point3D origin;
origin[0] = 511;
origin[1] = 0;
origin[2] = 0;
//Define normal:
mitk::Vector3D normal;
mitk::FillVector3D(normal, 0, 0, 1);
//Initialize PlaneGeometry:
mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
planeGeometry->InitializePlane(origin, normal);
//Set Bounds:
mitk::BoundingBox::BoundsArrayType bounds = planeGeometry->GetBounds();
bounds[0] = 0;
bounds[1] = 512;
bounds[2] = 0;
bounds[3] = 512;
bounds[4] = 0;
bounds[5] = 1;
planeGeometry->SetBounds(bounds);
//Initialize SlicedGeometry3D:
mitk::SlicedGeometry3D::Pointer slicedGeometry3D = mitk::SlicedGeometry3D::New();
slicedGeometry3D->InitializeEvenlySpaced(dynamic_cast<mitk::PlaneGeometry*>(planeGeometry.GetPointer()), 20);
mitk::BaseGeometry::Pointer geometry3D = dynamic_cast< mitk::BaseGeometry* > ( slicedGeometry3D.GetPointer() );
geometry3D->SetImageGeometry(true);
//Define origin for second Geometry3D;
mitk::Point3D origin2;
origin2[0] = 511;
origin2[1] = 60;
origin2[2] = 0;
//Define normal:
mitk::Vector3D normal2;
mitk::FillVector3D(normal2, 0, 1, 0);
//Initialize PlaneGeometry:
mitk::PlaneGeometry::Pointer planeGeometry2 = mitk::PlaneGeometry::New();
planeGeometry2->InitializePlane(origin2, normal2);
//Initialize SlicedGeometry3D:
mitk::SlicedGeometry3D::Pointer secondSlicedGeometry3D = mitk::SlicedGeometry3D::New();
secondSlicedGeometry3D->InitializeEvenlySpaced(dynamic_cast<mitk::PlaneGeometry*>(planeGeometry2.GetPointer()), 20);
mitk::BaseGeometry::Pointer secondGeometry3D = dynamic_cast< mitk::BaseGeometry* > ( secondSlicedGeometry3D.GetPointer() );
secondGeometry3D->SetImageGeometry(true);
/***************************************************************/
CheckPlanesInsideBoundingBoxOnlyOnOneSlice(geometry3D);
CheckPlanesOutsideOfBoundingBox(geometry3D);
CheckPlanesInsideBoundingBox(geometry3D);
CheckIntersectionPointsOfTwoGeometry3D(geometry3D, secondGeometry3D);
CheckIntersectionWithPointCloud( geometry3D );
/** ToDo:
* test also rotated 3D geometry!
*/
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkExtractSliceFilterTest.cpp b/Core/Code/Testing/mitkExtractSliceFilterTest.cpp
index 7a70c208dc..2d41170e8e 100644
--- a/Core/Code/Testing/mitkExtractSliceFilterTest.cpp
+++ b/Core/Code/Testing/mitkExtractSliceFilterTest.cpp
@@ -1,1169 +1,1169 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkExtractSliceFilter.h>
#include <mitkTestingMacros.h>
#include <mitkItkImageFileReader.h>
#include <itkImageRegionIterator.h>
#include <mitkImageCast.h>
#include <itkImage.h>
#include <mitkImageAccessByItk.h>
#include <mitkStandardFileLocations.h>
#include <mitkImageWriter.h>
#include <mitkITKImageImport.h>
#include <mitkImagePixelReadAccessor.h>
#include <mitkRotationOperation.h>
#include <mitkInteractionConst.h>
#include <mitkNumericTypes.h>
#include <ctime>
#include <cstdlib>
#include <math.h>
#include <mitkGeometry3D.h>
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageMapper.h>
#include <vtkImageReslice.h>
#include <vtkImageActor.h>
#include <vtkImageMapToColors.h>
#include <vtkLookupTable.h>
#include <vtkTexture.h>
#include <vtkPolyDataMapper.h>
#include <vtkPlaneSource.h>
//use this to create the test volume on the fly
#define CREATE_VOLUME
//use this to save the created volume
//#define SAVE_VOLUME
//use this to calculate the error from the sphere mathematical model to our pixel based one
//#define CALC_TESTFAILURE_DEVIATION
//use this to render an oblique slice through a specified image
//#define SHOW_SLICE_IN_RENDER_WINDOW
//use this to have infos printed in mbilog
//#define EXTRACTOR_DEBUG
/*these are the deviations calculated by the function CalcTestFailureDeviation (see for details)*/
#define Testfailure_Deviation_Mean_128 0.853842
#define Testfailure_Deviation_Volume_128 0.145184
#define Testfailure_Deviation_Diameter_128 1.5625
#define Testfailure_Deviation_Mean_256 0.397693
#define Testfailure_Deviation_Volume_256 0.0141357
#define Testfailure_Deviation_Diameter_256 0.78125
#define Testfailure_Deviation_Mean_512 0.205277
#define Testfailure_Deviation_Volume_512 0.01993
#define Testfailure_Deviation_Diameter_512 0.390625
class mitkExtractSliceFilterTestClass{
public:
static void TestSlice(mitk::PlaneGeometry* planeGeometry, std::string testname)
{
TestPlane = planeGeometry;
TestName = testname;
mitk::ScalarType centerCoordValue = TestvolumeSize / 2.0;
mitk::ScalarType center[3] = {centerCoordValue, centerCoordValue, centerCoordValue};
mitk::Point3D centerIndex(center);
double radius = TestvolumeSize / 4.0;
if(TestPlane->Distance(centerIndex) >= radius ) return;//outside sphere
//feed ExtractSliceFilter
mitk::ExtractSliceFilter::Pointer slicer = mitk::ExtractSliceFilter::New();
slicer->SetInput(TestVolume);
slicer->SetWorldGeometry(TestPlane);
slicer->Update();
MITK_TEST_CONDITION_REQUIRED(slicer->GetOutput() != NULL, "Extractor returned a slice");
mitk::Image::Pointer reslicedImage = slicer->GetOutput();
AccessFixedDimensionByItk(reslicedImage, TestSphereRadiusByItk, 2);
AccessFixedDimensionByItk(reslicedImage, TestSphereAreaByItk, 2);
/*
double devArea, devDiameter;
if(TestvolumeSize == 128.0){ devArea = Testfailure_Deviation_Volume_128; devDiameter = Testfailure_Deviation_Diameter_128; }
else if(TestvolumeSize == 256.0){devArea = Testfailure_Deviation_Volume_256; devDiameter = Testfailure_Deviation_Diameter_256;}
else if (TestvolumeSize == 512.0){devArea = Testfailure_Deviation_Volume_512; devDiameter = Testfailure_Deviation_Diameter_512;}
else{devArea = Testfailure_Deviation_Volume_128; devDiameter = Testfailure_Deviation_Diameter_128;}
*/
std::string areatestName = TestName.append(" area");
std::string diametertestName = TestName.append(" testing diameter");
//TODO think about the deviation, 1% makes no sense at all
MITK_TEST_CONDITION(std::abs(100 - testResults.percentageAreaCalcToPixel) < 1, areatestName );
MITK_TEST_CONDITION(std::abs(100 - testResults.percentageRadiusToPixel) < 1, diametertestName );
#ifdef EXTRACTOR_DEBUG
MITK_INFO << TestName << " >>> " << "planeDistanceToSphereCenter: " << testResults.planeDistanceToSphereCenter;
MITK_INFO << "area in pixels: " << testResults.areaInPixel << " <-> area in mm: " << testResults.areaCalculated << " = " << testResults.percentageAreaCalcToPixel << "%";
MITK_INFO << "calculated diameter: " << testResults.diameterCalculated << " <-> diameter in mm: " << testResults.diameterInMM << " <-> diameter in pixel: " << testResults.diameterInPixel << " = " << testResults.percentageRadiusToPixel << "%";
#endif
}
/*
* get the radius of the slice of a sphere based on pixel distance from edge to edge of the circle.
*/
template<typename TPixel, unsigned int VImageDimension>
static void TestSphereRadiusByItk (itk::Image<TPixel, VImageDimension>* inputImage)
{
typedef itk::Image<TPixel, VImageDimension> InputImageType;
//set the index to the middle of the image's edge at x and y axis
typename InputImageType::IndexType currentIndexX;
currentIndexX[0] = (int)(TestvolumeSize / 2.0);
currentIndexX[1] = 0;
typename InputImageType::IndexType currentIndexY;
currentIndexY[0] = 0;
currentIndexY[1] = (int)(TestvolumeSize / 2.0);
//remember the last pixel value
double lastValueX = inputImage->GetPixel(currentIndexX);
double lastValueY = inputImage->GetPixel(currentIndexY);
//storage for the index marks
std::vector<typename InputImageType::IndexType> indicesX;
std::vector<typename InputImageType::IndexType> indicesY;
/*Get four indices on the edge of the circle*/
while(currentIndexX[1] < TestvolumeSize && currentIndexX[0] < TestvolumeSize)
{
//move x direction
currentIndexX[1] += 1;
//move y direction
currentIndexY[0] += 1;
if(inputImage->GetPixel(currentIndexX) > lastValueX)
{
//mark the current index
typename InputImageType::IndexType markIndex;
markIndex[0] = currentIndexX[0];
markIndex[1] = currentIndexX[1];
indicesX.push_back(markIndex);
}
else if( inputImage->GetPixel(currentIndexX) < lastValueX)
{
//mark the current index
typename InputImageType::IndexType markIndex;
markIndex[0] = currentIndexX[0];
markIndex[1] = currentIndexX[1] - 1;//value inside the sphere
indicesX.push_back(markIndex);
}
if(inputImage->GetPixel(currentIndexY) > lastValueY)
{
//mark the current index
typename InputImageType::IndexType markIndex;
markIndex[0] = currentIndexY[0];
markIndex[1] = currentIndexY[1];
indicesY.push_back(markIndex);
}
else if( inputImage->GetPixel(currentIndexY) < lastValueY)
{
//mark the current index
typename InputImageType::IndexType markIndex;
markIndex[0] = currentIndexY[0];
markIndex[1] = currentIndexY[1] - 1;//value inside the sphere
indicesY.push_back(markIndex);
}
//found both marks?
if(indicesX.size() == 2 && indicesY.size() == 2) break;
//the new 'last' values
lastValueX = inputImage->GetPixel(currentIndexX);
lastValueY = inputImage->GetPixel(currentIndexY);
}
/*
*If we are here we found the four marks on the edge of the circle.
*For the case our plane is rotated and shifted, we have to calculate the center of the circle,
*else the center is the intersection of both straight lines between the marks.
*When we have the center, the diameter of the circle will be checked to the reference value(math!).
*/
//each distance from the first mark of each direction to the center of the straight line between the marks
double distanceToCenterX = std::abs(indicesX[0][1] - indicesX[1][1]) / 2.0;
//double distanceToCenterY = std::abs(indicesY[0][0] - indicesY[1][0]) / 2.0;
//the center of the straight lines
typename InputImageType::IndexType centerX;
//typename InputImageType::IndexType centerY;
centerX[0] = indicesX[0][0];
centerX[1] = indicesX[0][1] + distanceToCenterX;
//TODO think about implicit cast to int. this is not the real center of the image, which could be between two pixels
//centerY[0] = indicesY[0][0] + distanceToCenterY;
//centerY[1] = inidcesY[0][1];
typename InputImageType::IndexType currentIndex(centerX);
lastValueX = inputImage->GetPixel(currentIndex);
long sumpixels = 0;
std::vector<typename InputImageType::IndexType> diameterIndices;
//move up
while(currentIndex[1] < TestvolumeSize)
{
currentIndex[1] += 1;
if( inputImage->GetPixel(currentIndex) != lastValueX)
{
typename InputImageType::IndexType markIndex;
markIndex[0] = currentIndex[0];
markIndex[1] = currentIndex[1] - 1;
diameterIndices.push_back(markIndex);
break;
}
sumpixels++;
lastValueX = inputImage->GetPixel(currentIndex);
}
currentIndex[1] -= sumpixels; //move back to center to go in the other direction
lastValueX = inputImage->GetPixel(currentIndex);
//move down
while(currentIndex[1] >= 0)
{
currentIndex[1] -= 1;
if( inputImage->GetPixel(currentIndex) != lastValueX)
{
typename InputImageType::IndexType markIndex;
markIndex[0] = currentIndex[0];
markIndex[1] = currentIndex[1];//outside sphere because we want to calculate the distance from edge to edge
diameterIndices.push_back(markIndex);
break;
}
sumpixels++;
lastValueX = inputImage->GetPixel(currentIndex);
}
/*
*Now sumpixels should be the apromximate diameter of the circle. This is checked with the calculated diameter from the plane transformation(math).
*/
mitk::Point3D volumeCenter;
volumeCenter[0] = volumeCenter[1] = volumeCenter[2] = TestvolumeSize / 2.0;
double planeDistanceToSphereCenter = TestPlane->Distance(volumeCenter);
double sphereRadius = TestvolumeSize/4.0;
//calculate the radius of the circle cut from the sphere by the plane
double diameter = 2.0 * std::sqrt(std::pow(sphereRadius, 2) - std::pow( planeDistanceToSphereCenter , 2));
double percentageRadiusToPixel = 100 / diameter * sumpixels;
/*
*calculate the radius in mm by the both marks of the center line by using the world coordinates
*/
//get the points as 3D coordinates
mitk::Vector3D diameterPointRight, diameterPointLeft;
diameterPointRight[2] = diameterPointLeft[2] = 0.0;
diameterPointLeft[0] = diameterIndices[0][0];
diameterPointLeft[1] = diameterIndices[0][1];
diameterPointRight[0] = diameterIndices[1][0];
diameterPointRight[1] = diameterIndices[1][1];
//transform to worldcoordinates
TestVolume->GetGeometry()->IndexToWorld(diameterPointLeft, diameterPointLeft);
TestVolume->GetGeometry()->IndexToWorld(diameterPointRight, diameterPointRight);
//euklidian distance
double diameterInMM = ( (diameterPointLeft * -1.0) + diameterPointRight).GetNorm();
testResults.diameterInMM = diameterInMM;
testResults.diameterCalculated = diameter;
testResults.diameterInPixel = sumpixels;
testResults.percentageRadiusToPixel = percentageRadiusToPixel;
testResults.planeDistanceToSphereCenter = planeDistanceToSphereCenter;
}
/*brute force the area pixel by pixel*/
template<typename TPixel, unsigned int VImageDimension>
static void TestSphereAreaByItk (itk::Image<TPixel, VImageDimension>* inputImage)
{
typedef itk::Image<TPixel, VImageDimension> InputImageType;
typedef itk::ImageRegionConstIterator< InputImageType > ImageIterator;
ImageIterator imageIterator( inputImage, inputImage->GetLargestPossibleRegion() );
imageIterator.GoToBegin();
int sumPixelsInArea = 0;
while( !imageIterator.IsAtEnd() )
{
if(inputImage->GetPixel(imageIterator.GetIndex()) == pixelValueSet) sumPixelsInArea++;
++imageIterator;
}
mitk::Point3D volumeCenter;
volumeCenter[0] = volumeCenter[1] = volumeCenter[2] = TestvolumeSize / 2.0;
double planeDistanceToSphereCenter = TestPlane->Distance(volumeCenter);
double sphereRadius = TestvolumeSize/4.0;
//calculate the radius of the circle cut from the sphere by the plane
double radius = std::sqrt(std::pow(sphereRadius, 2) - std::pow( planeDistanceToSphereCenter , 2));
double areaInMM = 3.14159265358979 * std::pow(radius, 2);
testResults.areaCalculated = areaInMM;
testResults.areaInPixel = sumPixelsInArea;
testResults.percentageAreaCalcToPixel = 100 / areaInMM * sumPixelsInArea;
}
/*
* random a voxel. define plane through this voxel. reslice at the plane. compare the pixel vaues of the voxel
* in the volume with the pixel value in the resliced image.
* there are some indice shifting problems which causes the test to fail for oblique planes. seems like the chosen
* worldcoordinate is not corrresponding to the index in the 2D image. and so the pixel values are not the same as
* expected.
*/
static void PixelvalueBasedTest()
{
/* setup itk image */
typedef itk::Image<unsigned short, 3> ImageType;
typedef itk::ImageRegionConstIterator< ImageType > ImageIterator;
ImageType::Pointer image = ImageType::New();
ImageType::IndexType start;
start[0] = start[1] = start[2] = 0;
ImageType::SizeType size;
size[0] = size[1] = size[2] = 32;
ImageType::RegionType imgRegion;
imgRegion.SetSize(size);
imgRegion.SetIndex(start);
image->SetRegions(imgRegion);
image->SetSpacing(1.0);
image->Allocate();
ImageIterator imageIterator( image, image->GetLargestPossibleRegion() );
imageIterator.GoToBegin();
unsigned short pixelValue = 0;
//fill the image with distinct values
while ( !imageIterator.IsAtEnd() )
{
image->SetPixel(imageIterator.GetIndex(), pixelValue);
++imageIterator;
++pixelValue;
}
/* end setup itk image */
mitk::Image::Pointer imageInMitk;
CastToMitkImage(image, imageInMitk);
/*mitk::ImageWriter::Pointer writer = mitk::ImageWriter::New();
writer->SetInput(imageInMitk);
std::string file = "C:\\Users\\schroedt\\Desktop\\cube.nrrd";
writer->SetFileName(file);
writer->Update();*/
PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Frontal);
PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Sagittal);
PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Axial);
}
static void PixelvalueBasedTestByPlane(mitk::Image* imageInMitk, mitk::PlaneGeometry::PlaneOrientation orientation){
typedef itk::Image<unsigned short, 3> ImageType;
//set the seed of the rand function
srand((unsigned)time(0));
/* setup a random orthogonal plane */
int sliceindex = 17;//rand() % 32;
bool isFrontside = true;
bool isRotated = false;
if( orientation == mitk::PlaneGeometry::Axial)
{
/*isFrontside = false;
isRotated = true;*/
}
mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
plane->InitializeStandardPlane(imageInMitk->GetGeometry(), orientation, sliceindex, isFrontside, isRotated);
mitk::Point3D origin = plane->GetOrigin();
mitk::Vector3D normal;
normal = plane->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
plane->SetOrigin(origin);
//we dont need this any more, because we are only testing orthogonal planes
/*mitk::Vector3D rotationVector;
rotationVector[0] = randFloat();
rotationVector[1] = randFloat();
rotationVector[2] = randFloat();
float degree = randFloat() * 180.0;
mitk::RotationOperation* op = new mitk::RotationOperation(mitk::OpROTATE, plane->GetCenter(), rotationVector, degree);
plane->ExecuteOperation(op);
delete op;*/
/* end setup plane */
/* define a point in the 3D volume.
* add the two axis vectors of the plane (each multiplied with a
* random number) to the origin. now the two random numbers
* become our index coordinates in the 2D image, because the
* length of the axis vectors is 1.
*/
mitk::Point3D planeOrigin = plane->GetOrigin();
mitk::Vector3D axis0, axis1;
axis0 = plane->GetAxisVector(0);
axis1 = plane->GetAxisVector(1);
axis0.Normalize();
axis1.Normalize();
unsigned char n1 = 7;// rand() % 32;
unsigned char n2 = 13;// rand() % 32;
mitk::Point3D testPoint3DInWorld;
testPoint3DInWorld = planeOrigin + (axis0 * n1) + (axis1 * n2);
//get the index of the point in the 3D volume
ImageType::IndexType testPoint3DInIndex;
imageInMitk->GetGeometry()->WorldToIndex(testPoint3DInWorld, testPoint3DInIndex);
itk::Index<3> testPoint2DInIndex;
/* end define a point in the 3D volume.*/
//do reslicing at the plane
mitk::ExtractSliceFilter::Pointer slicer = mitk::ExtractSliceFilter::New();
slicer->SetInput(imageInMitk);
slicer->SetWorldGeometry(plane);
slicer->Update();
mitk::Image::Pointer slice = slicer->GetOutput();
// Get TestPoiont3D as Index in Slice
slice->GetGeometry()->WorldToIndex(testPoint3DInWorld,testPoint2DInIndex);
mitk::Point3D p, sliceIndexToWorld, imageIndexToWorld;
p[0] = testPoint2DInIndex[0];
p[1] = testPoint2DInIndex[1];
p[2] = testPoint2DInIndex[2];
slice->GetGeometry()->IndexToWorld(p, sliceIndexToWorld);
p[0] = testPoint3DInIndex[0];
p[1] = testPoint3DInIndex[1];
p[2] = testPoint3DInIndex[2];
imageInMitk->GetGeometry()->IndexToWorld(p, imageIndexToWorld);
itk::Index<2> testPoint2DIn2DIndex;
testPoint2DIn2DIndex[0] = testPoint2DInIndex[0];
testPoint2DIn2DIndex[1] = testPoint2DInIndex[1];
typedef mitk::ImagePixelReadAccessor< unsigned short, 3 > VolumeReadAccessorType;
typedef mitk::ImagePixelReadAccessor< unsigned short, 2 > SliceReadAccessorType;
VolumeReadAccessorType VolumeReadAccessor( imageInMitk );
SliceReadAccessorType SliceReadAccessor( slice );
//compare the pixelvalues of the defined point in the 3D volume with the value of the resliced image
unsigned short valueAt3DVolume = VolumeReadAccessor.GetPixelByIndex( testPoint3DInIndex );
unsigned short valueAtSlice = SliceReadAccessor.GetPixelByIndex( testPoint2DIn2DIndex );
//valueAt3DVolume == valueAtSlice is not always working. because of rounding errors
//indices are shifted
MITK_TEST_CONDITION(valueAt3DVolume == valueAtSlice, "comparing pixelvalues for orthogonal plane");
vtkSmartPointer<vtkImageData> imageInVtk = vtkSmartPointer<vtkImageData>::New();
imageInVtk = imageInMitk->GetVtkImageData();
vtkSmartPointer<vtkImageData> sliceInVtk = vtkSmartPointer<vtkImageData>::New();
sliceInVtk = slice->GetVtkImageData();
double PixelvalueByMitkOutput = sliceInVtk->GetScalarComponentAsDouble(n1, n2, 0, 0);
//double valueVTKinImage = imageInVtk->GetScalarComponentAsDouble(testPoint3DInIndex[0], testPoint3DInIndex[1], testPoint3DInIndex[2], 0);
/* Test that everything is working equally if vtkoutput is used instead of the default output
* from mitk ImageToImageFilter
*/
mitk::ExtractSliceFilter::Pointer slicerWithVtkOutput = mitk::ExtractSliceFilter::New();
slicerWithVtkOutput->SetInput(imageInMitk);
slicerWithVtkOutput->SetWorldGeometry(plane);
slicerWithVtkOutput->SetVtkOutputRequest(true);
slicerWithVtkOutput->Update();
vtkSmartPointer<vtkImageData> vtkImageByVtkOutput = vtkSmartPointer<vtkImageData>::New();
vtkImageByVtkOutput = slicerWithVtkOutput->GetVtkOutput();
double PixelvalueByVtkOutput = vtkImageByVtkOutput->GetScalarComponentAsDouble(n1, n2, 0, 0);
MITK_TEST_CONDITION(PixelvalueByMitkOutput == PixelvalueByVtkOutput, "testing convertion of image output vtk->mitk by reslicer");
/*================ mbilog outputs ===========================*/
#ifdef EXTRACTOR_DEBUG
MITK_INFO << "\n" << "TESTINFO index: " << sliceindex << " orientation: " << orientation << " frontside: " << isFrontside << " rotated: " << isRotated;
MITK_INFO << "\n" << "slice index to world: " << sliceIndexToWorld;
MITK_INFO << "\n" << "image index to world: " << imageIndexToWorld;
MITK_INFO << "\n" << "vtk: slice: " << PixelvalueByMitkOutput << ", image: "<< valueVTKinImage;
MITK_INFO << "\n" << "testPoint3D InWorld" << testPoint3DInWorld << " is " << testPoint2DInIndex << " in 2D";
MITK_INFO << "\n" << "randoms: " << ((int)n1) << ", " << ((int)n2);
MITK_INFO << "\n" << "point is inside plane: " << plane->IsInside(testPoint3DInWorld) << " and volume: " << imageInMitk->GetGeometry()->IsInside(testPoint3DInWorld);
MITK_INFO << "\n" << "volume idx: " << testPoint3DInIndex << " = " << valueAt3DVolume ;
MITK_INFO << "\n" << "volume world: " << testPoint3DInWorld << " = " << valueAt3DVolumeByWorld ;
MITK_INFO << "\n" << "slice idx: " << testPoint2DInIndex << " = " << valueAtSlice ;
itk::Index<3> curr;
curr[0] = curr[1] = curr[2] = 0;
for( int i = 0; i < 32 ; ++i){
for( int j = 0; j < 32; ++j){
++curr[1];
if(SliceReadAccessor.GetPixelByIndex( curr ) == valueAt3DVolume){
MITK_INFO << "\n" << valueAt3DVolume << " MATCHED mitk " << curr;
}
}
curr[1] = 0;
++curr[0];
}
typedef itk::Image<unsigned short, 2> Image2DType;
Image2DType::Pointer img = Image2DType::New();
CastToItkImage(slice, img);
typedef itk::ImageRegionConstIterator< Image2DType > Iterator2D;
Iterator2D iter(img, img->GetLargestPossibleRegion());
iter.GoToBegin();
while( !iter.IsAtEnd() ){
if(img->GetPixel(iter.GetIndex()) == valueAt3DVolume) MITK_INFO << "\n" << valueAt3DVolume << " MATCHED itk " << iter.GetIndex();
++iter;
}
#endif //EXTRACTOR_DEBUG
}
/* random a float value */
static float randFloat(){ return (((float)rand()+1.0) / ((float)RAND_MAX + 1.0)) + (((float)rand()+1.0) / ((float)RAND_MAX + 1.0)) / ((float)RAND_MAX + 1.0);}
/* create a sphere with the size of the given testVolumeSize*/
static void InitializeTestVolume()
{
#ifdef CREATE_VOLUME
//do sphere creation
ItkVolumeGeneration();
#ifdef SAVE_VOLUME
//save in file
mitk::ImageWriter::Pointer writer = mitk::ImageWriter::New();
writer->SetInput(TestVolume);
std::string file;
std::ostringstream filename;
filename << "C:\\home\\schroedt\\MITK\\Modules\\ImageExtraction\\Testing\\Data\\sphere_";
filename << TestvolumeSize;
filename << ".nrrd";
file = filename.str();
writer->SetFileName(file);
writer->Update();
#endif//SAVE_VOLUME
#endif
#ifndef CREATE_VOLUME //read from file
mitk::StandardFileLocations::Pointer locator = mitk::StandardFileLocations::GetInstance();
std::string filename = locator->FindFile("sphere_512.nrrd.mhd", "Modules/ImageExtraction/Testing/Data");
mitk::ItkImageFileReader::Pointer reader = mitk::ItkImageFileReader::New();
reader->SetFileName(filename);
reader->Update();
TestVolume = reader->GetOutput();
#endif
#ifdef CALC_TESTFAILURE_DEVIATION
//get the TestFailureDeviation in %
AccessFixedDimensionByItk(TestVolume, CalcTestFailureDeviation, 3);
#endif
}
//the test result of the sphere reslice
struct SliceProperties{
double planeDistanceToSphereCenter;
double diameterInMM;
double diameterInPixel;
double diameterCalculated;
double percentageRadiusToPixel;
double areaCalculated;
double areaInPixel;
double percentageAreaCalcToPixel;
};
static mitk::Image::Pointer TestVolume;
static double TestvolumeSize;
static mitk::PlaneGeometry::Pointer TestPlane;
static std::string TestName;
static unsigned char pixelValueSet;
static SliceProperties testResults;
static double TestFailureDeviation;
private:
/*
* Generate a sphere with a radius of TestvolumeSize / 4.0
*/
static void ItkVolumeGeneration ()
{
typedef itk::Image<unsigned char, 3> TestVolumeType;
typedef itk::ImageRegionConstIterator< TestVolumeType > ImageIterator;
TestVolumeType::Pointer sphereImage = TestVolumeType::New();
TestVolumeType::IndexType start;
start[0] = start[1] = start[2] = 0;
TestVolumeType::SizeType size;
size[0] = size[1] = size[2] = TestvolumeSize;
TestVolumeType::RegionType imgRegion;
imgRegion.SetSize(size);
imgRegion.SetIndex(start);
sphereImage->SetRegions(imgRegion);
sphereImage->SetSpacing(1.0);
sphereImage->Allocate();
sphereImage->FillBuffer(0);
mitk::Vector3D center;
center[0] = center[1] = center[2] = TestvolumeSize / 2.0;
double radius = TestvolumeSize / 4.0;
double pixelValue = pixelValueSet;
double distanceToCenter = 0.0;
ImageIterator imageIterator( sphereImage, sphereImage->GetLargestPossibleRegion() );
imageIterator.GoToBegin();
mitk::Vector3D currentVoxelInIndex;
while ( !imageIterator.IsAtEnd() )
{
currentVoxelInIndex[0] = imageIterator.GetIndex()[0];
currentVoxelInIndex[1] = imageIterator.GetIndex()[1];
currentVoxelInIndex[2] = imageIterator.GetIndex()[2];
distanceToCenter = (center + ( currentVoxelInIndex * -1.0 )).GetNorm();
//if distance to center is smaller then the radius of the sphere
if( distanceToCenter < radius)
{
sphereImage->SetPixel(imageIterator.GetIndex(), pixelValue);
}
++imageIterator;
}
CastToMitkImage(sphereImage, TestVolume);
}
/* calculate the devation of the voxel object to the mathematical sphere object.
* this is use to make a statement about the accuracy of the resliced image, eg. the circle's diameter or area.
*/
template<typename TPixel, unsigned int VImageDimension>
static void CalcTestFailureDeviation (itk::Image<TPixel, VImageDimension>* inputImage)
{
typedef itk::Image<TPixel, VImageDimension> InputImageType;
typedef itk::ImageRegionConstIterator< InputImageType > ImageIterator;
ImageIterator iterator(inputImage, inputImage->GetLargestPossibleRegion());
iterator.GoToBegin();
int volumeInPixel = 0;
while( !iterator.IsAtEnd() )
{
if(inputImage->GetPixel(iterator.GetIndex()) == pixelValueSet) volumeInPixel++;
++iterator;
}
double diameter = TestvolumeSize / 2.0;
double volumeCalculated = (1.0 / 6.0) * 3.14159265358979 * std::pow(diameter, 3);
double volumeDeviation = std::abs( 100 - (100 / volumeCalculated * volumeInPixel) );
typename InputImageType::IndexType index;
index[0] = index[1] = TestvolumeSize / 2.0;
index[2] = 0;
int sumpixels = 0;
while (index[2] < TestvolumeSize )
{
if(inputImage->GetPixel(index) == pixelValueSet) sumpixels++;
index[2] += 1;
}
double diameterDeviation = std::abs( 100 - (100 / diameter * sumpixels) );
#ifdef DEBUG
MITK_INFO << "volume deviation: " << volumeDeviation << " diameter deviation:" << diameterDeviation;
#endif
mitkExtractSliceFilterTestClass::TestFailureDeviation = (volumeDeviation + diameterDeviation) / 2.0;
}
};
/*================ #END class ================*/
/*================#BEGIN Instanciation of members ================*/
mitk::Image::Pointer mitkExtractSliceFilterTestClass::TestVolume = mitk::Image::New();
double mitkExtractSliceFilterTestClass::TestvolumeSize = 256.0;
mitk::PlaneGeometry::Pointer mitkExtractSliceFilterTestClass::TestPlane = mitk::PlaneGeometry::New();
std::string mitkExtractSliceFilterTestClass::TestName = "";
unsigned char mitkExtractSliceFilterTestClass::pixelValueSet = 255;
mitkExtractSliceFilterTestClass::SliceProperties mitkExtractSliceFilterTestClass::testResults = {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0};
double mitkExtractSliceFilterTestClass::TestFailureDeviation = 0.0;
/*================ #END Instanciation of members ================*/
/*================ #BEGIN test main ================*/
-int mitkExtractSliceFilterTest(int argc, char* argv[])
+int mitkExtractSliceFilterTest(int , char* [])
{
MITK_TEST_BEGIN("mitkExtractSliceFilterTest")
//pixelvalue based testing
mitkExtractSliceFilterTestClass::PixelvalueBasedTest();
//initialize sphere test volume
mitkExtractSliceFilterTestClass::InitializeTestVolume();
mitk::Vector3D spacing = mitkExtractSliceFilterTestClass::TestVolume->GetGeometry()->GetSpacing();
//the center of the sphere = center of image
double sphereCenter = mitkExtractSliceFilterTestClass::TestvolumeSize / 2.0;
double planeSize = mitkExtractSliceFilterTestClass::TestvolumeSize;
/* axial plane */
mitk::PlaneGeometry::Pointer geometryAxial = mitk::PlaneGeometry::New();
geometryAxial->InitializeStandardPlane(planeSize, planeSize, spacing, mitk::PlaneGeometry::Axial, sphereCenter, false, true);
geometryAxial->ChangeImageGeometryConsideringOriginOffset(true);
mitk::Point3D origin = geometryAxial->GetOrigin();
mitk::Vector3D normal;
normal = geometryAxial->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
//geometryAxial->SetOrigin(origin);
mitkExtractSliceFilterTestClass::TestSlice(geometryAxial, "Testing axial plane");
/* end axial plane */
/* sagittal plane */
mitk::PlaneGeometry::Pointer geometrySagital = mitk::PlaneGeometry::New();
geometrySagital->InitializeStandardPlane(planeSize, planeSize, spacing, mitk::PlaneGeometry::Sagittal, sphereCenter, true, false);
geometrySagital->ChangeImageGeometryConsideringOriginOffset(true);
origin = geometrySagital->GetOrigin();
normal = geometrySagital->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
//geometrySagital->SetOrigin(origin);
mitkExtractSliceFilterTestClass::TestSlice(geometrySagital, "Testing sagittal plane");
/* sagittal plane */
/* sagittal shifted plane */
mitk::PlaneGeometry::Pointer geometrySagitalShifted = mitk::PlaneGeometry::New();
geometrySagitalShifted->InitializeStandardPlane(planeSize, planeSize, spacing, mitk::PlaneGeometry::Sagittal, (sphereCenter - 14), true, false);
geometrySagitalShifted->ChangeImageGeometryConsideringOriginOffset(true);
origin = geometrySagitalShifted->GetOrigin();
normal = geometrySagitalShifted->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
//geometrySagitalShifted->SetOrigin(origin);
mitkExtractSliceFilterTestClass::TestSlice(geometrySagitalShifted, "Testing sagittal plane shifted");
/* end sagittal shifted plane */
/* coronal plane */
mitk::PlaneGeometry::Pointer geometryCoronal = mitk::PlaneGeometry::New();
geometryCoronal->InitializeStandardPlane(planeSize, planeSize, spacing, mitk::PlaneGeometry::Frontal, sphereCenter, true, false);
geometryCoronal->ChangeImageGeometryConsideringOriginOffset(true);
origin = geometryCoronal->GetOrigin();
normal = geometryCoronal->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
//geometryCoronal->SetOrigin(origin);
mitkExtractSliceFilterTestClass::TestSlice(geometryCoronal, "Testing coronal plane");
/* end coronal plane */
/* oblique plane */
mitk::PlaneGeometry::Pointer obliquePlane = mitk::PlaneGeometry::New();
obliquePlane->InitializeStandardPlane(planeSize, planeSize, spacing, mitk::PlaneGeometry::Sagittal, sphereCenter, true, false);
obliquePlane->ChangeImageGeometryConsideringOriginOffset(true);
origin = obliquePlane->GetOrigin();
normal = obliquePlane->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
//obliquePlane->SetOrigin(origin);
mitk::Vector3D rotationVector;
rotationVector[0] = 0.2;
rotationVector[1] = 0.4;
rotationVector[2] = 0.62;
float degree = 37.0;
mitk::RotationOperation* op = new mitk::RotationOperation(mitk::OpROTATE, obliquePlane->GetCenter(), rotationVector, degree);
obliquePlane->ExecuteOperation(op);
delete op;
mitkExtractSliceFilterTestClass::TestSlice(obliquePlane, "Testing oblique plane");
/* end oblique plane */
#ifdef SHOW_SLICE_IN_RENDER_WINDOW
/*================ #BEGIN vtk render code ================*/
//set reslicer for renderwindow
mitk::ItkImageFileReader::Pointer reader = mitk::ItkImageFileReader::New();
std::string filename = "C:\\home\\Pics\\Pic3D.nrrd";
reader->SetFileName(filename);
reader->Update();
mitk::Image::Pointer pic = reader->GetOutput();
vtkSmartPointer<vtkImageReslice> slicer = vtkSmartPointer<vtkImageReslice>::New();
slicer->SetInput(pic->GetVtkImageData());
mitk::PlaneGeometry::Pointer obliquePl = mitk::PlaneGeometry::New();
obliquePl->InitializeStandardPlane(pic->GetGeometry(), mitk::PlaneGeometry::Sagittal, pic->GetGeometry()->GetCenter()[0], true, false);
obliquePl->ChangeImageGeometryConsideringOriginOffset(true);
mitk::Point3D origin2 = obliquePl->GetOrigin();
mitk::Vector3D n;
n = obliquePl->GetNormal();
n.Normalize();
origin2 += n * 0.5;//pixelspacing is 1, so half the spacing is 0.5
obliquePl->SetOrigin(origin2);
mitk::Vector3D rotation;
rotation[0] = 0.534307;
rotation[1] = 0.000439605;
rotation[2] = 0.423017;
MITK_INFO << rotation;
float rotateDegree = 70;
mitk::RotationOperation* operation = new mitk::RotationOperation(mitk::OpROTATE, obliquePl->GetCenter(), rotationVector, degree);
obliquePl->ExecuteOperation(operation);
delete operation;
double origin[3];
origin[0] = obliquePl->GetOrigin()[0];
origin[1] = obliquePl->GetOrigin()[1];
origin[2] = obliquePl->GetOrigin()[2];
slicer->SetResliceAxesOrigin(origin);
mitk::Vector3D right, bottom, normal;
right = obliquePl->GetAxisVector( 0 );
bottom = obliquePl->GetAxisVector( 1 );
normal = obliquePl->GetNormal();
right.Normalize();
bottom.Normalize();
normal.Normalize();
double cosines[9];
mitk::vnl2vtk(right.GetVnlVector(), cosines);//x
mitk::vnl2vtk(bottom.GetVnlVector(), cosines + 3);//y
mitk::vnl2vtk(normal.GetVnlVector(), cosines + 6);//n
slicer->SetResliceAxesDirectionCosines(cosines);
slicer->SetOutputDimensionality(2);
slicer->Update();
//set vtk renderwindow
vtkSmartPointer<vtkPlaneSource> vtkPlane = vtkSmartPointer<vtkPlaneSource>::New();
vtkPlane->SetOrigin(0.0, 0.0, 0.0);
//These two points define the axes of the plane in combination with the origin.
//Point 1 is the x-axis and point 2 the y-axis.
//Each plane is transformed according to the view (axial, coronal and saggital) afterwards.
vtkPlane->SetPoint1(1.0, 0.0, 0.0); //P1: (xMax, yMin, depth)
vtkPlane->SetPoint2(0.0, 1.0, 0.0); //P2: (xMin, yMax, depth)
//these are not the correct values for all slices, only a square plane by now
vtkSmartPointer<vtkPolyDataMapper> imageMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
imageMapper->SetInputConnection(vtkPlane->GetOutputPort());
vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
//built a default lookuptable
lookupTable->SetRampToLinear();
lookupTable->SetSaturationRange( 0.0, 0.0 );
lookupTable->SetHueRange( 0.0, 0.0 );
lookupTable->SetValueRange( 0.0, 1.0 );
lookupTable->Build();
//map all black values to transparent
lookupTable->SetTableValue(0, 0.0, 0.0, 0.0, 0.0);
lookupTable->SetRange(-255.0, 255.0);
//lookupTable->SetRange(-1022.0, 1184.0);//pic3D range
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
texture->SetInput(slicer->GetOutput());
texture->SetLookupTable(lookupTable);
texture->SetMapColorScalarsThroughLookupTable(true);
vtkSmartPointer<vtkActor> imageActor = vtkSmartPointer<vtkActor>::New();
imageActor->SetMapper(imageMapper);
imageActor->SetTexture(texture);
// Setup renderers
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(imageActor);
// Setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interaction
renderWindowInteractor->SetRenderWindow(renderWindow);
//renderer->AddViewProp(imageActor);
renderWindow->Render();
renderWindowInteractor->Start();
// always end with this!
/*================ #END vtk render code ================*/
#endif //SHOW_SLICE_IN_RENDER_WINDOW
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkFocusManagerTest.cpp b/Core/Code/Testing/mitkFocusManagerTest.cpp
index 1900f5446f..a2fe828de7 100644
--- a/Core/Code/Testing/mitkFocusManagerTest.cpp
+++ b/Core/Code/Testing/mitkFocusManagerTest.cpp
@@ -1,91 +1,94 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkFocusManager.h"
#include "mitkTestingMacros.h"
#include "mitkVtkPropRenderer.h"
#include "mitkGlobalInteraction.h"
int mitkFocusManagerTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("FocusManager");
// Global interaction must(!) be initialized if used
mitk::GlobalInteraction::GetInstance()->Initialize("global");
mitk::RenderingManager::Pointer rm = mitk::RenderingManager::GetInstance();
//building up necessary objects
vtkRenderWindow* renderWindow = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer element1 = mitk::VtkPropRenderer::New( "renderer1", renderWindow, rm );
mitk::VtkPropRenderer::Pointer element2 = mitk::VtkPropRenderer::New( "renderer2", renderWindow, rm );
mitk::VtkPropRenderer::Pointer element3 = mitk::VtkPropRenderer::New( "renderer3", renderWindow, rm );
+ element1->InitSize(100, 100);
+ element2->InitSize(100, 100);
+ element3->InitSize(100, 100);
//the FocusManager itself
mitk::FocusManager::Pointer focusManager = mitk::FocusManager::New();
//testing
MITK_TEST_CONDITION_REQUIRED(focusManager.IsNotNull(), "Testing Instatiation");
MITK_TEST_CONDITION_REQUIRED(element1.IsNotNull(), "Testing Instatiation of an element");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element is focused on");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing of an element");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == NULL, "Testing focused on an empty list");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element; Elements in list: 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element2), "Testing addition of a second element; Elements in list: 1 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element3), "Testing addition of a third element; Elements in list: 1 2 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element1), "Testing setting focused to element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "focus on element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element2), "Testing setting focused to element 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "focus on element 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element3), "Testing setting focused to element 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "focus on element 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing first element; Elements in list: 2 3");
- MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is the one behind the deleted one: 2");
+ MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "Testing if focused element is still element 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element again; Elements in list: 2 3 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element3), "Testing removing element 3; Elements in list: 2 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if focused element is the one behind the deleted one: 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing last element 1; Elements in list: 2 ");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is 2");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing same element");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element2), "Testing removing last element in list (2)");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element3), "Testing removing from empty list ");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element2), "Testing removing from empty list with different object");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing from empty list with different object again");
focusManager = NULL;
//TODO: test IsLast() IsFirst() GetFirst() GetLast() GoToNext() GetIter() SetLoop(bool loop)
//Delete renderWindo correctly
renderWindow->Delete();
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkImageDimensionConverterTest.cpp b/Core/Code/Testing/mitkImageDimensionConverterTest.cpp
index ff084a8523..fffd3015d7 100644
--- a/Core/Code/Testing/mitkImageDimensionConverterTest.cpp
+++ b/Core/Code/Testing/mitkImageDimensionConverterTest.cpp
@@ -1,292 +1,292 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// mitk includes
#include <mitkImage.h>
#include <mitkImageDataItem.h>
#include <mitkImageCast.h>
#include "mitkItkImageFileReader.h"
#include <mitkTestingMacros.h>
#include <mitkImageStatisticsHolder.h>
#include <mitkConvert2Dto3DImageFilter.h>
#include <mitkRotationOperation.h>
#include <mitkInteractionConst.h>
#include <mitkImageWriter.h>
#include <mitkPlaneOperation.h>
#include "mitkTestingConfig.h"
#include "mitkItkImageFileReader.h"
// itk includes
#include <itkImage.h>
#include <itkMersenneTwisterRandomVariateGenerator.h>
// stl includes
#include <fstream>
// vtk includes
#include <vtkImageData.h>
-int mitkImageDimensionConverterTest(int argc, char* argv[])
+int mitkImageDimensionConverterTest(int , char* [])
{
MITK_TEST_BEGIN(mitkImageDimensionConverterTest);
// Define an epsilon which is the allowed error
float eps = 0.00001;
// Define helper variables
float error = 0;
bool matrixIsEqual = true;
std::stringstream sstream;
mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New();
mitk::ItkImageFileReader::Pointer imageReader = mitk::ItkImageFileReader::New();
mitk::Convert2Dto3DImageFilter::Pointer convertFilter = mitk::Convert2Dto3DImageFilter::New();
///////////////////////////////////////
// Create 2D Image with a 3D rotation from scratch.
typedef itk::Image<double,2> ImageType;
ImageType::Pointer itkImage = ImageType::New();
ImageType::RegionType myRegion;
ImageType::SizeType mySize;
ImageType::IndexType myIndex;
ImageType::SpacingType mySpacing;
mySpacing[0] = 1;
mySpacing[1] = 1;
myIndex[0] = 0;
myIndex[1] = 0;
mySize[0] = 50;
mySize[1] = 50;
myRegion.SetSize( mySize);
myRegion.SetIndex( myIndex );
itkImage->SetSpacing(mySpacing);
itkImage->SetRegions( myRegion);
itkImage->Allocate();
itkImage->FillBuffer(50);
mitk::Image::Pointer mitkImage2D;
mitk::CastToMitkImage(itkImage,mitkImage2D);
// rotate
mitk::Point3D p;
p[0] = 1;
p[1] = 3;
p[2] = 5;
mitk::Vector3D v;
v[0] = 0.3;
v[1] = 1;
v[2] = 0.1;
mitk::RotationOperation op(mitk::OpROTATE, p, v, 35);
mitkImage2D->GetGeometry()->ExecuteOperation(&op);
// Save original Geometry infos
mitk::Vector3D Original_col0, Original_col1, Original_col2;
Original_col0.SetVnlVector(mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
Original_col1.SetVnlVector(mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
Original_col2.SetVnlVector(mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
MITK_INFO << "Rotated Matrix: " << Original_col0 << " " << Original_col1 << " " << Original_col2;
mitk::Point3D Original_Origin = mitkImage2D->GetGeometry()->GetOrigin();
mitk::Vector3D Original_Spacing = mitkImage2D->GetGeometry()->GetSpacing();
MITK_TEST_CONDITION_REQUIRED( mitkImage2D->GetDimension() == 2 , "Created Image is Dimension 2");
///////////////////////////////////////
// mitkImage2D is now a 2D image with 3D Geometry information.
// Save it without conversion and load it again. It should have an identitiy matrix
sstream.clear();
sstream << MITK_TEST_OUTPUT_DIR << "" << "/rotatedImage2D";
imageWriter->SetInput(mitkImage2D);
imageWriter->SetFileName(sstream.str().c_str());
imageWriter->SetExtension(".nrrd");
imageWriter->Write();
sstream << ".nrrd";
imageReader->SetFileName(sstream.str().c_str());
imageReader->Update();
mitk::Image::Pointer imageLoaded2D = imageReader->GetOutput();
// check if image can be loaded
MITK_TEST_CONDITION_REQUIRED( imageLoaded2D.IsNotNull() , "Loading saved 2D Image");
MITK_TEST_CONDITION_REQUIRED( imageLoaded2D->GetDimension() == 2 , "Loaded Image is Dimension 2");
// check if spacing is ok
mitk::Vector3D Loaded2D_Spacing = imageLoaded2D->GetGeometry()->GetSpacing();
error = abs(Loaded2D_Spacing[0] - Original_Spacing[0]) +
abs(Loaded2D_Spacing[1] - Original_Spacing[1]) +
abs(Loaded2D_Spacing[2] - 1) ;
MITK_TEST_CONDITION_REQUIRED( error < eps , "Compare Geometry: Spacing");
// Check origin
mitk::Point3D Loaded2D_Origin = imageLoaded2D->GetGeometry()->GetOrigin();
error = abs(Loaded2D_Origin[0] - Original_Origin[0]) +
abs(Loaded2D_Origin[1] - Original_Origin[1]) +
abs(Loaded2D_Origin[2] - 0) ;
MITK_TEST_CONDITION_REQUIRED( error < eps, "Compare Geometry: Origin");
// Check matrix
mitk::Vector3D Loaded2D_col0, Loaded2D_col1, Loaded2D_col2;
Loaded2D_col0.SetVnlVector(imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
Loaded2D_col1.SetVnlVector(imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
Loaded2D_col2.SetVnlVector(imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
if (
(abs(1 - Loaded2D_col0[0]) > eps) ||
(abs(0 - Loaded2D_col0[1]) > eps) ||
(abs(0 - Loaded2D_col0[2]) > eps) ||
(abs(0 - Loaded2D_col1[0]) > eps) ||
(abs(1 - Loaded2D_col1[1]) > eps) ||
(abs(0 - Loaded2D_col1[2]) > eps) ||
(abs(0 - Loaded2D_col2[0]) > eps) ||
(abs(0 - Loaded2D_col2[1]) > eps) ||
(abs(1 - Loaded2D_col2[2]) > eps) )
{
matrixIsEqual = false;
}
else
matrixIsEqual = true;
MITK_TEST_CONDITION_REQUIRED( matrixIsEqual , "Compare Geometry: Matrix");
///////////////////////////////////////
// mitkImage2D is a 2D image with 3D Geometry information.
// Convert it with filter to a 3D image and check if everything went well
convertFilter->SetInput(mitkImage2D);
convertFilter->Update();
mitk::Image::Pointer mitkImage3D = convertFilter->GetOutput();
MITK_TEST_CONDITION_REQUIRED( mitkImage3D->GetDimension() == 3 , "Converted Image is Dimension 3");
// check if geometry is still same
mitk::Vector3D Converted_Spacing = mitkImage3D->GetGeometry()->GetSpacing();
error = abs(Converted_Spacing[0] - Original_Spacing[0]) +
abs(Converted_Spacing[1] - Original_Spacing[1]) +
abs(Converted_Spacing[2] - Original_Spacing[2]) ;
MITK_TEST_CONDITION_REQUIRED( error < eps , "Compare Geometry: Spacing");
mitk::Point3D Converted_Origin = mitkImage3D->GetGeometry()->GetOrigin();
error = abs(Converted_Origin[0] - Original_Origin[0]) +
abs(Converted_Origin[1] - Original_Origin[1]) +
abs(Converted_Origin[2] - Original_Origin[2]) ;
MITK_INFO << Converted_Origin << " and " << Original_Origin;
MITK_TEST_CONDITION_REQUIRED( error < eps , "Compare Geometry: Origin");
mitk::Vector3D Converted_col0, Converted_col1, Converted_col2;
Converted_col0.SetVnlVector(mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
Converted_col1.SetVnlVector(mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
Converted_col2.SetVnlVector(mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
if (
(abs(Original_col0[0] - Converted_col0[0]) > eps) ||
(abs(Original_col0[1] - Converted_col0[1]) > eps) ||
(abs(Original_col0[2] - Converted_col0[2]) > eps) ||
(abs(Original_col1[0] - Converted_col1[0]) > eps) ||
(abs(Original_col1[1] - Converted_col1[1]) > eps) ||
(abs(Original_col1[2] - Converted_col1[2]) > eps) ||
(abs(Original_col2[0] - Converted_col2[0]) > eps) ||
(abs(Original_col2[1] - Converted_col2[1]) > eps) ||
(abs(Original_col2[2] - Converted_col2[2]) > eps) )
{
MITK_INFO << "Oh No! Original Image Matrix and Converted Image Matrix are different!";
MITK_INFO << "original Image:" << Original_col0 << " " << Original_col1 << " " << Original_col2;
MITK_INFO << "converted Image:" << Converted_col0 << " " << Converted_col1 << " " << Converted_col2;
matrixIsEqual = false;
}
else
matrixIsEqual = true;
MITK_TEST_CONDITION_REQUIRED( matrixIsEqual , "Compare Geometry: Matrix");
///////////////////////////////////////
// So far it seems good! now try to save and load the file
std::stringstream sstream2;
sstream2 << MITK_TEST_OUTPUT_DIR << "" << "/rotatedImage";
imageWriter->SetInput(mitkImage3D);
imageWriter->SetFileName(sstream2.str().c_str());
imageWriter->SetExtension(".nrrd");
imageWriter->Write();
sstream2 << ".nrrd";
imageReader->SetFileName(sstream2.str().c_str());
imageReader->Update();
mitk::Image::Pointer imageLoaded = imageReader->GetOutput();
// check if image can be loaded
MITK_TEST_CONDITION_REQUIRED( imageLoaded.IsNotNull() , "Loading saved Image");
// check if loaded image is still what it should be:
MITK_TEST_CONDITION_REQUIRED( imageLoaded->GetDimension() == 3 , "Loaded Image is Dimension 3");
// check if geometry is still same
mitk::Vector3D Loaded_Spacing = imageLoaded->GetGeometry()->GetSpacing();
error = abs(Loaded_Spacing[0] - Original_Spacing[0]) +
abs(Loaded_Spacing[1] - Original_Spacing[1]) +
abs(Loaded_Spacing[2] - Original_Spacing[2]) ;
MITK_TEST_CONDITION_REQUIRED( error < eps , "Compare Geometry: Spacing");
mitk::Point3D Loaded_Origin = imageLoaded->GetGeometry()->GetOrigin();
error = abs(Loaded_Origin[0] - Original_Origin[0]) +
abs(Loaded_Origin[1] - Original_Origin[1]) +
abs(Loaded_Origin[2] - Original_Origin[2]) ;
MITK_TEST_CONDITION_REQUIRED( error < eps , "Compare Geometry: Origin");
mitk::Vector3D Loaded_col0, Loaded_col1, Loaded_col2;
Loaded_col0.SetVnlVector(imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
Loaded_col1.SetVnlVector(imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
Loaded_col2.SetVnlVector(imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
if (
(abs(Original_col0[0] - Loaded_col0[0]) > eps) ||
(abs(Original_col0[1] - Loaded_col0[1]) > eps) ||
(abs(Original_col0[2] - Loaded_col0[2]) > eps) ||
(abs(Original_col1[0] - Loaded_col1[0]) > eps) ||
(abs(Original_col1[1] - Loaded_col1[1]) > eps) ||
(abs(Original_col1[2] - Loaded_col1[2]) > eps) ||
(abs(Original_col2[0] - Loaded_col2[0]) > eps) ||
(abs(Original_col2[1] - Loaded_col2[1]) > eps) ||
(abs(Original_col2[2] - Loaded_col2[2]) > eps) )
{
MITK_INFO << "Oh No! Original Image Matrix and Converted Image Matrix are different!";
MITK_INFO << "original Image:" << Original_col0 << " " << Original_col1 << " " << Original_col2;
MITK_INFO << "converted Image:" << Loaded_col0 << " " << Loaded_col1 << " " << Loaded_col2;
matrixIsEqual = false;
}
else
matrixIsEqual = true;
MITK_TEST_CONDITION_REQUIRED( matrixIsEqual , "Compare Geometry: Matrix");
return 0;
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkImageVtkMapper2DLevelWindowTest.cpp b/Core/Code/Testing/mitkImageVtkMapper2DLevelWindowTest.cpp
index 35bf27b1fa..62116333c0 100644
--- a/Core/Code/Testing/mitkImageVtkMapper2DLevelWindowTest.cpp
+++ b/Core/Code/Testing/mitkImageVtkMapper2DLevelWindowTest.cpp
@@ -1,57 +1,58 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//MITK
#include "mitkTestingMacros.h"
#include "mitkRenderingTestHelper.h"
#include <mitkLevelWindowProperty.h>
#include <mitkLevelWindowPreset.h>
//VTK
#include <vtkRegressionTestImage.h>
int mitkImageVtkMapper2DLevelWindowTest(int argc, char* argv[])
{
// load all arguments into a datastorage, take last argument as reference rendering
// setup a renderwindow of fixed size X*Y
// render the datastorage
// compare rendering to reference image
MITK_TEST_BEGIN("mitkImageVtkMapper2DTest")
mitk::RenderingTestHelper renderingHelper(640, 480, argc, argv);
//chose a level window: here we randomly chosen the blood preset.
mitk::LevelWindowPreset* levelWindowPreset = mitk::LevelWindowPreset::New();
bool loadedPreset = levelWindowPreset->LoadPreset();
MITK_TEST_CONDITION_REQUIRED(loadedPreset == true, "Testing if level window preset could be loaded");
double level = levelWindowPreset->getLevel("Blood");
double window = levelWindowPreset->getWindow("Blood");
+ levelWindowPreset->Delete();
//apply level window to all images
renderingHelper.SetImageProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(level, window)) );
//for now this test renders Sagittal
renderingHelper.SetViewDirection(mitk::SliceNavigationController::Sagittal);
//### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper
MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv) == true, "CompareRenderWindowAgainstReference test result positive?" );
//use this to generate a reference screenshot or save the file:
if(false)
{
renderingHelper.SaveReferenceScreenShot("/media/hdd/thomasHdd/Pictures/tmp/output1.png");
}
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp b/Core/Code/Testing/mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp
new file mode 100644
index 0000000000..18dd0c73b1
--- /dev/null
+++ b/Core/Code/Testing/mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp
@@ -0,0 +1,72 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+//MITK
+#include "mitkTestingMacros.h"
+#include "mitkRenderingTestHelper.h"
+
+//VTK
+#include <vtkRegressionTestImage.h>
+#include <mitkTransferFunctionProperty.h>
+#include <mitkTransferFunction.h>
+#include <mitkRenderingModeProperty.h>
+
+
+int mitkImageVtkMapper2DOpacityTransferFunctionTest(int argc, char* argv[])
+{
+ // load all arguments into a datastorage, take last argument as reference rendering
+ // setup a renderwindow of fixed size X*Y
+ // render the datastorage
+ // compare rendering to reference image
+ MITK_TEST_BEGIN("mitkImageVtkMapper2DopacityTransferFunctionTest")
+
+ mitk::RenderingTestHelper renderingHelper(640, 480, argc, argv);
+
+ //define some controlpoints for a scalaropacity
+ mitk::TransferFunction::ControlPoints scalarOpacityPoints;
+ scalarOpacityPoints.push_back( std::make_pair( 255, 0 ) );
+ scalarOpacityPoints.push_back( std::make_pair( 0, 0.1 ) );
+ scalarOpacityPoints.push_back( std::make_pair( 127, 0.3 ) );
+
+ //define an arbitrary colortransferfunction
+ vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
+ colorTransferFunction->SetColorSpaceToRGB();
+ colorTransferFunction->AddRGBPoint(0.0, 1, 0, 0); //black = red
+ colorTransferFunction->AddRGBPoint(127.5, 0, 1, 0); //grey = green
+ colorTransferFunction->AddRGBPoint(255.0, 0, 0, 1); //white = blue
+
+ mitk::TransferFunction::Pointer transferFunction = mitk::TransferFunction::New();
+ transferFunction->SetColorTransferFunction( colorTransferFunction );
+ transferFunction->SetScalarOpacityPoints(scalarOpacityPoints);
+
+ //set the rendering mode to use the transfer function
+ renderingHelper.SetImageProperty("Image Rendering.Mode", mitk::RenderingModeProperty::New(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR));
+ //set the property for the image
+ renderingHelper.SetImageProperty("Image Rendering.Transfer Function", mitk::TransferFunctionProperty::New(transferFunction));
+
+ //### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper
+ MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv, 20.0) == true, "CompareRenderWindowAgainstReference test result positive?" );
+
+ //renderingHelper.SetAutomaticallyCloseRenderWindow(false);
+
+ //use this to generate a reference screenshot or save the file:
+ if(false)
+ {
+ renderingHelper.SaveReferenceScreenShot("/tmp/output3.png");
+ }
+
+ MITK_TEST_END();
+}
diff --git a/Core/Code/Testing/mitkLogTest.cpp b/Core/Code/Testing/mitkLogTest.cpp
index cee8373457..ede203ff37 100644
--- a/Core/Code/Testing/mitkLogTest.cpp
+++ b/Core/Code/Testing/mitkLogTest.cpp
@@ -1,286 +1,335 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkCommon.h"
#include "mitkTestingMacros.h"
#include <mitkLog.h>
#include <mitkNumericTypes.h>
#include <itkMultiThreader.h>
#include <itksys/SystemTools.hxx>
#include <mitkStandardFileLocations.h>
+/** Documentation
+ *
+ * @brief this class provides an accessible BackendCout to determine whether this backend was
+ * used to process a message or not.
+ * It is needed for the disable / enable backend test.
+ */
+class TestBackendCout : public mbilog::BackendCout
+{
+public:
+ TestBackendCout()
+ {
+ m_Called = false;
+ mbilog::BackendCout();
+ }
+
+ void ProcessMessage(const mbilog::LogMessage &l)
+ {
+ m_Called = true;
+ mbilog::BackendCout::ProcessMessage(l);
+ }
+
+ bool WasCalled()
+{
+ return m_Called;
+}
+
+private:
+
+ bool m_Called;
+};
/** Documentation
*
* @brief Objects of this class can start an internal thread by calling the Start() method.
* The thread is then logging messages until the method Stop() is called. The class
* can be used to test if logging is thread-save by using multiple objects and let
* them log simuntanously.
*/
class mitkTestLoggingThread : public itk::Object
{
public:
mitkClassMacro(mitkTestLoggingThread,itk::Object);
mitkNewMacro1Param(mitkTestLoggingThread,itk::MultiThreader::Pointer);
int NumberOfMessages;
protected:
mitkTestLoggingThread(itk::MultiThreader::Pointer MultiThreader)
{
ThreadID = -1;
NumberOfMessages = 0;
m_MultiThreader = MultiThreader;
}
bool LoggingRunning;
int ThreadID;
itk::MultiThreader::Pointer m_MultiThreader;
void LogMessages()
{
while(LoggingRunning)
{
MITK_INFO << "Test info stream in thread" << ThreadID << "\n even with newlines";
MITK_WARN << "Test warning stream in thread " << ThreadID <<". "
<< "Even with a very long text, even without meaning or implied meaning or content, just a long sentence to see whether something has problems with long sentences or output in files or into windows or commandlines or whatever.";
MITK_DEBUG << "Test debugging stream in thread " << ThreadID;
MITK_ERROR << "Test error stream in thread " << ThreadID;
MITK_FATAL << "Test fatal stream in thread " << ThreadID;
NumberOfMessages += 5;
}
}
static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void* pInfoStruct)
{
/* extract this pointer from Thread Info structure */
struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
if (pInfo == NULL)
{
return ITK_THREAD_RETURN_VALUE;
}
if (pInfo->UserData == NULL)
{
return ITK_THREAD_RETURN_VALUE;
}
mitkTestLoggingThread *thisthread = (mitkTestLoggingThread*)pInfo->UserData;
if (thisthread != NULL)
thisthread->LogMessages();
return ITK_THREAD_RETURN_VALUE;
}
public:
int Start()
{
LoggingRunning = true;
this->ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this);
return ThreadID;
}
void Stop()
{
LoggingRunning = false;
}
};
/** Documentation
*
* @brief This class holds static test methods to sturcture the test of the mitk logging mechanism.
*/
class mitkLogTestClass
{
public:
static void TestSimpleLog()
{
bool testSucceded = true;
try
{
MITK_INFO << "Test info stream.";
MITK_WARN << "Test warning stream.";
MITK_DEBUG << "Test debugging stream."; //only activated if cmake variable is on!
//so no worries if you see no output for this line
MITK_ERROR << "Test error stream.";
MITK_FATAL << "Test fatal stream.";
}
catch(mitk::Exception e)
{
testSucceded = false;
}
MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging streams.");
}
static void TestObjectInfoLogging()
{
bool testSucceded = true;
try
{
int i = 123;
float f = .32234;
double d = 123123;
std::string testString = "testString";
std::stringstream testStringStream;
testStringStream << "test" << "String" << "Stream";
mitk::Point3D testMitkPoint;
testMitkPoint.Fill(2);
MITK_INFO << i;
MITK_INFO << f;
MITK_INFO << d;
MITK_INFO << testString;
MITK_INFO << testStringStream.str();
MITK_INFO << testMitkPoint;
}
catch(mitk::Exception e)
{
testSucceded = false;
}
MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging of object information.");
}
static void TestThreadSaveLog(bool toFile)
{
bool testSucceded = true;
try
{
if (toFile)
{
std::string filename = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + "/testthreadlog.log";
itksys::SystemTools::RemoveFile(filename.c_str()); // remove old file, we do not want to append to large files
mitk::LoggingBackend::SetLogFile(filename.c_str());
}
unsigned int numberOfThreads = 20;
unsigned int threadRuntimeInMilliseconds = 2000;
std::vector<unsigned int> threadIDs;
std::vector<mitkTestLoggingThread::Pointer> threads;
itk::MultiThreader::Pointer multiThreader = itk::MultiThreader::New();
for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx)
{
//initialize threads...
mitkTestLoggingThread::Pointer newThread = mitkTestLoggingThread::New(multiThreader);
threads.push_back(newThread);
std::cout << "Created " << threadIdx << ". thread." << std::endl;
}
for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx)
{
//start them
std::cout << "Start " << threadIdx << ". thread." << std::endl;
threadIDs.push_back( threads[threadIdx]->Start() );
std::cout << threadIdx << ". thread has ID " << threadIDs[threadIdx] << std::endl;
}
//wait for some time (milliseconds)
itksys::SystemTools::Delay( threadRuntimeInMilliseconds );
for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx)
{
//stop them
std::cout << "Stop " << threadIdx << ". thread." << std::endl;
threads[threadIdx]->Stop();
}
for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx)
{
//Wait for all threads to end
multiThreader->TerminateThread(threadIDs[threadIdx]);
std::cout << "Terminated " << threadIdx << ". thread (" << threads[threadIdx]->NumberOfMessages << " messages)." << std::endl;
}
}
catch(std::exception e)
{
MITK_ERROR << "exception during 'TestThreadSaveLog': "<<e.what();
testSucceded = false;
}
catch(...)
{
MITK_ERROR << "unknown exception during 'TestThreadSaveLog'";
testSucceded = false;
}
//if no error occured until now, everything is ok
MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging in different threads.");
}
static void TestLoggingToFile()
{
std::string filename = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + "/testlog.log";
mitk::LoggingBackend::SetLogFile(filename.c_str());
MITK_INFO << "Test logging to default filename: " << mitk::LoggingBackend::GetLogFile();
MITK_TEST_CONDITION_REQUIRED(itksys::SystemTools::FileExists(filename.c_str()),"Testing if log file exists.");
//TODO delete log file?
}
static void TestAddAndRemoveBackends()
{
mbilog::BackendCout myBackend = mbilog::BackendCout();
mbilog::RegisterBackend(&myBackend);
MITK_INFO << "Test logging";
mbilog::UnregisterBackend(&myBackend);
//if no error occured until now, everything is ok
MITK_TEST_CONDITION_REQUIRED(true,"Test add/remove logging backend.");
}
static void TestDefaultBackend()
{
//not possible now, because we cannot unregister the mitk logging backend in the moment. If such a method is added to mbilog utility one may add this test.
}
+static void TestEnableDisableBackends()
+{
+ TestBackendCout myCoutBackend = TestBackendCout();
+ mbilog::RegisterBackend(&myCoutBackend);
+
+ mbilog::DisableBackends(mbilog::Console);
+ MITK_INFO << "There should be no output!";
+ bool success = !myCoutBackend.WasCalled();
+
+ mbilog::EnableBackends(mbilog::Console);
+ MITK_INFO << "Now there should be an output.";
+ success &= myCoutBackend.WasCalled();
+
+ mbilog::UnregisterBackend(&myCoutBackend);
+ MITK_TEST_CONDITION_REQUIRED(success, "Test disable / enable logging backends.")
+}
};
int mitkLogTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("Log")
MITK_TEST_OUTPUT(<<"TESTING ALL LOGGING OUTPUTS, ERROR MESSAGES ARE ALSO TESTED AND NOT MEANING AN ERROR OCCURED!")
mitkLogTestClass::TestSimpleLog();
mitkLogTestClass::TestObjectInfoLogging();
mitkLogTestClass::TestLoggingToFile();
mitkLogTestClass::TestAddAndRemoveBackends();
mitkLogTestClass::TestThreadSaveLog( false ); // false = to console
mitkLogTestClass::TestThreadSaveLog( true ); // true = to file
+ mitkLogTestClass::TestEnableDisableBackends();
// TODO actually test file somehow?
// always end with this!
MITK_TEST_END()
}
+
+
diff --git a/Core/Code/Testing/mitkLookupTableTest.cpp b/Core/Code/Testing/mitkLookupTableTest.cpp
index bc9189ec54..8ab1f93045 100644
--- a/Core/Code/Testing/mitkLookupTableTest.cpp
+++ b/Core/Code/Testing/mitkLookupTableTest.cpp
@@ -1,183 +1,187 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkLookupTable.h>
#include <mitkTestFixture.h>
#include "mitkTestingMacros.h"
#include <mitkNumericTypes.h>
#include <iostream>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
class mitkLookupTableTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkLookupTableTestSuite);
MITK_TEST(TestCreateLookupTable);
MITK_TEST(TestSetVtkLookupTable);
MITK_TEST(TestSetOpacity);
MITK_TEST(TestCreateColorTransferFunction);
MITK_TEST(TestCreateOpacityTransferFunction);
MITK_TEST(TestCreateGradientTransferFunction);
CPPUNIT_TEST_SUITE_END();
private:
mitk::LookupTable::Pointer m_LookupTable;
public:
void TestCreateLookupTable()
{
// let's create an object of our class
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// first test: did this work?
// it makes no sense to continue without an object.
CPPUNIT_ASSERT_MESSAGE("Testing instantiation", myLookupTable.IsNotNull());
}
void TestSetVtkLookupTable ()
{
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// create a vtkLookupTable and add two values
vtkLookupTable *lut = vtkLookupTable::New();
lut->SetTableValue(0, 0.5, 0.5, 0.5, 1.0);
lut->SetTableValue(1, 0.5, 0.5, 0.5, 0.5);
lut->Build();
myLookupTable->SetVtkLookupTable(lut);
// check if the same lookuptable is returned
vtkLookupTable *lut2 = myLookupTable->GetVtkLookupTable();
CPPUNIT_ASSERT_MESSAGE("Input and output table are not equal",lut == lut2);
lut->Delete();
}
void TestSetOpacity()
{
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// create a vtkLookupTable and add two values
vtkLookupTable *lut = vtkLookupTable::New();
lut->SetRange(0, 200);
lut->SetAlphaRange(0.0, 1.0);
lut->Build();
myLookupTable->SetVtkLookupTable(lut);
myLookupTable->ChangeOpacityForAll(0.7f);
for (int i = 0; i < lut->GetNumberOfTableValues(); ++i)
{
CPPUNIT_ASSERT_MESSAGE("Opacity not set for all", mitk::Equal(0.7, lut->GetOpacity(i), 0.01, true));
}
vtkIdType tableIndex = 10;
myLookupTable->ChangeOpacity(tableIndex, 1.0);
double rgba[4];
lut->GetTableValue(tableIndex, rgba);
CPPUNIT_ASSERT_MESSAGE("Opacity not set for value", mitk::Equal(1.0, rgba[3], 0.01, true));
+ lut->Delete();
}
void TestCreateColorTransferFunction ()
{
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// create a vtkLookupTable and add two values
vtkLookupTable *lut = vtkLookupTable::New();
lut->SetRange(0, 255);
lut->Build();
myLookupTable->SetVtkLookupTable(lut);
vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = myLookupTable->CreateColorTransferFunction();
CPPUNIT_ASSERT(colorTransferFunction != 0);
vtkIdType numberOfTableEntries = lut->GetNumberOfTableValues();
double rgbaTable[4];
double rgbaFunction[4];
for (int i = 0; i < numberOfTableEntries; ++i)
{
lut->GetIndexedColor(i, rgbaTable);
colorTransferFunction->GetIndexedColor(i, rgbaFunction);
CPPUNIT_ASSERT_MESSAGE("Wrong color of transfer function",
mitk::Equal(rgbaTable[0], rgbaFunction[0], 0.000001, true) &&
mitk::Equal(rgbaTable[1], rgbaFunction[1], 0.000001, true) &&
mitk::Equal(rgbaTable[2], rgbaFunction[2], 0.000001, true)
);
}
+ lut->Delete();
}
void TestCreateOpacityTransferFunction ()
{
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// create a vtkLookupTable and add two values
vtkLookupTable *lut = vtkLookupTable::New();
lut->SetAlphaRange(0, 1.0);
lut->Build();
myLookupTable->SetVtkLookupTable(lut);
vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction = myLookupTable->CreateOpacityTransferFunction();
CPPUNIT_ASSERT(opacityTransferFunction != 0);
int funcSize = opacityTransferFunction->GetSize();
double *table = new double[funcSize];
double rgba[4];
opacityTransferFunction->GetTable(0, 1, funcSize, table);
for (int i = 0; i < funcSize; ++i)
{
lut->GetIndexedColor(i, rgba);
CPPUNIT_ASSERT_MESSAGE("Wrong opacity of transfer function",
mitk::Equal(table[i], rgba[3], 0.000001, true)
);
}
+ lut->Delete();
delete [] table;
}
void TestCreateGradientTransferFunction ()
{
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// create a vtkLookupTable and add two values
vtkLookupTable *lut = vtkLookupTable::New();
lut->SetAlphaRange(0, 0.73);
lut->Build();
myLookupTable->SetVtkLookupTable(lut);
vtkSmartPointer<vtkPiecewiseFunction> gradientTransferFunction = myLookupTable->CreateGradientTransferFunction();
CPPUNIT_ASSERT(gradientTransferFunction != 0);
int funcSize = gradientTransferFunction->GetSize();
double *table = new double[funcSize];
double rgba[4];
gradientTransferFunction->GetTable(0, 1, funcSize, table);
for (int i = 0; i < funcSize; ++i)
{
lut->GetIndexedColor(i, rgba);
CPPUNIT_ASSERT_MESSAGE("Wrong opacity of transfer function",
mitk::Equal(table[i], rgba[3], 0.000001, true)
);
}
+ lut->Delete();
delete [] table;
}
};
MITK_TEST_SUITE_REGISTRATION(mitkLookupTable)
diff --git a/Core/Code/Testing/mitkPlaneGeometryTest.cpp b/Core/Code/Testing/mitkPlaneGeometryTest.cpp
index 15c374a232..4ee3639731 100644
--- a/Core/Code/Testing/mitkPlaneGeometryTest.cpp
+++ b/Core/Code/Testing/mitkPlaneGeometryTest.cpp
@@ -1,1137 +1,845 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlaneGeometry.h"
#include "mitkRotationOperation.h"
#include "mitkInteractionConst.h"
#include "mitkLine.h"
#include "mitkGeometry3D.h"
#include "mitkThinPlateSplineCurvedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include <mitkTestingMacros.h>
#include <mitkTestFixture.h>
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include <fstream>
#include <iomanip>
static const mitk::ScalarType testEps = 1E-9; // the epsilon used in this test == at least float precision.
class mitkPlaneGeometryTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkPlaneGeometryTestSuite);
- MITK_TEST(mitkPlaneGeometryTestWrapper);
+ MITK_TEST(TestInitializeStandardPlane);
MITK_TEST(TestProjectPointOntoPlane);
- MITK_TEST(testPlaneGeometryCloning);
- MITK_TEST(testInheritance);
+ MITK_TEST(TestPlaneGeometryCloning);
+ MITK_TEST(TestInheritance);
+ MITK_TEST(TestSetExtendInMM);
+ MITK_TEST(TestRotate);
+ MITK_TEST(TestClone);
+ MITK_TEST(TestPlaneComparison);
+ MITK_TEST(TestAxialInitialization);
+ MITK_TEST(TestFrontalInitialization);
+ MITK_TEST(TestSaggitalInitialization);
+
// Currently commented out, see See bug 15990
// MITK_TEST(testPlaneGeometryInitializeOrder);
- //MITK_TEST(mappingTests2D);
MITK_TEST(TestIntersectionPoint);
MITK_TEST(TestCase1210);
CPPUNIT_TEST_SUITE_END();
+private:
+ // private test members that are initialized by setUp()
+ mitk::PlaneGeometry::Pointer planegeometry;
+ mitk::Point3D origin;
+ mitk::Vector3D right, bottom, normal;
+ mitk::ScalarType width, height;
+ mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
+
public:
void setUp()
{
+ planegeometry = mitk::PlaneGeometry::New();
+ width = 100; widthInMM = width;
+ height = 200; heightInMM = height;
+ thicknessInMM = 1.0;
+ mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
+ mitk::FillVector3D(right, widthInMM, 0, 0);
+ mitk::FillVector3D(bottom, 0, heightInMM, 0);
+ mitk::FillVector3D(normal, 0, 0, thicknessInMM);
+
+ planegeometry->InitializeStandardPlane(right.GetVnlVector(), bottom.GetVnlVector());
+ planegeometry->SetOrigin(origin);
}
void tearDown()
{
}
- // This test is supposed to verify inheritance behaviour, this test will fail if the behaviour changes in the future
- void testInheritance()
+ // This test verifies inheritance behaviour, this test will fail if the behaviour changes in the future
+ void TestInheritance()
{
mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
mitk::Geometry3D::Pointer g3d = dynamic_cast < mitk::Geometry3D* > ( plane.GetPointer() );
CPPUNIT_ASSERT_MESSAGE("Planegeometry should not be castable to Geometry 3D", g3d.IsNull());
mitk::BaseGeometry::Pointer base = dynamic_cast < mitk::BaseGeometry* > ( plane.GetPointer() );
CPPUNIT_ASSERT_MESSAGE("Planegeometry should be castable to BaseGeometry", base.IsNotNull());
base = NULL;
g3d = mitk::Geometry3D::New();
base = dynamic_cast < mitk::BaseGeometry* > ( g3d.GetPointer() );
CPPUNIT_ASSERT_MESSAGE("Geometry3D should be castable to BaseGeometry", base.IsNotNull());
g3d=NULL;
mitk::SlicedGeometry3D::Pointer sliced = mitk::SlicedGeometry3D::New();
g3d = dynamic_cast < mitk::Geometry3D* > ( sliced.GetPointer() );
CPPUNIT_ASSERT_MESSAGE("SlicedGeometry3D should not be castable to Geometry3D", g3d.IsNull());
plane=NULL;
mitk::ThinPlateSplineCurvedGeometry::Pointer thin = mitk::ThinPlateSplineCurvedGeometry::New();
plane = dynamic_cast < mitk::PlaneGeometry* > ( thin.GetPointer() );
CPPUNIT_ASSERT_MESSAGE("AbstractTransformGeometry should be castable to PlaneGeometry", plane.IsNotNull());
plane = mitk::PlaneGeometry::New();
mitk::AbstractTransformGeometry::Pointer atg = dynamic_cast < mitk::AbstractTransformGeometry* > ( plane.GetPointer() );
CPPUNIT_ASSERT_MESSAGE("PlaneGeometry should not be castable to AbstractTransofrmGeometry", atg.IsNull());
}
+ // See bug 1210
+ // Test does not use standard Parameters
void TestCase1210()
{
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, down, spacing;
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right,
1.015625, 1.015625, 1.1999969482421875
);
mitk::FillVector3D(down,
1.4012984643248170709237295832899161312802619418765e-45, 0, 0
);
mitk::FillVector3D(spacing,
0, 1.4713633875410579244699160624544119378442750389703e-43, 9.2806360452222355258639080851310540729807238879469e-32
);
std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
CPPUNIT_ASSERT_NO_THROW(planegeometry->InitializeStandardPlane(right, down, &spacing));
/*
std::cout << "Testing width, height and thickness (in units): ";
if((mitk::Equal(planegeometry->GetExtent(0),width)==false) ||
(mitk::Equal(planegeometry->GetExtent(1),height)==false) ||
(mitk::Equal(planegeometry->GetExtent(2),1)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm): ";
if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
*/
}
/**
* @brief This method tests method IntersectionPoint
*
* See also bug #7151. (ref 2 this test: iggy)
* This test was written due to incorrect calculation of the intersection point
* between a given line and plane. This only occured when the pointdistance of
* the line was less than 1.
* Test Behavour:
* ==============
* we have a given line and a given plane.
* we let the line intersect the plane.
* when testing several positions on the line the resulting intersection point must be the same
* we test a position where the distance between the correspoinding points is < 0 and another position where the distance is > 0.
*
*/
+ // Test does not use standard Parameters
void TestIntersectionPoint()
{
//init plane with its parameter
mitk::PlaneGeometry::Pointer myPlaneGeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
origin[0] = 0.0;
origin[1] = 2.0;
origin[2] = 0.0;
mitk::Vector3D normal;
normal[0] = 0.0;
normal[1] = 1.0;
normal[2] = 0.0;
myPlaneGeometry->InitializePlane(origin,normal);
//generate points and line for intersection testing
//point distance of given line > 1
mitk::Point3D pointP1;
pointP1[0] = 2.0;
pointP1[1] = 1.0;
pointP1[2] = 0.0;
mitk::Point3D pointP2;
pointP2[0] = 2.0;
pointP2[1] = 4.0;
pointP2[2] = 0.0;
mitk::Vector3D lineDirection;
lineDirection[0] = pointP2[0] - pointP1[0];
lineDirection[1] = pointP2[1] - pointP1[1];
lineDirection[2] = pointP2[2] - pointP1[2];
mitk::Line3D xingline( pointP1, lineDirection );
mitk::Point3D calcXingPoint;
myPlaneGeometry->IntersectionPoint(xingline, calcXingPoint);
//point distance of given line < 1
mitk::Point3D pointP3;
pointP3[0] = 2.0;
pointP3[1] = 2.2;
pointP3[2] = 0.0;
mitk::Point3D pointP4;
pointP4[0] = 2.0;
pointP4[1] = 1.7;
pointP4[2] = 0.0;
mitk::Vector3D lineDirection2;
lineDirection2[0] = pointP4[0] - pointP3[0];
lineDirection2[1] = pointP4[1] - pointP3[1];
lineDirection2[2] = pointP4[2] - pointP3[2];
mitk::Line3D xingline2( pointP3, lineDirection2 );
mitk::Point3D calcXingPoint2;
myPlaneGeometry->IntersectionPoint( xingline2, calcXingPoint2 );
//intersection points must be the same
CPPUNIT_ASSERT_MESSAGE("Failed to calculate Intersection Point", calcXingPoint == calcXingPoint2);
}
/**
* @brief This method tests method ProjectPointOntoPlane.
*
* See also bug #3409.
*/
+ // Test does not use standard Parameters
void TestProjectPointOntoPlane()
{
mitk::PlaneGeometry::Pointer myPlaneGeometry = mitk::PlaneGeometry::New();
//create normal
mitk::Vector3D normal;
normal[0] = 0.0;
normal[1] = 0.0;
normal[2] = 1.0;
//create origin
mitk::Point3D origin;
origin[0] = -27.582859;
origin[1] = 50;
origin[2] = 200.27742;
//initialize plane geometry
myPlaneGeometry->InitializePlane(origin,normal);
//output to descripe the test
std::cout << "Testing PlaneGeometry according to bug #3409" << std::endl;
std::cout << "Our normal is: " << normal << std::endl;
std::cout << "So ALL projected points should have exactly the same z-value!" << std::endl;
//create a number of points
mitk::Point3D myPoints[5];
myPoints[0][0] = -27.582859;
myPoints[0][1] = 50.00;
myPoints[0][2] = 200.27742;
myPoints[1][0] = -26.58662;
myPoints[1][1] = 50.00;
myPoints[1][2] = 200.19026;
myPoints[2][0] = -26.58662;
myPoints[2][1] = 50.00;
myPoints[2][2] = 200.33124;
myPoints[3][0] = 104.58662;
myPoints[3][1] = 452.12313;
myPoints[3][2] = 866.41236;
myPoints[4][0] = -207.58662;
myPoints[4][1] = 312.00;
myPoints[4][2] = -300.12346;
//project points onto plane
mitk::Point3D myProjectedPoints[5];
for ( unsigned int i = 0; i < 5; ++i )
{
myProjectedPoints[i] = myPlaneGeometry->ProjectPointOntoPlane( myPoints[i] );
}
//compare z-values with z-value of plane (should be equal)
bool allPointsOnPlane = true;
for ( unsigned int i = 0; i < 5; ++i )
{
if ( fabs(myProjectedPoints[i][2] - origin[2]) > mitk::sqrteps )
{
allPointsOnPlane = false;
}
}
CPPUNIT_ASSERT_MESSAGE("All points lie not on the same plane", allPointsOnPlane);
}
- void testPlaneGeometryCloning()
+ void TestPlaneGeometryCloning()
{
mitk::PlaneGeometry::Pointer geometry2D = createPlaneGeometry();
try
{
mitk::PlaneGeometry::Pointer clone = geometry2D->Clone();
itk::Matrix<mitk::ScalarType,3,3> matrix = clone->GetIndexToWorldTransform()->GetMatrix();
CPPUNIT_ASSERT_MESSAGE("Test if matrix element exists...", matrix[0][0] == 31);
double origin = geometry2D->GetOrigin()[0];
CPPUNIT_ASSERT_MESSAGE("First Point of origin as expected...", mitk::Equal(origin, 8));
double spacing = geometry2D->GetSpacing()[0];
CPPUNIT_ASSERT_MESSAGE("First Point of spacing as expected...", mitk::Equal(spacing, 31));
}
catch (...)
{
CPPUNIT_FAIL("Error during access on a member of cloned geometry");
}
// direction [row] [coloum]
MITK_TEST_OUTPUT( << "Casting a rotated 2D ITK Image to a MITK Image and check if Geometry is still same" );
}
- void testPlaneGeometryInitializeOrder()
+ void TestPlaneGeometryInitializeOrder()
{
mitk::Vector3D mySpacing;
mySpacing[0] = 31;
mySpacing[1] = 0.1;
mySpacing[2] = 5.4;
mitk::Point3D myOrigin;
myOrigin[0] = 8;
myOrigin[1] = 9;
myOrigin[2] = 10;
mitk::AffineTransform3D::Pointer myTransform = mitk::AffineTransform3D::New();
itk::Matrix<mitk::ScalarType, 3,3> transMatrix;
transMatrix.Fill(0);
transMatrix[0][0] = 1;
transMatrix[1][1] = 2;
transMatrix[2][2] = 4;
myTransform->SetMatrix(transMatrix);
mitk::PlaneGeometry::Pointer geometry2D1 = mitk::PlaneGeometry::New();
geometry2D1->SetIndexToWorldTransform(myTransform);
geometry2D1->SetSpacing(mySpacing);
geometry2D1->SetOrigin(myOrigin);
mitk::PlaneGeometry::Pointer geometry2D2 = mitk::PlaneGeometry::New();
geometry2D2->SetSpacing(mySpacing);
geometry2D2->SetOrigin(myOrigin);
geometry2D2->SetIndexToWorldTransform(myTransform);
mitk::PlaneGeometry::Pointer geometry2D3 = mitk::PlaneGeometry::New();
geometry2D3->SetIndexToWorldTransform(myTransform);
geometry2D3->SetSpacing(mySpacing);
geometry2D3->SetOrigin(myOrigin);
geometry2D3->SetIndexToWorldTransform(myTransform);
CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 1 matches that of Geometry 2.", mitk::Equal(geometry2D1->GetOrigin(), geometry2D2->GetOrigin()));
CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 1 match those of Geometry 3.", mitk::Equal(geometry2D1->GetOrigin(), geometry2D3->GetOrigin()));
CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 2 match those of Geometry 3.", mitk::Equal(geometry2D2->GetOrigin(), geometry2D3->GetOrigin()));
CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 1 match those of Geometry 2.", mitk::Equal(geometry2D1->GetSpacing(), geometry2D2->GetSpacing()));
CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 1 match those of Geometry 3.", mitk::Equal(geometry2D1->GetSpacing(), geometry2D3->GetSpacing()));
CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 2 match those of Geometry 3.", mitk::Equal(geometry2D2->GetSpacing(), geometry2D3->GetSpacing()));
CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 1 match those of Geometry 2.", compareMatrix(geometry2D1->GetIndexToWorldTransform()->GetMatrix(), geometry2D2->GetIndexToWorldTransform()->GetMatrix()));
CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 1 match those of Geometry 3.", compareMatrix(geometry2D1->GetIndexToWorldTransform()->GetMatrix(), geometry2D3->GetIndexToWorldTransform()->GetMatrix()));
CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 2 match those of Geometry 3.", compareMatrix(geometry2D2->GetIndexToWorldTransform()->GetMatrix(), geometry2D3->GetIndexToWorldTransform()->GetMatrix()));
}
- // This is a wrapper to make the old test compatible to CCP Unit without rewriting all the conditions below.
- // The test is far from optimal anyway and should be rewritten when time permits
- void mitkPlaneGeometryTestWrapper()
- {
- CPPUNIT_ASSERT_MESSAGE("Failed general PlaneGeometryTest, see output for further details", mitkPlaneGeometryTest() == EXIT_SUCCESS);
- }
-
- int mitkPlaneGeometryTest()
+ void TestInitializeStandardPlane()
{
- int result;
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: width", mitk::Equal(planegeometry->GetExtent(0),width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: height", mitk::Equal(planegeometry->GetExtent(1),height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: depth", mitk::Equal(planegeometry->GetExtent(2),1, testEps));
- /*
- // the following can be used to reproduce a bug in ITK matrix inversion
- // which was found while investigating bug #1210.
- result = TestCase1210();
- if(result!=EXIT_SUCCESS)
- return result;
- */
-
- mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
-
- mitk::Point3D origin;
- mitk::Vector3D right, bottom, normal;
- mitk::ScalarType width, height;
- mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
-
- width = 100; widthInMM = width;
- height = 200; heightInMM = height;
- thicknessInMM = 1.0;
- mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
- mitk::FillVector3D(right, widthInMM, 0, 0);
- mitk::FillVector3D(bottom, 0, heightInMM, 0);
- mitk::FillVector3D(normal, 0, 0, thicknessInMM);
-
- std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
- planegeometry->InitializeStandardPlane(right.GetVnlVector(), bottom.GetVnlVector());
-
- std::cout << "Testing width, height and thickness (in units): ";
- if((mitk::Equal(planegeometry->GetExtent(0),width, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtent(1),height, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtent(2),1, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing width, height and thickness (in mm): ";
- if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: width in mm", mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: heght in mm", mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: depth in mm", mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps) );
- std::cout << "Testing GetAxisVector(): ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorRight", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorBottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorNormal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps) );
- std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = {1.0, 1.0, 1.5}): "<<std::endl;
mitk::Vector3D spacing;
thicknessInMM = 1.5;
normal.Normalize(); normal *= thicknessInMM;
mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
planegeometry->InitializeStandardPlane(right.GetVnlVector(), bottom.GetVnlVector(), &spacing);
- std::cout << "Testing width, height and thickness (in units): ";
- if((mitk::Equal(planegeometry->GetExtent(0),width, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtent(1),height, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtent(2),1, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: width", mitk::Equal(planegeometry->GetExtent(0),width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: height", mitk::Equal(planegeometry->GetExtent(1),height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: depth", mitk::Equal(planegeometry->GetExtent(2),1, testEps));
- std::cout << "Testing width, height and thickness (in mm): ";
- if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: width in mm", mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: height in mm", mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: depth in mm", mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps) );
- std::cout << "Testing GetAxisVector(): ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorRight", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorBottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorNormal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps) );
- std::cout << "Testing SetExtentInMM(2, ...), querying by GetExtentInMM(2): ";
- thicknessInMM = 3.5;
- normal.Normalize(); normal *= thicknessInMM;
- planegeometry->SetExtentInMM(2, thicknessInMM);
- if(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ ;
+ }
- std::cout << "Testing SetExtentInMM(2, ...), querying by GetAxisVector(2) and comparing to normal: ";
- if(mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ void TestSetExtendInMM()
+ {
+ normal.Normalize();
+ normal *= thicknessInMM;
+ planegeometry->SetExtentInMM(2, thicknessInMM);
+ CPPUNIT_ASSERT_MESSAGE("Testing SetExtentInMM(2, ...), querying by GetExtentInMM(2): ", mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing SetExtentInMM(2, ...), querying by GetAxisVector(2) and comparing to normal: ", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
- std::cout << "Testing SetOrigin: ";
planegeometry->SetOrigin(origin);
- if(mitk::Equal(planegeometry->GetOrigin(), origin, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing SetOrigin", mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
- std::cout << "Testing GetAxisVector() after SetOrigin: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Right", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Bottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps) );
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Normal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps) );
- result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
+ }
- std::cout << "Changing the IndexToWorldTransform to a rotated version by SetIndexToWorldTransform() (keep origin): "<<std::endl;
+ void TestRotate()
+ {
+ // Changing the IndexToWorldTransform to a rotated version by SetIndexToWorldTransform() (keep origin):
mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = planegeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
mitk::VnlVector axis(3);
mitk::FillVector3D(axis, 1.0, 1.0, 1.0); axis.normalize();
vnl_quaternion<mitk::ScalarType> rotation(axis, 0.223);
vnlmatrix = rotation.rotation_matrix_transpose()*vnlmatrix;
mitk::Matrix3D matrix;
matrix = vnlmatrix;
transform->SetMatrix(matrix);
transform->SetOffset(planegeometry->GetIndexToWorldTransform()->GetOffset());
right.SetVnlVector( rotation.rotation_matrix_transpose()*right.GetVnlVector() );
bottom.SetVnlVector(rotation.rotation_matrix_transpose()*bottom.GetVnlVector());
normal.SetVnlVector(rotation.rotation_matrix_transpose()*normal.GetVnlVector());
planegeometry->SetIndexToWorldTransform(transform);
//The origin changed,because m_Origin=m_IndexToWorldTransform->GetOffset()+GetAxisVector(2)*0.5
//and the AxisVector changes due to the rotation. In other words: the rotation was done around
//the corner of the box, not around the planes origin. Now change it to a rotation around
//the origin, simply by re-setting the origin to the original one:
planegeometry->SetOrigin(origin);
- mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
- std::cout << "Testing whether SetIndexToWorldTransform kept origin: ";
- if(mitk::Equal(planegeometry->GetOrigin(), origin, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
+ CPPUNIT_ASSERT_MESSAGE("Testing whether SetIndexToWorldTransform kept origin: ", mitk::Equal(planegeometry->GetOrigin(), origin, testEps) );
- MITK_TEST_OUTPUT( << "Testing consistancy of index and world coordinates. ");
mitk::Point2D point; point[0] = 4; point[1] = 3;
mitk::Point2D dummy;
planegeometry->WorldToIndex(point, dummy);
planegeometry->IndexToWorld(dummy, dummy);
- MITK_TEST_CONDITION_REQUIRED(dummy == point, "");
+ CPPUNIT_ASSERT_MESSAGE("Testing consistancy of index and world coordinates.", dummy == point);
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width of rotated version: ", mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height of rotated version: ", mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness of rotated version: ", mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps));
- std::cout << "Testing width, height and thickness (in mm) of rotated version: ";
- if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: right ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: bottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: normal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
- std::cout << "Testing GetAxisVector() of rotated version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
+ mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(),planegeometry->GetExtentInMM(0), testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
+ mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(),planegeometry->GetExtentInMM(1), testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
+ mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(),planegeometry->GetExtentInMM(2), testEps));
- std::cout << "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(),planegeometry->GetExtentInMM(0), testEps)==false) ||
- (mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(),planegeometry->GetExtentInMM(1), testEps)==false) ||
- (mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(),planegeometry->GetExtentInMM(2), testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
- result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
- if(result!=EXIT_SUCCESS)
- return result;
-
- std::cout << "Testing SetSizeInUnits() of rotated version: "<<std::endl;
width *= 2;
height *= 3;
planegeometry->SetSizeInUnits(width, height);
+ CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ", mitk::Equal(planegeometry->GetExtent(0),width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ", mitk::Equal(planegeometry->GetExtent(1),height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ", mitk::Equal(planegeometry->GetExtent(2),1, testEps));
+
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of version with changed size in units: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of version with changed size in units: ", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of version with changed size in units: ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
+
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: right ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: bottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: normal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
+
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
+ mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(),planegeometry->GetExtentInMM(0), testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
+ mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(),planegeometry->GetExtentInMM(1), testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
+ mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(),planegeometry->GetExtentInMM(2), testEps));
+
+ mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
+ }
- std::cout << "Testing width, height and thickness (in units): ";
- if((mitk::Equal(planegeometry->GetExtent(0),width, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtent(1),height, testEps)==false) ||
- (mitk::Equal(planegeometry->GetExtent(2),1, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing width, height and thickness (in mm) of version with changed size in units: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing GetAxisVector() of version with changed size in units: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(),planegeometry->GetExtentInMM(0), testEps)==false) ||
- (mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(),planegeometry->GetExtentInMM(1), testEps)==false) ||
- (mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(),planegeometry->GetExtentInMM(2), testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
- if(result!=EXIT_SUCCESS)
- return result;
-
- std::cout << "Testing Clone(): ";
+ void TestClone()
+ {
mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
- if((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount()!=1))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ // Cave: Statement below is negated!
+ CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ", ! ((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount()!=1)));
+ CPPUNIT_ASSERT_MESSAGE("Testing origin of cloned version: ", mitk::Equal(clonedplanegeometry->GetOrigin(), origin, testEps));
- std::cout << "Testing origin of cloned version: ";
- if(mitk::Equal(clonedplanegeometry->GetOrigin(), origin, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtent(0),width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtent(1),height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing extent (in units) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtent(2),1, testEps));
- std::cout << "Testing width, height and thickness (in units) of cloned version: ";
- if((mitk::Equal(clonedplanegeometry->GetExtent(0),width, testEps)==false) ||
- (mitk::Equal(clonedplanegeometry->GetExtent(1),height, testEps)==false) ||
- (mitk::Equal(clonedplanegeometry->GetExtent(2),1, testEps)==false)
- )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtentInMM(1), heightInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtentInMM(2), thicknessInMM, testEps));
- std::cout << "Testing width, height and thickness (in mm) of cloned version: ";
- if(!mitk::Equal(clonedplanegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(clonedplanegeometry->GetExtentInMM(1), heightInMM, testEps) || !mitk::Equal(clonedplanegeometry->GetExtentInMM(2), thicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing GetAxisVector() of cloned version: ";
- if((mitk::Equal(clonedplanegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(clonedplanegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(clonedplanegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- result = mappingTests2D(clonedplanegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: right", mitk::Equal(clonedplanegeometry->GetAxisVector(0), right, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: bottom", mitk::Equal(clonedplanegeometry->GetAxisVector(1), bottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: normal", mitk::Equal(clonedplanegeometry->GetAxisVector(2), normal, testEps));
- // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane'
- std::cout << "Testing Clone(): ";
- mitk::PlaneGeometry::Pointer clonedplanegeometry2 = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
- if((clonedplanegeometry2.IsNull()) || (clonedplanegeometry2->GetReferenceCount()!=1))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout << "Testing if cloned and original version are at the same place: ";
- if(mitk::Equal(clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer()), true) ==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing if the origin is on the plane: ";
- if(mitk::Equal(clonedplanegeometry2->IsOnPlane(origin), true)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- mitk::VnlVector newaxis(3);
- mitk::FillVector3D(newaxis, 1.0, 1.0, 1.0); newaxis.normalize();
- vnl_quaternion<mitk::ScalarType> rotation2(newaxis, 0.0);
-
- mitk::Vector3D clonednormal = clonedplanegeometry2->GetNormal();
- mitk::Point3D clonedorigin = clonedplanegeometry2->GetOrigin();
-
- mitk::RotationOperation* planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 180.0 );
+ mappingTests2D(clonedplanegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
+ }
- clonedplanegeometry2->ExecuteOperation( planerot );
+ void TestSaggitalInitialization()
+ {
+ mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
- std::cout << "Testing whether the flipped plane is still the original plane: ";
- if( mitk::Equal( clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer()), true )==false )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
- clonedorigin += clonednormal;
- clonedplanegeometry2->SetOrigin( clonedorigin );
+ // Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Sagittal, zPosition = 0, frontside=true):
+ planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Sagittal);
- std::cout << "Testing if the translated (cloned, flipped) plane is parallel to its origin plane: ";
- if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), true )==false )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ mitk::Vector3D newright, newbottom, newnormal;
+ mitk::ScalarType newthicknessInMM;
- delete planerot;
+ newright = bottom;
+ newthicknessInMM = widthInMM/width*1.0; // extent in normal direction is 1;
+ newnormal = right; newnormal.Normalize(); newnormal *= newthicknessInMM;
+ newbottom = normal; newbottom.Normalize(); newbottom *= thicknessInMM;
- planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 0.5 );
- clonedplanegeometry2->ExecuteOperation( planerot );
+ CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of sagitally initialized version:", mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps));
- std::cout << "Testing if a non-paralell plane gets recognized as not paralell [rotation +0.5 degree] : ";
- if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), false )==false )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ //ok, corner was fine, so we can dare to believe the origin is ok.
+ origin = planegeometry->GetOrigin();
- delete planerot;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), 1, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
- planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), -1.0 );
- clonedplanegeometry2->ExecuteOperation( planerot );
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), heightInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps));
- std::cout << "Testing if a non-paralell plane gets recognized as not paralell [rotation -0.5 degree] : ";
- if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), false )==false )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps));
- delete planerot;
+ mappingTests2D(planegeometry, height, 1, heightInMM, thicknessInMM, origin, newright, newbottom);
- planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 360.5 );
- clonedplanegeometry2->ExecuteOperation( planerot );
+ // set origin back to the one of the axial slice:
+ origin = clonedplanegeometry->GetOrigin();
+ // Testing backside initialization: InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition = 0, frontside=false, rotated=true):
+ planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Axial, 0, false, true);
+ mitk::Point3D backsideorigin;
+ backsideorigin=origin+clonedplanegeometry->GetAxisVector(1);//+clonedplanegeometry->GetAxisVector(2);
- std::cout << "Testing if a non-paralell plane gets recognized as not paralell [rotation 360 degree] : ";
- if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), true )==false )
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing origin of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetOrigin(), backsideorigin, testEps));
- std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition = 0, frontside=true): " <<std::endl;
- planegeometry->InitializeStandardPlane(clonedplanegeometry);
+ mitk::Point3D backsidecornerpoint0;
+ backsidecornerpoint0 = cornerpoint0+clonedplanegeometry->GetAxisVector(1);//+clonedplanegeometry->GetAxisVector(2);
+ CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of sagitally initialized version: ", mitk::Equal(planegeometry->GetCornerPoint(0), backsidecornerpoint0, testEps));
- std::cout << "Testing origin of axially initialized version: ";
- if(mitk::Equal(planegeometry->GetOrigin(), origin)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
+ mitk::Equal(planegeometry->GetExtent(0), width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
+ mitk::Equal(planegeometry->GetExtent(1), height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
+ mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
- std::cout << "Testing GetCornerPoint(0) of axially initialized version: ";
- if(mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
- std::cout << "Testing width, height and thickness (in units) of axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ";
- if(!mitk::Equal(planegeometry->GetExtent(0), width, testEps) || !mitk::Equal(planegeometry->GetExtent(1), height, testEps) || !mitk::Equal(planegeometry->GetExtent(2), 1, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), -bottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), -normal, testEps));
- std::cout << "Testing width, height and thickness (in mm) of axially initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, backsideorigin, right, -bottom);
+ }
- std::cout << "Testing GetAxisVector() of axially initialized version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ void TestFrontalInitialization()
+ {
+ mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
- result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
+ //--------
mitk::Vector3D newright, newbottom, newnormal;
mitk::ScalarType newthicknessInMM;
- std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Frontal, zPosition = 0, frontside=true): " <<std::endl;
+
+ // Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Frontal, zPosition = 0, frontside=true)
planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Frontal);
newright = right;
newbottom = normal; newbottom.Normalize(); newbottom *= thicknessInMM;
newthicknessInMM = heightInMM/height*1.0/*extent in normal direction is 1*/;
newnormal = -bottom; newnormal.Normalize(); newnormal *= newthicknessInMM;
- std::cout << "Testing GetCornerPoint(0) of frontally initialized version: ";
- if(mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of frontally initialized version: ", mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps));
+
//ok, corner was fine, so we can dare to believe the origin is ok.
origin = planegeometry->GetOrigin();
- std::cout << "Testing width, height and thickness (in units) of frontally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtent(0), width, testEps) || !mitk::Equal(planegeometry->GetExtent(1), 1, testEps) || !mitk::Equal(planegeometry->GetExtent(2), 1, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), 1, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness (in units) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
- std::cout << "Testing width, height and thickness (in mm) of frontally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps));
- std::cout << "Testing GetAxisVector() of frontally initialized version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps));
- result = mappingTests2D(planegeometry, width, 1, widthInMM, thicknessInMM, origin, newright, newbottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ mappingTests2D(planegeometry, width, 1, widthInMM, thicknessInMM, origin, newright, newbottom);
- std::cout << "Changing plane to in-plane unit spacing using SetSizeInUnits: " <<std::endl;
+ //Changing plane to in-plane unit spacing using SetSizeInUnits:
planegeometry->SetSizeInUnits(planegeometry->GetExtentInMM(0), planegeometry->GetExtentInMM(1));
- std::cout << "Testing origin of unit spaced, frontally initialized version: ";
- if(mitk::Equal(planegeometry->GetOrigin(), origin, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE( "Testing origin of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
- std::cout << "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps) || !mitk::Equal(planegeometry->GetExtent(2), 1, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
- std::cout << "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps));
- std::cout << "Testing GetAxisVector() of unit spaced, frontally initialized version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps));
- result = mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
- std::cout << "Changing plane to unit spacing also in normal direction using SetExtentInMM(2, 1.0): " <<std::endl;
+ // Changing plane to unit spacing also in normal direction using SetExtentInMM(2, 1.0):
planegeometry->SetExtentInMM(2, 1.0);
newnormal.Normalize();
- std::cout << "Testing origin of unit spaced, frontally initialized version: ";
- if(mitk::Equal(planegeometry->GetOrigin(), origin, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing origin of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
- std::cout << "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps) || !mitk::Equal(planegeometry->GetExtent(2), 1, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
- std::cout << "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), 1.0, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), 1.0, testEps));
- std::cout << "Testing GetAxisVector() of unit spaced, frontally initialized version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps));
+ mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
+ }
- result = mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ void TestAxialInitialization()
+ {
+ mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
- std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Sagittal, zPosition = 0, frontside=true): " <<std::endl;
- planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Sagittal);
- newright = bottom;
- newthicknessInMM = widthInMM/width*1.0/*extent in normal direction is 1*/;
- newnormal = right; newnormal.Normalize(); newnormal *= newthicknessInMM;
+ // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane'
+ mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
- std::cout << "Testing GetCornerPoint(0) of sagitally initialized version: ";
- if(mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
- //ok, corner was fine, so we can dare to believe the origin is ok.
- origin = planegeometry->GetOrigin();
+ CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ", ! ((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount()!=1)) );
- std::cout << "Testing width, height and thickness (in units) of sagitally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtent(0), height, testEps) || !mitk::Equal(planegeometry->GetExtent(1), 1, testEps) || !mitk::Equal(planegeometry->GetExtent(2), 1, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition = 0, frontside=true): " <<std::endl;
+ planegeometry->InitializeStandardPlane(clonedplanegeometry);
- std::cout << "Testing width, height and thickness (in mm) of sagitally initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), heightInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing origin of axially initialized version: ", mitk::Equal(planegeometry->GetOrigin(), origin));
- std::cout << "Testing GetAxisVector() of sagitally initialized version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of axially initialized version: ", mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0));
- result = mappingTests2D(planegeometry, height, 1, heightInMM, thicknessInMM, origin, newright, newbottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
+ mitk::Equal(planegeometry->GetExtent(0), width, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
+ mitk::Equal(planegeometry->GetExtent(1), height, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness (in units) of axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
+ mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
- //set origin back to the one of the axial slice:
- origin = clonedplanegeometry->GetOrigin();
- std::cout << "Testing backside initialization: InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition = 0, frontside=false, rotated=true): " <<std::endl;
- planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Axial, 0, false, true);
- mitk::Point3D backsideorigin;
- backsideorigin=origin+clonedplanegeometry->GetAxisVector(1);//+clonedplanegeometry->GetAxisVector(2);
+ CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of axially initialized version: ",
+ mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of axially initialized version: ",
+ mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of axially initialized version: ",
+ mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
- std::cout << "Testing origin of backsidedly, axially initialized version: ";
- if(mitk::Equal(planegeometry->GetOrigin(), backsideorigin, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ",
+ mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ",
+ mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
+ CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ",
+ mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
- std::cout << "Testing GetCornerPoint(0) of sagitally initialized version: ";
- mitk::Point3D backsidecornerpoint0;
- backsidecornerpoint0 = cornerpoint0+clonedplanegeometry->GetAxisVector(1);//+clonedplanegeometry->GetAxisVector(2);
- if(mitk::Equal(planegeometry->GetCornerPoint(0), backsidecornerpoint0, testEps)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
+ }
- std::cout << "Testing width, height and thickness (in units) of backsidedly, axially initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ";
- if(!mitk::Equal(planegeometry->GetExtent(0), width, testEps) || !mitk::Equal(planegeometry->GetExtent(1), height, testEps) || !mitk::Equal(planegeometry->GetExtent(2), 1, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ void TestPlaneComparison()
+ {
+ // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane'
+ mitk::PlaneGeometry::Pointer clonedplanegeometry2 = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
- std::cout << "Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ";
- if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps) || !mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ", ! ((clonedplanegeometry2.IsNull()) || (clonedplanegeometry2->GetReferenceCount()!=1)) );
+ CPPUNIT_ASSERT_MESSAGE("Testing wheter original and clone are at the same position", clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer()));
+ CPPUNIT_ASSERT_MESSAGE(" Asserting that origin is on the plane cloned plane:", clonedplanegeometry2->IsOnPlane(origin));
- std::cout << "Testing GetAxisVector() of backsidedly, axially initialized version: ";
- if((mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), -bottom, testEps)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), -normal, testEps)==false))
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ mitk::VnlVector newaxis(3);
+ mitk::FillVector3D(newaxis, 1.0, 1.0, 1.0); newaxis.normalize();
+ vnl_quaternion<mitk::ScalarType> rotation2(newaxis, 0.0);
+
+ mitk::Vector3D clonednormal = clonedplanegeometry2->GetNormal();
+ mitk::Point3D clonedorigin = clonedplanegeometry2->GetOrigin();
+
+ mitk::RotationOperation* planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 180.0 );
+
+ clonedplanegeometry2->ExecuteOperation( planerot );
+ CPPUNIT_ASSERT_MESSAGE(" Asserting that a flipped plane is still on the original plane: ", clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer()));
+
+ clonedorigin += clonednormal;
+ clonedplanegeometry2->SetOrigin( clonedorigin );
+
+ CPPUNIT_ASSERT_MESSAGE("Testing if the translated (cloned, flipped) plane is parallel to its origin plane: ", clonedplanegeometry2->IsParallel(planegeometry));
+ delete planerot;
+
+ planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 0.5 );
+ clonedplanegeometry2->ExecuteOperation( planerot );
+
+ CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as not paralell [rotation +0.5 degree] : ", ! clonedplanegeometry2->IsParallel(planegeometry));
+ delete planerot;
+
+ planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), -1.0 );
+ clonedplanegeometry2->ExecuteOperation( planerot );
+
+ CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as not paralell [rotation -0.5 degree] : ", ! clonedplanegeometry2->IsParallel(planegeometry));
+ delete planerot;
- result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, backsideorigin, right, -bottom);
- if(result!=EXIT_SUCCESS)
- return result;
+ planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 360.5 );
+ clonedplanegeometry2->ExecuteOperation( planerot );
- return EXIT_SUCCESS;
+ CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as paralell [rotation 360 degree] : ", clonedplanegeometry2->IsParallel(planegeometry));
}
private:
// helper Methods for the Tests
mitk::PlaneGeometry::Pointer createPlaneGeometry()
{
mitk::Vector3D mySpacing;
mySpacing[0] = 31;
mySpacing[1] = 0.1;
mySpacing[2] = 5.4;
mitk::Point3D myOrigin;
myOrigin[0] = 8;
myOrigin[1] = 9;
myOrigin[2] = 10;
mitk::AffineTransform3D::Pointer myTransform = mitk::AffineTransform3D::New();
itk::Matrix<mitk::ScalarType, 3,3> transMatrix;
transMatrix.Fill(0);
transMatrix[0][0] = 1;
transMatrix[1][1] = 2;
transMatrix[2][2] = 4;
myTransform->SetMatrix(transMatrix);
mitk::PlaneGeometry::Pointer geometry2D = mitk::PlaneGeometry::New();
geometry2D->SetIndexToWorldTransform(myTransform);
geometry2D->SetSpacing(mySpacing);
geometry2D->SetOrigin(myOrigin);
return geometry2D;
}
bool compareMatrix(itk::Matrix<mitk::ScalarType, 3,3> left, itk::Matrix<mitk::ScalarType, 3,3> right)
{
bool equal = true;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
equal &= mitk::Equal(left[i][j], right[i][j]);
return equal;
}
- int mappingTests2D(const mitk::PlaneGeometry* planegeometry, const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::Point3D& origin, const mitk::Vector3D& right, const mitk::Vector3D& bottom)
+ /**
+ * This function tests for correct mapping and is called several times from other tests
+ **/
+ void mappingTests2D(const mitk::PlaneGeometry* planegeometry, const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::Point3D& origin, const mitk::Vector3D& right, const mitk::Vector3D& bottom)
{
std::cout << "Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected: ";
mitk::Point2D pt2d_mm;
mitk::Point3D pt3d_mm, expected_pt3d_mm;
pt2d_mm[0] = widthInMM/2.3; pt2d_mm[1] = heightInMM/2.5;
expected_pt3d_mm = origin+right*(pt2d_mm[0]/right.GetNorm())+bottom*(pt2d_mm[1]/bottom.GetNorm());
planegeometry->Map(pt2d_mm, pt3d_mm);
- if(mitk::Equal(pt3d_mm, expected_pt3d_mm, testEps) == false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected", mitk::Equal(pt3d_mm, expected_pt3d_mm, testEps));
std::cout << "Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected: ";
mitk::Point2D testpt2d_mm;
planegeometry->Map(pt3d_mm, testpt2d_mm);
std::cout << std::setprecision(12) << "Expected pt2d_mm " << pt2d_mm << std::endl;
std::cout << std::setprecision(12) << "Result testpt2d_mm " << testpt2d_mm << std::endl;
std::cout << std::setprecision(12) << "10*mitk::eps " << 10*mitk::eps << std::endl;
//This eps is temporarily set to 10*mitk::eps. See bug #15037 for details.
- if(mitk::Equal(pt2d_mm, testpt2d_mm, 10*mitk::eps) == false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected", mitk::Equal(pt2d_mm, testpt2d_mm, 10*mitk::eps));
std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
mitk::Point2D pt2d_units;
pt2d_units[0] = width/2.0; pt2d_units[1] = height/2.0;
pt2d_mm[0] = widthInMM/2.0; pt2d_mm[1] = heightInMM/2.0;
planegeometry->IndexToWorld(pt2d_units, testpt2d_mm);
-
std::cout << std::setprecision(12) << "Expected pt2d_mm " << pt2d_mm << std::endl;
std::cout << std::setprecision(12) << "Result testpt2d_mm " << testpt2d_mm << std::endl;
std::cout << std::setprecision(12) << "10*mitk::eps " << 10*mitk::eps << std::endl;
//This eps is temporarily set to 10*mitk::eps. See bug #15037 for details.
- if(mitk::Equal(pt2d_mm, testpt2d_mm, 10*mitk::eps) == false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ", mitk::Equal(pt2d_mm, testpt2d_mm, 10*mitk::eps));
std::cout << "Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected: ";
mitk::Point2D testpt2d_units;
planegeometry->WorldToIndex(pt2d_mm, testpt2d_units);
std::cout << std::setprecision(12) << "Expected pt2d_units " << pt2d_units << std::endl;
std::cout << std::setprecision(12) << "Result testpt2d_units " << testpt2d_units << std::endl;
std::cout << std::setprecision(12) << "10*mitk::eps " << 10*mitk::eps << std::endl;
//This eps is temporarily set to 10*mitk::eps. See bug #15037 for details.
- if(mitk::Equal(pt2d_units, testpt2d_units, 10*mitk::eps) == false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- return EXIT_SUCCESS;
+ CPPUNIT_ASSERT_MESSAGE("Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected:", mitk::Equal(pt2d_units, testpt2d_units, 10*mitk::eps));
}
};
MITK_TEST_SUITE_REGISTRATION(mitkPlaneGeometry)
\ No newline at end of file
diff --git a/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp b/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp
index fe9f325a1b..119a63a5df 100644
--- a/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp
+++ b/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp
@@ -1,95 +1,184 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkTestingConfig.h>
#include <mitkTestFixture.h>
#include <mitkIOUtil.h>
#include <mitkInteractionTestHelper.h>
#include <mitkPointSet.h>
#include <mitkPointSetDataInteractor.h>
+#include <vtkDebugLeaks.h>
class mitkPointSetDataInteractorTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkPointSetDataInteractorTestSuite);
+
+ /// \todo Fix VTK memory leaks. Bug 18144.
+ vtkDebugLeaks::SetExitError(0);
+
MITK_TEST(AddPointInteraction);
+ MITK_TEST(DeletePointInteraction);
CPPUNIT_TEST_SUITE_END();
private:
mitk::DataNode::Pointer m_TestPointSetNode;
mitk::PointSetDataInteractor::Pointer m_DataInteractor;
mitk::PointSet::Pointer m_TestPointSet;
public:
void setUp()
{
//Create DataNode as a container for our PointSet to be tested
m_TestPointSetNode = mitk::DataNode::New();
// Create PointSetData Interactor
m_DataInteractor = mitk::PointSetDataInteractor::New();
// Load the according state machine for regular point set interaction
m_DataInteractor->LoadStateMachine("PointSet.xml");
// Set the configuration file that defines the triggers for the transitions
m_DataInteractor->SetEventConfig("PointSetConfig.xml");
//Create new PointSet which will receive the interaction input
m_TestPointSet = mitk::PointSet::New();
m_TestPointSetNode->SetData(m_TestPointSet);
// set the DataNode (which already is added to the DataStorage)
m_DataInteractor->SetDataNode(m_TestPointSetNode);
}
void tearDown()
{
//destroy all objects
+ m_TestPointSetNode->SetDataInteractor(NULL);
m_TestPointSetNode = NULL;
m_TestPointSet = NULL;
m_DataInteractor = NULL;
}
void AddPointInteraction()
{
//Path to the reference PointSet
std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/PointSetDataInteractor_add_points_in_2D_ref.mps");
//Path to the interaction xml file
std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PointSetDataInteractor_add_points_in_2D.xml");
//Create test helper to initialize all necessary objects for interaction
mitk::InteractionTestHelper interactionTestHelper(interactionXmlPath);
//Add our test node to the DataStorage of our test helper
interactionTestHelper.AddNodeToStorage(m_TestPointSetNode);
//Start Interaction
interactionTestHelper.PlaybackInteraction();
//Load the reference PointSet
mitk::PointSet::Pointer referencePointSet = mitk::IOUtil::LoadPointSet(referencePointSetPath);
//Compare reference with the result of the interaction
MITK_ASSERT_EQUAL(m_TestPointSet, referencePointSet, "");
}
+ void PlayInteraction( std::string &xmlFile, mitk::DataNode* node )
+ {
+ mitk::InteractionTestHelper interactionTestHelper( xmlFile );
+ interactionTestHelper.AddNodeToStorage( node );
+ interactionTestHelper.PlaybackInteraction();
+ }
+
+ void EvaluateState( std::string &refPsFile, mitk::PointSet::Pointer ps, int selected )
+ {
+ mitk::PointSet::Pointer refPs = mitk::IOUtil::LoadPointSet( refPsFile );
+ refPs->UpdateOutputInformation();
+ ps->UpdateOutputInformation();
+
+ MITK_ASSERT_EQUAL(ps, refPs, "");
+
+ MITK_TEST_CONDITION_REQUIRED(true, "Test against reference point set." );
+ MITK_TEST_CONDITION_REQUIRED(ps->GetNumberOfSelected() == 1, "One selected point." );
+ MITK_TEST_CONDITION_REQUIRED(ps->GetSelectInfo( selected ) , "Testing if proper point is selected." );
+ }
+
+ void SetupInteractor( mitk::PointSetDataInteractor* dataInteractor, mitk::DataNode* node )
+ {
+ dataInteractor->LoadStateMachine("PointSet.xml");
+ dataInteractor->SetEventConfig("PointSetConfig.xml");
+ dataInteractor->SetDataNode( node );
+ }
+
+ void DeletePointInteraction()
+ {
+ mitk::PointSetDataInteractor::Pointer dataInteractor = mitk::PointSetDataInteractor::New();
+ mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New();
+
+ //Path to the reference PointSet
+ std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/InputData/InitPointSet.mps");
+ mitk::PointSet::Pointer ps = mitk::IOUtil::LoadPointSet( referencePointSetPath );
+ pointSetNode->SetData( ps );
+
+ this->SetupInteractor( dataInteractor, pointSetNode );
+
+ std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-0_1.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-0.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 1 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-1_3.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-1.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 1 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-2_4.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-2.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 1 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-3_8.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-3.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 1 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-4_2.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-4.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 4 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-5_6.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-5.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 4 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-6_7.xml");
+ referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-6.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+ EvaluateState( referencePointSetPath, ps, 4 );
+
+ interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-7_5.xml");
+ //referencePointSetPath = GetTestDataFilePath("InteractionTestData/PointSet1.mps");
+ PlayInteraction( interactionXmlPath, pointSetNode );
+
+ MITK_TEST_CONDITION_REQUIRED(ps->GetPointSet()->GetNumberOfPoints() == 0, "Empty point set check.");
+ MITK_TEST_CONDITION_REQUIRED(ps->GetNumberOfSelected() == 0, "No selected points." );
+ }
+
};
MITK_TEST_SUITE_REGISTRATION(mitkPointSetDataInteractor)
diff --git a/Core/Code/Testing/mitkProgressBarTest.cpp b/Core/Code/Testing/mitkProgressBarTest.cpp
new file mode 100644
index 0000000000..5cec7687c0
--- /dev/null
+++ b/Core/Code/Testing/mitkProgressBarTest.cpp
@@ -0,0 +1,37 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkTestingMacros.h>
+#include <mitkTestingConfig.h>
+#include <mitkTestFixture.h>
+#include <mitkProgressBar.h>
+
+class mitkProgressBarTestSuite : public mitk::TestFixture
+{
+ CPPUNIT_TEST_SUITE(mitkProgressBarTestSuite);
+ MITK_TEST(TestInstantiation);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void TestInstantiation()
+ {
+ mitk::ProgressBar::Pointer pb = mitk::ProgressBar::GetInstance();
+ CPPUNIT_ASSERT_MESSAGE("Single instance can be created on demand", pb.IsNotNull());
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkProgressBar)
diff --git a/Core/Code/Testing/mitkProportionalTimeGeometryTest.cpp b/Core/Code/Testing/mitkProportionalTimeGeometryTest.cpp
new file mode 100644
index 0000000000..97a2805040
--- /dev/null
+++ b/Core/Code/Testing/mitkProportionalTimeGeometryTest.cpp
@@ -0,0 +1,112 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkProportionalTimeGeometry.h"
+#include "mitkGeometry3D.h"
+#include "mitkThinPlateSplineCurvedGeometry.h"
+#include "mitkSlicedGeometry3D.h"
+
+#include <mitkTestingMacros.h>
+#include <mitkTestFixture.h>
+
+
+class mitkProportionalTimeGeometryTestSuite : public mitk::TestFixture
+{
+ CPPUNIT_TEST_SUITE(mitkProportionalTimeGeometryTestSuite);
+ MITK_TEST(TestInheritance);
+ MITK_TEST(TestProportionalTimeGeometryCloning);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // This test is supposed to verify inheritance behaviour, this test will fail if the behaviour changes in the future
+ void TestInheritance()
+ {
+ mitk::ProportionalTimeGeometry::Pointer ptGeom = mitk::ProportionalTimeGeometry::New();
+ mitk::Geometry3D::Pointer g3d = dynamic_cast < mitk::Geometry3D* > ( ptGeom.GetPointer() );
+ CPPUNIT_ASSERT_MESSAGE("ProportionalTimeGeometry should not be castable to Geometry3D", g3d.IsNull());
+
+ mitk::TimeGeometry::Pointer base = dynamic_cast < mitk::TimeGeometry* > ( ptGeom.GetPointer() );
+ CPPUNIT_ASSERT_MESSAGE("ProportionalTimeGeometry should be castable to TimeGeometry", base.IsNotNull());
+ }
+
+
+ void TestProportionalTimeGeometryCloning()
+ {
+ mitk::ProportionalTimeGeometry::Pointer geom = CreateProportionalTimeGeometry();
+
+ mitk::ProportionalTimeGeometry::Pointer clone = geom->Clone();
+ CPPUNIT_ASSERT_MESSAGE("First time point of clone matches original",
+ clone->GetFirstTimePoint() == 1.1);
+ CPPUNIT_ASSERT_MESSAGE("Step duration of clone matches original",
+ clone->GetStepDuration() == 2.2);
+
+ mitk::PlaneGeometry *planeGeom = dynamic_cast<mitk::PlaneGeometry*>(clone->GetGeometryForTimeStep(0).GetPointer());
+ itk::Matrix<mitk::ScalarType,3,3> matrix = planeGeom->GetIndexToWorldTransform()->GetMatrix();
+ CPPUNIT_ASSERT_MESSAGE("Matrix element [0][0] of clone matches original", matrix[0][0] == 31);
+
+ double origin = planeGeom->GetOrigin()[0];
+ CPPUNIT_ASSERT_MESSAGE("First Point of origin of clone matches original", mitk::Equal(origin, 8));
+
+ double spacing = planeGeom->GetSpacing()[0];
+ CPPUNIT_ASSERT_MESSAGE("First Point of spacing of clone matches original", mitk::Equal(spacing, 31));
+ }
+
+private:
+ // helper Methods for the Tests
+
+ mitk::ProportionalTimeGeometry::Pointer CreateProportionalTimeGeometry()
+ {
+ mitk::Vector3D mySpacing;
+ mySpacing[0] = 31;
+ mySpacing[1] = 0.1;
+ mySpacing[2] = 5.4;
+ mitk::Point3D myOrigin;
+ myOrigin[0] = 8;
+ myOrigin[1] = 9;
+ myOrigin[2] = 10;
+ mitk::AffineTransform3D::Pointer myTransform = mitk::AffineTransform3D::New();
+ itk::Matrix<mitk::ScalarType, 3,3> transMatrix;
+ transMatrix.Fill(0);
+ transMatrix[0][0] = 1;
+ transMatrix[1][1] = 2;
+ transMatrix[2][2] = 4;
+
+ myTransform->SetMatrix(transMatrix);
+
+ mitk::PlaneGeometry::Pointer geom2D = mitk::PlaneGeometry::New();
+ geom2D->SetIndexToWorldTransform(myTransform);
+ geom2D->SetSpacing(mySpacing);
+ geom2D->SetOrigin(myOrigin);
+
+ mitk::ProportionalTimeGeometry::Pointer geom = mitk::ProportionalTimeGeometry::New();
+ geom->SetFirstTimePoint(1.1);
+ geom->SetStepDuration(2.2);
+ geom->SetTimeStepGeometry(geom2D, 0);
+
+ return geom;
+ }
+
+};
+MITK_TEST_SUITE_REGISTRATION(mitkProportionalTimeGeometry)
diff --git a/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp b/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp
index 70e327d5d5..2f8b17e6c4 100644
--- a/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp
+++ b/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp
@@ -1,172 +1,174 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTestingMacros.h"
#include <vtkMitkThickSlicesFilter.h>
#include "mitkImageWriteAccessor.h"
#include "mitkImage.h"
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkDataArray.h>
class vtkMitkThickSlicesFilterTestHelper
{
public:
static mitk::Image::Pointer CreateTestImage( int min, int max )
{
mitk::PixelType pixelType( mitk::MakeScalarPixelType<unsigned char>() );
mitk::Image::Pointer testImage = mitk::Image::New();
unsigned int* dim = new unsigned int[3];
dim[0] = 10;
dim[1] = 10;
dim[2] = max+1-min;
testImage->Initialize( pixelType, 3, dim );
size_t buffer_size = dim[0] * dim[1] * sizeof(unsigned char);
for( int i=min; i<=max; ++i )
{
mitk::ImageWriteAccessor writeAccess( testImage, testImage->GetSliceData( i-min ) );
memset( writeAccess.GetData(), i, buffer_size );
}
return testImage;
}
static void EvaluateResult( unsigned char expectedValue, vtkImageData* image, const char* projection )
{
MITK_TEST_CONDITION_REQUIRED( image->GetDimensions()[0] == 10
&& image->GetDimensions()[1] == 10
&& image->GetDimensions()[2] == 1,
"Resulting image has correct size" );
unsigned char* value = static_cast<unsigned char*>( image->GetScalarPointer(0,0,0) );
MITK_INFO << "Evaluating projection mode: " << projection;
MITK_INFO << "expected value: " << static_cast<double>( expectedValue );
MITK_INFO << "actual value: " << static_cast<double>( value[0] );
MITK_TEST_CONDITION_REQUIRED( value[0] == expectedValue,
"Resulting image has correct pixel-value" );
}
};
/**
* Test for vtkMitkThickSlicesFilter.
*
*/
-int vtkMitkThickSlicesFilterTest(int argc, char** const argv)
+int vtkMitkThickSlicesFilterTest(int, char* [])
{
// always start with this!
MITK_TEST_BEGIN("vtkMitkThickSlicesFilterTest")
vtkMitkThickSlicesFilter* thickSliceFilter = vtkMitkThickSlicesFilter::New();
//////////////////////////////////////////////////////////////////////////
// Image looks like:
// 000000000
// 111111111
// 222222222
mitk::Image::Pointer testImage1 = vtkMitkThickSlicesFilterTestHelper::CreateTestImage( 0, 2 );
thickSliceFilter->SetInputData( testImage1->GetVtkImageData() );
// MaxIP
thickSliceFilter->SetThickSliceMode( 0 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 2, thickSliceFilter->GetOutput(), "MaxIP" );
// Sum
thickSliceFilter->SetThickSliceMode( 1 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 1, thickSliceFilter->GetOutput(), "Sum" );
// Weighted
thickSliceFilter->SetThickSliceMode( 2 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 1, thickSliceFilter->GetOutput(), "Weighted" );
// MinIP
thickSliceFilter->SetThickSliceMode( 3 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 0, thickSliceFilter->GetOutput(), "MinIP" );
// Mean
thickSliceFilter->SetThickSliceMode( 4 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 1, thickSliceFilter->GetOutput(), "Mean" );
//////////////////////////////////////////////////////////////////////////
// Image looks like:
// 333333333
// 444444444
// 555555555
// 666666666
// 777777777
// 888888888
mitk::Image::Pointer testImage2 = vtkMitkThickSlicesFilterTestHelper::CreateTestImage( 3, 8 );
thickSliceFilter->SetInputData( testImage2->GetVtkImageData() );
// MaxIP
thickSliceFilter->SetThickSliceMode( 0 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 8, thickSliceFilter->GetOutput(), "MaxIP" );
// Sum
thickSliceFilter->SetThickSliceMode( 1 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 5, thickSliceFilter->GetOutput(), "Sum" );
// Weighted
thickSliceFilter->SetThickSliceMode( 2 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 4, thickSliceFilter->GetOutput(), "Weighted" );
// MinIP
thickSliceFilter->SetThickSliceMode( 3 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 3, thickSliceFilter->GetOutput(), "MinIP" );
// Mean
thickSliceFilter->SetThickSliceMode( 4 );
thickSliceFilter->Modified();
thickSliceFilter->Update();
vtkMitkThickSlicesFilterTestHelper::EvaluateResult( 6, thickSliceFilter->GetOutput(), "Mean" );
+ thickSliceFilter->Delete();
+
MITK_TEST_END()
}
diff --git a/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp b/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp
index 1e8759440f..d2c65d5136 100644
--- a/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp
+++ b/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp
@@ -1,220 +1,242 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//MITK
#include <mitkInteractionTestHelper.h>
#include <mitkStandaloneDataStorage.h>
#include <mitkGlobalInteraction.h>
#include <mitkIOUtil.h>
#include <mitkInteractionEventConst.h>
//us
#include <usGetModuleContext.h>
#include <tinyxml.h>
mitk::InteractionTestHelper::InteractionTestHelper(const std::string &interactionXmlFilePath)
: m_InteractionFilePath(interactionXmlFilePath)
{
this->Initialize(interactionXmlFilePath);
}
void mitk::InteractionTestHelper::Initialize(const std::string &interactionXmlFilePath)
{
//TiXmlDocument document(interactionXmlPath.c_str());
TiXmlDocument document(interactionXmlFilePath);
bool loadOkay = document.LoadFile();
if (loadOkay)
{
// Global interaction must(!) be initialized
if(! mitk::GlobalInteraction::GetInstance()->IsInitialized())
mitk::GlobalInteraction::GetInstance()->Initialize("global");
//get RenderingManager instance
mitk::RenderingManager* rm = mitk::RenderingManager::GetInstance();
//create data storage
m_DataStorage = mitk::StandaloneDataStorage::New();
//for each renderer found create a render window and configure
for( TiXmlElement* element = document.FirstChildElement(mitk::InteractionEventConst::xmlTagInteractions())->FirstChildElement(mitk::InteractionEventConst::xmlTagConfigRoot())->FirstChildElement(mitk::InteractionEventConst::xmlTagRenderer());
element != NULL;
element = element->NextSiblingElement(mitk::InteractionEventConst::xmlTagRenderer()) )
{
//get name of renderer
const char* rendererName = element->Attribute(mitk::InteractionEventConst::xmlEventPropertyRendererName().c_str());
//get view direction
mitk::SliceNavigationController::ViewDirection viewDirection = mitk::SliceNavigationController::Axial;
if(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection()) != NULL)
{
int viewDirectionNum = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection())->c_str());
viewDirection = static_cast<mitk::SliceNavigationController::ViewDirection>(viewDirectionNum);
}
//get mapper slot id
mitk::BaseRenderer::MapperSlotId mapperID = mitk::BaseRenderer::Standard2D;
if(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID()) != NULL)
{
int mapperIDNum = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID())->c_str());
mapperID = static_cast<mitk::BaseRenderer::MapperSlotId>(mapperIDNum);
}
+
+ // Get Size of Render Windows
+ int size[3];
+ size[0]=size[1]=size[2]=0;
+ if(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeX()) != NULL)
+ {
+ size[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeX())->c_str());
+ }
+ if(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeY()) != NULL)
+ {
+ size[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeY())->c_str());
+ }
+ if(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeZ()) != NULL)
+ {
+ size[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeZ())->c_str());
+ }
+
//create renderWindow, renderer and dispatcher
mitk::RenderWindow::Pointer rw = mitk::RenderWindow::New(NULL, rendererName, rm); //VtkRenderWindow is created within constructor if NULL
+ if (size[0] != 0 && size[1] != 0)
+ rw->SetSize(size[0],size[1]);
+
//set storage of renderer
rw->GetRenderer()->SetDataStorage(m_DataStorage);
//set view direction to axial
rw->GetSliceNavigationController()->SetDefaultViewDirection( viewDirection );
//set renderer to render 2D
rw->GetRenderer()->SetMapperID(mapperID);
//connect SliceNavigationControllers to timestep changed event of TimeNavigationController
rw->GetSliceNavigationController()->ConnectGeometryTimeEvent(rm->GetTimeNavigationController(), false);
rm->GetTimeNavigationController()->ConnectGeometryTimeEvent(rw->GetSliceNavigationController(), false);
//add to list of kown render windows
m_RenderWindowList.push_back(rw);
}
//TODO: check the following lines taken from QmitkStdMultiWidget and adapt them to be executed in our code here.
// mitkWidget1->GetSliceNavigationController()
// ->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
//########### register display interactor to handle scroll events ##################
//use MouseModeSwitcher to ensure that the statemachine of DisplayInteractor is loaded correctly
m_MouseModeSwitcher = mitk::MouseModeSwitcher::New();
}
else
{
mitkThrow() << "Can not load interaction xml file <" << m_InteractionFilePath << ">";
}
}
mitk::InteractionTestHelper::~InteractionTestHelper()
{
mitk::RenderingManager* rm = mitk::RenderingManager::GetInstance();
//unregister renderers
InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
for(; it != end; it++)
{
rm->GetTimeNavigationController()->Disconnect((*it)->GetSliceNavigationController());
(*it)->GetSliceNavigationController()->Disconnect(rm->GetTimeNavigationController());
mitk::BaseRenderer::RemoveInstance((*it)->GetVtkRenderWindow());
}
rm->RemoveAllObservers();
}
mitk::DataStorage::Pointer mitk::InteractionTestHelper::GetDataStorage()
{
return m_DataStorage;
}
void mitk::InteractionTestHelper::AddNodeToStorage(mitk::DataNode::Pointer node)
{
this->m_DataStorage->Add(node);
mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage);
}
void mitk::InteractionTestHelper::PlaybackInteraction()
{
//load events if not loaded yet
if(m_Events.empty())
this->LoadInteraction();
//playback all events in queue
for (unsigned long i=0; i < m_Events.size(); ++i)
{
//let dispatcher of sending renderer process the event
m_Events.at(i)->GetSender()->GetDispatcher()->ProcessEvent(m_Events.at(i));
}
}
void mitk::InteractionTestHelper::LoadInteraction()
{
//load interaction pattern from xml file
std::ifstream xmlStream(m_InteractionFilePath.c_str());
mitk::XML2EventParser parser(xmlStream);
m_Events = parser.GetInteractions();
xmlStream.close();
+ // Avoid VTK warning: Trying to delete object with non-zero reference count.
+ parser.SetReferenceCount(0);
}
void mitk::InteractionTestHelper::SetTimeStep(int newTimeStep)
{
bool timeStepIsvalid = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetCreatedWorldGeometry()->IsValidTimeStep(newTimeStep);
if(timeStepIsvalid)
{
mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->SetPos(newTimeStep);
}
}
mitk::RenderWindow* mitk::InteractionTestHelper::GetRenderWindowByName(const std::string &name)
{
InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
for(; it != end; it++)
{
if( name.compare( (*it)->GetRenderer()->GetName() ) == 0)
return (*it).GetPointer();
}
return NULL;
}
mitk::RenderWindow* mitk::InteractionTestHelper::GetRenderWindowByDefaultViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection)
{
InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
for(; it != end; it++)
{
if( viewDirection == (*it)->GetSliceNavigationController()->GetDefaultViewDirection() )
return (*it).GetPointer();
}
return NULL;
}
mitk::RenderWindow* mitk::InteractionTestHelper::GetRenderWindow(unsigned int index)
{
if( index < m_RenderWindowList.size() )
{
return m_RenderWindowList.at(index).GetPointer();
}
else
{
return NULL;
}
}
diff --git a/Core/Code/TestingHelper/mitkRenderingTestHelper.cpp b/Core/Code/TestingHelper/mitkRenderingTestHelper.cpp
index 31a94c8271..acfcd9909a 100644
--- a/Core/Code/TestingHelper/mitkRenderingTestHelper.cpp
+++ b/Core/Code/TestingHelper/mitkRenderingTestHelper.cpp
@@ -1,305 +1,305 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//VTK
#include <vtkRenderWindow.h>
#include <vtkPNGWriter.h>
#include <vtkRenderLargeImage.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
//MITK
#include <mitkRenderingTestHelper.h>
#include <mitkStandaloneDataStorage.h>
#include <mitkRenderWindow.h>
#include <mitkGlobalInteraction.h>
#include <mitkSliceNavigationController.h>
#include <mitkNodePredicateDataType.h>
#include <mitkIOUtil.h>
// include gl to read out properties
#include <vtkOpenGL.h>
#include <vtkOpenGLExtensionManager.h>
#if defined _MSC_VER
#if _MSC_VER >= 1700
#define RESIZE_WORKAROUND
#endif
#endif
#ifdef RESIZE_WORKAROUND
#include "vtkWin32OpenGLRenderWindow.h"
#endif
//VTK Testing to compare the rendered image pixel-wise against a reference screen shot
#include "vtkTesting.h"
mitk::RenderingTestHelper::RenderingTestHelper(int width, int height, mitk::BaseRenderer::RenderingMode::Type renderingMode)
: m_AutomaticallyCloseRenderWindow(true)
{
this->Initialize(width, height, renderingMode );
}
mitk::RenderingTestHelper::RenderingTestHelper(int width, int height, int argc, char* argv[], mitk::BaseRenderer::RenderingMode::Type renderingMode)
: m_AutomaticallyCloseRenderWindow(true)
{
this->Initialize(width, height, renderingMode);
this->SetInputFileNames(argc, argv);
}
void mitk::RenderingTestHelper::Initialize(int width, int height, mitk::BaseRenderer::RenderingMode::Type renderingMode)
{
// Global interaction must(!) be initialized
mitk::GlobalInteraction::GetInstance()->Initialize("global");
m_RenderWindow = mitk::RenderWindow::New(NULL ,"unnamed renderer" , NULL, renderingMode);
m_DataStorage = mitk::StandaloneDataStorage::New();
m_RenderWindow->GetRenderer()->SetDataStorage(m_DataStorage);
this->SetMapperIDToRender2D();
this->GetVtkRenderWindow()->SetSize( width, height );
#ifdef RESIZE_WORKAROUND
HWND hWnd = static_cast<vtkWin32OpenGLRenderWindow*>(this->GetVtkRenderWindow())->GetWindowId();
RECT r;
r.left = 10;
r.top = 10;
r.right = r.left + width;
r.bottom = r.top + height;
LONG style = GetWindowLong(hWnd, GWL_STYLE);
AdjustWindowRect( &r, style, FALSE );
MITK_INFO << "WANTED:";
MITK_INFO << r.right-r.left;
MITK_INFO << r.bottom-r.top;
RECT rect;
if(GetWindowRect(hWnd, &rect))
{
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
MITK_INFO << "ACTUAL:";
MITK_INFO << width;
MITK_INFO <<height;
}
SetWindowPos( hWnd
, HWND_TOP, 0, 0, r.right-r.left, r.bottom-r.top,
SWP_NOZORDER);
GetWindowRect(hWnd, &rect);
int width2 = rect.right - rect.left;
int height2 = rect.bottom - rect.top;
MITK_INFO << "ACTUAL2:";
MITK_INFO << width2;
MITK_INFO << height2;
SetWindowPos( hWnd
, HWND_TOP, 0, 0, 2*(r.right-r.left) - width2 ,2*(r.bottom-r.top) - height2,
SWP_NOZORDER);
#endif
m_RenderWindow->GetRenderer()->Resize( width, height);
//Prints the glinfo after creation of the vtkrenderwindow, we always want to do this for debugging.
this->PrintGLInfo();
}
mitk::RenderingTestHelper::~RenderingTestHelper()
{
}
bool mitk::RenderingTestHelper::IsAdvancedOpenGL()
{
const GLubyte *version = glGetString(GL_VERSION);
if(!version)
return false;
return *version >= '2';
}
void mitk::RenderingTestHelper::PrintGLInfo()
{
GLint maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);;
MITK_INFO << "OpenGL Render Context Information: \n"
<< "- GL_VENDOR: "<< glGetString(GL_VENDOR) << "\n"
<< "- GL_RENDERER: "<< glGetString(GL_RENDERER) << "\n"
<< "- GL_VERSION: "<< glGetString(GL_VERSION) << "\n"
<< "- GL_MAX_TEXTURE_SIZE: "<< maxTextureSize << "\n"
<< "- GL_EXTENSIONS: "<< glGetString(GL_EXTENSIONS);
}
void mitk::RenderingTestHelper::SetMapperID( mitk::BaseRenderer::StandardMapperSlot id)
{
m_RenderWindow->GetRenderer()->SetMapperID(id);
}
void mitk::RenderingTestHelper::SetMapperIDToRender3D()
{
this->SetMapperID(mitk::BaseRenderer::Standard3D);
mitk::RenderingManager::GetInstance()->InitializeViews( this->GetDataStorage()->ComputeBoundingGeometry3D( this->GetDataStorage()->GetAll() ) );
}
void mitk::RenderingTestHelper::SetMapperIDToRender2D()
{
this->SetMapperID(mitk::BaseRenderer::Standard2D);
}
void mitk::RenderingTestHelper::Render()
{
//if the datastorage is initialized and at least 1 image is loaded render it
if(m_DataStorage.IsNotNull() || m_DataStorage->GetAll()->Size() >= 1 )
{
//Prepare the VTK camera before rendering.
m_RenderWindow->GetRenderer()->PrepareRender();
this->GetVtkRenderWindow()->Render();
if(m_AutomaticallyCloseRenderWindow == false)
{
//Use interaction to stop the test
this->GetVtkRenderWindow()->GetInteractor()->Start();
}
}
else
{
MITK_ERROR << "No images loaded in data storage!";
}
}
mitk::DataStorage::Pointer mitk::RenderingTestHelper::GetDataStorage()
{
return m_DataStorage;
}
void mitk::RenderingTestHelper::SetInputFileNames(int argc, char* argv[])
{
//i is set 1, because 0 is the testname as string
//parse parameters
for (int i = 1; i < argc; ++i)
{
//add everything to a list but -T and -V
std::string tmp = argv[i];
if((tmp.compare("-T")) && (tmp.compare("-V")))
{
this->AddToStorage(tmp);
}
else
{
break;
}
}
}
void mitk::RenderingTestHelper::SetViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection)
{
mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController()->SetDefaultViewDirection(viewDirection);
mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()) );
}
void mitk::RenderingTestHelper::ReorientSlices(mitk::Point3D origin, mitk::Vector3D rotation)
{
mitk::SliceNavigationController::Pointer sliceNavigationController =
mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController();
sliceNavigationController->ReorientSlices(origin, rotation);
}
vtkRenderer* mitk::RenderingTestHelper::GetVtkRenderer()
{
return m_RenderWindow->GetRenderer()->GetVtkRenderer();
}
void mitk::RenderingTestHelper::SetImageProperty(const char *propertyKey, mitk::BaseProperty* property )
{
this->m_DataStorage->GetNode(mitk::NodePredicateDataType::New("Image"))->SetProperty(propertyKey, property);
}
vtkRenderWindow* mitk::RenderingTestHelper::GetVtkRenderWindow()
{
return m_RenderWindow->GetVtkRenderWindow();
}
bool mitk::RenderingTestHelper::CompareRenderWindowAgainstReference(int argc, char* argv[], double threshold)
{
this->Render();
-
+ m_RenderWindow->GetRenderer()->ForceImmediateUpdate();
//retVal meanings: (see VTK/Rendering/vtkTesting.h)
//0 = test failed
//1 = test passed
//2 = test not run
//3 = something with vtkInteraction
if(vtkTesting::Test(argc, argv, this->GetVtkRenderWindow(), threshold) == 1)
return true;
else
return false;
}
//method to save a screenshot of the renderwindow (e.g. create a reference screenshot)
void mitk::RenderingTestHelper::SaveAsPNG(std::string fileName)
{
vtkSmartPointer<vtkRenderer> renderer = this->GetVtkRenderer();
bool doubleBuffering( renderer->GetRenderWindow()->GetDoubleBuffer() );
renderer->GetRenderWindow()->DoubleBufferOff();
vtkSmartPointer<vtkRenderLargeImage> magnifier = vtkSmartPointer<vtkRenderLargeImage>::New();
magnifier->SetInput(renderer);
magnifier->SetMagnification(1);
vtkSmartPointer<vtkImageWriter> fileWriter = vtkSmartPointer<vtkPNGWriter>::New();
fileWriter->SetInputConnection(magnifier->GetOutputPort());
fileWriter->SetFileName(fileName.c_str());
fileWriter->Write();
renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering);
}
void mitk::RenderingTestHelper::SetAutomaticallyCloseRenderWindow(bool automaticallyCloseRenderWindow)
{
m_AutomaticallyCloseRenderWindow = automaticallyCloseRenderWindow;
}
void mitk::RenderingTestHelper::SaveReferenceScreenShot(std::string fileName)
{
this->SaveAsPNG(fileName);
}
void mitk::RenderingTestHelper::AddToStorage(const std::string &filename)
{
try
{
mitk::DataNode::Pointer node = mitk::IOUtil::LoadDataNode(filename);
this->AddNodeToStorage(node);
}
catch ( itk::ExceptionObject & e )
{
MITK_ERROR << "Failed loading test data '" << filename << "': " << e.what();
}
}
void mitk::RenderingTestHelper::AddNodeToStorage(mitk::DataNode::Pointer node)
{
this->m_DataStorage->Add(node);
mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()) );
-}
\ No newline at end of file
+}
diff --git a/Core/Code/TestingHelper/mitkTestingMacros.h b/Core/Code/TestingHelper/mitkTestingMacros.h
index ffa5dbd4c4..02edc5fe47 100644
--- a/Core/Code/TestingHelper/mitkTestingMacros.h
+++ b/Core/Code/TestingHelper/mitkTestingMacros.h
@@ -1,386 +1,386 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkTestingMacros_h
#define mitkTestingMacros_h
#include <exception>
#include <string>
#include <iostream>
#include <itkMacro.h>
#include <mitkTestManager.h>
#include <mitkTestCaller.h>
#include <mitkException.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/ui/text/TestRunner.h>
namespace mitk {
/** @brief Indicate a failed test. */
class TestFailedException : public std::exception {
public:
TestFailedException() {}
};
}
/**
* @brief Output some text without generating a terminating newline. Include
*
* @ingroup MITKTestingAPI
*/
#define MITK_TEST_OUTPUT_NO_ENDL(x) \
std::cout x ;
/**
* @brief Output some text.
*
* @ingroup MITKTestingAPI
*/
#define MITK_TEST_OUTPUT(x) \
MITK_TEST_OUTPUT_NO_ENDL(x << "\n")
/**
* @brief Do some general test preparations. Must be called first in the
* main test function.
*
* @deprecatedSince{2013_09} Use MITK_TEST_SUITE_REGISTRATION instead.
* @ingroup MITKTestingAPI
*/
#define MITK_TEST_BEGIN(testName) \
std::string mitkTestName(#testName); \
mitk::TestManager::GetInstance()->Initialize(); \
try {
/**
* @brief Fail and finish test with message MSG
*
* @deprecatedSince{2013_09} Use CPPUNIT_FAIL instead
* @ingroup MITKTestingAPI
*/
#define MITK_TEST_FAILED_MSG(MSG) \
MITK_TEST_OUTPUT(MSG) \
throw mitk::TestFailedException();
/**
* @brief Must be called last in the main test function.
*
* @deprecatedSince{2013_09} Use MITK_TEST_SUITE_REGISTRATION instead.
* @ingroup MITKTestingAPI
*/
#define MITK_TEST_END() \
- } catch (mitk::TestFailedException ex) { \
+ } catch (const mitk::TestFailedException&) { \
MITK_TEST_OUTPUT(<< "Further test execution skipped.") \
mitk::TestManager::GetInstance()->TestFailed(); \
- } catch (std::exception ex) { \
+ } catch (const std::exception& ex) { \
MITK_TEST_OUTPUT(<< "std::exception occured " << ex.what()) \
mitk::TestManager::GetInstance()->TestFailed(); \
} \
if (mitk::TestManager::GetInstance()->NumberOfFailedTests() > 0) { \
MITK_TEST_OUTPUT(<< mitkTestName << ": [DONE FAILED] , subtests passed: " << \
mitk::TestManager::GetInstance()->NumberOfPassedTests() << " failed: " << \
mitk::TestManager::GetInstance()->NumberOfFailedTests() ) \
return EXIT_FAILURE; \
} else { \
MITK_TEST_OUTPUT(<< mitkTestName << ": " \
<< mitk::TestManager::GetInstance()->NumberOfPassedTests() \
<< " tests [DONE PASSED]") \
return EXIT_SUCCESS; \
} \
/**
* @deprecatedSince{2013_09} Use CPPUNIT_ASSERT or CPPUNIT_ASSERT_MESSAGE instead.
*/
#define MITK_TEST_CONDITION(COND,MSG) \
MITK_TEST_OUTPUT_NO_ENDL(<< MSG) \
if ( ! (COND) ) { \
mitk::TestManager::GetInstance()->TestFailed(); \
MITK_TEST_OUTPUT(<< " [FAILED]\n" << "In " << __FILE__ \
<< ", line " << __LINE__ \
<< ": " #COND " : [FAILED]") \
} else { \
MITK_TEST_OUTPUT(<< " [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
/**
* @deprecatedSince{2013_09} Use CPPUNIT_ASSERT or CPPUNIT_ASSERT_MESSAGE instead.
*/
#define MITK_TEST_CONDITION_REQUIRED(COND,MSG) \
MITK_TEST_OUTPUT_NO_ENDL(<< MSG) \
if ( ! (COND) ) { \
MITK_TEST_FAILED_MSG(<< " [FAILED]\n" << " +--> in " << __FILE__ \
<< ", line " << __LINE__ \
<< ", expression is false: \"" #COND "\"") \
} else { \
MITK_TEST_OUTPUT(<< " [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
/**
* \brief Begin block which should be checked for exceptions
*
* @deprecatedSince{2013_09} Use CPPUNIT_ASSERT_THROW instead.
* @ingroup MITKTestingAPI
*
* This macro, together with MITK_TEST_FOR_EXCEPTION_END, can be used
* to test whether a code block throws an expected exception. The test FAILS if the
* exception is NOT thrown. A simple example:
*
MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ImageFileReaderException)
typedef itk::ImageFileReader< itk::Image<unsigned char,2> > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName("/tmp/not-existing");
reader->Update();
MITK_TEST_FOR_EXCEPTION_END(itk::ImageFileReaderException)
*
*/
#define MITK_TEST_FOR_EXCEPTION_BEGIN(EXCEPTIONCLASS) \
try {
/**
* @deprecatedSince{2013_09}
*/
#define MITK_TEST_FOR_EXCEPTION_END(EXCEPTIONCLASS) \
mitk::TestManager::GetInstance()->TestFailed(); \
MITK_TEST_OUTPUT( << "Expected an '" << #EXCEPTIONCLASS << "' exception. [FAILED]") \
} \
catch (EXCEPTIONCLASS) { \
MITK_TEST_OUTPUT( << "Caught an expected '" << #EXCEPTIONCLASS \
<< "' exception. [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
/**
* @brief Simplified version of MITK_TEST_FOR_EXCEPTION_BEGIN / END for
* a single statement
*
* @deprecatedSince{2013_09} Use CPPUNIT_ASSERT_THROW instead.
* @ingroup MITKTestingAPI
*/
#define MITK_TEST_FOR_EXCEPTION(EXCEPTIONCLASS, STATEMENT) \
MITK_TEST_FOR_EXCEPTION_BEGIN(EXCEPTIONCLASS) \
STATEMENT ; \
MITK_TEST_FOR_EXCEPTION_END(EXCEPTIONCLASS)
/**
* @brief Testing macro to test if two objects are equal.
*
* @ingroup MITKTestingAPI
*
* This macro uses mitk::eps and the corresponding mitk::Equal methods for all
* comparisons and will give verbose output on the dashboard/console.
* Feel free to implement mitk::Equal for your own datatype or purpose.
*
* @deprecatedSince{2013_09} Use MITK_ASSERT_EQUAL instead.
*
* @param OBJ1 First object.
* @param OBJ2 Second object.
* @param MSG Message to appear with the test.
*/
#define MITK_TEST_EQUAL(OBJ1,OBJ2,MSG) \
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(OBJ1, OBJ2, mitk::eps, true)==true, MSG)
/**
* @brief Testing macro to test if two objects are equal.
*
* @ingroup MITKTestingAPI
*
* This macro uses mitk::eps and the corresponding mitk::Equal methods for all
* comparisons and will give verbose output on the dashboard/console.
* Feel free to implement mitk::Equal for your own datatype or purpose.
*
* @param EXPECTED First object.
* @param ACTUAL Second object.
* @param MSG Message to appear with the test.
* @throw Throws mitkException if a NULL pointer is given as input.
*/
#define MITK_ASSERT_EQUAL(EXPECTED, ACTUAL, MSG) \
if(((EXPECTED).IsNull()) || ((ACTUAL).IsNull())) { \
mitkThrow() << "mitk::Equal does not work with NULL pointer input."; \
} \
CPPUNIT_ASSERT_MESSAGE(MSG, mitk::Equal(*(EXPECTED), *(ACTUAL), mitk::eps, true))
/**
* @brief Testing macro to test if two objects are not equal.
*
* @ingroup MITKTestingAPI
*
* This macro uses mitk::eps and the corresponding mitk::Equal methods for all
* comparisons and will give verbose output on the dashboard/console.
*
* @deprecatedSince{2013_09} Use MITK_ASSERT_NOT_EQUAL instead.
*
* @param OBJ1 First object.
* @param OBJ2 Second object.
* @param MSG Message to appear with the test.
*
* \sa MITK_TEST_EQUAL
*/
#define MITK_TEST_NOT_EQUAL(OBJ1,OBJ2,MSG) \
CPPUNIT_ASSERT_MESSAGE(MSG, !mitk::Equal(*(OBJ1), *(OBJ2), mitk::eps, true))
/**
* @brief Testing macro to test if two objects are not equal.
*
* @ingroup MITKTestingAPI
*
* This macro uses mitk::eps and the corresponding mitk::Equal methods for all
* comparisons and will give verbose output on the dashboard/console.
*
* @param OBJ1 First object.
* @param OBJ2 Second object.
* @param MSG Message to appear with the test.
* @throw Throws mitkException if a NULL pointer is given as input.
*
* \sa MITK_ASSERT_EQUAL
*/
#define MITK_ASSERT_NOT_EQUAL(OBJ1, OBJ2, MSG) \
if(((OBJ1).IsNull()) || ((OBJ2).IsNull())) { \
mitkThrow() << "mitk::Equal does not work with NULL pointer input."; \
} \
CPPUNIT_ASSERT_MESSAGE(MSG, !mitk::Equal(*(OBJ1), *(OBJ2), mitk::eps, true))
/**
* @brief Registers the given test suite.
*
* @ingroup MITKTestingAPI
*
* @param TESTSUITE_NAME The name of the test suite class, without "TestSuite"
* at the end.
*/
#define MITK_TEST_SUITE_REGISTRATION(TESTSUITE_NAME) \
int TESTSUITE_NAME ## Test(int /*argc*/, char* /*argv*/[]) \
{ \
CppUnit::TextUi::TestRunner runner; \
runner.addTest(TESTSUITE_NAME ## TestSuite::suite()); \
return runner.run() ? 0 : 1; \
}
/**
* @brief Adds a test to the current test suite.
*
* @ingroup MITKTestingAPI
*
* Use this macro after the CPPUNIT_TEST_SUITE() macro to add test cases.
* The macro internally just calls the CPPUNIT_TEST macro.
*
* @param TESTMETHOD The name of the member funtion test.
*/
#define MITK_TEST(TESTMETHOD) CPPUNIT_TEST(TESTMETHOD)
/**
* @brief Adds a parameterized test to the current test suite.
*
* @ingroup MITKTestingAPI
*
* Use this macro after the CPPUNIT_TEST_SUITE() macro to add test cases
* which need custom parameters.
*
* @param TESTMETHOD The name of the member function test.
* @param ARGS A std::vector<std::string> object containing test parameter.
*
* @note Use the macro MITK_PARAMETERIZED_TEST only if you know what
* you are doing. If you are not sure, use MITK_TEST instead.
*/
#define MITK_PARAMETERIZED_TEST(TESTMETHOD, ARGS) \
{ \
std::string testName = #TESTMETHOD; \
for (std::size_t i = 0; i < ARGS.size(); ++i) \
{ \
testName += "_" + ARGS[i]; \
} \
CPPUNIT_TEST_SUITE_ADD_TEST( \
( new mitk::TestCaller<TestFixtureType>( \
context.getTestNameFor(testName), \
&TestFixtureType::TESTMETHOD, \
context.makeFixture(), args ) ) ); \
}
/**
* @brief Adds a parameterized test to the current test suite.
*
* @ingroup MITKTestingAPI
*
* Use this macro after the CPPUNIT_TEST_SUITE() macro to add test cases
* which need parameters from the command line.
*
* @warning Use the macro MITK_PARAMETERIZED_CMD_LINE_TEST only
* if you know what you are doing. If you are not sure, use
* MITK_TEST instead. MITK_PARAMETERIZED_CMD_LINE_TEST is meant
* for migrating from ctest to CppUnit. If you implement new
* tests, the MITK_TEST macro will be sufficient.
*
* @param TESTMETHOD The name of the member function test.
*/
#define MITK_PARAMETERIZED_CMD_LINE_TEST(TESTMETHOD) \
CPPUNIT_TEST_SUITE_ADD_TEST( \
( new mitk::TestCaller<TestFixtureType>( \
context.getTestNameFor( #TESTMETHOD), \
&TestFixtureType::TESTMETHOD, \
context.makeFixture() ) ) );
/**
* @brief Adds a parameterized test to the current test suite.
*
* @ingroup MITKTestingAPI
*
* Use this macro after the CPPUNIT_TEST_SUITE() macro to add test cases
* which need one custom parameter.
*
* @param TESTMETHOD The name of the member function test.
* @param arg1 A custom string parameter being passed to the fixture.
*
* @note Use the macro MITK_PARAMETERIZED_TEST_1 only if you know what
* you are doing. If you are not sure, use MITK_TEST instead.
*
* @see MITK_PARAMETERIZED_TEST
*/
#define MITK_PARAMETERIZED_TEST_1(TESTMETHOD, arg1) \
{ \
std::vector<std::string> args; \
args.push_back(arg1); \
MITK_PARAMETERIZED_TEST(TESTMETHOD, args) \
}
/**
* @brief Adds a parameterized test to the current test suite.
*
* @ingroup MITKTestingAPI
*
* Use this macro after the CPPUNIT_TEST_SUITE() macro to add test cases
* which need two custom parameter.
*
* @param TESTMETHOD The name of the member function test.
* @param arg1 A custom string parameter being passed to the fixture.
*
* @note Use the macro MITK_PARAMETERIZED_TEST_2 only if you know what
* you are doing. If you are not sure, use MITK_TEST instead.
*
* @see MITK_PARAMETERIZED_TEST
*/
#define MITK_PARAMETERIZED_TEST_2(TESTMETHOD, arg1, arg2) \
{ \
std::vector<std::string> args; \
args.push_back(arg1); \
args.push_back(arg2); \
MITK_PARAMETERIZED_TEST(TESTMETHOD, args) \
}
#endif
diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake
index c070cc1304..04887912c3 100644
--- a/Core/Code/files.cmake
+++ b/Core/Code/files.cmake
@@ -1,418 +1,412 @@
set(H_FILES
Algorithms/itkImportMitkImageContainer.h
Algorithms/itkImportMitkImageContainer.txx
Algorithms/itkMITKScalarImageToHistogramGenerator.h
Algorithms/itkMITKScalarImageToHistogramGenerator.txx
Algorithms/mitkInstantiateAccessFunctions.h
Algorithms/mitkPixelTypeList.h
Algorithms/mitkPPArithmeticDec.h
Algorithms/mitkPPArgCount.h
Algorithms/mitkPPCat.h
Algorithms/mitkPPConfig.h
Algorithms/mitkPPControlExprIIf.h
Algorithms/mitkPPControlIf.h
Algorithms/mitkPPControlIIf.h
Algorithms/mitkPPDebugError.h
Algorithms/mitkPPDetailAutoRec.h
Algorithms/mitkPPDetailDMCAutoRec.h
Algorithms/mitkPPExpand.h
Algorithms/mitkPPFacilitiesEmpty.h
Algorithms/mitkPPFacilitiesExpand.h
Algorithms/mitkPPLogicalBool.h
Algorithms/mitkPPRepetitionDetailDMCFor.h
Algorithms/mitkPPRepetitionDetailEDGFor.h
Algorithms/mitkPPRepetitionDetailFor.h
Algorithms/mitkPPRepetitionDetailMSVCFor.h
Algorithms/mitkPPRepetitionFor.h
Algorithms/mitkPPSeqElem.h
Algorithms/mitkPPSeqForEach.h
Algorithms/mitkPPSeqForEachProduct.h
Algorithms/mitkPPSeq.h
Algorithms/mitkPPSeqEnum.h
Algorithms/mitkPPSeqSize.h
Algorithms/mitkPPSeqToTuple.h
Algorithms/mitkPPStringize.h
Algorithms/mitkPPTupleEat.h
Algorithms/mitkPPTupleElem.h
Algorithms/mitkPPTupleRem.h
Algorithms/mitkClippedSurfaceBoundsCalculator.h
Algorithms/mitkExtractSliceFilter.h
Algorithms/mitkConvert2Dto3DImageFilter.h
Algorithms/mitkPlaneClipping.h
Common/mitkCommon.h
Common/mitkExceptionMacro.h
DataManagement/mitkProportionalTimeGeometry.h
DataManagement/mitkTimeGeometry.h
DataManagement/mitkImageAccessByItk.h
DataManagement/mitkImageCast.h
DataManagement/mitkImagePixelAccessor.h
DataManagement/mitkImagePixelReadAccessor.h
DataManagement/mitkImagePixelWriteAccessor.h
DataManagement/mitkImageReadAccessor.h
DataManagement/mitkImageWriteAccessor.h
DataManagement/mitkITKImageImport.h
DataManagement/mitkITKImageImport.txx
DataManagement/mitkImageToItk.h
DataManagement/mitkShaderProperty.h
DataManagement/mitkImageToItk.txx
DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibility reasons.
DataManagement/mitkPropertyListReplacedObserver.cpp
DataManagement/mitkVectorDeprecated.h
DataManagement/mitkArray.h
DataManagement/mitkQuaternion.h
DataManagement/mitkNumericTypes.h
DataManagement/mitkVector.h
DataManagement/mitkPoint.h
DataManagement/mitkMatrix.h
Interactions/mitkEventMapperAddOn.h
Interfaces/mitkIDataNodeReader.h
Rendering/mitkLocalStorageHandler.h
Rendering/Colortables/HotIron.h
Rendering/Colortables/Jet.h
Rendering/Colortables/PET20.h
Rendering/Colortables/PETColor.h
IO/mitkPixelTypeTraits.h
)
set(CPP_FILES
Algorithms/mitkBaseDataSource.cpp
Algorithms/mitkCompareImageDataFilter.cpp
Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp
Algorithms/mitkDataNodeSource.cpp
Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp
Algorithms/mitkHistogramGenerator.cpp
Algorithms/mitkImageChannelSelector.cpp
Algorithms/mitkImageSliceSelector.cpp
Algorithms/mitkImageSource.cpp
Algorithms/mitkImageTimeSelector.cpp
Algorithms/mitkImageToImageFilter.cpp
Algorithms/mitkImageToSurfaceFilter.cpp
Algorithms/mitkPointSetSource.cpp
Algorithms/mitkPointSetToPointSetFilter.cpp
Algorithms/mitkRGBToRGBACastImageFilter.cpp
Algorithms/mitkSubImageSelector.cpp
Algorithms/mitkSurfaceSource.cpp
Algorithms/mitkSurfaceToImageFilter.cpp
Algorithms/mitkSurfaceToSurfaceFilter.cpp
Algorithms/mitkUIDGenerator.cpp
Algorithms/mitkVolumeCalculator.cpp
Algorithms/mitkClippedSurfaceBoundsCalculator.cpp
Algorithms/mitkExtractSliceFilter.cpp
Algorithms/mitkConvert2Dto3DImageFilter.cpp
Controllers/mitkBaseController.cpp
Controllers/mitkCallbackFromGUIThread.cpp
Controllers/mitkCameraController.cpp
Controllers/mitkCameraRotationController.cpp
Controllers/mitkCoreActivator.cpp
Controllers/mitkFocusManager.cpp
Controllers/mitkLimitedLinearUndo.cpp
Controllers/mitkOperationEvent.cpp
Controllers/mitkPlanePositionManager.cpp
Controllers/mitkProgressBar.cpp
Controllers/mitkRenderingManager.cpp
Controllers/mitkSliceNavigationController.cpp
Controllers/mitkSlicesCoordinator.cpp
Controllers/mitkSlicesRotator.cpp
Controllers/mitkSlicesSwiveller.cpp
Controllers/mitkStatusBar.cpp
Controllers/mitkStepper.cpp
Controllers/mitkTestManager.cpp
Controllers/mitkUndoController.cpp
Controllers/mitkVerboseLimitedLinearUndo.cpp
Controllers/mitkVtkInteractorCameraController.cpp
Controllers/mitkVtkLayerController.cpp
DataManagement/mitkProportionalTimeGeometry.cpp
DataManagement/mitkTimeGeometry.cpp
DataManagement/mitkAbstractTransformGeometry.cpp
DataManagement/mitkAnnotationProperty.cpp
DataManagement/mitkApplicationCursor.cpp
DataManagement/mitkBaseData.cpp
DataManagement/mitkBaseGeometry.cpp
DataManagement/mitkBaseProperty.cpp
DataManagement/mitkClippingProperty.cpp
DataManagement/mitkChannelDescriptor.cpp
DataManagement/mitkColorProperty.cpp
DataManagement/mitkDataStorage.cpp
# DataManagement/mitkDataTree.cpp
DataManagement/mitkDataNode.cpp
DataManagement/mitkDataNodeFactory.cpp
# DataManagement/mitkDataTreeStorage.cpp
DataManagement/mitkDisplayGeometry.cpp
DataManagement/mitkEnumerationProperty.cpp
DataManagement/mitkPlaneGeometryData.cpp
DataManagement/mitkGeometry3D.cpp
DataManagement/mitkGeometryData.cpp
DataManagement/mitkGroupTagProperty.cpp
DataManagement/mitkImage.cpp
DataManagement/mitkImageAccessorBase.cpp
DataManagement/mitkImageCaster.cpp
DataManagement/mitkImageCastPart1.cpp
DataManagement/mitkImageCastPart2.cpp
DataManagement/mitkImageCastPart3.cpp
DataManagement/mitkImageCastPart4.cpp
DataManagement/mitkImageDataItem.cpp
DataManagement/mitkImageDescriptor.cpp
DataManagement/mitkImageReadAccessor.cpp
DataManagement/mitkImageStatisticsHolder.cpp
DataManagement/mitkImageVtkAccessor.cpp
DataManagement/mitkImageVtkReadAccessor.cpp
DataManagement/mitkImageVtkWriteAccessor.cpp
DataManagement/mitkImageWriteAccessor.cpp
DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp
DataManagement/mitkLandmarkProjector.cpp
DataManagement/mitkLine.cpp
DataManagement/mitkLevelWindow.cpp
DataManagement/mitkLevelWindowManager.cpp
DataManagement/mitkLevelWindowPreset.cpp
DataManagement/mitkLevelWindowProperty.cpp
DataManagement/mitkLookupTable.cpp
DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable
DataManagement/mitkMemoryUtilities.cpp
DataManagement/mitkModalityProperty.cpp
DataManagement/mitkModeOperation.cpp
DataManagement/mitkModifiedLock.cpp
DataManagement/mitkNodePredicateAnd.cpp
DataManagement/mitkNodePredicateBase.cpp
DataManagement/mitkNodePredicateCompositeBase.cpp
DataManagement/mitkNodePredicateData.cpp
DataManagement/mitkNodePredicateDataType.cpp
DataManagement/mitkNodePredicateDimension.cpp
DataManagement/mitkNodePredicateFirstLevel.cpp
DataManagement/mitkNodePredicateNot.cpp
DataManagement/mitkNodePredicateOr.cpp
DataManagement/mitkNodePredicateProperty.cpp
DataManagement/mitkNodePredicateSource.cpp
DataManagement/mitkPlaneOrientationProperty.cpp
DataManagement/mitkPlaneGeometry.cpp
DataManagement/mitkPlaneOperation.cpp
DataManagement/mitkPointOperation.cpp
DataManagement/mitkPointSet.cpp
DataManagement/mitkProperties.cpp
DataManagement/mitkPropertyList.cpp
DataManagement/mitkPropertyObserver.cpp
DataManagement/mitkRestorePlanePositionOperation.cpp
DataManagement/mitkApplyTransformMatrixOperation.cpp
DataManagement/mitkRotationOperation.cpp
DataManagement/mitkSlicedData.cpp
DataManagement/mitkSlicedGeometry3D.cpp
DataManagement/mitkSmartPointerProperty.cpp
DataManagement/mitkStandaloneDataStorage.cpp
DataManagement/mitkStateTransitionOperation.cpp
DataManagement/mitkStringProperty.cpp
DataManagement/mitkSurface.cpp
DataManagement/mitkSurfaceOperation.cpp
DataManagement/mitkThinPlateSplineCurvedGeometry.cpp
DataManagement/mitkTransferFunction.cpp
DataManagement/mitkTransferFunctionProperty.cpp
DataManagement/mitkTransferFunctionInitializer.cpp
DataManagement/mitkVector.cpp
DataManagement/mitkNumericConstants.cpp
DataManagement/mitkVtkInterpolationProperty.cpp
DataManagement/mitkVtkRepresentationProperty.cpp
DataManagement/mitkVtkResliceInterpolationProperty.cpp
DataManagement/mitkVtkScalarModeProperty.cpp
DataManagement/mitkVtkVolumeRenderingProperty.cpp
DataManagement/mitkWeakPointerProperty.cpp
DataManagement/mitkRenderingModeProperty.cpp
DataManagement/mitkResliceMethodProperty.cpp
DataManagement/mitkMaterial.cpp
DataManagement/mitkPointSetShapeProperty.cpp
DataManagement/mitkFloatPropertyExtension.cpp
DataManagement/mitkIntPropertyExtension.cpp
DataManagement/mitkPropertyExtension.cpp
DataManagement/mitkPropertyFilter.cpp
DataManagement/mitkPropertyAliases.cpp
DataManagement/mitkPropertyDescriptions.cpp
DataManagement/mitkPropertyExtensions.cpp
DataManagement/mitkPropertyFilters.cpp
DataManagement/mitkShaderProperty.cpp
Interactions/mitkAction.cpp
Interactions/mitkAffineInteractor.cpp
Interactions/mitkBindDispatcherInteractor.cpp
Interactions/mitkCoordinateSupplier.cpp
Interactions/mitkDataInteractor.cpp
Interactions/mitkDispatcher.cpp
Interactions/mitkDisplayCoordinateOperation.cpp
Interactions/mitkDisplayInteractor.cpp
Interactions/mitkDisplayPositionEvent.cpp
# Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded
# Interactions/mitkDisplayVectorInteractorScroll.cpp
Interactions/mitkEvent.cpp
Interactions/mitkEventConfig.cpp
Interactions/mitkEventDescription.cpp
Interactions/mitkEventFactory.cpp
Interactions/mitkInteractionEventHandler.cpp
Interactions/mitkEventMapper.cpp
Interactions/mitkEventRecorder.cpp
Interactions/mitkEventStateMachine.cpp
Interactions/mitkGlobalInteraction.cpp
Interactions/mitkInteractor.cpp
Interactions/mitkInternalEvent.cpp
Interactions/mitkInteractionEvent.cpp
Interactions/mitkInteractionEventConst.cpp
Interactions/mitkInteractionPositionEvent.cpp
Interactions/mitkInteractionKeyEvent.cpp
Interactions/mitkMousePressEvent.cpp
Interactions/mitkMouseMoveEvent.cpp
Interactions/mitkMouseReleaseEvent.cpp
Interactions/mitkMouseWheelEvent.cpp
Interactions/mitkMouseDoubleClickEvent.cpp
Interactions/mitkMouseModeSwitcher.cpp
Interactions/mitkMouseMovePointSetInteractor.cpp
Interactions/mitkMoveBaseDataInteractor.cpp
Interactions/mitkNodeDepententPointSetInteractor.cpp
Interactions/mitkPointSetDataInteractor.cpp
Interactions/mitkPointSetInteractor.cpp
Interactions/mitkPositionEvent.cpp
Interactions/mitkPositionTracker.cpp
Interactions/mitkSinglePointDataInteractor.cpp
Interactions/mitkStateMachineAction.cpp
Interactions/mitkStateMachineCondition.cpp
Interactions/mitkStateMachineState.cpp
Interactions/mitkStateMachineTransition.cpp
Interactions/mitkState.cpp
Interactions/mitkStateMachineContainer.cpp
Interactions/mitkStateEvent.cpp
Interactions/mitkStateMachine.cpp
Interactions/mitkStateMachineFactory.cpp
Interactions/mitkTransition.cpp
Interactions/mitkWheelEvent.cpp
Interactions/mitkKeyEvent.cpp
Interactions/mitkVtkEventAdapter.cpp
Interactions/mitkVtkInteractorStyle.cxx
Interactions/mitkCrosshairPositionEvent.cpp
Interactions/mitkXML2EventParser.cpp
Interfaces/mitkInteractionEventObserver.cpp
Interfaces/mitkIShaderRepository.cpp
Interfaces/mitkIPropertyAliases.cpp
Interfaces/mitkIPropertyDescriptions.cpp
Interfaces/mitkIPropertyExtensions.cpp
Interfaces/mitkIPropertyFilters.cpp
Interfaces/mitkIPersistenceService.cpp
IO/mitkBaseDataIOFactory.cpp
IO/mitkCoreDataNodeReader.cpp
IO/mitkDicomSeriesReader.cpp
IO/mitkDicomSR_LoadDICOMScalar.cpp
IO/mitkDicomSR_LoadDICOMScalar4D.cpp
IO/mitkDicomSR_LoadDICOMRGBPixel.cpp
IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp
IO/mitkDicomSR_ImageBlockDescriptor.cpp
IO/mitkDicomSR_GantryTiltInformation.cpp
IO/mitkDicomSR_SliceGroupingResult.cpp
IO/mitkFileReader.cpp
IO/mitkFileSeriesReader.cpp
IO/mitkFileWriter.cpp
# IO/mitkIpPicGet.c
IO/mitkImageGenerator.cpp
IO/mitkImageWriter.cpp
IO/mitkImageWriterFactory.cpp
IO/mitkItkImageFileIOFactory.cpp
IO/mitkItkImageFileReader.cpp
IO/mitkItkLoggingAdapter.cpp
IO/mitkItkPictureWrite.cpp
IO/mitkIOUtil.cpp
IO/mitkLookupTableProperty.cpp
IO/mitkOperation.cpp
# IO/mitkPicFileIOFactory.cpp
# IO/mitkPicFileReader.cpp
# IO/mitkPicFileWriter.cpp
# IO/mitkPicHelper.cpp
# IO/mitkPicVolumeTimeSeriesIOFactory.cpp
# IO/mitkPicVolumeTimeSeriesReader.cpp
IO/mitkPixelType.cpp
IO/mitkPointSetIOFactory.cpp
IO/mitkPointSetReader.cpp
IO/mitkPointSetWriter.cpp
IO/mitkPointSetWriterFactory.cpp
IO/mitkRawImageFileReader.cpp
IO/mitkStandardFileLocations.cpp
IO/mitkSTLFileIOFactory.cpp
IO/mitkSTLFileReader.cpp
IO/mitkSurfaceVtkWriter.cpp
IO/mitkSurfaceVtkWriterFactory.cpp
IO/mitkVtkLoggingAdapter.cpp
IO/mitkVtiFileIOFactory.cpp
IO/mitkVtiFileReader.cpp
IO/mitkVtkImageIOFactory.cpp
IO/mitkVtkImageReader.cpp
IO/mitkVtkSurfaceIOFactory.cpp
IO/mitkVtkSurfaceReader.cpp
IO/vtkPointSetXMLParser.cpp
IO/mitkLog.cpp
Rendering/mitkBaseRenderer.cpp
Rendering/mitkVtkMapper.cpp
Rendering/mitkRenderWindowFrame.cpp
Rendering/mitkPlaneGeometryDataMapper2D.cpp
Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp
Rendering/mitkGLMapper.cpp
Rendering/mitkGradientBackground.cpp
Rendering/mitkManufacturerLogo.cpp
Rendering/mitkMapper.cpp
Rendering/mitkPointSetGLMapper2D.cpp
Rendering/mitkPointSetVtkMapper2D.cpp
Rendering/mitkPointSetVtkMapper3D.cpp
Rendering/mitkSurfaceGLMapper2D.cpp
Rendering/mitkSurfaceVtkMapper3D.cpp
Rendering/mitkVolumeDataVtkMapper3D.cpp
Rendering/mitkVtkPropRenderer.cpp
Rendering/mitkVtkWidgetRendering.cpp
Rendering/vtkMitkRectangleProp.cpp
Rendering/vtkMitkRenderProp.cpp
Rendering/mitkVtkEventProvider.cpp
Rendering/mitkRenderWindow.cpp
Rendering/mitkRenderWindowBase.cpp
Rendering/mitkImageVtkMapper2D.cpp
Rendering/vtkMitkThickSlicesFilter.cpp
Rendering/vtkMitkLevelWindowFilter.cpp
Rendering/vtkNeverTranslucentTexture.cpp
Rendering/mitkOverlay.cpp
Rendering/mitkVtkOverlay.cpp
Rendering/mitkVtkOverlay2D.cpp
Rendering/mitkVtkOverlay3D.cpp
Rendering/mitkOverlayManager.cpp
Rendering/mitkAbstractOverlayLayouter.cpp
- Rendering/mitkTextOverlay2D.cpp
- Rendering/mitkTextOverlay3D.cpp
- Rendering/mitkLabelOverlay3D.cpp
- Rendering/mitkOverlay2DLayouter.cpp
- Rendering/mitkScaleLegendOverlay
-
Common/mitkException.cpp
Common/mitkCommon.h
Common/mitkCoreObjectFactoryBase.cpp
Common/mitkCoreObjectFactory.cpp
Common/mitkCoreServices.cpp
)
set(RESOURCE_FILES
Interactions/globalConfig.xml
Interactions/DisplayInteraction.xml
Interactions/DisplayConfig.xml
Interactions/DisplayConfigPACS.xml
Interactions/DisplayConfigPACSPan.xml
Interactions/DisplayConfigPACSScroll.xml
Interactions/DisplayConfigPACSZoom.xml
Interactions/DisplayConfigPACSLevelWindow.xml
Interactions/DisplayConfigMITK.xml
Interactions/PointSet.xml
Interactions/Legacy/StateMachine.xml
Interactions/Legacy/DisplayConfigMITKTools.xml
Interactions/PointSetConfig.xml
mitkLevelWindowPresets.xml
)
diff --git a/Core/Documentation/Doxygen/Concepts/Overlays.dox b/Core/Documentation/Doxygen/Concepts/Overlays.dox
index 0fb9ad3b1f..38e8b8d1e1 100644
--- a/Core/Documentation/Doxygen/Concepts/Overlays.dox
+++ b/Core/Documentation/Doxygen/Concepts/Overlays.dox
@@ -1,136 +1,123 @@
/**
\page OverlaysPage Overlays and Annotations Concepts
\tableofcontents
\section OverlaysPage_Introduction Overlays and Annotations
The overlays in MITK are a simple way to display additional information on the render windows. A class, deriving from mitk::Overlay represents an arbitrary
2D or 3D object that can be rendered as an overlay. This can for example be used for the annotation of 3D points or to overlay despriptions in the window corners.
The mitk::OverlayManager is used to add the overlays to the renderwindows, updating them and manage the respective layout managers.
The following features are implemented in this framework.
<ol>
<li>Definition of graphical elements that can be displayed in the render windows.
<li>It is possible to manage multiple elements in each window.
<li>A single Overlay can be rendered on any number of available render windows.
<li>2D and 3D textelements are already defined in the Overlay module and are using VTK to create custom annotations.
<li>The mitk::BaseLayouter interface enables the implementation of layout managers, to handle the placement of the overlays.
</ol>
\section OverlaysPage_ArchitectureSection General Architecture
\dot
digraph linker_deps {
node [shape=record, fontname=Helvetica, fontsize=10];
BR [ label="BaseRenderer" ];
BL [ label="{BaseLayouter|+ArrangeOverlays()}" ];
O [ label="{Overlay|-PropertyList|+RemoveOverlay(BaseRenderer*)\n+UpdateOverlay(BaseRenderer*)\n+RemoveOverlay(BaseRenderer*)}" ];
OM [ label="{OverlayManager|+AddOverlay(Overlay*)\n+RemoveOverlay(Overlay*)}" ];
TO [ label="TextOverlay" ];
VTKO [ label="{vtkOverlay|#GetVtkActor()}" ];
TO -> VTKO;
VTKO -> O;
OM -> O [style="dashed",label="manages"];
OM -> BL [style="dashed"];
OM -> BR [style="dashed"];
BR -> OM [style="dashed"];
}
\enddot
The mitk::Overlay can be implemented using a custom rendering framework like VTK. In this diagram, the vtkOverlay is shown as the superclass for all Overlays which use the vtk framework for rendering.
The OverlayManager can be registered to several BaseRenderer instances in order to call the update method of each Overlay during the rendering phase of the renderer.
It also manages the respective Layouters which are used to manage the placement of a group of Overlays.
\subsection OverlaysPage_OverlaySubsection Overlay
The mitk::Overlay is an abstract class that can manage property lists like the mitk::DataNode and provides the interfaces to thr three methods
mitk::Overlay::AddOverlay, mitk::Overlay::UpdateOverlay and mitk::Overlay::RemoveOverlay. The subclasses of the mitk::Overlay have to implement these methods
in order to provide the functionallity of an overlay. There are already a few implementations of mitk::Overlay which are using VTK as a rendering
framework to display the Overlays. However the mitk::Overlay can also be implemented using OpenGL to draw the Overlay on the renderwindows.
\subsection OverlaysPage_OverlayManagerSubsection OverlayManager
The mitk::OverlayManager is the manager for a set of Overlays and the respective Layouters.
Before the manager can be used, all mitk::BaseRenderer have to be registered to the mitk::OverlayManager instance like this:
\snippet OverlayExample.cpp CreateOverlayManager
The mitk::OverlayManager can then be used anywhere in the program by fetching it as follows:
\snippet OverlayExample.cpp GetOverlayManagerInstance
All mitk::Overlay instances can now be added to the OverlayManager by calling mitk::OverlayManager::AddOverlay.
\subsection OverlaysPage_LayouterSubsection Layouter
In order to use Layouters for the positioning
of the Overlays, each Layouter object that has been created has to be added to an internal list in the OverlayManager:
\snippet OverlayExample.cpp AddLayouter
The mitk::OverlayManager::SetLayouter method can then be used to configure an Overlay to be positioned by a certain Layouter:
\snippet OverlayExample.cpp SetLayouterToOverlay
-\section OverlaysPage_UsageSection Usage of Predefined Overlays
-
-\subsection OverlaysPage_TextWidget2DUsageSubsection mitkTextOverlay2D
-This exemplary overlay can render UTF-8 encoded text as a 2D Overlay. The Overlay2DLayouter can be used to automatically place a group of overlays to a
-specific corner.
-\snippet OverlayExample.cpp TextOverlay2D
-\snippet OverlayExample.cpp SetLayouterToOverlay
-
-\subsection OverlaysPage_TextWidget3DUsageSubsection mitkTextOverlay3D
-This overlay displays labels in 3D coordinates. The labels always face the camera.
-
-\snippet OverlayExample.cpp TextOverlay3D
-
\subsection OverlaysPage_NotManagedSubsection Manually Managed Overlays
In order to integrate an Overlay into an mitk::Mapper, it is advised not to use the OverlayManager but to manually manage the Overlay.
To do so, the update methods of the overlays have to be called manually before the start of each rendering procedure. It must only be called if the Properties have changed or if your custom overlay implements its own rendering mechanism.
\section OverlaysPage_CustomOverlaySection Implement a Custom Overlay
A new custom Overlay should derive from mitkOverlay or one of the later mentioned subclasses VtkOverlay2D oder VtkOverlay3D. There should always be an implementation for the methods
AddOverlay, RemoveOverlay and Update Overlay.
UpdateOverlay is the procedure that is called in each rendering step. If the Overlay is rendered by VTK, this method only applies the properties to the representation.
If the custom Overlay requires additional properties, they should be made accessible by getters and setters for a better usability:
\code
void mitk::VtkOverlay3D::SetPosition3D(Point3D position3D, mitk::BaseRenderer *renderer)
{
mitk::Point3dProperty::Pointer position3dProperty = mitk::Point3dProperty::New(position3D);
SetProperty("Position3D", position3dProperty,renderer);
}
mitk::Point3D mitk::VtkOverlay3D::GetPosition3D(mitk::BaseRenderer *renderer)
{
mitk::Point3D position3D;
GetPropertyValue<mitk::Point3D>("Position3D", position3D, renderer);
return position3D;
}
\endcode
\subsection OverlaysPage_CustomVTK2DOverlaySubsection VTK 2D Overlay
VTK based overlays which are meant to be displayed in 2D over the render window should derive from the mitk::VtkOverlay2D.
The mitk::VtkOverlay2D is a subclass of Vtk::Overlay, that uses VTK to render the overlay. This class creates the Overlay representation as a vtkActor2D, and is very easy to implement
because only UpdateVtkOverlay2D and GetVtkActor2D have to be implemented. The add, update and remove methods are implemented in the superclasses.
UpdateVtkOverlay2D only needs to apply the specific properties and GetVtkActor2D simply returns the created vtkActor.
\subsection OverlaysPage_CustomVTK3DOverlaySubsection VTK 3D Overlay
The mitkVtkOverlay3D works just like mitkVtkOverlay2D, but it is designed for arbitrary 3D objects which derive from vtkProp,
\section OverlaysPage_CustomLayouterSection Implement a Custom Layouter
A Layouter is used for an automatic positioning of a group of Overlays and is derived from mitkBaseLayouter. Every Layouter that manages a group of Layouts should have a unique identifier
which is used to register the Layouter in the OverlayManager. A Layouter is always uniquely defined by the identifier and one BaseRenderer. Before a Layouter can be used by the
OverlayManager it has to be added, using the AddLayouter Method. An Overlay can then be added to a Layout as follows:
\code
overlayManager->SetLayouter(textOverlay.GetPointer(),mitk::Overlay2DLayouter::STANDARD_2D_TOPLEFT,axialRenderer);
\endcode
A new Layouter has to implement PrepareLayout which should parse the internal Overlay list and set their position as required.
*/
diff --git a/Documentation/Doxygen/DeveloperManual/HowTos/InteractionTestingHowTo.dox b/Documentation/Doxygen/DeveloperManual/HowTos/InteractionTestingHowTo.dox
new file mode 100644
index 0000000000..88bb0874e7
--- /dev/null
+++ b/Documentation/Doxygen/DeveloperManual/HowTos/InteractionTestingHowTo.dox
@@ -0,0 +1,70 @@
+/**
+
+\page InteractionTestingHowTo Interaction Testing in MITK
+
+\tableofcontents
+
+\section RecordingInteractions Recording Interactions
+To be able to record interactions activate Interaction Event Recorder in MITK-build cmake.
+The following table explains how to step-wise create an interaction sequence, which is necessary for developing interaction tests.
+The given example shows how the AddTool Segmentation Interaction Test was developed.
+For implementation examples refer to mitkToolInteractionTest.cpp or mitkPlanarFigureInteractionTest.cpp
+
+Step | AddTool Segmentation Example
+-------------- | ----------------------
+Load Image | MITK-Data/Pic3D.nrrd
+Do not scroll image slices before recording starts | -
+Activate Interaction | Click on Add in segmentation plugin
+Define output filename (be careful: plugin appends interactions to existing files) | SegmentationInteractor_AddTool.xml
+Start recording | Click on record symbol (red circle) in Event Recorder Plugin
+Perform Interaction | Draw a segmentation in the render window
+Stop recording | Click on stop symbol (red square) in Event Recorder Plugin
+Save record (\<interaction\>.xml) to your testing environment | MITK-Data/InteractionTestData/Interactions/SegmentationInteractor_AddTool.xml
+Save interaction result (Image, Surface, etc.) to your testing environment | InteractionTestData/ReferenceData/SegmentationInteractor_AddTool.nrrd
+
+\section Limitations Limitations
+<ul>
+ <li> No VTK interactions are recorded
+ <li> Renderwindows have to stay constant during record (e.g. no resizing)
+ <li> Interactions have to follow the new Interaction concept
+</ul>
+
+\section UsingInteractionsInTests Using Interactions in Tests
+
+In order to use interaction tests, the class mitk::InteractionTestHelper has to be used.
+The usage of this class is explained with an example of the SegmentationTool test.
+The TestHelper needs to know the location of the recorded interaction file.
+This is done by giving the filename to the constructor.
+
+\code
+//Create test helper to initialize all necessary objects for interaction
+mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionPattern));
+\endcode
+
+The InteractionTestHelper stores its own DataStorage.
+We want to use this DataStorage and provide all necessary DataNodes.
+\code
+//Use data storage of test helper
+mitk::DataStorage::Pointer dataStorage = interactionTestHelper.GetDataStorage();
+
+//add images to datastorage
+interactionTestHelper.AddNodeToStorage(patientImageNode);
+interactionTestHelper.AddNodeToStorage(workingImageNode);
+\endcode
+
+Let the InteractionTestHelper know about the relevant time step (particularly necessary with 4D images)
+\code
+//set time step
+interactionTestHelper.SetTimeStep(timestep);
+\endcode
+
+When everything is set up, the loaded Interaction can be played back.
+\code
+//Start Interaction
+interactionTestHelper.PlaybackInteraction();
+\endcode
+
+
+
+
+*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/AboutTesting/AboutTestingPage.dox b/Documentation/Doxygen/DeveloperManual/Starting/AboutTesting/AboutTestingPage.dox
index 79869a4d33..71f56ac001 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/AboutTesting/AboutTestingPage.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/AboutTesting/AboutTestingPage.dox
@@ -1,13 +1,14 @@
/**
\page AboutTestingPage Testing
Testing is a very important part of ensuring code quality. We use <a href="http://www.cdash.org/">CDash</a> for testing whether MITK builds on a variety of platforms and configurations. You can find our dashboard <a href="http://cdash.mitk.org/index.php?project=MITK&display=project">here</a>.
Additionally we support tests of software function as well. More detailed information on testing in MITK can be found below.
<ul>
<li> \subpage GeneralTests
<li> \subpage RenderingTests
<li> \subpage DICOMTesting
+ <li> \subpage InteractionTestingHowTo
</ul>
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/FirstSteps.dox b/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/FirstSteps.dox
index 537a0091b0..7b01d0b3e1 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/FirstSteps.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/FirstSteps.dox
@@ -1,14 +1,15 @@
/**
\page FirstSteps First steps in Development
This section will show you how to extend MITK for your own project.
<ul>
<li> \subpage NewPluginPage </li>
<li> \subpage NewModulePage</li>
<li> \subpage NewViewPage</li>
<li> \subpage CMAKE_FAQ </li>
<li> \subpage StatemachineEditor </li>
+ <li> \subpage MiniAppCommandLineToolHowToPage </li>
</ul>
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/MiniAppCommandLineTool/MiniAppCommandLineToolHowTo.dox b/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/MiniAppCommandLineTool/MiniAppCommandLineToolHowTo.dox
new file mode 100644
index 0000000000..3164a26673
--- /dev/null
+++ b/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/MiniAppCommandLineTool/MiniAppCommandLineToolHowTo.dox
@@ -0,0 +1,199 @@
+/**
+
+\page MiniAppCommandLineToolHowToPage How to create a MiniApp command line tool
+
+\tableofcontents
+
+This page will give you an overview of creating your own command line tool that can be integrated into a MiniApp.
+If you don't know about MiniApps, you can read what MiniApps are at the \ref MiniAppExplainPage page.
+
+\section MiniAppCommandLineToolHowToPageDescription What's a MiniApp command line tool?
+
+A MiniApp command line tool allows for configuration of command line arguments and eases the access to these argument values.
+Additionally, a command line tool provides a XML representation of the configured arguments. This XML representation can be used for automatic user interface generation.
+
+\section MiniAppCommandLineToolHowToPageSetUp Setting up a command line tool
+
+This section describes the most important code parts of a command line tool using the \ref TensorReconstruction command line tool as an example.
+
+First the main function of the command line tool is specified. This function is registered at the MiniAppManager via the macro defined in \ref MiniAppManager.h
+
+\code
+int TensorReconstruction(int argc, char* argv[])
+{
+
+}
+
+RegisterDiffusionMiniApp(TensorReconstruction);
+\endcode
+
+Within the body of the main function the accepted arguments of the command line tool are specified via the addArgument method of the ctkCommandLineParser located in DiffusionImaging/MiniApps directory.
+
+The \ref TensorReconstruction command line tool requires an input file, an output file, and optionally accepts a threshold of type integer.
+
+\code
+ctkCommandLineParser parser;
+parser.setArgumentPrefix("--", "-");
+parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
+parser.addArgument("outFile", "o", ctkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
+parser.addArgument("b0Threshold", "t", ctkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);
+\endcode
+
+Following argument types are available for the addArgument method:
+\li String
+\li Bool
+\li StringList
+\li Int
+\li Float
+\li InputDirectory
+\li InputFile
+\li OutputDirectory
+\li OutputFile
+
+The distinction between InputFile/OutputFile and InputDirectory/OutputDirectory respectively ensures that the appropriate UI widget is chosen.
+The label string passed to the addArgument method is the label for the corresponding UI widget.
+
+After specification of allowed arguments the parser's parseArguments method is called. This method returns a mapping of long argument names and their values.
+
+\code
+map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
+if (parsedArgs.size() == 0)
+ return EXIT_FAILURE;
+\endcode
+
+The following code snippet shows how argument values can be accessed and converted:
+
+\code
+std::string inFileName = us::any_cast<string>(parsedArgs["input"]);
+std::string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
+
+int threshold = 0;
+if (parsedArgs.count("b0Threshold"))
+ threshold = us::any_cast<int>(parsedArgs["b0Threshold"]);
+\endcode
+
+\section MiniAppCommandLineToolHowToPageXMLRepresentation Retrieving XML argument description
+
+According to the specified command line arguments, a XML representation of the arguments is generated and emitted on the console if the MiniApp command line tool is executed with argument "--xml".
+
+In order to use the XML representation for automatic user interface generation additional information has to be provided for the parser.
+Please provide category, title, description and contributor as shown in code snippet below for the \ref TensorReconstruction command line tool:
+
+\code
+parser.setCategory("Preprocessing Tools");
+parser.setTitle("Tensor Reconstruction");
+parser.setDescription("Takes a .dwi, .fsl/.fslgz file as input and saves the computed reconstructed tensor to the specified file. It also allows for a threshold to be set, to exclude low b values from the reconstruction process.");
+parser.setContributor("MBI");
+\endcode
+
+Note that in the generated UI the parameter widgets are contained in a group box. There is a default label ("Parameters") and a default description ("Groupbox containing parameters.") specified. The label of such a parameter group and the description can be set via the parser's changeParameterGroup method.
+The method must be called before adding the arguments.
+
+Running the \ref TensorReconstruction command line tool for MITK Diffusion MiniApp with argument "--xml" ...
+\code
+./MitkDiffusionMiniApps TensorReconstruction --xml
+\endcode
+
+... will emit following XML description:
+
+\code
+<executable>
+ <category>Preprocessing Tools</category>
+ <title>Tensor Reconstruction</title>
+ <description>Takes a .dwi, .fsl/.fslgz file as input and saves the computed reconstructed tensor to the specified file. It also allows for a threshold to be set, to exclude low b values from the reconstruction process.</description>
+ <contributor>MBI</contributor>
+ <parameters>
+ <label>Parameters</label>
+ <description>Groupbox containing parameters.</description>
+ <file>
+ <name>input</name>
+ <label>Input file</label>
+ <description>input raw dwi (.dwi or .fsl/.fslgz)</description>
+ <longflag>input</longflag>
+ <flag>i</flag>
+ <channel>input</channel>
+ </file>
+ <file>
+ <name>outFile</name>
+ <label>Output file</label>
+ <description>output file</description>
+ <longflag>outFile</longflag>
+ <flag>o</flag>
+ <channel>output</channel>
+ </file>
+ <integer>
+ <name>b0Threshold</name>
+ <label>b0 threshold</label>
+ <description>baseline image intensity threshold</description>
+ <longflag>b0Threshold</longflag>
+ <flag>t</flag>
+ </integer>
+ </parameters>
+</executable>
+\endcode
+
+This XML description is used for automatic user interface generation in MITK Workbench. The generated user interface is depicted in the following screenshot:
+\imageMacro{generated_ui_tensor_reconstruction.png, "Generated UI of TensorReconstruction command line tool in MITK Workbench", 10}
+
+\section MiniAppCommandLineToolHowToPageWorkbenchIntegration Integrating a command line tool into MITK Workbench
+
+At current state of development MiniApps are not fully supported by the MITK Workbench.
+Nevertheless, there's a workaround for integrating command line tools via the Command Line Modules plug-in:
+
+Create an executable file (e.g. sh-file using Linux OS or bat-file using Windows OS) in the directory where your MiniApp binary is located.
+The sh-file for the \ref TensorReconstruction command line tool has following content:
+
+\code
+#!/bin/bash
+if [[ $1 == "--xml" || $1 == "--XML" ]];
+then
+ echo '
+ <executable>
+ <category>Preprocessing Tools</category>
+ <title>Tensor Reconstruction</title>
+ <description>Takes a .dwi, .fsl/.fslgz file as input and saves the computed reconstructed tensor to the specified file. It also allows for a threshold to be set, to exclude low b values from the reconstruction process.</description>
+ <contributor>MBI</contributor>
+ <parameters>
+ <label>Parameters</label>
+ <description>Groupbox containing parameters.</description>
+ <file>
+ <name>input</name>
+ <label>Input file</label>
+ <description>input raw dwi (.dwi or .fsl/.fslgz)</description>
+ <longflag>input</longflag>
+ <flag>i</flag>
+ <channel>input</channel>
+ </file>
+ <file>
+ <name>outFile</name>
+ <label>Output file</label>
+ <description>output file</description>
+ <longflag>outFile</longflag>
+ <flag>o</flag>
+ <channel>output</channel>
+ </file>
+ <integer>
+ <name>b0Threshold</name>
+ <label>b0 threshold</label>
+ <description>baseline image intensity threshold</description>
+ <longflag>b0Threshold</longflag>
+ <flag>t</flag>
+ </integer>
+ </parameters>
+ </executable>
+ '
+else
+ BASEDIR=$(dirname $0)
+ echo "Calling parameters" $*
+ $BASEDIR/MitkDiffusionMiniApps TensorReconstruction $*
+fi
+\endcode
+
+For each command line tool the including MiniApp binary, the concrete command line tool name, and its XML output have to be specified.
+
+The executable file has be to be anncounced in MITK Workbench. This can be done in Preferences window:
+Click 'Window' -> 'Preferences', and select 'Command Line Modules'. You can add directories containing executable files or you can select single executable files.
+Click 'OK' button.
+The configured command line tools are now available via the drop-down box of the Command Line Modules tab.
+
+*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/MiniAppCommandLineTool/images/generated_ui_tensor_reconstruction.png b/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/MiniAppCommandLineTool/images/generated_ui_tensor_reconstruction.png
new file mode 100644
index 0000000000..7de0734e66
Binary files /dev/null and b/Documentation/Doxygen/DeveloperManual/Starting/FirstSteps/MiniAppCommandLineTool/images/generated_ui_tensor_reconstruction.png differ
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step01.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step01.dox
index 652617c041..b7a04677ab 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step01.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step01.dox
@@ -1,27 +1,27 @@
/**
\page Step01Page MITK Tutorial - Step 1: Displaying an image
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd
+http://mitk.org/download/tutorial-data/Pic3D.nrrd
\imageMacro{step1_result.png,"",6.22}
Open your IDE. All steps can be found among the listed projects.
The first program shows how to display an image in a 2D view. The picture above is a screenshot of the program.
The program has to be executed using the image file Pic3D.nrrd.
If you are using Visual Studio use the StartVS_release.bat in your bin\\ subdirectory to start it with all required paths set.
To set the image file path in Visual Studio, right click on "MitkStep1"-project and go to 'Properties -> Configuration Properties -> Debugging'.
Now insert the image file path to Pic3D.nrrd in the "Command Arguments" text field.
Then right click on the "MitkStep1"-project again and select "Set as StartUp Project". Start to run the code. Use this also in the following steps.
\imageMacro{configureVisualStudioProperties.png,"",11.85}
The code is divided into parts I through V. First of all a DataTree has to be created. Then data has to be read from a file which afterwards has to be put into the tree. Part IV creates a window and passes the tree to it. The last part deals with some Qt-specific initialization.
\include Step1.cpp
\ref Step00Page "[Previous step]" \ref Step02Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step02.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step02.dox
index bd35b8bae2..f74f894583 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step02.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step02.dox
@@ -1,34 +1,34 @@
/**
\page Step02Page MITK Tutorial - Step 2: Load one or more data sets
\li \ref Step2.cpp "Step2.cpp" \n
Contains the code for this example.
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image) \n
-.../MITK/Modules/Segmentation/Testing/Data/lungs.vtk (surface)
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image) \n
+http://mitk.org/download/tutorial-data/lungs.vtk (surface)
\image html step2_result.png
\dontinclude Step2.cpp
This program shows how to load multiple data sets.
A DataNodeFactory is used to produce nodes containing the data.
The picture above shows the result of the program when reading both the image file and the surface file.
In order to obtain the result the program has to be executed using the image file Pic3D.nrrd and the surface file lungs.vtk.
The code for this example equals the code of Step 1 except for part II and part III which are changed as follows:
\skipline Part II
\until exit(2)
\line }
\line }
\ref Step01Page "[Previous step]" \ref Step03Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step03.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step03.dox
index 9cb98dc0fd..fa6556de5e 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step03.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step03.dox
@@ -1,51 +1,51 @@
/**
\page Step03Page MITK Tutorial - Step 3: Create 3D view
\li \ref Step3.cpp "Step3.cpp" \n
Contains the code that both creates a 3D view and turns volume rendering on.
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image) \n
-.../MITK/Modules/Segmentation/Testing/Data/lungs.vtk (surface)
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image) \n
+http://mitk.org/download/tutorial-data/lungs.vtk (surface)
As in the previous step, one or more data sets (many images, surface and other formats) may be loaded. The difference is that they are displayed in a 3D view.
The QmitkRenderWindow is now used for displaying a 3D view, by setting the used mapper-slot to Standard3D.
Since volume-rendering is a (rather) slow procedure, the default is that images are not displayed in the 3D view.
In Step 3a the default is kept whereas in Step 3b volume rendering is turned on.
As in the previous step, to obtain the result the program has to be executed using the image file Pic3D.nrrd and the surface file lungs.vtk.
\section Step3aSection Step 3a - Volume rendering turned off
\imageMacro{step3a_result.png,"",6.22}
\dontinclude Step3.cpp
Tell the renderer to create a 3D view:
\skipline // Use it as a 3D view!
\skipline renderWindow.GetRenderer()->SetMapperID
The rest of the code remains unchanged.
The picture above shows the result of the program when reading both the image and the surface file.
As volume rendering is off the image is not visible.
\section Step3bSection Step 3b - Volume rendering turned on
\imageMacro{step3b_result.png,"",6.22}
Volume Rendering is now turned on as shown in the picture above.
\dontinclude Step3.cpp
The property "volumerendering" has to be enabled on the node containing the image.
\skipline Check
\until node->SetProperty
\ref Step02Page "[Previous step]" \ref Step04Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step04.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step04.dox
index 7bd72c0dbe..e90951aa98 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step04.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step04.dox
@@ -1,69 +1,69 @@
/**
\page Step04Page MITK Tutorial - Step 4: Use several views to explore data
\li \ref Step4.cpp "Step4.cpp"\n
Contains the code of step 4a + b.
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image) \n
-.../MITK/Modules/Segmentation/Testing/Data/lungs.vtk (surface)
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image) \n
+http://mitk.org/download/tutorial-data/lungs.vtk (surface)
As in Step 2 and Step 3 one or more data sets may be loaded.
This now creates three views on the data.
The QmitkRenderWindow is used for displaying a 3D view as in Step 3, but without volume-rendering.
Furthermore two 2D views for slicing through the data are created.
The class QmitkSliceWidget is used, which is based on the class QmitkRenderWindow, but additionally provides sliders to slice through the data. We create two instances of
QmitkSliceWidget, one for axial and one for sagittal slicing.
Step 4b enhances the program in that the two slices are also shown at their correct position in 3D as well as intersection-line, each in the other 2D view.
As in the previous steps, to obtain the result the program has to be executed using the image file Pic3D.nrrd and the surface file lungs.vtk.
\section Step4aSection Step 4a - Create axial and sagittal view
\imageMacro{step4a_result.png,"",11.01}
\dontinclude Step4.cpp
Create a Qt horizontal box for the layout:
\skipline QHBox
Then create a renderwindow:
\skipline QmitkRenderWindow
\until SetMapperID
Create a 2D view for slicing axially:
\skipline view2
\until view2.SetData
Then create a 2D view for slicing sagitally.
\skipline view3
\until view3.SetData
The toplevelWidget is now the new main widget:
\skipline qtapplication
\skipline toplevelWidget.show
\section Step4bSection Step 4b - Display slice positions
\imageMacro{step4b_result.png,"",11.01}
We now want to see the position of the slice in 2D and the slice itself in 3D.
Therefore it has to be added to the tree:
\dontinclude Step4.cpp
\skipline ds->Add(view2.GetRenderer()
\skipline ds->Add(view3.GetRenderer()
Slice positions are now displayed as shown in the picture.
\dontinclude Step4.cpp
\ref Step03Page "[Previous step]" \ref Step05Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step05.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step05.dox
index d292aa832b..7e7a42d57a 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step05.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step05.dox
@@ -1,41 +1,41 @@
/**
\page Step05Page MITK Tutorial - Step 5: Interactively add points
-
+
\li \ref Step5.cpp "Step5.cpp"\n
Contains the code for this step.
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image) \n
-.../MITK/Modules/Segmentation/Testing/Data/lungs.vtk (surface)
-
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image) \n
+http://mitk.org/download/tutorial-data/lungs.vtk (surface)
+
In addition to Step 4 where 3 views were created on the data, we now want to interactively add points.
A node containing a PointSet as data is added to the data tree and a PointSetDataInteractor is associated with the node, which handles the interaction.
The @em interaction @em pattern is defined in a state-machine, stored in an external XML file. Thus, we need to load a state-machine.
A state machine describes interaction pattern with different states (states beeing something like "a point is selected") and transitions to these states (e.g. "select a point").
These transitions are associated with actions. In this way it is possible to model complex interaction schemes.
By what these transitions and actions are triggered is described in a configuration file. It maps user events to identifiers that are used in the state machine patterns.
In this way the user interaction can be changed by simply loading a different configuration file for a state machine, and the user may add points now with a right click instead of
left click + SHIFT, as in our case.
Therefore after loading the state machine pattern the PointSetDataInteractor is also given a event configuration file.
More information about interaction in MITK can be found \ref InteractionPage "here".
In order to add a point the shift key has to be pressed while left clicking in a render window.
You can also move points or remove them (left click while pressing ALT).
\image html step5_result.png
\dontinclude Step5.cpp
A PointSet and a node for it have to be created to be able to interactively adding points:
\skipline mitk::PointSet
\until interactor->SetDataNode(pointSetNode)
\ref Step04Page "[Previous step]" \ref Step06Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step06.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step06.dox
index d36da763a6..e7709887ea 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step06.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step06.dox
@@ -1,118 +1,118 @@
/**
\page Step06Page MITK Tutorial - Step 6: Use an interactive region-grower
The source is now split among several files:
-\li \ref Step6.cpp "Step6.cpp"
-\li \ref Step6.h "Step6.h"
+\li \ref Step6.cpp "Step6.cpp"
+\li \ref Step6.h "Step6.h"
\li \ref Step6RegionGrowing.txx "Step6RegionGrowing.txx"
\li \ref Step6RegionGrowing1.cpp "Step6RegionGrowing1.cpp"
\li \ref Step6RegionGrowing2.cpp "Step6RegionGrowing2.cpp"
\li \ref Step6main.cpp "Step6main.cpp"
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image)
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image)
In this step the program is enhanced by the possibility to start a region-grower at interactively added points.
We will see how MITK images can be accessed as ITK images.
We now load the image file Pic3D.nrrd only since the surface will be the result of the region-growing.
Add points in the image by pressing SHIFT+left mouse key, then adjust the thresholds and press 'Start region growing'.
\imageMacro{step6_result.png,"",13.55}
The class Step6 inherits from QWidget and provides methods for setting up the widgets.
Step6RegionGrowing.cpp contains a method for performing the region-growing. Step6main.cpp contains main.
Like in ITK and VTK class member names start with m_ followed by the proper member name starting with a capital letter (e.g. m_Tree).
Function names start with capital letters. To learn more about style conventions in MITK read \ref StyleGuideAndNotesPage "The MITK Style Guide".
\dontinclude Step6.cpp
The widgets are initialized as in the previous steps but with an additional QVBox for a button to start the segmentation:
\skipline Create controlsParent
\until hlayout->addWidget(m_LineEditThresholdMax)
This creates a button to start the segmentation and its clicked() signal is connected to the method StartRegionGrowing():
\dontinclude Step6.cpp
\skipline QPushButton* startButton
\skipline connect(startButton
\section AccessMTIKImagesAsITKImagesSection Access MITK images as ITK images
ITK images are templated whereas mitk::Images are not. To use ITK filters with MITK images, we have to convert from MITK to ITK. To do so, first
define an access method, which is templated as an ITK image is:
\code
template<TPixel, VImageDimension>
MyAccessMethod(itk::Image<TPixel, VImageDimension>* itkImage)
{
...
}
\endcode
If you don't understand this template syntax, you should read any C++ text book. Understanding template syntax is crucial to successfully using ITK.
To call this templated method with an (untemplated) mitk::Image, you can use the AccessByItk macro from mitkImageAccessByItk.h. This macro checks for
the actual image type of the mitk::Image and does any neccessary conversions. Look into "Modules / Adaptor classes" for more information.
\code
AccessByItk(mitkImage, MyAccessMethod)
\endcode
\dontinclude Step6RegionGrowing.txx
In this step our access method is called RegionGrowing() (defined in \ref Step6RegionGrowing.txx "Step6RegionGrowing.txx"):
\skipline template
\until }
\until }
Additionally the access function has to be instantiated for all datatypes and two/three dimensions as some compilers have memory problems without this explicit instantiation, some even need instantiations in separate files for 2D/3D: \n
For 2D in \ref Step6RegionGrowing1.cpp "Step6RegionGrowing1.cpp" :
\dontinclude Step6RegionGrowing1.cpp
\skipline InstantiateAccessFunctionForFixedDimension_1
... and for 3D in \ref Step6RegionGrowing2.cpp "Step6RegionGrowing2.cpp":
\dontinclude Step6RegionGrowing2.cpp
\skipline InstantiateAccessFunctionForFixedDimension_1
\dontinclude Step6.cpp
The method StartRegionGrowing() finally calls our access method RegionGrowing():
\skipline Step6::StartRegionGrowing
\until }
\section ConvertingITKMITKSection Converting ITK images to MITK images and vice versa
In some cases it is useful to simply convert between ITK and MITK images. The direction ITK to MITK is easy, since mitk::Image can handle most data types. The direction MITK to ITK is more critical, since ITK images have to be instantiated with a fixed pixel type and fixed dimension at compile time.
\li \code mitk::Image mitk::ImportItkImage(itk::Image<...>) \endcode
\li \code mitk::CastToItkImage(mitkImage, itk::Image<...>) \endcode
\section ConnectingMITKToVTKSection Connecting MITK images to VTK
Images are not converted or copied: The data array is just accessed via an encapsulating VTK object.
\li \code vtkImageData* mitk::Image::GetVtkImageData(int time = 0) \endcode
\section SurfacesMITKToVTKSection MITK Surfaces to VTK and vice versa
Again: not a conversion, just accessing.
\li \code vtkPolyData* mitk::Surface::GetVtkPolyData(int time = 0) \endcode
\li \code mitk::Surface::SetVtkPolyData(vtkPolyData*, int time = 0) \endcode
\ref Step05Page "[Previous step]" \ref Step07Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step07.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step07.dox
index 963460f55f..c3006dd5e0 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step07.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step07.dox
@@ -1,21 +1,21 @@
/**
-
+
\page Step07Page MITK Tutorial - Step 7: Convert result of region growing into a surface
-
- \li \ref Step7.cpp "Step7.cpp"\n
- \li \ref Step7.h "Step7.h"\n
- \li \ref Step7main.cpp "Step7main.cpp"\n
+
+ \li \ref Step7.cpp "Step7.cpp"\n
+ \li \ref Step7.h "Step7.h"\n
+ \li \ref Step7main.cpp "Step7main.cpp"\n
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image)
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image)
In this step the result of the previous step is converted into a surface by means of a VTK filter.
-
- Step7 inherits from Step6. It enhances the method StartRegionGrowing() by processing the result image.
-
+
+ Step7 inherits from Step6. It enhances the method StartRegionGrowing() by processing the result image.
+
\dontinclude Step7.cpp
\skipline if(m_ResultImage
\until }
-
+
\ref Step06Page "[Previous step]" \ref Step08Page "[Next step]" \ref TutorialPage "[Main tutorial page]"
-
- */
\ No newline at end of file
+
+ */
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step08.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step08.dox
index e5a7d8c13d..2e3562b004 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step08.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step08.dox
@@ -1,25 +1,25 @@
/**
-
+
\page Step08Page MITK Tutorial - Step 8: Use QmitkStdMultiWidget as widget
-
- \li \ref Step8.cpp "Step8.cpp"\n
- \li \ref Step8.h "Step8.h"\n
- \li \ref Step8main.cpp "Step8main.cpp"\n
+
+ \li \ref Step8.cpp "Step8.cpp"\n
+ \li \ref Step8.h "Step8.h"\n
+ \li \ref Step8main.cpp "Step8main.cpp"\n
\li Path to files used in this step: \n
-.../bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd (image)
+http://mitk.org/download/tutorial-data/Pic3D.nrrd (image)
In this step a QmitkStdMultiWidget is used. It offers four views of the data.
From top left to bottom left the views are initialized as axial, sagittal and coronar. The bottom right view is initialized as 3D view.
-
+
\image html step8_result.png
-
+
Step8 inherits from Step6. The method SetupWidgets() is changed: A QmitkStdMultiWidget is used instead of one QmitkRenderWindow and two instances of QmitkSliceWidget.
-
+
\dontinclude Step8.cpp
\skipline Part Ia
\until EnableNavigationControllerEventListening
-
-
+
+
\ref Step07Page "[Previous step]" \ref Step09Page "[Next step]"
-
+
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Tutorial.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Tutorial.dox
index e32a0baf93..c556bd47af 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Tutorial.dox
+++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Tutorial.dox
@@ -1,46 +1,46 @@
/**
\page TutorialPage The MITK Tutorial
If you have set up and compiled MITK already and want to know more about developing with MITK you might want to read the \ref TutorialSection. If you want help setting up MITK and creating your own project using MITK you should take a look at \ref HowToNewProject.
\section TutorialFirstSteps First steps in MITK
If you are absolutely new to MITK you might want to read up on setting up MITK to use in your development. The following pages will help you in this task.
<ul>
<li> \subpage HowToNewProject "A comprehensive guide to setting up your own MITK project"
<li> \ref BuildInstructionsPage "Building MITK"
<li> \ref CMAKE_FAQ
</ul>
\section TutorialSection Tutorial chapters
This tutorial will give you an introduction to developing with MITK.
We will start with configuring MITK to compile the tutorial, continue to show how to
display and do basic interaction with images, and finally show how to build a plug-in and add new interactions.
-The source code of the examples can be found in mitk/QApplications/Tutorial/ \n
+The source code of the examples can be found in Examples/Tutorial/ \n
Two data files are used to execute the example code.
\li Pic3D.nrrd \n
-This file contains an image and is located in bin/CMakeExternals/Source/MITK-Data/Pic3D.nrrd.
+This file contains an image and can be downloaded from http://mitk.org/download/tutorial-data/Pic3D.nrrd .
\li lungs.vtk \n
-This file contains a surface and is located in src/MITK/Modules/MitkExt/Testing/Data/lungs.vtk.
+This file contains a surface and can be downloaded from http://mitk.org/download/tutorial-data/lungs.vtk .
\li \subpage Step00Page "Step 0: Getting started"
\li \subpage Step01Page "Step 1: Displaying an image"
\li \subpage Step02Page "Step 2: Load one or more data sets"
\li \subpage Step03Page "Step 3: Create 3D view"
\li \subpage Step04Page "Step 4: Use several views to explore data"
\li \subpage Step05Page "Step 5: Interactively add points"
\li \subpage Step06Page "Step 6: Use an interactive region-grower"
\li \subpage Step07Page "Step 7: Convert result of region growing into a surface"
\li \subpage Step08Page "Step 8: Use QmitkStdMultiWidget as widget"
\li \subpage Step09Page "Step 9: A plug-in"
\li \subpage Step10Page "Step 10: How to use Interactor and how to implement new ones"
Enjoy MITK!
*/
diff --git a/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox b/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox
index 6e43c61bb7..978c30e49a 100644
--- a/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox
+++ b/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox
@@ -1,26 +1,27 @@
/**
\page MITKModuleManualsListPage MITK Module Manuals
\section MITKModuleManualsListPageOverview Overview
The modules are shared libraries that provide functionality that can be used by developers.
\section MITKModuleManualsListPageModuleManualList List of Module Manuals
\li \subpage IGTGeneralModulePage
\li \subpage MitkOpenCL_Overview
\li \subpage GeneratingDeviceModulesPage
\li \subpage mitkPython_Overview
\li \subpage USModulePage
+ \li \subpage OverlaysModulePage
\section MITKModuleManualsListPageAdditionalInformation Additional Information on Certain Modules
\li \ref PlanarPropertiesPage
\li \subpage DiffusionImagingPropertiesPage
\li \subpage ConnectomicsRenderingPropertiesPage
\section MITKMigrationGuides Migration Guides
\li \subpage InteractionMigration
\li \subpage GeometryMigration
*/
diff --git a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox
index 10c00d997a..884e29b1c9 100644
--- a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox
+++ b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox
@@ -1,44 +1,45 @@
/**
\page PluginListPage MITK Plugin Manuals
\section PluginListPageOverview Overview
The plugins and bundles provide much of the extended functionality of MITK. Each encapsulates a solution to a problem and associated features. This way one can easily assemble the necessary capabilites for a workflow without adding a lot of bloat, by combining plugins as needed.
The distinction between developer and end user use is for convenience only and mainly distinguishes which group a plugin is primarily aimed at.
\section PluginListPageEndUserPluginList List of Plugins for End User Use
\li \subpage org_blueberry_ui_qt_log
\li \subpage org_mitk_views_basicimageprocessing
\li \subpage org_mitk_views_cmdlinemodules
\li \subpage org_mitk_views_datamanager
\li \subpage org_mitk_gui_qt_dicom
\li \subpage org_mitk_gui_qt_diffusionimaging
\li \subpage org_mitk_views_imagecropper
\li \subpage org_mitk_views_imagenavigator
\li \subpage org_mitk_gui_qt_measurementtoolbox
\li \subpage org_mitk_views_meshdecimation
\li \subpage org_mitk_views_moviemaker
\li \subpage org_mitk_views_pointsetinteraction
\li \subpage org_mitk_gui_qt_python
\li \subpage org_mitk_gui_qt_registration
\li \subpage org_mitk_gui_qt_remeshing
\li \subpage org_mitk_views_segmentation
\li \subpage org_mitk_gui_qt_ultrasound
+ \li \subpage org_mitk_gui_qt_viewnavigator
\li \subpage org_mitk_views_volumevisualization
\li \subpage org_mitk_gui_qt_xnat
\section PluginListPageDevPluginList List of Plugins for Developer Use and Examples
\li \subpage org_surfacematerialeditor
\li \subpage org_toftutorial
\li \subpage org_mitk_gui_qt_examples
\li \subpage org_mitkexamplesopencv
\li \subpage org_mitk_gui_qt_igtexample
\li \subpage org_mitk_gui_qt_igttracking
\li \subpage org_blueberry_ui_qt_objectinspector
\li \subpage org_mitk_gui_qt_eventrecorder
*/
diff --git a/Documentation/Doxygen/UserManual/MiniApps.dox b/Documentation/Doxygen/UserManual/MiniApps.dox
index 104522399f..7b7af0fa00 100644
--- a/Documentation/Doxygen/UserManual/MiniApps.dox
+++ b/Documentation/Doxygen/UserManual/MiniApps.dox
@@ -1,70 +1,70 @@
/**
\page MiniAppExplainPage MITK MiniApps
-\section MiniAppDescription What are MiniApps
+\section MiniAppExplainPageDescription What are MiniApps
MiniApps are small compilations of command line tools. Each of these tools is designed to fulfill one simple task,
e.g. resample an image or extract image statistics of a given region of interest (ROI). Several tools that relate to
-a similiar topic or research area are grouped into one MiniApp.
+a similar topic or research area are grouped into one MiniApp.
They are intended to provide command line access to a variety of features of MITK, thus facilitating batched processing of data.
-\section MiniAppUsage Usage
+\section MiniAppExplainPageUsage Usage
-The MiniApps are built in a self-describing way. When calling a MiniApp without any arguements it will list
+The MiniApps are built in a self-describing way. When calling a MiniApp without any arguments it will list
all available sub-tools. When calling e.g. the DiffusionMiniApp it will look similarly to this:
\code
$./MitkDiffusionMiniApps
Please choose the mini app to execute:
(0) BatchedFolderRegistration
(1) CopyGeometry
(2) DicomFolderDump
(3) DiffusionIndices
(4) DwiDenoising
(5) ExportShImage
(6) ExtractImageStatistics
(7) FiberDirectionExtraction
(8) FiberProcessing
(9) FileFormatConverter
(10) GibbsTracking
(11) LocalDirectionalFiberPlausibility
(12) MultishellMethods
(13) NetworkCreation
(14) NetworkStatistics
(15) PeakExtraction
(16) PeaksAngularError
(17) QballReconstruction
(18) StreamlineTracking
(19) TensorDerivedMapsExtraction
(20) TensorReconstruction
Please select:
\endcode
In order to select one of those tools simply append the displayed name to call, e.g. GibbsTracking
this will provide a listing of the parameters of that tool:
\code
-$./MitkDiffusionMiniApps GibbsTracking
+$./MitkDiffusionMiniApps GibbsTracking
[1.081] Start GibbsTracking ..
-i, --input, input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)
-p, --parameters, parameter file (.gtp)
-m, --mask, binary mask image (optional)
-s, --shConvention, sh coefficient convention (FSL, MRtrix) (optional), (default: FSL)
-o, --outFile, output fiber bundle (.fib)
-f, --noFlip, do not flip input image to match MITK coordinate convention (optional)
\endcode
To execute the tool with parameters an exemplary call would look like this:
\code
-$./MitkDiffusionMiniApps GibbsTracking -i test.dti -p param.gtp -o /tmp/fiber.fib
+$./MitkDiffusionMiniApps GibbsTracking -i test.dti -p param.gtp -o /tmp/fiber.fib
\endcode
-\section MiniAppAvailableList Available MiniApps
+\section MiniAppExplainPageAvailableList Available MiniApps
-\li \ref DiffusionMiniApps
+\li \subpage DiffusionMiniApps
*/
diff --git a/MITKConfig.cmake.in b/MITKConfig.cmake.in
index d4c40e210a..870631e385 100644
--- a/MITKConfig.cmake.in
+++ b/MITKConfig.cmake.in
@@ -1,201 +1,204 @@
# Update the CMake module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@MITK_SOURCE_DIR@/CMake")
set(CppMicroServices_DIR "@MITK_BINARY_DIR@/Core/CppMicroServices")
# Include MITK macros
include(MacroParseArguments)
include(mitkFunctionCheckMitkCompatibility)
include(mitkFunctionOrganizeSources)
include(mitkFunctionCreateWindowsBatchScript)
include(mitkFunctionInstallProvisioningFiles)
include(mitkFunctionInstallAutoLoadModules)
include(mitkFunctionGetLibrarySearchPaths)
include(mitkFunctionUseModules)
include(mitkMacroCreateModuleConf)
include(mitkFunctionCheckModuleDependencies)
include(mitkFunctionCreateModule)
include(mitkMacroCreateExecutable)
include(mitkMacroCheckModule)
include(mitkMacroCreateModuleTests)
include(mitkFunctionAddCustomModuleTest)
include(mitkMacroUseModule)
include(mitkMacroMultiplexPicType)
include(mitkMacroInstall)
include(mitkMacroInstallHelperApp)
include(mitkMacroInstallTargets)
include(mitkMacroGenerateToolsLibrary)
include(mitkMacroCreateCTKPlugin)
include(mitkMacroGetPMDPlatformString)
# Standard CMake macros
include(FeatureSummary)
# The MITK version number
set(MITK_VERSION_MAJOR "@MITK_VERSION_MAJOR@")
set(MITK_VERSION_MINOR "@MITK_VERSION_MINOR@")
set(MITK_VERSION_PATCH "@MITK_VERSION_PATCH@")
set(MITK_VERSION_STRING "@MITK_VERSION_STRING@")
# MITK compiler flags
set(MITK_C_FLAGS "@MITK_C_FLAGS@")
set(MTTK_C_FLAGS_DEBUG "@MITK_C_FLAGS_DEBUG@")
set(MITK_C_FLAGS_RELEASE "@MITK_C_FLAGS_RELEASE@")
set(MITK_CXX_FLAGS "@MITK_CXX_FLAGS@")
set(MTTK_CXX_FLAGS_DEBUG "@MITK_CXX_FLAGS_DEBUG@")
set(MITK_CXX_FLAGS_RELEASE "@MITK_CXX_FLAGS_RELEASE@")
set(MITK_EXE_LINKER_FLAGS "@MITK_EXE_LINKER_FLAGS@")
set(MITK_SHARED_LINKER_FLAGS "@MITK_SHARED_LINKER_FLAGS@")
set(MITK_MODULE_LINKER_FLAGS "@MITK_MODULE_LINKER_FLAGS@")
# Internal version numbers, used for approximate compatibility checks
# of a MITK development version (non-release).
set(MITK_VERSION_PLUGIN_SYSTEM 2) # dropped legacy BlueBerry plug-in CMake support
# MITK specific variables
set(MITK_SOURCE_DIR "@MITK_SOURCE_DIR@")
set(MITK_BINARY_DIR "@MITK_BINARY_DIR@")
set(MITK_CMAKE_DIR "@MITK_CMAKE_DIR@")
set(UTILITIES_DIR "@UTILITIES_DIR@")
set(REGISTER_QFUNCTIONALITY_CPP_IN "@REGISTER_QFUNCTIONALITY_CPP_IN@")
set(MITK_MODULES_PACKAGE_DEPENDS_DIR "@MITK_MODULES_PACKAGE_DEPENDS_DIR@")
set(MODULES_PACKAGE_DEPENDS_DIRS "@MODULES_PACKAGE_DEPENDS_DIRS@")
set(MITK_DOXYGEN_TAGFILE_NAME "@MITK_DOXYGEN_TAGFILE_NAME@")
if(MODULES_CONF_DIRS)
list(APPEND MODULES_CONF_DIRS "@MODULES_CONF_DIRS@")
list(REMOVE_DUPLICATES MODULES_CONF_DIRS)
else()
set(MODULES_CONF_DIRS "@MODULES_CONF_DIRS@")
endif()
set(MODULES_CONF_DIRNAME "@MODULES_CONF_DIRNAME@")
foreach(_module @MITK_MODULE_NAMES@)
set(${_module}_CONFIG_FILE "@MITK_BINARY_DIR@/@MODULES_CONF_DIRNAME@/${_module}Config.cmake")
endforeach()
# External projects
set(CTK_DIR "@CTK_DIR@")
set(ANN_DIR "@ANN_DIR@")
set(CppUnit_DIR "@CppUnit_DIR@")
set(GLEW_DIR "@GLEW_DIR@")
set(tinyxml_DIR "@tinyxml_DIR@")
set(ITK_DIR "@ITK_DIR@")
set(VTK_DIR "@VTK_DIR@")
set(DCMTK_DIR "@DCMTK_DIR@")
set(GDCM_DIR "@GDCM_DIR@")
set(BOOST_ROOT "@BOOST_ROOT@")
set(OpenCV_DIR "@OpenCV_DIR@")
set(Poco_DIR "@Poco_DIR@")
set(SOFA_DIR "@SOFA_DIR@")
set(Qwt_DIR "@Qwt_DIR@")
set(Qxt_DIR "@Qxt_DIR@")
set(ACVD_DIR "@ACVD_DIR@")
set(MITK_QMAKE_EXECUTABLE "@QT_QMAKE_EXECUTABLE@")
set(MITK_DATA_DIR "@MITK_DATA_DIR@")
+set(SimpleITK_DIR "@SimpleITK_DIR@")
+set(Python_DIR "@Python_DIR@")
# External SDK directories
set(MITK_PMD_SDK_DIR @MITK_PMD_SDK_DIR@)
# MITK use variables
set(MITK_USE_QT @MITK_USE_QT@)
set(MITK_USE_Qt4 @MITK_USE_Qt4@)
set(MITK_USE_Qt5 @MITK_USE_Qt5@)
set(MITK_DESIRED_QT_VERSION @DESIRED_QT_VERSION@)
set(MITK_USE_BLUEBERRY @MITK_USE_BLUEBERRY@)
set(MITK_USE_SYSTEM_Boost @MITK_USE_SYSTEM_Boost@)
set(MITK_USE_Boost @MITK_USE_Boost@)
set(MITK_USE_Boost_LIBRARIES @MITK_USE_Boost_LIBRARIES@)
set(MITK_USE_CTK @MITK_USE_CTK@)
set(MITK_USE_DCMTK @MITK_USE_DCMTK@)
set(MITK_USE_OpenCV @MITK_USE_OpenCV@)
set(MITK_USE_SOFA @MITK_USE_SOFA@)
set(MITK_USE_Python @MITK_USE_Python@)
+set(MITK_USE_SimpleITK @MITK_USE_SimpleITK@)
set(MITK_USE_ACVD @MITK_USE_ACVD@)
if(MITK_USE_Qt4)
set(MITK_QT4_MINIMUM_VERSION @MITK_QT4_MINIMUM_VERSION@)
find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED)
elseif(MITK_USE_Qt5)
set(MITK_QT5_MINIMUM_VERSION @MITK_QT5_MINIMUM_VERSION@)
find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
endif()
# MITK ToF use variables
set(MITK_TOF_PMDCAMCUBE_AVAILABLE @MITK_USE_TOF_PMDCAMCUBE@)
if(MITK_TOF_PMDCAMCUBE_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_PMDCAMCUBE "Enable support for PMD Cam Cube" @MITK_USE_TOF_PMDCAMCUBE@)
mark_as_advanced(MITK_USE_TOF_PMDCAMCUBE)
endif()
set(MITK_TOF_PMDCAMBOARD_AVAILABLE @MITK_USE_TOF_PMDCAMBOARD@)
if(MITK_TOF_PMDCAMBOARD_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_PMDCAMBOARD "Enable support for PMD Cam Board" @MITK_USE_TOF_PMDCAMBOARD@)
mark_as_advanced(MITK_USE_TOF_PMDCAMBOARD)
endif()
set(MITK_TOF_PMDO3_AVAILABLE @MITK_USE_TOF_PMDO3@)
if(MITK_TOF_PMDO3_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_PMDO3 "Enable support for PMD =3" @MITK_USE_TOF_PMDO3@)
mark_as_advanced(MITK_USE_TOF_PMDO3)
endif()
set(MITK_TOF_KINECT_AVAILABLE @MITK_USE_TOF_KINECT@)
if(MITK_TOF_KINECT_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_KINECT "Enable support for Kinect" @MITK_USE_TOF_KINECT@)
mark_as_advanced(MITK_USE_TOF_KINECT)
endif()
set(MITK_TOF_MESASR4000_AVAILABLE @MITK_USE_TOF_MESASR4000@)
if(MITK_TOF_MESASR4000_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_MESASR4000 "Enable support for MESA SR4000" @MITK_USE_TOF_MESASR4000@)
mark_as_advanced(MITK_USE_TOF_MESASR4000)
endif()
if(MITK_USE_IGT)
#include("${MITK_DIR}/mitkIGTConfig.cmake")
endif()
# Install rules for ToF libraries loaded at runtime
include("@MITK_BINARY_DIR@/mitkToFHardwareInstallRules.cmake")
if(NOT MITK_EXPORTS_FILE_INCLUDED)
if(EXISTS "@MITK_EXPORTS_FILE@")
set(MITK_EXPORTS_FILE_INCLUDED 1)
include("@MITK_EXPORTS_FILE@")
endif()
endif()
# BlueBerry support
if(MITK_USE_BLUEBERRY)
set(BlueBerry_DIR "@MITK_BINARY_DIR@/BlueBerry")
# Don't include the BlueBerry exports file, since the targets are
# also exported in the MITK exports file
set(BB_PLUGIN_EXPORTS_FILE_INCLUDED 1)
find_package(BlueBerry)
if(NOT BlueBerry_FOUND)
message(SEND_ERROR "MITK does not seem to be configured with BlueBerry support. Set MITK_USE_BLUEBERRY to ON in your MITK build configuration.")
endif()
set(MITK_PLUGIN_USE_FILE "@MITK_PLUGIN_USE_FILE@")
if(MITK_PLUGIN_USE_FILE)
if(EXISTS "${MITK_PLUGIN_USE_FILE}")
include("${MITK_PLUGIN_USE_FILE}")
endif()
endif()
set(MITK_PLUGIN_PROVISIONING_FILE "@MITK_EXTAPP_PROVISIONING_FILE@")
set(MITK_PROVISIONING_FILES
"${BLUEBERRY_PLUGIN_PROVISIONING_FILE}"
"${MITK_PLUGIN_PROVISIONING_FILE}")
endif()
# Set properties on exported targets
@MITK_EXPORTED_TARGET_PROPERTIES@
diff --git a/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.cpp b/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.cpp
index 477cb374a9..4407ad5e75 100644
--- a/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.cpp
+++ b/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.cpp
@@ -1,163 +1,163 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSimpleUnstructuredGridHistogram.h"
#include <mitkUnstructuredGrid.h>
#include <itkSampleToHistogramFilter.h>
#include <vtkDataArray.h>
#include <vtkPointData.h>
#include <vtkUnstructuredGrid.h>
namespace mitk {
SimpleUnstructuredGridHistogram::SimpleUnstructuredGridHistogram()
: m_UGHistogram(HistogramType::New()), m_InvMaxFrequency(1)
{
//MITK_INFO << "####### Created a SimpleUnstructuredGridHistogram";
}
double SimpleUnstructuredGridHistogram::GetMin() const
{
return m_UGHistogram->GetBinMin(0, 0);
}
double SimpleUnstructuredGridHistogram::GetMax() const
{
return m_UGHistogram->GetBinMax(0, m_UGHistogram->GetSize(0)-1);
}
void SimpleUnstructuredGridHistogram::ComputeFromBaseData( BaseData* source )
{
UnstructuredGrid* grid = dynamic_cast<UnstructuredGrid*>(source);
//m_UGHistogram->Initialize(grid);
vtkUnstructuredGrid* vtkUGrid = grid->GetVtkUnstructuredGrid();
ListSampleType::Pointer listSample = ListSampleType::New();
listSample->SetMeasurementVectorSize(1);
MeasurementVectorType v;
MeasurementVectorType lowerBound;
MeasurementVectorType upperBound;
int numberOfBins = 1;
- HistogramType::SizeType size;
+ HistogramType::SizeType size(1);
vtkDataArray* data;
/*if (m_UsePointData)*/ data = vtkUGrid->GetPointData()->GetScalars();
//else data = vtkUGrid->GetCellData()->GetScalars();
if (data == 0)
{
listSample->Resize(1);
v[0] = 0;
listSample->PushBack(v);
lowerBound[0] = 0;
upperBound[0] = 0;
size.Fill(numberOfBins);
}
else
{
listSample->Resize(data->GetNumberOfTuples());
for (vtkIdType i = 0; i < data->GetNumberOfTuples(); ++i)
{
v[0] = data->GetComponent(i, 0);
//if (v[0] != 0) MITK_INFO << "ug scalar: " << v[0];
listSample->PushBack(v);
}
vtkIdType numberOfTuples = data->GetNumberOfTuples();
if (numberOfTuples < 1000)
numberOfBins = 250;
else if (numberOfTuples < 30000)
numberOfBins = 100;
else if (numberOfTuples < 100000)
numberOfBins = 50;
else
numberOfBins = 20;
size.Fill(numberOfBins);
double range[2];
data->GetRange(range);
lowerBound[0] = range[0];
upperBound[0] = range[1];
}
typedef itk::Statistics::SampleToHistogramFilter<ListSampleType, HistogramType> FilterType;
FilterType::Pointer histoFilter = FilterType::New();
- FilterType::HistogramMeasurementVectorType binMin;
- FilterType::HistogramMeasurementVectorType binMax;
+ FilterType::HistogramMeasurementVectorType binMin(1);
+ FilterType::HistogramMeasurementVectorType binMax(1);
binMin[0] = lowerBound[0];
binMax[0] = upperBound[0];
histoFilter->SetInput(listSample);
histoFilter->SetHistogramSize(size);
histoFilter->SetHistogramBinMinimum(binMin);
histoFilter->SetHistogramBinMaximum(binMax);
histoFilter->Update();
- m_UGHistogram = histoFilter->GetOutput()->Clone();
+ m_UGHistogram = histoFilter->GetOutput();
m_BinSize = (GetMax() - GetMin())/(double)numberOfBins;
m_Mins = m_UGHistogram->GetMins();
m_Maxs = m_UGHistogram->GetMaxs();
HistogramType::AbsoluteFrequencyType maxFrequency = 0;
HistogramType::SizeValueType histoSize = m_UGHistogram->GetSize(0);
for (HistogramType::SizeValueType i = 0; i < histoSize; ++i)
{
HistogramType::AbsoluteFrequencyType f = m_UGHistogram->GetFrequency(i);
if (f > maxFrequency)
{
maxFrequency = f;
}
//MITK_INFO << "Bin #" << i << ": " << m_UGHistogram->GetMeasurement(i,0);
}
if (maxFrequency)
{
m_InvMaxFrequency = 1.0/log((double)maxFrequency);
}
//MITK_INFO << "UGHistogramm size: " << m_UGHistogram->GetSize(0) << ", maxF: " << maxFrequency
// << " min count: " << m_Mins.size() << " max count: " << m_Maxs.size();
}
float SimpleUnstructuredGridHistogram::GetRelativeBin( double start, double end ) const
{
//MITK_INFO << "GetRelativeBin start: " << start << ", end: " << end;
HistogramType::AbsoluteFrequencyType maxf = 0;
for(double pos = start; pos < end; pos += m_BinSize)
{
HistogramType::AbsoluteFrequencyType f = m_UGHistogram->GetFrequency(m_UGHistogram->GetIndex(pos));
if (f > maxf) maxf = f;
}
return log(static_cast<double>(maxf))*m_InvMaxFrequency;
}
}
diff --git a/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.h b/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.h
index a8fac7f008..93d3a2e5ad 100644
--- a/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.h
+++ b/Modules/AlgorithmsExt/mitkSimpleUnstructuredGridHistogram.h
@@ -1,61 +1,61 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKSIMPLEUNSTRUCTUREDGRIDHISTOGRAM_H
#define MITKSIMPLEUNSTRUCTUREDGRIDHISTOGRAM_H
#include <MitkAlgorithmsExtExports.h>
#include "mitkSimpleHistogram.h"
#include <itkListSample.h>
namespace mitk {
class MitkAlgorithmsExt_EXPORT SimpleUnstructuredGridHistogram : public SimpleHistogram
{
public:
SimpleUnstructuredGridHistogram();
virtual double GetMin() const;
virtual double GetMax() const;
virtual void ComputeFromBaseData( BaseData* source );
virtual float GetRelativeBin( double start, double end ) const;
private:
typedef double MeasurementType;
typedef itk::Vector<MeasurementType, 1> MeasurementVectorType;
typedef itk::Statistics::ListSample<MeasurementVectorType> ListSampleType;
typedef itk::Statistics::Histogram<MeasurementType> HistogramType;
- HistogramType::Pointer m_UGHistogram;
+ HistogramType::ConstPointer m_UGHistogram;
//UnstructuredGridHistogram::Pointer m_UGHistogram;
HistogramType::BinMinContainerType m_Mins;
HistogramType::BinMaxContainerType m_Maxs;
double m_InvMaxFrequency;
double m_BinSize;
};
}
#endif // MITKSIMPLEUNSTRUCTUREDGRIDHISTOGRAM_H
diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt
index bac394edeb..4115ae5781 100644
--- a/Modules/CMakeLists.txt
+++ b/Modules/CMakeLists.txt
@@ -1,79 +1,80 @@
# Modules must be listed according to their dependencies
set(module_dirs
DataTypesExt
AlgorithmsExt
MapperExt
IOExt
DICOMReader
DICOMTesting
Qt4Qt5TestModule
SceneSerializationBase
PlanarFigure
ImageDenoising
ImageExtraction
ImageStatistics
LegacyAdaptors
IpPicSupport
- Ext
SceneSerialization
GraphAlgorithms
ContourModel
SurfaceInterpolation
Segmentation
PlanarFigureSegmentation
OpenViewCore
QmlItems
+ Overlays
QtWidgets
QtWidgetsExt
SegmentationUI
DiffusionImaging
GPGPU
IGTBase
IGT
CameraCalibration
RigidRegistration
RigidRegistrationUI
DeformableRegistration
DeformableRegistrationUI
OpenCL
OpenCVVideoSupport
- Overlays
+ QtOverlays
InputDevices
ToFHardware
ToFProcessing
ToFUI
US
USUI
DicomUI
Simulation
Remeshing
Python
Persistence
IGTUI
VtkShaders
+ DicomRT
)
if(MITK_ENABLE_PIC_READER)
list(APPEND module_dirs IpPicSupportIO)
endif()
set(MITK_DEFAULT_SUBPROJECTS MITK-Modules)
foreach(module_dir ${module_dirs})
add_subdirectory(${module_dir})
endforeach()
if(MITK_PRIVATE_MODULES)
file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*)
foreach(subdir ${all_subdirs})
string(FIND ${subdir} "." _result)
if(_result EQUAL -1)
if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt)
message(STATUS "Found private module ${subdir}")
add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir})
endif()
endif()
endforeach()
endif(MITK_PRIVATE_MODULES)
diff --git a/Modules/ContourModel/Testing/Data/img.nrrd b/Modules/ContourModel/Testing/Data/img.nrrd
deleted file mode 100644
index 04a51b53cb..0000000000
--- a/Modules/ContourModel/Testing/Data/img.nrrd
+++ /dev/null
@@ -1,17 +0,0 @@
-NRRD0004
-# Complete NRRD file format specification at:
-# http://teem.sourceforge.net/nrrd/format.html
-content: SomeIDNumber42
-type: short
-dimension: 3
-space: right-anterior-superior
-sizes: 3 3 1
-thicknesses: 1 1 1
-space directions: (1,0,0) (0,1,0) (0,0,1)
-centerings: cell cell cell
-kinds: space space space
-encoding: ASCII
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-
-1 2 3 4 5 6 7 8 9
diff --git a/Modules/ContourModel/Testing/Data/lungs.vtk b/Modules/ContourModel/Testing/Data/lungs.vtk
deleted file mode 100644
index 5b0f7f17ac..0000000000
--- a/Modules/ContourModel/Testing/Data/lungs.vtk
+++ /dev/null
@@ -1,18985 +0,0 @@
-# vtk DataFile Version 3.0
-vtk output
-ASCII
-DATASET POLYDATA
-POINTS 7860 float
-59 174 77.8 95 170 80.2059 55 171 80.2222
-56 171 79.2353 56 172 78.5806 57 172 78.1765
-58 173 78.2 59 173 78.6923 61 173 79.6452
-87 173 80.4194 88 173 79.8 89 173 79.4571
-91 173 80.4706 58 174 78.5172 60 174 78.1765
-89 174 80.4706 91 174 80.8235 59 175 78.5172
-60 175 78.0909 63 175 79.4571 88 175 80.5588
-64 176 80.1429 63 177 80.2059 65 177 80.2059
-67 177 80.1429 81 177 80.4706 82 177 79.8
-84 177 79.8 62 177.087 81 64 177.5 81
-68 178 80.2059 80 178 80.2059 82 178 80.2059
-69 179 79.8529 77 179 80.2059 79 179 79.8
-80 179 80.2059 81 179 80.8235 70 180 80.5455
-74 180 80.4706 114 150 83.4706 113 151 83.4706
-112.739 151 84 114 152 82.8529 39 155 83.8
-38.6667 155 84 113 155 82.8 114 155 82.8
-39 156 83.1429 38.3333 156 84 40 156 83.4706
-114 156 83.1429 40 157 83.1429 40 158 83.8
-40.6667 158 84 42 158.833 84 41.3333 159 84
-109 159 83.4706 112 159 81.1765 113 159 81.4545
-43 160 83.2059 108 160 83.4706 109 160 82.8
-111 160 81.5294 112 160 81.1765 113 160 82.3
-110 161 82.2 111 161 81.5143 112 161 81.8182
-44 162 82.8 45 162 82.8 107 162 83.0323
-109 162 83.0323 110 162 82.2 111 162 82.2
-112 162 83.4828 46 163 83.4194 110 163 83.2059
-46.25 164 84 47 164 83.4194 106 164 82.2
-109 164 83.4706 104 165 83.4 105 165 82.4545
-106 165 82.2 108 165 83.4706 49 166 82.8
-50 166 82.8 51.1667 166 84 103 166 83.9
-51.4 167 84 99 167 83.2174 101 167 81.9
-96 168 83.4828 97 168 82.7 98 168 82.8182
-101 168 81.8824 95 169 81.8824 96 169 81.9677
-97 169 82.5556 93 170 82.3636 93 169.333 84
-96 170 81.2222 54 171 82.6552 93 171 81.6667
-94 171 81.1936 91 172 81.6207 92 172 81.9677
-93 172 81.6 94 172 81.8824 95 172 81.5294
-97 172 83.8846 68 173 83.3333 76 173 83.4706
-85 173 83.6842 86 173 81.7826 93 173 82.2
-71 174 82.6452 76 174 82.4571 84 174 83.6842
-85 174 83.8333 92 174 81.5294 57 174.727 84
-75 175 82.6452 80 175 82.4571 82 175 82.0714
-86 175 81.6 69 176 82.6452 71 176 82.8529
-72 176 83.8064 74 176 83.4194 80 176 82.2
-87 176 81.4545 60.2609 177 84 75 177 82.4571
-87 177 81.5294 89 177 82.8529 81 181.25 84
-115 146.357 87 36 149 86.4194 114 149 84.1765
-36 150 86.4194 37 150 86.8 36.0909 151 87
-37 151 86.0323 37 152 85.5556 37 153 86.0526
-38 153 86.6842 111 153 86.9091 37 154 86.1667
-38 154 84.7826 39 154 85.8261 38 155 84.6667
-38 156 85.0714 37.6538 156 87 41 157 84.6818
-41 158 84.1364 40 159 85.8571 41 159 84.1364
-44 158.278 87 108 159 84.5294 41 160 85.2273
-45.5 160 87 41.2 161 87 47 163 84.2727
-46 164 84.2308 52 165 85.3548 100 165 86.5455
-102 165 84.5294 53 166 86.0323 52 167 84.2647
-106 167 84.5294 51 168 84.9677 53 168 84.4545
-95 167.63 87 53 169 84.2647 92 168.75 87
-105 169 86.2059 67 169.75 87 89 170 84.8824
-98 170 85.56 98 171 85.7727 72 172 85
-74 172 85.5556 82 172 84.5294 84 172 84.6923
-98 172 85.3043 99 172 85.2 73 173 85.8261
-74 173 85.8261 84 173 84.8333 73 174 85.1538
-99 174 86.8235 73 175 85 74 175 84.5172
-184.833 178 87 186 178 85.8462 186 179 85
-188 179 84.9677 189 179 85.3 191 179 85.1818
-193 179 84.375 195 179 85.6552 196 179 86.069
-198 179 85.4545 198 178.261 87 201 179 86.4706
-202 179 86.2059 186 180 86.8235 189 180 85.3548
-190 180 84.6 191 180 84.6 193 180 84.4286
-196 180 86.1 198 180 85.5 200 180 86.2059
-201 179.75 87 193 181 86.8966 68 181.706 87
-82 182 84.5294 84 183.087 87 117 143 89.8
-118 143 89.4706 118 142.25 90 117 144 88.5
-118 144 89.4706 115 145 89.2174 116 145 87.9677
-117 145 88.2 34 146 89.6087 115 146 87.6818
-116 146 87.5769 117 146 89 35 147 87.9677
-116 147 87.2308 35 148 87.5769 36 148 87.4545
-35 149 87.5455 35.7727 152 90 39 153 89.7273
-151 155 88.8 42.6429 157 90 152 157 88.8
-153 157 89.1429 43 157.278 90 44 157.105 90
-45.4545 158 90 152 158 89.8 153 158 89.8
-45.8947 159 90 153 159 89.9 47.2857 161 90
-52 162 89.55 48 162.286 90 55 164 88.3043
-56 164 89.2174 98 164 88.8529 55 165 87.6923
-56 165 89.2174 96 165 89.2059 95.1818 165 90
-99 165 87.9677 45 165.346 90 56 166 88
-63 167 87.375 64.6 167 90 92.7692 167 90
-95 167 89.3182 94.375 167 90 64.3 168 90
-68.3333 168 90 93 167.75 90 93 168 89.5714
-94 168 89 94 167.75 90 72 168.474 90
-73 168.333 90 66 169.4 90 50 170.105 90
-174 175 89.4 175 175 88.8 176 175 89.4194
-176 176 89.0323 177 176 88.6452 178.6 176 90
-181 176 89.4231 181 177 89.3077 181 178 89.04
-182 178 88.7586 183 178 89.3182 184 178 89
-202 178 87.5172 204 178 88.5 182 179 89.4194
-183 179 89.7391 184 179 88.875 204 179 88.1538
-181 180 89.8235 183 180 89.4194 202 180 88
-119 140 92.7778 120 140 91.6452 118 141 91.9615
-119 141 90.8571 120 141 91.2 118 142 90.2
-119 142 90.1765 120 142 91.5 120.654 142 93
-119 143 90.5294 150 145 92.8 149.714 145 93
-150 146 91.8 150 147 91.5 151 147 91.8529
-117.895 148 93 150 148 91.8529 151 148 91.5
-151 149 90.5294 151 150 90.1765 36.5909 153 93
-39 154.5 93 39.1053 155 93 39.1667 156 93
-40 156.526 93 154 157 90.5294 156.105 159 93
-46 159.563 93 50.75 160 93 153 160 91.1471
-155 160 91.7 45.3333 161 93 51 161 91.0714
-52 161 91.2273 154 161 90.6 45.8667 162 93
-51 162 90.5 50.6875 162 93 154 162 91.7
-156 161.455 93 155 163 92.7391 155.25 163 93
-47 164 92.3077 46.25 164 93 159 164 91.5
-47 164.857 93 63 165 90.6667 92 165 90.8824
-159 165 90.8824 45 165.591 93 46.5455 166 93
-64 166 90.2609 66 166 92.6842 67 166 92.8636
-92 166 90.2 93 166 91.0385 158 166 91.5
-160 166 90.5806 161 166 92.3077 46.6 167 93
-65 166.684 93 69 166.4 93 70 166.227 93
-71 167 91.5556 72 167 92 75 167 90.6
-93 167 92.25 94 167 92.25 161 167 92.7391
-161.5 167 93 68.3333 168 93 72 168 91.5
-94 168 90.2143 160 168 92.4444 161 168 92.25
-162 168 91.5556 48.4 169 93 67 169 90.2727
-162 170 91.2353 51.2857 171 93 66 170.208 93
-167 171 92.8966 52.625 173 93 170 173 92.8235
-173 173 92.7778 174 174 90.2308 170 175 92.1429
-180 175 91.5 171 176 92.4194 172 175.091 93
-172 176 91.8889 174 176 90.2222 179 176 90.5455
-185 175.618 93 179 177 92.7 183 177 90.375
-177 178 91.2 178 178 92.7 178.333 178 93
-179 177.333 93 179.143 178 93 180 178 90.6
-176 178.833 93 177 178.818 93 177.286 179 93
-178 179 92.2105 179 179 91.5 204.833 179 93
-180 180 90.5294 204 180.172 93 121 139 93.2727
-123.105 139 96 33 140.857 96 34 141 94.8462
-34 142 93.9 35 143 93.6818 149 143 94.8889
-150 144 94.1818 149 145 93.7895 40 151 94.5
-40.0714 153 96 40 153.071 96 39.3529 156 96
-149.588 156 96 46 156.591 96 45 157.133 96
-48 158 94.8 47 159 93.8571 49 159 94.0714
-50.1818 159 96 45.6667 160 96 47 159.625 96
-52 159.895 96 45.5714 161 96 157 161 93.2308
-51 162 94.0714 52 161.722 96 52.8333 162 96
-54 161.5 96 156 162 95.25 158 162 93.2609
-159 162 93.6 41 163 94.8261 46 163 94.125
-51 162.692 96 52 163 95.4 52.75 163 96
-156 163 95.5714 46 164 93.3158 45.2273 164 96
-52 163.6 96 90 164 93.3214 155 164 93.6667
-43 165 94.1111 46 165 93.75 47 165 93.75
-156 165 93.2 45 166 94.5882 45.7273 166 96
-47 165.273 96 46.2727 166 96 54 166 94
-54.2 166 96 69.25 166 96 162 166 94.7727
-46 166.375 96 46 167 94.9286 54 166.667 96
-64.4615 167 96 69 166.5 96 155 166.474 96
-163 166.455 96 47 168 94.5 72 168 94.5
-94.55 168 96 164 168 94.1111 165 168 95.1
-46 169 95.8846 46.1667 169 96 47.5 169 96
-72 169 95.3182 164 169 94.1111 165 169 94.5556
-166 169 94.8 52 170 93.2 94 169.688 96
-166 170 93.4286 167 170 93.5455 51 170.625 96
-163 171 93.6 166 171 94.3636 168 171 94.375
-168 170.133 96 170 171 94.8 52 172 94
-52.1818 172 96 162 172 94.5 163 172 94.3
-164 172 95.7391 165 172 95.8636 167 172 94.3548
-168 172 94.3548 173 172 93.5172 52 172.5 96
-59 173 95.125 164 173 95.4194 165 173 95.0323
-171 173 93.1818 172 173 93.4545 216 173 95.8
-75 174 95 74.8421 174 96 76 173.533 96
-76 174 95 76.6364 174 96 167 174 95.1429
-172 174 93.8182 214 174 95.4706 168 175 94.5
-172 175 93.1765 183 174.941 96 170 177 94.5
-178 176.65 96 179 176.316 96 204.323 177 96
-176.85 178 96 178 178 93.2 179.591 178 96
-176 179 93.3158 177 179 93.8571 177 178.375 96
-178 178.609 96 177 180 94.1538 68 184.056 96
-124 138.071 99 33 139.357 99 34 140.056 99
-149 141 98.2174 150 140.5 99 149 142 96.2609
-115 143.111 99 41 153 98.6 40 154 98.0526
-41 154 98.7 42 154 98.6 43 154 97.9286
-43 153.773 99 44 155 97.5 44 156 98.1667
-44.7143 156 99 46 157 98.4545 42.8182 158 99
-45 158 97.4444 47 158 98.4706 48 158 98.25
-44 158.846 99 45 159 98.6 46 159 98
-46.75 159 99 47 158.75 99 46 160 97.6364
-46 159.375 99 47 160 97 49.1818 160 99
-51 160 97.5 46 161 97.2 47 161 97.5
-51 160.667 99 53 160.545 99 45.2778 162 99
-51 161.333 99 53 161.625 99 53 162 96.75
-161 162 97.8529 49.9333 163 99 52 162.2 99
-59 163 98.25 44.3158 164 99 60 163.667 99
-64 163.933 99 59 165 97 60 164.333 99
-60 165 97.6364 64.8182 165 99 66 165 97.125
-66.7143 165 99 68.75 165 99 47 166 97.8462
-47.3333 166 99 54 166 96.4 59 166 96
-58.2632 166 99 60 166 97.0909 65 166 98.7143
-64.8182 166 99 66 166 98.0526 66.75 166 99
-69 166 96.4286 70 165.833 99 224 166 98.8
-225 166 98.8 225 165.75 99 46 167 97.5
-47.8182 167 99 59 167 97.3636 58.25 167 99
-60 167 97.7143 67 166.286 99 69 167 96.75
-70 167 98.6 70 166.5 99 70.3333 167 99
-72 167 98.6 71.6667 167 99 72 166.5 99
-223 167 97.8529 224 167 97.6452 47 168 96.75
-46.4545 168 99 47.8571 168 99 56 168 98.7273
-55.8667 168 99 56 167.867 99 56.5 168 99
-61.8182 168 99 64.25 168 99 70 168 96.2609
-71 167.222 99 71 168 96.7895 73 168 97
-74 167.357 99 74 168 97.7727 222 168 97.8529
-223 168 97.3 224 168 98.7391 47 169 97.3636
-56 168.286 99 62 169 97.6552 62.9286 169 99
-64.25 169 99 69 169 96.9 71 169 97.35
-74.1 169 99 92.7 169 99 167 168.2 99
-221 169 97.7 222 169 97.3 223 169 98.7391
-46 170 97.5 52 169.462 99 54.2 170 99
-62 170 97.8182 62.6842 170 99 68 169.875 99
-69 170 98.25 68.5 170 99 70 170 97.1739
-71 170 97.25 72 170 97.5 72.9091 170 99
-74 169.056 99 77 170 97.5 76.4545 170 99
-77 169.571 99 170 170 96.4545 220 170 96.9
-221 170 97.0385 222 170 98.7391 61 171 98.7931
-60.7778 171 99 61.2857 171 99 69 170.5 99
-70 171 97.3333 71 171 97.25 72 171 98.625
-77 171 97.8 77.8571 171 99 94 170.294 99
-164 171 96.2727 165 171 96.4091 218 171 97.4
-219 171 96.6 220 171 96.2 221 171 98.2174
-49 172 96.3333 54 171.75 99 59 171.519 99
-60 172 98 69.1429 172 99 71 172 96.3
-72.4375 172 99 77 171.75 99 216 172 97.1818
-216 171.231 99 217 172 97.2414 218 172 96.5172
-219 172 97.5 220 172 98.7273 48 172.722 99
-50 173 97.875 51.5 173 99 58 173 96.5172
-57.1724 173 99 61 172.286 99 215 173 96.5294
-217 173 96.5294 218 173 97.3548 51 174 98.2174
-67 173.818 99 67.25 174 99 75.5 174 99
-78 174 98.7273 78.1053 174 99 180 173.097 99
-211 174 98.88 216 174 96.5294 58 174.737 99
-67 175 97.8462 66.0909 175 99 76 174.643 99
-77 175 98.4 77.75 175 99 78 174.667 99
-210 175 97.25 212 175 97.8261 213 175 96.6
-214 175 96.2 67 176 98.069 66.3571 176 99
-67.9 176 99 77 175.188 99 178 175.923 99
-178.25 176 99 209 176 96.4545 210 176 96.1154
-211 176 97.56 212 176 98.4444 213 176 98.1
-214 176 98.4231 67 176.5 99 179 176.75 99
-179.095 177 99 210 177 96.5806 212 176.833 99
-214 176.172 99 177 178.579 99 178 178.467 99
-63 183.375 99 66 183.818 99 67 184 98
-151 137 101.824 32 138 101.609 33 137.333 102
-150 138 100.696 33 139 99.5769 150 139 99.6667
-149 140 100.8 123 141 100.579 122 144 100.962
-120.8 145 102 107.773 150 102 41 152 99.5455
-34.5882 153 102 45 155 100.579 45.3913 155 102
-41 156 100.154 42 156 100.111 45 156 99.3158
-42 157 99.2727 43 157 100.111 46 157 99.6
-47 157 101.7 44 158 101.75 47 158 102
-48 158 100 43.8421 159 102 50 159 100.071
-51 160 99.4286 50 161 100.826 54 161 101.7
-55 161 101.5 158 161 101.667 157.25 161 102
-158 160.813 102 51 162 99.75 52 162 99.5455
-53 162 100.125 56 161.077 102 158 161.75 102
-227 162 101.1 228 162 101.739 46 162.444 102
-49 162.667 102 49 163 101.8 50 162.2 102
-60 162.944 102 226 163 100.5 227 163 99.9
-225 164 101.1 226 164 99.9 227 164 100.227
-47 165 101.167 59 165 101.727 65 165 99.8571
-66 165 101.5 80 164.567 102 225 165 99.5294
-226 165 100.111 46 166 101.824 60.875 166 102
-65 166 101 65.2 166 102 66 165.2 102
-66.8 166 102 226 165.944 102 46 167 99.9375
-47 167 101.077 60.75 167 102 61.1429 167 102
-62 166.455 102 64 167 100.5 65 167 100.364
-66 167 100.286 70 167 99.8571 72 166.563 102
-167 167 100.5 47 168 100.636 56 168 99.8571
-65 168 100.2 66 168 100.773 67 168 101.654
-74 167.105 102 94 168 101.786 95.375 168 102
-167 168 99.5455 62.6364 169 102 66 169 101.727
-67 169 101.8 68 169 101.8 75 168.571 102
-75 169 101.25 76 168.455 102 76 169 100.2
-95.9167 169 102 54 169.591 102 55 170 101.182
-56 169.167 102 56 170 100.5 61 170 99.8182
-64.4545 170 102 67 170 101.7 73.5455 170 102
-75 169.75 102 76 169.857 102 76.1429 170 102
-52 170.474 102 53 170.143 102 54.3333 171 102
-61 171 99.6 51 172 102 58 171.727 102
-60 172 101 73 171.667 102 72.9333 172 102
-78 171.917 102 60.25 173 102 72 173 101.182
-78 173 101.25 78 172.333 102 79.5 173 102
-180 172.316 102 67.3333 174 102 68 174 101.25
-68.6667 174 102 77 174 100.579 77.75 174 102
-79 174 102 187 174 101.419 188 174 101.8
-206.895 174 102 58 174.25 102 66 175 102
-68 175 102 77 175 99.6 78 174.75 102
-207 175 101 65.5625 176 102 68.1364 176 102
-173 176 100.688 173 175.632 102 176.565 176 102
-215 176 100.826 215.6 176 102 161 176.074 102
-212 177 99.1034 176.8 178 102 203.5 178 102
-212 178 100.556 203 178.867 102 210 179 100.355
-202.091 180 102 203 181 100.75 66 185 100.08
-200 184.172 102 232 99 104.8 232 98.7143 105
-232 99.5 105 235 111 104.824 235 112 104.824
-151 133 104.471 32 136 103.6 31.3 136 105
-33 135.867 105 150 137 102.167 153 141 103.2
-154 142 104.8 154.75 143 105 230 156 104.419
-49 157 104.318 229 157 104.8 45 158 103.313
-46 158 103.615 229 158 103.7 230 158 104.053
-44 159 103.125 45 159 102.75 46 159 103.8
-53 158.316 105 228 159 104.206 229 159 103.5
-37.1765 160 105 54 160 103.5 164 160 103.8
-229 160 103.5 157.533 161 105 158 160.417 105
-158.875 161 105 228 161 102.682 228.944 161 105
-49 162 102.273 50 162 102.316 59.8 162 105
-62 162 104.545 158 161.875 105 46 163 104
-48 163 102.375 225 163 103.111 45.1429 164 105
-46 163.455 105 47 164 103.05 45 165 103.286
-60 165 102.75 167 165 102.529 46 165.25 105
-60 166 103.105 63 166 105 65 166 102.429
-60 167 102.45 61.8571 167 105 62 166.333 105
-62.6667 167 105 64 167 104.5 63.5 167 105
-64.1 167 105 65 166.4 105 64 167.25 105
-68 168 102.261 69 168 103.962 71 168 103.556
-72 168 104.778 73 168 104.333 74 168 104.684
-96.7143 168 105 166 168 103.875 166.75 168 105
-62 169 103.05 69 169 103.304 71 169 103.304
-73 169 104.063 75 169 102.818 76 169 102.947
-97.5455 169 105 54 170 103.929 55 170 103.125
-56 170 104.143 62 170 103.235 65 170 103.636
-66 170 103.65 74 169.273 105 77 170 103
-52 171 103 53 171 102.692 54 171 103
-71 171 103.304 73 171 102.4 78 171 104.75
-178 170.261 105 179 171 103 181 171 104.419
-52 172 103.179 58 172 103.125 72 172 103.826
-77 171.286 105 182 172 104 184 172 102.882
-188 172 104.8 58 173 103.826 59 173 103.5
-70 173 103.125 72 173 103.8 78 173 103.5
-78.4 173 105 81 173 105 181 173 103.5
-182 173 103.909 188 173 102.783 207 173 104.333
-208.125 173 105 59 174 102.692 69.75 174 105
-80 173.857 105 198 174 102.667 206 174 104.217
-210 173.273 105 67 175 103.615 67.75 175 105
-68.2857 175 105 88 175 104 87.25 175 105
-88.75 175 105 176 175 104.308 176 174.455 105
-177 174.87 105 177 175 104.438 66 176 104.625
-67 176 104.625 68 176 103 88 175.75 105
-173.231 176 105 176 176 104.438 178.067 176 105
-204.091 178 105 203.25 179 105 200.571 180 105
-201 179.4 105 203 179.056 105 206 180 103.8
-201.75 181 105 205 181 104.333 206 181 103.8
-207 181 104.1 173 182 103.56 175.667 185 105
-230 94 107.4 230 93.1429 108 231 95 106.889
-231 96 106.355 231 97 106.182 232 97 106.636
-232 98 105.577 231 99 106.5 233 99 106.333
-233 98.1667 108 232 100 105.2 233.292 100 108
-233 101.5 108 233 102 107.684 233 103 106.111
-233 104 105.882 233 105 106.182 234 105 105.682
-234 106 105.222 235 105.75 108 234 107 105.2
-234 108 105.529 235 110 105.577 235.913 110 108
-234 111 105.529 236 111 106.421 236.292 114 108
-235 116 106.355 235 117 107.032 235 119 107.8
-235 120 107.8 236 120 107.739 236 121 106.696
-236 123 105.667 236 125 106.889 236 126 107.333
-235 127 107.824 236 128 106.355 236 130 107.1
-150 131 107.778 150 132 105.9 149.192 132 108
-151 132 105.818 235 132 107.8 31 135 106.8
-31 134.143 108 32 135 105.136 31 136 107
-33 135.133 108 235 136 107.471 120 139.435 108
-235 140 106.889 155 141 105.667 234 141 107.471
-235 141 107.217 234 142 107.143 235 141.857 108
-234 143 107.032 155 144 105.545 156 144 107.625
-234 144 107.333 233 145 107.824 162 151 107.471
-231 156 106.714 230.933 157 108 225.933 159 108
-57 160 107.684 168 160 107.471 57 161 106
-58 161 106.636 59 161 105.316 60 161 105.783
-158 161 106.05 58 162 108 59 162 106.2
-63 162 106 82 161.833 108 83 162 107.8
-83 161.833 108 84 162 106.759 160 162 106.714
-159.455 162 108 160 161.455 108 160.75 162 108
-46 164 105.6 64 166 106.286 65 166 106.636
-66 166 105.75 173 166 106.2 174 166 107.032
-176 166 107.778 62 167 105.333 64 167 105.231
-174 167 107.55 176 167 107.739 177 167 106.962
-216 167 107.1 168.13 168 108 174 168 105.75
-177 168 106.889 178 168 106.889 218 168 105.2
-74 169 105.333 166 168.25 108 167.2 169 108
-168 168.2 108 179 169 105.529 181 169 106.2
-183 170 105.529 192 169.333 108 195 170 107.471
-207 170 107.8 77 171 105.316 96 170.111 108
-197 171 106.645 198 171 106.457 208 171 106.457
-82 172 107.25 82 171.625 108 82.75 172 108
-197 172 106.5 198 172 106.826 203.5 172 108
-205.75 172 108 207 172 106.826 208 172 106.355
-80 173 106.2 82 172.375 108 175 173 107.087
-174.563 173 108 200 173 107.885 203 173 107.912
-205.455 173 108 209 173 106.105 210 173 105.474
-68 174 105.273 69 174 105.6 90 174 107.526
-89.75 174 108 90.75 174 108 175 174 106.895
-176 174 106.25 203 174 107.5 68 175 105.24
-88 175 105.818 90 174.75 108 177 174.895 108
-206 175 106.5 205.833 175 108 171 176 107.5
-171 175.333 108 172.231 176 108 176 175.933 108
-177.13 176 108 205 175.909 108 205 176 107.864
-206 176 106.636 205 178 105.882 204 179 105.29
-201 180 107.25 202 180 107.211 203 180 106.962
-202 181 106 203 181 107.348 169 182 106.235
-203 182 106.826 204 182 106.2 205 182 105.455
-171 183 105.176 173 183 105.778 204 183 107.1
-205 183 107.778 172 184 106.5 86 189.824 108
-227 88 110.4 226.5 88 111 228 89 109.444
-228 90 108.9 228 91 109.2 229 91 109.174
-229 92 108.667 230 91.8182 111 229 93 108.581
-230 93 108.2 233 101 109.5 232 102 108.24
-230.167 107 111 231 108 110.824 230.833 108 111
-232 109 109.182 236 119 108.545 236.64 125 111
-150 129.966 111 234.692 130 111 149 130.231 111
-148.63 131 111 235 131 109.227 236 131 108.273
-236 132 108.158 31 133 110.25 30.5882 135 111
-128 135 110.423 129 135 110.206 128 136 108.231
-129 136 110.1 129 136.818 111 157 138.643 111
-157 140 109.304 232.316 140 111 235.806 140 111
-156 141 108.136 156 142 109.08 157 142 109.4
-156 143 109.227 158 143 109.313 157 144 108.182
-232 145 109.2 234 145 108.682 234.567 145 111
-162 146 110.143 161 147 109.355 231 147 110.824
-233 147 110.864 164 148 110.471 232 148 110.909
-162 149 109.75 232 149 110.423 232.714 149 111
-231 150 110.423 232.929 150 111 231 151 109.696
-232 151 108.789 231 152 109.421 232 152 109
-231 153 110.053 230 154 108.692 170 157 109.457
-168 158 109.2 171 158 109.457 60 159 110.1
-168 159 108.529 172 159 109.457 223 158.875 111
-224 159 110.739 170 160 109.2 171 160 109.457
-172 160 109.8 174 160 110.143 82 161 108.909
-173 161 109.886 175 161 109.457 177 161 110.206
-177.818 161 111 105 162 110.25 106 162 109.2
-174 162 109.8 175 162 109.457 178 162 110.8
-220 162 110.25 220 161.417 111 106 163 109
-106.25 163 111 160 163 108.429 161 163 109.364
-161.2 163 111 175 163 108.882 161 164 109
-178 164 110.333 160 164.909 111 161.13 165 111
-179 165 108.968 184 165 109.457 183 166 109.457
-185 166 109.457 210 166 110.471 214 166 109.2
-215 166 108.882 66 167 109.6 65.125 167 111
-66 166.417 111 67 166.625 111 67.2727 167 111
-184 167 110.333 185 167 110.679 186 167 110.032
-187 167 109.457 194 167 110.8 193.5 167 111
-195 166.625 111 209 167 110.125 215 167 108.529
-66 168 109.5 65.25 168 111 67 168 110.308
-166.696 168 111 169 167.563 111 169 168 110.222
-170 168 110.735 171 168 110.735 172 167.87 111
-185 168 110.211 187 168 108.529 192 168 110.211
-192.714 168 111 193.25 168 111 195 168 109.645
-201 168 109.853 203 168 110.684 204 168 110.684
-207 167.5 111 210 168 109.826 213 168 110.864
-214 168 110.04 92.6842 169 111 167 168.875 111
-168 168.947 111 169 168.438 111 172 169 109.645
-173 169 109.429 192.818 169 111 194 169 109.5
-193.25 169 111 202 169 110.625 205 169 110.471
-207 169 108.75 93.25 170 111 173 170 109.35
-173.688 170 111 193 169.25 111 94 170.4 111
-95 170.625 111 173 171 111 82 172 108.818
-186 172 110.55 185.727 172 111 205 172 109.636
-205 171.375 111 92 173 110.55 91.25 173 111
-93 172.455 111 93 173 110.4 175 173 110.625
-186 172.375 111 195 173 110.471 195 172.571 111
-196 172.444 111 196 173 109.5 205 173 110.143
-90.5 174 111 91 173.2 111 91 174 108.6
-92 174 110.438 94 174 110.55 95 173.667 111
-95 174 109.875 175 174 109.75 176 174 109.313
-196 174 109.821 197 174 109.889 197.667 174 111
-204 174 108.947 205 173.4 111 205.75 174 111
-91 174.25 111 95 174.75 111 171 175 108.273
-176 175 109.909 195.563 175 111 197 175 110.217
-85 176 108 84.25 176 111 85 175.25 111
-85.1875 176 111 171.857 176 111 177 176 108.29
-196 176 111 197 176 110.143 205 175.333 111
-85 176.188 111 197 176.286 111 212 180.067 111
-207 67 113.333 208 68 112.645 209 68 112.889
-210 68.0667 114 210 70 112.457 213 71 112.313
-214 71 112.75 215 71 113.5 215 72 112.25
-216 73 111.261 217 73 111.273 213 74 112.8
-216 74 111.968 218 74 112.364 218.231 74 114
-218 75 111.783 218 76 112.313 219.091 76 114
-218 77 113.419 219 77 113.679 219.25 77 114
-219 78 113.778 220 78 113.419 220 79 113.143
-221 80 113.419 221.857 81 114 222 82 113.8
-222.167 84 114 223 84 113.143 224 85 113.333
-225 85 113.55 225 87 113.778 226 87 112.696
-226 88 111.783 227 87.2632 114 229 98 111.176
-231 110 111.529 230.04 113 114 231 114 111.529
-232 119 112.773 232 120 111.947 233 121 111.5
-233 128 111.581 234 129 112.227 31 130 113.793
-149 130 111.333 233.375 130 114 234 130 113.348
-31 131 112.636 32 131 112.5 234 131 112.364
-31 132 113.182 30.875 132 114 32 132 112.5
-232 132 112.2 233 132 111.455 131 133 112.962
-132 133 113.1 132 132.182 114 149 132.944 114
-129 134 112.111 130 134 111.581 131 134 111.9
-132 134 113.778 232 133.684 114 233 134 111.931
-130 135 111.2 131 135 112.7 126 135.067 114
-158 136 113.333 31.2857 137 114 232 137 111.581
-157 138 112.08 229.5 138 114 233 138 111.176
-229 142 113.824 230 142 113.143 108 143 113.545
-161 143 111.857 231 144 112.5 165 145 112.8
-164 146 112.313 229 146 113.8 231 146 111.091
-230 147 111.176 232.962 148 114 229 149 111.931
-226 151 113.143 227 152 113.545 229 152 113.909
-232.176 152 114 228 153 112.909 103 154 113.4
-104 154 113.455 101.818 155 114 103 155 111.429
-104 155 113 59 157 112.235 59 158 111.529
-222 157.565 114 177 159 113 220 160 112.545
-106 161.053 114 106.783 162 114 161 163 113.571
-189 163 113.206 106 163.13 114 159.677 164 114
-189 164 112.889 191 164 112.889 197.25 164 114
-208 164 112.457 161.667 165 114 191 165 113.684
-192 165 112.889 198 165 113.25 205 165 113.217
-67 166 112 66.4737 166 114 67 165.667 114
-68 166 112.241 68.8947 166 114 190 166 113.5
-191 166 113.25 192 166 111.947 197 166 113.885
-197 165.667 114 198 166 113.778 199 166 112.5
-203 166 111.75 66 166.75 114 68 167 111.923
-192 167 111.545 193 167 111.273 56 168 112.25
-56 167.125 114 56.5833 168 114 66.1429 168 114
-68 167.947 114 67.8571 168 114 90.625 168 114
-93 167.261 114 167.769 168 114 168 167.25 114
-172 167.391 114 193 168 111.6 56 169 111.75
-56.2 169 114 169 168.609 114 184 169 113.684
-184 168.333 114 185 168.75 114 185 169 113.308
-192.417 169 114 202.65 169 114 203 168.125 114
-204 168.455 114 173 169.857 114 185 170 113.308
-184.6 170 114 193 170 111.9 194 169.444 114
-194 170 112.125 95 170.261 114 185 171 112.263
-186 171 113.182 192.889 171 114 194 171 112
-195 171 112.696 93 171.684 114 185 172 113.182
-186.438 172 114 194 172 113 195 172 111.667
-196 172 112.714 204 171.875 114 205 172 112.875
-204.4 172 114 205.231 172 114 94 173 111.5
-185 172.111 114 205 173 112.5 204.867 173 114
-205.5 173 114 91.8667 174 114 94.6667 174 114
-195 173.722 114 197.429 174 114 206 173.25 114
-206 174 111.429 93 174.393 114 172 175 111.75
-172.125 175 114 196 174.667 114 205 175 113.571
-206.15 175 114 85 176 111.346 171 175.545 114
-176 186.853 114 181 187.808 114 201.75 67 117
-204 67 116.125 203 68 116.471 205 69 116.1
-208 73 116.217 209 73 116.125 208 74 116.333
-207.5 74 117 209 74 115.962 210 76 116.1
-211 76 116.217 215 77 115.2 214 78 115.8
-216 78 115.645 217 78 116.333 213 78.6667 117
-218 79 116.444 221.966 80 117 219 81 115.2
-222 81 114.136 221 82 114.176 221 83 114.857
-225 84.1111 117 223 86.8667 117 224 89 115.7
-225 89 115.227 225 90 115.5 224.697 92 117
-224 95 116.824 234.059 105 117 226 108 116.4
-227 110 116.778 228 111 116.824 228 112 116.206
-228 113 116.419 229 114 114.529 229 115 114.857
-229 118 115.8 230 119 116.885 231 119 115.759
-231 121 114.931 230 122 114.882 30 125 116.087
-31 126 115.5 228.5 126 117 146 127.966 117
-145.955 128 117 146 129 115.655 32 130 114.231
-134 130 116.5 135 130 116.471 230 130 116.778
-132 131 116.069 133 131 114.818 134 131 115.3
-135 131 116.778 132 132 114.182 133 132 114.091
-134 132 115.5 133 133 114.931 159 133 115.5
-229 133 116.143 230 133 115.147 149.433 134 117
-230 134 116.032 231 134 116.1 232 134 114.692
-159 135 114.2 161 135 116.217 228 135 116.8
-229 135 115.889 232 135 115.364 159 136 114.857
-160 136 115.56 161 136 116.739 163 136 116.333
-229 136 116.625 162 137 116.217 230 137 114.4
-164 138 116.739 164 139 115.889 226 142 116.824
-105.867 143 117 226 143 116.143 229 143 114.176
-167 144 115.2 228 144 115.853 229 144 115.235
-104 144.933 117 103.857 145 117 105 145 115.5
-168 145 116.625 229 145 115 168 146 116.885
-169 146 116.778 170 146 116.333 227 146 116.545
-170 148 115.8 172 149 115.457 222.125 149 117
-223 150 115.457 224 151 115.2 220 152 116.143
-221 152 115.853 222 152 115.8 224 152 115.853
-51 152.087 117 221 153 115.457 222 153 115.8
-223 153 116.471 102 154 116.143 104 154 115.5
-219 154 116.5 101.895 155 117 103.545 155 117
-182 154.75 117 216 155 116.471 217 155 116.032
-218 155 116.333 181 156 115.457 182 156 116.4
-216 156 115.8 217 156 116.333 217.75 156 117
-223 155.917 117 161 157 114.8 160.313 157 117
-161 156.083 117 162 157 116 162.333 157 117
-182 157 116.032 185 157 116.206 212 157 116.471
-214 157 116.559 216 157 115.457 217 157 116.333
-217.75 157 117 161 157.55 117 162 157.857 117
-176 158 114.207 183 158 115.853 212 158 115.457
-216 158 115.457 217 158 116.032 218 158 115.929
-185 159 115.457 205 158.833 117 208 159 116.419
-210 159 116.125 189 160 115.457 192 160 116.8
-207 160 116.032 208 160 115.645 209 160 116.217
-217 160 114.9 187 161 114.29 188 161 114.968
-204 161 115.8 205 161 115.645 207 161 116.419
-208 161 116.419 209.5 161 117 217 161 116.069
-103.083 162 117 206 162 116.1 210 162 114.667
-216 162 116.864 217 162 116.88 58 163 116.739
-57.8182 163 117 58.25 163 117 69 162.818 117
-103 163 116.087 103 162.125 117 211 163 114.931
-69 164 116.217 103 163.875 117 162.077 164 117
-68 165 116.25 68 164.813 117 159.933 165 117
-197 165 114.333 69 166 114.667 170 166 114.9
-190 166 114.75 190 165.455 117 191 166 115.2
-56 167 114.75 56 166 117 66 167 114.333
-67 167 116.348 67.3333 167 117 91 167 114.783
-191 167 115.765 192 167 116.455 56 168 117
-67 168 114.692 68 167.385 117 89.0909 168 117
-168.125 168 117 172 168 116.1 171.684 168 117
-184 168 114.6 184 167 117 184.333 168 117
-190.923 168 117 192 168 114.923 193 168 115.333
-193.333 168 117 201.067 168 117 202 167.067 117
-203 168 114.13 204.467 168 117 56 169 114.563
-89.25 169 117 91 169 115 94.6364 169 117
-171 169 115.579 172 169 115.7 184 168.8 117
-184 169 116 185 169 116.25 192 169 114.789
-202 169 116.6 201.923 169 117 204.609 169 117
-79 170 115.875 79 169.727 117 80 169.417 117
-80 170 115.385 185 170 116.571 192 169.737 117
-79 170.273 117 80 170.304 117 94 170.286 117
-185 171 115.737 186 171 114.474 195 171 116.727
-194.875 171 117 204 171 116.8 204 170.857 117
-94 171.455 117 186 172 114.778 194 172 115.286
-194 171.467 117 195 172 116.333 196 172 115
-205 172 114.474 92.2273 173 117 195 173 115.773
-196 173 116.1 205 173 114.6 93 174 116.75
-171 173.889 117 197 174 114.692 205 174 115.286
-206 174 115.636 206 175 114.818 172 175.933 117
-204 185 115.579 176.85 186 117 177 185.813 117
-178 185.417 117 184 186 116.735 184 187.385 117
-200.25 67 120 200.333 69 120 204 70 117.968
-202.125 71 120 204 71 118.313 204 74 119.143
-206 77 118.457 208 77 118.5 207 78 119.032
-210 78 118.25 217 79 117.273 210 79.5455 120
-214 80 119.5 216 80 117.261 217 80 117.103
-216 81 117.667 221 86 118.364 219 87 119.824
-220 87 119.8 220.5 87 120 220 88 119.559
-221 88 119.5 222 87.2857 120 222 89 119.1
-222 90.3333 120 223 90.7692 120 224 91.125 120
-222.545 93 120 224 93 118.56 33 105 119.8
-33 107 119.471 32 108 119.739 33 108 119.824
-223.867 108 120 32 109 118.556 33 109 119.824
-224.526 109 120 31 110 119.526 225 110 119.1
-32 111 118.5 224 111 119.419 224 112 118.457
-225 112 118.2 31 113 117.75 224 113 118.457
-225 113 118.645 226 113 118.3 226 114 119.864
-31 119 117.529 226 119 118.457 226 120 118.457
-227 120 118.258 230 120 117.391 225 121 119.471
-227 121 119.739 229 121 118.08 33 127 118.818
-29.4857 128 120 227.929 128 120 145.147 129 120
-228 129 119.864 226 130 119.143 162 131 118.8
-226 131 119.118 161 132 118.235 164 132 118.8
-227 132 118.457 34.4545 133 120 34 134 119.211
-226 135 118.457 230 135 117.517 231 135 117.409
-230 136 117.429 165 137 117.176 169 136.167 120
-169 137 119.143 168 138 118.457 224 138 118.8
-226 138 118.75 110 139 119.824 167 139 118.645
-225 139 119.032 226 139 119.333 227 139 118.556
-167 140 118 226 140 118.941 228 140 117.265
-224 141 118.8 106.133 142 120 221 142 118.8
-106 142.5 120 105.75 143 120 170 143 118.645
-173 143 118.8 103 144 119.769 105.857 144 120
-220 144 118.457 102 145 117.6 103 145 117.947
-104 144.667 120 105 144.857 120 221 145 118.457
-99 146 118.853 101 146 118.182 102 146 117.231
-219 146 118.457 221 146 118.8 222 146 119.206
-223 146 119.471 174 147 118.2 219 147 118.8
-221 147 119.559 222 147 119.273 223 147 118.909
-220.286 148 120 221 148 119.559 222 148 118.545
-221 149 119.1 179 150 118.457 220.346 150 120
-177 151 118.556 178 151 118.889 179 151 118.457
-213 152 118.8 218 152 117.857 181 153 119.1
-185 153 119.824 215 153 118.457 217 153 117.882
-102 153.85 120 103.438 154 120 210 154 118.457
-215 154 118.2 222 154 117.455 223 154 118.111
-224 154 117.45 104 155 119.143 209 155 118.457
-211 155 118.457 213 155 118.7 219 155 117.273
-221 155 118.759 222 155 119.172 223 155 118.435
-103 155.895 120 104 155.143 120 184 156 117.529
-189 156 118.457 211 156 117.882 213 156 117.968
-218.727 156 120 219 155.87 120 219.429 156 120
-220 156 119.294 222 156 119.04 161 157 118.737
-162 157 118.636 189 157 118.2 201 157 119.206
-219 156.75 120 219 157 119.5 198 158 119.419
-202 158 119.206 203 159 118.4 165 160 119.609
-164.727 160 120 165 159.75 120 202 160 117.182
-210 160 117.6 165 160.6 120 210 161 117.333
-211 161 119.786 211.25 161 120 212.75 161 120
-214 161 118.909 216 161 118.105 57 162 118.688
-57 161.125 120 58 161.083 120 58 162 118.565
-104 162 118.65 105 162 118.111 106 162 117.375
-188 162 119.684 57 163 118.688 67.5333 163 120
-68 162.417 120 101 163 119.308 100.143 163 120
-102 162.739 120 102 163 118.364 103 162.563 120
-104 163 119 188 163 119 57 164 119
-56.5556 164 120 57.8 164 120 101 164 119.217
-102 164 119.25 103 164 118 103.111 164 120
-181 164 119.308 188 164 119.308 189 164 118.889
-57 165 117.75 56.25 165 120 57.25 165 120
-68 165 118.125 68.3125 165 120 162 164.053 120
-162.667 165 120 169 164.5 120 180.739 165 120
-189 165 118.444 190 165 117.75 197 165 119.667
-198 165 119.55 57 165.25 120 68 166 118.826
-69 165.55 120 69 166 118.313 93.2 166 120
-161 165.947 120 182 166 118.364 183 166 117.375
-189.067 166 120 191 165.333 120 198 166 118.25
-199 166 118.95 56 167 117.75 68 167 118
-162 166.261 120 171.519 167 120 183 166.636 120
-190 166.737 120 198 166.35 120 200 167 119.182
-199.25 167 120 200 166.571 120 201 166.632 120
-201 167 117.375 184 168 117.75 193 168 118.579
-192.25 168 120 201 168 118 202 167.417 120
-192 169 119.211 192 168.375 120 203 169 119.87
-203 168.857 120 79 170 117.563 80 170 118.75
-193 170 119.684 203 170 117.391 204 170 117.6
-93 171 119 94 171 118 94.3704 171 120
-94.3704 172 120 94 172.667 120 170.192 175 120
-171 175.808 120 184 184.267 120 176.533 186 120
-180 186 117.25 181 186 117.6 181.8 186 120
-182.091 186 120 185 186 117.091 175 186.588 120
-181 187 120 184 187 117.652 183.053 187 120
-185 187 117.088 182 187.615 120 200.25 68 123
-200.333 69 123 205 80 122.625 207 80 121.556
-208 80 122.423 210 80 120.714 221 79.913 123
-205 80.75 123 207 81 121.889 214 81 120.12
-206 82 122.032 207 82 121.645 208 82 122.8
-213 82 120.333 214 82 120.231 211 83 121.645
-213 83 121.5 210.182 84 123 212 84 121.8
-213 84 122.125 213 84.875 123 214 85.5 123
-216 87 122.739 217 87 122.55 221 87 120.273
-222 87 120.333 218 88 121.2 220 89 121.038
-221 89 120.103 221 90 120.231 221 91 121.5
-223 91 122.25 220 92 122.129 221 92 121.7
-222 92 121.889 222.667 92 123 222 93 120.529
-34 102 121.962 34 101.182 123 33 103 121.895
-34 103 121.7 33 104 120.682 34 104 121.5
-31.8235 105 123 34 105 121.5 32 106 120.667
-222 107 120.529 220 109 122.778 224 109 121
-220 110 122.333 221 110 122.032 222 110 122.206
-223 110 121.909 221 111 122.806 222 111 121.909
-221 114 122.032 222 114 120.857 220 115 122.143
-225 115 120.273 226 115 120.692 223 116 121.25
-224 116 121.125 225 116 120.333 221 117 121.457
-224 117 121.2 222 118 122.333 223 118 122.739
-223 119 122.063 223 120 121.853 222 121 121.457
-224 121 120.529 221 122 121.457 223 122 121.457
-226 122 120.455 227 122 121.219 221 123 121.457
-224 123 121.5 225 123 121.853 226 123 121.909
-227 123 121.219 149 123.7 123 226 124 121.909
-227 124 120.094 34.4737 126 123 226 126 121.125
-161 126.5 123 165 127 122.824 225 127 122.1
-226 127 121.7 34.7391 128 123 134 127.833 123
-145.059 128 123 165 128 121.8 217.875 128 123
-219 128 121.8 223 128 121.8 227 128 122.167
-135 128.077 123 162 129 121.235 164 129 121.8
-167 129 121.8 226 129 120.115 227 129 120.316
-35 130 121.818 136.4 130 123 124 133 121.355
-219 133 121.457 168 134 121.5 220 135 121.8
-219 136 122.786 218 138 121.457 220 138 121.457
-221 138 121.645 222 138 121.304 174 139 121.457
-177 139 122.471 220 139 122.8 221 139 122.8
-222 139 122.217 223 139 120.5 104.6 140 123
-106 140 121.355 173 140 121.2 177 141 122.1
-178 141 122.032 179 141 122.471 221 141 120.818
-105 142 123 106 142 120.857 176 142 122.129
-215 142 122.25 102 143 120.29 103 143 120.261
-104 143 120.75 176 143 121.543 212 143 122.471
-104 144 120.857 116 144 121.714 117 143.818 123
-181 144 121.8 182 144 122.471 212 144 121.457
-214 144 121.886 104.417 145 123 106 145 122
-116 145 120.167 117 145 120.3 179 145 121.457
-215 145 121.8 105 145.438 123 106 145.261 123
-116 145.739 123 181 146 122.778 184 146 121.8
-210 146 122.806 214 146 121.645 216 146 121.457
-46 147 121.111 181 147 122.778 182 147 122.778
-184 147 121.457 205 147 122.471 205 146.5 123
-208 147 121.457 209 147 121.8 211 147 121.8
-91 147.5 123 181 148 121.7 205 148 121.457
-207 148 121.457 211 148 121.457 212 148 122.125
-214 148 122.125 90 149 122.419 188 149 121.8
-210 149 121.457 212.375 149 123 42 150 122.4
-41.625 150 123 42 149.625 123 42.2727 150 123
-89 150 120.882 203 150 121.853 204 150 121.457
-209 150 121.457 210 150 121.645 211 150 122.217
-211.75 150 123 220 150 121.08 52 151 120.692
-208 151 121.457 214 150.625 123 53 152 122.5
-54.75 152 123 62 151.5 123 84 152 120.529
-189 152 121.457 208 152 121.2 177 153 122.609
-176.4 153 123 177 152.727 123 177.75 153 123
-177 153.25 123 103 154.211 123 104 155 120.857
-200 155 121.457 101.313 156 123 103 156 120.375
-217 156 122.182 216.455 156 123 218 155.813 123
-218 156 122.182 219.429 156 123 102 156.846 123
-103 156.933 123 217 157 121.696 216.286 157 123
-218 157 122.182 219 157 120.75 217 157.5 123
-206 159 122.053 207 159 121.875 165 159.813 123
-207 160 121.355 208 159.083 123 209 159.727 123
-209 160 122.438 209.429 160 123 60 161 122.333
-165 160.75 123 166 161 121.091 186 161 122.71
-187 160.364 123 188 161 122.55 207 161 121.696
-208 161 122.053 209 160.333 123 212 161 121.125
-57 161.455 123 70 162 120.273 72 161.263 123
-72 162 121.645 167 162 122.125 166.125 162 123
-167 161.125 123 187 162 120.222 57 163 122.625
-71 163 121 98 163 122.526 98 162.625 123
-99 162.045 123 99 163 120.261 100 163 120.158
-102 163 121.636 101.667 163 123 103 163 120.875
-167 162.467 123 169 163 122.71 168.25 163 123
-181 163 122.55 180.87 163 123 181.75 163 123
-57 164 120.75 58 163.273 123 90.6957 164 123
-93 164 122.4 100 164 121.091 102 164 121.125
-103 164 120.333 161 164 121.2 168 164 122.739
-167.923 164 123 172 163.6 123 182 163.143 123
-57 165 120.375 161 164.6 123 163 164.391 123
-182 165 122.842 182 164.857 123 191.375 165 123
-195 164.333 123 196 164.217 123 198 164.923 123
-172.654 166 123 182 166 120.783 195.8 166 123
-210 166 122.609 209.75 166 123 85 167 122.222
-84.125 167 123 85 166.632 123 85.5833 167 123
-162 166.783 123 163 166.526 123 191 167 121.235
-191 166.167 123 200 167 121.125 201 167 121.235
-210 167 122.438 211 167 122.4 84 168 122.4
-83.25 168 123 169 167.609 123 192 168 120.375
-201 168 120.4 202 168 121.05 203 168 120.783
-211 168 120.2 211.875 168 123 84 168.2 123
-90.125 169 123 91 169.368 123 95.1875 170 123
-211 169.15 123 212 169.375 123 92.4615 171 123
-93 172 121.75 170 171.87 123 170 173 120.75
-171 172.727 123 193 174 122.6 193 173.333 123
-194 173.067 123 194 175 120 194.9 175 123
-171 175.316 123 159 180.31 123 183.4 184 123
-184.545 184 123 182.895 185 123 175.143 186 123
-177 185.4 123 177 186 121.615 180.417 186 123
-181 186 121.091 178 187 121.889 179 187 122.1
-180 187 121.5 183 186.333 123 178 187.909 123
-182 188.435 123 193 188.077 123 92 190.6 123
-203 70 125.71 202 71 124.5 202.37 71 126
-202.286 73 126 208 81 123.12 205 83 125.727
-208 83 123.682 207 84 124.826 206 85 125.778
-205.8 85 126 206.5 85 126 206 86 125.125
-205.364 86 126 206.875 86 126 209 86 125.125
-210.375 86 126 211 85.7727 126 207.4 87 126
-209 87 125.032 210 87 125.333 210.545 87 126
-214 87 124.304 212 87.25 126 211.143 88 126
-213 88 125.625 210.867 89 126 212 89 124.645
-213 90 125.333 216 91 125.7 223.909 91 126
-215 92 125.739 216 92 125.75 224 92 124.636
-214 93 125.778 217 93 124.889 216 94 124.645
-217 94 125.217 218 94 125.625 217 95 125.217
-218 95 125.211 219 95 125.786 36 96 125.8
-36 95.7143 126 216 96 124.645 217 96 124.889
-218 96 124.111 219 96 123.136 35 97 125.778
-36 97 125.471 36 98 125.824 34 99 125.609
-35 99 124.5 34 100 124.421 35 100 124.5
-215 100 124.457 35 101 124.818 216 105 124.457
-218 109 124.5 219 109 124 218 111 123.882
-219 111 123.517 216 112 125.471 221 112 123.176
-215 113 125.5 218 113 125.885 220 113 124
-219 114 125.864 214 116 125.824 215.75 117 126
-217 119 124.457 36 121 124.457 37 121 125.471
-152.6 121 126 155 121 124.457 157 121 124.8
-215 121 124.457 152 122 125.625 153 122 124.853
-166 121.833 126 153 123 123.882 155 123 124.457
-165 123 125.125 218 123 124.457 36 124 124.8
-146.923 124 126 165 124 125.217 170 123.833 126
-218 124 124.8 220 124 123.818 36 125 124.457
-160 125 124.313 165 125 125.125 170 125 124.8
-212 125 125.1 211.4 125 126 219.857 125 126
-221 125 125.25 223 125 125.545 224 125 125.206
-35 126 123.882 36 126 124.645 37 126 124.645
-145.8 126 126 160 126 123.783 170 126 124.457
-212 126 125.778 213 126 125.55 213.6 126 126
-219 126 125.885 223 126 125.545 224 126 124.909
-36 127 125.217 213.25 127 126 36 128 124.826
-37 128 124.889 174 127.25 126 217 127.739 126
-216.571 128 126 228 128 123.75 227.25 128 126
-37 129 124.645 38.5 129 126 174 129 124.645
-214 129 125.55 216 129 125.55 216 128.727 126
-228 128.75 126 38 130 125.471 174 130 124.889
-146.5 131 126 212 131 124.457 37 132 125.559
-176 132 124.645 216 132 124.889 177 133 125.143
-211 133 124.8 215 133 124.457 211 134 124.457
-217 135 124.3 216 136 124.147 217 136 124.5
-176 137 124.111 213 138 124.2 207.167 139 126
-209 139 124.457 217 139 124.125 224 139 125.455
-223.2 139 126 224 138.556 126 225 138.5 126
-225 139 125.143 102 140 124.2 104 140 124.227
-182 140 124.645 183 140 124.7 207.5 140 126
-216 140 124.8 217 140 124.545 43 141 125.824
-103 141 123.947 104.857 141 126 167 141 124.385
-166.364 141 126 167 140.417 126 182 141 124.889
-184 141 124.645 209 141 124.645 216 141 124.345
-218 141 123.818 42 142 124.235 43 142 125.559
-99 142 124.2 105 141.25 126 167 142 124
-183 142 124.645 186 142 124.7 186.722 142 126
-203 142 124.457 207.222 142 126 209 142 124.645
-213 142 124.5 46 142.5 126 168 143 123.13
-169 143 124.3 185 143 124.645 190 143 125.778
-191 143 124.457 192 143 124.645 205 143 124.8
-97 144 123.182 105 144 124.826 116 143.769 126
-168 144 124 169 144 123 184 144 123.882
-190 144 125.032 191 144 124.645 198 144 124.457
-202 144 124.457 105 145 124.105 106 145 124.2
-116.737 145 126 168 144.37 126 169 144.609 126
-188 145 125.1 189 144.125 126 193 145 125.55
-201 145 124.457 205 145 124.457 89 145.25 126
-115 145.857 126 115.25 146 126 194 146 124.457
-90 147 124.5 116 146.111 126 191 147 124.645
-202 147 124.457 196 148 124.8 43 149 124.364
-44 149 125.609 45 149 125.8 59 149 125.824
-191 149 124.457 194 149 123.529 197 149 124.556
-214 149 124.412 216 149 124.56 217 149 124.364
-42 150 123.818 43 149.857 126 44 149.273 126
-59.3333 150 126 60 150 125.75 61 150 125.333
-64 150 124.457 212.25 150 126 215 150 125.833
-216 150 125.864 217 150 124.909 54 151 123.316
-55 151 123.833 56 151 124.5 211.4 151 126
-214.75 151 126 54 152 124.286 59 151.375 126
-177 153 124.286 218 153 125.667 217.727 153 126
-176 154 125.308 102 155 125.8 174 155 125.55
-174 154.571 126 175 155 124.862 214 155 125.118
-215 155 124.5 217 155 124.875 217.4 155 126
-175 156 124.889 176 156 124.929 176.667 156 126
-214 155.909 126 216 156 123.938 217.368 156 126
-218 156 123.6 219 156 123.692 100 156.333 126
-102 157 123.75 103 156.273 126 204 157 125.4
-216 157 124.714 218 157 123.6 219 157 123.391
-100 157.909 126 205 158 123.8 206 158 124.091
-184 159 125.323 184 158.125 126 185 158.217 126
-185 159 124.258 205 159 123.517 208 158.923 126
-165 160 123.333 185 160 123.9 186 160 123.13
-208.654 160 126 209 160 123.75 61 161 123.3
-72 161 123.789 74 161 125.471 94 161 125.455
-94.5455 161 126 180 161 125.727 180 160.714 126
-181 160.444 126 185 161 125.684 57 162 124.2
-57.6 162 126 60 162 125.25 61 162 123.75
-70 162 124.579 73 162 123.556 92 162 124.7
-167 162 125.625 167.333 162 126 168 161.923 126
-168 162 125.143 181 162 123.188 180.063 162 126
-208 162 124.875 60 162.097 126 61 162.273 126
-69 163 124.5 71 163 125.727 71.25 163 126
-167.391 163 126 168 163 123.2 171 162.265 126
-181.25 163 126 207 162.2 126 208 163 126
-90 164 124.92 97.7273 164 126 163 164 125.25
-163 163.813 126 181 164 123.563 182 164 123.783
-190 163.773 126 87 165 125.4 86.6 165 126
-87.8571 165 126 192 165 124.111 194 165 123.1
-86 166 124.35 87 166 124.444 87.6364 166 126
-90.7391 166 126 164.435 166 126 191.857 166 126
-198 166 125.318 210 166 125.25 84.4737 167 126
-86 167 124.25 86.5833 167 126 162 166.6 126
-163 167 124.8 171.2 167 126 189 166.143 126
-210 167 124.125 211 167 123.75 84 168 123.818
-90 168 123.4 211 168 125.211 191 170 124.696
-190.333 170 126 192 169.889 126 192 170 125.25
-169 171 124.765 170 170.842 126 170 171 125.609
-191 170.909 126 192 171 124.263 191.083 171 126
-169 172 124.043 168.375 172 126 192 172 125.455
-193 172 124.875 171 173 124.636 170.737 173 126
-193 173 123.75 194 173 123.75 170 174 125.211
-171 174 125 195 175 124.2 195.13 175 126
-194 175.435 126 195 175.375 126 197 178 124.889
-197 179 124.821 197.733 179 126 197 179.917 126
-175 183 125.6 179 183 125.769 164 183.941 126
-184 184 124.2 175 185 124.889 176 185 125.308
-177 184.714 126 184 185 125.684 170 185.722 126
-170.714 186 126 173 185.714 126 176 185.375 126
-171 186.087 126 172 186.261 126 179 186.455 126
-180 186.333 126 192 186.818 126 182.5 188 126
-93 190 125 96 190.059 126 202.654 72 129
-207 72 128.806 209 72.6087 129 210 73.0909 129
-208 76 128 207.533 76 129 210 79 126.789
-210 78.2632 129 211 79 128.6 210 80 127.364
-210.857 80 129 211 79.6667 129 212 80 128.833
-211.5 80 129 212 79.9091 129 212 81 128.483
-211.5 81 129 212.5 81 129 212 81.4545 129
-207 85 126.857 205.1 86 129 207 86 126.5
-208 86 126.214 211 85.6667 129 212 86 126.5
-213 86 126.5 207 87 128 212 87 126.857
-213 87 127.071 205.833 88 129 207 87.0909 129
-210 88 126.4 211 87.75 129 211 88 127
-206 88.1667 129 210 89 127.773 205 90 128.684
-214 90 126.316 204 90.625 129 205 91 127.889
-211 90.625 129 212 90.4167 129 213 91 127.071
-215 91 126.882 223 91 128.143 204 92 128.125
-223 92 126.882 37 93 128.6 38 92.7143 129
-38.0909 93 129 203 93 128.684 205 93 127.457
-208 93 128.206 209 93 128.032 210 93 128.667
-37 94 128.053 203 94 128.333 209 94 128.333
-213.125 94 129 219 94 127.286 36 95 127
-202.739 95 129 209 95 128.125 34.9333 96 129
-203.5 96 129 209.583 96 129 213 96 128.625
-212.75 96 129 206 97 127.8 208 97 127.457
-210 96.7143 129 210 97 128.684 205 97.5 129
-209 98 127.889 211 98 127.889 212 99 127.889
-213 99 127.5 209 100 127.645 209 101 127.457
-212 102 127.457 208 103 127.8 208 104 127.457
-205 109 128.206 203 110 128.143 206 110 128.032
-207 110 127.457 214 110 127.457 212 111 127.457
-200 111.833 129 201 113 127.457 198.625 114 129
-204 114 127.853 218 114 126.818 199 115 127.8
-200 115 127.457 201 117 127.457 215 117 126.265
-223 117 127.895 222.632 117 129 223.875 117 129
-211 118 127.457 212 118 127.5 223 118 128
-222.143 118 129 223.261 118 129 202 119 128.8
-208 119 127.457 213 119 128.206 214 119 127.182
-202 120 128.419 203 120 128.5 209 120 127.457
-161 120.417 129 204 121 128.118 209 121 128.032
-152 121.818 129 166.6 122 129 205 122 127.457
-29.8235 123 129 167 122.25 129 168.6 123 129
-149 123.7 129 170.25 124 129 188 124 128.909
-187.833 124 129 208 124 127.889 196 125 128.143
-197 125 127.8 206 125 127.457 218 124.955 129
-218.1 125 129 39 126 127.182 189 126 128.824
-199 126 128.032 204 126 127.457 206 126 127.645
-210 126 128.308 133 126.824 129 172.75 127 129
-174 126.857 129 174.286 127 129 199 127 128.333
-205 127 127.457 206 127 127.889 210.455 127 129
-211 127 126.75 214 127 128.077 214.571 127 129
-216 126.25 129 218 127 126.3 217.25 127 129
-173 127.125 129 199 128 128.125 206 128 128.125
-215 128 126.964 228 128 126.818 179 128.182 129
-181 129 127.645 206.833 129 129 39 130 126.581
-146.273 130 129 179 130 127.8 183 130 127.457
-197 130 127.853 198 130 127.889 205 130 127.457
-207 130 128.25 209 129.417 129 39 131 126.529
-40 131 127.2 41.625 131 129 197 131 128.4
-198 131 128.55 201 131 128.125 209 131 127.457
-40 132 127.853 188 133 128.032 40 134 127.286
-180 134 127.543 187 134 127.889 188 134 128.217
-192 134 128.471 193 133.75 129 184 135 128.1
-188.286 135 129 192 135 127.457 43 136 127.8
-43.875 136 129 182 136 127.2 184 136 128.778
-185 136 128.778 186 136 128.125 206 136 127.457
-219 136 128.55 183 137 128.143 184 137 128.778
-185 137 128.778 196 137 128.55 203 137 127.8
-218 137 128.625 217.813 137 129 219 137 127.696
-220.375 137 129 102 138 126.29 184 138 127.75
-187 138 127.645 188 138 127.962 202 138 128.559
-219 137.667 129 220 137.375 129 222 138 128.4
-221.25 138 129 223 138 127.25 224 138 127.875
-224.375 138 129 186 139 128.1 187 139 127.889
-188 139 128.333 201 139 128.8 203 139 128.559
-205 139 128.032 206 139 127.444 223 139 126.429
-222.6 139 129 225 138.714 129 225.105 139 129
-186 140 126.563 187 140 127.111 188 140 127.853
-192 140 127.457 193 140 127.457 197 140 127.645
-200 140 127.457 204 140 128.423 204.714 140 129
-225 139.133 129 104 141 127.636 166.667 141 129
-167 140.143 129 188 141 128.4 189 141 128.909
-190 141 128.182 196 141 127.457 205.167 141 129
-213 141 127.154 214 141 127 105 142 126.818
-166.435 142 129 189 142 128.897 199 142 127.235
-200 142 126.882 201 142 126.176 207 142 128
-48 143 127.5 106 143 128.167 187.5 143 129
-189 143 128.833 188.857 143 129 194 143 127.345
-206 143 126.316 207 143 128 208 143 126.682
-50 143.188 129 207 144 127.615 208 144 127.7
-113.6 145 129 114 144.143 129 188 144.091 129
-114 146 128.217 115 147 128.769 114.714 147 129
-116 146.609 129 43 149 127.636 44 149 127.286
-44.4 149 129 45 148.455 129 46 148.727 129
-46 149 128.182 47 149 127.95 47.4667 149 129
-67 149 126.529 46 149.25 129 47 149.875 129
-59 150 126.094 211.455 150 129 214 150 126.75
-59 151 127 210 151 127.625 210 150.522 129
-211 151 126.3 213.667 151 129 208.813 152 129
-210 152 127.889 211 152 127.95 209 153 129
-211 152.304 129 216 153 128.786 214 153.565 129
-217 154 127.875 218 153.933 129 217.75 154 129
-174 154.5 129 176.895 155 129 205 155 128.71
-206 155 128.118 207 154.625 129 207 155 128.667
-101 156 128 102 156 127.826 174.074 156 129
-177 155.087 129 177 156 126.577 183 156 128.25
-182.125 156 129 204 156 127.147 206 156 128.308
-97 157 127.846 98 156.313 129 98 157 127.821
-100 156.067 129 101 156.625 129 101.25 157 129
-102 157 127.2 176 157 126.115 177 157 126.441
-183 157 127.8 184 156.632 129 184 157 128.125
-202 157 128.824 203 157 126.9 214 156.618 129
-217 157 127.5 178 158 128.71 183 158 128.222
-184 158 126.158 61 159 128.727 62 159 127.645
-95 159 128.4 183 158.778 129 183.1 159 129
-207.435 159 129 58.375 160 129 62 160 126.9
-71.9259 160 129 73 160 127.3 75 159.895 129
-94 160 126.75 95 160 127.038 95.7727 160 129
-179 160 128.8 180 159.045 129 180 160 126.577
-187 160 126.316 204 159.333 129 208 160 127.962
-62.4667 161 129 75 161 127.818 95 161 126.682
-95.5862 161 129 179.357 161 129 185 161 126.6
-186 161 128.348 186 160.545 129 208 161 127.304
-62 161.636 129 61.4286 162 129 71 162 128.625
-71.0769 162 129 92 161.056 129 168.769 162 129
-170 162 126.2 180 161.947 129 186 162 126.75
-187 162 128.217 207 162 126.692 207 161.167 129
-61 162.2 129 88.4545 163 129 89 162.455 129
-90 162.105 129 95 163 127.92 97.875 163 129
-167.833 163 129 181 162.231 129 187 162.75 129
-88 164 127.8 88 163.455 129 89 164 126.9
-95 164 127.714 97 164 128.286 96.6429 164 129
-100.176 164 129 163 163.571 129 163.857 164 129
-172.382 164 129 188 163.067 129 193 163.263 129
-86.5417 165 129 87 164.522 129 89 165 127.125
-90 165 127.5 97 165 128.769 98 165 128.217
-162.045 165 129 196 165 128.273 86 166 128.2
-86.3636 166 129 87.5833 166 129 91 165.261 129
-99 165.333 129 162 166 127.929 168.923 166 129
-194 166 126.818 195 166 128.294 195 165.6 129
-196 166 128.429 197 166 127.909 85 167 127.111
-86 167 127.05 92 167 127.5 93 167 128.5
-95.6667 167 129 165 167 126.857 189 167 127.125
-189.667 167 129 191 166.385 129 193 166.111 129
-166 168 128.1 166.857 168 129 189 168 127.696
-190 168 129 95.3704 169 129 164 168.333 129
-167.25 169 129 188.727 169 129 190 169 126.375
-95 169.909 129 168 170 127.75 169 170 126.783
-169.773 170 129 191 169.125 129 192 170 126.75
-168 171 128.25 167.87 171 129 169.944 171 129
-192 171 128.063 192 172 126.333 193 172 126.474
-193 173 126.45 194 173 126.45 194 174 127.222
-194 175 127.111 195 175 126.6 196 177 127.714
-196 176.75 129 197 177 127.333 197.833 177 129
-196 178 127.364 198.667 178 129 198 179.75 129
-207 180 128 92 181 128.667 92.375 181 129
-196 180.778 129 197 181 128.526 196.4 181 129
-202 181 127.174 204 181 127.765 207 181 127.393
-208 181 128.55 92 182 127.636 92.9091 182 129
-200.75 182 129 202 182 127.038 206 182 128.471
-207 182 128 208 182 127.444 209 182 126.9
-92 183 128.571 92.6667 183 129 174 183 126.273
-173.375 183 129 177 183 127.773 197 183 128.609
-198 183 128.71 207 183 128.333 208 183 126.261
-92 183.125 129 172 184 128.526 171.25 184 129
-171 185 128.455 172 185 127.8 173 185 126.682
-170 185.9 129 170.25 186 129 176 185.929 129
-175.68 187 129 179 187 127.565 178.45 187 129
-180 187 127.385 181 186.4 129 179 188 127
-178.5 188 129 180 188 126.5 181 188 127.5
-182 188 127.688 192.727 189 129 94 189.409 129
-95 190 127 193 189.194 129 86 191 126.5
-90.7368 191 129 87 191.8 129 90 191.452 129
-203 72 130.929 204 72 131.308 207 74 131.727
-208 74 130.962 211 74 130.765 208 75 130
-207.474 75 132 209 75 131.526 209 75.375 132
-208 76.5556 132 211 79 129.6 210 80 130.636
-212 80 129.231 212 81 129.882 213 82 130.5
-214 83 130.2 214.6 83 132 214 84 132
-206 85 130.2 214 85 129.429 213.5 85 132
-215 84.1 132 215 85 129.545 206.667 86 132
-210.727 86 132 215 85.5 132 42 87 131.909
-205.9 87 132 205.182 88 132 207 88 132
-41 89 131.824 205 89 130.846 205 88.2857 132
-206 89 129.882 207 89 130.857 208 89 130
-206 90 129.125 208 90 130.345 209 90 129.529
-210 90 129.261 39 91 131.739 211 91 129.391
-212 91 130.75 216 91 131.571 215.8 91 132
-216 90.7143 132 38 92 131.143 39 92 130.962
-39.6 92 132 203.37 92 132 212 92 130.364
-216 92 130.875 39 93 131 212 93 130.655
-216 92.75 132 211 95 132 212 95 132
-213 95 130.071 215 95 131.609 215 94.25 132
-216 95 132 202.533 96 132 215 95.3333 132
-211 97 129.094 34.5 98 132 203 98 131.129
-204 99 131.419 205 99 131.25 206 99 130.773
-37 100 129.529 201.727 100 132 207 100 130.304
-202 101 131.032 203 101 130.457 204 101 130.8
-202 102.25 132 202.857 103 132 203.167 104 132
-198.346 112 132 196 115.929 132 223 117 130.4
-194 118 131.739 193.889 118 132 223 118 130.636
-194 119 131.419 193.143 119 132 195 120 131.559
-212 120 129.882 153 121 129.667 155 121 130.543
-161 121 129.875 192 121 131.806 192 120.75 132
-192.5 121 132 195 121 131.471 212 121 130.154
-161 122 130.543 166 122 129.45 192.667 122 132
-193.75 122 132 40 123 131.1 152 123 129.857
-166 123 129.581 168 123 129.45 191 123 131.125
-193 122.75 132 193 123 131.909 202 123 129.545
-209 123 129.818 210 123 130.56 41 124 131.684
-159 124 130.543 167 124 130.147 187 124 130.364
-188 123.087 132 189 124 130.5 190 124 130.75
-195 124 129.857 210 124 129.409 218 124 131.625
-218 123.727 132 40 125 130.5 150 125 130.645
-157 125 130.543 165 125 129.529 170 125 130.355
-186 125 129.545 185.64 125 132 187 125 129.261
-191.75 125 132 192 124.5 132 194 125 131.182
-209 125 129.469 217 125 129.563 43 126 130.8
-157 126 130.543 158 126 129.581 160 126 129.2
-161 126 130.2 163 126 130.543 187 126 129.2
-190 126 130.235 201 126 129.094 208 126 129.714
-151 127 130.889 153 127 131.143 154 127 131.471
-155 127 131.118 156 127 131.471 159 127 129.5
-170 127 130.543 188 127 129.818 192 126.6 132
-192 127 131.824 210 127 130.667 133 127.5 132
-160 128 130.3 174 128 131.333 175 127.875 132
-176 127.625 132 180 127.435 132 185 128 131.885
-184.857 128 132 187 128 130.235 188 128 129.818
-191 128 131.206 200 128 129.844 201 128 130.545
-206.913 128 132 209.933 128 132 216 127.889 132
-44 129 130.645 161 129 131.824 164 128.909 132
-184 128.231 132 192 129 130.3 200 129 129.844
-201 129 130.182 207 128.286 132 42 130 130.111
-44 130 131.333 187 130 129.529 188 130 129.529
-189 130 130.08 190 130 129.882 191 130 130.5
-192 130 130.111 194 130 130.2 201 130 129.091
-44 131 131.333 188 131 129.265 189 131 130.773
-192 131 131.217 193 131 130.2 199 131 130.2
-46 132 131.333 192 132 131.333 194 132 130.5
-196 132 129.882 199 132 132 43 133 131.909
-47 133 131.032 106 133 129.882 110 132.265 132
-189.538 133 132 192 133 130 193 133 129.529
-195 133 130.235 197 133 131.217 197.462 133 132
-42 134 130.909 48 134 131.419 189 134 130.071
-190 133.545 132 191 134 130.8 194 134 129.682
-195 134 130.5 196 134 130.3 197.5 134 132
-198.857 134 132 45 134.857 132 103 135 129.265
-196 135 130 101 136 129.265 102 136 129.176
-189 136 129.517 196.571 136 132 218 136 129.167
-217.105 136 132 189 137 129.774 190 137 129.469
-196.696 137 132 201 137 129.9 221 136.875 132
-221 137 130.875 49 137.85 132 199.688 138 132
-217 138 131 220 138 129.682 223 138 130.615
-45 139 130.545 46 139 131.206 49 139 130.457
-52 139 130.457 199 139 129.882 199 138.478 132
-222 138.545 132 223 139 130.286 224 139 130.154
-50 141 130.457 87 141 131.206 131.294 141 132
-168 141 130.105 185 141 131.625 186 141 131.438
-186.188 141 132 204.75 141 132 205 140.813 132
-207.333 141 132 50 142 130.2 86 142 130.457
-106 142 131.143 167 142 130.182 186 142 132
-188 142 129.391 205.417 142 132 106 142.286 132
-187 143 131.25 186.333 143 132 187 142.857 132
-187.667 143 132 206 142.259 132 56 144 130.457
-75 144 130.457 80 144 130.457 85 144 129.265
-158 144 130.875 157.667 144 132 159 143.091 132
-159 144 130.421 159.667 144 132 171 144 129.789
-172 143.25 132 186.813 144 132 189 144 132
-74 145 130.457 81 145 129.529 82 145 130.235
-84 145 129.818 113.818 145 132 158 144.75 132
-159 145 131.308 158.143 145 132 159.545 145 132
-170 145 130.8 172 145 130.853 116.111 146 132
-159 145.4 132 172 146 131.118 73 147 129.176
-114 147 129.556 116 146.375 132 114 148 131
-115 147.947 132 45 149 129.783 46 149 129.6
-47 149 130.75 212 150 129.783 212 151 130.957
-208.8 152 132 210.545 152 132 63 153 131.077
-62.2 153 132 63 152.667 132 64 153 130.95
-208 153 129.75 210.133 153 132 216 153 129.273
-218 153 130.826 65 153.571 132 65 154 131.667
-66 153.667 132 66 154 131.419 207 154 130.875
-206.625 154 132 209 154 131.667 209.5 154 132
-216 154 130.667 217 154 129.474 64.8125 155 132
-66 155 131.118 181 155 130.3 182 155 129.1
-183 155 129.167 203.25 155 132 208 155 130.5
-209 155 131.8 210 155 131.471 211 154.421 132
-211 155 130.969 212 154.192 132 65.6 156 132
-67 155.125 132 67 156 131.323 68 156 131.667
-98.5455 156 132 175 155.818 132 176 155.65 132
-180.923 156 132 182 156 129.115 201 156 130.696
-202 155.419 132 208 156 131.8 209 155.5 132
-210.25 156 132 64 157 131.8 64.5 157 132
-66 157 131.769 68 157 131.118 69 157 131.118
-70.1875 157 132 99 156.357 132 99.4091 157 132
-175.1 157 132 184.077 157 132 200 157 130.543
-206.143 157 132 209 157 131.824 209.667 157 132
-212 156.292 132 214 156.519 132 61.2273 158 132
-65 158 131.654 70 157.75 132 93.6667 158 132
-94 157.474 132 185 158 129.947 184.188 158 132
-200 158 130.543 201 158 130.355 206 158 130.5
-206 157.071 132 61 158.278 132 71.4167 159 132
-72 158.533 132 74 158.824 132 75 159 130.889
-98 158.567 132 178 159 130.174 179 158.1 132
-179 159 129.158 183 158.188 132 184 159 131.348
-184 158.375 132 185 159 131.2 200 159 131.71
-204.25 159 132 207 159 130.579 206.25 159 132
-77 159.455 132 77.75 160 132 181 159.227 132
-185 160 130.742 186 160 129.783 206 160 131.885
-207 160 131.04 77 161 131.118 78 160.4 132
-78 161 131.743 89 161 131.053 92.6 161 132
-178 160.545 132 91 161.474 132 99 163 130.909
-181 162.375 132 186 162.474 132 96 163.571 132
-163 164 129.947 168.265 164 132 184 164 131.471
-183.25 164 132 189 163.45 132 193 164 131.625
-87 165 130.65 87.75 165 132 92 164.409 132
-96 165 129.158 98.9333 165 132 163 165 131.172
-164 165 131.333 183.333 165 132 185 165 130.147
-194 165 130.875 195 165 130.5 87 166 129.75
-97 166 131.684 163 166 131.5 166 165.903 132
-190 165.833 132 189.875 166 132 167 166.567 132
-93 168 129.316 163.769 168 132 167 168 129.091
-168 167.346 132 168 168 130.3 188 168 132
-95 168.273 132 166 169 130.227 167 169 129.1
-189 168.857 132 189 169 131.571 190 169 130.105
-62.75 170 132 63 169.8 132 64 169.143 132
-64 170 129.429 94 170 129.882 190 170 129.45
-191 170 129.778 63 171 131.571 62.75 171 132
-169 170.895 132 176 171 131.25 175.143 171 132
-197 170.625 132 175 172 131.667 176 172 130.5
-178 172 131.71 179 172 131.71 179.429 172 132
-198 172 130.444 199 172 131.4 176 173 131.308
-177 172.667 132 179 173 131.71 179.273 173 132
-175 174 131.4 198 173.909 132 198 175.4 132
-199 175.8 132 197 176.6 132 199 177 131.125
-180 179 131.71 196 178.4 132 201 179 130.444
-200.067 179 132 178 180 131.71 178 179.75 132
-178.75 180 132 92 181 132 178 181 130.895
-177 181 132 178.875 181 132 208.526 181 132
-92 182 131 179 181.091 132 196 181.455 132
-92 183 129.333 171 182.941 132 199 183 130.696
-201 183 130.364 206 183 130 172 183.684 132
-180.875 184 132 198 184 129.794 199 184 130.6
-200 184 130.625 202 184 130.821 203 184 131.471
-204 184 131.824 182 184.6 132 183 184.6 132
-184 184.625 132 199 185 131.4 200 185 130.5
-201 185 130.2 202 185 130.8 203 185 131.1
-204 185 130.962 168 185.045 132 171 186 129.45
-172 186 129.75 191 186 131.571 201 186 129.2
-175 187 131.217 176 188 129.783 178 189 130.579
-179 188.75 132 179 189 131.625 93 189.8 132
-179 189.167 132 193 189.323 132 85 191 131.727
-91 190.056 132 86 68 134.625 87 68 134.125
-85 69 134.206 87 69 134.419 91 69 134.824
-203 72.6538 135 207.278 75 135 208 75.6842 135
-215 77 133.444 49 78 134.8 214 78 134.769
-210 79 132.529 214 78.2857 135 216 78.1333 135
-213 79.8667 135 214 80 133.962 213 81 133.5
-212.375 81 135 211.714 82 135 207 82.375 135
-207 83 134.118 208 83 133.846 209 83 134.824
-209.333 83 135 211.714 83 135 43 84 133.696
-44 84 134.419 44 83.1429 135 206 84 132.125
-207 84 133.846 208 84 133.5 208.714 84 135
-209 83.3333 135 210 84 134.769 210.167 84 135
-213 84 134.143 214 83.5 135 213.667 84 135
-42 85 133 41.5652 85 135 43 85 132.581
-44 85 134.471 207 85 134.75 207.125 85 135
-208 84.4167 135 210 84.3333 135 213.75 85 135
-214 84.3333 135 215 84.625 135 215.25 85 135
-42 86 132.261 43 86 133.2 207 86 132.5
-211 86 133.8 41 87 132.316 43.5909 87 135
-206 87 132.143 41 88 132.1 42 88 132.882
-206 88 133.227 40 89 132.115 205 89 132.6
-206 89 133.714 207 89 133.412 39 90 133.8
-206 89.6 135 40 91 132.176 216 91 132.857
-215 94 132.75 214.4 94 135 215.6 94 135
-214 95 133.421 213.333 95 135 216 94.4 135
-214 96 133.444 215 96 132.9 215.737 96 135
-216 95.375 135 214 97 133.778 215 97 134.053
-214 97.9167 135 210 102 134.71 210 101.727 135
-202.278 103 135 230.5 103 135 40 115 132.581
-196 117.143 135 193.25 119 135 192 120.75 135
-192.667 121 135 43 122 133.355 44.25 122 135
-190.75 122 135 192.75 122 135 193.25 122 135
-193 122.167 135 40 124 132.176 188 123.833 135
-189 123.833 135 190 123.286 135 218 123.421 135
-192 125 132.75 193 125 132.316 218.806 125 135
-192 126 132.75 148 127 132.857 149 127 133.2
-150 127 132.176 209.375 127 135 133 128 133.444
-186.143 128 135 206.125 128 135 209.909 128 135
-216 128 133.2 148 129 133.543 149 129 133.543
-156 129 133.543 163 129 132.857 174 129 132.103
-206 129 134.182 207 129 133.25 216 128.75 135
-154 130 133.543 204 130 134.71 203.85 130 135
-205 130 134.25 206 130 134.684 207 129.368 135
-215 130 134.308 215 129.25 135 148 131 132.857
-163 131 133.543 174 131 134.286 189.353 131 135
-204 130.75 135 215 131 133 215.667 131 135
-151 132 134.118 160 132 133.5 162 132 133.8
-163 132 133.543 166 132 134.471 199 131.462 135
-215 132 133.688 214.125 132 135 150 133 134.143
-189 133 133.75 189 132.286 135 191 133 132.833
-44 134 132.29 45 134 132.529 51 134 134.143
-52 134 134.206 150 134 134.032 156 134 133.645
-157 134 133.889 163 134 133.125 164 134 133.147
-175 134 134.727 189 134 133.227 190 134 133.364
-190.5 134 135 46 135 132.882 47 135 132.882
-51 134.833 135 53 135 134.333 154 135 134.471
-155 135 134.143 164 135 133.455 187.643 135 135
-189 135 133.345 198.333 135 135 47 136 134.559
-47.625 136 135 165 136 134.531 190 136 133.966
-211 136 134.654 210.8 136 135 213 136 133.8
-214 136 134.032 215 136 134.333 46 137 133.182
-47 137 134.559 48 137 134.897 49 136.583 135
-57 137 134.8 57 136.75 135 189 136.455 135
-190 136.526 135 195.5 137 135 211 137 134.118
-210.091 137 135 212 137 134.118 214 137 133.8
-215 137 132.857 216 137 132.1 46 138 132.529
-47 138 133.182 56 138 134.217 56 137.143 135
-55.25 138 135 90 138 132.882 161 138 134.714
-55 139 132.429 55 138.1 135 215 138.609 135
-117 140 134.6 116.714 140 135 118 140 133.8
-119 139.455 135 119 140 134.053 119.316 140 135
-185 139.867 135 69 141 133.8 73 141 133.457
-76 141 134.824 76 140.6 135 79 141 133.457
-186 140.444 135 186.333 141 135 203 141 134.032
-204 141 133.35 207.455 141 135 77 142 132.909
-104.5 142 135 105.75 142 135 168 142 132.321
-169 142 133.179 170 142 133.32 185 142 132.13
-186.333 142 135 203 142 134.824 105 142.6 135
-186 143 132.429 186.545 143 135 187 143 132.857
-159 144 134 170 143.167 135 171 143.391 135
-172 143.105 135 186 143.429 135 187 144 134.25
-187.25 144 135 159 145 133.636 188 144.375 135
-113.5 146 135 115 146 134.7 161 146 133.95
-160 146 135 161 145.125 135 162 146 135
-113 147 132.789 113 146.125 135 161 147 134.125
-160.563 147 135 162 147 134.679 172 147 132.091
-113 148 133.3 112.37 148 135 161 147.467 135
-162 147.273 135 173 148 133.645 174 148 134.739
-178 148 133.6 178 147.417 135 50 149 133.714
-49.8125 149 135 51 149 133.6 112.818 149 135
-114 149 134.727 125 148.04 135 174 149 134
-175 149 133.846 177 149 133.355 178 149 133
-178.783 149 135 51 150 133 50.0909 150 135
-52 149.067 135 53 149.565 135 53.9091 150 135
-113 149.133 135 178 150 133.688 53 150.667 135
-177 151 134.71 178 151 133.8 210 151 132.692
-211 151 132.346 179 152 133.969 179.917 152 135
-210 152 133.125 63 153 133 63.7273 153 135
-178 152.188 135 180 153 133.258 181 153 134.55
-65 153.625 135 66 153.667 135 66.2727 154 135
-180 154 132.103 182 153.769 135 210 154 132.375
-211 153.6 135 179.409 155 135 182.955 155 135
-212 154.263 135 214 155 134.471 213.333 155 135
-65 156 133.688 64.5625 156 135 68 155.3 135
-175 156 132.4 177 156 132.875 183 156 134.885
-198 155.65 135 210 156 132.2 212 156 134.625
-213 156 133.4 214 156 133.826 65 157 132.261
-98.6774 157 135 165 157 134.16 164.364 157 135
-165 156.417 135 176 156.867 135 175.867 157 135
-181 156.077 135 182 157 133.2 183 157 134.333
-198 157 132.529 208 157 132.75 210 157 132.273
-61.1429 158 135 67 158 133.258 70 158 132.273
-71 157.625 135 71 158 132.75 195 158 134.471
-197 158 133.543 205 158 133.5 205 157.5 135
-204.333 158 135 208 158 134.609 209.917 158 135
-210 157.909 135 61 159 134.167 61.4545 159 135
-65.9333 159 135 71 158.375 135 72 158.727 135
-77 158.654 135 208 159 134.6 209 159 134.609
-60 160 132.875 61 160 134.2 62 160 134.9
-78 160 132.222 79 159.217 135 80 159.263 135
-80 160 133.765 200.435 160 135 208 159.143 135
-209 159.214 135 60 161 132.333 61 161 133
-62 161 132.692 79 161 132.771 81 161 133.8
-87.5 161 135 95.5 161 135 169 161 133.385
-182 161 134.143 200 160.909 135 77 162 132.577
-81 162 134.471 92 161.778 135 178 162 132.581
-179 162 132.222 182 162 133.421 186 161.931 135
-72 163 132.818 76 162.323 135 81 162.261 135
-93 162.182 135 178 163 133.846 177.333 163 135
-181 163 133.111 182 163 133.355 183 162.364 135
-183 163 133.645 98 163.769 135 182 164 132.794
-183 164 132.194 187.947 164 135 190 164 132.333
-191 164 132.333 88 164.25 135 88 165 133
-91 164.957 135 168.222 165 135 183 165 132.789
-189 165 133.853 190 165 132.882 195 165 134.25
-195 164.333 135 98.4 166 135 149.588 166 135
-165 166 133.962 166 166 133.125 169 166 133.5
-168.5 166 135 172 166 132.261 173 165.091 135
-182 165.292 135 186 165.955 135 187 166 134.842
-195 166 134.143 97 166.706 135 165 166.6 135
-166 166.192 135 168 166.125 135 168 167 133.174
-169 166.286 135 173 167 134.25 172.125 167 135
-173.875 167 135 195 167 134.053 94 167.091 135
-94 168 132.778 95 167.7 135 173 168 134.679
-174 168 134.032 189 168 132.6 195 168 134.419
-196 167.25 135 196 168 134.471 165.433 169 135
-174 169 133.5 196 169 133.625 63 170 135
-64 170 133.2 174 170 133.645 175 170 133.174
-195 169.545 135 196 170 133.688 197 169.75 135
-197 170 133.875 63 171 134 168 170.5 135
-176 170.067 135 196.417 171 135 86 172 133.543
-174.3 172 135 178 171.8 135 179.875 172 135
-219 171.739 135 83 173 134.778 84.7143 173 135
-87 173 133.543 173.926 173 135 174 172.75 135
-177 172.733 135 179.917 173 135 205 173 133.696
-205 172.091 135 206 173 133.565 206.647 173 135
-81 174 134.52 80.5556 174 135 82 174 134.333
-85 173.667 135 176 173.25 135 178 173.273 135
-179.182 174 135 198 173.857 135 205 173.667 135
-206 174 135 81 174.8 135 86 175 134.087
-174 175 134.143 175 175 132.429 175.316 175 135
-179 174.333 135 86 176 133.421 87 176 133.889
-198 175.364 135 199.261 176 135 207 176 134.053
-207 175.25 135 208 175.571 135 208 176 132.429
-86 177 134.182 85.8696 177 135 87 177 134.308
-176 177 134.609 177 177 134.667 207 177 134.069
-208 177 134.182 208.545 177 135 86 177.333 135
-87 177.545 135 176 178 134.609 177 178 134.625
-177.375 178 135 180 177.222 135 181 177.684 135
-199.929 178 135 200.091 178 135 201 177.565 135
-207 178 132.6 208 178 133.091 208.737 178 135
-176 178.6 135 177 179 134.55 178 178.417 135
-178 179 133.688 179 179 132.273 181 179 132.158
-196 179 133.227 198 178.933 135 199 178.684 135
-177 180 135 179 180 132.75 180 180 132.833
-181 180 132.167 182.065 180 135 197 179.429 135
-197 180 134.143 178 180.909 135 178 181 134.625
-180.375 181 135 182 181 133.364 196 181 133.071
-196.818 181 135 197 180.667 135 198 180.818 135
-177 181.5 135 178 181.333 135 181.125 182 135
-199 182 134.6 182 182.875 135 182 184 134.25
-166 184.045 135 184 184.1 135 174 186 134.318
-180 185.391 135 174 187 132.333 177 186.333 135
-190.4 187 135 90 188 134.609 89.625 188 135
-178 187.087 135 90 189 134.125 90.875 189 135
-174 189 134.1 193 188.591 135 91 189.143 135
-179 190 133.154 180 189.133 135 180 190 132.947
-181 190 134.684 88.4737 191 135 84 192 133.304
-93 191.391 135 80 192.5 135 92 68 135.3
-92.6429 68 138 82 69 136.773 83 69 135.273
-84 68.1923 138 66 70 136.5 66 69.4348 138
-69 70 137.419 72 70 137.824 75 70 136.645
-81 70 136 82 70 136.2 83 70 135.6
-84 70 135.75 86.875 70 138 87 69.9333 138
-89 69.875 138 89.1333 70 138 93 70 136.645
-94 69.1818 138 94 70 137.206 97 70 137.684
-65 71 137.739 66 71 136.962 67 71 137.333
-80 70.9444 138 83 71 137 90 71 137.684
-93 71 136.645 94 71 136.457 97 71 137.217
-97.8571 71 138 63 72 137.679 64 72 137.8
-64 71.3333 138 96 72 137.125 97 72 137.125
-97.875 72 138 62 73 137.778 97 72.875 138
-98 72.3333 138 97.3333 73 138 98 73 137.684
-98.5 73 138 99.25 73 138 101 73 136.889
-202 73 136.2 203 73 136.5 92 73.5 138
-101 74 137.419 202 74 136.636 203 73.5 138
-51 76 136.364 51 75.7778 138 52 76 136.364
-52.75 76 138 211 76 136.147 49 77 136.929
-50 77 135.316 51 77 135.261 52 77 137.053
-52.5 77 138 48 78 136.071 50 78 135.321
-51 78 136.556 47 79 137.455 48 79 135.261
-49 79 136 214 79 136.875 216 79 136.444
-47 80 135.5 48 80 136.5 213 80 135.333
-215 80 136.25 46 81 136.125 213 81 135.536
-214 80.2 138 214 81 136.286 45 82 135.714
-214 82 135.346 218.333 82 138 44 83 135.167
-45 83 135.2 46 83 136.5 207 83 136.071
-209 83 135.15 212 83 135.273 219 83 137.739
-218 83 138 45 84 135.529 207 84 136.5
-208 84 135.714 210 84 135.143 213 84 135.273
-218 84 137.52 217.5 84 138 219 83.3333 138
-207.2 85 138 214 85 135.333 215 85 135.45
-218 85 136.8 218.6 85 138 218 86 138
-40.5 87 138 215 94 135.391 215 95 137.25
-216 95 135.333 215 97 137.571 214 98 135.75
-213 98 138 41.375 99 138 204 99 136.889
-213 99 137.25 213.75 99 138 213 100 137.526
-202 101 135.968 212 101 137.667 211.25 101 138
-212 100.25 138 209.263 102 138 211 101.091 138
-211 102 136.696 210 103 135.938 209.421 103 138
-211.545 103 138 210 103.917 138 42 109 137.545
-42.6842 110 138 197 118 136.25 195 121 137.217
-195.316 121 138 45.5 122 138 192 122 135.783
-193 123 136.5 194.857 123 138 199 124 137.824
-188 125 136.2 189 125 136.2 191 125 135.667
-217 125 137.864 49 126 137.143 188 126 136.355
-190 126 137.032 192 126 136.8 186 127 135.222
-191 126.5 138 208 127 135.6 218 126.375 138
-207 128 136.826 208 128 137.143 99 128.5 138
-103 129 135.882 105 128.172 138 206 129 137.571
-208 129 135.818 97 130 137.471 99 130 136.457
-183 130 136.2 184 130 135.875 204 129.864 138
-205 129.533 138 206 129.333 138 98 131 136.889
-177 131 136.543 186 130.4 138 190 130.143 138
-190.4 131 138 204 131 135.6 203 131 138
-204.444 131 138 31 132 135.783 97 132 136.826
-173 132 135.667 182 132 136.543 184 132 136.25
-198 131.85 138 199 131.739 138 202 132 137.4
-202 131.842 138 203 132 136.25 203.583 132 138
-215 132 138 54 133 136.2 55 133 136.8
-56 132.5 138 89.6 133 138 93 133 136.8
-168 133 136.543 172 133 136.543 175 133 135.194
-177 133 136.2 184 133 136.889 184.909 133 138
-200 133 136.636 201 133 137.55 202 133 136.444
-203 133 137 56 134 137.143 92 134 137.032
-151 134 135.529 152 134 136.543 153 134 135.529
-174 134 135.176 176 134 135.455 180 133.273 138
-184 134 137.625 185 134 137.125 202 134 137.4
-51 135 135.2 54 135 135.6 57 135 136.556
-86 134.833 138 87 135 137.206 152 135 136.543
-160 135 136.355 175 135 135.441 185 135 137
-186 135 136.95 187 134.286 138 187 135 136.421
-201 134.182 138 213 134.727 138 48 136 135.391
-49 136 136.313 50 136 137.8 51 136 137.8
-53 136 135.4 55 136 136.2 57 136 136.125
-58 136 137.1 60 136 136.8 82 136 137.471
-89 136 135.968 152 136 135.968 158 136 136.2
-167 136 136.111 170 136 136.543 174 136 137.118
-176 136 135.577 192.818 136 138 210.6 136 138
-211 135.818 138 219 136 136.962 50 137 136.286
-52 136.533 138 53 136.65 138 55.3333 137 138
-56 137 135.429 153 137 135.857 159 137 136.111
-162 137 135.316 167 137 136.696 170 137 136.543
-177 137 137.55 195 137 137.053 209 137 137.625
-210 136.375 138 219 137 137.516 52 137.467 138
-55.5455 138 138 74 138 136.457 77 138 136.457
-79 138 137.217 80 138 137.217 158 138 137.4
-170 138 136.543 175 138 137.824 209 138 136.5
-210 138 135.794 220 138 137.318 221 138 137.143
-154 139 136.543 171 139 137.679 172 139 137.75
-196 139 136.5 208 139 136.75 209 139 135.875
-210 139 136 211 139 136.429 119 140 136
-155 140 137.471 184 139.625 138 184.2 140 138
-203 140 135.158 207 140 136.5 209 140 136.5
-182.684 141 138 202 140.056 138 208 140.75 138
-103.563 142 138 105.9 142 138 130.735 142 138
-156 142 137.4 185.7 142 138 201 142 136.457
-202 142 135.794 157 143 137.857 201 143 137.032
-202 143 136.645 203 143 137.217 205 142.69 138
-207 142.286 138 170 144 136.154 183 143.182 138
-185 143.261 138 188 144 135.29 155 145 137.182
-170.056 145 138 161.667 146 138 170 146 136.5
-162 146.25 138 169 147 137.471 168.143 147 138
-33.8235 148 138 175 148 137.053 50 149 135.333
-51 149 136.105 112 149 135.794 153 149 135.2
-51 150 137 53 149.522 138 54 150 135.6
-54.5 150 138 113 150 137.438 114 149.37 138
-163 150 137.609 163 149.625 138 179 149.5 138
-56.7273 151 138 58 150.125 138 58 151 137.222
-58.5833 151 138 112 150.933 138 163 151 137.71
-164 151 137.7 164.273 151 138 58 151.368 138
-173 151.333 138 176 151.5 138 64 153 135.333
-210 153 135.176 65 154 135.333 95 153.067 138
-182 154 135.783 210 154 138 121.176 155 138
-181 155 137.5 181 154.375 138 182 155 136.853
-67 155.222 138 98.5667 156 138 164.6 156 138
-182 156 136 211 156 135.692 166 157 135.667
-167 157 137.032 57 158 136.875 56.8 158 138
-58 158 135.375 59 158 135.375 63 158 137.739
-71 158 136.8 92.7368 158 138 165 157.875 138
-165.222 158 138 168 158 137.824 193 158 136.765
-207 157.467 138 208 158 137.25 208 157.947 138
-208.25 158 138 57 158.75 138 58 158.875 138
-59 158.467 138 62 159 135.667 72 159 135.375
-77 159 136.5 81 158.44 138 86 159 137.118
-90 159 136.6 168 159 137.471 170 159 137.735
-192 159 137.4 208 159 135.857 209 158.75 138
-209 159 137.25 73 160 136.2 74 160 136.457
-76 160 137.9 77 159.6 138 168 160 136.929
-171.37 160 138 194 160 136.543 73 161 136.2
-76 160.143 138 84 161 136.543 86 161 136.355
-91 161 136.5 106 161 136.714 105.25 161 138
-106.375 161 138 172.067 161 138 194 161 136.8
-193.263 161 138 195 161 137.25 195.467 161 138
-199 161 138 91 161.286 138 91 162 136.636
-91.625 162 138 106 162 136.875 105.25 162 138
-106.375 162 138 167.588 162 138 195 162 137.55
-200 161.75 138 76.9231 163 138 78 163 135.652
-89 163 136.826 91 162.333 138 176.935 163 138
-187.278 163 138 194 163 136.263 195 163 137.25
-77.75 164 138 194 164 137.143 195 164 135.75
-78 164.25 138 87 164.429 138 90.4348 165 138
-98.5 165 138 119.294 165 138 168 165 135.947
-91 166 136.889 167 165.565 138 168 166 135.222
-90 167 137.735 98 167 137.053 97.25 167 138
-99 166.417 138 99 167 136.688 165.567 167 138
-169 167 135.833 171.857 167 138 87 168 137.1
-86.6667 168 138 89 168 136.8 90 168 137.323
-91 167.857 138 93 167.261 138 99 168 136.565
-100 167.813 138 100 168 137.182 174 167.091 138
-196 167.25 138 63 169 136.875 62.625 169 138
-63 168 138 87 169 136.25 88 169 136.688
-89 169 136.543 90.15 169 138 98.8696 169 138
-100 169 135.273 201 169 137.71 63 169.429 138
-86 170 135.115 88 170 136.645 89 170 137.032
-196 170 136.313 196 169.25 138 197 170 135.45
-201 170 137.667 202 170 137.609 202.188 170 138
-89 171 137.684 100 170.133 138 174 170.636 138
-175 171 137.842 175 170.75 138 197 171 135.778
-201 170.188 138 202 170.75 138 83 172 136.421
-82.4444 172 138 176 172 136.688 177 172 136.138
-178 172 135.48 179 172 135.875 198 172 135.882
-84 173 136 173 172.867 138 174 172.455 138
-175 173 137 178 173 135.45 179 173 136.375
-198 173 135.581 205 173 137.727 206 173 137.75
-80.625 174 138 82.75 174 138 84 173.526 138
-85.0667 174 138 81 174.375 138 85.85 175 138
-175.368 175 138 205 175 137.684 205 174.5 138
-169 176 137.8 168.818 176 138 199 176 135.667
-202.286 176 138 203 175.474 138 204 176 137.323
-205 176 136.412 206 175.417 138 169 177 136.895
-168 177 138 175.75 177 138 176 176.571 138
-177 176.364 138 177.467 177 138 198 177 136.4
-199 177 136.4 202 177 137.55 201.813 177 138
-205 177 136.2 206 177 136 169 177.875 138
-177.333 178 138 179 178 137.143 179.4 178 138
-198 178 136.556 199 178 136.444 201.667 178 138
-203 178 135.375 204 178 135.9 208.526 178 138
-177 179 136.125 177 178.375 138 178 179 137.333
-179 179 137.5 179.167 179 138 197 179 135.45
-201 179 137.333 178 180 137.5 179 180 135.75
-181 180 137.318 182 180 135.333 201.684 180 138
-208.077 180 138 172 180.8 138 181 181 137
-181.714 181 138 198 181 137 201.087 181 138
-209 180.923 138 172 182 136.263 178 182 135.375
-183 182 136.364 197 181.333 138 198 181.045 138
-200 181.727 138 172 183 135.273 173 182.071 138
-173 183 135.4 182 183 135.75 183 183 135.923
-191 183 137.4 190.667 183 138 191 182.8 138
-191.273 183 138 184 183.591 138 187 184 136.645
-188 183.818 138 188.5 184 138 191 183.6 138
-167 184.071 138 189 184.667 138 189 185 137.864
-72 185.75 138 85 186 137.125 85 185.364 138
-89 186 135.577 88.3 186 138 196 186 135.462
-195.313 186 138 72 187 136.25 73 187 136.696
-84 187 136.969 85 187 137.032 90 187 135.857
-90.3226 187 138 174 186.091 138 177.944 187 138
-190.455 187 138 195 187 136.5 196 187 135.577
-198 187 135.231 73 188 137 89 188 135.652
-90.3333 188 138 191 187.75 138 73 188.158 138
-88.8 190 138 90.1053 190 138 180 189.125 138
-182.091 190 138 74 190.842 138 179 190.913 138
-180 190.875 138 181 190.929 138 182 190.286 138
-86 192.045 138 86 69 140.571 87 69 139.5
-89 69 140.625 89.1333 69 141 86.5333 70 141
-89 70 138.857 97 69.2 141 63 71 140
-64 71 138.136 71 71 138.529 72 71 138.882
-79 71 138.12 80 71 138.143 86 71 138.24
-87 70.3684 141 87 71 139 88 71 139.429
-89 71 139.08 98 70.5 141 98 71 138.5
-99 71 138.3 99.6429 71 141 62 72 138.214
-65 72 138.909 73 72 139.355 81 72 138.24
-87 72 139.345 98 72 139 100 72 138.857
-60 73 139.8 61 73 138.833 63 73 138.2
-74 73 139.8 76 73 139.889 80 73 140.217
-81 73 139.556 86 73 139.3 87 73 139.556
-89 73 138.931 97 73 138.167 99 73 139
-102 73 138.96 58 74 139.5 59 74 138.6
-60 74 138.6 61 74 139 62 74 139.4
-63 74 140.1 77 74 139.645 78 74 139.889
-80 74 139.889 89 74 140.1 95 73.5417 141
-98 74 139.5 56 75 138.75 58 75 138.25
-59 75 138.667 60 75 139.75 64 74.6 141
-77 75 140.471 79 74.8333 141 83 75 139.889
-87 75 140.806 90 75 139.457 97 75 140.769
-98 75 140.318 99 75 140.684 203 75 140.6
-204 74.1111 141 52 76 139.125 54 76 138.545
-53.25 76 141 55 76 138.316 57 76 138.818
-59 76 139.962 84 76 139.8 85 76 139.8
-86 76 140.206 100 76 139.7 101 76 139.7
-53 76.375 141 53 77 139.636 87 77 140.471
-99 77 140.679 102 77 140.824 54 77.75 141
-96 78 139.8 99 78 140.032 100 78 140.206
-47.3846 79 141 213.737 80 141 217 80 138.103
-53 80.25 141 216 80.9091 141 207 82.9444 141
-48 84 140.471 219 84 139.2 218 84.75 141
-219 84.4 141 215 96 138.29 214 97 139.5
-212.5 98 141 213 97.6842 141 214 98 139.8
-211.778 99 141 212 98.5 141 213.737 100 141
-211.167 101 141 210 104 139 211 104 139.696
-42 105 138.667 210 104.5 141 211 105 140.8
-210.5 105 141 229 105.25 141 42 107 138.783
-210 107 139.091 210 108 140.526 209.25 108 141
-43 109 138.968 43 111 138.529 45 112 140.471
-201 114 140.76 201 115 139.44 202.8 115 141
-204 115 140.76 203.5 115 141 204.286 115 141
-199 116 138.469 202 116 139.143 203 115.5 141
-203 116 140.647 203.5 116 141 201 117 140.118
-202 117 139.846 203 116.167 141 200 118 140.76
-200.167 118 141 201 117.333 141 48 119 139.8
-198 119 138.818 199 119.818 141 200 119.333 141
-197 122 140.143 198 122 140.8 200 121.25 141
-50 123 139.457 198 123 139.645 199 123 138.261
-200 123 138 197 124 139.543 200 124 138.8
-50 125 139.579 53 125 139.8 99 124.833 141
-103 125 140.824 196 125 138.667 198 125 139.625
-199 125 139.35 200 124.55 141 218 125 139
-100 126 140.143 193 126 138.1 196 126 139.6
-199 125.407 141 218 126 138.818 46 127 140.609
-45 127 141 100 127 139.853 102 127 140.545
-216 127 138.333 217 127 138.231 53 128 139.313
-192 128 139.5 216 128 138.321 54 129 139.645
-57 129 139.457 58 129 139.8 96 129 139.2
-189 129 138.6 131 130 138.103 188 130 138.517
-191 130 139.421 204 130 138.45 205 130 138.75
-206 130 138.2 221 130 139.8 222 129.474 141
-222 130 139.333 55 131 138.529 56 131 139.2
-130 131 140.182 132 131 138.6 188 131 139.636
-204 131 138.571 215 131 138.321 221 131 139.091
-220.125 131 141 222 131 139.2 60 132 139.457
-87 132 139.457 186 132 140.8 187 131.565 141
-188 131.909 141 188.071 132 141 190.5 132 141
-197.3 132 141 203 132 139.75 63 133 139.8
-88 133 138.882 185.923 133 141 201 132.75 141
-202 132.167 141 71 135 139.457 182 134.591 141
-112.87 136 141 115 135.955 141 178 136 140.531
-178.625 136 141 184 136 139.607 215 135.75 141
-52 137 139.75 55 136.462 141 173 137 138.455
-182.556 137 141 184 137 139.125 185 137 138.9
-190.286 137 141 194.667 137 141 199 136.25 141
-216 136.667 141 217 137 138.783 216.056 137 141
-129.308 138 141 183 138 139.781 184 138 139.031
-185 138 139.781 186 138 140.7 193.091 138 141
-207 137.727 141 173 139 139.091 174 139 138.094
-175 139 138.5 179 139 138.115 184 139 138.714
-184.889 139 141 192 138.091 141 193 139 139.889
-194 139 138.667 213 138.867 141 212.75 139 141
-105 139.87 141 109 140 139.765 110 140 140.25
-176 139.828 141 179 140 138.652 180 140 139.636
-191 140 140.118 192 140 139.455 194 140 138.857
-196 140 138.103 197 140 139.44 210 140 141
-103.63 141 141 106 141 139.846 108 141 140.735
-107.25 141 141 109 141 139.6 110.875 141 141
-169 140.818 141 171 141 139.645 173 140.261 141
-180 141 139.778 181 141 140 184.273 141 141
-193 141 139.455 194 141 139.147 195 141 139.412
-196 141 138.9 197 141 139.444 198 141 139.696
-199 141 140.438 106.4 142 141 170 142 140.8
-182 142 139.038 192 141.5 141 198 142 140.4
-199 142 139.385 157 144 138.316 181.87 144 141
-183 144 139 184 144 140.053 184.316 144 141
-201 144 138.9 207.857 144 141 170 145 139.5
-201 145 138.947 202 145 140.571 127.548 146 141
-161 146 138.5 168 145.222 141 201 146 139.875
-161 147 138.75 162 147 138.529 168 147 138.158
-167.053 147 141 211 147 140.667 210.818 147 141
-211 146.714 141 114 148 140.444 125 147.481 141
-212 148 140.76 211.833 148 141 212 147.5 141
-213 147.625 141 213 148 140.182 177.667 149 141
-213 149 139.846 214 149 139.385 220 149 139.364
-219 149 141 220 148.143 141 53 150 139.138
-64 150 140.71 164.933 150 141 214 149.875 141
-57.25 151 141 58 150 141 59 151 141
-62 151 140.118 63 151 140.118 64 151 140.471
-162.333 151 141 173 150.955 141 178 151 140.9
-179 153 138.375 180 153 138.75 180 154 138.75
-181 154 138.29 92 155 140.419 167 155 140.625
-169 155 139.8 170 155 139.8 207 155 140.211
-208 155 139.962 210 155 138.529 67 156 140.864
-68 155.565 141 69 155.222 141 71.5556 156 141
-99.0303 156 141 164.867 156 141 167 156 138.316
-168 156 139.147 169 156 139.2 170.773 156 141
-208 156 140.806 209 156 139.235 65 157 139.5
-90 157 138.783 92 157 139.355 168 157 138.794
-170 157 139.543 187 157 140.8 187 156.818 141
-188 157 139.645 191 156.192 141 191 157 138.9
-195 156.684 141 197 156.848 141 57 158 138.474
-58 158 139.105 59 158 139.05 66 158 140.9
-91 158 139.2 92 158 139.355 176 157.391 141
-187 158 140.625 188 158 139.111 191 158 138.194
-209 158 138.375 84 158.263 141 92 159 138.529
-189 159 139.125 190 159 139.25 200 159 138.857
-92 160 138.577 102 160 140.667 102.6 160 141
-166.63 160 141 188 159.13 141 199 160 140.1
-199 159.7 141 219 160 140.4 220 160 139.875
-76 161 138.529 77 161 139.8 78.5 161 141
-93 161 138.167 103 161 139.895 104 160.813 141
-104 161 138.75 106 161 138.391 181 160.333 141
-200 161 138.333 219 160.75 141 82.75 162 141
-89 162 139.2 90 162 138.231 90 161.077 141
-104 161.75 141 106 162 138.391 172 162 140.318
-193 161.909 141 193.083 162 141 195 162 139.125
-77.8125 163 141 85.8125 163 141 90 163 138.2
-91 163 139.304 185.375 163 141 194 163 140.063
-77.4167 164 141 79 163.909 141 91 163.813 141
-185.4 164 141 194 164 138.273 195 164 138.529
-77 165 138.938 78 165 140.077 178 164.778 141
-195 165 138.529 76 166 139.895 77 166 139.174
-172 166 140.739 184 165.52 141 195 166 138.529
-64 167 140.294 63 167 141 64 166 141
-76 167 139.565 75.45 167 141 77 167 140.55
-97 166.8 141 171 166.231 141 172 167 138.316
-173 167 138.677 200.125 167 141 76 168 140.125
-99 168 140.75 99 167.875 141 173 168 138.321
-174 168 138.968 196 168 138.29 63 169 138.818
-75 169 140.25 74.6316 169 141 100 169 139.304
-174 169 139.313 195 169 139.571 202 169 138.455
-203 169 139.853 205 169 140.667 75 170 140.667
-75.2 170 141 85.32 170 141 174 170 138.75
-175 170 138.29 203 170 140.167 201 170.783 141
-202 171 138.273 202.833 171 141 83 172 140.727
-83.125 172 141 82 173 138.778 83 173 140.318
-84 173 139.579 87 172.545 141 173 173 141
-174 173 139.286 81 174 138.29 82 174 138.265
-87 174 139.8 169 175 140.526 204.714 175 141
-205 174.895 141 168.545 176 141 170 176 139.421
-174 175.467 141 176 177 138.375 177 177 138.75
-202 177 139.125 202.172 177 141 170 177.4 141
-180 178 138.391 208.091 178 141 180 179 139
-51.5667 180 141 180 180 138.231 203.261 180 141
-172.286 181 141 182 181 138.545 183 182 139.636
-185 182 139.929 186 182 140.667 198 181.182 141
-171 183 140.5 175 182.517 141 182 183 138.75
-185 183 140.217 186 183 139.6 191 183 138.6
-167.143 184 141 182 184 139.5 183 183.429 141
-189 184 138.75 189.429 184 141 71 185 139.35
-71 184.267 141 90.5667 185 141 180 184.333 141
-86 185.684 141 86 186 139.714 87 185.933 141
-87 186 140.833 88 186 139.227 74 187 138.667
-75 186.455 141 83 187 138.136 86 187 139.333
-87 187 139.696 106 186.433 141 169 187 140.167
-169 186.688 141 178.625 187 141 192 187 139.125
-74 188 138.857 78 187.895 141 81 188 139.543
-83 188 138.091 84 188 138.103 86 188 140.727
-87 188 139.889 169 188 139.655 168.409 188 141
-170 187.182 141 170.75 188 141 193 187.033 141
-74 189 140.647 75 189 139.5 84 189 139.846
-172.467 189 141 73.9091 190 141 76 190 139.364
-82 190 139.543 83 190 139.543 84 190 140.419
-89 189.75 141 89 190 139.8 180 190 140.1
-180.75 190 141 182 189.889 141 80 191 139.2
-83 191 139.543 84 191 140.032 85 191 140.727
-89 191 139.235 179 190.091 141 182 190.182 141
-84 192 138.794 88 192 139 90 192 139.2
-89 193.13 141 68 68.8529 144 67.5455 69 144
-69 68.6571 144 70 68.4857 144 71 68.4857 144
-72 68.4857 144 73 68.4857 144 74 68.3529 144
-75 68.3429 144 76 68.3529 144 77 68.5862 144
-78 68.7391 144 79 68.9444 144 79.1667 69 144
-83 69 144 91 69 144 92 69 144
-93 69 144 94 69 144 65 69.8235 144
-64.5 70 144 66 69.3529 144 67 69.2143 144
-80 69.1515 144 81 69.1818 144 82 69.1818 144
-84 69.2609 144 85 69.9444 144 85.0833 70 144
-89.2273 70 144 90 69.2609 144 95 69.2727 144
-96 70 144 63 70.8235 144 62.7391 71 144
-64 70.2069 144 86 70.4783 144 87 70.7857 144
-88 70.7391 144 89 70.2941 144 97 70.6 144
-98 71 141.882 97.25 71 144 99 71 143.7
-62 71.7727 144 61.7727 72 144 98 72 141.316
-97 72 144 99 72 141.882 100 71.9167 144
-99.9231 72 144 101 71.7391 144 101.353 72 144
-60 72.8235 144 59.5 73 144 61 72.5 144
-97.3158 73 144 99 73 141.545 99.6207 73 144
-102 72.3793 144 102.529 73 144 57.5 74 144
-58 73.8235 144 59 73.1765 144 73 74 141.783
-87 74 141.316 94.6471 74 144 95 73.6667 144
-95.5 74 144 98 73.7222 144 99 74 142.364
-98.4545 74 144 99.2609 74 144 103 73.7273 144
-103.182 74 144 56 75 144 57 74.2609 144
-67.3333 75 144 68 74.75 144 69 74.5455 144
-70 74.3182 144 71 74.2857 144 72 74.2857 144
-73 74.7727 144 73.4167 75 144 94.0833 75 144
-95.6471 75 144 99 74.4615 144 103.364 75 144
-204 74.3929 144 203.393 75 144 205 74.1765 144
-206 74.7857 144 206.261 75 144 54 76 144
-55 75.4074 144 63.0909 76 144 64 75.6429 144
-65 75.4444 144 66 75.3182 144 67 75.1176 144
-74 75.25 144 75 75.697 144 76 75.8485 144
-76.4545 76 144 80 76 141.818 94 76 141.25
-95 75.4074 144 103.364 76 144 203.324 76 144
-207 75.5 144 207.739 76 144 50.7059 77 144
-51 76.8529 144 52 77 144 53.0833 77 144
-61 77 143.833 61.2 77 144 62 76.75 144
-63 76.0588 144 77 76.1765 144 78 76.2222 144
-79 76.5238 144 79.9091 77 144 103.036 77 144
-203.647 77 144 208 76.2069 144 209 76.8148 144
-209.227 77 144 49 78 144 50 77.4286 144
-53 77.0909 144 60.0909 78 144 61 77.0909 144
-80 77.0455 144 81 77.375 144 82 77.75 144
-82.3636 78 144 84 78 142.364 102.429 78 144
-103 77.0588 144 204 77.5217 144 204.324 78 144
-210 77.6071 144 210.688 78 144 48 78.8214 144
-47.8148 79 144 58.0909 79 144 59 78.5455 144
-60 78.0455 144 83 78.3182 144 84 78.4444 144
-85 78.4444 144 86 78.5455 144 86.9091 79 144
-89 79 141.75 101.389 79 144 102 78.5217 144
-204.647 79 144 211 78.1515 144 212 78.5 144
-212.739 79 144 47.4783 80 144 55 80 144
-56 79.7059 144 57 79.75 144 58 79.0588 144
-87 79.0455 144 88 79.4444 144 89 79.5455 144
-90 79.6429 144 91 79.8182 144 91.6667 80 144
-100.059 80 144 101 79.3043 144 205 79.7059 144
-205.147 80 144 213 79.1765 144 214 79.697 144
-214.455 80 144 46 81 144 47 80.5 144
-53 81 141.75 54.5833 81 144 92 80.1176 144
-93 80.1176 144 94 80.4118 144 95 80.75 144
-96 80.75 144 97 80.6 144 98 80.375 144
-99 80.4118 144 100 80.0455 144 205.5 81 144
-215 80.3529 144 216 80.697 144 216.455 81 144
-45 81.6071 144 44.6667 82 144 52 82 143.833
-52.0909 82 144 53 81.6429 144 54 81.3182 144
-205.971 82 144 217 81.5217 144 217.478 82 144
-44 83 144 51.0588 83 144 52 82.0588 144
-206 82.0435 144 206.647 83 144 218 82.9231 144
-218.056 83 144 43.3529 84 144 49.7059 84 144
-50 83.7826 144 51 83.0455 144 207 83.6667 144
-207.176 84 144 218 84 142 219 83.7391 144
-219.273 84 144 43 84.6667 144 42.7857 85 144
-48.6207 85 144 49 84.5217 144 207.647 85 144
-220 84.5926 144 220.478 85 144 42 86 144
-48.0357 86 144 207.824 86 144 221 85.6667 144
-221.176 86 144 41.2143 87 144 47.5294 87 144
-48 86.0588 144 207.971 87 144 221.824 87 144
-41 87.2727 144 40.5152 88 144 47.0357 88 144
-208 87.1667 144 208.179 88 144 222 87.5 144
-222.176 88 144 40 89 144 46.697 89 144
-47 88.0909 144 208.353 89 144 222.667 89 144
-39.5152 90 144 46.3636 90 144 208 90 144
-218 90 143.824 217.909 90 144 218 89.9412 144
-218.036 90 144 223 89.6471 144 223.261 90 144
-39 91 144 46.0357 91 144 207.586 91 144
-218 91 143.833 217.909 91 144 218.045 91 144
-223.793 91 144 38.5152 92 144 45.697 92 144
-46 91.0909 144 207.486 92 144 218 91.0625 144
-224 91.5 144 224.176 92 144 38.1765 93 144
-45.5455 93 144 207.343 93 144 224.485 93 144
-38 93.5 144 37.8235 94 144 45.3636 94 144
-207.176 94 144 224.824 94 144 37.5152 95 144
-45.0357 95 144 207 95 144 225 94.5 144
-225.176 95 144 37.1765 96 144 44.8529 96 144
-45 95.1667 144 206.824 96 144 225.485 96 144
-37 96.5 144 36.8235 97 144 44.6765 97 144
-206.515 97 144 225.824 97 144 36.6571 98 144
-44.6765 98 144 206.176 98 144 226 97.5 144
-226.176 98 144 36.3429 99 144 44.5143 99 144
-206 99 144 211.793 99 144 212 98.4545 144
-213 98.4 144 213.462 99 144 226.485 99 144
-36.1765 100 144 44.5 100 144 205.824 100 144
-211.75 100 144 213.333 100 144 226.824 100 144
-36 100.5 144 35.8235 101 144 44.3529 101 144
-205.821 101 144 211.522 101 144 213 101 144
-227 100.353 144 227.324 101 144 35.5152 102 144
-44.3636 102 144 205.393 102 144 210.667 102 144
-211 101.522 144 213.179 102 144 227.647 102 144
-35.1765 103 144 43 103 141.682 44 103 142.364
-44.3636 103 144 205.214 103 144 210.353 103 144
-213.185 103 144 228 103 144 35 103.5 144
-34.8235 104 144 44.5455 104 144 205 103.353 144
-204.676 104 144 210 104 141.462 210.379 104 144
-212.706 104 144 213 103.5 144 228 104 144
-34.5152 105 144 44.697 105 144 204.353 105 144
-210.478 105 144 212.538 105 144 228.324 105 144
-34.1765 106 144 44.8529 106 144 204 106 144
-209.944 106 144 210 105.917 144 213 105.5 144
-213.261 106 144 221 106 143.7 220 106 144
-221 105 144 221.091 106 144 228.647 106 144
-34 106.545 144 33.8529 107 144 45 106.833 144
-45.0294 107 144 203.676 107 144 209 107 144
-212 107 141.545 213 107 142.2 213.522 107 144
-219 107 143 218.739 107 144 219 106.647 144
-220 107 143 220.333 107 144 221 106.077 144
-229 107 144 33.5152 108 144 45.0294 108 144
-203.353 108 144 208.708 108 144 212 108 144
-213 107.667 144 219 108 142.2 218.333 108 144
-220 108 143.118 220.179 108 144 229.324 108 144
-33.1818 109 144 45.1818 109 144 203 108.706 144
-202.853 109 144 209 109 142.8 208.5 109 144
-210 108.923 144 209.857 109 144 211 108.179 144
-218 109 142.95 217.759 109 144 218 108.462 144
-219 109 142.2 219.667 109 144 220 108.455 144
-229.647 109 144 33 110 144 45.5294 110 144
-202.697 110 144 209 110 143.824 208 110 144
-209.053 110 144 218 110 143.824 217.941 110 144
-218.167 110 144 219 109.706 144 230 110 144
-32.8235 111 144 45.8529 111 144 202.429 111 144
-209 110.2 144 218 110.2 144 230 111 144
-32.6571 112 144 46 111.455 144 46.1818 112 144
-202.045 112 144 230.176 112 144 32.4857 113 144
-46.5294 113 144 202 112.059 144 201.429 113 144
-230.485 113 144 32.4857 114 144 47 113.941 144
-47.0357 114 144 201.045 114 144 208 114 143.842
-207.8 114 144 208 113.8 144 209 113.8 144
-209 114 143.842 210 113.417 144 210 114 142.95
-211 113.588 144 211 114 142.95 211.583 114 144
-230.824 114 144 32.4857 115 144 47.5294 115 144
-202 115 144 203.417 115 144 204 114.696 144
-205 114.588 144 205 115 142.25 206 114.417 144
-207 114.8 144 207 115 143.727 207.2 115 144
-208 114.2 144 209 114.091 144 210 114.412 144
-211 114.304 144 231 115 144 32.4857 116 144
-48 115.941 144 48.0357 116 144 201 115.6 144
-200.636 116 144 201.8 116 144 203 116 142
-202.2 116 144 203.8 116 144 204.2 116 144
-205 115.636 144 205.8 116 144 206.2 116 144
-207 115.2 144 231 116 144 32.4857 117 144
-48.5294 117 144 200.083 117 144 202 116.077 144
-204 116.043 144 206 116.063 144 231 117 144
-32.4857 118 144 49 117.727 144 49.2143 118 144
-200 117.2 144 199.818 118 144 231 118 144
-32.4857 119 144 49.8214 119 144 199.583 119 144
-231 119 144 32.4857 120 144 50 119.217 144
-50.6207 120 144 99 119.833 144 98.6667 120 144
-100 119.833 144 101 120 143.684 101 119.882 144
-101.167 120 144 199 119.636 144 198.818 120 144
-230.824 120 144 32.4857 121 144 51 120.478 144
-51.5217 121 144 97 121 143.684 97 120.833 144
-96.8333 121 144 98 121 143.684 98 120.667 144
-101.167 121 144 198 121 141.3 199 120.8 144
-199.083 121 144 230.657 121 144 32.4857 122 144
-44 122 141.938 43 122 144 44 121.353 144
-45 121.773 144 45.1786 122 144 52 121.478 144
-52.5217 122 144 97 122 143.684 96.6667 122 144
-100 122 143.684 101 122 143.684 101.333 122 144
-199.647 122 144 230.514 122 144 32.4857 123 144
-43.9565 123 144 45 123 142.263 45.5 123 144
-53 122.478 144 53.5217 123 144 96 122.667 144
-95.6667 123 144 98 123 143.684 100 123 143.684
-101 123 143 102 122.8 144 102.083 123 144
-200 122.5 144 200.353 123 144 230.343 123 144
-32.4857 124 144 44 123.056 144 45 124 143.824
-44.9444 124 144 45.2 124 144 54 123.478 144
-54.7059 124 144 95 124 143.684 95 123.667 144
-94.6667 124 144 96 124 143.684 97 124 143.684
-101 124 141.346 102 124 141.24 103 123.393 144
-103 124 141.783 104 123.966 144 104.059 124 144
-200.273 124 144 230.176 124 144 32.4857 125 144
-45 125 144 46 124.4 144 46.5455 125 144
-55 124.217 144 56 124.955 144 56.0588 125 144
-95 125 143.684 94.6667 125 144 96 125 143.684
-97 125 143 102 125 141.24 104 125 141.75
-105 124.727 144 105.222 125 144 200 124.353 144
-199.607 125 144 230 125 144 32.3429 126 144
-44.5 126 144 46 126 142.286 47 125.417 144
-47.6364 126 144 57 125.941 144 57.0588 126 144
-92 125.833 144 91.6667 126 144 93 125.667 144
-94 125.364 144 102 126 141.75 103 126 141.346
-105 126 141.75 105.643 126 144 197.455 126 144
-198 125.824 144 199 125.5 144 230 126 144
-32.3235 127 144 44.0556 127 144 48 126.8 144
-48.2 127 144 58 126.696 144 58.3889 127 144
-89 127 143.684 89 126.882 144 88.6667 127 144
-90 126.833 144 91 126.667 144 105.821 127 144
-195 126.824 144 194.647 127 144 196 126.485 144
-197 126.152 144 230 127 144 32.3429 128 144
-45 127.773 144 45.8333 128 144 46.1667 128 144
-47 127.706 144 48 127.059 144 59 127.478 144
-59.7059 128 144 88 128 143.684 88 127.667 144
-87.6667 128 144 89 128 143.684 90 128 143
-106 128 144 193.571 128 144 194 127.478 144
-230 128 144 32.4857 129 144 46 128.034 144
-60 129 141.75 60 128.217 144 61 128.955 144
-61.0909 129 144 85 129 143.684 85 128.882 144
-84.6667 129 144 86 128.833 144 87 128.667 144
-89 129 142.364 106.147 129 144 192 129 141.13
-193.227 129 144 230.147 129 144 32.4857 130 144
-62 129.588 144 62.6364 130 144 84 129.667 144
-83.6667 130 144 85 130 143 106.571 130 144
-192 130 142.286 193 130 143.053 193.545 130 144
-220.706 130 144 221 129.815 144 222 129.625 144
-222.353 130 144 230.303 130 144 32.4857 131 144
-63 130.25 144 64 130.588 144 65 130.882 144
-65.3333 131 144 81 130.882 144 80.6667 131 144
-82 130.833 144 83 130.364 144 106.727 131 144
-192 131 143.833 193 131 143.833 194 130.833 144
-194 131 143.824 195 130.917 144 195 131 143.833
-195.091 131 144 197.417 131 144 198 130.759 144
-199 130.708 144 199.412 131 144 220 131 141.25
-219 131 144 220 130.522 144 222 130.545 144
-221.545 131 144 230.303 131 144 32.4857 132 144
-66 131.25 144 67 131.588 144 67.6364 132 144
-75 131.882 144 74.6667 132 144 76 131.882 144
-77 131.882 144 78 131.682 144 79 131.588 144
-80 131.25 144 107 131.375 144 107.357 132 144
-129.167 132 144 130 131.821 144 131 132 142
-130.294 132 144 187 132 144 188 131.739 144
-188.545 132 144 193 132 143.842 194.2 132 144
-195 131.2 144 196.667 132 144 197 131.5 144
-200 131.476 144 200.393 132 144 218 132 142.263
-217.607 132 144 218 131.607 144 219 132 141
-220 132 141.176 221 131.5 144 220.727 132 144
-230.303 132 144 32.6571 133 144 68 132.182 144
-69 132.357 144 70 132.455 144 71 132.455 144
-72 133 141.75 72 132.455 144 73 132.357 144
-74 132.182 144 107.739 133 144 127 133 144
-128 132.5 144 129 132.034 144 130.778 133 144
-186 132.706 144 185.815 133 144 188.739 133 144
-192.2 133 144 193 132.2 144 194 132.091 144
-197 132.455 144 197.214 133 144 201 133 142
-200.739 133 144 202 133 142.364 203 133 141.24
-217 133 142.2 216.586 133 144 217 132.586 144
-218 133 141.571 219 133 143.118 219.294 133 144
-220 132.571 144 230.485 133 144 32.8235 134 144
-108 133.261 144 108.586 134 144 126 133.667 144
-125.353 134 144 130.824 134 144 185.593 134 144
-188 134 142 188.414 134 144 192.059 134 144
-197.176 134 144 201 133.375 144 201.588 134 144
-202 134 142.5 216 134 143.786 215.964 134 144
-216 133.944 144 217 134 141.652 218 134 143
-218.261 134 144 219 133.227 144 230.818 134 144
-33 135 144 108.957 135 144 123 135 144
-124 134.657 144 125 134.176 144 130.657 135 144
-180 135 142 181 135 142.364 186 134.733 144
-186.8 135 144 187.083 135 144 188 134.522 144
-192 135 144 196.667 135 144 197 134.353 144
-201.455 135 144 216 135 141.667 215.588 135 144
-217 135 142.25 217.304 135 144 218 134.273 144
-230.824 135 144 33 136 144 109 135.083 144
-110 135.353 144 111 135.227 144 112 135.478 144
-112.364 136 144 115.294 136 144 116 135.571 144
-117 135.667 144 118 135.971 144 119 135.824 144
-120 135.966 144 121 135.793 144 122 135.586 144
-129.875 136 144 130 135.852 144 180 136 143.727
-181 136 143.8 182 136 143.842 187 135.034 144
-191.455 136 144 195.815 136 144 196 135.815 144
-200.773 136 144 201 135.667 144 216 135.412 144
-217 135.25 144 230.657 136 144 33 137 144
-53 137 141.429 54.0833 137 144 55 136.621 144
-56 136.514 144 57 136.233 144 58 136.393 144
-59 136.739 144 59.375 137 144 113 136.656 144
-114 136.815 144 115 136.227 144 129.185 137 144
-181 137 143.8 182 137 142.765 190 136.733 144
-189.75 137 144 191 136.5 144 194.545 137 144
-195 136.815 144 200 137 143.167 200.227 137 144
-212 137 143.1 213 137 143.211 213.833 137 144
-214 136.917 144 214.091 137 144 215 137 142.421
-216 137 141.176 230.514 137 144 33 138 144
-54.0588 138 144 59 138 141.652 60 137.909 144
-60.0909 138 144 128.821 138 144 129 137.5 144
-180.636 138 144 181 137.2 144 181.364 138 144
-189 138 143.571 190 138 143.571 190 137.8 144
-191 138 141.75 191 137.455 144 192 137.353 144
-193 137.273 144 194 137.214 144 199 137.545 144
-198.545 138 144 200 137.185 144 205.5 138 144
-206 137.824 144 207 137.233 144 208 137.261 144
-209 137.412 144 209.833 138 144 210 138 143.684
-211 138 143.684 211.286 138 144 212 137.545 144
-212.5 138 144 213 138 143.167 214 137.083 144
-214 138 141.938 230.343 138 144 33 139 144
-55 138.727 144 55.5455 139 144 58.5455 139 144
-59 138.783 144 60 138.059 144 129 138.5 144
-129.179 139 144 180.688 139 144 181.833 139 144
-185 138.783 144 184.545 139 144 186 138.621 144
-187 138.5 144 188 138.214 144 189 138.091 144
-190 139 142.286 189.455 139 144 198.059 139 144
-203.739 139 144 204 138.824 144 205 138.176 144
-209.588 139 144 211 139 142.364 212 138.217 144
-212 139 141.75 230.176 139 144 33.3529 140 144
-56 139.152 144 57 139.176 144 58 139.176 144
-73 140 143.813 72.8571 140 144 73 139.941 144
-73.0833 140 144 104 140 144 105 139.227 144
-106 139.571 144 107 139.786 144 108 139.5 144
-109 139.214 144 110 139.353 144 110.478 140 144
-129.647 140 144 161 140 141.24 168 140 142.385
-177 140 144 181 139.313 144 181 140 141.938
-184 139.353 144 183.353 140 144 189.552 140 144
-198.706 140 144 202.393 140 144 203 139.5 144
-209.25 140 144 230 140 144 33.6765 141 144
-73 140.167 144 103.676 141 144 107 141 141.12
-110.739 141 144 129.818 141 144 165 141 143
-173 140.515 144 172.407 141 144 174 140.353 144
-175 140.353 144 176 140.176 144 178 140.313 144
-178.667 141 144 183.217 141 144 190 140.722 144
-190.833 141 144 199 140.294 144 200 141 144
-201 141 144 202 140.333 144 209 140.667 144
-208.882 141 144 230 141 144 34 142 144
-104 141.688 144 104.227 142 144 107 142 142.8
-108 142 144 109.545 142 144 110 141.773 144
-130 142 144 160.818 142 144 161 141.75 144
-162 141.059 144 163 141.304 144 164 141.412 144
-165 141.412 144 166 141.2 144 167 141.091 144
-168 141.091 144 168.909 142 144 171.75 142 144
-172 141.647 144 179 141.5 144 179.393 142 144
-183.964 142 144 191 141.036 144 192 141.773 144
-192.417 142 144 208.455 142 144 230 142 144
-34 143 144 105 142.607 144 106 142.353 144
-107 142.182 144 109 142.176 144 129.571 143 144
-160.304 143 144 169 142.091 144 169.625 143 144
-171.059 143 144 180 142.607 144 180.333 143 144
-184 142.077 144 184.522 143 144 193 142.412 144
-193.625 143 144 195 143 141.3 198 143 144
-208.179 143 144 230 143 144 34 144 144
-128.941 144 144 129 143.941 144 159.818 144 144
-160 143.636 144 170 143.353 144 171 143.091 144
-181 143.815 144 181.179 144 144 184.607 144 144
-194 143.222 144 195 143.643 144 196 143.515 144
-197 143.152 144 199 143.75 144 199.182 144 144
-204 143.848 144 203.545 144 144 205 143.852 144
-205.364 144 144 208 143.455 144 207.5 144 144
-229.824 144 144 34 145 144 127.727 145 144
-128 144.727 144 159 145 143 159.636 145 144
-166 145 144 167 144.727 144 168 144.571 144
-169 144.778 144 170 144.688 144 171 144.625 144
-172 144.588 144 172.304 145 144 182 145 144
-183.75 145 144 184 144.81 144 199.696 145 144
-202 145 144 203 144.261 144 206 144.292 144
-207 144.261 144 229.485 145 144 34 146 144
-64 146 143.824 63.5 146 144 64 145.833 144
-64.1429 146 144 127.5 146 144 160 145.8 144
-160 146 143.727 160.059 146 144 167 146 144
-173 146 144 183 145.5 144 200 145.636 144
-200.8 146 144 201.056 146 144 229.176 146 144
-34.3529 147 144 64 146.2 144 126.375 147 144
-127 146.63 144 158.091 147 144 159 146.091 144
-160 146.091 144 167.222 147 144 173.571 147 144
-201 146.059 144 211 147 141.857 229 147 144
-34.6765 148 144 63.8571 148 144 64 147.8 144
-64.1667 148 144 110 148 144 111 147.824 144
-112 147.848 144 112.455 148 144 124 148 144
-125 147.207 144 126 147.176 144 157.304 148 144
-158 147.059 144 168 147.778 144 168.214 148 144
-174 147.706 144 174.217 148 144 212 147.833 144
-211.909 148 144 213 147.333 144 214 147.657 144
-215 148 144 229 148 144 35 149 144
-64 149 141.682 63 149 144 65 148.455 144
-65.2609 149 144 108.227 149 144 109 148.5 144
-113 148.353 144 113.393 149 144 123.676 149 144
-156.5 149 144 157 148.389 144 169 149 144
-175 149 143 174.588 149 144 211.955 149 144
-216 149 144 220 149 144 228.824 149 144
-35.1765 150 144 59.1667 150 144 60 149.821 144
-61 149.667 144 62 149.5 144 65.7222 150 144
-108 150 141.652 107.357 150 144 108 149.217 144
-113 150 144 123.214 150 144 155.607 150 144
-156 149.5 144 163 150 144 164 149.414 144
-165 149.955 144 165.056 150 144 170 149.848 144
-170.185 150 144 175 150 143.625 174.667 150 144
-177 150 143.684 178 150 141.429 212 149.059 144
-212.941 150 144 215 150 144 228.485 150 144
-35.3429 151 144 58 151 141.6 59.0455 151 144
-66 150.833 144 66.0909 151 144 106.955 151 144
-107 150.909 144 112 150.667 144 111.353 151 144
-122.185 151 144 123 150.214 144 155 151 144
-162.214 151 144 165.214 151 144 171 151 144
-173.714 151 144 174 150.667 144 177 151 141.429
-213 150.036 144 214 150.364 144 228.176 151 144
-35.6571 152 144 60 152 144 62 152 141.682
-66 152 143.842 67 151.909 144 67 152 143.833
-67.2 152 144 94.2174 152 144 95 151.182 144
-96 151.217 144 97 151.696 144 98 151.941 144
-98 152 143.842 99 151.941 144 99 152 143.842
-99.2 152 144 107 151.091 144 108 151.706 144
-109 151.773 144 110 151.586 144 111 151.176 144
-121.571 152 144 122 151.294 144 154.657 152 144
-162.786 152 144 165 152 144 172 151.294 144
-173 151.294 144 187 152 143.769 186.909 152 144
-187 151.833 144 187.083 152 144 227.824 152 144
-228 151.5 144 36 153 144 61 152.343 144
-62 152.486 144 63 152.486 144 64 152.414 144
-65 152.304 144 66 152.059 144 67 152.2 144
-68 153 143.667 67.6667 153 144 68 152.667 144
-68.1667 153 144 73 153 143.769 72.9655 153 144
-73 152.857 144 74 152.417 144 74 153 142.6
-74.3043 153 144 93.1852 153 144 94 152.185 144
-99 153 143.842 99.2 153 144 121.179 153 144
-154.343 153 144 163 152.261 144 164 152.773 144
-168.625 153 144 169 152.778 144 170 152.571 144
-170 153 142.286 170.706 153 144 187 152.056 144
-227.485 153 144 36.3429 154 144 68 153.167 144
-73 154 143.833 72.9412 154 144 74 154 143.824
-74.0435 154 144 92 154 144 93 153.185 144
-99.4118 154 144 121.485 154 144 154.176 154 144
-164 154 143.824 163.944 154 144 164 153.833 144
-165 153.588 144 165 154 142.95 166 153.964 144
-167 153.786 144 168 153.357 144 171 153.417 144
-171.368 154 144 227.176 154 144 36.6571 155 144
-68.4545 155 144 69 154.625 144 70 154.778 144
-71 155 144 72 155 143.833 72 154.941 144
-72.2 155 144 73 154.2 144 74 154.059 144
-89.2 155 144 90 154.879 144 91 154.667 144
-99.25 155 144 121.029 155 144 154 154.5 144
-153.824 155 144 164 154.2 144 164.8 155 144
-166 155 141.429 171.586 155 144 203 155 141.571
-202 155 144 203 154.5 144 204 154.586 144
-204.923 155 144 226.647 155 144 227 154.333 144
-37 156 144 67.4783 156 144 68 155.294 144
-72.5652 156 144 87.5217 156 144 88 155.522 144
-89 155.043 144 99 156 144 120.824 156 144
-121 155.143 144 153.515 156 144 165 156 144
-171.486 156 144 185.955 156 144 186 155.938 144
-187 155.478 144 188 155.393 144 189 155 144
-190 155 144 191 155.393 144 191.773 156 144
-198.759 156 144 199 155.696 144 200 155.179 144
-201 155.176 144 205 155.091 144 206 156 143.625
-205.833 156 144 226.324 156 144 37.5152 157 144
-66.8214 157 144 67 156.688 144 72.1765 157 144
-86 157 144 87 156.522 144 98.3529 157 144
-120.514 157 144 153 157 144 165.485 157 144
-171.486 157 144 186 157 142.364 185.571 157 144
-192 156.185 144 193 156.545 144 193.833 157 144
-195 157 144 197.667 157 144 198 156.786 144
-205 156.909 144 204.917 157 144 225.824 157 144
-226 156.647 144 37.8235 158 144 67 157.294 144
-68 158 144 71.2143 158 144 72 157.214 144
-83.9412 158 144 84 157.957 144 85 157.727 144
-98 157.522 144 97.6071 158 144 120.176 158 144
-152.515 158 144 165.5 158 144 171.657 158 144
-174.5 158 144 175 157.333 144 176 157.414 144
-177 157.786 144 177.6 158 144 185.818 158 144
-194 157.091 144 196 157.353 144 197 157.414 144
-203.455 158 144 204 157.647 144 225.485 158 144
-38 158.5 144 38.1765 159 144 69 158.5 144
-70 158.657 144 71 158.207 144 83 159 144
-97.1818 159 144 101.917 159 144 102 158.955 144
-102.091 159 144 119.824 159 144 120 158.5 144
-152.176 159 144 165.853 159 144 171.5 159 144
-174.5 159 144 178 158.235 144 178.722 159 144
-186 158.273 144 186.696 159 144 200.091 159 144
-201 158.697 144 202 158.364 144 203 158.185 144
-225 159 144 38.5152 160 144 82 160 143
-82.6364 160 144 97 159.8 144 96.9412 160 144
-100.294 160 144 101 159.478 144 103 159.476 144
-103.478 160 144 119.514 160 144 152 159.353 144
-151.676 160 144 166 159.556 144 166.19 160 144
-171.393 160 144 174.966 160 144 179 159.238 144
-179.727 160 144 187 159.241 144 188 159.829 144
-188.5 160 144 195 159.588 144 194.364 160 144
-196 159.786 144 197 159.676 144 198 159.657 144
-199 159.353 144 200 159.034 144 217.647 160 144
-218 159.739 144 219 159 144 220 159.588 144
-220.304 160 144 224.485 160 144 39 161 144
-79 161 141.75 80 161 143 81 161 143.684
-83 160.667 144 83 161 143.684 84 160.667 144
-84.3333 161 144 90 161 144 91 160.824 144
-91.375 161 144 96.9545 161 144 99.5882 161 144
-100 160.417 144 101 161 141.12 104 161 144
-119.514 161 144 151.353 161 144 167 160.944 144
-167.059 161 144 171 160.917 144 170.941 161 144
-175 160.059 144 175.571 161 144 180 160.353 144
-180.917 161 144 181.2 161 144 182 160.81 144
-182.444 161 144 189 160.207 144 190 160.176 144
-191 160.607 144 192 161 144 195 161 142
-194.25 161 144 217 161 143.824 216.909 161 144
-217 160.917 144 218 161 142.714 219 161 141.25
-220 161 144 224 161 144 39.5152 162 144
-79 162 143 80 162 143 81 162 142.364
-85 161.25 144 86 161.941 144 86.0909 162 144
-89 161.586 144 88.2941 162 144 92 161.455 144
-92.3529 162 144 96.7778 162 144 100 161.304 144
-101 161.828 144 102 162 144 103 162 144
-119.514 162 144 151 161.522 144 150.676 162 144
-168 161.727 144 168.6 162 144 171 162 143.684
-170.667 162 144 176 162 144 181 161.045 144
-183 161.313 144 183.917 162 144 193 162 144
-194 162 143.75 194 161.8 144 216 162 143
-215.588 162 144 216 161.588 144 217 162 143.053
-218 162 144 219 161.478 144 223.485 162 144
-39.8235 163 144 78 163 141.6 79 163 142.765
-87 162.588 144 88 162.179 144 92.0345 163 144
-96.9643 163 144 119.514 163 144 150.353 163 144
-168.375 163 144 171 162.286 144 171.217 163 144
-176.485 163 144 184 162.059 144 184.727 163 144
-216 162.412 144 217 162.273 144 223 163 144
-40 163.5 144 40.1765 164 144 77.1667 164 144
-78 163.706 144 78.4545 164 144 91.1852 164 144
-92 163.043 144 97 163.045 144 97.6364 164 144
-119.514 164 144 150 163.667 144 149.824 164 144
-168.043 164 144 171.414 164 144 176.966 164 144
-185 163.5 144 185.375 164 144 222.393 164 144
-40.5152 165 144 64.6471 165 144 65 164.818 144
-66 164.75 144 67 164.909 144 67 165 143.833
-67.0588 165 144 76 165 144 77 164.043 144
-78.3929 165 144 90 165 144 91 164.185 144
-98 164.522 144 98.4783 165 144 119.514 165 144
-149.793 165 144 160 165 143.824 159.917 165 144
-160 164.917 144 161 164.941 144 161 165 143.833
-161.091 165 144 167.515 165 144 168 164.059 144
-171.4 165 144 177 164.059 144 177.727 165 144
-181 164.966 144 180.917 165 144 182 164.966 144
-182.083 165 144 185.478 165 144 199 165 143.842
-198.8 165 144 199 164.8 144 199.091 165 144
-210.966 165 144 211 164.941 144 212 164.909 144
-212 165 143.4 212.077 165 144 221.5 165 144
-222 164.5 144 41 166 144 63.4138 166 144
-64 165.393 144 65 166 141 66.5455 166 144
-67 165.091 144 75.5 166 144 78.1515 166 144
-89.1923 166 144 99 166 141.857 98.7059 166 144
-119.514 166 144 149.739 166 144 160 165.059 144
-161 165.091 144 166.522 166 144 167 165.607 144
-171 165.706 144 170.848 166 144 178 165.214 144
-179 165.176 144 180 165.324 144 183 165.333 144
-183.957 166 144 184.167 166 144 185 165.688 144
-199 166 143.833 198.941 166 144 200 165.588 144
-200 166 142.95 201 166 144 211 166 141.5
-210.773 166 144 212 166 144 221.179 166 144
-41.5152 167 144 63.0556 167 144 65 167 142.263
-65.6875 167 144 66 166.706 144 75.0345 167 144
-78 166.227 144 77.5 167 144 88 167 144
-89 166.227 144 96 166.667 144 95.5 167 144
-97 166.586 144 98 167 143.571 98 166.923 144
-99 167 142.615 119.514 167 144 149.739 167 144
-165.593 167 144 166 166.522 144 170.152 167 144
-184 166.056 144 199 166.167 144 199.217 167 144
-202 166.343 144 203 166.676 144 203.647 167 144
-211 166.455 144 220.824 167 144 221 166.455 144
-42 168 144 63 168 142 64 167.739 144
-65 167.324 144 74.5 168 144 75 167.056 144
-77 167.944 144 76.9655 168 144 87.2143 168 144
-91 168 143.571 91 167.957 144 90.9412 168 144
-92 167.818 144 93 167.966 144 93.1667 168 144
-94.2941 168 144 95 167.478 144 119.353 168 144
-149.786 168 144 165.034 168 144 170 167.455 144
-169.824 168 144 199.5 168 144 204 167.261 144
-205 167.621 144 206 167.739 144 207 167.455 144
-207 168 142.8 207.353 168 144 220.485 168 144
-42.6667 169 144 73.8485 169 144 74 168.773 144
-76.6471 169 144 86.7391 169 144 87 168.5 144
-90 168.727 144 89.7273 169 144 94 168.185 144
-119.029 169 144 149.971 169 144 164.545 169 144
-165 168.091 144 170 169 144 200 168.944 144
-200.029 169 144 204 169 141.125 206.944 169 144
-207 168.857 144 220 169 144 43 169.647 144
-43.1765 170 144 74 170 142.263 73.6071 170 144
-76.2333 170 144 85.8519 170 144 86 169.81 144
-89 169.941 144 88.9412 170 144 118.5 170 144
-119 169.056 144 150 169.083 144 150.324 170 144
-165 170 141.5 164.583 170 144 170.773 170 144
-200.414 170 144 205 170 141.682 206.333 170 144
-219.333 170 144 43.8235 171 144 74 171 143.118
-73.7059 171 144 75 171 143.167 75.2381 171 144
-76 170.304 144 85 171 142.105 85.75 171 144
-87 171 144 88 170.727 144 118.176 171 144
-150.647 171 144 165 170.417 144 166 170.478 144
-167 171 144 170 171 141.167 171 170.455 144
-171 171 143 171.273 171 144 201 171 144
-203 170.688 144 202.688 171 144 204 170.304 144
-205 170.515 144 206 170.353 144 218.647 171 144
-219 170.478 144 44 171.261 144 44.5 172 144
-74 171.294 144 75 171.185 144 84 172 141.875
-85 172 141.75 86 171.25 144 86 172 142.364
-117.853 172 144 118 171.545 144 150.824 172 144
-168 171.607 144 168.478 172 144 171 172 144
-202 171.647 144 218 172 144 45 172.586 144
-45.3529 173 144 117.5 173 144 151 172.353 144
-151.324 173 144 169 173 143.833 168.917 173 144
-169.167 173 144 170 172.545 144 217.333 173 144
-46 174 144 117.029 174 144 151.647 174 144
-168.294 174 144 170 173.833 144 170.056 174 144
-173 174 141.9 216.5 174 144 217 173.393 144
-46.6667 175 144 116.5 175 144 117 174.056 144
-152 174.522 144 152.324 175 144 168.261 175 144
-170.739 175 144 174 175 142.5 203.5 175 144
-204 174.955 144 205 174.815 144 205.179 175 144
-215.5 175 144 216 174.5 144 47 175.393 144
-47.5 176 144 115.848 176 144 116 175.773 144
-152.647 176 144 168.529 176 144 171 175.5 144
-171.261 176 144 202.81 176 144 203 175.2 144
-205.957 176 144 214.393 176 144 215 175.5 144
-48 176.5 144 48.5 177 144 115.176 177 144
-153 176.522 144 153.324 177 144 169 176.593 144
-169.393 177 144 171.333 177 144 202.643 177 144
-206 176.045 144 206.778 177 144 213.393 177 144
-214 176.393 144 49 177.5 144 49.5 178 144
-114.5 178 144 115 177.261 144 154 178 144
-170 177.944 144 171 178 144 203 177.909 144
-203.043 178 144 207 177.261 144 207.607 178 144
-212.667 178 144 213 177.5 144 50 178.5 144
-50.5 179 144 113.848 179 144 114 178.773 144
-155 179 144 183 179 143.824 182.941 179 144
-183 178.955 144 183.167 179 144 203.414 179 144
-208 178.647 144 208.176 179 144 211.697 179 144
-212 178.688 144 51 179.5 144 51.5 180 144
-113 180 144 156 180 144 182.964 180 144
-184 179.278 144 184 180 142.143 185 179.824 144
-185.214 180 144 203.515 180 144 209 179.824 144
-210 180 144 211 179.676 144 52 180.5 144
-52.6071 181 144 112 181 144 157 181 144
-183 181 142.5 182.783 181 144 184 181 141.571
-185 181 141.125 186 180.957 144 186.056 181 144
-202.706 181 144 203 180.773 144 53 181.333 144
-53.8148 182 144 111 182 144 158 181.848 144
-158.227 182 144 165 182 143.824 164.957 182 144
-165 181 144 166 181.333 144 166 182 142.2
-166.706 182 144 172 182 144 173 181.545 144
-173.455 182 144 183 181.455 144 184 182 141.938
-183.353 182 144 187 181.63 144 187.37 182 144
-198.353 182 144 199 181.476 144 200 181.179 144
-201 181.343 144 202 181.343 144 54 182.152 144
-55 182.848 144 55.2273 183 144 110 183 144
-159 182.5 144 159.773 183 144 165 182.043 144
-166 183 142.8 165.786 183 144 167 182.833 144
-167 183 143.667 167.077 183 144 171.739 183 144
-174 182.429 144 175 182.643 144 176 182.286 144
-177 182.214 144 178 182.393 144 179 183 144
-183.462 183 144 188 182.773 144 188.417 183 144
-198.515 183 144 56 183.5 144 57 184 144
-70.5882 184 144 71 183.72 144 72 183.966 144
-72.0588 184 144 87.9583 184 144 88 183.957 144
-89 183.5 144 89.7727 184 144 109 184 144
-160 183.152 144 161 184 144 166 183.5 144
-167 184 141.429 166.5 184 144 168 183.545 144
-168.625 184 144 171.167 184 144 180 183.478 144
-181 184 144 182.545 184 144 183 183.545 144
-189 183.318 144 190 183.706 144 190.217 184 144
-198.182 184 144 58 184.676 144 58.6471 185 144
-70.4138 185 144 73 184.593 144 73.5238 185 144
-87.4138 185 144 90 184.227 144 90.6071 185 144
-108 185 144 162 185 144 166.6 185 144
-169 184.182 144 170 184.176 144 171 184.042 144
-182 184.171 144 190.786 185 144 198.179 185 144
-59 185.176 144 60 185.824 144 60.5 186 144
-71 185.5 144 71.7727 186 144 74 185.455 144
-75 185.957 144 75.0909 186 144 83.3529 186 144
-84 185.676 144 85 185.667 144 86 186 144
-87 185.706 144 90.4286 186 144 107 186 144
-163 186 144 166.414 186 144 178 185.964 144
-177.857 186 144 178.2 186 144 191 185.214 144
-191.786 186 144 196.688 186 144 197 185.815 144
-198 185.192 144 61 186.176 144 62 186.824 144
-62.2609 187 144 72 186.179 144 73 186.667 144
-73.2727 187 144 76 186.303 144 77 186.75 144
-78 186.964 144 79 186.966 144 80 186.647 144
-81 186.514 144 82 186.343 144 83 186.176 144
-90 186.5 144 89.6471 187 144 105.706 187 144
-106 186.848 144 164 186.821 144 164.227 187 144
-166.077 187 144 176 186.767 144 175.611 187 144
-177 186.207 144 178.706 187 144 192 186.214 144
-192.815 187 144 195.522 187 144 196 186.5 144
-63 187.5 144 63.7391 188 144 74 188 144
-89.1471 188 144 103.478 188 144 104 187.586 144
-105 187.343 144 165 187.515 144 166 187.045 144
-169 187.217 144 168.217 188 144 170 187.217 144
-171 187.909 144 171.063 188 144 174.179 188 144
-175 187.324 144 178.5 188 144 193 187.152 144
-194 187.676 144 195 187.522 144 64 188.176 144
-65 188.657 144 66 189 144 74.625 189 144
-85 188.727 144 84.7931 189 144 86 188.407 144
-86.7273 189 144 89 188.5 144 88.7059 189 144
-102.5 189 144 103 188.393 144 168.455 189 144
-170 189 141.429 171.083 189 144 173 189 144
-174 188.227 144 178.485 189 144 67 189.5 144
-68 190 144 75 189.353 144 75 190 141.938
-76 190 143.571 76 189.941 144 76.0357 190 144
-84.9706 190 144 87 189.214 144 88 189.414 144
-101.393 190 144 102 189.5 144 169 189.353 144
-170 189.522 144 171 189.091 144 173 190 144
-179 190 141.167 178.5 190 144 182 190 143
-69 190.343 144 70 190.657 144 71 191 144
-72 191 144 73 190.778 144 74 190.714 144
-75 190.688 144 76 190.083 144 85 190.056 144
-85.6071 191 144 100 191 144 101 190.333 144
-174 191 144 178 191 144 86 191.478 144
-86.3529 192 144 98 192 144 99 191.5 144
-175 191.514 144 176 191.514 144 177 191.514 144
-87 192.815 144 87.1852 193 144 95 193 144
-96 192.657 144 97 192.343 144 88 193.786 144
-89 193.824 144 90 193.647 144 91 193.514 144
-92 193.514 144 93 193.514 144 94 193.343 144
-
-POLYGONS 13733 54932
-3 0 13 17
-3 14 0 17
-3 3 2 4
-3 5 3 4
-3 7 3 6
-3 6 3 5
-3 2 13 4
-3 5 4 13
-3 6 5 13
-3 9 10 11
-3 0 7 13
-3 7 6 13
-3 14 7 0
-3 14 8 7
-3 19 8 14
-3 10 9 20
-3 20 9 126
-3 11 10 15
-3 15 10 20
-3 12 11 16
-3 16 11 15
-3 16 121 12
-3 17 18 14
-3 19 14 22
-3 21 8 19
-3 28 17 13
-3 17 28 18
-3 14 18 22
-3 22 18 28
-3 132 20 126
-3 15 20 132
-3 21 19 29
-3 29 19 22
-3 23 21 29
-3 21 23 24
-3 24 127 21
-3 125 25 26
-3 27 125 26
-3 24 23 29
-3 127 24 30
-3 34 31 25
-3 26 25 32
-3 32 25 31
-3 27 26 32
-3 30 24 38
-3 127 30 33
-3 31 34 36
-3 36 34 35
-3 37 31 36
-3 37 32 31
-3 27 32 37
-3 38 33 30
-3 39 33 38
-3 35 34 39
-3 35 137 36
-3 37 36 137
-3 40 140 42
-3 42 41 40
-3 40 41 43
-3 43 41 42
-3 43 42 47
-3 47 42 46
-3 48 44 45
-3 49 48 45
-3 50 44 48
-3 51 46 58
-3 47 46 51
-3 51 2917 47
-3 50 48 52
-3 52 155 50
-3 48 53 52
-3 54 155 52
-3 53 54 52
-3 46 160 58
-3 160 57 58
-3 51 58 59
-3 65 51 59
-3 60 55 56
-3 61 160 71
-3 160 61 57
-3 57 61 62
-3 58 57 66
-3 66 57 62
-3 63 58 66
-3 64 58 63
-3 59 58 65
-3 65 58 64
-3 56 69 60
-3 70 60 69
-3 62 61 72
-3 66 62 72
-3 63 66 67
-3 64 63 68
-3 68 63 67
-3 65 64 75
-3 75 64 68
-3 75 2917 65
-3 76 60 70
-3 72 61 71
-3 66 72 73
-3 67 66 74
-3 74 66 73
-3 68 67 75
-3 75 67 74
-3 69 165 70
-3 76 70 165
-3 72 71 81
-3 73 72 77
-3 77 72 81
-3 77 74 73
-3 75 74 77
-3 164 78 79
-3 164 76 165
-3 164 79 86
-3 80 71 168
-3 81 71 80
-3 82 80 168
-3 89 82 168
-3 83 80 82
-3 84 80 83
-3 81 80 85
-3 85 80 84
-3 78 86 79
-3 88 86 87
-3 92 89 168
-3 84 83 171
-3 171 83 82
-3 171 85 84
-3 88 87 90
-3 90 87 86
-3 174 91 92
-3 89 92 96
-3 93 94 174
-3 101 93 174
-3 94 95 174
-3 174 95 91
-3 92 91 96
-3 96 91 95
-3 89 96 177
-3 101 97 93
-3 93 97 98
-3 94 93 99
-3 99 93 98
-3 180 95 94
-3 96 95 180
-3 103 173 175
-3 3 173 103
-3 3 7 173
-3 173 7 264
-3 101 100 1
-3 97 101 1
-3 102 97 1
-3 102 98 97
-3 99 98 111
-3 111 98 102
-3 111 94 99
-3 122 103 175
-3 3 103 2
-3 104 100 101
-3 107 104 101
-3 1 100 105
-3 105 100 104
-3 122 2 103
-3 112 264 7
-3 179 185 115
-3 11 179 115
-3 11 106 179
-3 179 106 107
-3 104 107 108
-3 105 104 109
-3 109 104 108
-3 105 110 1
-3 105 109 110
-3 1 110 102
-3 111 102 110
-3 122 13 2
-3 8 112 7
-3 115 185 114
-3 11 115 9
-3 106 11 12
-3 121 106 12
-3 121 107 106
-3 108 107 116
-3 116 107 121
-3 109 108 111
-3 111 108 116
-3 110 109 111
-3 112 8 21
-3 117 112 127
-3 113 123 118
-3 184 113 118
-3 125 184 118
-3 119 184 125
-3 114 119 120
-3 115 114 120
-3 9 115 126
-3 111 116 136
-3 136 116 121
-3 127 112 21
-3 117 127 128
-3 128 193 117
-3 194 123 113
-3 131 118 123
-3 125 118 124
-3 124 118 131
-3 126 119 125
-3 120 119 126
-3 115 120 126
-3 15 121 16
-3 28 13 122
-3 129 193 128
-3 129 130 194
-3 194 130 123
-3 123 130 134
-3 131 123 134
-3 25 124 131
-3 125 124 25
-3 126 125 27
-3 132 136 15
-3 121 15 136
-3 28 122 133
-3 128 127 33
-3 129 128 130
-3 34 131 134
-3 25 131 34
-3 135 126 27
-3 132 126 135
-3 136 132 135
-3 29 133 218
-3 29 22 133
-3 22 28 133
-3 130 128 33
-3 134 130 33
-3 27 219 135
-3 136 135 219
-3 29 38 24
-3 134 33 39
-3 34 134 39
-3 38 29 218
-3 27 37 219
-3 219 37 137
-3 218 39 38
-3 137 35 39
-3 140 234 138
-3 139 236 237
-3 140 138 42
-3 141 139 237
-3 142 139 141
-3 40 43 140
-3 43 234 140
-3 143 144 141
-3 141 144 142
-3 144 147 142
-3 148 42 138
-3 2917 234 43
-3 145 144 143
-3 147 144 145
-3 146 145 143
-3 147 145 146
-3 42 148 46
-3 47 2917 43
-3 154 149 146
-3 147 146 150
-3 150 146 149
-3 151 147 150
-3 154 152 149
-3 149 152 150
-3 44 152 45
-3 44 151 152
-3 151 150 152
-3 44 155 151
-3 46 148 760
-3 153 152 154
-3 45 153 49
-3 152 153 45
-3 44 50 155
-3 154 49 153
-3 154 157 49
-3 157 48 49
-3 48 157 53
-3 155 54 156
-3 244 155 55
-3 55 155 156
-3 46 760 160
-3 51 65 2917
-3 53 156 54
-3 53 157 156
-3 157 158 156
-3 55 158 56
-3 55 156 158
-3 55 60 245
-3 55 245 244
-3 245 60 159
-3 157 163 161
-3 157 161 158
-3 158 161 56
-3 60 162 159
-3 160 760 71
-3 56 161 163
-3 69 56 163
-3 76 162 60
-3 69 163 165
-3 76 164 162
-3 256 168 760
-3 71 760 168
-3 78 164 165
-3 86 252 164
-3 86 88 252
-3 81 75 77
-3 165 359 78
-3 252 88 166
-3 252 166 257
-3 256 167 168
-3 78 359 86
-3 257 166 169
-3 167 261 92
-3 168 167 92
-3 85 171 81
-3 171 75 81
-3 166 90 170
-3 88 90 166
-3 169 166 173
-3 173 166 170
-3 264 169 173
-3 261 259 174
-3 92 261 174
-3 86 359 172
-3 86 172 90
-3 90 172 170
-3 172 173 170
-3 89 177 82
-3 171 82 177
-3 2917 171 177
-3 173 172 175
-3 175 172 359
-3 178 264 112
-3 179 107 176
-3 176 101 174
-3 101 176 107
-3 94 111 180
-3 359 122 175
-3 183 178 182
-3 184 276 183
-3 111 181 180
-3 187 180 181
-3 180 187 96
-3 182 178 112
-3 179 184 185
-3 186 181 111
-3 187 181 186
-3 177 96 187
-3 182 112 117
-3 183 182 188
-3 189 183 188
-3 113 183 189
-3 184 183 113
-3 185 184 190
-3 185 190 114
-3 117 193 182
-3 188 182 191
-3 191 182 193
-3 189 188 194
-3 194 188 191
-3 113 189 194
-3 119 190 184
-3 114 190 119
-3 136 192 111
-3 186 111 192
-3 187 186 192
-3 194 191 193
-3 194 193 129
-3 133 122 218
-3 136 219 220
-3 196 195 197
-3 197 195 295
-3 198 196 197
-3 198 199 196
-3 201 202 200
-3 202 203 205
-3 200 202 205
-3 203 204 205
-3 205 204 206
-3 206 207 291
-3 295 208 197
-3 198 197 208
-3 199 198 209
-3 209 198 208
-3 210 199 209
-3 200 199 211
-3 211 199 210
-3 201 200 211
-3 212 201 211
-3 202 201 213
-3 213 201 212
-3 203 202 213
-3 204 203 214
-3 214 203 213
-3 215 204 214
-3 206 204 215
-3 215 216 206
-3 207 206 216
-3 211 210 217
-3 217 210 209
-3 212 211 217
-3 217 213 212
-3 214 213 217
-3 215 214 217
-3 220 137 39
-3 219 137 220
-3 221 222 223
-3 221 227 224
-3 222 221 225
-3 225 221 224
-3 225 315 222
-3 224 227 228
-3 315 225 228
-3 228 225 224
-3 226 540 230
-3 227 226 231
-3 231 226 230
-3 228 227 232
-3 232 227 231
-3 232 315 228
-3 230 540 138
-3 234 230 138
-3 234 231 230
-3 232 231 315
-3 315 231 234
-3 235 233 229
-3 238 235 229
-3 236 233 235
-3 761 233 236
-3 237 235 238
-3 236 235 237
-3 237 238 141
-3 139 142 236
-3 142 761 236
-3 143 141 238
-3 239 142 147
-3 239 419 142
-3 238 320 143
-3 320 146 143
-3 146 320 154
-3 147 151 239
-3 148 138 760
-3 155 239 151
-3 241 239 155
-3 320 762 154
-3 762 157 154
-3 155 244 241
-3 325 240 243
-3 243 240 242
-3 247 242 240
-3 243 242 248
-3 248 242 247
-3 248 325 243
-3 159 246 245
-3 159 249 246
-3 247 250 248
-3 762 163 157
-3 159 162 249
-3 251 162 164
-3 251 164 253
-3 252 253 164
-3 253 252 336
-3 165 163 262
-3 333 252 254
-3 254 252 257
-3 255 333 254
-3 165 262 359
-3 255 254 258
-3 258 254 257
-3 259 451 260
-3 256 451 261
-3 261 451 259
-3 167 256 261
-3 258 257 263
-3 263 257 169
-3 264 258 263
-3 255 258 264
-3 267 259 260
-3 75 171 2917
-3 263 169 264
-3 264 346 255
-3 351 346 265
-3 265 346 264
-3 259 267 174
-3 269 265 264
-3 178 363 270
-3 363 178 275
-3 271 266 354
-3 271 354 272
-3 272 273 274
-3 271 272 274
-3 268 274 273
-3 267 268 273
-3 267 273 174
-3 264 178 269
-3 269 178 360
-3 275 178 276
-3 184 365 276
-3 179 805 184
-3 354 179 176
-3 272 354 176
-3 174 272 176
-3 273 272 174
-3 178 277 360
-3 270 277 178
-3 276 178 183
-3 122 359 278
-3 187 192 177
-3 279 280 385
-3 385 280 281
-3 391 282 279
-3 279 282 280
-3 281 280 282
-3 283 281 282
-3 281 283 284
-3 122 382 218
-3 1226 192 136
-3 285 286 395
-3 401 287 286
-3 288 286 287
-3 395 286 289
-3 289 286 288
-3 289 290 395
-3 393 395 290
-3 196 290 195
-3 393 290 196
-3 196 199 393
-3 199 200 393
-3 393 200 205
-3 205 291 292
-3 287 401 293
-3 287 293 288
-3 289 288 294
-3 294 288 293
-3 290 289 295
-3 295 289 294
-3 290 295 195
-3 291 205 206
-3 207 296 291
-3 292 291 296
-3 293 297 298
-3 294 293 298
-3 295 294 298
-3 295 298 208
-3 216 215 299
-3 216 299 207
-3 207 299 296
-3 299 409 296
-3 215 409 299
-3 209 409 217
-3 208 409 209
-3 409 215 217
-3 300 301 410
-3 301 304 410
-3 300 302 303
-3 301 300 304
-3 304 300 303
-3 303 302 306
-3 306 302 305
-3 304 303 307
-3 307 303 306
-3 307 308 304
-3 223 302 221
-3 305 302 223
-3 222 305 223
-3 222 309 305
-3 309 306 305
-3 307 306 308
-3 308 306 309
-3 221 302 227
-3 222 315 309
-3 315 308 309
-3 233 415 229
-3 415 414 229
-3 302 226 227
-3 302 540 226
-3 312 310 311
-3 423 312 311
-3 312 314 310
-3 313 312 423
-3 314 312 313
-3 316 313 423
-3 314 313 317
-3 317 313 316
-3 317 914 314
-3 317 316 318
-3 914 317 318
-3 142 419 761
-3 540 760 138
-3 319 316 423
-3 318 316 319
-3 914 318 319
-3 2917 315 234
-3 229 320 238
-3 241 322 321
-3 239 241 321
-3 319 240 325
-3 324 322 241
-3 323 322 324
-3 319 423 240
-3 241 244 324
-3 245 425 244
-3 246 425 245
-3 240 423 247
-3 325 248 250
-3 330 325 250
-3 427 426 249
-3 249 426 246
-3 247 423 250
-3 249 430 327
-3 249 162 430
-3 427 249 327
-3 250 423 329
-3 330 250 329
-3 442 163 762
-3 251 331 162
-3 331 430 162
-3 337 332 328
-3 333 328 332
-3 330 329 334
-3 326 330 434
-3 434 330 334
-3 335 331 251
-3 336 332 337
-3 252 333 336
-3 333 332 336
-3 423 338 329
-3 329 338 334
-3 339 434 338
-3 338 434 334
-3 335 342 443
-3 335 251 342
-3 251 253 342
-3 337 253 336
-3 760 451 256
-3 341 339 338
-3 340 341 338
-3 440 344 441
-3 163 442 262
-3 343 443 342
-3 255 346 333
-3 573 441 344
-3 262 442 349
-3 342 345 343
-3 451 347 260
-3 344 440 348
-3 348 440 356
-3 573 344 357
-3 357 344 348
-3 262 349 454
-3 454 350 262
-3 352 346 351
-3 347 805 179
-3 354 347 179
-3 355 347 354
-3 260 347 355
-3 348 356 357
-3 358 573 357
-3 262 350 359
-3 360 351 265
-3 352 351 360
-3 361 363 362
-3 363 364 362
-3 362 364 365
-3 365 184 805
-3 266 366 354
-3 366 355 354
-3 367 355 366
-3 267 367 268
-3 267 260 367
-3 260 355 367
-3 358 357 368
-3 368 369 358
-3 265 269 360
-3 363 361 270
-3 270 361 370
-3 364 363 371
-3 371 363 275
-3 276 364 371
-3 365 364 276
-3 271 643 266
-3 366 266 832
-3 832 266 643
-3 367 366 474
-3 366 832 474
-3 372 271 274
-3 474 268 367
-3 274 268 372
-3 372 268 474
-3 356 373 357
-3 368 357 374
-3 374 357 373
-3 375 369 368
-3 375 368 374
-3 377 270 370
-3 276 371 275
-3 372 643 271
-3 375 374 378
-3 378 374 373
-3 278 359 376
-3 380 360 277
-3 277 270 377
-3 277 377 380
-3 379 122 278
-3 494 122 379
-3 122 494 382
-3 177 192 1226
-3 518 386 383
-3 507 383 386
-3 385 384 516
-3 387 384 385
-3 507 386 388
-3 388 389 507
-3 389 391 516
-3 385 391 279
-3 385 516 391
-3 281 387 385
-3 386 518 388
-3 389 388 390
-3 389 390 391
-3 387 281 284
-3 284 392 387
-3 285 387 392
-3 393 387 285
-3 285 395 393
-3 391 283 282
-3 391 390 283
-3 283 392 284
-3 283 394 392
-3 285 392 286
-3 392 394 286
-3 283 390 396
-3 396 397 283
-3 398 399 394
-3 398 394 397
-3 397 394 283
-3 399 400 401
-3 399 401 394
-3 394 401 286
-3 292 393 205
-3 382 707 218
-3 402 396 390
-3 403 396 402
-3 403 404 405
-3 403 405 396
-3 396 405 397
-3 400 398 397
-3 400 397 406
-3 406 397 405
-3 400 406 401
-3 292 296 407
-3 405 408 406
-3 401 406 408
-3 297 293 408
-3 293 401 408
-3 296 409 407
-3 297 408 298
-3 532 408 405
-3 298 408 532
-3 39 218 1226
-3 39 1226 220
-3 304 411 410
-3 413 412 414
-3 761 413 414
-3 761 414 415
-3 418 416 539
-3 423 418 539
-3 417 416 418
-3 417 914 416
-3 414 412 229
-3 310 418 311
-3 310 417 418
-3 310 914 417
-3 415 233 761
-3 418 423 311
-3 310 314 914
-3 319 573 914
-3 420 761 419
-3 229 762 320
-3 419 239 421
-3 421 420 419
-3 319 325 573
-3 239 542 421
-3 239 321 542
-3 542 321 322
-3 542 322 422
-3 322 323 422
-3 326 325 330
-3 324 422 323
-3 246 424 425
-3 324 244 422
-3 426 424 246
-3 426 554 424
-3 429 554 426
-3 429 426 428
-3 428 426 427
-3 327 430 557
-3 427 327 431
-3 431 327 557
-3 428 427 431
-3 429 428 431
-3 328 432 564
-3 573 326 440
-3 430 331 433
-3 328 564 337
-3 328 333 432
-3 438 432 333
-3 440 326 434
-3 331 335 433
-3 433 335 449
-3 570 435 337
-3 570 337 564
-3 435 436 437
-3 570 436 435
-3 339 439 434
-3 439 447 434
-3 440 434 447
-3 443 449 335
-3 337 444 253
-3 337 435 444
-3 444 435 445
-3 435 437 445
-3 445 437 446
-3 333 346 438
-3 346 576 438
-3 423 470 338
-3 439 341 447
-3 339 341 439
-3 441 573 440
-3 448 449 443
-3 443 343 448
-3 444 342 253
-3 445 450 444
-3 446 450 445
-3 346 579 576
-3 338 452 340
-3 340 447 341
-3 340 452 447
-3 452 456 447
-3 356 447 456
-3 447 356 440
-3 442 453 349
-3 454 449 448
-3 458 449 454
-3 343 345 455
-3 343 455 448
-3 448 455 454
-3 345 459 455
-3 342 459 345
-3 444 459 342
-3 579 346 352
-3 352 584 579
-3 584 352 586
-3 451 805 347
-3 452 338 470
-3 349 453 457
-3 454 349 458
-3 457 458 349
-3 459 454 455
-3 459 350 454
-3 459 460 350
-3 589 462 461
-3 586 352 353
-3 365 805 598
-3 456 452 470
-3 573 358 464
-3 464 471 573
-3 465 458 457
-3 465 457 466
-3 466 457 453
-3 466 460 465
-3 466 359 460
-3 359 350 460
-3 461 467 589
-3 462 467 461
-3 352 360 595
-3 360 468 595
-3 353 352 607
-3 352 595 607
-3 608 361 469
-3 463 362 598
-3 463 469 362
-3 469 361 362
-3 365 598 362
-3 456 470 356
-3 464 369 375
-3 358 369 464
-3 471 464 375
-3 453 477 466
-3 359 466 472
-3 466 477 472
-3 468 360 639
-3 608 626 370
-3 608 370 361
-3 470 893 356
-3 375 475 471
-3 476 471 475
-3 478 617 472
-3 478 472 477
-3 376 617 479
-3 376 472 617
-3 376 359 472
-3 370 653 377
-3 480 628 473
-3 480 473 629
-3 372 474 485
-3 373 356 893
-3 475 378 481
-3 375 378 475
-3 476 475 482
-3 482 475 481
-3 483 471 476
-3 483 476 482
-3 376 648 278
-3 479 648 376
-3 380 639 360
-3 485 643 372
-3 481 378 678
-3 482 481 679
-3 679 481 678
-3 483 482 486
-3 486 482 679
-3 487 483 486
-3 278 648 684
-3 379 488 484
-3 379 278 488
-3 650 685 484
-3 685 379 484
-3 380 377 987
-3 378 489 678
-3 679 490 486
-3 381 487 490
-3 487 486 490
-3 381 491 492
-3 381 492 487
-3 491 493 664
-3 492 491 664
-3 859 278 684
-3 488 278 859
-3 495 494 685
-3 494 379 685
-3 378 373 496
-3 373 893 496
-3 378 496 489
-3 496 497 489
-3 498 678 489
-3 498 489 497
-3 679 499 490
-3 381 490 500
-3 490 499 500
-3 381 500 491
-3 500 501 491
-3 493 491 501
-3 507 493 501
-3 502 493 507
-3 387 493 502
-3 503 700 382
-3 382 495 503
-3 494 495 382
-3 504 701 687
-3 893 505 496
-3 496 505 497
-3 498 497 505
-3 499 498 506
-3 506 498 505
-3 500 499 506
-3 501 500 506
-3 383 507 501
-3 502 507 508
-3 384 502 508
-3 502 384 387
-3 382 700 707
-3 510 512 513
-3 512 514 513
-3 515 505 893
-3 505 515 506
-3 501 506 515
-3 383 501 518
-3 516 508 507
-3 508 516 384
-3 513 511 510
-3 501 515 518
-3 516 389 519
-3 507 389 516
-3 516 519 389
-3 515 521 518
-3 388 518 521
-3 388 521 390
-3 524 393 292
-3 292 407 524
-3 521 1217 390
-3 522 403 525
-3 522 526 403
-3 399 398 526
-3 399 526 523
-3 523 526 522
-3 523 400 399
-3 523 527 400
-3 390 528 402
-3 529 525 528
-3 529 530 525
-3 528 525 402
-3 402 525 403
-3 530 404 531
-3 530 529 404
-3 531 404 526
-3 526 404 403
-3 398 531 526
-3 398 400 531
-3 400 527 531
-3 529 528 532
-3 532 528 390
-3 404 529 405
-3 529 532 405
-3 407 409 524
-3 218 707 533
-3 220 1226 136
-3 1052 298 532
-3 208 298 1052
-3 533 1226 218
-3 409 208 1052
-3 411 534 410
-3 534 411 1258
-3 535 412 536
-3 411 304 757
-3 1258 411 757
-3 412 413 536
-3 410 540 300
-3 538 537 914
-3 761 536 413
-3 540 302 300
-3 304 308 758
-3 758 757 304
-3 539 914 537
-3 762 412 535
-3 416 914 539
-3 759 758 308
-3 539 537 423
-3 308 315 759
-3 315 2917 759
-3 412 762 229
-3 541 761 420
-3 421 541 420
-3 421 542 541
-3 542 543 541
-3 546 541 544
-3 544 541 543
-3 544 545 546
-3 422 543 542
-3 546 545 547
-3 765 543 422
-3 548 545 544
-3 547 545 548
-3 548 549 547
-3 325 326 573
-3 422 768 765
-3 549 548 769
-3 424 550 425
-3 422 244 768
-3 551 768 244
-3 425 550 552
-3 424 553 550
-3 553 424 554
-3 425 555 244
-3 555 551 244
-3 555 425 556
-3 425 552 556
-3 550 557 552
-3 557 556 552
-3 558 553 559
-3 558 557 553
-3 557 550 553
-3 554 559 553
-3 429 776 554
-3 557 430 556
-3 560 561 430
-3 556 430 561
-3 557 558 431
-3 431 558 562
-3 561 560 558
-3 562 558 560
-3 431 562 429
-3 429 563 776
-3 562 563 429
-3 560 433 565
-3 430 433 560
-3 562 560 566
-3 566 560 565
-3 563 562 566
-3 432 567 564
-3 568 567 432
-3 568 432 438
-3 779 568 438
-3 565 433 569
-3 433 449 569
-3 564 567 570
-3 436 570 785
-3 437 571 572
-3 437 436 571
-3 436 785 571
-3 438 786 572
-3 438 572 779
-3 571 779 572
-3 576 786 438
-3 577 569 449
-3 444 450 575
-3 572 575 446
-3 572 446 437
-3 446 575 450
-3 786 575 572
-3 760 805 451
-3 579 578 576
-3 449 458 577
-3 459 444 588
-3 444 574 588
-3 580 581 582
-3 583 579 584
-3 585 584 586
-3 459 587 460
-3 459 588 587
-3 591 580 590
-3 582 592 580
-3 592 590 580
-3 592 582 581
-3 594 583 593
-3 584 595 583
-3 595 593 583
-3 596 584 585
-3 595 584 596
-3 353 597 586
-3 597 463 598
-3 597 598 586
-3 599 600 601
-3 601 600 814
-3 602 458 465
-3 602 815 458
-3 815 577 458
-3 465 460 587
-3 465 587 602
-3 603 587 588
-3 462 589 467
-3 604 591 590
-3 605 591 604
-3 592 606 590
-3 606 604 590
-3 606 592 581
-3 593 820 594
-3 593 468 820
-3 595 468 593
-3 595 596 607
-3 597 353 607
-3 608 463 609
-3 608 469 463
-3 609 463 610
-3 610 463 597
-3 610 611 609
-3 612 613 614
-3 644 573 471
-3 599 615 616
-3 616 600 599
-3 442 477 453
-3 815 617 618
-3 815 602 617
-3 602 587 617
-3 619 587 603
-3 617 587 619
-3 620 621 622
-3 622 623 620
-3 606 605 604
-3 625 820 468
-3 625 468 639
-3 626 608 609
-3 627 609 611
-3 627 628 609
-3 628 626 609
-3 613 628 627
-3 612 628 613
-3 612 473 628
-3 473 612 629
-3 629 630 631
-3 474 832 833
-3 599 632 615
-3 615 632 633
-3 616 615 634
-3 634 615 633
-3 634 600 616
-3 635 618 478
-3 617 478 618
-3 635 479 619
-3 617 619 479
-3 620 636 621
-3 623 636 620
-3 370 626 640
-3 628 641 626
-3 641 640 626
-3 628 480 641
-3 631 660 629
-3 660 631 642
-3 474 833 485
-3 471 483 644
-3 645 599 680
-3 599 645 632
-3 632 645 646
-3 633 632 647
-3 647 632 646
-3 647 634 633
-3 477 635 478
-3 477 648 635
-3 635 648 479
-3 484 859 649
-3 488 859 484
-3 484 649 650
-3 668 669 624
-3 624 637 668
-3 637 651 668
-3 652 637 638
-3 651 637 652
-3 370 654 653
-3 370 640 654
-3 655 653 654
-3 656 654 640
-3 641 657 640
-3 657 656 640
-3 480 658 641
-3 641 658 657
-3 480 659 658
-3 480 629 659
-3 660 659 629
-3 661 662 663
-3 483 487 644
-3 487 492 644
-3 664 644 492
-3 680 665 645
-3 645 665 666
-3 646 645 667
-3 667 645 666
-3 667 647 646
-3 670 668 651
-3 652 670 651
-3 987 377 653
-3 654 671 655
-3 671 654 672
-3 654 656 672
-3 657 673 656
-3 673 672 656
-3 658 674 657
-3 674 673 657
-3 674 658 659
-3 675 662 661
-3 691 662 675
-3 676 661 663
-3 675 661 676
-3 485 677 643
-3 387 664 493
-3 680 681 665
-3 665 681 682
-3 666 665 683
-3 683 665 682
-3 683 667 666
-3 648 698 684
-3 686 669 687
-3 669 668 687
-3 703 668 670
-3 687 668 703
-3 688 671 672
-3 673 689 672
-3 689 688 672
-3 674 690 673
-3 690 689 673
-3 676 691 675
-3 499 678 498
-3 679 678 499
-3 692 694 693
-3 693 694 680
-3 680 694 695
-3 681 680 696
-3 696 680 695
-3 682 681 697
-3 697 681 696
-3 697 683 682
-3 698 699 684
-3 859 684 699
-3 859 699 707
-3 685 503 495
-3 685 700 503
-3 702 686 701
-3 687 701 686
-3 703 504 687
-3 866 688 689
-3 690 866 689
-3 714 517 693
-3 693 517 704
-3 692 704 509
-3 692 693 704
-3 509 705 692
-3 705 694 692
-3 695 694 706
-3 706 694 705
-3 697 696 706
-3 706 696 695
-3 504 702 701
-3 716 702 504
-3 710 510 511
-3 710 512 510
-3 514 512 867
-3 512 710 867
-3 514 712 711
-3 867 712 514
-3 393 713 387
-3 517 715 704
-3 509 704 715
-3 509 715 705
-3 715 738 705
-3 738 697 706
-3 738 706 705
-3 703 716 504
-3 718 708 717
-3 717 708 709
-3 511 719 710
-3 511 513 719
-3 514 719 513
-3 514 720 719
-3 730 719 720
-3 721 711 722
-3 721 720 711
-3 720 514 711
-3 712 722 711
-3 2917 177 1226
-3 393 520 713
-3 520 1014 713
-3 714 885 723
-3 714 723 724
-3 517 714 725
-3 725 714 724
-3 517 725 726
-3 517 726 715
-3 726 738 715
-3 727 718 717
-3 728 718 727
-3 729 717 709
-3 727 717 729
-3 721 730 720
-3 520 393 877
-3 1021 877 393
-3 1021 393 524
-3 723 885 734
-3 734 885 733
-3 724 723 735
-3 735 723 734
-3 736 724 735
-3 725 724 737
-3 737 724 736
-3 726 725 738
-3 738 725 737
-3 727 739 728
-3 729 739 727
-3 893 521 515
-3 731 522 525
-3 731 732 740
-3 731 740 522
-3 522 740 523
-3 741 523 740
-3 734 733 742
-3 735 734 742
-3 894 743 736
-3 894 736 735
-3 737 736 743
-3 744 738 737
-3 893 1217 521
-3 746 527 741
-3 527 523 741
-3 735 742 894
-3 530 745 525
-3 531 746 530
-3 530 746 745
-3 746 531 527
-3 524 409 901
-3 390 1051 532
-3 707 747 533
-3 532 1051 1052
-3 747 748 533
-3 533 748 749
-3 749 748 902
-3 533 749 902
-3 902 1226 533
-3 913 753 750
-3 752 751 754
-3 1103 410 534
-3 755 753 913
-3 756 755 913
-3 750 753 914
-3 914 753 755
-3 535 754 751
-3 535 536 754
-3 755 756 538
-3 914 755 538
-3 538 756 537
-3 535 751 762
-3 761 764 536
-3 756 423 537
-3 541 546 761
-3 546 764 761
-3 547 763 764
-3 546 547 764
-3 544 543 766
-3 766 543 765
-3 544 766 548
-3 763 549 767
-3 547 549 763
-3 764 763 767
-3 768 766 765
-3 548 766 769
-3 766 768 769
-3 769 767 549
-3 769 770 767
-3 764 767 770
-3 771 764 770
-3 551 769 768
-3 772 769 551
-3 772 773 770
-3 772 770 769
-3 770 773 771
-3 774 771 773
-3 774 554 918
-3 555 775 551
-3 551 775 772
-3 559 773 558
-3 558 773 926
-3 554 773 559
-3 774 773 554
-3 554 776 918
-3 918 776 777
-3 762 930 442
-3 555 924 775
-3 556 924 555
-3 556 925 924
-3 561 926 556
-3 556 926 925
-3 926 561 558
-3 776 563 778
-3 777 776 778
-3 566 778 563
-3 567 777 778
-3 568 777 567
-3 568 779 931
-3 931 779 780
-3 760 1132 805
-3 781 782 783
-3 565 569 791
-3 565 791 566
-3 791 945 566
-3 939 778 945
-3 945 778 566
-3 940 778 939
-3 570 940 784
-3 570 778 940
-3 570 567 778
-3 784 785 570
-3 785 786 571
-3 571 786 779
-3 780 779 786
-3 780 786 787
-3 787 786 576
-3 781 788 782
-3 569 577 791
-3 793 574 792
-3 792 574 794
-3 940 444 784
-3 940 794 444
-3 794 574 444
-3 575 784 444
-3 785 784 575
-3 786 785 575
-3 576 578 787
-3 789 796 797
-3 797 790 789
-3 792 945 801
-3 793 792 801
-3 793 801 574
-3 795 578 803
-3 579 803 578
-3 789 946 798
-3 789 798 796
-3 796 798 799
-3 797 796 800
-3 800 796 799
-3 800 790 797
-3 801 588 574
-3 802 951 580
-3 951 581 580
-3 803 579 583
-3 803 804 1128
-3 804 585 586
-3 804 586 1128
-3 586 598 1128
-3 952 573 825
-3 798 946 806
-3 799 798 807
-3 807 798 806
-3 814 800 807
-3 807 800 799
-3 790 800 814
-3 577 808 953
-3 577 953 950
-3 801 953 808
-3 801 808 588
-3 802 591 954
-3 580 591 802
-3 951 809 581
-3 803 594 810
-3 583 594 803
-3 811 812 804
-3 811 804 810
-3 810 804 803
-3 812 585 804
-3 812 813 585
-3 813 596 585
-3 601 946 599
-3 806 946 601
-3 814 807 806
-3 601 814 806
-3 577 815 808
-3 588 808 816
-3 816 808 815
-3 588 816 603
-3 954 605 957
-3 591 605 954
-3 581 809 606
-3 809 817 606
-3 820 810 594
-3 820 821 810
-3 822 811 810
-3 822 810 821
-3 607 813 822
-3 607 596 813
-3 597 823 610
-3 610 823 611
-3 613 824 614
-3 824 612 614
-3 831 612 824
-3 573 644 825
-3 952 825 664
-3 618 826 815
-3 826 816 815
-3 603 826 619
-3 816 826 603
-3 622 621 827
-3 622 827 623
-3 605 606 957
-3 957 606 817
-3 637 818 819
-3 637 624 818
-3 819 960 637
-3 625 828 820
-3 828 821 820
-3 822 821 829
-3 829 821 828
-3 607 822 830
-3 830 822 829
-3 966 607 830
-3 597 607 966
-3 967 597 966
-3 823 597 967
-3 611 823 627
-3 627 823 968
-3 824 613 627
-3 968 824 627
-3 629 612 831
-3 630 629 831
-3 831 631 630
-3 839 631 831
-3 825 644 834
-3 664 825 834
-3 600 634 814
-3 477 442 648
-3 618 635 826
-3 619 826 635
-3 621 636 827
-3 623 827 636
-3 637 960 638
-3 960 835 638
-3 625 639 828
-3 829 828 836
-3 836 828 639
-3 830 829 837
-3 837 829 836
-3 976 966 830
-3 976 830 838
-3 838 830 837
-3 839 840 642
-3 839 642 631
-3 840 841 842
-3 839 841 840
-3 841 989 842
-3 833 843 485
-3 664 834 644
-3 599 1154 680
-3 647 814 634
-3 648 442 698
-3 649 859 855
-3 855 844 649
-3 844 650 649
-3 650 844 845
-3 845 846 847
-3 844 846 845
-3 624 669 848
-3 624 848 985
-3 638 835 652
-3 835 985 652
-3 639 380 849
-3 836 639 849
-3 836 850 837
-3 653 838 850
-3 838 837 850
-3 653 655 976
-3 653 976 838
-3 976 655 993
-3 851 659 988
-3 988 659 660
-3 840 660 642
-3 840 852 660
-3 852 988 660
-3 842 852 840
-3 853 852 842
-3 854 842 662
-3 854 853 842
-3 662 842 663
-3 663 842 989
-3 995 663 989
-3 677 485 843
-3 1154 693 680
-3 667 814 647
-3 859 990 855
-3 856 844 855
-3 845 857 650
-3 650 857 685
-3 848 669 858
-3 670 985 848
-3 670 848 858
-3 985 670 652
-3 380 987 849
-3 653 850 987
-3 671 993 655
-3 659 862 674
-3 994 659 851
-3 862 659 994
-3 662 691 854
-3 995 676 663
-3 996 387 997
-3 683 814 667
-3 991 685 992
-3 992 685 857
-3 686 861 669
-3 860 861 686
-3 669 861 858
-3 861 703 858
-3 858 703 670
-3 671 688 993
-3 862 863 674
-3 674 863 690
-3 676 864 691
-3 995 864 676
-3 387 870 997
-3 697 892 683
-3 892 814 683
-3 700 999 859
-3 700 859 707
-3 991 999 685
-3 999 700 685
-3 686 702 860
-3 860 702 1006
-3 865 861 860
-3 703 861 865
-3 993 688 1008
-3 688 866 1008
-3 690 1009 866
-3 690 863 1009
-3 868 869 867
-3 870 387 713
-3 870 713 1013
-3 693 1187 714
-3 699 698 707
-3 702 716 1006
-3 1006 716 880
-3 703 865 1018
-3 709 708 872
-3 872 708 871
-3 871 873 872
-3 1009 1008 866
-3 710 874 867
-3 867 875 868
-3 874 875 867
-3 876 867 869
-3 876 712 867
-3 713 1014 1013
-3 1004 1014 520
-3 1004 520 877
-3 1187 1023 714
-3 697 738 892
-3 716 1018 880
-3 1018 716 703
-3 871 708 881
-3 708 718 881
-3 872 882 709
-3 873 882 872
-3 730 710 719
-3 730 883 710
-3 883 874 710
-3 721 722 884
-3 721 884 874
-3 721 874 883
-3 875 874 884
-3 876 722 712
-3 884 722 876
-3 878 877 1021
-3 1046 885 879
-3 714 1023 885
-3 728 886 881
-3 728 881 718
-3 882 729 709
-3 882 887 729
-3 721 883 730
-3 890 1033 731
-3 1033 732 731
-3 892 738 891
-3 728 739 886
-3 739 887 886
-3 729 887 739
-3 525 895 890
-3 731 525 890
-3 741 740 732
-3 733 885 1046
-3 743 897 737
-3 894 897 743
-3 892 737 897
-3 892 744 737
-3 891 738 744
-3 891 744 892
-3 733 1046 742
-3 892 897 899
-3 525 745 895
-3 746 1040 745
-3 898 896 901
-3 901 896 524
-3 742 1046 899
-3 899 894 742
-3 897 894 899
-3 900 898 901
-3 903 1047 901
-3 901 409 903
-3 747 902 748
-3 903 409 1052
-3 904 905 906
-3 909 1093 750
-3 1095 909 750
-3 1095 750 914
-3 751 910 911
-3 912 910 752
-3 752 910 751
-3 750 1093 913
-3 912 754 536
-3 912 752 754
-3 913 1093 756
-3 912 536 764
-3 762 751 911
-3 1258 757 759
-3 1105 914 915
-3 540 410 1103
-3 915 914 916
-3 760 540 1103
-3 757 758 759
-3 916 914 573
-3 759 2917 4237
-3 771 918 764
-3 917 919 923
-3 773 772 920
-3 920 921 773
-3 771 774 918
-3 928 922 919
-3 923 919 922
-3 772 775 924
-3 772 924 920
-3 924 925 920
-3 921 920 926
-3 926 920 925
-3 921 926 773
-3 777 927 918
-3 777 568 927
-3 932 1115 573
-3 922 928 929
-3 938 923 929
-3 929 923 922
-3 931 927 568
-3 1121 927 931
-3 1301 1132 760
-3 929 928 933
-3 933 938 929
-3 780 787 1121
-3 780 1121 931
-3 1121 787 1126
-3 783 934 935
-3 782 934 783
-3 935 781 783
-3 936 781 935
-3 937 928 789
-3 938 933 937
-3 937 933 928
-3 782 943 934
-3 788 943 782
-3 936 788 781
-3 943 788 936
-3 937 789 790
-3 937 790 938
-3 944 945 791
-3 792 939 945
-3 794 939 792
-3 940 939 794
-3 787 578 1126
-3 941 578 795
-3 942 941 795
-3 795 803 1128
-3 795 1128 942
-3 791 577 947
-3 791 947 948
-3 791 948 944
-3 948 1137 949
-3 948 949 944
-3 944 949 945
-3 945 949 801
-3 952 932 573
-3 577 950 947
-3 950 953 947
-3 801 949 1137
-3 801 1137 953
-3 805 1128 598
-3 932 952 1141
-3 938 790 814
-3 802 954 951
-3 951 954 809
-3 956 812 811
-3 1140 813 812
-3 809 957 817
-3 954 957 809
-3 819 958 959
-3 818 958 819
-3 959 960 819
-3 962 955 961
-3 963 956 964
-3 963 961 956
-3 961 955 956
-3 811 964 956
-3 811 822 964
-3 822 1140 964
-3 1140 822 813
-3 824 969 831
-3 664 1141 952
-3 1144 958 624
-3 958 818 624
-3 961 965 962
-3 963 965 961
-3 967 968 823
-3 968 969 824
-3 831 969 970
-3 970 971 831
-3 831 971 839
-3 833 832 972
-3 832 1366 972
-3 930 698 442
-3 1144 624 975
-3 960 975 835
-3 1144 975 960
-3 976 967 966
-3 977 968 967
-3 969 968 977
-3 970 969 978
-3 978 969 977
-3 1155 971 978
-3 978 971 970
-3 979 971 1155
-3 839 971 979
-3 839 980 841
-3 979 980 839
-3 841 980 989
-3 643 1366 832
-3 972 981 833
-3 981 843 833
-3 982 983 844
-3 844 984 846
-3 983 984 844
-3 846 984 847
-3 624 985 975
-3 975 985 835
-3 849 987 836
-3 986 987 849
-3 836 987 850
-3 994 977 967
-3 978 977 994
-3 851 988 978
-3 851 978 994
-3 1155 978 988
-3 1155 852 979
-3 1155 988 852
-3 853 979 852
-3 980 979 853
-3 854 980 853
-3 854 989 980
-3 1382 1366 677
-3 1366 643 677
-3 1382 677 981
-3 843 981 677
-3 996 664 387
-3 693 1154 1365
-3 855 991 856
-3 990 991 855
-3 856 982 844
-3 856 991 982
-3 991 992 982
-3 845 992 857
-3 845 983 992
-3 983 982 992
-3 847 983 845
-3 984 983 847
-3 987 986 849
-3 993 967 976
-3 994 967 993
-3 989 854 1165
-3 854 691 1165
-3 995 989 1165
-3 997 998 1161
-3 996 997 1161
-3 698 930 707
-3 990 859 999
-3 991 990 999
-3 862 1001 863
-3 862 994 1001
-3 994 993 1001
-3 691 1002 1165
-3 995 1002 864
-3 1002 691 864
-3 998 997 870
-3 1161 998 1003
-3 1004 1161 1003
-3 1005 1161 1004
-3 693 1169 1187
-3 1365 1169 693
-3 860 1006 1000
-3 860 1000 1007
-3 1000 1006 1007
-3 1007 865 860
-3 1001 993 1009
-3 1009 993 1008
-3 1001 1009 863
-3 1011 868 1010
-3 1011 1179 868
-3 1179 869 868
-3 1179 1012 869
-3 1013 998 870
-3 1003 998 1014
-3 1014 998 1013
-3 1004 1003 1014
-3 1005 1004 877
-3 1015 1005 877
-3 878 1005 1015
-3 1162 1005 878
-3 1162 878 1163
-3 1163 878 1021
-3 1007 1006 1018
-3 1018 1006 880
-3 865 1007 1018
-3 873 871 1189
-3 871 1188 1189
-3 873 1189 1019
-3 1010 875 884
-3 868 875 1010
-3 876 1011 1010
-3 876 1010 884
-3 869 1020 876
-3 1020 1011 876
-3 1012 1020 869
-3 1015 877 878
-3 1016 1022 879
-3 885 1016 879
-3 1017 1016 885
-3 885 1023 1017
-3 871 881 1024
-3 871 1024 1025
-3 871 1025 1188
-3 873 1026 882
-3 873 1019 1026
-3 1028 1029 1027
-3 1030 1032 1033
-3 1031 1032 1030
-3 1022 1046 879
-3 881 886 1034
-3 881 1034 1024
-3 1034 1035 1024
-3 1024 1036 1025
-3 1024 1035 1036
-3 1036 1196 1025
-3 1036 1026 1196
-3 1036 887 1026
-3 882 1026 887
-3 1027 1037 1028
-3 1029 1037 1027
-3 888 1202 889
-3 1038 888 889
-3 1039 1031 1030
-3 1205 1031 1039
-3 1033 890 1039
-3 1033 1039 1030
-3 1033 1032 1040
-3 1033 1040 732
-3 887 1034 886
-3 1035 1034 887
-3 1036 1035 887
-3 888 1204 1202
-3 1204 888 1038
-3 1205 1039 890
-3 1205 890 895
-3 741 732 1040
-3 1041 524 896
-3 1427 895 745
-3 1040 1427 745
-3 741 1040 746
-3 1022 1210 1046
-3 902 747 707
-3 898 1045 1042
-3 896 898 1042
-3 896 1042 1041
-3 1043 1044 900
-3 1045 900 1044
-3 1045 898 900
-3 1050 899 1046
-3 1043 900 1047
-3 900 901 1047
-3 1049 1046 1048
-3 1050 1046 1049
-3 1433 899 1050
-3 1217 1051 390
-3 1049 1048 1220
-3 1225 1222 1051
-3 1051 1222 1052
-3 1047 903 1215
-3 903 1052 1223
-3 1055 1053 1056
-3 1056 1053 1060
-3 1058 1053 1055
-3 1056 1058 1055
-3 1060 1057 1056
-3 1058 1056 1057
-3 1058 1057 1059
-3 1059 1057 1060
-3 1059 1062 1058
-3 905 1059 1060
-3 904 1061 1062
-3 905 904 1062
-3 905 1062 1059
-3 905 1063 906
-3 905 1060 1063
-3 1060 1238 1063
-3 906 1061 904
-3 906 1063 1061
-3 1063 1064 1061
-3 1064 1062 1061
-3 1238 1064 1063
-3 1065 1237 1066
-3 1067 1066 1237
-3 1238 1067 1237
-3 1067 1238 1068
-3 1066 1067 1070
-3 1070 1067 1068
-3 1238 1239 1069
-3 1238 1069 1068
-3 1070 1068 1069
-3 1072 1066 1070
-3 1242 1069 1239
-3 1070 1069 1071
-3 1071 1069 1242
-3 1072 1070 1071
-3 1071 1242 1073
-3 1072 1071 1073
-3 1073 1242 1074
-3 1072 1073 1076
-3 1076 1073 1074
-3 1076 1074 1075
-3 1074 1242 1077
-3 907 1075 1077
-3 1075 1074 1077
-3 907 1078 1076
-3 907 1076 1075
-3 907 1081 908
-3 1077 1081 907
-3 907 908 1078
-3 908 1081 1080
-3 908 1080 1078
-3 1078 1080 1079
-3 1472 1082 1081
-3 1243 1079 1080
-3 1081 1243 1080
-3 1082 1243 1081
-3 1084 1082 1083
-3 1084 1083 1085
-3 1085 1083 1086
-3 1086 1084 1085
-3 1087 1084 1086
-3 1088 1084 1087
-3 1087 1089 1088
-3 1088 1089 1090
-3 1090 1091 1088
-3 1089 1091 1090
-3 1094 1093 1092
-3 1095 1092 1093
-3 909 1095 1093
-3 1098 1097 1099
-3 1102 1251 1096
-3 1100 1097 1098
-3 1504 1100 1098
-3 910 1100 911
-3 910 1099 1100
-3 1099 1097 1100
-3 1099 910 1101
-3 910 912 1101
-3 1504 911 1100
-3 534 1258 1256
-3 1095 914 1259
-3 1504 762 911
-3 1259 914 1105
-3 1101 912 764
-3 1263 1259 1105
-3 1102 1106 1104
-3 1104 1106 1107
-3 1258 759 4237
-3 1112 1263 1105
-3 1109 1107 1108
-3 1108 1107 1106
-3 915 916 1105
-3 916 1112 1105
-3 1110 1109 1108
-3 916 573 1111
-3 1112 916 1111
-3 1108 1114 1110
-3 1110 1114 1113
-3 573 1268 1111
-3 1268 1112 1111
-3 1114 1270 1113
-3 760 1511 2369
-3 1115 1268 573
-3 1288 917 1116
-3 1276 1115 1290
-3 919 917 1118
-3 917 1288 1118
-3 1116 917 1117
-3 1118 928 919
-3 917 923 1117
-3 1532 927 1119
-3 1290 1115 932
-3 1117 923 938
-3 1121 1119 927
-3 1120 1290 932
-3 1122 1119 1121
-3 1122 1123 1119
-3 1123 1124 1292
-3 1119 1123 1292
-3 1124 942 1292
-3 935 934 1125
-3 935 1125 936
-3 1297 1120 932
-3 928 1118 789
-3 1126 1122 1121
-3 1123 1122 1127
-3 1127 1122 1126
-3 941 1124 1127
-3 1124 1123 1127
-3 942 1124 941
-3 942 1128 1292
-3 1129 1130 1131
-3 1131 1130 1132
-3 934 943 1125
-3 936 1125 943
-3 1133 1134 1135
-3 1135 1136 1133
-3 1297 932 1141
-3 1118 1311 789
-3 1127 1126 578
-3 941 1127 578
-3 1129 805 1132
-3 1130 1129 1132
-3 1133 1315 1134
-3 1136 1315 1133
-3 948 947 1137
-3 1298 1141 1318
-3 1311 946 789
-3 947 953 1137
-3 423 893 470
-3 1142 1318 1141
-3 1143 1318 1142
-3 946 1311 599
-3 956 955 1138
-3 1138 1139 956
-3 956 1140 812
-3 1139 1140 956
-3 959 958 1144
-3 959 1144 960
-3 1138 962 1145
-3 955 962 1138
-3 964 1145 963
-3 964 1139 1145
-3 1139 1138 1145
-3 1140 1139 964
-3 1142 1141 1146
-3 1147 1142 1146
-3 1143 1142 1147
-3 1148 1143 1147
-3 1323 1148 1353
-3 962 965 1145
-3 963 1145 965
-3 974 973 1577
-3 1577 1150 974
-3 664 1151 1141
-3 1151 1146 1141
-3 1147 1146 1151
-3 1152 1147 1151
-3 1148 1147 1152
-3 1153 1148 1152
-3 1160 1148 1153
-3 1353 1148 1160
-3 1149 1343 1154
-3 974 1156 973
-3 974 1157 1156
-3 1157 1150 1158
-3 1157 974 1150
-3 1153 1152 1151
-3 1160 1153 1159
-3 1354 1353 1160
-3 1365 1154 1343
-3 1166 1382 981
-3 664 996 1151
-3 1153 1151 996
-3 1159 1153 996
-3 996 1160 1159
-3 1161 1160 996
-3 1354 1160 1161
-3 1354 1161 1162
-3 1005 1162 1161
-3 1373 1162 1163
-3 1168 1163 1167
-3 1359 1168 1175
-3 1377 1164 1169
-3 707 930 5643
-3 995 1165 1002
-3 1171 1172 1170
-3 1167 1163 1173
-3 1168 1167 1174
-3 1174 1167 1173
-3 1183 1168 1174
-3 1175 1168 1183
-3 1184 1175 1183
-3 1164 1176 1177
-3 1169 1164 1178
-3 1178 1164 1177
-3 1186 1169 1178
-3 1187 1169 1186
-3 1172 1180 1170
-3 1173 1163 1021
-3 1021 1174 1173
-3 1185 1016 1176
-3 1177 1176 1016
-3 1017 1177 1016
-3 1178 1177 1017
-3 1017 1186 1178
-3 1179 1011 1020
-3 1012 1179 1020
-3 1193 1182 1181
-3 1409 1194 1181
-3 1194 1193 1181
-3 1021 1183 1174
-3 1184 1183 1195
-3 1195 1183 1021
-3 1016 1185 1022
-3 1022 1185 1415
-3 1023 1186 1017
-3 1187 1186 1023
-3 1188 1025 1196
-3 1019 1196 1026
-3 1019 1189 1196
-3 1189 1188 1196
-3 1028 1197 1029
-3 1190 1198 1191
-3 1192 1198 1190
-3 1193 1205 1182
-3 1031 1205 1193
-3 1031 1193 1194
-3 1194 1409 1199
-3 1194 1199 1031
-3 1031 1199 1032
-3 524 1195 1021
-3 524 1413 1195
-3 1200 1022 1201
-3 1201 1022 1415
-3 1028 1037 1197
-3 1029 1197 1037
-3 1202 1203 889
-3 1038 1203 1204
-3 1038 889 1203
-3 1206 1040 1032
-3 1206 1032 1199
-3 524 1041 1413
-3 1207 1413 1208
-3 1208 1413 1041
-3 1201 1207 1208
-3 1201 1208 1200
-3 1200 1208 1209
-3 1200 1209 1022
-3 1205 895 1427
-3 1206 1427 1040
-3 1210 1208 1041
-3 1209 1208 1210
-3 1022 1209 1210
-3 1041 1042 1211
-3 1041 1211 1210
-3 1210 1211 1046
-3 1433 892 899
-3 1044 1043 1212
-3 1212 1213 1044
-3 1044 1214 1045
-3 1213 1214 1044
-3 1045 1211 1042
-3 1045 1214 1211
-3 1046 1211 1048
-3 1047 1212 1043
-3 1047 1215 1212
-3 1215 1213 1212
-3 1214 1213 1216
-3 1216 1213 1215
-3 1211 1214 1216
-3 1216 1215 1218
-3 1211 1216 1219
-3 1219 1216 1218
-3 1048 1211 1220
-3 1211 1219 1220
-3 1049 1433 1050
-3 1217 1221 1051
-3 1051 1221 1225
-3 1215 903 1223
-3 1218 1215 1223
-3 1219 1218 1223
-3 1220 1219 1224
-3 1224 1219 1223
-3 1893 1433 1049
-3 1893 1049 1224
-3 1224 1049 1220
-3 902 707 5643
-3 1217 1632 1221
-3 1221 1632 1225
-3 1893 1224 1223
-3 1632 1052 1225
-3 1225 1052 1222
-3 902 5643 1226
-3 1229 1227 1230
-3 1234 1229 1230
-3 1227 1231 1230
-3 1234 1230 1232
-3 1232 1230 1231
-3 1232 1231 1233
-3 1234 1232 1233
-3 1233 1231 1235
-3 1234 1233 1236
-3 1236 1233 1235
-3 1235 1231 1469
-3 1054 1469 1053
-3 1054 1236 1469
-3 1236 1235 1469
-3 1054 1053 1234
-3 1054 1234 1236
-3 1053 1469 1060
-3 1234 1053 1058
-3 1058 1062 1234
-3 1238 1060 1469
-3 1062 1064 1234
-3 1234 1064 1663
-3 1064 1237 1663
-3 1238 1237 1064
-3 1237 1065 1066
-3 1237 1066 1663
-3 1066 1072 1663
-3 1241 1240 1239
-3 1242 1239 1240
-3 1241 1242 1240
-3 1472 1242 1241
-3 1470 1472 1241
-3 1072 1076 1079
-3 1242 1472 1077
-3 1077 1472 1081
-3 1076 1078 1079
-3 1472 1473 1082
-3 1473 1083 1082
-3 1475 1083 1473
-3 1082 1084 1243
-3 1243 1084 1244
-3 1086 1083 1475
-3 1476 1086 1475
-3 1086 1476 1087
-3 1084 1088 1244
-3 1089 1087 1476
-3 1244 1088 1091
-3 1089 1476 1246
-3 1249 1089 1246
-3 1089 1249 1091
-3 1245 1247 1248
-3 1245 1248 1092
-3 1245 1092 1503
-3 1091 1249 1250
-3 1091 1250 1244
-3 1248 1094 1092
-3 1096 1246 1489
-3 1249 1246 1096
-3 1251 1249 1096
-3 1251 1250 1249
-3 1251 1244 1250
-3 1262 1244 1251
-3 1099 1252 1098
-3 1099 1487 1252
-3 1095 1503 1092
-3 1102 1096 1489
-3 1499 1102 1489
-3 1098 1252 1253
-3 1967 1487 1101
-3 1487 1099 1101
-3 1098 1253 1504
-3 1255 1254 1257
-3 1257 1254 1256
-3 1258 1500 1255
-3 1257 1258 1255
-3 1505 1102 1499
-3 1103 534 1502
-3 1256 1502 534
-3 1258 1257 1256
-3 1259 1503 1095
-3 1505 1508 1102
-3 1094 423 1093
-3 1251 1102 1262
-3 1967 1101 764
-3 1102 1104 1262
-3 1260 1259 1263
-3 1506 1259 1260
-3 1093 423 756
-3 1508 1261 1106
-3 1102 1508 1106
-3 1104 1107 1262
-3 1263 1112 1264
-3 1260 1263 1265
-3 1265 1263 1264
-3 1260 1512 1506
-3 1261 1108 1106
-3 1109 1262 1107
-3 1264 1112 1266
-3 1265 1264 1267
-3 1267 1264 1266
-3 1260 1265 1267
-3 1273 1260 1267
-3 1512 1260 1273
-3 1109 1110 1262
-3 1268 1266 1112
-3 1268 1267 1266
-3 1273 1267 1268
-3 1114 1108 1269
-3 1262 1110 1271
-3 1110 1113 1271
-3 1103 1511 760
-3 1272 1512 1273
-3 1270 1271 1113
-3 1114 1269 1275
-3 1114 1275 1271
-3 1114 1271 1270
-3 1274 1517 1518
-3 1517 1274 1269
-3 1275 1269 1274
-3 1272 1273 1278
-3 1276 1272 1278
-3 1277 1275 1274
-3 1279 1280 1277
-3 1115 1273 1268
-3 1115 1278 1273
-3 1284 1279 1281
-3 1282 1280 1279
-3 1284 1282 1279
-3 1115 1276 1278
-3 1284 1281 1283
-3 1286 1282 1284
-3 1285 1283 1281
-3 1284 1283 1286
-3 1286 1283 1285
-3 1287 1285 1281
-3 1287 1286 1285
-3 1289 1276 1290
-3 1525 1288 1287
-3 918 1740 764
-3 1287 1288 1116
-3 918 927 1740
-3 927 1531 1740
-3 1525 1533 1118
-3 1525 1118 1288
-3 1287 1116 1117
-3 1531 927 1532
-3 2369 1301 760
-3 1773 1289 1291
-3 1292 1532 1119
-3 1293 1290 1120
-3 1289 1290 1293
-3 1291 1289 1293
-3 1773 1291 1300
-3 1300 1291 1294
-3 1533 1296 1118
-3 1120 1297 1293
-3 1291 1293 1298
-3 1298 1293 1297
-3 1294 1291 1299
-3 1299 1291 1298
-3 1300 1294 1302
-3 1302 1294 1299
-3 1296 1295 1535
-3 1118 1296 1535
-3 1287 1117 814
-3 1303 1300 1302
-3 1304 1300 1303
-3 1300 1304 1305
-3 1118 1535 1311
-3 1129 1301 805
-3 1131 1301 1129
-3 1132 1301 1131
-3 1135 1134 1538
-3 1135 1538 1136
-3 1298 1297 1141
-3 1302 1299 1308
-3 1308 1299 1298
-3 1303 1302 1309
-3 1309 1302 1308
-3 1304 1303 1309
-3 1305 1304 1310
-3 1310 1304 1309
-3 1312 1311 1535
-3 938 814 1117
-3 1307 1313 1306
-3 1313 1307 1314
-3 1315 1541 1134
-3 1538 1134 1541
-3 1315 1136 1316
-3 1316 1136 1538
-3 1538 1317 1316
-3 1318 1308 1298
-3 1309 1308 1318
-3 1321 1541 1315
-3 1316 1319 1315
-3 1319 1316 1317
-3 1320 1309 1318
-3 1310 1309 1320
-3 1801 599 1311
-3 1321 1315 1322
-3 1315 1319 1322
-3 1322 1319 1317
-3 1318 1143 1320
-3 1310 1320 1323
-3 1323 1320 1143
-3 1324 1310 1323
-3 599 1801 1154
-3 1323 1143 1148
-3 1325 1324 1323
-3 1326 1324 1325
-3 1329 1801 1328
-3 1154 1801 1149
-3 1149 1801 1329
-3 1330 1331 1332
-3 1330 1333 1334
-3 1332 1333 1330
-3 1325 1323 1353
-3 1326 1325 1336
-3 1336 1325 1335
-3 1324 1326 1337
-3 1337 1326 1336
-3 1338 1324 1337
-3 1542 1324 1338
-3 1342 1327 1362
-3 1364 1327 1342
-3 1328 1327 1364
-3 1329 1328 1343
-3 1149 1329 1343
-3 1344 1331 1330
-3 1345 1331 1344
-3 1334 1346 1330
-3 1346 1344 1330
-3 1347 1577 973
-3 1150 1348 1349
-3 1150 1577 1348
-3 1348 1350 1349
-3 1335 1325 1353
-3 1336 1335 1353
-3 1337 1336 1354
-3 1354 1336 1353
-3 1338 1337 1354
-3 1355 1338 1354
-3 1566 1338 1355
-3 1566 1355 1356
-3 1357 1339 1340
-3 1341 1339 1358
-3 1358 1339 1357
-3 1341 1358 1561
-3 1563 1359 1360
-3 1342 1362 1363
-3 1364 1342 1363
-3 1328 1364 1365
-3 1343 1328 1365
-3 1346 1345 1344
-3 1156 1157 1367
-3 1156 1367 1347
-3 1156 1347 973
-3 1367 1157 1158
-3 1367 1158 1368
-3 1349 1158 1150
-3 1349 1369 1158
-3 1369 1368 1158
-3 1350 1369 1349
-3 1351 1369 1350
-3 1351 1352 1370
-3 1371 1370 1352
-3 1355 1354 1162
-3 1372 1356 1355
-3 1162 1372 1355
-3 1374 1373 1357
-3 1358 1357 1163
-3 1163 1357 1373
-3 1561 1358 1168
-3 1168 1358 1163
-3 1562 1561 1168
-3 1359 1562 1168
-3 1360 1359 1375
-3 1362 1361 1377
-3 1377 1361 1376
-3 1363 1362 1377
-3 1169 1363 1377
-3 1365 1363 1169
-3 1364 1363 1365
-3 1382 1378 1366
-3 981 1383 1166
-3 1384 1351 1370
-3 1371 1379 1370
-3 1379 1384 1370
-3 1379 1371 1380
-3 1162 1381 1372
-3 1162 1373 1381
-3 1374 1381 1373
-3 1359 1175 1375
-3 1377 1376 1164
-3 1166 1383 1382
-3 1380 1384 1379
-3 1171 1170 1385
-3 1171 1385 1172
-3 1175 1388 1389
-3 1609 1175 1389
-3 1164 1389 1388
-3 1176 1164 1388
-3 1170 1180 1385
-3 1172 1385 1180
-3 1390 1392 1393
-3 1392 1613 1393
-3 1181 1182 1394
-3 1386 1395 1387
-3 1396 1398 1399
-3 1397 1398 1396
-3 1175 1184 1413
-3 1388 1175 1400
-3 1400 1175 1413
-3 1176 1400 1185
-3 1388 1400 1176
-3 1401 1190 1191
-3 1401 1402 1190
-3 1192 1190 1403
-3 1403 1190 1402
-3 1391 1403 1402
-3 1391 1390 1403
-3 1390 1404 1403
-3 1404 1390 1393
-3 1613 1405 1393
-3 1405 1406 1407
-3 1613 1406 1405
-3 1394 1182 1408
-3 1181 1394 1409
-3 1394 1408 1409
-3 1396 1399 1410
-3 1411 1410 1399
-3 1411 1399 1412
-3 1184 1195 1413
-3 1414 1400 1413
-3 1414 1185 1400
-3 1414 1415 1185
-3 1191 1416 1401
-3 1191 1198 1416
-3 1403 1416 1192
-3 1192 1416 1198
-3 1404 1416 1403
-3 1417 1405 1407
-3 1182 1205 1408
-3 1205 1419 1408
-3 1419 1409 1408
-3 1409 1419 1199
-3 1420 1396 1410
-3 1411 1421 1410
-3 1421 1411 1412
-3 1414 1413 1430
-3 1415 1629 1201
-3 1422 1423 1424
-3 1424 1425 1422
-3 1203 1202 1418
-3 1202 1631 1418
-3 1418 1426 1203
-3 1418 1625 1426
-3 1203 1426 1204
-3 1205 1427 1419
-3 1427 1199 1419
-3 1199 1427 1206
-3 1410 1428 1420
-3 1428 1410 1429
-3 1410 1421 1429
-3 1429 1421 1432
-3 1207 1430 1413
-3 1201 1629 1207
-3 1629 1430 1207
-3 1433 814 892
-3 1422 1431 1423
-3 1425 1431 1422
-3 1426 1631 1202
-3 1204 1426 1202
-3 1429 1432 1428
-3 1632 1217 893
-3 1226 2516 2917
-3 1052 1632 1633
-3 1435 1436 1437
-3 1434 1435 1437
-3 1435 1434 1438
-3 1436 1435 1438
-3 1437 1436 1439
-3 1439 1436 1438
-3 1434 1638 1438
-3 1441 1437 1439
-3 1445 1438 1638
-3 1439 1438 1445
-3 1440 1441 1439
-3 1638 1639 1445
-3 1441 1440 1442
-3 1448 1441 1444
-3 1444 1441 1442
-3 1440 1439 1445
-3 1442 1440 1445
-3 1444 1442 1443
-3 1443 1442 1446
-3 1446 1442 1445
-3 1444 1443 1447
-3 1447 1443 1446
-3 1448 1444 1447
-3 1446 1445 1645
-3 1449 1447 1446
-3 1451 1448 1447
-3 1449 1451 1447
-3 1645 1647 1446
-3 1450 1446 1647
-3 1449 1446 1450
-3 1451 1449 1450
-3 1647 1452 1450
-3 1451 1450 1453
-3 1453 1450 1452
-3 1453 1454 1451
-3 1452 1648 1455
-3 1452 1455 1453
-3 1456 1454 1453
-3 1456 1453 1455
-3 1648 1457 1455
-3 1455 1457 1456
-3 1457 1458 1456
-3 1457 1654 1458
-3 1654 1459 1458
-3 1653 1654 1460
-3 1461 1460 1654
-3 1461 1462 1460
-3 1461 1463 1462
-3 1462 1463 1460
-3 1464 1460 1463
-3 1463 1466 1464
-3 1465 1466 1463
-3 1659 1467 1465
-3 1465 1467 1466
-3 1228 1227 1468
-3 1228 1468 1466
-3 1228 1466 1467
-3 1468 1227 1229
-3 1467 1659 1228
-3 1228 1659 1227
-3 1234 1468 1229
-3 1227 1659 1231
-3 1234 4051 1468
-3 1469 1231 1662
-3 1238 1469 1664
-3 1238 1664 1239
-3 1664 1666 1239
-3 1239 1666 1241
-3 1241 1666 1470
-3 1072 1079 1663
-3 1471 1470 1666
-3 1663 1079 1243
-3 1471 1670 1470
-3 1470 1670 1472
-3 1673 1472 1670
-3 1473 1472 1673
-3 1475 1473 1474
-3 1243 1244 1663
-3 1674 1474 1473
-3 1474 1674 1475
-3 1475 1674 1476
-3 1476 1477 1246
-3 1476 1480 1477
-3 1480 1481 1477
-3 1477 1481 1246
-3 1486 1482 1478
-3 1483 1478 1482
-3 1247 1493 1248
-3 1247 1479 1493
-3 1245 1479 1247
-3 1481 1480 1484
-3 1481 1484 1246
-3 1485 1482 1486
-3 1483 1482 1487
-3 1487 1482 1485
-3 1487 1967 1483
-3 1248 1493 1094
-3 1245 1503 1694
-3 1489 1480 1488
-3 1246 1484 1489
-3 1484 1480 1489
-3 1252 1485 1486
-3 1252 1486 1504
-3 1487 1485 1252
-3 1490 1491 1492
-3 1494 1490 1492
-3 1492 1491 1693
-3 1697 1094 1493
-3 1701 1694 1503
-3 1252 1504 1253
-3 1490 1494 1496
-3 1496 1494 1495
-3 1491 1490 1497
-3 1497 1490 1496
-3 1497 1693 1491
-3 1498 1499 1488
-3 1488 1499 1489
-3 1256 1254 1502
-3 1502 1255 1494
-3 1502 1254 1255
-3 1500 1494 1255
-3 1500 1495 1494
-3 1496 1495 1501
-3 1501 1495 1500
-3 1501 1497 1496
-3 1705 1499 1498
-3 1500 1258 1501
-3 2278 1497 1501
-3 1705 1712 1499
-3 1499 1712 1505
-3 1258 2278 1501
-3 1697 423 1094
-3 1503 1259 1506
-3 1258 4237 2278
-3 1712 1507 1261
-3 1505 1712 1261
-3 1508 1505 1261
-3 1512 1503 1506
-3 1719 1503 1512
-3 2686 1967 764
-3 1103 1978 1511
-3 1507 1509 1510
-3 1261 1507 1513
-3 1513 1507 1510
-3 1108 1261 1513
-3 1514 1512 1515
-3 1513 1510 1721
-3 1108 1513 1269
-3 1262 1271 1519
-3 1511 1724 2369
-3 1272 1515 1512
-3 1513 1721 1269
-3 1272 1276 1515
-3 1721 1516 1518
-3 1269 1721 1517
-3 1517 1721 1518
-3 1514 1515 1276
-3 1271 1275 1519
-3 1518 1277 1274
-3 1277 1519 1275
-3 1731 1514 1276
-3 1518 1516 1520
-3 1279 1518 1520
-3 1277 1518 1279
-3 1277 1280 1519
-3 1519 1280 1524
-3 2686 764 1740
-3 1279 1520 1281
-3 1280 1282 1524
-3 1289 1731 1276
-3 1520 1521 1522
-3 1281 1520 1523
-3 1282 1286 1524
-3 1521 1735 1522
-3 1523 1520 1522
-3 4845 930 762
-3 1523 1522 1525
-3 1281 1523 1287
-3 1287 1523 1525
-3 1287 1524 1286
-3 1773 2021 1289
-3 1526 1529 1528
-3 1527 1530 1526
-3 1530 1529 1526
-3 1522 2034 1525
-3 1530 1528 1529
-3 1533 1525 2034
-3 1292 1531 1532
-3 1128 1531 1292
-3 1753 1300 1534
-3 1533 1776 1535
-3 1296 1533 1295
-3 1301 1128 805
-3 1774 1534 1779
-3 1776 1788 1535
-3 1295 1533 1535
-3 1305 1534 1300
-3 1310 1534 1305
-3 1779 1534 1310
-3 1542 1779 1310
-3 1535 1788 1312
-3 1797 1536 1306
-3 1307 1306 1536
-3 1537 1307 1536
-3 1789 1542 1790
-3 1306 1313 1806
-3 1797 1306 1806
-3 1307 1537 1314
-3 1537 1540 1314
-3 1542 1310 1324
-3 1539 1790 1542
-3 1312 1801 1311
-3 1287 814 4422
-3 1313 1810 1806
-3 1313 1540 1810
-3 1314 1540 1313
-3 1538 1811 1317
-3 1783 1539 1542
-3 1543 1783 1542
-3 1545 1328 1808
-3 1799 1545 1808
-3 1317 1811 1322
-3 1811 1546 1322
-3 1543 1542 1547
-3 1548 1543 1547
-3 1560 1549 1544
-3 1562 1544 1549
-3 1563 1544 1562
-3 1550 1544 1563
-3 1545 1550 1327
-3 1328 1545 1327
-3 1551 1552 1553
-3 1551 1553 1554
-3 1553 1555 1554
-3 1322 1546 1321
-3 1547 1542 1556
-3 1557 1547 1556
-3 1548 1547 1558
-3 1558 1547 1557
-3 1339 1548 1558
-3 1815 1548 1339
-3 1341 1815 1339
-3 1341 1559 1560
-3 1815 1341 1560
-3 1560 1559 1549
-3 1549 1559 1561
-3 1562 1549 1561
-3 1327 1550 1563
-3 1332 1823 1564
-3 1331 1823 1332
-3 1552 1551 1333
-3 1552 1333 1564
-3 1564 1333 1332
-3 1334 1333 1551
-3 1334 1551 1565
-3 1565 1551 1554
-3 1565 1554 1555
-3 1348 1817 1351
-3 1817 1578 1351
-3 1556 1542 1338
-3 1566 1556 1338
-3 1557 1556 1566
-3 1566 1558 1557
-3 1339 1558 1567
-3 1567 1558 1566
-3 1339 1567 1340
-3 1559 1341 1561
-3 1359 1563 1562
-3 1327 1563 1362
-3 1569 1570 1568
-3 1571 1823 1345
-3 1823 1331 1345
-3 1565 1572 1573
-3 1565 1573 1334
-3 1334 1573 1346
-3 1555 1572 1565
-3 1574 1575 1366
-3 1366 1575 972
-3 1575 981 972
-3 1576 1577 1347
-3 1350 1348 1351
-3 1351 1578 1352
-3 1356 1579 1566
-3 1579 1567 1566
-3 1340 1579 1357
-3 1567 1579 1340
-3 1361 1563 1360
-3 1362 1563 1361
-3 1580 1569 1568
-3 1847 1569 1580
-3 1581 1568 1570
-3 1580 1568 1581
-3 1571 1345 1830
-3 1345 1346 1830
-3 1830 1346 1573
-3 1850 981 1575
-3 1347 1367 1576
-3 1367 1368 1576
-3 1369 1582 1368
-3 1368 1582 1576
-3 1582 1369 1351
-3 1352 1578 1834
-3 1371 1352 1834
-3 1583 1585 1586
-3 1584 1585 1583
-3 1579 1587 1841
-3 1579 1356 1587
-3 1356 1372 1587
-3 1841 1357 1579
-3 1841 1595 1357
-3 1595 1374 1357
-3 1360 1588 1589
-3 1375 1588 1360
-3 1361 1360 1590
-3 1360 1589 1590
-3 1590 1376 1361
-3 1581 1847 1580
-3 1383 1850 1597
-3 981 1850 1383
-3 1351 1384 1582
-3 1591 1380 1834
-3 1380 1371 1834
-3 1583 1592 1593
-3 1583 1586 1592
-3 1592 1586 1585
-3 1594 1372 1381
-3 1594 1587 1372
-3 1595 1594 1374
-3 1595 1596 1594
-3 1594 1381 1374
-3 1375 1175 1588
-3 1588 1175 1874
-3 1376 1590 1164
-3 1383 1597 1382
-3 1382 1597 1378
-3 1380 1591 1384
-3 1598 1593 1592
-3 1870 1599 1592
-3 1599 1598 1592
-3 1600 1587 1594
-3 1596 1601 1594
-3 1601 1600 1594
-3 1602 1596 1595
-3 1602 1601 1596
-3 1874 1175 1609
-3 1604 1593 1598
-3 1614 1593 1604
-3 1386 1387 1604
-3 1386 1604 1599
-3 1599 1604 1598
-3 1599 1870 1386
-3 1870 1605 1386
-3 1600 1601 1606
-3 1602 1607 1601
-3 1607 1606 1601
-3 1880 1608 1602
-3 1608 1607 1602
-3 1610 1611 1609
-3 1610 1609 1389
-3 1389 1612 1610
-3 1389 1164 1612
-3 1164 1590 1612
-3 1603 1392 1391
-3 1391 1392 1390
-3 1392 1619 1613
-3 1392 1603 1619
-3 1387 1614 1604
-3 1387 1395 1614
-3 1395 1876 1614
-3 1605 1395 1386
-3 1876 1395 1605
-3 1397 1606 1607
-3 1398 1397 1607
-3 1608 1398 1607
-3 1608 1880 1398
-3 1398 1880 1399
-3 1615 1611 1610
-3 1616 1611 1615
-3 1617 1610 1612
-3 1615 1610 1617
-3 1402 1401 1618
-3 1402 1618 1391
-3 1613 1619 1406
-3 1619 1407 1406
-3 1396 1620 1397
-3 1399 1880 1412
-3 1880 1621 1412
-3 1414 1616 1615
-3 1415 1622 1623
-3 1414 1622 1415
-3 1414 1617 1622
-3 1414 1615 1617
-3 1401 1624 1618
-3 1401 1416 1624
-3 1416 1404 1624
-3 1393 1624 1404
-3 1405 1624 1393
-3 1405 1886 1624
-3 1619 1417 1407
-3 1619 1886 1417
-3 1886 1405 1417
-3 1625 1418 1626
-3 1418 1887 1626
-3 1627 1620 1420
-3 1620 1396 1420
-3 1627 1621 1888
-3 1421 1412 1621
-3 1628 1616 1430
-3 1616 1414 1430
-3 1623 1629 1415
-3 1623 1622 1629
-3 1424 1423 1630
-3 1424 1630 1425
-3 1625 1892 1631
-3 1625 1631 1426
-3 1626 1892 1625
-3 1420 1428 1627
-3 1428 1432 1627
-3 1432 1621 1627
-3 1621 1432 1421
-3 1628 1430 1891
-3 1430 1629 1891
-3 1423 1431 1630
-3 1425 1630 1431
-3 814 1433 1893
-3 1634 1636 1635
-3 1434 1437 1635
-3 1636 1637 1635
-3 1434 1635 1637
-3 1637 1903 1434
-3 1441 1635 1437
-3 1434 1903 1641
-3 1434 1641 1638
-3 1448 1635 1441
-3 1640 1638 1641
-3 1639 1638 1642
-3 1642 1638 1640
-3 1641 1642 1640
-3 1639 1642 1643
-3 1445 1639 1643
-3 1445 1643 1645
-3 1645 1643 1644
-3 1644 1643 1908
-3 1908 1649 1644
-3 1644 1649 1645
-3 1651 1448 1454
-3 1448 1451 1454
-3 1646 1645 1649
-3 1647 1645 1646
-3 1647 1648 1452
-3 1454 1456 1651
-3 1647 1646 1649
-3 1912 1648 1647
-3 1648 1909 1650
-3 1651 1456 1458
-3 1912 1647 1649
-3 1913 1650 1909
-3 1648 1650 1652
-3 1648 1652 1457
-3 1913 1914 1650
-3 1650 1914 1652
-3 1653 1651 1459
-3 1651 1458 1459
-3 1457 1652 1654
-3 1654 1653 1459
-3 1653 1460 1656
-3 1654 1652 1655
-3 1654 1655 1461
-3 1655 1652 1914
-3 1464 1656 1460
-3 1461 1655 1463
-3 1466 1656 1464
-3 1657 1658 1655
-3 1655 1658 1463
-3 1463 1658 1465
-3 1466 1468 1656
-3 1922 1658 1657
-3 1465 1658 1659
-3 1658 1922 1660
-3 1658 1660 1659
-3 1231 1660 1661
-3 1660 1231 1659
-3 1662 1231 1661
-3 4051 1234 1663
-3 1666 1664 1665
-3 1666 1665 1667
-3 1667 1665 1668
-3 1669 1666 1667
-3 1471 1666 1669
-3 1669 1667 1668
-3 1471 1669 1670
-3 1669 1668 1670
-3 1670 1668 1671
-3 1670 1671 1673
-3 1673 1671 1672
-3 1672 1951 1673
-3 1673 1951 1674
-3 1673 1674 1473
-3 1676 1677 1947
-3 1951 1954 1675
-3 1674 1951 1675
-3 1675 1954 1476
-3 1675 1476 1674
-3 1476 1954 1678
-3 1677 1676 1956
-3 1677 1956 1478
-3 1681 1679 1680
-3 1245 1681 1479
-3 1476 1678 1480
-3 1480 1678 1685
-3 1682 1677 1478
-3 1682 1955 1677
-3 1956 1486 1478
-3 1478 1483 1682
-3 1483 1967 1955
-3 1483 1955 1682
-3 1686 1687 1683
-3 1683 1687 1688
-3 1684 1683 1689
-3 1689 1683 1688
-3 1479 1681 1493
-3 1245 1694 1963
-3 1685 1965 1488
-3 1480 1685 1488
-3 1687 1686 1691
-3 1691 1686 1690
-3 1688 1687 1692
-3 1692 1687 1691
-3 1692 1689 1688
-3 1486 1956 1504
-3 2279 1494 1686
-3 1492 1686 1494
-3 1690 1686 1492
-3 1693 1690 1492
-3 1693 1691 1690
-3 1689 1692 1693
-3 1693 1692 1691
-3 1493 1681 1697
-3 1703 1695 1965
-3 1488 1965 1696
-3 1696 1965 1695
-3 1488 1696 1498
-3 1494 2279 1502
-3 1693 1497 2278
-3 1689 1693 2278
-3 1696 1695 1698
-3 1698 1695 1704
-3 1498 1696 1699
-3 1699 1696 1698
-3 1498 1699 1700
-3 1956 3036 1504
-3 1707 1694 1701
-3 1702 1694 1707
-3 1709 1694 1702
-3 1704 1695 1703
-3 1969 1698 1704
-3 1699 1698 1969
-3 1970 1699 1969
-3 1970 1705 1699
-3 1699 1705 1700
-3 1700 1705 1498
-3 1701 1503 1706
-3 1707 1701 1706
-3 1702 1707 1708
-3 1709 1702 1711
-3 1711 1702 1708
-3 1703 1710 1704
-3 1710 1969 1704
-3 1705 1970 1971
-3 1708 1707 1711
-3 1711 1707 1706
-3 1972 1709 1711
-3 1705 1971 1712
-3 1503 1711 1706
-3 1972 1711 1713
-3 1968 1985 1710
-3 1712 1985 1507
-3 1712 1710 1985
-3 1719 1711 1503
-3 1714 1711 1719
-3 1713 1711 1714
-3 1972 1713 1714
-3 1983 1972 1714
-3 1504 3036 762
-3 3634 1978 1103
-3 1719 1512 1514
-3 1983 1714 1719
-3 1985 1509 1507
-3 1509 1985 1715
-3 1718 1715 1717
-3 1715 1718 1509
-3 1509 1718 1510
-3 4845 762 3036
-3 1724 1511 1716
-3 1983 1719 1725
-3 1715 2000 1717
-3 1718 1717 1720
-3 1721 1718 1720
-3 1718 1721 1510
-3 1722 1724 1716
-3 2000 1730 1717
-3 1720 1717 1730
-3 1721 1720 1726
-3 1722 1723 1724
-3 1719 1514 1727
-3 1725 1719 1727
-3 1728 1725 1727
-3 1516 1726 1720
-3 1721 1726 1516
-3 1729 1728 1731
-3 1731 1728 1727
-3 1516 1720 1521
-3 1720 1730 1521
-3 1514 1731 1727
-3 2008 1729 1731
-3 2008 1731 1732
-3 1733 1735 1730
-3 1521 1730 1735
-3 1516 1521 1520
-3 1733 1738 1734
-3 1735 1733 1734
-3 1289 1732 1731
-3 2021 1732 1289
-3 1738 1736 1737
-3 1734 1738 1739
-3 1735 1734 1739
-3 1735 1739 1522
-3 2023 1746 1736
-3 1741 1736 1746
-3 1737 1736 1741
-3 1738 1737 1742
-3 1742 1737 1741
-3 1739 1738 1743
-3 1743 1738 1742
-3 2034 1739 1743
-3 1522 1739 2034
-3 1744 2028 1526
-3 2028 1745 1526
-3 1527 1526 1745
-3 1749 2021 1753
-3 1751 1746 2023
-3 1746 2032 1742
-3 1746 1742 1741
-3 1743 1742 2032
-3 1528 2028 1744
-3 1528 1747 2028
-3 1526 1528 1744
-3 1748 1530 1745
-3 1745 1530 1527
-3 1746 1751 1752
-3 1530 1747 1528
-3 1748 1747 1530
-3 1753 2021 1773
-3 1749 1753 1754
-3 1750 2031 1755
-3 1751 1750 1756
-3 1756 1750 1755
-3 1757 1752 1756
-3 1756 1752 1751
-3 1531 1128 3731
-3 1759 1760 1761
-3 1759 1763 1762
-3 1761 1763 1759
-3 1753 1773 1300
-3 1754 1753 1764
-3 2045 1754 1765
-3 1765 1754 1764
-3 1755 2031 1768
-3 1768 2031 1767
-3 1756 1755 1769
-3 1769 1755 1768
-3 1770 1757 1756
-3 1769 1770 1756
-3 2034 1758 1533
-3 1301 3731 1128
-3 1759 1771 1760
-3 1762 1771 1759
-3 1772 1771 1762
-3 1763 1772 1762
-3 1764 1753 1774
-3 1765 1764 1774
-3 1779 1765 1774
-3 2025 1765 1779
-3 2046 2025 1779
-3 1766 1781 1775
-3 1788 1766 1775
-3 1767 1766 1788
-3 1768 1767 1776
-3 1776 1767 1788
-3 1769 1768 1777
-3 1777 1768 1776
-3 1770 1769 1778
-3 1778 1769 1777
-3 1533 1770 1778
-3 4845 5643 930
-3 1753 1534 1774
-3 1775 1781 1782
-3 1788 1775 1782
-3 1778 1777 1776
-3 1533 1778 1776
-3 2056 1779 1783
-3 1784 2056 1783
-3 2066 1785 1780
-3 1781 1780 1786
-3 1786 1780 1785
-3 1787 1781 1786
-3 2067 1782 1787
-3 1787 1782 1781
-3 1542 1789 1779
-3 1789 1783 1779
-3 1790 1783 1789
-3 2066 2060 1791
-3 1791 2060 1544
-3 1785 2066 1791
-3 1792 1785 1791
-3 1798 1785 1792
-3 1793 1785 1798
-3 1786 1785 1794
-3 1794 1785 1793
-3 1787 1786 1795
-3 1795 1786 1794
-3 1795 2067 1787
-3 2074 1796 1788
-3 1536 1797 2081
-3 2081 1537 1536
-3 1783 1790 1539
-3 1784 1783 1543
-3 1792 1791 1798
-3 1794 1793 1799
-3 1799 1793 1798
-3 1795 1794 1799
-3 1796 1800 1801
-3 1788 1796 1801
-3 1788 1801 1312
-3 1806 1807 1797
-3 2080 1540 2081
-3 1540 1537 2081
-3 1798 1791 1550
-3 1799 1798 1545
-3 1801 1800 1328
-3 1809 1805 2421
-3 2080 2091 1540
-3 2091 1810 1540
-3 1548 1784 1543
-3 1815 1784 1548
-3 1544 1784 1815
-3 1550 1791 1544
-3 1545 1798 1550
-3 1809 1812 1813
-3 1809 1816 1812
-3 1816 1809 2421
-3 1541 1321 1814
-3 1546 1811 2109
-3 1544 1815 1560
-3 1553 1552 1824
-3 1812 1553 1813
-3 1824 1813 1553
-3 1555 1553 1812
-3 1555 1812 1816
-3 1546 2121 1321
-3 1321 2121 1814
-3 2110 2446 1817
-3 2446 1835 1817
-3 1819 1820 1818
-3 1821 2128 1822
-3 1822 2128 1821
-3 1564 1824 1552
-3 1564 1823 1824
-3 1825 1813 1824
-3 1816 1831 1555
-3 1826 2120 1575
-3 1348 1833 2110
-3 1817 1348 2110
-3 1835 1578 1817
-3 1818 1820 1827
-3 1828 1827 1820
-3 1829 2128 1569
-3 1821 1569 2128
-3 1829 1570 2128
-3 1821 2128 1569
-3 1569 2128 1570
-3 1571 1830 1823
-3 1830 1824 1823
-3 1573 1572 1831
-3 1573 1831 1824
-3 1573 1824 1830
-3 1825 1824 1831
-3 1831 1572 1555
-3 1826 1574 1832
-3 1575 1574 1826
-3 1577 1576 1833
-3 1577 1833 1348
-3 1834 1578 1835
-3 1836 2140 1837
-3 1837 1838 1836
-3 1839 1818 1827
-3 1828 1840 1827
-3 1840 1839 1827
-3 1842 1841 1828
-3 1841 1840 1828
-3 1845 1843 1844
-3 1845 1846 1590
-3 1844 1846 1845
-3 1569 1847 1829
-3 1570 1847 1581
-3 1829 1847 1570
-3 1849 1832 1574
-3 1848 1832 1849
-3 1849 1574 1366
-3 1576 1582 1833
-3 1835 1851 1834
-3 1834 1851 1852
-3 1853 1583 1854
-3 1853 2140 1583
-3 1584 1583 1836
-3 1836 1583 2140
-3 1584 1838 1585
-3 1584 1836 1838
-3 1585 1838 1855
-3 1853 1854 1838
-3 1855 1838 1854
-3 1839 1856 1865
-3 1839 1840 1856
-3 1841 1587 1856
-3 1841 1856 1840
-3 1841 1842 1595
-3 1857 1843 1845
-3 1858 1843 1857
-3 1589 1588 1857
-3 1589 1857 1845
-3 1590 1589 1845
-3 1846 1859 1590
-3 1860 2149 1861
-3 1860 1862 1863
-3 1861 1862 1860
-3 1378 2485 1849
-3 1378 1849 1366
-3 1868 1597 1850
-3 1384 1851 1582
-3 1852 1851 1384
-3 1591 1852 1384
-3 1834 1852 1591
-3 1593 1854 1583
-3 1593 1864 1854
-3 1864 1855 1854
-3 1585 1864 1592
-3 1855 1864 1585
-3 1865 1856 1587
-3 1858 1857 1588
-3 1858 1588 2152
-3 2152 1588 1874
-3 1859 2153 1590
-3 1860 1866 2149
-3 1863 1866 1860
-3 1867 1866 1863
-3 1378 1868 2485
-3 1868 1378 1597
-3 1864 1593 1869
-3 1592 1864 1870
-3 1864 1869 1870
-3 1865 1587 1600
-3 1865 1600 1878
-3 1871 1602 1595
-3 1871 1595 1872
-3 1872 1595 1842
-3 1590 2153 1873
-3 1874 1873 2153
-3 1603 2154 1875
-3 1593 1614 1869
-3 1870 1869 1876
-3 1876 1869 1614
-3 1870 1876 1605
-3 1606 1877 1878
-3 1600 1606 1878
-3 1872 1878 1877
-3 1872 1877 1871
-3 1871 1877 1879
-3 1602 1871 1880
-3 1871 1879 1880
-3 1874 1609 1873
-3 1611 1873 1609
-3 1611 1881 1873
-3 1881 1590 1873
-3 1590 1881 1612
-3 1391 1882 1603
-3 1603 1882 2154
-3 1603 1875 1619
-3 1875 2157 1619
-3 1397 1877 1606
-3 1397 1883 1877
-3 1883 1879 1877
-3 1880 1879 1884
-3 1884 1879 1883
-3 1881 1616 1885
-3 1611 1616 1881
-3 1612 1885 1617
-3 1881 1885 1612
-3 1391 1618 1882
-3 1886 1882 1618
-3 1886 1619 2157
-3 1397 1620 1883
-3 1620 1888 1883
-3 1888 1884 1883
-3 1880 1884 1888
-3 1880 1888 1621
-3 1885 1616 1889
-3 1617 1890 1622
-3 1617 1885 1890
-3 1885 1889 1890
-3 1886 1618 1624
-3 1620 1627 1888
-3 1616 1628 1889
-3 1628 1891 1889
-3 1891 1890 1889
-3 1622 1891 1629
-3 1890 1891 1622
-3 1631 2160 1418
-3 1631 1892 2160
-3 893 2500 1632
-3 1895 1896 1894
-3 1896 1632 1894
-3 1633 1632 1896
-3 1633 1896 2163
-3 2163 2173 1633
-3 1893 1223 2515
-3 1633 2173 1898
-3 1052 1633 1898
-3 2172 1052 1898
-3 1635 1899 1634
-3 1634 1899 1636
-3 1899 1900 1636
-3 1900 1902 1636
-3 1637 1636 1901
-3 1902 1903 1636
-3 1901 1636 1903
-3 1637 1901 1903
-3 1902 1904 1903
-3 1906 1903 1904
-3 1641 1903 1906
-3 1635 1448 2180
-3 1906 1904 1905
-3 1642 1906 1643
-3 1641 1906 1642
-3 1643 1906 1910
-3 1910 1908 1643
-3 1651 2180 1448
-3 1906 1905 1907
-3 1910 1906 1907
-3 2189 1908 1910
-3 1649 1908 1911
-3 1911 1908 2189
-3 1911 1912 1649
-3 1912 1909 1648
-3 1912 1913 1909
-3 2183 1914 1911
-3 1911 1914 1912
-3 1913 1912 1914
-3 1653 2180 1651
-3 1656 2180 1653
-3 1914 1916 1915
-3 1914 1915 1655
-3 4051 2180 1656
-3 1915 1657 1655
-3 1918 2198 1915
-3 1918 1915 1917
-3 1917 1915 1916
-3 1657 1915 2198
-3 2199 1657 2198
-3 1916 1919 1917
-3 1918 1917 1920
-3 1920 1917 1919
-3 1918 1920 1921
-3 1920 2203 1922
-3 1920 1922 1921
-3 1657 1921 1922
-3 1923 1922 2203
-3 1924 1922 1923
-3 1924 1925 1922
-3 1922 1925 1660
-3 1660 1925 1661
-3 1927 1926 1662
-3 1927 1662 1661
-3 1468 4051 1656
-3 2557 2563 1926
-3 1926 2563 1662
-3 1469 1662 2563
-3 1664 1469 2220
-3 2219 1929 1928
-3 1930 1929 2219
-3 1929 1930 1931
-3 1664 2220 1932
-3 1936 1933 1930
-3 1931 1930 1934
-3 1934 1930 1933
-3 1932 1935 1937
-3 1932 1937 1664
-3 1933 1936 1938
-3 1934 1933 1938
-3 2226 1937 1935
-3 1664 1937 1665
-3 2226 1939 1937
-3 1937 1939 1941
-3 1665 1937 1941
-3 1939 1943 1940
-3 1941 1939 1940
-3 1665 1941 1668
-3 1938 1936 1942
-3 1941 1940 1944
-3 1944 1940 1943
-3 1668 1941 1945
-3 1945 1941 1944
-3 1944 1943 1946
-3 1945 1944 1946
-3 1668 1945 2233
-3 2233 1945 1946
-3 1936 3036 1942
-3 1942 3036 1947
-3 1938 1942 1947
-3 2234 2232 1946
-3 2234 1946 1943
-3 2233 2236 1671
-3 2233 1671 1668
-3 1671 2236 2238
-3 1671 2238 1948
-3 1947 3036 1676
-3 1948 2238 1949
-3 1949 2238 1952
-3 1671 1948 1950
-3 1950 1948 1949
-3 1672 1671 1951
-3 1671 1950 1951
-3 1950 1949 1953
-3 1954 1950 1953
-3 1951 1950 1954
-3 1949 1952 2247
-3 1953 1949 2247
-3 2606 1947 1677
-3 1953 1678 1954
-3 1244 1262 1663
-3 2256 1678 1953
-3 2606 1677 1955
-3 2254 1679 1245
-3 1679 1958 1680
-3 1245 1679 1681
-3 2258 1957 1678
-3 2254 1245 1963
-3 2272 2254 1963
-3 1678 1957 1959
-3 1684 2279 1683
-3 1680 1958 1681
-3 2272 1963 1961
-3 2275 1960 2276
-3 1959 2276 1960
-3 1959 1960 1685
-3 1678 1959 1685
-3 1967 1966 1955
-3 1966 2263 1955
-3 1683 2279 1686
-3 1684 1689 2278
-3 1962 1960 2275
-3 1965 1960 1962
-3 1685 1960 1965
-3 1964 1961 1963
-3 2272 1961 1964
-3 1958 1697 1681
-3 1964 1963 1694
-3 2279 1103 1502
-3 1975 2281 1964
-3 1965 1962 1703
-3 1709 1964 1694
-3 1962 2275 1968
-3 1968 2275 1976
-3 1703 1962 1968
-3 2281 1975 1973
-3 1968 1976 1977
-3 1703 1968 1710
-3 1969 1710 1971
-3 1970 1969 1971
-3 1972 1964 1709
-3 1975 1964 1972
-3 1974 1973 1975
-3 1710 1712 1971
-3 1968 1977 1985
-3 1979 1975 1972
-3 1974 1975 1991
-3 1973 1974 1991
-3 2288 1973 1991
-3 2287 2293 1976
-3 1977 1976 1980
-3 1981 1977 1980
-3 1982 1977 1981
-3 1977 1982 1985
-3 1983 1979 1972
-3 1975 1979 1983
-3 1991 1975 1983
-3 1976 2293 1986
-3 1980 1976 1984
-3 1984 1976 1986
-3 1981 1980 1984
-3 1982 1981 1984
-3 2296 2288 1991
-3 1982 1984 1985
-3 1987 1511 1978
-3 2304 1988 2300
-3 1986 2300 1988
-3 2000 1986 1988
-3 1715 1984 2000
-3 1984 1986 2000
-3 1985 1984 1715
-3 1511 1989 1990
-3 1716 1511 1990
-3 1987 1989 1511
-3 1992 2296 1991
-3 1988 2304 1995
-3 1990 1994 1716
-3 1983 1725 1991
-3 1992 1991 2008
-3 2330 2004 2304
-3 1995 2304 2004
-3 2305 2001 1996
-3 1993 2305 1997
-3 1997 2305 1996
-3 1723 1722 1998
-3 1723 1998 1993
-3 1723 1993 1997
-3 1716 1999 1722
-3 1722 1999 1998
-3 1999 1716 1994
-3 1991 1725 1728
-3 2008 1991 1728
-3 1988 1995 2000
-3 1996 2001 2002
-3 2003 1996 2002
-3 1724 2003 2369
-3 1724 1997 2003
-3 1997 1996 2003
-3 1723 1997 1724
-3 1729 2008 1728
-3 2000 1995 2005
-3 2005 1995 2004
-3 2006 2000 2005
-3 2007 2000 2006
-3 1730 2000 2007
-3 2002 2001 2369
-3 2003 2002 2369
-3 2321 1992 2008
-3 2004 2330 2009
-3 2013 2004 2009
-3 2005 2004 2010
-3 2010 2004 2013
-3 2006 2005 2011
-3 2011 2005 2010
-3 2007 2006 2012
-3 2012 2006 2011
-3 1730 2007 2012
-3 2331 2686 1740
-3 2013 2014 2010
-3 2011 2010 2015
-3 2015 2010 2014
-3 2012 2011 1733
-3 1733 2011 2015
-3 1730 2012 1733
-3 2016 2014 2013
-3 2015 2014 1733
-3 1733 2014 2016
-3 2706 2355 2001
-3 2321 2008 2019
-3 2019 2008 1732
-3 2017 2321 2019
-3 2018 1736 2016
-3 1733 1736 1738
-3 1733 2016 1736
-3 2363 2331 1740
-3 2017 2019 2020
-3 2021 2017 2020
-3 2366 2363 1740
-3 2001 2355 2369
-3 2021 2019 1732
-3 2020 2019 2021
-3 2017 2021 1749
-3 2341 2017 2024
-3 2024 2017 1749
-3 2022 2027 2018
-3 2360 2022 2018
-3 2027 2023 2018
-3 2018 2023 1736
-3 1740 2367 2366
-3 2022 2360 2030
-3 2027 2022 2026
-3 1531 2367 1740
-3 1745 2028 2377
-3 2029 1745 2377
-3 2025 2024 1749
-3 2030 2371 2036
-3 2022 2030 2031
-3 2031 2030 2038
-3 2026 2022 2031
-3 1750 2026 2031
-3 1751 2027 1750
-3 2027 2026 1750
-3 2023 2027 1751
-3 2032 2033 1743
-3 2033 2034 1743
-3 2035 1748 2029
-3 2029 1748 1745
-3 2045 2025 1749
-3 1781 2036 2371
-3 2038 2030 2037
-3 1746 1752 2039
-3 2039 2040 1746
-3 1746 2040 2032
-3 2040 2041 2032
-3 2033 2032 2042
-3 2042 2032 2041
-3 2034 2042 1758
-3 2034 2033 2042
-3 2035 1747 1748
-3 2035 2044 1747
-3 2044 2043 1747
-3 1754 2045 1749
-3 2025 2045 1765
-3 2037 2030 2047
-3 2047 2030 2036
-3 2038 2037 1766
-3 1766 2037 2047
-3 2048 2038 1766
-3 2031 2038 2048
-3 1752 1757 2049
-3 1752 2049 2050
-3 1752 2050 2039
-3 2050 2051 2052
-3 2050 2052 2039
-3 2039 2052 2040
-3 2041 2040 2053
-3 2053 2040 2052
-3 1758 2042 2053
-3 2042 2041 2053
-3 1761 1760 2054
-3 1761 2055 1763
-3 2054 2055 1761
-3 1784 2046 2056
-3 1781 2379 2061
-3 2061 2379 2057
-3 1766 2036 1781
-3 2047 2036 1766
-3 1767 2048 1766
-3 2031 2048 1767
-3 2058 2049 1757
-3 2058 1757 2059
-3 2059 1757 1770
-3 2051 2058 2059
-3 2052 2051 2059
-3 2052 2059 1533
-3 1758 2052 1533
-3 2053 2052 1758
-3 1760 1771 2054
-3 1772 2054 1771
-3 2055 2054 1772
-3 1763 2055 1772
-3 2056 2046 1779
-3 2046 1784 2060
-3 1533 2059 1770
-3 2057 2060 2066
-3 2061 2057 2062
-3 2062 2057 2066
-3 1781 2061 1780
-3 1780 2061 2062
-3 2063 2064 2065
-3 2060 1784 1544
-3 1780 2062 2066
-3 2067 2071 1782
-3 1782 2071 1788
-3 2071 2074 1788
-3 2063 2068 2064
-3 2067 1795 2069
-3 2071 2067 2070
-3 2070 2067 2069
-3 2411 2072 2071
-3 2073 2071 2072
-3 2074 2071 2073
-3 2075 2094 2076
-3 2075 2077 2078
-3 2076 2077 2075
-3 2077 2402 2078
-3 1797 2080 2081
-3 2079 2080 1797
-3 2082 2419 2407
-3 1795 1799 2069
-3 1808 2069 1799
-3 2070 2069 1808
-3 2070 1808 2071
-3 2072 2071 1328
-3 2071 1808 1328
-3 1800 2072 1328
-3 2073 2072 1800
-3 2074 2073 1800
-3 1796 2074 1800
-3 2083 2094 2075
-3 1802 1803 2083
-3 1802 2083 2078
-3 2078 2083 2075
-3 1802 2402 1804
-3 1802 2078 2402
-3 2084 2085 1805
-3 2086 2088 2089
-3 2089 1807 1806
-3 2089 2088 1807
-3 2088 2090 1807
-3 1797 1807 2090
-3 1797 2090 2091
-3 1797 2091 2079
-3 2429 2091 2090
-3 2080 2079 2091
-3 2092 2419 2082
-3 2092 2082 2407
-3 4422 1524 1287
-3 2093 2094 2083
-3 1803 2093 2083
-3 1803 2095 2093
-3 1804 1803 1802
-3 2084 1805 1809
-3 2096 2087 2086
-3 2089 2097 2086
-3 2097 2096 2086
-3 1806 1810 2098
-3 1806 2098 2089
-3 2089 2098 2097
-3 2091 2429 2099
-3 2091 2099 1810
-3 2098 1810 2099
-3 2443 1538 1541
-3 1811 2443 2108
-3 1811 1538 2443
-3 2101 2419 2092
-3 2124 2419 2101
-3 2102 2101 2092
-3 2103 2094 2093
-3 2104 2094 2103
-3 2105 2093 2095
-3 2103 2093 2105
-3 1813 2106 2107
-3 1813 2107 1809
-3 1809 2107 2084
-3 2099 2097 2098
-3 1814 2443 1541
-3 2108 2109 1811
-3 2447 2123 2100
-3 2123 2111 2100
-3 2124 2101 2112
-3 2101 2102 2112
-3 2113 2112 2102
-3 2102 2125 2113
-3 2103 2116 2104
-3 2105 2116 2103
-3 2106 1813 2117
-3 2118 2107 2106
-3 2118 2106 2119
-3 2119 2106 2117
-3 2119 1816 2118
-3 1816 2421 2118
-3 2819 1826 1832
-3 2120 1826 2819
-3 1546 2109 2130
-3 2446 2131 1835
-3 2111 2122 2458
-3 2111 2123 2122
-3 1819 1818 2124
-3 1819 2124 2112
-3 1819 2112 2113
-3 2113 2125 1819
-3 1819 2125 1820
-3 2114 2115 2126
-3 2127 2126 2115
-3 2117 1825 2129
-3 1813 1825 2117
-3 1816 2129 1831
-3 1816 2119 2129
-3 2119 2117 2129
-3 1546 2130 2121
-3 2123 2458 2122
-3 2132 2458 2123
-3 1818 2133 2124
-3 2142 1828 1820
-3 2142 1820 2125
-3 2127 2134 2126
-3 2134 2135 2136
-3 2134 2127 2135
-3 2137 2135 2127
-3 2135 2138 2139
-3 2137 2138 2135
-3 2138 2144 2139
-3 1825 1831 2129
-3 1850 1575 2120
-3 1837 2140 1838
-3 2133 1818 1839
-3 2133 1839 2146
-3 1842 2142 2141
-3 1842 1828 2142
-3 2136 2135 2143
-3 2135 2139 2143
-3 1843 2144 1844
-3 1843 2139 2144
-3 1843 2143 2139
-3 1844 2144 2480
-3 1846 1844 2480
-3 1832 1848 2484
-3 1582 2476 1833
-3 2476 1851 2131
-3 2476 1582 1851
-3 1835 2131 1851
-3 1838 2140 1853
-3 1865 2145 2146
-3 1839 1865 2146
-3 2142 2146 2145
-3 2142 2145 2141
-3 2141 2145 2151
-3 2141 2151 1842
-3 2143 1843 1858
-3 2143 1858 2479
-3 2148 2479 1858
-3 1846 2148 2147
-3 1846 2147 2153
-3 1846 2153 1859
-3 1861 2150 1862
-3 2149 2150 1861
-3 1862 2150 1863
-3 1849 2484 1848
-3 1849 2485 2484
-3 1850 2156 1868
-3 1865 2151 2145
-3 1842 2151 1872
-3 2152 2148 1858
-3 2152 2147 2148
-3 2153 2147 2152
-3 1867 2149 1866
-3 2150 2149 1867
-3 1863 2150 1867
-3 2154 2485 1868
-3 2154 1868 2155
-3 1868 2156 2155
-3 1878 2151 1865
-3 1878 1872 2151
-3 2153 2152 1874
-3 2155 1875 2154
-3 2155 2156 1875
-3 2156 2157 1875
-3 2490 2489 1882
-3 2489 2154 1882
-3 1882 1886 2490
-3 2158 2490 1886
-3 2157 2158 1886
-3 2492 2493 1887
-3 1887 2493 1626
-3 2159 1887 1418
-3 1418 2160 2159
-3 1892 2889 2160
-3 2889 1892 1626
-3 2500 2906 1632
-3 1894 2162 1895
-3 2162 1896 1895
-3 2163 1896 2507
-3 2163 2508 2164
-3 2507 2508 2163
-3 2508 2165 2164
-3 1897 2166 2161
-3 2167 1897 2161
-3 3403 1893 2515
-3 1894 1632 2504
-3 1632 2168 2504
-3 2504 2162 1894
-3 2169 2163 2164
-3 2169 2173 2163
-3 2165 2169 2164
-3 1897 2171 2166
-3 1897 2170 2171
-3 1897 2167 2170
-3 2170 2167 2172
-3 2161 2172 2167
-3 2172 2161 2515
-3 1898 2173 2915
-3 2171 2170 1898
-3 2171 1898 2915
-3 2172 1898 2170
-3 1052 2515 1223
-3 2172 2515 1052
-3 1635 2174 1899
-3 1899 2174 1900
-3 2174 2175 1900
-3 1902 1900 2175
-3 1902 1905 1904
-3 1905 2176 1907
-3 1907 2176 2177
-3 2178 1907 2177
-3 1910 1907 2179
-3 1907 2178 2179
-3 2181 2182 2176
-3 2176 2182 2177
-3 2521 2178 2182
-3 2182 2178 2177
-3 2178 2521 2179
-3 2191 2179 2521
-3 1910 2191 2189
-3 2179 2191 1910
-3 2184 2182 2181
-3 2185 2182 2184
-3 2521 2182 2186
-3 2186 2182 2185
-3 2521 2186 2191
-3 2189 2187 1911
-3 1911 2187 2183
-3 2187 2188 2183
-3 2183 2188 1914
-3 2184 2181 2525
-3 2185 2184 2525
-3 2523 2185 2525
-3 2186 2185 2523
-3 2187 2189 2190
-3 2188 2187 2190
-3 2188 2190 1914
-3 2191 2192 2189
-3 2190 2189 2193
-3 2193 2189 2192
-3 2196 2190 2193
-3 1914 2190 2196
-3 2192 2191 2194
-3 2194 2193 2192
-3 2194 2196 2193
-3 2196 2194 2195
-3 2196 2197 1914
-3 1914 2197 2200
-3 1914 2200 1916
-3 2196 2200 2197
-3 1916 2200 1919
-3 1921 2198 1918
-3 2199 2198 1921
-3 1657 2199 1921
-3 1919 2200 2201
-3 1919 2202 1920
-3 2201 2202 1919
-3 1920 2202 2203
-3 2201 2200 2204
-3 2202 2201 2203
-3 2201 2204 2203
-3 2203 2204 1923
-3 1923 2205 1924
-3 2962 1924 2205
-3 2962 2546 1924
-3 1925 1924 2546
-3 2204 2206 2207
-3 1923 2204 2208
-3 2208 2204 2207
-3 2209 2962 2205
-3 2209 2205 2208
-3 2208 2205 1923
-3 1925 2546 1661
-3 2546 2549 1661
-3 2208 2207 2210
-3 1926 2209 2208
-3 1926 2208 2210
-3 1927 2549 1926
-3 1926 2549 2209
-3 2549 1927 1661
-3 2210 2207 2557
-3 2210 2557 1926
-3 2574 2563 2562
-3 2563 2574 1469
-3 2213 2212 2217
-3 2212 2213 2211
-3 2211 2213 2214
-3 2214 2212 2211
-3 1469 2574 2220
-3 2215 2213 2217
-3 2214 2213 2216
-3 2216 2213 2215
-3 2216 2572 2214
-3 2215 2217 1928
-3 1928 2218 2215
-3 2218 2216 2215
-3 2218 2572 2216
-3 2217 2219 1928
-3 2218 1929 1931
-3 1928 1929 2218
-3 1931 2572 2218
-3 1930 2219 2217
-3 2220 2226 1932
-3 1930 2217 1936
-3 2220 2574 2221
-3 1932 2226 2222
-3 1932 2222 1935
-3 2220 2221 2224
-3 2224 2221 2223
-3 2226 2220 2225
-3 2225 2220 2224
-3 2222 2226 1935
-3 2224 2223 2227
-3 2225 2224 2228
-3 2228 2224 2227
-3 2226 2225 1939
-3 1939 2225 2228
-3 2227 2579 2230
-3 2227 2230 2228
-3 1943 1939 2230
-3 1939 2228 2230
-3 1934 1938 2587
-3 2582 2229 2579
-3 2230 2579 2229
-3 2582 2231 2229
-3 2229 2231 2234
-3 2230 2229 2234
-3 1943 2230 2234
-3 2232 2233 1946
-3 2587 1938 1947
-3 2234 2235 2232
-3 2235 2236 2232
-3 2233 2232 2236
-3 2234 2231 2237
-3 2234 2237 2240
-3 2235 2234 2238
-3 2238 2234 2240
-3 2236 2235 2238
-3 2240 2237 2239
-3 2237 2231 2245
-3 2245 2231 2586
-3 2239 2237 2245
-3 2240 2239 2241
-3 2238 2240 2244
-3 2244 2240 2241
-3 2239 2245 2242
-3 2241 2239 2242
-3 2244 2241 2242
-3 2238 2244 1952
-3 2242 2245 2243
-3 2246 2242 2243
-3 2244 2242 2246
-3 2587 1947 2606
-3 2245 2586 2249
-3 2244 2246 2250
-3 1952 2244 2247
-3 2244 2250 2247
-3 2247 2248 1953
-3 2243 2245 2249
-3 2246 2243 2250
-3 2250 2243 2249
-3 2247 2250 2251
-3 2252 2247 2251
-3 2248 2247 2253
-3 2253 2247 2252
-3 2248 2253 1953
-3 1676 3036 1956
-3 2250 2249 2605
-3 2615 2250 2605
-3 2251 2250 2615
-3 2251 2615 2255
-3 2251 2255 2252
-3 2253 2252 2256
-3 2256 2252 2255
-3 2253 2256 1953
-3 2258 2255 2615
-3 2256 2255 2258
-3 1955 2257 2606
-3 2254 2601 1679
-3 2256 2258 1678
-3 1679 2601 1958
-3 1958 2601 2265
-3 2615 2261 2258
-3 2258 2261 2262
-3 2257 1955 2263
-3 2259 2254 2272
-3 2272 2273 2260
-3 2260 2273 2266
-3 2274 2260 2266
-3 2267 2268 2269
-3 2262 2261 2269
-3 2258 2262 2270
-3 2258 2270 1957
-3 2264 2279 2271
-3 2279 1684 2271
-3 2278 2271 1684
-3 2266 2273 2274
-3 2262 2269 2275
-3 2270 2262 2276
-3 2276 2262 2275
-3 1957 2276 1959
-3 2270 2276 1957
-3 2274 2273 2272
-3 2269 2268 2280
-3 2263 1966 2277
-3 2272 1964 2274
-3 2268 2267 2280
-3 2275 2269 2280
-3 1966 2648 2277
-3 2280 2267 2653
-3 1958 2265 1697
-3 2281 2274 1964
-3 1967 2648 1966
-3 2288 2274 2281
-3 2275 2280 2282
-3 2279 3634 1103
-3 2282 2280 2283
-3 2275 2282 2287
-3 2275 2287 1976
-3 2288 2281 1973
-3 2288 2658 2274
-3 2282 2283 2285
-3 2285 2283 2284
-3 2287 2282 2286
-3 2286 2282 2285
-3 2290 2284 2662
-3 2284 2290 2285
-3 2286 2285 2291
-3 2291 2285 2290
-3 2287 2286 2292
-3 2292 2286 2291
-3 2287 2292 2293
-3 3634 2294 1978
-3 1978 2294 2295
-3 2289 2288 2297
-3 2299 2289 2297
-3 2293 2292 2291
-3 2295 2294 2301
-3 2288 2296 2303
-3 2297 2288 2303
-3 2299 2297 2298
-3 2291 2290 2300
-3 2293 2300 1986
-3 2291 2300 2293
-3 2688 2307 2668
-3 2668 2307 2676
-3 2295 2301 2302
-3 1978 2302 1987
-3 2295 2302 1978
-3 1992 2303 2296
-3 2298 2297 2313
-3 2299 2298 2313
-3 2691 2299 2313
-3 2300 2685 2304
-3 2307 2688 2305
-3 2305 2688 2706
-3 2306 2307 2305
-3 2302 2301 3172
-3 3172 1987 2302
-3 1989 1987 3172
-3 2297 2303 2308
-3 2313 2297 2321
-3 2321 2297 2308
-3 2305 2706 2001
-3 2306 2305 1993
-3 1998 2306 1993
-3 1998 2310 2306
-3 2310 2307 2306
-3 2310 2317 2307
-3 1990 1989 1994
-3 1994 1989 3172
-3 1992 2308 2303
-3 2321 2308 1992
-3 2691 2313 2314
-3 2328 2315 2309
-3 2316 2309 2315
-3 2304 2309 2316
-3 2310 1998 1999
-3 2310 1999 2317
-3 1999 1994 2318
-3 2324 1994 3172
-3 2318 1994 2324
-3 2312 2320 2311
-3 2320 2319 2311
-3 2339 2315 2328
-3 2304 2316 2330
-3 2330 2316 2322
-3 1999 2323 2317
-3 2318 2323 1999
-3 2324 2323 2318
-3 2320 2325 2319
-3 2313 2321 2326
-3 2314 2313 2333
-3 2333 2313 2326
-3 2334 2314 2333
-3 2327 2314 2334
-3 2315 2339 2345
-3 2316 2315 2345
-3 2329 2316 2345
-3 2322 2316 2330
-3 2330 2316 2329
-3 2326 2321 2017
-3 2333 2326 2332
-3 2721 2327 2334
-3 2336 2335 2328
-3 2335 2337 2328
-3 2337 2338 2328
-3 2339 2328 2338
-3 2329 2345 2346
-3 2009 2330 2329
-3 2332 2326 2341
-3 2341 2326 2017
-3 2333 2332 2341
-3 2334 2333 2341
-3 2715 2342 2336
-3 2336 2342 2335
-3 2337 2335 2343
-3 2343 2335 2342
-3 2339 2338 2344
-3 2345 2339 2344
-3 2346 2345 2350
-3 2009 2329 2346
-3 2346 2013 2009
-3 2706 2340 2355
-3 2355 2340 2347
-3 2344 2338 2349
-3 2345 2344 2361
-3 2361 2350 2345
-3 2013 2346 2742
-3 2744 2013 2742
-3 2362 2013 2744
-3 2013 2362 2016
-3 2351 2352 2353
-3 2353 2354 2351
-3 2369 2355 2730
-3 2347 2730 2355
-3 2739 2348 2370
-3 2740 2370 2356
-3 2342 2715 2357
-3 2357 2715 2356
-3 2337 2343 2364
-3 2338 2337 2358
-3 2358 2337 2364
-3 2349 2338 2359
-3 2359 2338 2358
-3 2344 2349 2360
-3 2360 2349 2359
-3 2360 2361 2344
-3 2362 2744 2755
-3 2016 2362 2018
-3 2331 2363 2738
-3 2756 2738 2363
-3 2343 2342 2371
-3 2364 2343 2371
-3 2359 2358 2030
-3 2360 2359 2030
-3 2361 2360 2365
-3 2365 2018 2755
-3 2362 2755 2018
-3 2366 2756 2363
-3 2348 2334 2341
-3 2370 2348 2341
-3 2357 2356 2371
-3 2342 2357 2371
-3 2358 2364 2030
-3 2030 2364 2371
-3 2018 2365 2360
-3 2761 2366 2367
-3 1531 2368 2367
-3 2372 2373 2374
-3 2374 2375 2372
-3 2025 2341 2024
-3 2372 2376 2373
-3 2375 2376 2372
-3 2046 2341 2025
-3 2370 2341 2046
-3 2356 2370 2046
-3 2028 1747 2767
-3 2377 2028 2767
-3 2035 2377 2378
-3 2035 2029 2377
-3 2371 2356 2046
-3 2379 2371 2046
-3 2381 2380 1747
-3 2380 2767 1747
-3 1747 2043 2381
-3 2378 2043 2044
-3 2381 2043 2378
-3 2035 2378 2044
-3 2379 2046 2057
-3 1781 2371 2379
-3 2382 2384 2385
-3 2385 2050 2049
-3 2385 2384 2050
-3 2384 2386 2050
-3 2386 2051 2050
-3 2381 2387 2380
-3 2388 2387 2381
-3 2378 2388 2381
-3 2389 2383 2382
-3 2390 2383 2389
-3 2385 2391 2382
-3 2391 2389 2382
-3 2049 2058 2392
-3 2049 2392 2385
-3 2385 2392 2391
-3 2058 2789 2392
-3 2058 2051 2789
-3 2051 2386 2789
-3 2057 2046 2060
-3 2389 2393 2390
-3 2391 2393 2389
-3 2789 2391 2392
-3 2394 2398 2395
-3 2065 2799 2396
-3 2064 2799 2065
-3 2396 2063 2065
-3 2395 2397 2394
-3 2398 2397 2395
-3 2397 2399 2400
-3 2398 2399 2397
-3 2399 2401 2400
-3 2077 2814 3259
-3 3259 2402 2077
-3 2064 2403 2799
-3 2068 2403 2064
-3 2396 2404 2063
-3 2063 2404 2068
-3 2068 2404 2403
-3 2396 2418 2404
-3 2801 2406 2405
-3 2394 2397 2408
-3 2409 2408 2397
-3 2409 2400 2410
-3 2409 2397 2400
-3 2401 2410 2400
-3 2076 2813 2412
-3 2094 2813 2076
-3 2814 2077 2412
-3 2412 2077 2076
-3 2804 2815 2402
-3 2413 2414 2415
-3 2817 2414 2413
-3 2404 2417 2403
-3 2417 2404 2416
-3 2418 2416 2404
-3 2405 2406 2419
-3 2407 2419 2406
-3 2072 2411 2071
-3 2420 2813 2094
-3 1804 2815 2827
-3 2402 2815 1804
-3 2084 2829 2085
-3 1805 2085 2817
-3 2085 2829 2817
-3 2817 2413 1805
-3 2421 1805 2413
-3 2421 2413 2415
-3 2118 2421 2415
-3 2422 2424 2425
-3 2423 2424 2422
-3 2425 2424 2426
-3 2426 2086 2087
-3 2426 2424 2086
-3 2424 2428 2086
-3 2427 2088 2428
-3 2088 2086 2428
-3 2088 2429 2090
-3 2427 2429 2088
-3 2416 2430 2417
-3 2433 2434 2824
-3 2824 2435 2433
-3 2844 2092 2407
-3 2420 2094 2436
-3 2095 1803 2437
-3 2095 2437 2420
-3 2095 2420 2436
-3 2827 2437 1804
-3 2437 1803 1804
-3 2422 2425 2440
-3 2426 2440 2425
-3 2087 2096 2440
-3 2426 2087 2440
-3 2441 2427 2428
-3 2429 2427 2442
-3 2442 2427 2441
-3 2429 2442 2099
-3 2444 2445 2833
-3 2432 2444 2833
-3 2432 2431 2444
-3 2431 2110 2444
-3 2446 2110 2431
-3 2100 2434 2433
-3 2100 2111 2434
-3 2433 2435 2447
-3 2433 2447 2100
-3 2864 2419 2124
-3 2102 2092 2844
-3 2436 2104 2448
-3 2094 2104 2436
-3 2095 2448 2105
-3 2436 2448 2095
-3 2829 2107 2118
-3 2829 2084 2107
-3 2853 2438 1832
-3 2819 1832 2438
-3 2096 2839 2440
-3 2441 2839 2097
-3 2839 2096 2097
-3 2099 2441 2097
-3 2442 2441 2099
-3 2443 1814 2449
-3 2108 2443 2449
-3 2109 2108 2450
-3 2450 2854 2109
-3 2110 1833 2445
-3 2110 2445 2444
-3 2131 2446 2457
-3 2111 2451 2452
-3 2123 2843 2451
-3 2123 2447 2843
-3 2452 2451 2843
-3 2102 2453 2125
-3 2102 2844 2453
-3 2849 2455 2114
-3 2454 2455 2849
-3 2115 2114 2456
-3 2114 2455 2456
-3 2104 2116 2448
-3 2105 2448 2116
-3 2819 2439 2120
-3 2109 2467 2130
-3 2467 2109 2854
-3 2458 2451 2111
-3 2123 2451 2132
-3 2132 2451 2458
-3 2849 2114 2459
-3 2114 2126 2459
-3 2115 2456 2470
-3 2127 2115 2470
-3 2462 2463 2464
-3 2464 2465 2462
-3 1832 2868 2853
-3 2130 2466 2121
-3 2467 2466 2130
-3 2133 2864 2124
-3 2133 2468 2469
-3 2133 2469 2864
-3 2468 2125 2469
-3 2468 2142 2125
-3 2134 2459 2126
-3 2134 2136 2470
-3 2137 2127 2470
-3 2137 2471 2138
-3 2470 2471 2137
-3 2138 2471 2144
-3 2472 2461 2460
-3 2473 2472 2460
-3 2474 2475 2463
-3 2483 2462 2465
-3 2483 2474 2462
-3 2463 2462 2474
-3 2439 1850 2120
-3 2476 2131 2457
-3 2146 2468 2133
-3 2146 2477 2468
-3 2142 2468 2477
-3 2143 2470 2136
-3 2143 2478 2470
-3 2478 2471 2470
-3 2144 2471 2479
-3 2471 2478 2479
-3 2479 2480 2144
-3 2473 2481 2472
-3 2481 2865 2472
-3 2481 2473 2482
-3 2474 2483 2475
-3 2868 1832 2484
-3 423 4373 893
-3 2142 2477 2146
-3 2479 2478 2143
-3 2480 2479 2148
-3 1846 2480 2148
-3 2865 2481 2487
-3 2482 2488 2481
-3 2488 2487 2481
-3 2439 2156 1850
-3 2489 2485 2154
-3 2489 2490 2158
-3 2156 2486 2157
-3 2486 2158 2157
-3 2881 2491 2492
-3 2493 2492 2491
-3 2492 1887 2881
-3 2493 2889 1626
-3 2494 2496 2497
-3 2495 2496 2494
-3 2496 2498 2497
-3 814 1893 4422
-3 2159 2881 1887
-3 2499 2881 2159
-3 2160 2499 2159
-3 2499 2160 2889
-3 2494 2497 2892
-3 2892 2497 2498
-3 893 4373 2500
-3 2900 2906 2500
-3 2161 2501 2901
-3 2901 2502 2161
-3 2899 2162 2904
-3 2899 1896 2162
-3 2507 1896 2899
-3 2501 2161 2503
-3 1632 2906 2910
-3 2910 2168 1632
-3 2505 2162 2506
-3 2505 2903 2162
-3 2904 2162 2903
-3 2161 2166 2503
-3 2166 2512 2503
-3 2161 2502 2515
-3 2515 2502 3945
-3 2506 2162 2504
-3 2506 2504 2513
-3 2513 2509 2506
-3 2510 2506 2509
-3 2510 2511 2507
-3 2508 2507 2511
-3 2508 2511 2169
-3 2165 2508 2169
-3 2171 2512 2166
-3 2510 2509 2513
-3 2514 2510 2513
-3 2511 2510 2514
-3 2169 2511 2514
-3 2173 2169 2514
-3 2512 2171 2915
-3 2915 2173 2514
-3 1635 2919 2174
-3 2175 2174 2518
-3 2919 2517 2174
-3 2517 2518 2174
-3 2175 2518 1902
-3 2519 2518 2517
-3 2518 2519 1902
-3 2519 2520 1902
-3 1902 2520 1905
-3 1905 2520 2176
-3 2520 2522 2176
-3 2181 2176 2522
-3 2181 2522 2525
-3 2186 2523 2191
-3 2523 2525 2524
-3 2191 2523 2531
-3 2523 2524 2531
-3 2526 2525 2522
-3 2527 2524 2525
-3 2191 2531 2194
-3 2528 2525 2526
-3 2529 2528 2526
-3 2530 2527 2525
-3 2528 2530 2525
-3 2532 2533 2194
-3 2532 2194 2531
-3 2943 2194 2533
-3 2195 2194 2943
-3 2531 2534 2535
-3 2532 2531 2536
-3 2536 2531 2535
-3 2536 2537 2532
-3 2538 2195 2943
-3 2946 2538 2943
-3 2196 2195 2538
-3 2948 2535 2534
-3 2536 2535 2948
-3 2949 2536 2948
-3 2537 2536 2949
-3 2946 2541 2538
-3 2538 2961 2196
-3 2540 2542 2539
-3 2539 2542 2543
-3 2541 2539 2543
-3 2541 2961 2538
-3 2961 2200 2196
-3 2544 2543 2542
-3 2955 2541 2544
-3 2544 2541 2543
-3 2961 2541 2955
-3 2545 2200 2961
-3 2200 2545 2204
-3 2545 2547 2548
-3 2551 2545 2548
-3 2204 2545 2551
-3 2206 2204 2551
-3 2209 2964 2962
-3 2546 2964 2549
-3 2548 2547 2551
-3 2551 2554 2206
-3 2554 2207 2206
-3 2964 2209 2549
-3 2551 2547 2552
-3 2553 2551 2552
-3 2554 2551 2553
-3 2977 2207 2554
-3 2550 2560 2547
-3 2552 2547 2560
-3 2553 2552 2555
-3 2554 2553 2556
-3 2556 2553 2555
-3 2557 2554 2556
-3 2977 2557 2207
-3 2555 2552 2561
-3 2561 2552 2560
-3 2556 2555 2562
-3 2562 2555 2561
-3 2557 2556 2563
-3 2563 2556 2562
-3 2558 2981 2564
-3 2558 2564 2565
-3 2568 2564 2981
-3 2565 2564 2566
-3 2566 2564 2568
-3 2561 2560 2571
-3 2562 2561 2571
-3 2981 3496 2567
-3 2981 2567 2568
-3 2994 2571 2560
-3 2569 2567 3496
-3 2568 2567 2570
-3 2570 2567 2569
-3 2572 2566 2568
-3 2570 2572 2568
-3 2212 2569 3496
-3 2570 2569 2572
-3 2572 2569 2212
-3 2574 2571 2573
-3 2571 2574 2562
-3 2212 3496 2217
-3 2212 2214 2572
-3 2997 2573 2571
-3 2217 3496 1936
-3 3004 2573 2997
-3 1262 4051 1663
-3 2572 1931 4052
-3 2574 2575 2221
-3 1931 1934 4052
-3 2575 2574 2223
-3 2575 2223 2221
-3 2576 2573 2578
-3 2574 2573 2576
-3 2223 2574 2577
-3 2577 2574 2576
-3 2223 2577 2227
-3 4052 1934 2587
-3 2582 2576 2578
-3 2577 2576 2582
-3 2577 2582 2227
-3 2580 2578 3004
-3 2582 2578 2581
-3 2581 2578 2580
-3 2579 2227 2582
-3 2581 2580 3010
-3 2582 2581 2583
-3 3010 2580 2585
-3 3010 2231 2583
-3 2582 2583 2231
-3 2580 2584 2585
-3 2585 2231 3010
-3 2586 2585 3014
-3 2231 2585 2586
-3 3026 2592 3014
-3 2586 3014 2592
-3 2589 2590 2591
-3 2588 2587 2600
-3 2589 2593 2594
-3 2590 2589 2594
-3 2591 2590 2597
-3 2599 2586 2592
-3 2586 2599 2249
-3 2600 2587 2606
-3 3533 2254 2593
-3 2594 2593 2596
-3 2596 2593 2254
-3 2590 2594 2597
-3 2597 2594 2596
-3 2595 2591 2598
-3 2610 2592 3527
-3 2592 2610 2604
-3 2599 2592 2604
-3 2601 2254 3533
-3 2254 2597 2596
-3 2591 2597 2607
-3 2598 2591 2608
-3 2602 2598 2608
-3 2608 2598 2602
-3 2603 2595 2598
-3 2249 2599 2605
-3 2599 2604 2605
-3 2588 2600 2618
-3 2618 2600 2606
-3 2607 2597 2254
-3 2591 2607 2608
-3 2603 2598 2609
-3 2609 2621 2603
-3 2604 2612 2613
-3 2604 2613 2605
-3 2614 2605 2613
-3 2615 2605 2614
-3 2606 2257 2617
-3 2617 2257 2616
-3 2618 2606 2617
-3 2620 2607 2254
-3 2608 2607 2259
-3 2259 2607 2620
-3 2609 2598 2608
-3 2622 2610 2611
-3 2604 2610 2623
-3 2623 2610 2622
-3 2624 2604 2623
-3 2612 2625 2613
-3 2613 2625 2626
-3 2614 2613 2626
-3 2615 2614 2627
-3 2627 2614 2626
-3 2617 2616 2628
-3 2618 2617 2631
-3 2631 2617 2628
-3 2644 2618 2631
-3 2601 2619 2265
-3 2259 2620 2254
-3 2272 2608 2259
-3 2260 2608 2272
-3 2621 2609 2608
-3 2629 2624 2623
-3 2267 2625 2633
-3 2626 2625 2269
-3 2269 2625 2267
-3 2261 2626 2269
-3 2627 2626 2261
-3 2615 2627 2261
-3 2257 2263 2616
-3 2628 2616 2630
-3 2630 2616 2263
-3 2631 2628 2630
-3 3055 2264 2271
-3 3587 3055 2271
-3 2260 2274 2608
-3 2640 2629 2623
-3 2635 2636 3073
-3 2637 2630 2263
-3 2631 2630 2637
-3 2644 2631 2637
-3 2264 3055 2279
-3 3587 2271 2278
-3 2639 2621 2608
-3 2632 2621 2639
-3 2645 2632 2639
-3 2623 2622 2640
-3 2634 2642 2641
-3 2634 2641 2633
-3 2633 2641 2267
-3 2635 2643 2636
-3 3073 2643 2635
-3 2263 2277 2637
-3 2645 2639 2608
-3 2637 2277 2648
-3 2644 2637 2648
-3 2646 2265 2619
-3 2645 2608 2658
-3 2645 2649 2651
-3 2647 2622 2652
-3 2640 2622 2647
-3 2641 2640 2650
-3 2267 2641 2650
-3 2658 2608 2274
-3 2650 2640 2653
-3 2267 2650 2653
-3 1697 2265 2646
-3 2649 2645 2658
-3 3110 2654 2652
-3 2640 2647 2652
-3 2659 2652 2654
-3 2640 2652 2659
-3 2653 2640 2659
-3 2653 2655 2280
-3 2651 2649 2658
-3 3110 2661 2654
-3 2655 2653 2659
-3 2280 2655 2283
-3 2655 2659 2656
-3 2657 2655 2656
-3 2283 2655 2657
-3 2648 1967 3095
-3 3106 2651 2658
-3 2660 2661 3110
-3 2284 2657 2656
-3 2283 2657 2284
-3 2675 3095 1967
-3 3634 2669 2294
-3 2288 2289 2658
-3 2654 2661 2659
-3 2284 2656 2659
-3 2668 2669 3121
-3 3106 2658 2289
-3 2670 3106 2289
-3 2659 2662 2284
-3 2659 2673 2662
-3 2663 2664 2665
-3 2663 2666 2667
-3 2665 2666 2663
-3 2681 2670 2289
-3 3144 2670 2671
-3 2672 2661 2660
-3 2683 2661 2672
-3 3162 2659 2661
-3 3163 2659 3162
-3 2659 3163 2673
-3 2674 2662 2673
-3 2685 2662 2674
-3 2290 2662 2685
-3 2686 2675 1967
-3 2668 3121 2688
-3 2676 3154 2669
-3 2676 2669 2668
-3 3154 2294 2669
-3 3154 2677 2294
-3 2677 2301 2294
-3 2678 2679 2680
-3 2671 2670 2691
-3 2691 2670 2681
-3 2682 2671 2691
-3 3144 2671 2682
-3 2692 3144 2682
-3 2673 3163 2684
-3 2674 2673 2684
-3 2685 2674 2684
-3 2300 2290 2685
-3 2675 2686 2687
-3 2698 2675 2687
-3 2689 2301 2677
-3 2690 2679 2678
-3 2680 2690 2678
-3 2299 2691 2289
-3 2691 2681 2289
-3 2692 2682 2701
-3 3169 2694 3137
-3 2705 3137 2694
-3 2683 2672 2696
-3 2696 2672 2695
-3 2697 2683 2696
-3 2683 2697 3162
-3 2697 2304 3162
-3 2684 3162 2304
-3 2685 2684 2304
-3 2698 2687 2686
-3 2307 3164 2676
-3 2689 3172 2301
-3 2719 2679 2690
-3 2699 2719 2690
-3 2680 2700 2690
-3 2700 2699 2690
-3 2682 2691 2711
-3 2701 2693 2692
-3 2703 3159 2702
-3 2694 3169 2715
-3 2705 2694 2725
-3 3179 2696 2695
-3 2309 2696 2328
-3 2697 2696 2309
-3 2304 2697 2309
-3 2331 2698 2686
-3 2706 2726 2340
-3 3164 2317 2707
-3 3164 2307 2317
-3 3164 2707 3172
-3 2312 2311 2708
-3 2719 2699 2709
-3 2700 2710 2699
-3 2710 2709 2699
-3 2710 2700 2720
-3 2314 2711 2691
-3 2701 2682 2711
-3 2712 2702 3159
-3 2722 2712 3159
-3 2703 2702 2713
-3 2713 2702 2712
-3 2704 2703 2713
-3 3167 3160 2714
-3 3167 2714 2724
-3 3169 3167 2724
-3 2715 3169 2724
-3 2328 2696 3179
-3 2707 2317 2716
-3 3172 2707 2717
-3 2717 2707 2716
-3 2717 2324 3172
-3 2319 3183 3184
-3 2319 3184 2708
-3 2319 2708 2311
-3 2718 2312 2708
-3 2312 2718 2320
-3 2710 2719 2709
-3 2720 2719 2710
-3 2314 2327 2711
-3 2701 2711 2327
-3 2693 2701 2721
-3 2722 2721 2712
-3 2712 2721 2732
-3 2713 2712 2732
-3 2723 2704 2713
-3 2723 2729 3176
-3 2714 3176 2729
-3 2694 2715 2725
-3 2340 2726 2730
-3 2317 2323 2716
-3 2324 2716 2323
-3 2717 2716 2324
-3 2319 2727 3183
-3 2731 2728 2727
-3 2325 2731 2727
-3 2325 2727 2319
-3 2718 2731 2325
-3 2718 2325 2320
-3 2721 2701 2327
-3 2714 2729 2734
-3 2715 2724 2733
-3 2336 2725 2715
-3 2328 2725 2336
-3 2723 2713 2732
-3 2729 2723 2732
-3 2724 2714 2733
-3 2732 2721 2334
-3 2334 2348 2732
-3 2740 2732 2739
-3 2729 2732 2740
-3 2734 2729 2740
-3 2714 2734 2733
-3 2715 2733 2356
-3 2735 3193 2736
-3 3193 2737 2736
-3 3171 2331 2738
-3 2340 2730 2347
-3 2739 2732 2348
-3 2741 2734 2740
-3 2356 2733 2734
-3 2350 2742 2346
-3 2743 2744 2742
-3 2353 2352 2745
-3 2354 2353 2745
-3 2736 2746 2735
-3 2747 2746 2736
-3 2737 2747 2736
-3 3201 2748 2749
-3 3201 2749 2738
-3 2750 2738 2749
-3 2751 2738 2750
-3 2369 3718 3731
-3 2730 3718 2369
-3 2740 2739 2370
-3 2356 2741 2740
-3 2734 2741 2356
-3 2350 2361 2752
-3 2350 2752 3203
-3 2350 3203 2742
-3 3203 2753 2742
-3 2743 2742 2754
-3 2754 2742 2753
-3 2744 2743 2755
-3 2755 2743 2754
-3 1524 4422 1519
-3 2352 2351 2745
-3 2354 2745 2351
-3 2757 2738 2756
-3 2758 2738 2757
-3 3201 2738 2758
-3 2750 2749 2748
-3 2751 2750 2368
-3 3198 2751 2368
-3 1531 3198 2368
-3 3731 3198 1531
-3 2369 3731 1301
-3 2752 2361 2759
-3 2361 2365 2759
-3 2753 2760 2365
-3 2759 2365 2760
-3 2754 2753 2365
-3 2755 2754 2365
-3 2756 2366 2761
-3 2367 2757 2761
-3 2757 2756 2761
-3 2758 2757 2367
-3 2368 2758 2367
-3 2758 2368 2762
-3 2748 2762 2368
-3 2750 2748 2368
-3 2374 2373 2763
-3 2374 2763 2375
-3 2373 2376 2763
-3 2375 2763 2376
-3 2767 3226 2377
-3 2377 3226 2378
-3 2768 2766 2770
-3 2769 2766 2768
-3 2771 2773 2772
-3 2380 2783 2767
-3 3226 2785 2378
-3 2768 2770 2775
-3 2766 2776 2770
-3 2776 2775 2770
-3 2776 2766 2777
-3 2778 2771 2772
-3 2382 2383 2779
-3 2382 2779 2773
-3 2773 2779 2772
-3 2773 2384 2382
-3 2773 2780 2384
-3 2773 2774 2780
-3 2780 2781 2384
-3 2384 2782 2386
-3 2781 2782 2384
-3 2783 2380 3236
-3 2380 2784 3236
-3 2380 2387 2784
-3 3240 2784 2387
-3 3240 2387 2785
-3 2785 2387 2388
-3 2785 2388 2378
-3 1697 4373 423
-3 3241 2775 2776
-3 2777 3241 2776
-3 2778 2787 3249
-3 2778 2772 2787
-3 2772 2779 2787
-3 2383 2390 2787
-3 2779 2383 2787
-3 2788 2781 2780
-3 3249 2788 2780
-3 2782 2781 2789
-3 2789 2781 2788
-3 2782 2789 2386
-3 2784 2790 3236
-3 3240 2790 2784
-3 2792 2791 2786
-3 2791 2797 2786
-3 2390 3249 2787
-3 2390 2393 3249
-3 3249 2391 2788
-3 3249 2393 2391
-3 2789 2788 2391
-3 2793 2795 2796
-3 2794 2795 2793
-3 2394 2797 2792
-3 2792 2797 2791
-3 2792 2798 2394
-3 2398 2394 2798
-3 2793 2796 2800
-3 2795 2801 2796
-3 2801 2800 2796
-3 2797 2836 3247
-3 2836 2797 2394
-3 2398 2802 2399
-3 2398 2798 2802
-3 2802 2803 2399
-3 2399 2803 2401
-3 2402 3259 2804
-3 2396 2799 2418
-3 2810 2811 2809
-3 2812 2793 2800
-3 2801 2405 2812
-3 2801 2812 2800
-3 2795 2406 2801
-3 2795 2407 2406
-3 2795 2844 2407
-3 2410 2803 2802
-3 2410 2802 2409
-3 2401 2803 2410
-3 2412 2813 2814
-3 2815 2804 2816
-3 2816 2804 2828
-3 2805 2414 2817
-3 2415 2414 2805
-3 2415 2805 2818
-3 2818 2805 2806
-3 2403 2417 2799
-3 2417 2820 2799
-3 2418 2799 2820
-3 2821 2418 2820
-3 2821 2822 2418
-3 2416 2418 2823
-3 2823 2418 2822
-3 2825 2809 2824
-3 2809 2811 2824
-3 2824 2811 2435
-3 2405 3290 2812
-3 2408 2836 2394
-3 2408 2409 2826
-3 2409 3281 2826
-3 2409 2802 3281
-3 2420 2437 2814
-3 2420 2814 2813
-3 2437 2827 2814
-3 2816 2827 2815
-3 2828 2827 2816
-3 2829 2830 2817
-3 2415 2831 2118
-3 2415 2818 2831
-3 2439 2819 2807
-3 3306 2439 2807
-3 3306 2807 2808
-3 2422 3299 2423
-3 2423 3299 2424
-3 2417 2430 2820
-3 2821 2430 2832
-3 2821 2820 2430
-3 2832 2430 2833
-3 2416 2823 2430
-3 2833 2430 2823
-3 2432 2822 2431
-3 2432 2823 2822
-3 2432 2833 2823
-3 2446 2431 3288
-3 2431 2822 3288
-3 3288 2834 2446
-3 2824 2434 2825
-3 3290 2405 2419
-3 2826 2836 2408
-3 2837 2836 2826
-3 3281 2837 2826
-3 2118 2830 2829
-3 2830 2118 2831
-3 2819 2438 2838
-3 2839 3299 2422
-3 2422 2440 2839
-3 2428 3309 2441
-3 2833 2445 2832
-3 3301 2111 2842
-3 3301 2434 2111
-3 2447 2842 2843
-3 2447 2835 2842
-3 2447 2435 2835
-3 3301 2842 2835
-3 2419 3302 3290
-3 3302 2419 2864
-3 2848 3314 2454
-3 3314 3322 2454
-3 2838 2853 3305
-3 2853 2838 2438
-3 2441 3309 2839
-3 3321 2449 1814
-3 3321 2450 2449
-3 2450 2108 2449
-3 2450 2840 2854
-3 2446 2834 2457
-3 2452 2842 2111
-3 2843 2842 2452
-3 2844 2848 2453
-3 2849 2848 2454
-3 2454 3322 2455
-3 2455 3322 2856
-3 2456 2455 2856
-3 2850 2464 2846
-3 2846 2845 2850
-3 2845 2851 2850
-3 2852 2845 2847
-3 2851 2845 2852
-3 1814 2121 3321
-3 3321 2121 2861
-3 2832 2445 3329
-3 3329 2445 1833
-3 2848 2855 2453
-3 2453 2855 2125
-3 2855 2848 3344
-3 2849 3344 2848
-3 2456 2856 2470
-3 2460 2461 2857
-3 2463 2858 2464
-3 2465 2850 2859
-3 2465 2464 2850
-3 2860 2859 2851
-3 2859 2850 2851
-3 2852 2860 2851
-3 2439 3306 2486
-3 2466 2861 2121
-3 2862 2861 2467
-3 2467 2861 2466
-3 2467 2854 2862
-3 2469 2855 2864
-3 2855 2469 2125
-3 2459 3330 2849
-3 2459 2856 3330
-3 2134 2856 2459
-3 2470 2856 2134
-3 2857 2472 2865
-3 2461 2472 2857
-3 2460 2866 2473
-3 2460 2857 2866
-3 2857 2865 2866
-3 2463 2475 2867
-3 2463 2867 2858
-3 2858 2867 3335
-3 2483 2465 2867
-3 3335 2867 2465
-3 2859 3335 2465
-3 2860 3335 2859
-3 2868 2485 2853
-3 1833 2476 3329
-3 2457 2863 2476
-3 2476 2863 3329
-3 2866 2865 2869
-3 2473 2869 2482
-3 2866 2869 2473
-3 2475 2483 2867
-3 2484 2485 2868
-3 2487 2869 2865
-3 2482 2869 2488
-3 2869 2487 2488
-3 2439 2486 2156
-3 2870 2872 2873
-3 2489 3889 2485
-3 2874 3360 3356
-3 2874 2875 2876
-3 3356 2875 2874
-3 2870 2877 2871
-3 2877 2878 2879
-3 2877 2870 2878
-3 2870 2873 2878
-3 3365 2873 2872
-3 2878 2873 3365
-3 2489 2158 3889
-3 2158 2486 3889
-3 2880 3360 2874
-3 2881 3360 2880
-3 2491 2880 2876
-3 2876 2880 2874
-3 2876 2885 2491
-3 2882 2879 2878
-3 3365 2883 2878
-3 2883 2882 2878
-3 2880 2491 2881
-3 2884 2493 2491
-3 2884 2491 2885
-3 2882 2886 3366
-3 2882 2883 2886
-3 2887 2886 2883
-3 2885 2888 2884
-3 2884 2888 2889
-3 2884 2889 2493
-3 2495 2494 2886
-3 2886 2494 3366
-3 2886 2887 2496
-3 2886 2496 2495
-3 2494 3369 3366
-3 2887 2498 2496
-3 2887 2883 2498
-3 2499 2888 2881
-3 2499 2889 2888
-3 2891 2890 2498
-3 2891 2498 2883
-3 2494 2892 3369
-3 2890 2893 2892
-3 2890 2892 2498
-3 2891 2893 2890
-3 3381 2894 2895
-3 2895 2894 2896
-3 2895 2897 3381
-3 2896 2897 2895
-3 3395 4422 1893
-3 1893 3404 3395
-3 2898 2902 3398
-3 2903 2898 3400
-3 2902 2898 2903
-3 3403 3404 1893
-3 2902 3410 3398
-3 2503 2901 2501
-3 2503 2905 2901
-3 2502 2901 2905
-3 2502 2905 3945
-3 2910 2906 2907
-3 2168 2910 2908
-3 3410 2168 2908
-3 2902 2168 3410
-3 2909 2902 2903
-3 2909 2504 2902
-3 2909 3414 2504
-3 2168 2902 2504
-3 2903 2505 2909
-3 2899 3418 2507
-3 2512 2905 2503
-3 2910 2911 2908
-3 2513 2504 3414
-3 2506 2912 2505
-3 2510 2912 2506
-3 2507 2913 2510
-3 2510 2913 2912
-3 2913 2507 3418
-3 2905 2512 2915
-3 3945 2914 2515
-3 2513 3421 2514
-3 3427 3403 2515
-3 3423 2514 3421
-3 3423 2915 2514
-3 2916 3426 2516
-3 2516 1226 3428
-3 2516 3426 2917
-3 2916 2516 3428
-3 2517 2918 2519
-3 2919 2918 2517
-3 2519 2918 2520
-3 2920 2919 2921
-3 2921 2919 1635
-3 2922 2923 3437
-3 2924 2925 2926
-3 2928 2926 2929
-3 2928 2927 2926
-3 2927 2924 2926
-3 2929 2930 2931
-3 2929 2926 2930
-3 2932 2930 2925
-3 2925 2930 2926
-3 2933 2931 2930
-3 2934 2931 2933
-3 2935 2930 2932
-3 2933 2930 2935
-3 2933 2936 2934
-3 2935 2936 2933
-3 2522 3450 2526
-3 2524 2527 2937
-3 2526 3450 2529
-3 3450 2938 2529
-3 2937 2530 2939
-3 2527 2530 2937
-3 2524 2940 2531
-3 2524 2937 2940
-3 2937 2939 2940
-3 2533 3456 2941
-3 2532 3456 2533
-3 2942 2533 2941
-3 2942 2943 2533
-3 2528 2529 2947
-3 2947 2529 2938
-3 2528 2939 2530
-3 2528 2944 2939
-3 2531 2944 2534
-3 2531 2940 2944
-3 2940 2939 2944
-3 2532 2537 3456
-3 3456 2537 2950
-3 2950 2945 2942
-3 2943 2942 2946
-3 2946 2942 2945
-3 2952 2528 2947
-3 2952 2948 2944
-3 2952 2944 2528
-3 2534 2944 2948
-3 2950 2537 2949
-3 2950 2949 2951
-3 2945 2950 2951
-3 2945 2951 2540
-3 2945 2540 2539
-3 2541 2945 2539
-3 2946 2945 2541
-3 3467 3470 2948
-3 2949 2948 2953
-3 2953 2948 3470
-3 2540 2953 2542
-3 2540 2951 2953
-3 2951 2949 2953
-3 3471 2953 3470
-3 2542 3471 2958
-3 2542 2953 3471
-3 2958 2544 2542
-3 2954 2956 2957
-3 3468 2954 2957
-3 2959 2544 2958
-3 2544 2959 2960
-3 2544 2960 2955
-3 2961 2955 2960
-3 2957 2956 2969
-3 2969 2956 2963
-3 3468 2957 2969
-3 2970 3468 2987
-3 2987 3468 2969
-3 2547 2961 2550
-3 2961 2960 2550
-3 2545 2961 2547
-3 2962 2964 2546
-3 3470 2970 2971
-3 2972 3470 2971
-3 2550 2960 2959
-3 2976 2550 2959
-3 3501 2967 2966
-3 3501 2966 2973
-3 2973 2966 2965
-3 2963 2968 2986
-3 2986 2968 2974
-3 2969 2963 2986
-3 2971 2970 2975
-3 2975 2972 2971
-3 2986 2974 2979
-3 2975 2970 2980
-3 2980 2970 2987
-3 2554 2557 2977
-3 2978 2973 2981
-3 2978 2981 2558
-3 2978 2558 2559
-3 2558 2978 2559
-3 2558 3501 2978
-3 3501 2973 2978
-3 2979 2982 2986
-3 2987 2969 2986
-3 2976 2985 2984
-3 2976 2984 2550
-3 2550 2984 2560
-3 2558 2565 3501
-3 2982 2990 2986
-3 2980 2987 2991
-3 2988 2983 2980
-3 2988 2980 2989
-3 2989 2980 2991
-3 2988 2989 3495
-3 2992 2985 3495
-3 2985 2992 2984
-3 2984 2992 2994
-3 2560 2984 2994
-3 2565 2566 3501
-3 2987 2986 2991
-3 2991 2986 2990
-3 3495 2989 2992
-3 2992 2989 2991
-3 2995 2991 2990
-3 2992 2991 3005
-3 3005 2991 2995
-3 2993 2992 3005
-3 2994 2992 2993
-3 2566 2572 3501
-3 2993 3005 2997
-3 2994 2993 2997
-3 2996 2995 3503
-3 3005 2995 2996
-3 2994 2997 2571
-3 2996 3503 2998
-3 3501 2572 4052
-3 3005 2996 2998
-3 2998 3503 2999
-3 3005 2998 2999
-3 2997 3005 3004
-3 3005 2999 3000
-3 3509 3001 3000
-3 3002 3000 3001
-3 3003 3000 3002
-3 3003 3002 3005
-3 3000 3003 3005
-3 3004 2578 2573
-3 3004 3005 2580
-3 3001 3006 3007
-3 3002 3001 3009
-3 3005 3002 3009
-3 3019 3005 3009
-3 2580 3005 3019
-3 2584 2580 3019
-3 2581 3010 2583
-3 3007 3008 3012
-3 3012 3008 3011
-3 3007 3012 3013
-3 3001 3007 3013
-3 3009 3001 3013
-3 2584 3019 3014
-3 2584 3014 2585
-3 3012 3011 3013
-3 3009 3013 3023
-3 3031 3009 3023
-3 3019 3009 3018
-3 3014 3019 3026
-3 3020 3016 3015
-3 3021 3016 3020
-3 3022 3015 3017
-3 3020 3015 3022
-3 2588 4052 2587
-3 3011 3008 3045
-3 3024 3009 3043
-3 3018 3009 3024
-3 3019 3018 3025
-3 3026 3019 3025
-3 3013 3011 3045
-3 3023 3013 3027
-3 3031 3023 3028
-3 3028 3023 3027
-3 3018 3024 3029
-3 3025 3018 3519
-3 2588 3532 4052
-3 2589 3521 3520
-3 2591 3521 2589
-3 2591 3030 3521
-3 3013 3045 3051
-3 3028 3027 3539
-3 3031 3028 3539
-3 3029 3024 3032
-3 3032 3024 3043
-3 3032 3018 3029
-3 3519 3018 3032
-3 3026 3025 2592
-3 3520 2593 2589
-3 3033 2593 3520
-3 2595 3030 2591
-3 2595 3529 3030
-3 3034 3529 2595
-3 3027 3013 3539
-3 3009 3031 3035
-3 3043 3009 3035
-3 3025 3527 2592
-3 3533 2593 3033
-3 2595 3037 3034
-3 2595 3535 3037
-3 3038 3535 2595
-3 3539 3013 3051
-3 3540 3032 3043
-3 2601 3533 3039
-3 2603 3038 2595
-3 2603 3040 3038
-3 3549 3044 3045
-3 3574 3539 3051
-3 3031 3539 3052
-3 3035 3031 3052
-3 3564 3540 3043
-3 3550 2611 3527
-3 3527 2611 2610
-3 2588 2618 3532
-3 3049 3532 2618
-3 2601 3039 2619
-3 2603 2621 3040
-3 3052 3539 3574
-3 3043 3035 3046
-3 2612 3047 3048
-3 2612 2604 3047
-3 3056 3040 2621
-3 3572 3050 3041
-3 3045 3044 3081
-3 3051 3045 3081
-3 3046 3035 3053
-3 3053 3035 3052
-3 3043 3046 3061
-3 3061 3046 3053
-3 3061 3564 3043
-3 3063 2611 3054
-3 2611 3063 2622
-3 2624 3066 2604
-3 3066 3047 2604
-3 2612 2633 2625
-3 2618 2644 3049
-3 3078 2619 3039
-3 3056 2621 2632
-3 3044 3549 3081
-3 3598 3574 3059
-3 3059 3574 3051
-3 3574 3599 3052
-3 3053 3052 3061
-3 3061 3052 3060
-3 3586 3062 3063
-3 3586 3063 3054
-3 2624 2629 3064
-3 3065 3066 3064
-3 3064 3066 2624
-3 3067 2612 3048
-3 3068 3067 3048
-3 2612 3067 2633
-3 3553 3049 3088
-3 2632 3069 3056
-3 3069 2632 3057
-3 2632 3058 3057
-3 2632 3074 3058
-3 3051 3081 3070
-3 3059 3051 3070
-3 3070 3598 3059
-3 3061 3060 3071
-3 3085 3063 3062
-3 2629 2640 3064
-3 3065 3064 3072
-3 3072 3064 2640
-3 3072 2634 3068
-3 3065 3072 3068
-3 2634 2633 3068
-3 3068 2633 3067
-3 2644 2638 3049
-3 3088 3049 2638
-3 2645 3074 2632
-3 3079 3074 2645
-3 3074 3079 3075
-3 3060 3052 3083
-3 3071 3060 3083
-3 3063 3085 2622
-3 3072 2640 2641
-3 2642 3072 2641
-3 2634 3072 2642
-3 2636 2643 3073
-3 2638 2644 3077
-3 3088 2638 3087
-3 3087 2638 3077
-3 3080 3075 3079
-3 3074 3075 3080
-3 3074 3080 3613
-3 3070 3081 3082
-3 3626 3070 3082
-3 3052 3609 3620
-3 3076 3071 3084
-3 3084 3071 3083
-3 3077 2648 3086
-3 2644 2648 3077
-3 3087 3077 3086
-3 2619 3078 2646
-3 3079 2645 2651
-3 3619 3630 3089
-3 3619 3089 3081
-3 3082 3081 3090
-3 3090 3081 3089
-3 3090 3626 3082
-3 3091 3620 3626
-3 3620 3091 3052
-3 3084 3083 3092
-3 3076 3084 3092
-3 3085 3076 3092
-3 2622 3092 2652
-3 3085 3092 2622
-3 3087 3086 3093
-3 3088 3087 3093
-3 3096 3079 2651
-3 3080 3079 3096
-3 3622 3080 3094
-3 3626 3090 3089
-3 3116 3091 3626
-3 2652 3092 3110
-3 3095 3086 2648
-3 3093 3086 3095
-3 3632 3088 3095
-3 3095 3088 3093
-3 4097 2646 3078
-3 3080 3096 3106
-3 3052 3091 3116
-3 3092 3083 3110
-3 3642 3632 3095
-3 1697 2646 4097
-3 3080 3101 3109
-3 3097 3080 3109
-3 3094 3080 3098
-3 3098 3080 3097
-3 3099 3647 3100
-3 3083 3052 3110
-3 3080 3106 3112
-3 3101 3080 3112
-3 3098 3097 3102
-3 3099 3646 3103
-3 3647 3099 3103
-3 3642 3095 3104
-3 3642 3104 3105
-3 2651 3106 3096
-3 3101 3112 3107
-3 3108 3101 3107
-3 3109 3101 3108
-3 3097 3109 3123
-3 3102 3097 3123
-3 3110 3052 3116
-3 2675 3104 3095
-3 3655 3121 3656
-3 3656 3121 3634
-3 2669 3634 3121
-3 3107 3112 3113
-3 3108 3107 3114
-3 3114 3107 3113
-3 3109 3108 3114
-3 3661 3657 3102
-3 3103 3646 3662
-3 3115 3654 3647
-3 3117 3118 3659
-3 3111 3117 3659
-3 3111 3119 3117
-3 3120 3119 3111
-3 2670 3122 3106
-3 3122 3112 3106
-3 3113 3112 3122
-3 3114 3113 3122
-3 3109 3114 3133
-3 3133 3114 3122
-3 3123 3109 3133
-3 3102 3123 3124
-3 3124 3661 3102
-3 3116 3664 3125
-3 3110 3116 3125
-3 2660 3110 3139
-3 3119 3118 3117
-3 3126 3118 3119
-3 3120 3126 3119
-3 3127 3126 3120
-3 3130 3132 3131
-3 3128 3132 3130
-3 3672 3104 2675
-3 2670 3144 3122
-3 3133 3122 3144
-3 3123 3133 3134
-3 3124 3123 3135
-3 3135 3123 3134
-3 3135 3661 3124
-3 3103 3662 3147
-3 3147 3662 3158
-3 3647 3103 3148
-3 3148 3103 3147
-3 3115 3647 3160
-3 3676 3115 3149
-3 3149 3115 3160
-3 3125 3136 3137
-3 3110 3125 3138
-3 3138 3125 3137
-3 3139 3110 3138
-3 3128 3140 3141
-3 3128 3130 3140
-3 2665 2664 3140
-3 2665 3140 3131
-3 3131 3140 3130
-3 3131 3132 3142
-3 3131 3142 2665
-3 2665 3142 2666
-3 3142 2667 2666
-3 3143 2667 3142
-3 3134 3133 3145
-3 3145 3133 3144
-3 3135 3134 3146
-3 3146 3134 3145
-3 3158 3661 3135
-3 3158 3135 3146
-3 3149 3150 3676
-3 3676 3150 3136
-3 3136 3150 3137
-3 3138 3137 3151
-3 3152 3138 3151
-3 3139 3690 2660
-3 2660 3690 2672
-3 2664 3141 3140
-3 2664 2663 3141
-3 2663 3153 3141
-3 2667 3153 2663
-3 3153 2667 3143
-3 3121 3682 2706
-3 2680 3155 3156
-3 2679 3155 2680
-3 2680 3156 3684
-3 2692 3157 3144
-3 3157 3145 3144
-3 3146 3145 3157
-3 3158 3146 3157
-3 3147 3158 3159
-3 3647 3148 3160
-3 3160 3148 3176
-3 3137 3150 3169
-3 2705 3151 3137
-3 3161 3152 3151
-3 3161 3151 2705
-3 3690 3170 2672
-3 3162 2661 2683
-3 2698 3672 2675
-3 3674 3672 3171
-3 3171 3672 2698
-3 3121 2706 2688
-3 2676 3164 3154
-3 2677 3154 2689
-3 2689 3154 3164
-3 3155 2679 3165
-3 2692 2693 3157
-3 3696 3157 2693
-3 3157 3166 3158
-3 3159 3158 3166
-3 2703 3147 3159
-3 2704 3147 2703
-3 2704 3148 3147
-3 3176 3148 2704
-3 3149 3160 3167
-3 3150 3149 3168
-3 3168 3149 3167
-3 3169 3150 3168
-3 2695 2672 3170
-3 2684 3163 3162
-3 3180 3681 3171
-3 2689 3164 3172
-3 2679 2719 3165
-3 2700 2680 3684
-3 3714 2700 3684
-3 3173 3696 2693
-3 3175 3174 3166
-3 3159 3166 3174
-3 3176 2704 2723
-3 3169 3168 3167
-3 3177 3161 2705
-3 3170 3177 3178
-3 2695 3170 3179
-3 3170 3178 3179
-3 2331 3171 2698
-3 3704 3180 3171
-3 2706 3682 2726
-3 2726 3682 3707
-3 3713 2720 3714
-3 2720 2700 3714
-3 3173 2693 3185
-3 2722 3174 3175
-3 3716 2722 3175
-3 3174 2722 3159
-3 2714 3160 3176
-3 2705 2725 3177
-3 3178 3177 3181
-3 3179 3178 3182
-3 3182 3178 3181
-3 3179 3182 2328
-3 2720 3726 2719
-3 3713 3726 2720
-3 2721 3185 2693
-3 3716 3185 2722
-3 3185 2721 2722
-3 3181 3177 2725
-3 3182 3181 2725
-3 2328 3182 2725
-3 2726 3707 3720
-3 3183 2727 3186
-3 2718 3189 2731
-3 2738 3704 3171
-3 3704 2738 3198
-3 2730 2726 3720
-3 3732 3187 3188
-3 3732 3186 3187
-3 3186 2727 3187
-3 2728 3187 2727
-3 2728 3189 3187
-3 2728 2731 3189
-3 3731 3717 3198
-3 3720 3718 2730
-3 1262 1519 4422
-3 2735 3191 3193
-3 3190 3191 2735
-3 3192 3193 3191
-3 2737 3194 3195
-3 2737 3193 3194
-3 3194 3196 3195
-3 3198 2738 2751
-3 2735 2746 3190
-3 2747 3190 2746
-3 3191 3190 2747
-3 3191 2747 3192
-3 2747 2737 3192
-3 3195 3199 2737
-3 3199 3192 2737
-3 3196 3199 3195
-3 3200 3199 3196
-3 3197 3200 3196
-3 2752 3202 3739
-3 2752 3739 3203
-3 2758 3204 3201
-3 3201 3204 2748
-3 3205 3202 3207
-3 3206 3202 3205
-3 2752 3207 3202
-3 2752 2759 3207
-3 2760 3203 3739
-3 3208 2760 3739
-3 3203 2760 2753
-3 2758 2762 3204
-3 2748 3204 2762
-3 3206 3205 3209
-3 3205 3210 3209
-3 3207 3211 3205
-3 3211 3210 3205
-3 2759 3211 3207
-3 2759 3213 3211
-3 2759 3208 3213
-3 3208 2759 2760
-3 3210 3212 3209
-3 3213 3212 3210
-3 3211 3213 3210
-3 3214 2764 2765
-3 3214 3750 2764
-3 3214 2773 3215
-3 3216 2773 3214
-3 2765 3216 3214
-3 2765 3217 3216
-3 2765 2764 3217
-3 3217 3218 3216
-3 3217 2764 3750
-3 2768 3219 2769
-3 2766 2769 3779
-3 2769 3219 3779
-3 3779 3220 2766
-3 3221 3223 3222
-3 3222 3223 3224
-3 2771 3771 3215
-3 2773 2771 3215
-3 3216 2774 2773
-3 3216 3218 2774
-3 2767 2783 3225
-3 3225 3226 2767
-3 2768 3227 3219
-3 3227 2768 2775
-3 3228 3229 2777
-3 3228 2777 3220
-3 3220 2777 2766
-3 3230 3231 3765
-3 3247 3221 3232
-3 3222 3233 3221
-3 3233 3232 3221
-3 3233 3222 3224
-3 2771 2778 3771
-3 2780 2774 3249
-3 3234 3235 3236
-3 3236 3235 2783
-3 3235 3237 2783
-3 3225 2783 3238
-3 3238 2783 3237
-3 3238 3239 3240
-3 3238 3240 3225
-3 3225 3240 3226
-3 2785 3226 3240
-3 3227 2775 3241
-3 3241 2777 3229
-3 3241 3229 3242
-3 3250 3242 3229
-3 3243 3231 3230
-3 3251 3231 3243
-3 3244 3245 3230
-3 3245 3243 3230
-3 2786 3247 3232
-3 2792 2786 3232
-3 2798 2792 3232
-3 2798 3232 3233
-3 2778 3249 3248
-3 3234 3819 3255
-3 3236 3819 3234
-3 3239 2790 3240
-3 3820 3227 3241
-3 3241 3242 3820
-3 3250 3820 3242
-3 3245 3252 3243
-3 3252 3251 3243
-3 3835 3245 3244
-3 3835 2795 3245
-3 2795 3252 3245
-3 3246 3247 3811
-3 2786 2797 3247
-3 3233 3812 2798
-3 2790 3819 3236
-3 2794 2793 3257
-3 2794 3257 3251
-3 2794 3251 3252
-3 3251 3257 3256
-3 2795 2794 3252
-3 3247 3271 3811
-3 2798 3812 3258
-3 2804 3259 3253
-3 3253 3260 2804
-3 3260 3253 3254
-3 3261 3263 3262
-3 3262 3263 3274
-3 3255 3265 3264
-3 3265 3255 3266
-3 3267 3268 3269
-3 3822 3268 3267
-3 3269 3833 2811
-3 3268 3833 3269
-3 2793 3834 3257
-3 2795 3835 3270
-3 2836 3271 3247
-3 3272 2798 3258
-3 2798 3272 2802
-3 2804 3260 3273
-3 2805 3285 3261
-3 2806 2805 3261
-3 3262 2806 3261
-3 2806 3262 3274
-3 3264 2807 3286
-3 2808 2807 3264
-3 2808 3264 3275
-3 3275 3264 3265
-3 3276 3265 3266
-3 3275 3265 3276
-3 2810 2809 3277
-3 2810 3277 3267
-3 2810 3267 3269
-3 2811 2810 3269
-3 3833 4338 2811
-3 3834 2812 3278
-3 3834 2793 2812
-3 3278 3279 3280
-3 3834 3278 3280
-3 3270 3280 3279
-3 2795 3270 2844
-3 2836 3293 3271
-3 3281 3272 3258
-3 3293 3281 3258
-3 3272 3281 2802
-3 2804 3282 3283
-3 2804 3283 2828
-3 3273 3282 2804
-3 2805 2817 3284
-3 2805 3284 3285
-3 2806 2831 2818
-3 2806 3274 2831
-3 3838 2831 3274
-3 3286 2807 2819
-3 3275 3298 2808
-3 3298 3275 3276
-3 3288 2822 3287
-3 2809 3289 3277
-3 2825 3289 2809
-3 2811 4338 2435
-3 4338 3301 2435
-3 3290 3278 2812
-3 3290 3279 3278
-3 3270 3279 3291
-3 3291 3279 3290
-3 3270 3291 2844
-3 2836 3292 3293
-3 3293 3292 3281
-3 2814 2827 3294
-3 2827 2828 3294
-3 3294 2828 3283
-3 2817 2830 3284
-3 3284 2830 2831
-3 3284 2831 3285
-3 3295 3297 2838
-3 3296 3297 3295
-3 2838 3297 2819
-3 2424 3299 3845
-3 3309 2428 3845
-3 2428 2424 3845
-3 2822 3300 3287
-3 2822 2821 3300
-3 2821 2832 3300
-3 3312 2834 3288
-3 3301 2825 2434
-3 2835 2435 3301
-3 3302 3291 3290
-3 3302 3313 3291
-3 3291 3313 2844
-3 2837 3292 2836
-3 3281 3292 2837
-3 3295 3303 3304
-3 3295 3305 3303
-3 2838 3305 3295
-3 3298 3306 2808
-3 3306 3298 3276
-3 3307 3308 3299
-3 3307 3299 2839
-3 2840 3310 2841
-3 3310 2840 2841
-3 3311 2840 3310
-3 2844 3313 3314
-3 2848 2844 3314
-3 2845 3315 3316
-3 2846 3315 2845
-3 2847 3316 3303
-3 2847 2845 3316
-3 3316 3304 3303
-3 3305 3317 3303
-3 3317 2847 3303
-3 3305 2853 3318
-3 3305 3318 3317
-3 3319 3308 3307
-3 3858 3308 3319
-3 2839 3320 3307
-3 3307 3320 3319
-3 3327 2839 3309
-3 2450 3321 2840
-3 2840 3321 3310
-3 2854 2840 3311
-3 2834 3312 2457
-3 2846 2464 3323
-3 2846 3323 3324
-3 2846 3324 3315
-3 2847 3856 3325
-3 2847 3325 2852
-3 3317 3856 2847
-3 3318 3856 3317
-3 3326 3856 3318
-3 3318 2853 3326
-3 3319 3867 3858
-3 3320 3867 3319
-3 3327 3320 2839
-3 3321 2861 3328
-3 2832 3329 3300
-3 3302 3347 3863
-3 3330 3864 3344
-3 3330 3331 3332
-3 3864 3330 3332
-3 3322 3332 3331
-3 3322 3331 3333
-3 2856 3322 3334
-3 3334 3322 3333
-3 2464 2858 3335
-3 2464 3335 3323
-3 3335 3336 3323
-3 2860 3866 3323
-3 2860 3323 3336
-3 3324 3323 3866
-3 3325 2860 2852
-3 3866 2860 3325
-3 2485 3326 2853
-3 2485 3337 3326
-3 3337 3857 3326
-3 3338 3857 3337
-3 3339 3306 3858
-3 2854 3340 2862
-3 3345 2854 3311
-3 3345 3340 2854
-3 2457 3312 2863
-3 2864 3341 3302
-3 3302 3341 3347
-3 3342 3341 2864
-3 2855 3343 2864
-3 2864 3343 3342
-3 2855 3344 3343
-3 3344 2849 3330
-3 2856 3331 3330
-3 3333 3331 2856
-3 3334 3333 2856
-3 2860 3336 3335
-3 3873 3338 3337
-3 2486 3306 3339
-3 3350 2861 2862
-3 2862 3340 3350
-3 3345 3350 3340
-3 3348 3341 3342
-3 3347 3341 3348
-3 2485 3873 3337
-3 3339 3349 2486
-3 3345 3880 3350
-3 3346 3880 3345
-3 3348 3353 3347
-3 3353 3352 3347
-3 3348 3358 3353
-3 3873 2485 3889
-3 3354 2486 3349
-3 3355 3351 3877
-3 3356 3355 3877
-3 2871 3358 2870
-3 2871 3353 3358
-3 3359 3358 3891
-3 3359 2872 3358
-3 2872 2870 3358
-3 2486 3354 3889
-3 3360 3351 3355
-3 3361 3351 3360
-3 3356 3360 3355
-3 3356 3362 2875
-3 3356 3357 3362
-3 2875 3362 2876
-3 2871 2877 3353
-3 2877 3891 3353
-3 2879 3363 3359
-3 2879 3359 3891
-3 2879 3891 2877
-3 2872 3363 3365
-3 3359 3363 2872
-3 2876 3362 2885
-3 3363 2882 3364
-3 2879 2882 3363
-3 3363 3364 3365
-3 3894 2881 2888
-3 3894 2888 3362
-3 3366 3364 2882
-3 3366 3365 3364
-3 3365 3367 2883
-3 3365 3366 3367
-3 2885 3362 2888
-3 3369 3368 3366
-3 3368 3367 3366
-3 3367 3368 2883
-3 2883 3370 2891
-3 2883 3368 3370
-3 3368 3369 3370
-3 2893 3369 2892
-3 3370 3369 2893
-3 2891 3370 2893
-3 3372 3373 3371
-3 3375 3372 3371
-3 2894 3375 3373
-3 3373 3375 3371
-3 2894 3374 3376
-3 2894 3373 3374
-3 2500 4373 3952
-3 3381 3372 3375
-3 3375 2894 3381
-3 3377 2894 3376
-3 2896 2894 3377
-3 2896 3377 2897
-3 3381 3382 3383
-3 3381 2897 3382
-3 3382 2897 3377
-3 3386 3385 3378
-3 3387 3386 3378
-3 3389 3379 3380
-3 3388 3379 3389
-3 3391 3390 3384
-3 3385 3391 3384
-3 3392 3391 3385
-3 3386 3393 3385
-3 3393 3392 3385
-3 3387 3394 3386
-3 3394 3393 3386
-3 3395 3394 3387
-3 3396 3379 3388
-3 3405 3379 3396
-3 3397 3388 3389
-3 3396 3388 3397
-3 2900 2500 3952
-3 3398 3399 2898
-3 3402 3401 3382
-3 3940 3390 3391
-3 3392 3393 3403
-3 3394 3404 3393
-3 3404 3403 3393
-3 3395 3404 3394
-3 3397 3405 3396
-3 3411 2900 3952
-3 3406 3399 3410
-3 3398 3410 3399
-3 2899 2904 3400
-3 2906 2900 3411
-3 3407 3406 3408
-3 3406 3409 3408
-3 3410 3409 3406
-3 3400 2904 2903
-3 3411 3408 2906
-3 2906 3408 2907
-3 2907 3408 3412
-3 3954 3408 3409
-3 2908 3954 3409
-3 2908 3409 3410
-3 3414 2909 3413
-3 2505 4514 2909
-3 2909 4514 3413
-3 3956 3951 3403
-3 3934 3403 3951
-3 2907 3412 3953
-3 2910 2907 3953
-3 2911 2910 3954
-3 2910 3953 3954
-3 3954 2908 2911
-3 2505 3416 4514
-3 2912 3415 3416
-3 2912 3416 2505
-3 2912 2913 3417
-3 3415 2912 3417
-3 3418 3422 3417
-3 3417 2913 3418
-3 3418 3943 3422
-3 2915 3945 2905
-3 3945 3955 2914
-3 3427 3956 3403
-3 3419 3416 3415
-3 3420 3416 3419
-3 3417 3421 3415
-3 3421 3419 3415
-3 3422 3421 3417
-3 3943 3423 3422
-3 3423 3943 3945
-3 3423 3945 2915
-3 3955 3424 2914
-3 3414 3959 2513
-3 3420 3419 2513
-3 3420 2513 3959
-3 3421 2513 3419
-3 3422 3423 3421
-3 3427 2515 2914
-3 3427 2914 3424
-3 2916 3962 3425
-3 3426 2916 3425
-3 4531 3965 1226
-3 3428 1226 3965
-3 3426 3425 2917
-3 1226 5643 4531
-3 3428 3965 3430
-3 3428 3430 3431
-3 3429 2916 3428
-3 3431 3429 3428
-3 3432 2918 3433
-3 3433 2918 2919
-3 3432 2520 2918
-3 2919 3435 3433
-3 3435 2919 2920
-3 3433 3434 3438
-3 3433 3435 3434
-3 2921 3436 2920
-3 2920 3436 3435
-3 2520 4582 2522
-3 3438 3434 3437
-3 3434 3435 3437
-3 3439 3437 3435
-3 3440 3439 3436
-3 3439 3435 3436
-3 3975 3436 2921
-3 1635 3975 2921
-3 3437 2923 3438
-3 3440 3437 3439
-3 3440 2922 3437
-3 1635 2180 3975
-3 2922 3441 2923
-3 3441 2922 3440
-3 2924 3978 2925
-3 3442 2925 3978
-3 3978 2927 3443
-3 3978 2924 2927
-3 3442 3978 3443
-3 3442 3443 2928
-3 3442 2928 2929
-3 2931 3442 2929
-3 2931 3444 3442
-3 2925 3442 2932
-3 2932 3442 3444
-3 2928 3443 2927
-3 3444 2934 3445
-3 2931 2934 3444
-3 2932 3445 2935
-3 3444 3445 2932
-3 2934 2936 3445
-3 2935 3445 2936
-3 2522 3995 3450
-3 4002 3446 3447
-3 3983 3447 3446
-3 3983 3448 3447
-3 3447 3449 4002
-3 3448 3449 3447
-3 3451 3452 3449
-3 3451 3453 3454
-3 3449 3453 3451
-3 3450 3459 2938
-3 3455 3450 3995
-3 3459 3450 3455
-3 2941 3456 4020
-3 4020 2942 2941
-3 3457 3451 3454
-3 2938 3459 2947
-3 4020 3456 2950
-3 2950 2942 4020
-3 3459 3460 2947
-3 2948 2952 3461
-3 3462 4024 4027
-3 3463 3464 4028
-3 2952 3463 3465
-3 2952 3460 3463
-3 2952 2947 3460
-3 3464 3463 3460
-3 2952 3465 3461
-3 3465 3466 3461
-3 2948 3461 3467
-3 3461 3466 3467
-3 3463 4028 3481
-3 3463 3481 2954
-3 3468 3463 2954
-3 3468 3465 3463
-3 3466 3465 3469
-3 3469 3465 3468
-3 3467 3466 3469
-3 3467 3469 3470
-3 2954 3481 2956
-3 2970 3469 3468
-3 3470 3469 2970
-3 3471 3473 2958
-3 2958 3474 2959
-3 3473 3474 2958
-3 3475 3476 3477
-3 3472 3496 3478
-3 3472 3478 3479
-3 3480 4033 3472
-3 3479 3480 3472
-3 2956 3481 2963
-3 3470 2972 3471
-3 2972 3473 3471
-3 3474 3473 3482
-3 3474 3482 2959
-3 3483 3476 3475
-3 3486 3476 3483
-3 3483 3475 3486
-3 3478 3496 2965
-3 3478 2965 2966
-3 2967 3478 2966
-3 2967 3484 3478
-3 3484 3479 3478
-3 4642 3480 3479
-3 3484 4642 3479
-3 3481 2968 2963
-3 3493 2968 3481
-3 3473 2972 3487
-3 3482 3473 3485
-3 3485 3473 3487
-3 2959 3485 2976
-3 3482 3485 2959
-3 2965 3496 2973
-3 2967 3501 3484
-3 3501 4642 3484
-3 2968 3493 2974
-3 2972 2975 3487
-3 3485 3487 3488
-3 3485 3488 2976
-3 2974 3493 2979
-3 2975 2980 2983
-3 3487 2975 2983
-3 2976 3488 3489
-3 3491 3492 3490
-3 2973 3496 2981
-3 2982 2979 3493
-3 3487 2983 3495
-3 3488 3487 2985
-3 2985 3487 3495
-3 3489 3488 2985
-3 2976 3489 2985
-3 3492 3494 3490
-3 3497 2982 3493
-3 2982 3497 2990
-3 3495 2983 2988
-3 3493 3502 3497
-3 2990 3497 3499
-3 3499 3497 3498
-3 2990 3499 3500
-3 3497 3502 3505
-3 3498 3497 3506
-3 3506 3497 3505
-3 3499 3498 3500
-3 3500 3498 3506
-3 2990 3500 3503
-3 2990 3503 2995
-3 3507 3504 3502
-3 3505 3502 3504
-3 3505 3504 3506
-3 3506 3504 3507
-3 3507 3508 3506
-3 3509 3506 3508
-3 3503 3500 2999
-3 3500 3506 2999
-3 3506 3509 3000
-3 2999 3506 3000
-3 3509 3510 3001
-3 3001 3510 3006
-3 3510 3007 3006
-3 1936 4702 3036
-3 3007 3510 3008
-3 3511 3518 3510
-3 3008 3510 3518
-3 3511 3513 3518
-3 3015 3016 3512
-3 3015 3512 3017
-3 3511 3514 3513
-3 3512 3021 3515
-3 3016 3021 3512
-3 3017 3515 3022
-3 3512 3515 3017
-3 3516 3513 3514
-3 3517 3516 3514
-3 3518 3513 3516
-3 3518 3045 3008
-3 3021 3020 3515
-3 3022 3515 3020
-3 3521 3030 3522
-3 3524 3523 3525
-3 3531 3516 3517
-3 3518 3516 3526
-3 3526 3516 3531
-3 3549 3518 3526
-3 3518 3549 3045
-3 3032 3527 3519
-3 3519 3527 3025
-3 3033 3520 3521
-3 3522 3543 3521
-3 3528 3543 3522
-3 3030 3528 3522
-3 3030 3529 3528
-3 3523 3524 3536
-3 3530 3525 3523
-3 3536 3530 3523
-3 3526 3531 3563
-3 3032 3540 3541
-3 3527 3032 3541
-3 3521 3577 3033
-3 3577 3533 3033
-3 3571 3528 3529
-3 3534 3571 3529
-3 3034 3037 3529
-3 3529 3037 3534
-3 3537 3530 3536
-3 3537 3536 3538
-3 3531 3537 3538
-3 3531 3538 3563
-3 3532 4063 3542
-3 3037 3544 3534
-3 3544 3556 3534
-3 3535 3544 3037
-3 3038 3544 3535
-3 3544 3038 3040
-3 3545 3042 3041
-3 3545 3041 3546
-3 3041 3547 3546
-3 3524 3548 3536
-3 3536 3548 3561
-3 3562 3536 3561
-3 3538 3536 3562
-3 3526 3563 3549
-3 3541 3540 3550
-3 3550 3540 3564
-3 3541 3550 3527
-3 4063 3049 3553
-3 4063 3532 3049
-3 4063 3553 3542
-3 3533 3554 3039
-3 3577 3554 3533
-3 3543 3555 3521
-3 3528 3570 3543
-3 3571 3570 3528
-3 3534 3556 3571
-3 3040 3557 3544
-3 3546 3559 3558
-3 3546 3558 3545
-3 3545 3558 3560
-3 3042 3560 3041
-3 3545 3560 3042
-3 3548 3547 3573
-3 3573 3547 3041
-3 3561 3548 3573
-3 3538 4069 3563
-3 2611 3550 3564
-3 3552 3565 5316
-3 3551 3565 3552
-3 3551 3047 3565
-3 3551 3048 3047
-3 3542 3553 3566
-3 3577 3576 3554
-3 3521 3579 3577
-3 3555 3567 3521
-3 3567 3579 3521
-3 3543 3568 3555
-3 3568 3567 3555
-3 3569 3568 3543
-3 3570 3569 3543
-3 3557 3556 3544
-3 3040 3056 3557
-3 3557 3056 3582
-3 3560 3558 3572
-3 3560 3572 3041
-3 3050 3573 3041
-3 3549 3563 3585
-3 3564 3061 3575
-3 2611 3575 3054
-3 3564 3575 2611
-3 3565 3066 5316
-3 3047 3066 3565
-3 3048 3551 3068
-3 3039 4081 3078
-3 4081 3039 4072
-3 3554 4074 3039
-3 4074 3554 3576
-3 3579 3578 3577
-3 3567 3580 3579
-3 3568 3580 3567
-3 3569 3581 3568
-3 3556 3582 3571
-3 3557 3582 3556
-3 3057 3589 3069
-3 3057 3058 3589
-3 3593 3558 3559
-3 3572 3558 3593
-3 3572 3583 3050
-3 3050 3583 3573
-3 3583 3561 3573
-3 3584 3561 3585
-3 3563 3584 3585
-3 3549 3585 3081
-3 3598 3599 3574
-3 3586 3054 3575
-3 5316 3066 3065
-3 3611 3566 3553
-3 3577 4074 3576
-3 4089 4074 3577
-3 3578 4089 3577
-3 3579 4089 3578
-3 3580 4089 3579
-3 3580 3568 4083
-3 3581 3588 3568
-3 3588 4083 3568
-3 3569 3588 3581
-3 3570 3588 3569
-3 3571 3604 3570
-3 3604 3588 3570
-3 3582 3604 3571
-3 3056 3589 3582
-3 3056 3069 3589
-3 3058 3590 3589
-3 3058 3591 3590
-3 3074 3591 3058
-3 3591 3074 3592
-3 3559 3594 3593
-3 3572 3593 3595
-3 3583 3572 3596
-3 3596 3572 3595
-3 3585 3561 3597
-3 3599 3609 3052
-3 3061 3071 3600
-3 3575 3061 3600
-3 3062 3601 3085
-3 3586 3601 3062
-3 3065 3602 5316
-3 3068 3602 3065
-3 3566 3611 3603
-3 3566 3603 3612
-3 3587 2279 3055
-3 3604 4083 3588
-3 3605 3604 3582
-3 4085 3582 3589
-3 3590 4085 3589
-3 3074 3606 3592
-3 3594 3606 3593
-3 3583 3596 3615
-3 3561 3583 3615
-3 3597 3561 3615
-3 3585 3597 3607
-3 3081 3585 3619
-3 3598 3070 3608
-3 3599 3598 3609
-3 3609 3598 3608
-3 3610 3600 3076
-3 3600 3071 3076
-3 3601 3076 3085
-3 3553 3088 3611
-3 3603 3611 3612
-3 5338 3587 2278
-3 3613 3606 3074
-3 3613 3593 3606
-3 3595 3593 3613
-3 3596 3595 3614
-3 3614 3595 3613
-3 3615 3596 3614
-3 3597 3615 3617
-3 3617 3615 3616
-3 3607 3597 3618
-3 3618 3597 3617
-3 3585 3607 3625
-3 3625 3607 3618
-3 3619 3585 3625
-3 3626 3608 3070
-3 3609 3608 3620
-3 3620 3608 3626
-3 3612 3611 3621
-3 3621 3611 3088
-3 3078 4081 4097
-3 3622 3613 3080
-3 3622 3614 3613
-3 3615 3614 3623
-3 3623 3614 3622
-3 3623 4697 3616
-3 3623 3616 3615
-3 3617 3616 4697
-3 3624 3617 4697
-3 3617 3624 3618
-3 3625 3618 3624
-3 3627 3612 3621
-3 4672 3612 3627
-3 3094 3644 3622
-3 3644 3623 3622
-3 3644 3636 3623
-3 3625 3624 3628
-3 3619 3625 3629
-3 3639 3619 3629
-3 3630 3619 3639
-3 3089 3631 3626
-3 3621 3088 3632
-3 3632 4116 3621
-3 4116 4117 3621
-3 3627 3621 3633
-3 3633 3621 4117
-3 3643 4672 3627
-3 3643 3627 3633
-3 2279 3635 3634
-3 4115 3637 3628
-3 3625 3628 3638
-3 3638 3628 3637
-3 3629 3625 3639
-3 3639 3625 3638
-3 3630 3639 3649
-3 3089 3630 3640
-3 3640 3630 3649
-3 3641 3089 3640
-3 3631 3089 3641
-3 3116 3626 3631
-3 4117 3643 3633
-3 3094 3098 3644
-3 3645 3636 3644
-3 3645 3644 3646
-3 3645 3646 4115
-3 3637 4115 3646
-3 3637 3646 3099
-3 3100 3637 3099
-3 3638 3637 3100
-3 3647 3638 3100
-3 3647 3639 3638
-3 3648 3639 3647
-3 3649 3639 3648
-3 3640 3649 3650
-3 3650 3641 3640
-3 3651 3116 3631
-3 3632 3642 3105
-3 4116 3632 3652
-3 3652 3632 3105
-3 3098 3102 3644
-3 3649 3648 3654
-3 3654 3648 3647
-3 3654 3650 3649
-3 4694 4168 3655
-3 3634 4694 3655
-3 3653 3634 3655
-3 3656 3653 3655
-3 3634 3653 3656
-3 3102 3657 3644
-3 3646 3644 3662
-3 3662 3644 3657
-3 3658 3650 3654
-3 3664 3116 3651
-3 3659 3660 3111
-3 3104 3672 3105
-3 3672 3652 3105
-3 3662 3657 3661
-3 3654 3115 3658
-3 3658 3115 3663
-3 3118 4162 3660
-3 3659 3118 3660
-3 3120 3665 3666
-3 3120 3111 3665
-3 4163 3652 3672
-3 3655 4168 3121
-3 3663 3115 3676
-3 3663 3676 3677
-3 3664 3668 3125
-3 3669 4162 3118
-3 3669 3118 3126
-3 3126 3127 3670
-3 3127 3120 3666
-3 3127 3666 3670
-3 3670 3666 3129
-3 3129 3665 3128
-3 3129 3666 3665
-3 3671 3128 3665
-3 3671 3132 3128
-3 4163 3672 3673
-3 4163 3674 3667
-3 3675 3667 3674
-3 4170 3667 3675
-3 3662 3661 3158
-3 3668 3677 3676
-3 3668 3676 3136
-3 3125 3668 3136
-3 3126 3678 3669
-3 3670 3678 3126
-3 3129 3678 3670
-3 3129 3128 3678
-3 3141 3679 3671
-3 3141 3671 3678
-3 3141 3678 3128
-3 3132 3671 3680
-3 3680 3671 3679
-3 3132 3143 3142
-3 3132 3680 3143
-3 3673 3672 3674
-3 4163 3673 3674
-3 3675 3674 3681
-3 3153 3679 3141
-3 3680 3679 3153
-3 3143 3680 3153
-3 3171 3681 3674
-3 3704 4170 3675
-3 3121 4168 3682
-3 3161 3688 3152
-3 3138 3152 3689
-3 3689 3152 3688
-3 3689 4189 3139
-3 3689 3139 3138
-3 3690 3139 4189
-3 3675 3681 3691
-3 3682 3706 3692
-3 3156 3165 3694
-3 3155 3165 3156
-3 4193 3684 3694
-3 3694 3684 3156
-3 4195 3684 4193
-3 3686 4196 3685
-3 3695 4196 3686
-3 3687 3695 3686
-3 3157 3696 3166
-3 3688 3161 3697
-3 3177 3170 4833
-3 4833 3170 3690
-3 3180 3691 3681
-3 3704 3691 3180
-3 3675 3691 3704
-3 3717 4180 3704
-3 3692 3706 3720
-3 3165 2719 3694
-3 4193 3694 2719
-3 3684 4195 3714
-3 3699 3700 3701
-3 3173 3701 3696
-3 3173 3699 3701
-3 3702 3175 3701
-3 3696 3701 3175
-3 3696 3175 3166
-3 3161 3703 3697
-3 3177 3703 3161
-3 3703 3177 4833
-3 3717 3704 3198
-3 3705 4180 3717
-3 3692 3720 3707
-3 3682 3692 3707
-3 3708 3710 3711
-3 3709 3710 3708
-3 3710 3712 3711
-3 4841 4193 2719
-3 3714 3727 3713
-3 3715 3700 3699
-3 3173 3185 3715
-3 3173 3715 3699
-3 4190 3705 3718
-3 3706 4190 3718
-3 3719 3706 3718
-3 3720 3706 3719
-3 3183 3721 3184
-3 3184 3728 2708
-3 3721 3728 3184
-3 2708 3728 2718
-3 3708 3722 3709
-3 3722 3723 3724
-3 3722 3708 3723
-3 3708 3711 3723
-3 3725 3711 3712
-3 3723 3711 3725
-3 4841 2719 3726
-3 3185 4211 3715
-3 4211 3185 3716
-3 3705 3717 3731
-3 3718 3705 3731
-3 3720 3719 3718
-3 3183 3186 3721
-3 3728 3189 2718
-3 3723 3729 3724
-3 3725 3729 3723
-3 4841 3726 4223
-3 3726 3713 4223
-3 3727 3730 3713
-3 3730 4223 3713
-3 3187 3189 3733
-3 3733 3189 3728
-3 3734 3186 3732
-3 3188 3734 3732
-3 3188 3735 3734
-3 3188 3187 3735
-3 3735 3187 3733
-3 3193 3192 3736
-3 3193 3737 3194
-3 3736 3737 3193
-3 3194 3738 3196
-3 3737 3738 3194
-3 3196 3738 3197
-3 3199 3736 3192
-3 3737 3736 3199
-3 3200 3737 3199
-3 3738 3737 3200
-3 3197 3738 3200
-3 3202 3206 4254
-3 3206 4253 4254
-3 3202 4254 3740
-3 3202 3740 3739
-3 3739 3740 3208
-3 4253 3206 3209
-3 3741 4253 3209
-3 3740 4254 3742
-3 3740 3742 3213
-3 3208 3740 3213
-3 3743 3744 3745
-3 3745 3746 3743
-3 3212 3747 3741
-3 3212 3741 3209
-3 3212 3213 3748
-3 3742 3748 3213
-3 3749 3750 3214
-3 3743 3746 3761
-3 3751 3752 3746
-3 3752 3761 3746
-3 3752 3753 3754
-3 3751 3753 3752
-3 3741 3755 3756
-3 3741 3747 3755
-3 3212 3757 3747
-3 3758 3748 4268
-3 3758 3757 3748
-3 3757 3212 3748
-3 3215 3749 3214
-3 3215 3759 3749
-3 3750 3749 3760
-3 3760 3749 3759
-3 3217 3760 3218
-3 3217 3750 3760
-3 3754 3762 3752
-3 3762 3761 3752
-3 3774 3754 3753
-3 3762 3754 3774
-3 3219 3778 3779
-3 3763 4266 4262
-3 4267 3764 4262
-3 3764 3763 4262
-3 3765 3764 4267
-3 3223 3221 3766
-3 3756 3755 3223
-3 3756 3223 3766
-3 3224 3223 3755
-3 3224 3755 3767
-3 3767 3755 3747
-3 3757 3768 3747
-3 3768 3767 3747
-3 3758 3769 3757
-3 3769 3768 3757
-3 3769 3770 3771
-3 3758 3770 3769
-3 3770 3772 3771
-3 3771 3772 3215
-3 3759 3215 3772
-3 3760 3759 2774
-3 3760 2774 3218
-3 3761 3762 3773
-3 3774 3775 3762
-3 3775 3773 3762
-3 3775 4277 3776
-3 3774 4277 3775
-3 3234 3777 3235
-3 3778 3219 3227
-3 3778 3227 4278
-3 3220 3779 3228
-3 3228 3779 4279
-3 4279 3229 3228
-3 3780 4266 3763
-3 3764 3781 3763
-3 3781 3780 3763
-3 3765 3231 3781
-3 3765 3781 3764
-3 3765 3796 3230
-3 3782 3783 3246
-3 3246 3783 3247
-3 3783 3766 3247
-3 3766 3221 3247
-3 3224 3767 3233
-3 3784 3768 3785
-3 3784 3767 3768
-3 3769 3785 3768
-3 3786 3785 3769
-3 3769 3771 3786
-3 3801 3786 3771
-3 3771 2778 3801
-3 4285 3249 2774
-3 3775 3790 3773
-3 3790 3789 3773
-3 3776 3790 3775
-3 3791 3776 4277
-3 3791 3790 3776
-3 3234 3255 3807
-3 3235 3777 3793
-3 3794 3237 3793
-3 3237 3235 3793
-3 3237 3239 3238
-3 3794 3239 3237
-3 4278 3227 3795
-3 3229 4279 3821
-3 3250 3229 3821
-3 3780 3781 4294
-3 3231 3251 4294
-3 3781 3231 4294
-3 3244 3230 3796
-3 4296 3783 3797
-3 3783 3782 3797
-3 3246 3797 3782
-3 3767 4297 3798
-3 3767 3798 3233
-3 3233 3798 3812
-3 3784 4297 3767
-3 3802 3801 2778
-3 2778 3248 3802
-3 3248 3249 4285
-3 3248 4285 3802
-3 3254 3803 3787
-3 3787 3260 3254
-3 3804 3787 3788
-3 3804 3260 3787
-3 3805 3790 3791
-3 3792 3805 3791
-3 3807 3255 3806
-3 3794 3819 2790
-3 3239 3794 2790
-3 3795 3227 3820
-3 4294 3251 3823
-3 3808 3835 3244
-3 3808 3244 3809
-3 3809 3244 3796
-3 3810 4296 3797
-3 3811 3810 3797
-3 3246 3811 3797
-3 3812 3813 4306
-3 3812 3798 3813
-3 3803 3254 3814
-3 3814 3254 3253
-3 4314 3260 3804
-3 3817 3831 3818
-3 3255 3264 3806
-3 3821 3820 3250
-3 3821 3822 3820
-3 3822 3833 3268
-3 3821 3833 3822
-3 3256 3823 3251
-3 3257 3824 3825
-3 3257 3825 3256
-3 3256 3825 3823
-3 3809 3825 3824
-3 3809 3824 3808
-3 3808 3824 3826
-3 3808 3826 3835
-3 3827 3810 3811
-3 3811 3271 3827
-3 3812 4306 3830
-3 3258 3830 3829
-3 3258 3812 3830
-3 4320 3253 3259
-3 3260 4314 3273
-3 3261 3815 3816
-3 3263 3261 3816
-3 3817 3263 3816
-3 3818 3263 3817
-3 3274 3263 3818
-3 3274 3818 3831
-3 3264 3286 3806
-3 3255 3819 3266
-3 3795 3820 3843
-3 3822 3267 3843
-3 3822 3843 3820
-3 3257 3834 3824
-3 3834 3826 3824
-3 3826 3834 3835
-3 3271 3836 3828
-3 3830 3836 3829
-3 3829 3836 3837
-3 3829 3837 3258
-3 3259 2814 4330
-3 4330 4320 3259
-3 3273 4314 4332
-3 3261 3285 3815
-3 3831 3838 3274
-3 3839 3831 3832
-3 3839 3840 3831
-3 3840 3838 3831
-3 3286 3842 3806
-3 3267 3277 3843
-3 3835 3834 3280
-3 3270 3835 3280
-3 3293 3836 3271
-3 3293 3837 3836
-3 3837 3293 3258
-3 2814 3294 4331
-3 2814 4331 4330
-3 3294 3283 3282
-3 3294 3282 4331
-3 4331 3282 4332
-3 4332 3282 3273
-3 3815 3285 4347
-3 4348 3838 4340
-3 3840 4340 3838
-3 3841 3296 4335
-3 3844 3297 3841
-3 3297 3296 3841
-3 3844 3286 2819
-3 3844 4342 3286
-3 4342 3842 3286
-3 3266 4336 3276
-3 3288 3287 4913
-3 3287 4337 4913
-3 3312 3288 4913
-3 3277 3846 3843
-3 3289 3846 3277
-3 4338 4345 3301
-3 3285 2831 4347
-3 4348 4347 2831
-3 3838 4348 2831
-3 3296 3295 4335
-3 3844 2819 3297
-3 3287 3300 3850
-3 3287 3850 4337
-3 2825 3846 3289
-3 2825 3301 3846
-3 3846 3301 4345
-3 3863 3847 3302
-3 3847 3853 3302
-3 3853 3313 3302
-3 3304 3856 4335
-3 3295 3304 4335
-3 3848 3306 4336
-3 4336 3306 3276
-3 3299 3308 3848
-3 3845 3299 3848
-3 3309 3845 4357
-3 3310 3849 3311
-3 3851 3847 3863
-3 3314 3313 4361
-3 3313 3853 4361
-3 3314 4361 4362
-3 3854 3314 4362
-3 3316 3315 3855
-3 3316 3855 3856
-3 3316 3856 3304
-3 3306 3848 3858
-3 3848 3308 3858
-3 3309 4357 3859
-3 3309 3859 3327
-3 3849 3321 3860
-3 3310 3321 3849
-3 3311 3849 3861
-3 3849 3860 3861
-3 3862 3852 3851
-3 3863 3862 3851
-3 3314 3854 3864
-3 3314 3865 3322
-3 3864 3865 3314
-3 3855 3324 3866
-3 3315 3324 3855
-3 3325 3856 3855
-3 3325 3855 3866
-3 3326 4364 3856
-3 3857 4364 3326
-3 3327 3867 3320
-3 3860 3328 3868
-3 3321 3328 3860
-3 3868 4374 3861
-3 3868 3861 3860
-3 3311 3861 4374
-3 3311 4374 3869
-3 3850 3300 3329
-3 3347 3862 3863
-3 3871 3343 3870
-3 3864 3870 3343
-3 3344 3864 3343
-3 3865 3864 3332
-3 3322 3865 3332
-3 3858 3867 3339
-3 3328 2861 3868
-3 2861 3874 3868
-3 3311 3869 3345
-3 3345 3872 3877
-3 3345 3869 3872
-3 3872 3876 3877
-3 2863 4378 3329
-3 4378 2863 3312
-3 3347 3878 3862
-3 3343 3871 3342
-3 3338 3873 3857
-3 3867 3879 3339
-3 2861 3350 3874
-3 3877 3875 3346
-3 3345 3877 3346
-3 3342 4399 3348
-3 4395 3857 3873
-3 4395 3349 3879
-3 3349 3339 3879
-3 3880 3874 3350
-3 3880 3346 3875
-3 3880 3875 3881
-3 3877 3351 3881
-3 3877 3881 3875
-3 3877 3876 3356
-3 3882 3352 3883
-3 3882 3878 3352
-3 3878 3347 3352
-3 3348 3883 3884
-3 3348 4399 3883
-3 3882 3883 4399
-3 3348 3884 3358
-3 3885 3887 3888
-3 3886 3887 3885
-3 3887 4407 3888
-3 3889 4395 3873
-3 3354 3349 3889
-3 3349 4395 3889
-3 3874 3880 3361
-3 3880 3881 3361
-3 3881 3351 3361
-3 3356 3876 3357
-3 3876 3362 3357
-3 3353 3883 3352
-3 3353 3890 3883
-3 3890 3884 3883
-3 3358 3884 3891
-3 3884 3890 3891
-3 3893 3885 3892
-3 3892 3888 4407
-3 3892 3885 3888
-3 3891 3890 3353
-3 3361 3360 3894
-3 2881 3894 3360
-3 3896 3895 3898
-3 3895 3899 3898
-3 3900 3899 3895
-3 3904 3903 3897
-3 3903 3910 3897
-3 3899 3905 3898
-3 3906 3905 3899
-3 3900 3906 3899
-3 3906 3900 3907
-3 3900 3901 3907
-3 3908 3901 3902
-3 3907 3901 3908
-3 3909 3905 3906
-3 3909 3898 3905
-3 3904 3910 3903
-3 3913 3373 3372
-3 3374 3911 3376
-3 3374 3913 3911
-3 3374 3373 3913
-3 3912 3914 3911
-3 3914 3376 3911
-3 3916 3913 3372
-3 3376 3914 4473
-3 3372 3381 3916
-3 3376 4473 4486
-3 3376 4486 3377
-3 3920 3921 3919
-3 3916 3381 3929
-3 3377 4486 3382
-3 3384 3918 3917
-3 3385 3384 3917
-3 3917 5068 3385
-3 4476 3378 3385
-3 3378 3926 3387
-3 3378 4476 3926
-3 3379 3922 3380
-3 3923 3920 3919
-3 3924 3920 3923
-3 3925 3919 3921
-3 3923 3919 3925
-3 3922 3379 3927
-3 3380 3927 3389
-3 3922 3927 3380
-3 3923 2899 3924
-3 3923 3925 3928
-3 3923 3928 2899
-3 3929 3381 3383
-3 3929 3383 3401
-3 3401 3383 3382
-3 4506 3402 3382
-3 3384 3390 3918
-3 3387 3926 3395
-3 3927 3405 3930
-3 3379 3405 3927
-3 3389 3930 3397
-3 3927 3930 3389
-3 2898 3399 3924
-3 3399 3935 3924
-3 3400 2898 3924
-3 3924 2899 3400
-3 2899 3928 3936
-3 4506 3932 3402
-3 4506 3939 3932
-3 3933 3390 3940
-3 3940 3391 3942
-3 3391 3392 3934
-3 3942 3391 3934
-3 3392 3403 3934
-3 3397 3930 3405
-3 3407 3935 3406
-3 3931 3935 3407
-3 3399 3406 3935
-3 3401 3402 3937
-3 3402 3932 3937
-3 3937 3932 3938
-3 3939 3938 3932
-3 3940 3939 3933
-3 3942 3941 3940
-3 3934 3951 3942
-3 3931 3408 3952
-3 3407 3408 3931
-3 3943 3418 2899
-3 3943 2899 3936
-3 3937 5130 3401
-3 5130 3937 3946
-3 3937 3938 3946
-3 3939 3947 3938
-3 3947 3946 3938
-3 3948 3947 3939
-3 3940 3949 3939
-3 3949 3948 3939
-3 3941 3950 3940
-3 3950 3949 3940
-3 3942 3951 3941
-3 3951 3950 3941
-3 3408 3411 3952
-3 3408 3953 3412
-3 3953 3408 3954
-3 3413 4514 4511
-3 3944 3945 3943
-3 5130 3946 3956
-3 3946 3947 3956
-3 3948 3956 3947
-3 3949 3956 3948
-3 3951 3956 3949
-3 3950 3951 3949
-3 3957 4511 4513
-3 3957 3414 4511
-3 3414 3413 4511
-3 3427 5130 3956
-3 3414 3957 3958
-3 3957 4513 3958
-3 3414 3958 3959
-3 4514 3416 3960
-3 3960 3416 3420
-3 3960 3420 3959
-3 3960 3959 3961
-3 3960 3961 4525
-3 3427 3964 5130
-3 2917 3425 3962
-3 3963 3959 3958
-3 3961 3959 3963
-3 4525 3961 3963
-3 3427 3424 3964
-3 3966 2916 3429
-3 3430 3965 4529
-3 3431 3430 3966
-3 3429 3431 3966
-3 3967 3969 3970
-3 3968 3967 3970
-3 4532 3968 3970
-3 3971 4532 3970
-3 3970 3969 4545
-3 4548 3971 3970
-3 2520 3432 4578
-3 3432 3972 4578
-3 3433 3972 3432
-3 3433 3438 3972
-3 2520 4578 4582
-3 3438 3973 3972
-3 3440 3436 4588
-3 4588 3436 3975
-3 3974 3973 2923
-3 3973 3438 2923
-3 3974 3440 4588
-3 4588 3975 3977
-3 2923 3441 3974
-3 3440 3974 3441
-3 3980 3977 3975
-3 3975 2180 3980
-3 3980 3979 3977
-3 4601 3980 2180
-3 4582 3986 2522
-3 3984 3981 3983
-3 3982 3983 3981
-3 3983 3982 4605
-3 3983 3985 3984
-3 3983 3446 3985
-3 3986 3987 2522
-3 3987 3995 2522
-3 3987 3986 3988
-3 3988 3986 3989
-3 3986 3990 3989
-3 3446 4002 3991
-3 3446 3991 3985
-3 3983 4605 3448
-3 4605 4611 3448
-3 2180 4051 5237
-3 3992 3993 3994
-3 3994 3993 4621
-3 3987 3996 3995
-3 3988 3997 3987
-3 3997 3996 3987
-3 3998 3989 3999
-3 3998 3997 3989
-3 3997 3988 3989
-3 3999 4000 4012
-3 3999 3989 4000
-3 4001 4000 3990
-3 3990 4000 3989
-3 4002 3449 4003
-3 4003 4004 4002
-3 4611 3449 3448
-3 4003 3449 4611
-3 3994 4006 4005
-3 3994 4005 3992
-3 3992 4005 4007
-3 3993 3992 4008
-3 4008 3992 4007
-3 4022 4621 3993
-3 4008 4022 3993
-3 4009 3995 3996
-3 4010 3997 4011
-3 4010 4009 3997
-3 4009 3996 3997
-3 3998 4011 3997
-3 4001 4012 4000
-3 4013 4002 3452
-3 4013 3991 4002
-3 3452 4002 3449
-3 4004 4014 4002
-3 3449 4002 4014
-3 3453 3449 4015
-3 3449 4014 4015
-3 4015 3454 3453
-3 4016 3454 4015
-3 4017 4005 4006
-3 4007 4005 4018
-3 4018 4005 4017
-3 4022 4008 4018
-3 4018 4008 4007
-3 4009 4019 3455
-3 3995 4009 3455
-3 4019 4009 4010
-3 3451 4013 3452
-3 3457 4631 3451
-3 3451 4631 4013
-3 4016 3457 3454
-3 4631 3457 4016
-3 4021 4006 4031
-3 4017 4006 4021
-3 4017 4021 3458
-3 4017 4022 4018
-3 3459 3455 4019
-3 3459 4019 4023
-3 4023 4019 3461
-3 3461 4019 4010
-3 4021 4031 4024
-3 3458 4021 4025
-3 4021 4024 4025
-3 3458 4025 4017
-3 4022 4017 4025
-3 4023 4026 3460
-3 3459 4023 3460
-3 3461 4026 4023
-3 4024 4031 4027
-3 3462 4025 4024
-3 3464 3460 4026
-3 3464 4026 4028
-3 4028 4026 4029
-3 3461 4030 4026
-3 4030 4029 4026
-3 4030 3461 4010
-3 3481 4028 4032
-3 4032 4028 4029
-3 4030 4032 4029
-3 4033 4031 3472
-3 4033 4027 4031
-3 3462 4027 4033
-3 3477 3476 4034
-3 3477 4034 3475
-3 3472 4031 3496
-3 4033 3480 4642
-3 3462 4033 4642
-3 3476 3486 4034
-3 3475 4034 3486
-3 3493 3481 4032
-3 3493 4032 4647
-3 4647 4032 4629
-3 4035 4036 4636
-3 4636 4037 4035
-3 4038 4039 4036
-3 4035 4038 4036
-3 4035 3490 4038
-3 4035 3491 3490
-3 3491 4040 3492
-3 3491 4037 4040
-3 3491 4035 4037
-3 4040 4638 3492
-3 4041 4039 4038
-3 3490 3494 4042
-3 3490 4042 4038
-3 4038 4042 4041
-3 3494 4043 4042
-3 3492 4043 3494
-3 3492 4044 4043
-3 4638 4044 3492
-3 4045 4039 4041
-3 4042 4046 4041
-3 4046 4045 4041
-3 4046 4042 4043
-3 4045 4047 4039
-3 4046 4047 4045
-3 4647 3502 3493
-3 3502 4647 3507
-3 4642 3501 5261
-3 3507 4647 4050
-3 4050 3508 3507
-3 3509 3508 4050
-3 3496 4702 1936
-3 5261 3501 4052
-3 3510 3509 4050
-3 4050 5269 3510
-3 3510 4053 3511
-3 3510 5269 4053
-3 3511 4053 3514
-3 4052 3532 5285
-3 3514 4054 3517
-3 4053 4054 3514
-3 4055 3524 3525
-3 4056 4055 3525
-3 3517 4054 3531
-3 5285 3532 4057
-3 4058 5285 4057
-3 4059 3524 4055
-3 3525 3530 4056
-3 4056 3530 4060
-3 4054 4061 3531
-3 3532 3542 4057
-3 4059 4066 3524
-3 3530 4062 4060
-3 3537 4062 3530
-3 4061 3537 3531
-3 4062 3537 4061
-3 3542 3566 4057
-3 4058 4057 3566
-3 3547 4065 3546
-3 3546 4065 4064
-3 3548 4066 3547
-3 3547 4066 4065
-3 4066 3548 3524
-3 4067 3551 3552
-3 3546 4064 3559
-3 3562 3561 4068
-3 3562 4069 3538
-3 4068 4069 3562
-3 4067 3552 5316
-3 4672 4058 3566
-3 4676 3559 4064
-3 4068 3584 4071
-3 3561 3584 4068
-3 3563 4069 4071
-3 4069 4068 4071
-3 3551 4070 3068
-3 4072 3039 4073
-3 3039 4074 4073
-3 3563 4071 3584
-3 3586 3575 4678
-3 4075 3586 4678
-3 4073 4082 4072
-3 4074 4082 4073
-3 4089 3580 4083
-3 4077 3559 4676
-3 4077 3594 3559
-3 4678 3575 3600
-3 4078 4678 3600
-3 3586 4075 3601
-3 4075 4079 3601
-3 5316 3602 4080
-3 4080 3602 4070
-3 4070 3602 3068
-3 3612 4672 3566
-3 3587 4076 5326
-3 4076 3587 5338
-3 4082 4081 4072
-3 4084 3604 3605
-3 4085 3590 3592
-3 3591 3592 3590
-3 3592 3606 4690
-3 3606 3594 4690
-3 4690 3594 4077
-3 3610 4087 4086
-3 3610 4086 4078
-3 3610 4078 3600
-3 3610 3076 4087
-3 4079 3076 3601
-3 4686 3076 4079
-3 5326 2279 3587
-3 4082 4097 4081
-3 4083 3604 4122
-3 3582 4108 3605
-3 3592 4099 4085
-3 4099 3592 4695
-3 4090 4078 4092
-3 4091 4078 4090
-3 4078 4086 4092
-3 4086 4093 4092
-3 4093 4087 4094
-3 4093 4086 4087
-3 3076 4094 4087
-3 3076 4686 4094
-3 4683 3634 3635
-3 3604 4105 4122
-3 4107 4105 3604
-3 4084 4107 3604
-3 4098 4107 4084
-3 3605 4098 4084
-3 4108 4098 3605
-3 4720 4108 3582
-3 3582 4085 4720
-3 4099 4720 4085
-3 3623 4100 4697
-3 3628 3624 4697
-3 4090 4101 4091
-3 4092 4101 4090
-3 4093 4101 4092
-3 4111 4095 4102
-3 4103 4095 4096
-3 4102 4095 4103
-3 4082 4112 4097
-3 4074 4112 4082
-3 4089 4104 4074
-3 4083 4122 4089
-3 4122 4121 4089
-3 4107 4106 4105
-3 4124 4107 4098
-3 4108 4124 4098
-3 4720 4099 4704
-3 4721 4099 4695
-3 3623 3636 4100
-3 4100 3636 4114
-3 4110 4111 4102
-3 4110 4102 4103
-3 4672 3643 4118
-3 4672 4118 4714
-3 3634 4683 4694
-3 4104 4112 4074
-3 4104 4089 4733
-3 4105 4746 4122
-3 4106 4746 4105
-3 4107 4123 4106
-3 4124 4123 4107
-3 4108 4141 4124
-3 4099 4721 4704
-3 4113 4114 3636
-3 4128 4115 3628
-3 4109 3631 3641
-3 4109 4725 3631
-3 4714 4118 4119
-3 4714 4119 4132
-3 1697 4097 4120
-3 4120 4097 4112
-3 4120 4104 4731
-3 4120 4112 4104
-3 4121 4733 4089
-3 4125 4734 4721
-3 4126 4114 4113
-3 4136 4114 4126
-3 3636 3645 4127
-3 3636 4127 4113
-3 4113 4127 4126
-3 4115 4128 3645
-3 4127 3645 4128
-3 3641 3650 4109
-3 4109 3650 5374
-3 4725 3651 3631
-3 4138 3651 4725
-3 4117 4116 3652
-3 3652 4129 4117
-3 4117 4130 3643
-3 4117 4129 4130
-3 3643 4130 4118
-3 4131 4132 4118
-3 4118 4132 4119
-3 5338 2278 3683
-3 1697 4120 4731
-3 4121 4134 4733
-3 4134 4133 4733
-3 4766 4134 4122
-3 4134 4121 4122
-3 4746 4106 4782
-3 4123 4782 4106
-3 4124 4135 4123
-3 4141 4135 4124
-3 4136 4126 4137
-3 4127 4137 4126
-3 4142 4127 4128
-3 4129 3652 4148
-3 4130 4129 4139
-3 4139 4129 4148
-3 4140 4130 4139
-3 4118 4130 4140
-3 4755 4118 4140
-3 4131 4118 4755
-3 4741 4132 4758
-3 4135 4141 4123
-3 4141 4782 4123
-3 4136 4137 4154
-3 4127 4142 4137
-3 4142 4154 4137
-3 3658 5374 3650
-3 3651 4138 3664
-3 4143 4147 4145
-3 4144 4147 4143
-3 4146 4145 4147
-3 3111 3660 4774
-3 4845 3036 4702
-3 4139 4148 4149
-3 4150 4140 4139
-3 4150 4139 4149
-3 4152 4153 4166
-3 1697 4731 4780
-3 4155 4154 4142
-3 4156 5374 3658
-3 3658 3663 4156
-3 4157 4144 4143
-3 4158 4144 4157
-3 4145 4159 4143
-3 4159 4157 4143
-3 4160 4159 4145
-3 4146 4160 4145
-3 4147 4161 4146
-3 4161 4160 4146
-3 3660 4162 4147
-3 4162 4161 4147
-3 3111 4774 4802
-3 3665 3111 4802
-3 3652 4163 4148
-3 4149 4148 4164
-3 4164 4148 4163
-3 4150 4149 3667
-3 3667 4149 4164
-3 4151 4150 3667
-3 4151 3667 4775
-3 3667 4171 4775
-3 4165 4166 4167
-3 4166 4165 4152
-3 3663 4806 4786
-3 3663 4786 4156
-3 3663 3677 4806
-3 3664 4806 3668
-3 3664 4138 4806
-3 4157 4800 4158
-3 4159 4800 4157
-3 4160 4800 4159
-3 4172 4800 4160
-3 4161 4172 4160
-3 4162 3669 4161
-3 3665 4802 3671
-3 3667 4164 4163
-3 3667 4170 4171
-3 4167 4171 4170
-3 4167 4170 4165
-3 4165 4170 4152
-3 4763 3682 4168
-3 3668 4806 3677
-3 3669 4172 4161
-3 3678 4172 3669
-3 3678 4801 4172
-3 4802 4801 3678
-3 3671 4802 3678
-3 4170 3704 4152
-3 4762 4152 3704
-3 4763 4184 3682
-3 4173 4174 4175
-3 4175 4176 4177
-3 4174 4176 4175
-3 4176 4178 4177
-3 3704 4180 4762
-3 4181 4182 4183
-3 3706 3682 4184
-3 4175 4174 4173
-3 4177 4174 4175
-3 1697 4780 4838
-3 4179 4185 3685
-3 3685 4185 3686
-3 4185 3687 3686
-3 4186 3687 4185
-3 4187 4815 4188
-3 4188 3689 3688
-3 4188 4815 3689
-3 3689 4815 4189
-3 4190 4181 4180
-3 4182 4181 4190
-3 4183 4182 4190
-3 4184 4183 4190
-3 3706 4184 4190
-3 4192 3693 4191
-3 4193 4194 4195
-3 3685 4196 4835
-3 3695 3687 4197
-3 3687 4186 4197
-3 4188 4198 4187
-3 3688 4198 4188
-3 3688 3697 4198
-3 3690 4189 4833
-3 4190 4180 3705
-3 3693 4199 4191
-3 4192 3698 3693
-3 4192 4199 3698
-3 3693 3698 4199
-3 4204 4194 4193
-3 4195 4194 4204
-3 4835 4196 4200
-3 3695 4200 4196
-3 4201 3701 4197
-3 4201 4202 3701
-3 4197 3701 3695
-3 3700 4200 3701
-3 3695 3701 4200
-3 3701 4202 3702
-3 3697 4832 4198
-3 3697 3703 4832
-3 4833 4832 3703
-3 3709 4203 3710
-3 3710 4203 3712
-3 4193 4841 4204
-3 4205 4195 4204
-3 3714 4195 4205
-3 3714 4205 4206
-3 4202 4207 4208
-3 4202 4201 4207
-3 4208 4207 3715
-3 4200 3700 4207
-3 3715 4207 3700
-3 3702 4202 4208
-3 3702 4208 4837
-3 3702 4837 3175
-3 4837 4208 4209
-3 4837 3716 3175
-3 3683 2278 4237
-3 3683 4237 4823
-3 3724 3709 3722
-3 3724 4210 3709
-3 4210 4203 3709
-3 3712 4210 3725
-3 4203 4210 3712
-3 4206 4846 3727
-3 4206 3727 3714
-3 4208 4211 4209
-3 4208 3715 4211
-3 4837 4211 3716
-3 3721 4212 5455
-3 3721 3186 4212
-3 3721 5455 4213
-3 4213 3728 3721
-3 4850 1697 4838
-3 3724 3729 4210
-3 3725 4210 3729
-3 4214 4215 4216
-3 4216 4217 4214
-3 4846 4229 3730
-3 3727 4846 3730
-3 4218 4219 4212
-3 4218 4212 3186
-3 3733 3728 4213
-3 4220 4215 4214
-3 4221 4215 4220
-3 4217 4222 4214
-3 4222 4220 4214
-3 4223 3730 4229
-3 4224 4219 4218
-3 4225 4219 4224
-3 3186 3734 4224
-3 4218 3186 4224
-3 3735 3733 4236
-3 4220 4226 4221
-3 4222 4226 4220
-3 4227 4226 4222
-3 4229 4228 4223
-3 4232 4245 4234
-3 4233 4245 4232
-3 4248 4225 4224
-3 4235 4225 4248
-3 3734 4236 4224
-3 4224 4236 4248
-3 3735 4236 3734
-3 4229 4238 4228
-3 4239 4229 4846
-3 4239 4238 4229
-3 4239 4231 4240
-3 4231 4230 4240
-3 4230 4241 4240
-3 4242 4230 4231
-3 4241 4230 4242
-3 4232 4244 4233
-3 4244 4232 4243
-3 4232 4234 4243
-3 4245 4243 4234
-3 4243 4246 4247
-3 4245 4246 4243
-3 4869 4228 4238
-3 4869 4238 4239
-3 4249 4239 4240
-3 4241 4249 4240
-3 4249 4241 4242
-3 4243 4250 4244
-3 4247 4250 4243
-3 4870 4239 4251
-3 4239 4249 4251
-3 4252 4251 4249
-3 4256 4249 4242
-3 4256 4252 4249
-3 4870 4255 4260
-3 4870 4251 4255
-3 4251 4252 4255
-3 4256 4255 4252
-3 3741 4257 4253
-3 4254 4257 3742
-3 4254 4253 4257
-3 3745 3744 4258
-3 4259 3745 4258
-3 4259 4871 3745
-3 4871 3746 3745
-3 4871 3751 3746
-3 4260 4255 4261
-3 4256 4261 4255
-3 4256 4262 4261
-3 4872 4257 3741
-3 4872 3742 4257
-3 4872 3748 3742
-3 3744 3743 4258
-3 3743 3761 4276
-3 3743 4276 4259
-3 3743 4259 4258
-3 4263 3751 4871
-3 3753 3751 4264
-3 3751 4263 4264
-3 4265 3753 4264
-3 1697 4850 4373
-3 4270 4260 4261
-3 4266 4270 4261
-3 4262 4266 4261
-3 3741 3756 4872
-3 4269 4268 3748
-3 4269 4272 4268
-3 4277 3774 4265
-3 4265 3774 3753
-3 4271 3765 4267
-3 4872 3756 3766
-3 3770 3758 4268
-3 4272 3770 4268
-3 3770 4272 3772
-3 3772 4272 4274
-3 4273 3759 4274
-3 3759 3772 4274
-3 4273 2774 3759
-3 4275 4276 3761
-3 3761 3773 4275
-3 3777 3234 4874
-3 4882 3777 4874
-3 3778 4279 3779
-3 4278 4279 3778
-3 4266 4293 4270
-3 4293 4266 3780
-3 3765 4280 3796
-3 4271 4280 3765
-3 4296 4281 3783
-3 3783 4281 3766
-3 3785 3786 4282
-3 3784 3785 4282
-3 4283 4284 4274
-3 4274 4284 4273
-3 4273 4284 4285
-3 2774 4273 4285
-3 3787 4299 4276
-3 3788 4275 4286
-3 3788 4276 4275
-3 3788 3787 4276
-3 3773 3789 4286
-3 4275 3773 4286
-3 4277 4302 3791
-3 3791 4302 3792
-3 3234 3807 4874
-3 3794 3793 3777
-3 3794 3777 4287
-3 4287 3777 4882
-3 4288 4289 4290
-3 4290 4886 4288
-3 4291 4279 4278
-3 4291 4278 3795
-3 4291 3795 4292
-3 3821 4279 4291
-3 4294 4884 3780
-3 3780 4884 4293
-3 4280 4884 4294
-3 4280 4294 4295
-3 4280 4295 3796
-3 4304 4281 4305
-3 4281 4296 4305
-3 4297 4309 3798
-3 3799 4297 3784
-3 3800 3799 3784
-3 3800 3784 4298
-3 4298 3784 4282
-3 3786 4298 4282
-3 3786 4885 4298
-3 4885 4311 4298
-3 4283 4885 3801
-3 4885 3786 3801
-3 3802 4283 3801
-3 4284 4283 3802
-3 4285 4284 3802
-3 3803 4299 3787
-3 3788 4286 3804
-3 3789 3804 4286
-3 3789 3790 4300
-3 3804 3789 4300
-3 3790 3805 4300
-3 4300 3805 4301
-3 4302 4301 3792
-3 4302 4303 4301
-3 4301 3805 3792
-3 4302 4893 4303
-3 3807 3806 4350
-3 3819 3794 4287
-3 3823 4295 4294
-3 3796 4295 3825
-3 3825 4295 3823
-3 3796 3825 3809
-3 4306 4307 4308
-3 4306 3813 4307
-3 4309 3813 3798
-3 3799 4319 4297
-3 4297 4319 4309
-3 3799 4310 4319
-3 3800 4310 3799
-3 3800 4311 4310
-3 3800 4298 4311
-3 3814 3253 4312
-3 3814 4312 4313
-3 3814 4313 3803
-3 3803 4313 4299
-3 4300 4314 3804
-3 4315 4314 4300
-3 4301 4315 4300
-3 4303 4315 4301
-3 3815 4315 4303
-3 3815 4303 3816
-3 4893 4316 4303
-3 3816 4303 4316
-3 3817 3816 4316
-3 4919 4317 3817
-3 3831 3817 4317
-3 3827 4308 4327
-3 3271 4308 3827
-3 3828 4306 4308
-3 3828 4308 3271
-3 4306 3836 3830
-3 4306 3828 3836
-3 4328 4309 4318
-3 4319 4318 4309
-3 3253 4320 4312
-3 4320 4321 4312
-3 4322 4313 4312
-3 4322 4312 4321
-3 3817 4316 4919
-3 3832 4324 4323
-3 3831 4324 3832
-3 3831 4317 4324
-3 4323 4324 4333
-3 4333 4325 4326
-3 4324 4325 4333
-3 3266 3819 4336
-3 4339 4304 4305
-3 4305 4296 4339
-3 3810 4339 4296
-3 3810 3827 4339
-3 4319 4328 4318
-3 4329 4328 4319
-3 4310 4329 4319
-3 4321 4320 4331
-3 4331 4320 4330
-3 4322 4321 4332
-3 4332 4321 4331
-3 4314 4906 4332
-3 4906 4322 4332
-3 3832 4323 3839
-3 3840 3839 4323
-3 3840 4323 4333
-3 4325 4334 4326
-3 4334 4333 4326
-3 3841 4335 4910
-3 4910 4911 3841
-3 3841 4911 3844
-3 4342 3844 4911
-3 3806 3842 4350
-3 4922 4913 4337
-3 3843 4344 3795
-3 3821 4338 3833
-3 4327 4339 3827
-3 4925 3815 4347
-3 3840 4333 4340
-3 4334 4341 4333
-3 4349 4341 4334
-3 3842 4342 4350
-3 4343 3795 4344
-3 3843 3846 4344
-3 4345 4338 4355
-3 4347 4348 4925
-3 4949 4348 4340
-3 4333 4949 4340
-3 4349 4333 4341
-3 4335 3856 4363
-3 4933 3312 4913
-3 4351 3795 4343
-3 4352 3795 4351
-3 4344 4351 4343
-3 3846 4353 4344
-3 4344 4353 4351
-3 3846 4345 4353
-3 4353 4345 4354
-3 4355 4356 4345
-3 4356 4354 4345
-3 4356 4346 3847
-3 4355 4346 4356
-3 3847 4346 3853
-3 3845 3848 4357
-3 4964 4337 3850
-3 4933 4379 3312
-3 4351 4353 4352
-3 4354 4358 4353
-3 4356 4359 4354
-3 4359 4358 4354
-3 3851 3852 4359
-3 3851 4359 4356
-3 3847 3851 4356
-3 4360 3853 4346
-3 4360 4368 3853
-3 4368 4361 3853
-3 4363 3856 4364
-3 4363 4364 4950
-3 4950 4364 4365
-3 4364 3857 4365
-3 3859 4357 4962
-3 4964 3850 4366
-3 4353 4380 4352
-3 4353 4358 4380
-3 4359 4367 4358
-3 4367 4380 4358
-3 3852 3862 4367
-3 4359 3852 4367
-3 4360 4382 4368
-3 4361 4368 4369
-3 4362 4361 3864
-3 3864 4361 4369
-3 4362 3864 3854
-3 3327 4372 3867
-3 3327 3859 4372
-3 3859 4962 4372
-3 4374 4375 3869
-3 4376 4377 3850
-3 4377 4366 3850
-3 3850 3329 4376
-3 4379 4378 3312
-3 4381 4380 4367
-3 3862 4381 4367
-3 4368 4382 4399
-3 3870 4399 3871
-3 3870 4369 4399
-3 4369 4368 4399
-3 3864 4369 3870
-3 4383 4371 4370
-3 4383 4370 4371
-3 4372 4384 3867
-3 3868 3874 4374
-3 4403 4385 4374
-3 4375 4374 4385
-3 4386 4375 4385
-3 3869 4375 4386
-3 3869 4386 3872
-3 3872 4386 4973
-3 3876 4387 4388
-3 3876 3872 4387
-3 3872 4973 4387
-3 4974 4376 4389
-3 4974 4388 4376
-3 4377 4376 4387
-3 4387 4376 4388
-3 3329 4389 4376
-3 4378 4389 3329
-3 4378 4390 4391
-3 4392 4378 4379
-3 4390 4378 4392
-3 3862 3878 4381
-3 3878 4382 4381
-3 3871 4399 3342
-3 4393 4383 4401
-3 4394 3857 4395
-3 4394 4395 4396
-3 4396 3879 3867
-3 4396 3867 4384
-3 3874 4403 4374
-3 3876 4388 4974
-3 4397 4391 4390
-3 4392 4398 4390
-3 4398 4397 4390
-3 4392 4416 4398
-3 3878 4399 4382
-3 4401 4402 4393
-3 4402 4400 4393
-3 4396 4395 3879
-3 4397 4404 4419
-3 4397 4398 4404
-3 4416 4404 4398
-3 3878 3882 4399
-3 4402 4405 4400
-3 4405 4402 4412
-3 3886 3885 4406
-3 3886 4407 3887
-3 4406 4407 3886
-3 4403 3874 3361
-3 4415 3362 4974
-3 3362 3876 4974
-3 4408 4419 4404
-3 4416 4409 4404
-3 4409 4408 4404
-3 4410 4400 4411
-3 4400 4405 4411
-3 4412 4413 4405
-3 4413 4411 4405
-3 4412 5012 4413
-3 4406 3893 4414
-3 3885 3893 4406
-3 4407 4414 3892
-3 4407 4406 4414
-3 4998 4990 4418
-3 3894 4415 3361
-3 3361 4415 4403
-3 3362 4415 3894
-3 3896 4416 3895
-3 3896 4409 4416
-3 3896 4408 4409
-3 4416 3900 3895
-3 4420 3900 4416
-3 4411 4417 4410
-3 3897 4417 4411
-3 3897 4411 4413
-3 4413 3904 3897
-3 4413 5021 3904
-3 4413 5012 5021
-3 3893 3892 4414
-3 4990 4425 4418
-3 3898 4419 4408
-3 3896 3898 4408
-3 3901 3900 5020
-3 3900 4420 5020
-3 5020 3902 3901
-3 4421 3902 5020
-3 3897 3910 4417
-3 4425 4424 4418
-3 4426 4427 4419
-3 4426 4419 3898
-3 3906 4428 4438
-3 3906 4439 4428
-3 3902 4421 3908
-3 4421 4429 3908
-3 3904 5021 5028
-3 4430 4431 4432
-3 4431 4433 4432
-3 4434 4423 4436
-3 4437 4424 4425
-3 5634 4426 4446
-3 3898 3909 4446
-3 4426 3898 4446
-3 3909 3906 4438
-3 3907 4449 4439
-3 3907 4439 3906
-3 3907 4440 4449
-3 3907 3908 4440
-3 3908 4429 4440
-3 3910 4441 4417
-3 5028 3910 3904
-3 4441 3910 5028
-3 4432 4442 4430
-3 4443 4442 4432
-3 4433 4443 4432
-3 4434 4444 4435
-3 4436 4444 4434
-3 4445 4437 4425
-3 4451 4445 4425
-3 3909 4447 4446
-3 4447 3909 4448
-3 3909 4438 4448
-3 4451 4450 4445
-3 4467 4451 4425
-3 4447 5634 4446
-3 3912 3911 5042
-3 3911 4452 5042
-3 4453 3912 5042
-3 4454 4456 4457
-3 4455 4456 4454
-3 4458 4445 4450
-3 4459 4445 4458
-3 4451 4460 4450
-3 4460 4458 4450
-3 4460 4451 4467
-3 3913 5075 3911
-3 3911 5075 4452
-3 3912 4453 3914
-3 4453 4473 3914
-3 4463 4455 4454
-3 4457 4464 4454
-3 4464 4463 4454
-3 4464 4457 4465
-3 4458 4466 4459
-3 4460 4466 4458
-3 4467 4466 4460
-3 4479 4461 4468
-3 4462 4469 4461
-3 4469 4468 4461
-3 4469 4462 4470
-3 4471 4472 3915
-3 3913 3916 5075
-3 3917 4474 4475
-3 4463 4476 5068
-3 4464 4477 4463
-3 4477 4476 4463
-3 4478 4464 4465
-3 4477 4464 4478
-3 4479 4468 4480
-3 4468 4469 4480
-3 4481 4469 4470
-3 4481 4482 4469
-3 4482 4480 4469
-3 4471 4482 4481
-3 4471 4483 4482
-3 3915 4483 4471
-3 4484 3915 4472
-3 4484 4472 4492
-3 3916 4485 4493
-3 3916 4493 5075
-3 4486 4473 4487
-3 3917 3918 4474
-3 3917 5067 5068
-3 3917 4475 5067
-3 5068 4476 3385
-3 3926 4476 4477
-3 5069 4477 4478
-3 4480 4488 4479
-3 3920 4488 4480
-3 3920 4480 4482
-3 3921 3920 4482
-3 3921 4482 4489
-3 4489 4482 4483
-3 4483 3915 4490
-3 4483 4490 4489
-3 3915 4484 4490
-3 4490 4484 4491
-3 4492 4491 4484
-3 3916 3929 4485
-3 4493 4485 4494
-3 4486 4493 4494
-3 4486 4494 3382
-3 3926 5069 5082
-3 4477 5069 3926
-3 3395 5088 4422
-3 4495 3924 4496
-3 4495 4488 3924
-3 4488 3920 3924
-3 4489 4495 3925
-3 4489 3925 3921
-3 3925 4495 4496
-3 4497 4489 4490
-3 4497 4490 4498
-3 4490 4491 4498
-3 4492 4498 4491
-3 4485 3929 4499
-3 4500 4501 4494
-3 4500 4494 4499
-3 4499 4494 4485
-3 4494 4502 3382
-3 4494 4501 4502
-3 4506 3382 4502
-3 4496 3924 4504
-3 4504 3924 4503
-3 3928 4504 5090
-3 3928 4496 4504
-3 3928 3925 4496
-3 3928 5090 3936
-3 4498 4505 4497
-3 5091 4498 4492
-3 4499 3929 3401
-3 4499 3401 4500
-3 3918 3390 4474
-3 4474 3390 5087
-3 3395 3926 5088
-3 5083 5095 3931
-3 3924 3935 4503
-3 3936 5090 4512
-3 4498 4507 4505
-3 5091 4507 4498
-3 4506 5094 3939
-3 3939 5094 5087
-3 3939 5087 3933
-3 3933 5087 3390
-3 3935 3931 5095
-3 3935 5095 5097
-3 5097 4503 3935
-3 5098 3944 4508
-3 5117 4500 3401
-3 5677 4237 2917
-3 4508 3943 3936
-3 3944 3943 4508
-3 3944 5104 4510
-3 3944 4510 3945
-3 3955 3945 4510
-3 3955 4510 4515
-3 3401 5130 5117
-3 3955 4515 5134
-3 4516 4517 5123
-3 3960 4518 4514
-3 3964 5129 5130
-3 4519 4517 4516
-3 4519 4516 4520
-3 4513 4521 3958
-3 4518 3960 4525
-3 3955 5134 3424
-3 3424 5134 4522
-3 5129 3964 4522
-3 4523 4519 4520
-3 4523 3966 4519
-3 3966 4523 2916
-3 4530 2916 4523
-3 4530 3962 2916
-3 3958 4521 3963
-3 4521 4524 3963
-3 4525 4524 4526
-3 4524 4525 3963
-3 4525 4526 4527
-3 3424 4522 3964
-3 4531 5643 5140
-3 4519 3966 4528
-3 3962 4530 2917
-3 5677 2917 4530
-3 4527 4524 4521
-3 4526 4524 4527
-3 3430 4529 4528
-3 4528 3966 3430
-3 4529 3965 4531
-3 3968 4536 3967
-3 4532 4533 3968
-3 3968 4533 4536
-3 4535 3969 3967
-3 4535 3967 4534
-3 4534 3967 4536
-3 4533 4532 4552
-3 4552 4532 3971
-3 4533 4552 4551
-3 4538 4537 4539
-3 4540 4541 5727
-3 5727 4541 4534
-3 4542 4534 4541
-3 4543 4534 4542
-3 4535 4534 4544
-3 4544 4534 4543
-3 3969 4535 4545
-3 4535 4544 4545
-3 4546 3970 4545
-3 4546 4547 3970
-3 3970 4547 4548
-3 4548 4560 3971
-3 4552 3971 4550
-3 4550 3971 4560
-3 4538 4554 4537
-3 4537 4554 4555
-3 4556 4537 4555
-3 4539 4537 4556
-3 5179 4541 4540
-3 5157 4541 5179
-3 4557 4541 5157
-3 4541 4557 4542
-3 4543 4542 4558
-3 4558 4542 4557
-3 4544 4543 4558
-3 4545 4544 4558
-3 4558 5159 4545
-3 4546 4545 5159
-3 4559 4548 4549
-3 4560 4548 4559
-3 4552 4550 4561
-3 4561 4550 4560
-3 4551 4552 4561
-3 4553 4551 4562
-3 4562 4551 4561
-3 4562 4563 4553
-3 4564 4565 4566
-3 5154 4556 4554
-3 4555 4554 4556
-3 4558 4557 5171
-3 5172 4558 5171
-3 4560 4559 4561
-3 4562 4561 4567
-3 4568 4562 4567
-3 4569 4563 4562
-3 4568 4569 4562
-3 5168 5177 4564
-3 5168 4570 5177
-3 4565 4564 5177
-3 4561 4559 4580
-3 4580 4567 4561
-3 4571 4568 4567
-3 4572 4573 4574
-3 4569 4568 4571
-3 4572 4574 4575
-3 4577 5174 4576
-3 4578 3972 4579
-3 5177 4570 5192
-3 4577 4576 4581
-3 4581 5187 4577
-3 5213 4579 4583
-3 5213 4582 4579
-3 4582 4578 4579
-3 3972 4583 4579
-3 3972 3974 4583
-3 3973 3974 3972
-3 4584 4586 4587
-3 4585 4584 4587
-3 4589 4590 4585
-3 4585 4590 4584
-3 4584 4590 4591
-3 4586 4584 4592
-3 4592 4584 4591
-3 4593 4587 4586
-3 4592 4593 4586
-3 3977 4600 4588
-3 4589 4594 3976
-3 3976 4595 4589
-3 4595 4590 4589
-3 4591 4590 4596
-3 4596 4590 4595
-3 4596 4592 4591
-3 4593 4592 4596
-3 4589 5235 4597
-3 4589 4597 4594
-3 4594 4597 4598
-3 3976 4594 4599
-3 4594 4598 4599
-3 3976 4599 4595
-3 4599 5238 4595
-3 5238 4596 4595
-3 4582 5213 5240
-3 4600 3977 3979
-3 3979 3980 4600
-3 4600 3980 4601
-3 4602 4597 5235
-3 4598 4597 4603
-3 4603 4597 4602
-3 4599 4598 5238
-3 5238 4598 4603
-3 4582 5240 3986
-3 4600 3981 4604
-3 4600 3982 3981
-3 3982 4600 4605
-3 4605 4600 4601
-3 5237 4605 4601
-3 5237 4601 2180
-3 4606 5235 4635
-3 5235 4606 4602
-3 4606 4603 4602
-3 5238 4603 4606
-3 4604 3984 4607
-3 3981 3984 4604
-3 4608 4604 4609
-3 4609 4604 4607
-3 4605 4608 4609
-3 5237 4608 4605
-3 4635 4610 4606
-3 4606 4610 4615
-3 3985 4607 3984
-3 4609 4607 4611
-3 4609 4611 4605
-3 4619 4612 5237
-3 4635 4613 4610
-3 4610 4613 4614
-3 4615 4610 4614
-3 5241 4606 4615
-3 4616 3986 5240
-3 4616 4617 3986
-3 3986 4617 3990
-3 3985 3991 4618
-3 4607 3985 4618
-3 4611 4607 4618
-3 4620 4612 4619
-3 5237 4051 4619
-3 4635 3994 4613
-3 4621 4613 3994
-3 4621 4614 4613
-3 4615 4614 5241
-3 5241 4614 4621
-3 4622 4616 5240
-3 4623 4616 4622
-3 3999 4623 3998
-3 3999 4617 4623
-3 4617 4616 4623
-3 4012 4617 3999
-3 4012 4624 4617
-3 3990 4617 4001
-3 4001 4617 4624
-3 3991 4625 4618
-3 4003 4625 4004
-3 4003 4611 4625
-3 4611 4618 4625
-3 4626 4627 4620
-3 4626 4619 4628
-3 4620 4619 4626
-3 4051 4628 4619
-3 4635 4006 3994
-3 4622 5240 4629
-3 4011 4629 4010
-3 4011 4622 4629
-3 4011 4623 4622
-3 3998 4623 4011
-3 4001 4624 4012
-3 4013 4625 3991
-3 4013 4630 4625
-3 4004 4625 4014
-3 4014 4625 4630
-3 4014 4631 4015
-3 4630 4631 4014
-3 4015 4631 4016
-3 4632 4627 4626
-3 4632 4626 4633
-3 4022 4642 4621
-3 4642 5241 4621
-3 4631 4630 4013
-3 4632 4634 4627
-3 4633 4634 4632
-3 4031 4006 4635
-3 4642 4022 4025
-3 4010 4629 4030
-3 4629 4032 4030
-3 4025 3462 4642
-3 4031 4635 3496
-3 4643 4647 4629
-3 4036 4039 5246
-3 4036 5246 4636
-3 5246 4637 4636
-3 4037 4638 4040
-3 4037 4636 4638
-3 4636 4637 4638
-3 5245 4637 5246
-3 4044 5245 4043
-3 4044 4637 5245
-3 4044 4638 4637
-3 4639 4046 5245
-3 4046 4043 5245
-3 4640 4039 4047
-3 4640 4641 4039
-3 4641 5246 4039
-3 4639 5249 4047
-3 4639 4047 4046
-3 4640 4047 5249
-3 4645 4644 4640
-3 4641 4640 4644
-3 5249 4645 4640
-3 4650 4644 4646
-3 4646 4644 4645
-3 4648 4649 4650
-3 4650 4646 4648
-3 4048 4651 4049
-3 4048 4652 4653
-3 4048 4049 4652
-3 4649 4653 4652
-3 4649 4648 4653
-3 4648 4656 4653
-3 4050 4647 4643
-3 4654 4655 4048
-3 4655 4651 4048
-3 4048 4653 4654
-3 4654 4653 4656
-3 4654 4657 4655
-3 4656 4657 4654
-3 5261 5256 4642
-3 4658 5261 4052
-3 5269 4050 5268
-3 5266 4659 4658
-3 4052 5266 4658
-3 4053 5269 5274
-3 5274 4660 4053
-3 4053 4660 4661
-3 4054 4053 4661
-3 4662 4660 5274
-3 4662 4661 4660
-3 4661 4061 4054
-3 4663 5285 4058
-3 4663 5292 5285
-3 4059 4055 4664
-3 4056 4060 4664
-3 4055 4056 4664
-3 4661 4662 4061
-3 4664 4665 4059
-3 4060 4062 4665
-3 4060 4665 4664
-3 4062 4061 4665
-3 4665 4061 4666
-3 4666 4061 4662
-3 5292 4663 4058
-3 4668 4064 4065
-3 4065 4066 4669
-3 4066 4059 4669
-3 4665 4670 4059
-3 5308 4670 4665
-3 5308 4665 4666
-3 5292 4058 4672
-3 4065 4669 4668
-3 4059 4670 4669
-3 4067 4671 5306
-3 5306 3551 4067
-3 5306 4070 3551
-3 4668 4673 4064
-3 4673 4676 4064
-3 4669 4674 4668
-3 4674 4673 4668
-3 4670 4677 4669
-3 4677 4674 4669
-3 4675 4677 4670
-3 4675 4670 5308
-3 4067 5316 4671
-3 5306 4679 4070
-3 4674 4677 4673
-3 5319 4677 4675
-3 4070 4679 5317
-3 4673 4077 4676
-3 4077 4673 4677
-3 4078 4680 4678
-3 4680 4681 4678
-3 4079 4678 4681
-3 4678 4079 4075
-3 5316 4080 5320
-3 4070 5317 5320
-3 4080 4070 5320
-3 4682 4683 4684
-3 5314 4682 4684
-3 4677 5327 4077
-3 4078 4685 4680
-3 4685 4686 4680
-3 4681 4680 4686
-3 4079 4681 4686
-3 4088 5320 4080
-3 5320 4088 4080
-3 4682 5324 4687
-3 4682 4687 4688
-3 4683 4682 4688
-3 5326 4076 5338
-3 4695 3592 4689
-3 3592 4690 4689
-3 4077 4696 4690
-3 4696 4077 5327
-3 4100 5327 5325
-3 5325 4697 4100
-3 4078 4091 4692
-3 4091 4691 4692
-3 4685 4078 4693
-3 4693 4078 4692
-3 4094 5331 4093
-3 4094 4685 5331
-3 4094 4686 4685
-3 4685 4693 5331
-3 4096 4095 5341
-3 4688 4687 4694
-3 4683 4688 4694
-3 4684 4683 3635
-3 4689 4722 4695
-3 3628 4697 4698
-3 4699 4091 4101
-3 4699 4700 4091
-3 4700 4691 4091
-3 4701 4699 4101
-3 4701 4101 5331
-3 4093 5331 4101
-3 4095 4111 5341
-3 5341 4103 4096
-3 5318 5298 4715
-3 4715 5298 4672
-3 5318 4715 4716
-3 4687 5324 4703
-3 4694 4687 4703
-3 4722 4721 4695
-3 4689 4705 4722
-3 4690 4706 4689
-3 4706 4690 4696
-3 3628 4698 4128
-3 4707 4708 4109
-3 4709 4700 4711
-3 4710 4700 4709
-3 4712 4699 4701
-3 4712 4711 4699
-3 4700 4699 4711
-3 4713 5341 4111
-3 4713 4110 5341
-3 4110 4103 5341
-3 4715 4672 4714
-3 4694 4703 4168
-3 4104 4733 4732
-3 4720 4719 4108
-3 4736 4722 4705
-3 4689 4723 4705
-3 4723 4736 4705
-3 4706 4723 4689
-3 4723 4706 4724
-3 4708 4725 4109
-3 4708 4726 4725
-3 4710 4709 4726
-3 4709 4727 4726
-3 4711 4728 4709
-3 4728 4727 4709
-3 4728 4711 4712
-3 4111 4110 4713
-3 4132 4741 4714
-3 4715 4714 4741
-3 4716 4715 4729
-3 4716 4729 4742
-3 4718 4717 4730
-3 4703 4718 4168
-3 4731 4104 4732
-3 4719 4141 4108
-3 4721 4734 4704
-3 4125 4721 4735
-3 4735 4721 4722
-3 4736 4785 4722
-3 4724 4738 4723
-3 4738 4737 4723
-3 4724 4749 4738
-3 4136 4750 4100
-3 4136 4100 4114
-3 4109 5374 4707
-3 4726 4752 4725
-3 4727 4739 4726
-3 4739 4752 4726
-3 4739 4728 4712
-3 4739 4727 4728
-3 4715 4741 4759
-3 4729 4715 4742
-3 4742 4715 4759
-3 4742 4761 4762
-3 4764 4730 4717
-3 4718 4730 4764
-3 4168 4718 4764
-3 4732 4745 4731
-3 4733 4745 4732
-3 4766 4122 4746
-3 4768 4719 4720
-3 4704 4769 4720
-3 4769 4768 4720
-3 4734 4769 4704
-3 4734 4125 4747
-3 4734 4747 4769
-3 4125 4735 4747
-3 4737 4738 4748
-3 4749 4748 4738
-3 4749 4750 4751
-3 4136 4751 4750
-3 4128 4771 4142
-3 4725 4752 4138
-3 4754 4755 4140
-3 4755 4756 4131
-3 4131 4756 4740
-3 4756 4757 4740
-3 4131 4776 4132
-3 4131 4740 4776
-3 4740 4757 4776
-3 4776 4758 4132
-3 4758 4777 4741
-3 4759 4741 4777
-3 4760 4742 4759
-3 4761 4742 4760
-3 4743 4763 4764
-3 4744 4743 4764
-3 4717 4744 4764
-3 5379 5338 3683
-3 4780 4731 4765
-3 4765 4731 4745
-3 4733 4780 4745
-3 4780 4765 4745
-3 4733 4133 4780
-3 4746 4781 4766
-3 4782 4169 4746
-3 4719 4767 4141
-3 4747 4770 4769
-3 4735 4770 4747
-3 4722 4785 4735
-3 4785 4770 4735
-3 4748 5372 4737
-3 4749 5372 4748
-3 5372 4749 4154
-3 4749 4751 4154
-3 4136 4154 4751
-3 4144 4772 4773
-3 4147 4144 4773
-3 4773 4753 4147
-3 4774 3660 4753
-3 3660 4147 4753
-3 4140 4150 4754
-3 4151 4754 4150
-3 4755 4754 4151
-3 4775 4755 4151
-3 4775 4756 4755
-3 4775 4757 4756
-3 4777 4758 4776
-3 4759 4778 4779
-3 4153 4779 4166
-3 4153 4760 4779
-3 4760 4759 4779
-3 4152 4760 4153
-3 4152 4762 4760
-3 4762 4761 4760
-3 4168 4764 4763
-3 4133 4134 4780
-3 4746 4169 4781
-3 4767 4783 4141
-3 4719 4784 4767
-3 4784 4783 4767
-3 4768 4784 4719
-3 5369 4784 4768
-3 5369 4768 4769
-3 4770 4798 4769
-3 4155 4771 4154
-3 4142 4771 4155
-3 4786 5394 5374
-3 4786 5374 4156
-3 4787 4788 4158
-3 5385 4788 4787
-3 4158 4788 4772
-3 4158 4772 4144
-3 4753 4789 4774
-3 4790 4775 4171
-3 4166 4779 4778
-3 4166 4778 4167
-3 4167 4778 4791
-3 4792 5354 4180
-3 4794 5354 4792
-3 4793 4794 4792
-3 4763 4794 4795
-3 4134 4803 4780
-3 4796 4803 4134
-3 4766 4796 4134
-3 4781 4796 4766
-3 4169 4796 4781
-3 6695 4169 4782
-3 6695 4782 4141
-3 4783 6695 4141
-3 4783 4784 4797
-3 5369 4804 4784
-3 4804 4797 4784
-3 4805 4804 5369
-3 5388 4798 4770
-3 4785 5388 4770
-3 4799 5385 4787
-3 4158 4800 4787
-3 4800 4799 4787
-3 4774 4789 4801
-3 4802 4774 4801
-3 4791 4171 4167
-3 4181 4792 4180
-3 4794 4793 4184
-3 4795 4794 4184
-3 5379 3683 4823
-3 4812 4803 4796
-3 4797 4804 4783
-3 4786 4806 5394
-3 4807 4816 5385
-3 5385 4799 4807
-3 4799 4808 4807
-3 4800 4809 4799
-3 4809 4808 4799
-3 4810 4809 4800
-3 4810 4800 4172
-3 4801 4789 4172
-3 4181 4183 4792
-3 4183 4793 4792
-3 4184 4793 4183
-3 4763 4795 4184
-3 4174 4811 4176
-3 4176 4811 4178
-3 4838 4780 4803
-3 4812 4838 4803
-3 3685 4813 4179
-3 4814 4179 4813
-3 5406 5394 4806
-3 4808 4817 4807
-3 4817 4816 4807
-3 4820 4817 4809
-3 4817 4808 4809
-3 4810 4820 4809
-3 4811 4174 4177
-3 4178 4811 4177
-3 3685 4818 4813
-3 4179 4814 4825
-3 4185 4825 4186
-3 4185 4179 4825
-3 4815 4827 4819
-3 4815 4187 4827
-3 4816 4189 4815
-3 4820 4189 4816
-3 4817 4820 4816
-3 4822 4192 4191
-3 4812 4824 4838
-3 3685 4835 4818
-3 4819 4826 5433
-3 4827 4826 4819
-3 4187 4198 4827
-3 4189 4820 4833
-3 4191 4199 4821
-3 4822 4199 4192
-3 4835 5430 4818
-3 4207 4186 4825
-3 4836 4207 4825
-3 4197 4207 4201
-3 4186 4207 4197
-3 5433 4829 5439
-3 5433 4826 4829
-3 4827 4830 4826
-3 4830 4829 4826
-3 4198 4831 4827
-3 4827 4831 4830
-3 4832 4831 4198
-3 5434 4838 4824
-3 5434 4824 4828
-3 4204 4834 4205
-3 4834 4206 4205
-3 4200 5437 4835
-3 4200 4836 5437
-3 4836 4200 4207
-3 4830 5439 4829
-3 4831 5439 4830
-3 4832 5439 4831
-3 4834 4841 4839
-3 4204 4841 4834
-3 4839 4206 4834
-3 4209 4211 4837
-3 4422 6658 1262
-3 4215 5445 4216
-3 5445 4217 4216
-3 4840 4217 5445
-3 4219 4849 6840
-3 5455 4212 4219
-3 5455 4219 6840
-3 4213 5455 3733
-3 4215 4221 5445
-3 5445 4221 5448
-3 4217 4840 4842
-3 4842 4222 4217
-3 5449 4222 4842
-3 4225 4849 4219
-3 3733 5455 4236
-3 4226 5448 4221
-3 4227 5449 4226
-3 4226 5449 5448
-3 5449 4227 4222
-3 4843 4841 4869
-3 4841 4223 4869
-3 4846 5462 4231
-3 4233 4848 4245
-3 4847 4848 4233
-3 4225 4235 4849
-3 4236 5455 4856
-3 4231 4239 4846
-3 4231 5462 4242
-3 5462 4859 4242
-3 4233 4244 4847
-3 4244 4851 4847
-3 4851 4848 4847
-3 4245 4848 4851
-3 4246 4245 4852
-3 4247 5468 4853
-3 4247 4246 5468
-3 4246 4852 5468
-3 5468 4854 4853
-3 4864 6882 4849
-3 4235 4248 4855
-3 4235 4855 4849
-3 4855 4248 4856
-3 4856 4248 4236
-3 4223 4228 4869
-3 4859 4256 4242
-3 4244 4250 4851
-3 4250 5468 4851
-3 4853 4250 4247
-3 4853 4854 4250
-3 4854 5468 4250
-3 4860 4861 4862
-3 4861 4863 4862
-3 4855 4864 4849
-3 4865 4858 4857
-3 4867 4857 4858
-3 4867 4866 4857
-3 4866 4865 4857
-3 4869 4239 4870
-3 4859 5482 4256
-3 4868 4860 4862
-3 4863 4868 4862
-3 4867 4865 4866
-3 5481 4870 4260
-3 4262 4256 5482
-3 4259 4276 4871
-3 4276 4873 4871
-3 4263 4871 4873
-3 4263 4265 4264
-3 4873 4265 4263
-3 5481 4260 4270
-3 5481 4270 5483
-3 4262 5482 5484
-3 4267 5484 4875
-3 4267 4262 5484
-3 3748 4872 4269
-3 4872 4876 4269
-3 4265 4881 4277
-3 4265 4873 4881
-3 4270 4879 5483
-3 5484 4879 4878
-3 5484 4878 4875
-3 4875 4878 4880
-3 4267 4880 4271
-3 4875 4880 4267
-3 5489 4876 3766
-3 4876 4872 3766
-3 4876 5491 4269
-3 4272 4269 5491
-3 4272 5491 4274
-3 4873 4276 5504
-3 4277 4881 5493
-3 4302 4277 5495
-3 4277 5493 5495
-3 5506 4874 3807
-3 4290 4883 5497
-3 5497 5486 4290
-3 4270 4293 4879
-3 4293 4878 4879
-3 4880 4878 4884
-3 4884 4878 4293
-3 4271 4884 4280
-3 4880 4884 4271
-3 4281 4898 5489
-3 3766 4281 5489
-3 4283 5491 4885
-3 4274 5491 4283
-3 4276 4299 4892
-3 4892 5504 4276
-3 3807 4894 5506
-3 3807 4350 4894
-3 4290 4289 4883
-3 4886 4290 5486
-3 5498 4887 5486
-3 4887 4886 5486
-3 5498 5507 4887
-3 4281 4304 4898
-3 4885 5491 4311
-3 4888 5518 4890
-3 4889 5518 4888
-3 4890 5518 4891
-3 4893 5495 5519
-3 4302 5495 4893
-3 4287 4882 3819
-3 4288 4895 4289
-3 4886 4895 4288
-3 4896 4895 4886
-3 4887 4912 4886
-3 4897 4887 5507
-3 4897 4912 4887
-3 4291 4292 5522
-3 3821 4291 5522
-3 3813 4899 4307
-3 4307 4899 4308
-3 4309 4899 3813
-3 4309 4900 4901
-3 4309 4901 4899
-3 4901 4900 4902
-3 4311 5491 5503
-3 4311 5503 4310
-3 4310 5503 5526
-3 4888 4903 4889
-3 4890 4903 4888
-3 4904 4903 4890
-3 4891 4904 4890
-3 4905 4904 4891
-3 5518 4905 4891
-3 4299 4313 4906
-3 4892 4299 4906
-3 5519 4892 4906
-3 4315 5519 4314
-3 5519 4315 4893
-3 3815 4893 4315
-3 3815 4907 4893
-3 4316 4893 4907
-3 4325 4921 4909
-3 5505 4911 4910
-3 5528 4911 5505
-3 4894 4350 5544
-3 4963 4877 4237
-3 4896 4886 4912
-3 4897 4913 4912
-3 4355 3821 5522
-3 4898 4914 5525
-3 5531 4327 4308
-3 4900 4328 4915
-3 4309 4328 4900
-3 4916 4902 4900
-3 4916 4900 4917
-3 4917 4900 4915
-3 4917 5526 4916
-3 4917 4310 5526
-3 4313 4322 4906
-3 4906 4314 5519
-3 3815 4918 4907
-3 4918 4316 4907
-3 4316 4918 4919
-3 4908 4317 4920
-3 4920 4317 4919
-3 4926 4921 4908
-3 4926 4908 4920
-3 4317 4908 4921
-3 4317 4921 4324
-3 4921 4325 4324
-3 4927 4325 4909
-3 4909 4910 4927
-3 4928 4927 4910
-3 5528 5532 4911
-3 4882 4336 3819
-3 4913 4922 4912
-3 4914 4898 4935
-3 4304 4924 4898
-3 4924 4935 4898
-3 4936 4924 4304
-3 4936 4304 4339
-3 5531 5550 4327
-3 4329 4915 4328
-3 4917 4915 4329
-3 4310 4917 4329
-3 4918 3815 4925
-3 4919 4918 4925
-3 4925 4926 4920
-3 4925 4920 4919
-3 4325 4927 4334
-3 4910 4335 4928
-3 4342 4911 4929
-3 4929 4911 5532
-3 4930 4931 5548
-3 5548 4932 4930
-3 4913 4923 4933
-3 3795 4952 4292
-3 4338 3821 4355
-3 4935 4924 4934
-3 4936 4934 4924
-3 4339 4937 4936
-3 4339 4938 4937
-3 4339 4327 5550
-3 5541 4925 4348
-3 4334 4927 4349
-3 4335 4363 4928
-3 4939 5554 4940
-3 4929 5532 4342
-3 4940 4941 4939
-3 4342 5544 4350
-3 4342 5532 5544
-3 4962 4336 4882
-3 3848 4336 4962
-3 4942 4931 4930
-3 4943 4931 4942
-3 4944 4930 4932
-3 4942 4930 4944
-3 4945 4922 4337
-3 4954 4935 4934
-3 4936 4946 4934
-3 4946 4954 4934
-3 4946 4936 4937
-3 4339 4947 4938
-3 5550 4947 4339
-3 4348 4948 5541
-3 4948 4348 4949
-3 4949 4333 4349
-3 4950 5553 4960
-3 5553 4950 5564
-3 4940 5554 4951
-3 4941 4940 4951
-3 4942 4944 4943
-3 3795 4352 4952
-3 4946 4955 4954
-3 4955 4946 5573
-3 4948 4959 4956
-3 4948 4949 4959
-3 4349 4959 4949
-3 4928 4363 4960
-3 4960 4363 4950
-3 4961 5564 4950
-3 3848 4962 4357
-3 4964 4945 4337
-3 4360 4346 4953
-3 5572 4954 4957
-3 4955 4958 4954
-3 4958 4957 4954
-3 4958 4955 5573
-3 4961 4950 4365
-3 4966 4945 4964
-3 4933 5592 4379
-3 4380 4952 4352
-3 4360 4953 4382
-3 4371 5577 4957
-3 4371 4957 4958
-3 4957 5577 5572
-3 4958 5573 4371
-3 5573 5577 4371
-3 4965 4961 4365
-3 3857 4965 4365
-3 4962 4971 4372
-3 4966 4964 4973
-3 4964 4967 4973
-3 4366 4377 4967
-3 4964 4366 4967
-3 4381 4952 4380
-3 4382 4953 4381
-3 4371 4383 5577
-3 5577 4383 5582
-3 4371 5577 4383
-3 5577 5582 4383
-3 4981 4968 4965
-3 3857 4981 4965
-3 3857 4394 4981
-3 4969 4970 4384
-3 4969 4384 4372
-3 4971 4969 4372
-3 4971 4972 4969
-3 4973 4385 4403
-3 4973 4386 4385
-3 4967 4387 4973
-3 4377 4387 4967
-3 5590 4974 4389
-3 4389 4975 5590
-3 4378 4975 4389
-3 4379 5592 4392
-3 5592 4985 4392
-3 4383 4393 5582
-3 5582 4393 5605
-3 4383 5582 4401
-3 5582 4986 4401
-3 4968 4978 4976
-3 4979 4978 4968
-3 4993 4968 4980
-3 4993 4979 4968
-3 4981 4980 4968
-3 4394 4396 4981
-3 4969 4994 4970
-3 4994 4969 4982
-3 4969 4972 4982
-3 4983 4972 4971
-3 4983 4984 4972
-3 4984 4982 4972
-3 4975 4378 4391
-3 4975 4391 5597
-3 5597 4391 4397
-3 4985 4416 4392
-3 4393 4400 5605
-3 4986 4402 4401
-3 5599 4402 4986
-3 4987 4988 4989
-3 4989 5600 4987
-3 4990 4977 4976
-3 4991 4990 4976
-3 4978 4992 4976
-3 4992 4991 4976
-3 4979 4992 4978
-3 4984 4995 4982
-3 4995 4994 4982
-3 5603 4984 4983
-3 4995 4984 5603
-3 5597 4397 4419
-3 5009 5597 4419
-3 4402 5599 4412
-3 4987 4997 4988
-3 5600 4997 4987
-3 4977 4990 4998
-3 4991 4999 4990
-3 4992 5000 4991
-3 5000 4999 4991
-3 5007 4979 4993
-3 5007 5000 4979
-3 5000 4992 4979
-3 4994 4995 5008
-3 5008 4995 5603
-3 4974 5590 4415
-3 5613 4416 4985
-3 4410 5605 4400
-3 4410 5001 5002
-3 4410 5002 5605
-3 4412 5001 5003
-3 4412 5599 5001
-3 5002 5001 5599
-3 4412 5003 5012
-3 5006 4996 5606
-3 5006 5005 4996
-3 5005 5004 4996
-3 4998 4418 4977
-3 5000 5007 4999
-3 4415 7464 4403
-3 5009 5010 5011
-3 4416 5010 5017
-3 4416 5613 5010
-3 5011 5010 5613
-3 4416 5017 4420
-3 4410 4417 5001
-3 4417 5012 5001
-3 5012 5003 5001
-3 5005 5013 5004
-3 5014 5013 5005
-3 5006 5014 5005
-3 4977 5015 5016
-3 4977 4418 5015
-3 4999 5007 4425
-3 4990 4999 4425
-3 4419 5025 5009
-3 5025 5010 5009
-3 5017 5010 5025
-3 4420 5017 5018
-3 5018 5019 4420
-3 5019 5020 4420
-3 5012 4417 5021
-3 5015 4434 5016
-3 5015 4423 4434
-3 4423 5015 5022
-3 5022 5015 4418
-3 4418 4424 5022
-3 5023 4427 4426
-3 5023 5024 4427
-3 4419 4427 5024
-3 4419 5024 5025
-3 4428 5025 4438
-3 4428 5018 5025
-3 5018 5017 5025
-3 4439 5018 4428
-3 4439 5026 5018
-3 5026 5019 5018
-3 5020 5019 5027
-3 5027 5019 5026
-3 4421 5027 4429
-3 5020 5027 4421
-3 5028 5021 4417
-3 4431 4430 5029
-3 5029 5030 4431
-3 4431 5030 4433
-3 5016 4434 5031
-3 5031 4434 4435
-3 5022 4436 4423
-3 5022 5033 4436
-3 5033 5032 4436
-3 4424 5033 5022
-3 4424 4437 5033
-3 4437 5034 5033
-3 5007 5628 4425
-3 5023 4426 5634
-3 5025 5024 4448
-3 4438 5025 4448
-3 4449 5026 4439
-3 4449 5027 5026
-3 4429 5027 4440
-3 4417 4441 5028
-3 4430 4442 5029
-3 4443 5029 4442
-3 5030 5029 4443
-3 4433 5030 4443
-3 4435 5035 5031
-3 4444 5035 4435
-3 4436 5032 4444
-3 4444 5032 5035
-3 4437 4445 5034
-3 5034 4445 5036
-3 4440 5027 4449
-3 4467 4425 5628
-3 5037 4447 4448
-3 5634 4447 5037
-3 5038 5046 5045
-3 5047 5046 5038
-3 4456 4455 5047
-3 4445 4459 5036
-3 4467 5036 4459
-3 5048 5041 5040
-3 5049 5041 5048
-3 4461 5050 5051
-3 4462 4461 5052
-3 4461 5051 5052
-3 5053 4462 5052
-3 4452 5075 5054
-3 5042 4452 5055
-3 5055 4452 5054
-3 4453 5055 4473
-3 5042 5055 4453
-3 5043 5044 5056
-3 5044 5067 5056
-3 5045 5058 5044
-3 5058 5067 5044
-3 5046 5058 5045
-3 5047 5059 5046
-3 5059 5058 5046
-3 4455 4463 5059
-3 5047 4455 5059
-3 4456 5047 5641
-3 5641 4457 4456
-3 5641 4465 4457
-3 4467 4459 4466
-3 5048 5060 5049
-3 5050 4461 4479
-3 5050 4479 5071
-3 4462 5053 4470
-3 5053 5061 4470
-3 5063 4471 5062
-3 5063 5640 4471
-3 4472 4471 5640
-3 5075 5064 5054
-3 5055 5054 5065
-3 5065 5054 5064
-3 5055 5065 4473
-3 4475 4474 5066
-3 5056 5066 5057
-3 5056 4475 5066
-3 5067 4475 5056
-3 5058 5068 5067
-3 4463 5068 5059
-3 5059 5068 5058
-3 4465 5641 4478
-3 5641 5069 4478
-3 4479 5070 5071
-3 4481 5070 5072
-3 4481 5061 5070
-3 4481 4470 5061
-3 5071 5070 5061
-3 4481 5062 4471
-3 4481 5072 5062
-3 5072 5073 5062
-3 5074 5063 5062
-3 5073 5074 5062
-3 5642 4472 5640
-3 4472 5642 4492
-3 4486 5064 5075
-3 4487 5064 4486
-3 5065 5064 4487
-3 4473 5065 4487
-3 5066 4474 5076
-3 4479 4488 5070
-3 4488 5077 5070
-3 5077 5072 5070
-3 5073 5072 5078
-3 5078 5072 5077
-3 5644 5074 5073
-3 5078 5644 5073
-3 5644 5079 5642
-3 4492 5642 5080
-3 5642 5079 5080
-3 4486 5075 4493
-3 4488 4495 5077
-3 4489 5077 4495
-3 5078 5077 4489
-3 5078 4489 5644
-3 4489 4497 5644
-3 4497 5084 5079
-3 4497 5079 5644
-3 5085 5647 5080
-3 5085 5080 5084
-3 5084 5080 5079
-3 5647 4492 5080
-3 4501 5086 4502
-3 4500 5086 4501
-3 4502 5086 4506
-3 5076 4474 5087
-3 5087 5081 5076
-3 3926 5082 5088
-3 5083 3931 5109
-3 5089 5083 5096
-3 4503 5090 4504
-3 5096 5090 4503
-3 4497 4505 5084
-3 5084 4505 5085
-3 5086 4500 5092
-3 5093 5086 5092
-3 4506 5086 5093
-3 4506 5093 5094
-3 5083 5089 5095
-3 5096 5097 5089
-3 5097 5095 5089
-3 5097 5096 4503
-3 5666 5090 5096
-3 5090 5666 4512
-3 5098 4505 4507
-3 5098 5654 4505
-3 5654 5085 4505
-3 4507 5091 5098
-3 5098 5091 5099
-3 5099 5091 5104
-3 5100 5101 5102
-3 5102 5103 5100
-3 5092 4500 5118
-3 5098 4508 5654
-3 4508 5659 5654
-3 5099 3944 5098
-3 3944 5099 5104
-3 4510 5104 5105
-3 5100 5108 5101
-3 5103 5108 5100
-3 5118 4500 5117
-3 5109 3952 4509
-3 3931 3952 5109
-3 3936 5666 5659
-3 5659 4508 3936
-3 4515 4510 5105
-3 4515 5105 5106
-3 5110 5106 5107
-3 5110 5111 5106
-3 5111 4515 5106
-3 5125 4511 4514
-3 5666 3936 4512
-3 4515 5111 5127
-3 5120 5119 5112
-3 5112 5672 5120
-3 5121 5674 5114
-3 5114 5113 5121
-3 5113 5122 5121
-3 5122 5113 5114
-3 4511 5125 4513
-3 5125 4514 4518
-3 5126 5125 4518
-3 5128 5681 5118
-3 5118 5117 5128
-3 5117 5129 5128
-3 5130 5129 5117
-3 5119 5131 5135
-3 5119 5120 5131
-3 5682 5120 5672
-3 5131 5120 5682
-3 5121 5686 5674
-3 5122 5686 5121
-3 5116 5115 5132
-3 5123 4517 5132
-3 5123 5132 5115
-3 5123 5124 4516
-3 5124 5133 4516
-3 4513 5125 5697
-3 4518 5680 5126
-3 5127 5134 4515
-3 5681 5129 4522
-3 5681 5128 5129
-3 5682 5135 5131
-3 4517 4519 5136
-3 5132 4517 5136
-3 4516 5133 4520
-3 5133 5137 4520
-3 4513 5697 4521
-3 5680 4518 5138
-3 5138 4518 4525
-3 5681 4522 5134
-3 4519 4528 5136
-3 4523 4520 5137
-3 4527 5138 4525
-3 4527 5139 5138
-3 4528 5712 5136
-3 4530 4523 5137
-3 5712 4530 5137
-3 5141 4527 4521
-3 4527 5141 5142
-3 4527 5142 5143
-3 5139 4527 5144
-3 5144 4527 5143
-3 5699 4531 5140
-3 5699 5708 4531
-3 5708 5715 4531
-3 4529 5145 4528
-3 4528 5145 5716
-3 5716 5712 4528
-3 4529 4531 5715
-3 4529 5715 5145
-3 4536 5146 4534
-3 5147 5146 4536
-3 4533 5148 4536
-3 5148 5147 4536
-3 5149 5148 4533
-3 4551 5152 4533
-3 5727 4539 4540
-3 4547 4546 5150
-3 4547 5150 5146
-3 4547 5146 5147
-3 4548 4547 5147
-3 4548 5147 5148
-3 5149 5160 5151
-3 5151 4549 5149
-3 5148 5149 4548
-3 4548 5149 4549
-3 4553 5152 4551
-3 5164 5152 4553
-3 5153 5154 4538
-3 4554 4538 5154
-3 4539 5155 4540
-3 5155 5156 4540
-3 5157 5158 4557
-3 5160 5150 4546
-3 5160 4546 5159
-3 5160 5159 5161
-3 5161 5162 5160
-3 5160 5162 5151
-3 5151 5162 5163
-3 4549 5163 4559
-3 5151 5163 4549
-3 5164 4563 5165
-3 5164 4553 4563
-3 5165 5166 5167
-3 5164 5165 5167
-3 5153 5168 4564
-3 4566 5153 4564
-3 5154 5153 4566
-3 4565 5154 4566
-3 4565 5169 5154
-3 4556 5154 5169
-3 5169 5155 4556
-3 4556 5155 4539
-3 5156 5155 5170
-3 4540 5156 5170
-3 5179 4540 5170
-3 4557 5158 5171
-3 5158 5157 5171
-3 4558 5172 5159
-3 5161 5159 5172
-3 5163 5162 5184
-3 5184 5162 5161
-3 5163 5184 4559
-3 5165 4569 5173
-3 4563 4569 5165
-3 5166 5165 5173
-3 5768 5167 5166
-3 5768 5166 5174
-3 5174 4577 5768
-3 5175 5176 5153
-3 5168 5153 5176
-3 5168 5176 4570
-3 4565 5177 5169
-3 5155 5169 5783
-3 5170 5155 5783
-3 5179 5170 5178
-3 5157 5179 5180
-3 5171 5157 5181
-3 5181 5157 5180
-3 5172 5171 5181
-3 5183 5172 5182
-3 5161 5172 5183
-3 5184 5161 5183
-3 4567 5185 4571
-3 4571 5173 4569
-3 4571 5185 5173
-3 4572 5173 4573
-3 4573 5173 5185
-3 4575 5173 4572
-3 4575 5186 5173
-3 5186 5166 5173
-3 5174 5186 4576
-3 5174 5166 5186
-3 4577 5187 5768
-3 5188 5189 5175
-3 5217 5188 5175
-3 5175 5189 5190
-3 5176 5175 5191
-3 5191 5175 5190
-3 4570 5176 5192
-3 5176 5191 5192
-3 5192 5193 5177
-3 5204 5177 5193
-3 5169 5177 5204
-3 5179 5178 5205
-3 5180 5179 5195
-3 5195 5179 5194
-3 5196 5180 5195
-3 5181 5180 5196
-3 5784 5183 5182
-3 5784 5197 5183
-3 5184 5183 5197
-3 4559 5184 5209
-3 5209 5184 5197
-3 4559 5209 4580
-3 4580 5198 4567
-3 5185 4567 5199
-3 5199 4567 5198
-3 4573 5199 4574
-3 4573 5185 5199
-3 4574 5186 4575
-3 4574 5199 5186
-3 5199 5212 5186
-3 4576 5186 4581
-3 5186 5212 4581
-3 5214 4583 3974
-3 5217 5200 5201
-3 5188 5217 5201
-3 5189 5188 5202
-3 5202 5188 5201
-3 5190 5189 5203
-3 5203 5189 5202
-3 5191 5190 5193
-3 5193 5190 5203
-3 5192 5191 5193
-3 5194 5179 5205
-3 5206 5195 5205
-3 5205 5195 5194
-3 5206 5824 5195
-3 5195 5824 5196
-3 5181 5196 5207
-3 5207 5196 5824
-3 5172 5181 5207
-3 5182 5172 5207
-3 5223 5182 5207
-3 5208 5784 5182
-3 5208 5182 5223
-3 4580 5209 5825
-3 5825 5198 4580
-3 5198 5210 5199
-3 5211 5199 5210
-3 5212 5199 5211
-3 4581 5212 5224
-3 4581 5224 5225
-3 5225 5187 4581
-3 5213 4583 5214
-3 4585 4587 5215
-3 5216 5218 5217
-3 5217 5218 5200
-3 5201 5200 5219
-3 5219 5200 5218
-3 5202 5201 5220
-3 5220 5201 5219
-3 5193 5203 5220
-3 5220 5203 5202
-3 5221 5207 5857
-3 5222 5207 5221
-3 5223 5207 5222
-3 5208 5223 5228
-3 5197 5208 5228
-3 5209 5197 5228
-3 5211 5210 5233
-3 5212 5211 5229
-3 5229 5211 5233
-3 5224 5212 5229
-3 5187 5225 5230
-3 5879 5214 3974
-3 5879 3974 4588
-3 5226 4589 4585
-3 5215 5226 4585
-3 5215 4587 4593
-3 5215 4593 5226
-3 5227 5226 4593
-3 5217 5226 5227
-3 5217 5227 5216
-3 5216 5227 5231
-3 5218 5216 5231
-3 5219 5218 5231
-3 5220 5219 5231
-3 5222 5221 5857
-3 5223 5222 5228
-3 5228 5222 5857
-3 5825 5209 5228
-3 5233 5210 5232
-3 5224 5229 5234
-3 5225 5224 5234
-3 5230 5225 5234
-3 5226 5235 4589
-3 4596 5227 4593
-3 5825 5228 5874
-3 5210 5825 5874
-3 5234 5229 5233
-3 4600 5879 4588
-3 5227 4596 5238
-3 5238 5231 5227
-3 5233 5232 5234
-3 5879 4600 5236
-3 5236 4600 4604
-3 4608 5236 4604
-3 4608 5239 5236
-3 5237 5239 4608
-3 5237 4612 5239
-3 5238 4606 5241
-3 4628 5242 4626
-3 5242 4628 4051
-3 5243 4620 4627
-3 5242 5244 5243
-3 5242 5243 4633
-3 5242 4633 4626
-3 4051 5244 5242
-3 4627 4634 5243
-3 4633 5243 4634
-3 5244 4051 5964
-3 4643 4629 6015
-3 4639 5245 5246
-3 4641 5247 5248
-3 4641 5248 5246
-3 6028 5249 5248
-3 5246 5248 5249
-3 5246 5249 4639
-3 5247 5250 5251
-3 4641 5250 5247
-3 4641 4644 5250
-3 4645 5249 6028
-3 5250 4644 4650
-3 4645 6028 5252
-3 4645 5252 4646
-3 4650 4649 5250
-3 4649 5253 5250
-3 4646 5252 4648
-3 4049 4651 5253
-3 5253 4652 4049
-3 5253 4649 4652
-3 4648 5252 4656
-3 5256 6052 4642
-3 4651 4655 5253
-3 5254 4655 4657
-3 5254 6064 4655
-3 6064 5253 4655
-3 4657 4656 5255
-3 5254 4657 5255
-3 4656 5258 5255
-3 4656 6066 5258
-3 5254 5257 6064
-3 5257 5258 5259
-3 5257 5254 5258
-3 5254 5255 5258
-3 6053 5256 5265
-3 5259 5258 5262
-3 5260 4051 1262
-3 5265 5256 5261
-3 5259 5262 5264
-3 5264 5262 5263
-3 4658 5265 5261
-3 4658 4659 5265
-3 5265 4659 5267
-3 5267 4659 5266
-3 5268 4050 6143
-3 4052 5267 5266
-3 5270 5275 5268
-3 5275 5269 5268
-3 5276 5275 5270
-3 5276 5277 5275
-3 5278 5271 5273
-3 5278 5277 5271
-3 5272 5271 5276
-3 5276 5271 5277
-3 5267 4052 5285
-3 5269 5279 5274
-3 5275 5280 5269
-3 5280 5279 5269
-3 5280 5277 5281
-3 5280 5275 5277
-3 5278 5281 5277
-3 5279 5282 5274
-3 5282 5287 5274
-3 5283 5279 5284
-3 5283 5282 5279
-3 5280 5284 5279
-3 5274 5286 4662
-3 5287 5286 5274
-3 5282 5288 5287
-3 5288 5282 5283
-3 4662 5286 6230
-3 6230 5286 5287
-3 6241 4662 6230
-3 6241 5289 4662
-3 5290 5289 6241
-3 5290 5291 5295
-3 4666 4662 5289
-3 4666 5289 5302
-3 5296 5302 5289
-3 5290 5293 5289
-3 5293 5296 5289
-3 5294 5293 5290
-3 5295 5294 5290
-3 6274 5295 5291
-3 5299 5285 5292
-3 4667 5296 5294
-3 5294 5296 5293
-3 4667 5294 5297
-3 5297 5294 5295
-3 5305 5295 6274
-3 5297 5295 5305
-3 4672 5298 5292
-3 5299 5292 5298
-3 5302 5308 4666
-3 4667 5304 5296
-3 5296 5304 5303
-3 4667 5305 5304
-3 4667 5297 5305
-3 5302 5309 5308
-3 5309 5302 5296
-3 5303 5309 5296
-3 5310 5309 5303
-3 5304 5310 5303
-3 5305 5310 5304
-3 4671 5316 5306
-3 5306 5311 4679
-3 5299 5298 5318
-3 5307 5300 5314
-3 5315 5307 5314
-3 6326 5315 4684
-3 5319 4675 5308
-3 5316 5317 5306
-3 4679 5311 5317
-3 5311 5306 5317
-3 5321 5299 5318
-3 5322 5299 5321
-3 4682 5300 5324
-3 5314 5300 4682
-3 4684 5315 5314
-3 5317 5316 5320
-3 6369 5322 5323
-3 5327 4677 5325
-3 5319 5325 4677
-3 5328 5325 5319
-3 6380 5328 5319
-3 5308 6380 5319
-3 5335 5321 5318
-3 5322 5321 5335
-3 5328 4697 5325
-3 4691 5330 4692
-3 5329 5330 4691
-3 4692 5331 4693
-3 5330 5331 4692
-3 5332 5333 5334
-3 5343 5333 5332
-3 5336 5322 5335
-3 5323 5322 5336
-3 6369 5323 5345
-3 5346 5324 6378
-3 5337 5326 6440
-3 5326 5338 6440
-3 4696 5327 5339
-3 5327 4100 5339
-3 4698 4697 5328
-3 4698 5328 6380
-3 5329 4700 5340
-3 4691 4700 5329
-3 5331 5340 4701
-3 5331 5330 5340
-3 5330 5329 5340
-3 5342 5343 5332
-3 5334 5344 5332
-3 5344 5342 5332
-3 4716 5335 5318
-3 4716 5336 5335
-3 5345 5354 6369
-3 4717 5324 5346
-3 4718 5324 4717
-3 4703 5324 4718
-3 5337 2279 5326
-3 4706 4696 5347
-3 5347 5339 5348
-3 5347 4696 5339
-3 5349 5348 5339
-3 5349 5339 4100
-3 5349 4100 5350
-3 4698 5351 4128
-3 4707 5352 6415
-3 4708 4707 6417
-3 4707 6415 6417
-3 4708 6417 5357
-3 4710 5353 4700
-3 5358 5353 4710
-3 4700 5353 5340
-3 4701 5340 4712
-3 4712 5340 5353
-3 5344 5343 5342
-3 5345 5323 5336
-3 5354 5345 5336
-3 6428 6369 5354
-3 4743 5346 6405
-3 4717 5346 5355
-3 5356 4724 5347
-3 4724 4706 5347
-3 5350 4100 6501
-3 4708 5357 4726
-3 5358 4710 4726
-3 5358 4726 5357
-3 6485 5353 5358
-3 6485 4712 5353
-3 4742 5336 4716
-3 4762 5336 4742
-3 5354 5336 4180
-3 6405 6465 4763
-3 4743 6405 4763
-3 5346 4743 4744
-3 5355 5346 4744
-3 4717 5355 4744
-3 5360 4736 4723
-3 4749 5356 4750
-3 4724 5356 4749
-3 6501 4100 4750
-3 4771 4128 5351
-3 5352 4707 5374
-3 4712 6485 4739
-3 4762 4180 5336
-3 4794 6465 5359
-3 4763 6465 4794
-3 3635 5361 4684
-3 4785 4736 5363
-3 5363 4736 5360
-3 5360 4723 5365
-3 4723 4737 5365
-3 5362 3635 2279
-3 6440 5338 5379
-3 4737 5372 5365
-3 5375 4138 4752
-3 4739 5375 4752
-3 4753 4773 5366
-3 4757 5367 4776
-3 4775 5367 4757
-3 6567 4776 5367
-3 4777 4776 5368
-3 4759 4777 5368
-3 4778 4759 5368
-3 5368 6598 4778
-3 4794 5359 5354
-3 4769 4798 5369
-3 5371 5370 5365
-3 5372 5371 5365
-3 4154 4771 5373
-3 4138 5375 6615
-3 4788 5385 6623
-3 4773 4772 4788
-3 4773 4788 6623
-3 5366 4773 6623
-3 4753 5366 5376
-3 5377 5376 5378
-3 5377 4753 5376
-3 4753 5377 4789
-3 5367 4775 4790
-3 4790 6567 5367
-3 6598 4791 4778
-3 5369 5386 4805
-3 5369 4798 5386
-3 4785 5363 5389
-3 5364 5389 5363
-3 5389 5364 6603
-3 5371 5381 5370
-3 5381 5380 5370
-3 5372 5382 5371
-3 5382 5381 5371
-3 5383 5382 5372
-3 5383 5372 4154
-3 5373 5383 4154
-3 5394 5384 5374
-3 4138 6615 4806
-3 5395 4172 5378
-3 5377 5378 4172
-3 5377 4172 4789
-3 4171 6660 4790
-3 4791 6660 4171
-3 6598 6660 4791
-3 4804 6695 4783
-3 4798 5387 5386
-3 5387 4798 5388
-3 5388 4785 5401
-3 4785 5389 5401
-3 6603 6680 5389
-3 5381 5390 5380
-3 5391 5390 5382
-3 5390 5381 5382
-3 5383 5391 5382
-3 6609 5392 5393
-3 5384 5393 5392
-3 5384 5394 5393
-3 4810 5395 5396
-3 4172 5395 4810
-3 5411 5399 5398
-3 4796 6676 4812
-3 4169 6676 4796
-3 6695 6676 4169
-3 6677 6695 4804
-3 4805 5386 5417
-3 5387 5417 5386
-3 5417 5388 5400
-3 5417 5387 5388
-3 5401 5400 5388
-3 6680 5402 5389
-3 5402 5401 5389
-3 5430 5370 5380
-3 4813 5380 5390
-3 5390 4814 4813
-3 5390 5391 4814
-3 5393 5404 6609
-3 5404 5403 6609
-3 5405 5404 5393
-3 5394 5405 5393
-3 5394 5406 5405
-3 5406 4806 5407
-3 5407 4806 6615
-3 4819 5385 4815
-3 5385 4816 4815
-3 4810 5396 4820
-3 4820 5396 5408
-3 4191 5409 6667
-3 5397 4191 6667
-3 5397 4822 4191
-3 5410 4822 5397
-3 5397 6692 5410
-3 5398 5413 5411
-3 5399 5413 5398
-3 5413 5399 5414
-3 5415 6677 5416
-3 6677 4804 5416
-3 4805 5416 4804
-3 5417 5416 4805
-3 5400 5401 5418
-3 5401 5402 5418
-3 6680 5419 5402
-3 5419 5418 5402
-3 6680 5430 5419
-3 5380 4818 5430
-3 4813 4818 5380
-3 4825 4814 5420
-3 5403 5404 5431
-3 5405 5421 5404
-3 5421 5431 5404
-3 5422 5421 5405
-3 5406 5423 5405
-3 5423 5422 5405
-3 5424 5423 5406
-3 5407 5425 5406
-3 5425 5424 5406
-3 5426 5425 5407
-3 5407 5427 5426
-3 5427 6707 4819
-3 5385 4819 6707
-3 4191 4821 5409
-3 5428 5410 6692
-3 4822 5410 5428
-3 5414 5411 5413
-3 4823 6720 5379
-3 4828 4824 4812
-3 6676 4828 4812
-3 5429 5415 5416
-3 5417 5429 5416
-3 5400 5418 5419
-3 5421 5422 5431
-3 5423 5431 5422
-3 5424 5432 5423
-3 5432 5431 5423
-3 5425 5432 5424
-3 5426 5432 5425
-3 5427 5433 5426
-3 5433 5432 5426
-3 4819 5433 5427
-3 4820 6739 4833
-3 5408 6739 4820
-3 4821 4199 5409
-3 4822 5428 4199
-3 4823 5444 6720
-3 5419 5435 5400
-3 5435 5419 5430
-3 4825 5438 4836
-3 5420 5438 4825
-3 5432 6757 5431
-3 5439 5432 5433
-3 4833 6739 6782
-3 4835 5436 5430
-3 5430 5436 5435
-3 5436 4835 5437
-3 5438 5437 4836
-3 5439 4832 5443
-3 6779 5443 4832
-3 6779 4832 5440
-3 4833 5440 4832
-3 5440 4833 6782
-3 5441 4206 4839
-3 5438 5436 5437
-3 5439 5442 6818
-3 5443 5442 5439
-3 4838 5434 4850
-3 5441 4839 4841
-3 5447 6818 5442
-3 5447 5442 5443
-3 5456 5444 4823
-3 4840 5449 4842
-3 4840 5445 5449
-3 5445 5448 5449
-3 5450 6815 5446
-3 5451 6815 5450
-3 4843 4844 5450
-3 4843 5450 5441
-3 5441 5450 5446
-3 4841 4843 5441
-3 6830 4846 4206
-3 5452 5453 5454
-3 6882 6840 4849
-3 4823 4237 5456
-3 4843 5451 5450
-3 4843 5450 4844
-3 5453 5457 5458
-3 5453 5452 5457
-3 5459 5457 5454
-3 5454 5457 5452
-3 5457 5460 5461
-3 5459 5460 5457
-3 4869 5451 4843
-3 5458 5463 5471
-3 5458 5457 5463
-3 5457 5461 5463
-3 5460 5464 5461
-3 5464 5463 5461
-3 5465 5466 5467
-3 4245 5468 4852
-3 4851 5468 4245
-3 4856 5455 4855
-3 4858 6890 4867
-3 4858 5478 6890
-3 6890 5470 4867
-3 4869 5479 5451
-3 5464 5471 5463
-3 5472 5473 4860
-3 5473 4861 4860
-3 5473 4863 4861
-3 5474 4863 5473
-3 5469 5477 5476
-3 5455 4864 4855
-3 4858 4865 5478
-3 5470 6949 4867
-3 4859 5480 5482
-3 5472 4860 6904
-3 4860 4868 6904
-3 5474 4868 4863
-3 6904 4868 5474
-3 5476 6926 5475
-3 5456 4237 6980
-3 6983 5478 4867
-3 4867 5478 4865
-3 4867 6949 6983
-3 4870 5479 4869
-3 5479 4870 6920
-3 4870 5482 5480
-3 4870 5480 6920
-3 4877 6980 4237
-3 5481 5482 4870
-3 6933 5496 4874
-3 4877 7000 6980
-3 5483 5482 5481
-3 5482 5483 5484
-3 4882 4874 5496
-3 5486 5488 5487
-3 5484 5483 4879
-3 5489 5490 4876
-3 5490 5491 4876
-3 4873 5504 5492
-3 4873 5492 4881
-3 5492 5493 4881
-3 5495 5493 5494
-3 5485 4874 5506
-3 5497 7032 5486
-3 5487 5499 5486
-3 5499 5498 5486
-3 5500 5499 5487
-3 5488 5508 5487
-3 5508 5500 5487
-3 5508 5488 5501
-3 5515 5489 4898
-3 5489 5515 7034
-3 5489 5502 5490
-3 5503 5490 5502
-3 5491 5490 5503
-3 4910 5485 5505
-3 5506 5505 5485
-3 4882 5496 4962
-3 5497 4883 4289
-3 5507 5498 5499
-3 5500 5507 5499
-3 5509 5512 5511
-3 5510 5512 5509
-3 5511 5512 5513
-3 5513 5514 5525
-3 5512 5514 5513
-3 4898 5514 5515
-3 4889 5517 5518
-3 5516 5517 4889
-3 5519 5504 4892
-3 4910 5527 5485
-3 5520 5505 5506
-3 5521 5520 5506
-3 5506 4894 5521
-3 4289 4895 5497
-3 5497 4895 4896
-3 5497 4896 5535
-3 4897 5507 5500
-3 5508 4913 5500
-3 4913 4897 5500
-3 5501 4913 5508
-3 5523 5510 5509
-3 5511 5524 5509
-3 5524 5523 5509
-3 5513 5530 5511
-3 5530 5524 5511
-3 5525 5530 5513
-3 5514 4898 5525
-3 5531 4308 4899
-3 7067 5531 4899
-3 4901 7067 4899
-3 5502 7067 4901
-3 4902 5502 4901
-3 4902 5526 5502
-3 5526 5503 5502
-3 4889 4903 5516
-3 4904 5516 4903
-3 5517 5516 4904
-3 4905 5517 4904
-3 5518 5517 4905
-3 4909 4921 5527
-3 4909 5527 4910
-3 5505 5520 5528
-3 5528 5520 5521
-3 4894 5544 5528
-3 5521 4894 5528
-3 5535 4896 4912
-3 5523 5524 5536
-3 5530 5529 5524
-3 5529 5536 5524
-3 5525 4914 5530
-3 4902 4916 5526
-3 4921 5543 7180
-3 4921 7180 5527
-3 5528 5544 5532
-3 7237 4373 4850
-3 4912 4922 5535
-3 4913 5501 4923
-3 5501 5558 4923
-3 4355 5522 5549
-3 5530 5536 5529
-3 4914 5536 5530
-3 5538 5537 5531
-3 5531 5537 5550
-3 4926 4925 5541
-3 4926 5541 4921
-3 5541 5542 4921
-3 5543 4921 5542
-3 7192 5533 5545
-3 5534 5545 5533
-3 5545 5546 5547
-3 5534 5546 5545
-3 7197 5535 4922
-3 4933 4923 5558
-3 4935 5559 4914
-3 4937 7169 7211
-3 4938 7169 4937
-3 5538 4938 5537
-3 5538 7169 4938
-3 4938 5550 5537
-3 5540 5551 5539
-3 4845 7220 5643
-3 5552 4927 5563
-3 5563 4927 4928
-3 5553 5554 5555
-3 4939 5555 5554
-3 5547 5556 5545
-3 5548 4943 5557
-3 4931 4943 5548
-3 4932 5557 4944
-3 5548 5557 4932
-3 4922 4945 7197
-3 4346 4355 5549
-3 5559 4935 5560
-3 5561 7211 7248
-3 5561 4946 7211
-3 4946 4937 7211
-3 4938 4947 5550
-3 5541 4948 5542
-3 5562 5542 4948
-3 4927 5552 4349
-3 4349 5552 7223
-3 5553 5555 4960
-3 5564 5554 5553
-3 5554 5565 4951
-3 5554 5564 5565
-3 4951 5565 5570
-3 4951 5570 4941
-3 4943 4944 5557
-3 4292 4952 5576
-3 5566 4953 4346
-3 7248 4954 5567
-3 7248 5560 4954
-3 5560 4935 4954
-3 7248 5567 5561
-3 5561 5567 5573
-3 5561 5573 4946
-3 4948 4956 5562
-3 5562 4956 5568
-3 5569 4349 7223
-3 5569 4959 4349
-3 5563 4928 4960
-3 5570 5565 5564
-3 5570 5564 4961
-3 4953 5566 5571
-3 4954 5572 5567
-3 5573 5567 5572
-3 5574 5587 5568
-3 4959 5575 5574
-3 4959 5574 5568
-3 4959 5568 4956
-3 4959 7302 5575
-3 4959 5569 7302
-3 5580 4933 5558
-3 5580 5592 4933
-3 5571 7361 4381
-3 4953 5571 4381
-3 5577 5573 5572
-3 5587 5574 5578
-3 5574 5579 5578
-3 7302 5579 5575
-3 5579 5574 5575
-3 4965 7344 4961
-3 7345 4971 4962
-3 4973 7464 4966
-3 7464 4945 4966
-3 4952 5581 5576
-3 4381 5581 4952
-3 7361 5581 4381
-3 5583 5584 5585
-3 5586 5587 5578
-3 5579 5588 5578
-3 5588 5586 5578
-3 5588 5579 7302
-3 7344 4965 4968
-3 7344 4968 4977
-3 5589 4384 4970
-3 7345 5596 4971
-3 4975 5591 5580
-3 4975 5580 5590
-3 5592 5580 5591
-3 4989 7402 5584
-3 5600 4989 5583
-3 5584 5583 4989
-3 5594 5587 5586
-3 5602 5587 5594
-3 5594 5586 5588
-3 4977 4968 4976
-3 7410 4993 4980
-3 7410 4980 5589
-3 5589 4980 4981
-3 4396 5589 4981
-3 5589 4396 4384
-3 4994 5589 4970
-3 4994 5595 5596
-3 4994 5596 5589
-3 4983 5596 5595
-3 4983 4971 5596
-3 4973 4403 7464
-3 5597 5591 4975
-3 5597 5592 5591
-3 4985 5592 5598
-3 5592 5597 5598
-3 4986 5582 5599
-3 5582 5605 5599
-3 5607 4996 5593
-3 7402 4988 5600
-3 4989 4988 7402
-3 5602 5594 5601
-3 4993 7410 5623
-3 4983 5595 5603
-3 5603 5595 4994
-3 5009 5604 5597
-3 5604 5598 5597
-3 5598 5604 4985
-3 5607 5606 4996
-3 4988 4997 5600
-3 5609 5602 5601
-3 5610 5601 5594
-3 5609 5601 5610
-3 5007 4993 5623
-3 5008 5603 4994
-3 7486 4415 5590
-3 5604 5009 5612
-3 4985 5604 5613
-3 5604 5612 5613
-3 5599 5605 5002
-3 4996 5004 5593
-3 5593 5004 5615
-3 5006 5606 5614
-3 5614 5606 5607
-3 5617 5607 7447
-3 5614 5607 5617
-3 4977 5619 7477
-3 5611 4977 7477
-3 5011 5612 5009
-3 5613 5612 5011
-3 5013 5615 5004
-3 5616 5615 5014
-3 5014 5615 5013
-3 5014 5617 5616
-3 5006 5617 5014
-3 5006 5614 5617
-3 5016 5618 5619
-3 4977 5016 5619
-3 5007 5623 5628
-3 5016 5620 5618
-3 5620 5621 5618
-3 5619 5618 5622
-3 5622 5618 5621
-3 5619 5622 7503
-3 4963 4237 5677
-3 5023 5625 5024
-3 5624 5625 5023
-3 5031 5620 5016
-3 5031 5626 5620
-3 5626 5627 5620
-3 5032 5621 5627
-3 5621 5620 5627
-3 5033 5621 5032
-3 5622 5621 5033
-3 5034 5622 5033
-3 5034 5628 5622
-3 5628 7503 5622
-3 5623 7503 5628
-3 5624 5023 7530
-3 5023 5634 7530
-3 7540 5625 5624
-3 4448 5625 7540
-3 4448 5024 5625
-3 5031 5035 5626
-3 5032 5626 5035
-3 5627 5626 5032
-3 5034 5036 5628
-3 5037 4448 7540
-3 5039 5630 5631
-3 5038 5630 5039
-3 5631 5038 5039
-3 5628 5036 4467
-3 5040 5041 5629
-3 5040 5629 5633
-3 5044 5043 7556
-3 5045 5044 5630
-3 5044 7556 5630
-3 5630 5038 5045
-3 5047 5038 5631
-3 7565 5049 5639
-3 7565 5632 5049
-3 5632 5041 5049
-3 5048 5040 5633
-3 5048 5633 5639
-3 5051 5050 5635
-3 5051 5636 5052
-3 5635 5636 5051
-3 5052 5636 5053
-3 5056 5057 5637
-3 5056 5637 5638
-3 5056 5638 5043
-3 5047 5631 5641
-3 5049 5060 5639
-3 5048 5639 5060
-3 5071 5635 5050
-3 5071 5636 5635
-3 5053 5071 5061
-3 5636 5071 5053
-3 5057 5066 5637
-3 5640 5074 5642
-3 5063 5074 5640
-3 5066 5076 5637
-3 5645 5638 5637
-3 5645 5637 5076
-3 5069 5641 5082
-3 5074 5644 5642
-3 5645 5076 5081
-3 5641 7610 5082
-3 4373 7616 3952
-3 5081 5087 5645
-3 5088 5082 7610
-3 3952 7616 4509
-3 5109 5652 5083
-3 5646 5096 5083
-3 5647 5085 5654
-3 4492 5648 5091
-3 4492 5647 5648
-3 5647 5654 5648
-3 5649 7640 7620
-3 7620 5650 5649
-3 5651 5093 5092
-3 5094 5093 5651
-3 5087 5094 5645
-3 5094 5651 5645
-3 5096 5646 5653
-3 7666 5096 5653
-3 5666 5096 7666
-3 5091 5648 5104
-3 5655 7640 5649
-3 5650 5656 5649
-3 5656 5655 5649
-3 5105 5656 5650
-3 5102 5101 5657
-3 5102 5657 5103
-3 5116 7680 5115
-3 5115 7680 5665
-3 5109 5658 5652
-3 5660 5648 5659
-3 5659 5648 5654
-3 5104 5648 5660
-3 5655 5104 5660
-3 5105 5104 5655
-3 5656 5105 5655
-3 5107 5662 5661
-3 5107 5106 5662
-3 5106 5105 5662
-3 5101 5108 5657
-3 5103 5657 5108
-3 5118 7671 5092
-3 5663 5664 5112
-3 5671 7680 5116
-3 5115 5665 5123
-3 7686 5109 4509
-3 7686 5658 5109
-3 5660 5659 5666
-3 5107 5661 5110
-3 5661 5111 5110
-3 5661 5662 5111
-3 5112 5673 5672
-3 5114 5667 5668
-3 5668 5669 5670
-3 5667 5669 5668
-3 5671 5670 5669
-3 7777 7761 4509
-3 7761 7686 4509
-3 5662 5127 5111
-3 5683 7724 5674
-3 5114 5674 7724
-3 5668 5675 5122
-3 5114 5668 5122
-3 5670 5676 5668
-3 5676 5675 5668
-3 5671 5116 5670
-3 5116 5676 5670
-3 5124 5123 5665
-3 5679 5678 5691
-3 5127 5693 5681
-3 5127 5662 5693
-3 5681 5693 5118
-3 5119 5135 5112
-3 5673 5695 5672
-3 5695 5682 5672
-3 5673 5683 5695
-3 5683 5674 5684
-3 5685 5684 5674
-3 5674 5686 5685
-3 5122 5675 5687
-3 5676 5688 5675
-3 5688 5687 5675
-3 5116 5132 5688
-3 5116 5688 5676
-3 5703 5137 5665
-3 5124 5137 5133
-3 5665 5137 5124
-3 5689 5678 5679
-3 5690 5689 5679
-3 5691 5678 5689
-3 5691 5689 5692
-3 5125 7784 5697
-3 5126 7784 5125
-3 5127 5681 5134
-3 5694 5135 5682
-3 5695 5694 5682
-3 5708 5695 5683
-3 5685 5700 5684
-3 5686 5696 5685
-3 5696 5686 5122
-3 5687 5696 5122
-3 5132 5136 5688
-3 7803 5689 5690
-3 5692 5689 7803
-3 5680 5138 7824
-3 5695 5699 5694
-3 5699 5698 5694
-3 5708 5699 5695
-3 5684 5708 5683
-3 5685 5701 5700
-3 5696 5702 5685
-3 5702 5701 5685
-3 5688 5136 5703
-3 5704 5703 5136
-3 5703 5704 5137
-3 5138 5705 7824
-3 5706 5705 5138
-3 5139 5707 5138
-3 5138 5707 5706
-3 7826 5707 5139
-3 5140 5643 5698
-3 5699 5140 5698
-3 5700 5708 5684
-3 5701 5709 5700
-3 5702 5710 5701
-3 5710 5709 5701
-3 5711 5710 5702
-3 5136 5712 5704
-3 5137 5704 5712
-3 5141 7840 5713
-3 7824 5705 5142
-3 7824 5142 5713
-3 5713 5142 5141
-3 5705 5706 5142
-3 5142 5706 5143
-3 5144 5143 5714
-3 5143 5706 5714
-3 7826 5139 5144
-3 5714 7826 5144
-3 5700 5715 5708
-3 5709 5715 5700
-3 5710 5715 5709
-3 5711 5145 5710
-3 5145 5715 5710
-3 5711 5716 5145
-3 5716 5717 5712
-3 5712 5717 4530
-3 5677 4530 5718
-3 5141 4521 7840
-3 5716 5718 5717
-3 4530 5717 5718
-3 4539 5719 5720
-3 4539 5721 5719
-3 4539 5722 5721
-3 4539 5723 5722
-3 4539 5724 5723
-3 4539 5725 5724
-3 5727 5726 4539
-3 4539 5726 5725
-3 5727 5729 5728
-3 5727 5730 5729
-3 5727 5731 5730
-3 4534 5732 5731
-3 4534 5731 5727
-3 5733 4534 5146
-3 5745 5733 5146
-3 5734 5749 5149
-3 5734 5149 4533
-3 4533 5735 5734
-3 5152 5736 4533
-3 4533 5736 5735
-3 5152 5737 5736
-3 4538 5738 5739
-3 4538 5740 5738
-3 4539 5741 4538
-3 4538 5741 5740
-3 5741 4539 5720
-3 4534 5742 5732
-3 5743 5742 4534
-3 5744 5743 4534
-3 5733 5744 4534
-3 5746 5745 5146
-3 5150 5747 5746
-3 5146 5150 5746
-3 5149 5748 5160
-3 5149 5749 5748
-3 5152 5750 5737
-3 5751 5750 5152
-3 5152 5759 5751
-3 5152 5164 5759
-3 5153 5752 5753
-3 4538 5754 5153
-3 5153 5754 5752
-3 5754 4538 5739
-3 5150 5755 5747
-3 5150 5160 5755
-3 5160 5756 5755
-3 5160 5757 5756
-3 5748 5758 5160
-3 5758 5757 5160
-3 5760 5761 5759
-3 5164 5760 5759
-3 5164 5167 5762
-3 5760 5164 5762
-3 5153 5763 5764
-3 5763 5153 5753
-3 5765 5761 5760
-3 5766 5761 5765
-3 5762 5767 5760
-3 5767 5765 5760
-3 5167 5767 5762
-3 5167 5768 5767
-3 5768 5769 5767
-3 5771 5770 5768
-3 5175 5772 5773
-3 5153 5774 5175
-3 5175 5774 5772
-3 5774 5153 5764
-3 5776 5766 5765
-3 5775 5766 5776
-3 5767 5776 5765
-3 5777 5767 5769
-3 5776 5767 5777
-3 5768 5778 5771
-3 5779 5778 5768
-3 5780 5217 5781
-3 5175 5782 5217
-3 5217 5782 5781
-3 5782 5175 5773
-3 5170 5783 5178
-3 5198 5785 5786
-3 5787 5198 5786
-3 5776 5788 5775
-3 5788 5789 5790
-3 5788 5776 5789
-3 5791 5776 5777
-3 5789 5776 5791
-3 5792 5779 5187
-3 5779 5768 5187
-3 5792 5187 5793
-3 5795 5794 5217
-3 5780 5795 5217
-3 5204 5817 5169
-3 5817 5818 5169
-3 5819 5169 5818
-3 5796 5797 5783
-3 5796 5783 5819
-3 5819 5783 5169
-3 5798 5783 5797
-3 5799 5783 5798
-3 5800 5783 5799
-3 5801 5783 5800
-3 5802 5783 5801
-3 5820 5802 5803
-3 5178 5802 5820
-3 5178 5783 5802
-3 5820 5205 5178
-3 5197 5784 5208
-3 5198 5825 5804
-3 5198 5804 5785
-3 5210 5198 5805
-3 5805 5198 5787
-3 5789 5806 5790
-3 5791 5806 5789
-3 5807 5793 5187
-3 5214 5808 5809
-3 5213 5214 5809
-3 5214 5810 5808
-3 5214 5811 5810
-3 5812 5811 5214
-3 5217 5814 5813
-3 5814 5217 5794
-3 5835 5838 5193
-3 5815 5816 5204
-3 5815 5204 5838
-3 5838 5204 5193
-3 5817 5204 5816
-3 5821 5205 5820
-3 5205 5821 5822
-3 5823 5205 5822
-3 5205 5823 5206
-3 5823 5840 5206
-3 5824 5206 5840
-3 5824 5857 5207
-3 5826 5804 5210
-3 5210 5804 5825
-3 5805 5826 5210
-3 5827 5807 5187
-3 5213 5809 5240
-3 5809 5828 5240
-3 5214 5829 5812
-3 5829 5214 5879
-3 5830 5829 5879
-3 5831 5226 5832
-3 5226 5833 5832
-3 5850 5833 5226
-3 5226 5834 5850
-3 5226 5217 5834
-3 5217 5813 5834
-3 5220 5868 5193
-3 5835 5193 5868
-3 5836 5837 5835
-3 5838 5835 5837
-3 5840 5823 5839
-3 5841 5824 5840
-3 5841 5842 5824
-3 5854 5824 5842
-3 5857 5824 5854
-3 5187 5230 5843
-3 5843 5827 5187
-3 5828 5844 5240
-3 5879 5845 5830
-3 5879 5846 5845
-3 5847 5846 5879
-3 5226 5849 5235
-3 5849 5848 5235
-3 5831 5849 5226
-3 5868 5220 5231
-3 5851 5852 5835
-3 5851 5835 5868
-3 5836 5835 5852
-3 5854 5842 5853
-3 5855 5857 5854
-3 5855 5856 5857
-3 5230 5234 5858
-3 5230 5858 5859
-3 5230 5859 5843
-3 5240 5844 5860
-3 5861 5240 5860
-3 5879 5862 5847
-3 5879 5863 5862
-3 5235 5864 5865
-3 5864 5235 5848
-3 5866 5867 5231
-3 5866 5231 5885
-3 5868 5231 5867
-3 5857 5856 5869
-3 5870 5857 5869
-3 5871 5857 5870
-3 5872 5857 5871
-3 5872 5873 5857
-3 5857 5873 5228
-3 5228 5873 5874
-3 5874 5232 5210
-3 5234 5893 5875
-3 5234 5875 5876
-3 5234 5876 5858
-3 5861 5877 5240
-3 5879 5878 5863
-3 5880 5879 5236
-3 5235 5865 5881
-3 5882 5883 5231
-3 5884 5231 5883
-3 5885 5231 5884
-3 5874 5873 5886
-3 5887 5874 5886
-3 5888 5874 5887
-3 5889 5874 5888
-3 5890 5874 5889
-3 5890 5891 5874
-3 5904 5874 5891
-3 5232 5874 5905
-3 5905 5874 5904
-3 5234 5232 5909
-3 5909 5232 5908
-3 5910 5234 5909
-3 5892 5234 5910
-3 5892 5893 5234
-3 5240 5877 5894
-3 5895 5240 5894
-3 5236 5896 5880
-3 5236 5897 5896
-3 5897 5236 5898
-3 5900 5899 5235
-3 5881 5900 5235
-3 5238 5901 5231
-3 5901 5902 5231
-3 5902 5882 5231
-3 5904 5891 5903
-3 5906 5232 5905
-3 5907 5232 5906
-3 5908 5232 5907
-3 5911 5892 5910
-3 5895 5912 5240
-3 5236 5913 5898
-3 5236 5239 5913
-3 5239 5914 5913
-3 5915 5914 5239
-3 5235 5916 5917
-3 5916 5235 5899
-3 5919 5920 5901
-3 5919 5901 5918
-3 5918 5901 5238
-3 5902 5901 5920
-3 5921 5902 5920
-3 5922 5240 5912
-3 5239 5923 5915
-3 4612 5923 5239
-3 5924 5923 4612
-3 5925 5235 5917
-3 5926 5927 5918
-3 5926 5918 5935
-3 5935 5918 5238
-3 5919 5918 5927
-3 5240 5928 5929
-3 5240 5922 5928
-3 5930 4620 5931
-3 5930 5924 4620
-3 5924 4612 4620
-3 5925 5932 5235
-3 5241 5944 5933
-3 5241 5933 5934
-3 5241 5934 5238
-3 5935 5238 5934
-3 5240 5929 5936
-3 5936 5937 5240
-3 5931 4620 5938
-3 5939 5931 5938
-3 5939 5938 5940
-3 5235 5941 5942
-3 5941 5235 5932
-3 5241 5943 5944
-3 5937 5945 5240
-3 4620 5243 5938
-3 5244 5938 5243
-3 5938 5946 5940
-3 5938 5244 5946
-3 5947 5946 5244
-3 5948 5235 5942
-3 5949 5943 5241
-3 5945 5950 5240
-3 5244 5951 5947
-3 5952 5951 5244
-3 5235 5953 4635
-3 5235 5948 5953
-3 5241 5954 5955
-3 5241 5955 5949
-3 5956 5240 5950
-3 5952 5244 5957
-3 4635 5958 5959
-3 4635 5959 3496
-3 5953 5958 4635
-3 5241 4642 5960
-3 5960 5954 5241
-3 5961 5240 5956
-3 5961 5962 5240
-3 5244 5963 5957
-3 5964 5963 5244
-3 5965 3496 5959
-3 4642 5966 5967
-3 4642 5967 5960
-3 5240 5962 4629
-3 5962 5968 4629
-3 5964 4051 5969
-3 5965 5970 3496
-3 5971 5966 4642
-3 5972 4629 5968
-3 5973 5974 5975
-3 5975 5976 5973
-3 4051 5977 5969
-3 5978 5977 4051
-3 5979 3496 5970
-3 5980 5971 4642
-3 5972 5981 4629
-3 5982 5974 5973
-3 5983 5974 5982
-3 5984 5973 5976
-3 5982 5973 5984
-3 5985 5978 4051
-3 5979 5986 3496
-3 4642 5987 5988
-3 4642 5988 5980
-3 4629 5981 5989
-3 5982 5990 5983
-3 5984 5990 5982
-3 5991 5985 4051
-3 5991 4051 5992
-3 5986 5993 3496
-3 5994 5987 4642
-3 4629 6000 6015
-3 5995 4629 5989
-3 6000 4629 5995
-3 5992 4051 5996
-3 3496 5997 5998
-3 5997 3496 5993
-3 5999 5994 4642
-3 6001 5996 4051
-3 5998 6002 3496
-3 6003 5999 4642
-3 6009 6003 4642
-3 6000 6004 6015
-3 6005 6001 4051
-3 6005 4051 6006
-3 6002 6007 3496
-3 6009 4642 6008
-3 6004 6010 6015
-3 6006 4051 6011
-3 3496 6012 6013
-3 6012 3496 6007
-3 4642 6014 6008
-3 6016 6011 4051
-3 6013 6017 3496
-3 6018 6014 4642
-3 6015 6019 4643
-3 5248 5247 6027
-3 5248 6027 6028
-3 6020 6016 4051
-3 6020 4051 6021
-3 6017 6022 3496
-3 6023 6018 4642
-3 6019 6024 4643
-3 5251 6025 6026
-3 5250 6025 5251
-3 6027 5247 5251
-3 6027 5251 6026
-3 6029 6021 4051
-3 3496 6022 6030
-3 6031 6023 4642
-3 6024 6032 4643
-3 6025 5250 6033
-3 5252 6028 6034
-3 6035 6029 4051
-3 3496 6036 6037
-3 6030 6036 3496
-3 4642 6052 6053
-3 6038 6031 4642
-3 6053 6038 4642
-3 6032 6039 4643
-3 5250 5253 6033
-3 6033 5253 6040
-3 6041 5252 6034
-3 6042 6035 4051
-3 6042 4051 6043
-3 6037 6044 3496
-3 6045 6038 6053
-3 4643 6039 6046
-3 5253 6047 6048
-3 6048 6040 5253
-3 6041 6049 5252
-3 6050 6043 4051
-3 4702 3496 6051
-3 3496 6044 6051
-3 6054 6045 6053
-3 6055 4643 6046
-3 6062 4643 6055
-3 5253 6056 6047
-3 6049 6057 4656
-3 5252 6049 4656
-3 4051 6058 6050
-3 4702 6059 6060
-3 6051 6059 4702
-3 6053 6052 5256
-3 6061 6054 6053
-3 6065 6056 5253
-3 6064 6065 5253
-3 4656 6067 6066
-3 4656 6057 6067
-3 6058 4051 6068
-3 6060 6069 4702
-3 6070 6061 6053
-3 6062 6063 4643
-3 6063 6071 4643
-3 6064 5257 5259
-3 6064 5259 6065
-3 6065 5259 6072
-3 6066 6073 5258
-3 6068 4051 6074
-3 4702 6075 6087
-3 4702 6069 6075
-3 6070 6053 6076
-3 4050 4643 6077
-3 6077 4643 6071
-3 5259 6078 6079
-3 6079 6072 5259
-3 6073 6093 5258
-3 6080 6094 6073
-3 6094 6093 6073
-3 6080 6081 6094
-3 6082 6083 6084
-3 6084 6085 6082
-3 5260 6086 4051
-3 6086 6074 4051
-3 6087 6088 4702
-3 6089 5265 6090
-3 6089 6076 5265
-3 6076 6053 5265
-3 6077 6091 4050
-3 5264 6092 5259
-3 5259 6092 6078
-3 5258 6093 5262
-3 6095 6094 6081
-3 6096 6097 6098
-3 6096 6083 6099
-3 6098 6083 6096
-3 6100 6082 6101
-3 6100 6099 6082
-3 6083 6082 6099
-3 6085 6101 6082
-3 5260 6102 6086
-3 6088 6103 4702
-3 6090 5265 6104
-3 6091 6105 4050
-3 6092 5264 6106
-3 5263 6107 6122
-3 5262 6107 5263
-3 5262 6093 6107
-3 6094 6107 6093
-3 6108 6107 6094
-3 6095 6108 6094
-3 6109 6097 6096
-3 6110 6097 6109
-3 6099 6111 6096
-3 6111 6109 6096
-3 6112 6099 6100
-3 6111 6099 6112
-3 6102 5260 6113
-3 4702 6103 6114
-3 6104 5265 6115
-3 4050 6116 6117
-3 6116 4050 6105
-3 6118 6106 5264
-3 6119 6106 6118
-3 5264 6120 6118
-3 5264 5263 6120
-3 6120 6121 6118
-3 6122 6120 5263
-3 6123 6124 6125
-3 6110 6123 6125
-3 6110 6109 6123
-3 6109 6126 6123
-3 6127 6111 6128
-3 6127 6126 6111
-3 6126 6109 6111
-3 6112 6128 6111
-3 6129 6113 5260
-3 6114 6130 4702
-3 5265 5267 6115
-3 5267 6131 6115
-3 4050 6117 6143
-3 6117 6132 6143
-3 6133 6119 6118
-3 6134 6119 6133
-3 6135 6118 6121
-3 6133 6118 6135
-3 6136 6124 6123
-3 6137 6124 6136
-3 6138 6126 6139
-3 6138 6136 6126
-3 6136 6123 6126
-3 6127 6139 6126
-3 5260 6140 6129
-3 6130 6141 4702
-3 6131 5267 6142
-3 6133 6144 6134
-3 6135 6144 6133
-3 6136 6145 6137
-3 6138 6145 6136
-3 6140 5260 6146
-3 6141 6147 4702
-3 6148 5267 6149
-3 6148 6142 5267
-3 6143 6154 5268
-3 6143 6150 6154
-3 6146 5260 6151
-3 6147 6152 4702
-3 5267 6153 6149
-3 6154 6155 5268
-3 6151 5260 6156
-3 6152 6157 4702
-3 5267 6159 6158
-3 5267 6158 6153
-3 6155 6160 5268
-3 6161 6162 6163
-3 6161 6164 6165
-3 6163 6164 6161
-3 6165 6166 6167
-3 6164 6166 6165
-3 6167 6168 6169
-3 6166 6168 6167
-3 6168 6170 6169
-3 6171 6156 5260
-3 6157 6172 4702
-3 5267 6173 6159
-3 6174 5270 5268
-3 6174 5268 6160
-3 5271 6175 6176
-3 5272 6175 5271
-3 5273 6177 6178
-3 5273 5271 6177
-3 5271 6176 6177
-3 6177 6179 6178
-3 6178 6180 6181
-3 6179 6180 6178
-3 6182 6161 6183
-3 6182 6181 6161
-3 6162 6161 6180
-3 6180 6161 6181
-3 6165 6183 6161
-3 6184 6183 6165
-3 6167 6184 6165
-3 6185 6184 6167
-3 6169 6185 6167
-3 6186 6185 6169
-3 6170 6186 6169
-3 5260 6187 6171
-3 6172 6188 4702
-3 6189 6173 5267
-3 6189 5267 6190
-3 5284 6191 6192
-3 6191 5284 6193
-3 6194 6174 6195
-3 5276 6174 6194
-3 5276 5270 6174
-3 5273 6197 5278
-3 5276 6194 5272
-3 5272 6194 6196
-3 5272 6196 6175
-3 5273 6198 6197
-3 5273 6178 6198
-3 6198 6208 6199
-3 6198 6178 6208
-3 6200 6181 6201
-3 6200 6208 6181
-3 6208 6178 6181
-3 6182 6201 6181
-3 6187 5260 6202
-3 6188 6203 4702
-3 5285 6190 5267
-3 5285 6204 6190
-3 6205 5284 6192
-3 6206 6193 5284
-3 6206 5284 5280
-3 6195 6206 5280
-3 6194 6195 5280
-3 6194 5280 5281
-3 6194 6207 6196
-3 6194 5281 6207
-3 6197 6207 5278
-3 5278 6207 5281
-3 6202 5260 6209
-3 6203 6210 4702
-3 5285 6212 6211
-3 5285 6211 6204
-3 5283 6213 6214
-3 6205 6213 5283
-3 5284 6205 5283
-3 6209 5260 6215
-3 6210 6216 4702
-3 5285 6217 6212
-3 5288 5283 6214
-3 6218 5288 6214
-3 6215 5260 6219
-3 6216 6220 4702
-3 5285 6221 6217
-3 6221 5285 6222
-3 6238 6223 6224
-3 6223 6238 6225
-3 6238 6226 6227
-3 6225 6238 6227
-3 6227 6226 6228
-3 5287 6229 6230
-3 6218 6229 5288
-3 6229 5287 5288
-3 5260 6231 6219
-3 6220 6232 4702
-3 5285 6233 6222
-3 6233 5285 6234
-3 6235 6236 6237
-3 6235 6238 6239
-3 6236 6235 6239
-3 6224 6239 6238
-3 6240 6228 6226
-3 6242 6241 6230
-3 6242 5291 6241
-3 6242 6243 5291
-3 5260 6244 6231
-3 6232 6245 4702
-3 6246 6247 6248
-3 6248 6249 6246
-3 5285 6251 6234
-3 6251 5285 6252
-3 6253 6235 6237
-3 6254 6253 6237
-3 6238 6235 6268
-3 6268 6235 6253
-3 6255 6238 6268
-3 6226 6238 6256
-3 6256 6238 6255
-3 6257 6240 6226
-3 6256 6257 6226
-3 5291 5290 6241
-3 5291 6243 6258
-3 6244 5260 6259
-3 6245 6260 4702
-3 6261 6247 6246
-3 6249 6262 6246
-3 6262 6261 6246
-3 6263 6249 6250
-3 6262 6249 6263
-3 5285 6264 6252
-3 6253 6266 6267
-3 6254 6266 6253
-3 6255 6268 6269
-3 6256 6255 6270
-3 6270 6255 6269
-3 6271 6257 6256
-3 6271 6256 6272
-3 6272 6256 6270
-3 6273 5291 6258
-3 6273 6274 5291
-3 6259 5260 6275
-3 6260 6276 4702
-3 6277 6278 6279
-3 6277 6261 6278
-3 6261 6262 6278
-3 6280 6262 6263
-3 6278 6262 6280
-3 5285 5299 6264
-3 5299 6281 6265
-3 5299 6265 6264
-3 6283 6284 6285
-3 6267 6284 6283
-3 6267 6283 6253
-3 6253 6283 6286
-3 6287 6253 6286
-3 6268 6253 6287
-3 6288 6268 6287
-3 6269 6268 6288
-3 6270 6269 6288
-3 6272 6270 6289
-3 6289 6270 6288
-3 6290 6272 6291
-3 6291 6272 6289
-3 6290 6291 6292
-3 6274 6294 5305
-3 6275 5260 6295
-3 6276 6296 4702
-3 6278 6297 6279
-3 6297 6278 6316
-3 6298 6316 6280
-3 6280 6316 6278
-3 6298 6299 6316
-3 5299 6300 6282
-3 5299 6282 6281
-3 6300 5299 6301
-3 6303 6283 6285
-3 6304 6303 6285
-3 6286 6283 6305
-3 6305 6283 6303
-3 6287 6286 6306
-3 6306 6286 6305
-3 5300 6287 6306
-3 6288 6287 5300
-3 5307 6288 5300
-3 5307 6307 6288
-3 6307 6289 6288
-3 5301 6291 6307
-3 6291 6289 6307
-3 5301 6308 6291
-3 6308 6292 6291
-3 6309 6293 6292
-3 6309 6292 6310
-3 6310 6292 6308
-3 5305 6311 6312
-3 6311 5305 6294
-3 6295 5260 6313
-3 6296 6314 4702
-3 6297 6316 6315
-3 6317 6316 6299
-3 5322 6301 5299
-3 6319 6302 6301
-3 6319 6301 5322
-3 6319 5322 6320
-3 6304 6324 6303
-3 6303 6324 5324
-3 6305 6303 5324
-3 6306 6305 5324
-3 5300 6306 5324
-3 6307 5307 6325
-3 5301 6307 6326
-3 6307 6325 6326
-3 5301 6326 6308
-3 6310 6308 6327
-3 6327 6308 6326
-3 6327 6328 6310
-3 6329 6348 5309
-3 6329 5309 6330
-3 6330 5309 5310
-3 5310 6331 6330
-3 6312 5310 5305
-3 6331 5310 6312
-3 6313 5260 6332
-3 6314 6333 4702
-3 6334 6315 5313
-3 5312 5313 6316
-3 6316 5313 6315
-3 5312 6316 6317
-3 6335 6317 6318
-3 6335 5312 6317
-3 6335 6336 5312
-3 6337 6320 5322
-3 6337 5322 6338
-3 6339 6340 6341
-3 6340 6339 6342
-3 6342 6362 6343
-3 6322 6343 6362
-3 6322 6362 6321
-3 6321 6362 5324
-3 6323 6321 5324
-3 6324 6323 5324
-3 5307 5315 6325
-3 6326 6325 5315
-3 6327 6326 4684
-3 6327 4684 6328
-3 6328 4684 6344
-3 5308 6345 6346
-3 5309 6347 5308
-3 5308 6347 6345
-3 6348 6347 5309
-3 6332 5260 6349
-3 6333 6350 4702
-3 5313 6351 6334
-3 6353 6352 6351
-3 5312 6353 6351
-3 5312 6351 5313
-3 5312 6354 6353
-3 6355 6354 5312
-3 6336 6355 5312
-3 5322 6356 6338
-3 6356 5322 6357
-3 6358 6359 6360
-3 6341 6359 6358
-3 6341 6358 6339
-3 6339 6358 6361
-3 6342 6339 6362
-3 6362 6339 6361
-3 5324 6362 6378
-3 6363 6344 4684
-3 6364 5308 6365
-3 6365 5308 6346
-3 6349 5260 6366
-3 6350 6367 4702
-3 6353 6368 6352
-3 6369 6370 6357
-3 6369 6357 5322
-3 6370 6369 6371
-3 6373 6374 6375
-3 6374 6373 6376
-3 6376 6378 6377
-3 6360 6377 6378
-3 6360 6378 6358
-3 6361 6358 6378
-3 6362 6361 6378
-3 6363 4684 6379
-3 6380 5308 6381
-3 6381 5308 6364
-3 6366 5260 6382
-3 6367 6383 4702
-3 6384 6372 6371
-3 6384 6371 6369
-3 6384 6369 6385
-3 6388 6386 6387
-3 6375 6386 6388
-3 6375 6388 6373
-3 6376 6373 6388
-3 6378 6376 5346
-3 5346 6376 6388
-3 6379 4684 6389
-3 6381 6391 6380
-3 6391 6390 6380
-3 6391 6381 6392
-3 5343 6393 6394
-3 5333 5343 6395
-3 5343 6394 6395
-3 6395 5334 5333
-3 6396 5334 6395
-3 6397 6382 5260
-3 6383 6398 4702
-3 6399 6385 6369
-3 6399 6369 6400
-3 6400 6402 6401
-3 6403 6404 6405
-3 6387 6406 6388
-3 6407 6389 4684
-3 6390 6408 4698
-3 6380 6390 4698
-3 6391 6409 6390
-3 6409 6408 6390
-3 6410 6391 6392
-3 6410 6411 6391
-3 6411 6409 6391
-3 6411 6412 6413
-3 6410 6412 6411
-3 6412 6414 6413
-3 6416 6417 6415
-3 6419 6420 6421
-3 6419 6421 6393
-3 6419 6393 5343
-3 6422 5344 6396
-3 5344 5334 6396
-3 1262 6397 5260
-3 6424 6397 1262
-3 6398 6425 4702
-3 6369 6428 6400
-3 6402 6400 6428
-3 6426 6402 6428
-3 6426 6428 6427
-3 6432 6465 6433
-3 6433 6465 6434
-3 6465 6404 6435
-3 6434 6465 6435
-3 6388 6406 6405
-3 5346 6388 6405
-3 4684 6436 6407
-3 6436 4684 6437
-3 6438 6472 2279
-3 6438 2279 6439
-3 6439 2279 5337
-3 6440 6441 6439
-3 6440 6439 5337
-3 5347 5348 6442
-3 5349 6443 5348
-3 5348 6443 6442
-3 6443 5349 5350
-3 6444 6443 5350
-3 4698 6408 5351
-3 6409 6445 6408
-3 6411 6445 6409
-3 6446 6413 6447
-3 6446 6445 6413
-3 6445 6411 6413
-3 6414 6447 6413
-3 6415 6448 6449
-3 6415 5352 6448
-3 6417 6418 6450
-3 6417 6450 5357
-3 6451 5357 6450
-3 6452 6453 6454
-3 6452 6420 6455
-3 6454 6420 6452
-3 6420 6419 6455
-3 6419 6456 6455
-3 5343 6456 6419
-3 5343 6457 6456
-3 6457 6458 6456
-3 6423 5344 6422
-3 6423 6457 5344
-3 6457 5343 5344
-3 6459 6424 1262
-3 6425 6460 4702
-3 6461 6428 5359
-3 5359 6428 5354
-3 6461 5359 6462
-3 6462 5359 6463
-3 6463 5359 6464
-3 5359 6465 6466
-3 6464 5359 6466
-3 6466 6465 6467
-3 6467 6465 6468
-3 6430 6468 6465
-3 6430 6465 6429
-3 6431 6429 6465
-3 6432 6431 6465
-3 6404 6465 6405
-3 6495 6469 4684
-3 6469 6437 4684
-3 2279 6471 6470
-3 6472 6471 2279
-3 6473 6441 6440
-3 5356 6474 6475
-3 6442 5356 5347
-3 6474 5356 6442
-3 5350 6501 6444
-3 6444 6501 6476
-3 6477 6445 6478
-3 6477 6408 6445
-3 6479 6478 6445
-3 6446 6479 6445
-3 6480 6448 5352
-3 6480 5352 6481
-3 6482 5357 6483
-3 6483 5357 6451
-3 5357 6484 5358
-3 6482 6484 5357
-3 6484 6485 5358
-3 6486 6487 6488
-3 6453 6486 6488
-3 6453 6452 6486
-3 6452 6489 6486
-3 6455 6490 6452
-3 6490 6489 6452
-3 6491 6456 6492
-3 6491 6490 6456
-3 6490 6455 6456
-3 6458 6492 6456
-3 6493 6459 1262
-3 6460 6494 4702
-3 6541 6496 6495
-3 4684 6541 6495
-3 4684 5361 6541
-3 2279 6497 6498
-3 6497 2279 6470
-3 6499 6473 6440
-3 4750 5356 6500
-3 6500 5356 6475
-3 6501 6502 6476
-3 4771 5351 6503
-3 6503 5351 6408
-3 6503 6408 6477
-3 5352 5374 6481
-3 6481 5374 6504
-3 6482 6483 6505
-3 6505 6506 6507
-3 6505 6507 6482
-3 6482 6507 6484
-3 6485 6507 4739
-3 6485 6484 6507
-3 6508 6509 6510
-3 6487 6508 6510
-3 6487 6486 6508
-3 6486 6511 6508
-3 6489 6512 6486
-3 6512 6511 6486
-3 6513 6490 6514
-3 6513 6512 6490
-3 6512 6489 6490
-3 6491 6514 6490
-3 6515 6493 1262
-3 6494 6516 4702
-3 6539 6496 6541
-3 6517 6496 6539
-3 6518 2279 6519
-3 2279 6520 6519
-3 6520 2279 6498
-3 6440 6521 6499
-3 5363 5360 6523
-3 6522 5363 6523
-3 4750 6500 6524
-3 6557 6524 6525
-3 4750 6524 6557
-3 4750 6557 6526
-3 4750 6526 6527
-3 4750 6527 6501
-3 6502 6501 6527
-3 6503 6528 4771
-3 5374 6529 6530
-3 6530 6504 5374
-3 4739 6507 6506
-3 4739 6506 6531
-3 6532 6509 6508
-3 6533 6509 6532
-3 6511 6534 6508
-3 6534 6532 6508
-3 6535 6512 6536
-3 6535 6534 6512
-3 6534 6511 6512
-3 6513 6536 6512
-3 6537 6515 1262
-3 1262 6595 6537
-3 4702 6516 4845
-3 6516 6538 4845
-3 6540 6539 6541
-3 6542 6541 5361
-3 6542 5361 6543
-3 6544 5362 6545
-3 5362 6546 6545
-3 5362 6547 6546
-3 6547 2279 6548
-3 6548 2279 6549
-3 6549 2279 6550
-3 2279 6551 6550
-3 6518 6551 2279
-3 6553 6521 5379
-3 5379 6521 6440
-3 5364 5363 6522
-3 5364 6522 6554
-3 6523 6555 6522
-3 6555 6554 6522
-3 5360 6556 6523
-3 6556 6555 6523
-3 5360 5365 6556
-3 6528 6558 4771
-3 5374 6559 6560
-3 6560 6529 5374
-3 6561 5375 6562
-3 6562 5375 4739
-3 6562 4739 6531
-3 6532 6563 6533
-3 6534 6563 6532
-3 6564 6563 6534
-3 6535 6564 6534
-3 6538 6566 4845
-3 4776 6568 5368
-3 6567 6568 4776
-3 6568 6569 5368
-3 5368 6569 6570
-3 6598 5368 6571
-3 5368 6570 6571
-3 6598 6571 6572
-3 6572 6573 6598
-3 5361 6575 6543
-3 3635 6576 5361
-3 5361 6576 6575
-3 5362 6577 3635
-3 6577 6576 3635
-3 6544 6577 5362
-3 5362 2279 6547
-3 5379 6552 6553
-3 5379 6578 6552
-3 5364 6554 6603
-3 6555 6579 6554
-3 6579 6603 6554
-3 6556 6580 6555
-3 6580 6579 6555
-3 5365 5370 6580
-3 6556 5365 6580
-3 5373 6581 6582
-3 6581 5373 6583
-3 6558 5373 4771
-3 6583 5373 6558
-3 5374 6584 6585
-3 6585 6559 5374
-3 5375 6586 6615
-3 6587 5375 6561
-3 6586 5375 6587
-3 6623 6588 5366
-3 6588 6589 5366
-3 6590 6591 5366
-3 6590 5366 6589
-3 6591 6592 6593
-3 6591 6593 5366
-3 5366 6594 5376
-3 5366 6593 6594
-3 5376 6594 5378
-3 6595 6565 6537
-3 6566 6596 4845
-3 4790 6597 6567
-3 6597 6568 6567
-3 6599 6573 6574
-3 6599 6598 6573
-3 6599 6600 6598
-3 5379 6601 6602
-3 5379 6602 6578
-3 6603 6579 6604
-3 6604 6580 6605
-3 6604 6579 6580
-3 5383 5373 6606
-3 6607 6606 5373
-3 5373 6582 6608
-3 6607 5373 6609
-3 6609 5373 6610
-3 6610 5373 6608
-3 6609 6611 5392
-3 6610 6611 6609
-3 6611 6612 5392
-3 5392 5374 5384
-3 5392 6612 5374
-3 6612 6613 5374
-3 6613 6584 5374
-3 6586 6614 6615
-3 6616 6614 6586
-3 6587 6616 6586
-3 6618 6619 5385
-3 5385 6619 6620
-3 6623 5385 6621
-3 6621 5385 6620
-3 6621 6622 6623
-3 6625 6626 6588
-3 6625 6588 6624
-3 6624 6588 6623
-3 6626 6627 6628
-3 6626 6628 6588
-3 6588 6628 6589
-3 6629 6590 6589
-3 6629 6589 6630
-3 6630 6589 6628
-3 6592 6629 6630
-3 6593 6592 6630
-3 6593 6630 5395
-3 5378 6593 5395
-3 6594 6593 5378
-3 6631 6595 1262
-3 6596 6632 4845
-3 6597 4790 6633
-3 4790 6660 6633
-3 6660 6634 6633
-3 6660 6598 6635
-3 6598 6636 6635
-3 6637 6636 6598
-3 6600 6637 6598
-3 5379 6638 6601
-3 6638 5379 6639
-3 6603 6640 6680
-3 6641 6605 6580
-3 6580 5370 6641
-3 5391 6642 6643
-3 5383 6644 5391
-3 5391 6644 6642
-3 6645 6644 5383
-3 6606 6645 5383
-3 6646 6645 6606
-3 6647 6646 6606
-3 6647 6648 6649
-3 6647 6606 6648
-3 6606 6607 6648
-3 6609 6648 6607
-3 5385 6651 6652
-3 6652 6653 5385
-3 6617 6618 5385
-3 6617 5385 6653
-3 6654 6623 6622
-3 6624 6623 6655
-3 6655 6623 6654
-3 6656 6625 6624
-3 6656 6624 6657
-3 6657 6624 6655
-3 6627 6656 6657
-3 6628 6627 6657
-3 6628 6657 5396
-3 6628 5396 5395
-3 6630 6628 5395
-3 1262 6658 6631
-3 6659 4845 6632
-3 6661 6660 6635
-3 6662 6661 6635
-3 6663 6664 6665
-3 6665 6666 6663
-3 5397 6667 6668
-3 5397 6668 6669
-3 6669 6670 5397
-3 6670 6671 5411
-3 6671 6672 5411
-3 5399 5411 6673
-3 5411 6672 6673
-3 6674 5399 6673
-3 6675 6639 5379
-3 5417 5400 6700
-3 6678 6700 5400
-3 6679 6680 6640
-3 6641 6680 6679
-3 6641 5430 6680
-3 6641 5370 5430
-3 4814 6681 6682
-3 4814 6643 6681
-3 4814 5391 6643
-3 6683 6649 6648
-3 6609 5403 6648
-3 6615 6650 5407
-3 5407 6650 6684
-3 6685 6686 5385
-3 6651 5385 6686
-3 5408 6654 6687
-3 6655 6654 5408
-3 5396 6655 5408
-3 6657 6655 5396
-3 6659 6689 4845
-3 6663 6690 6664
-3 6666 6690 6663
-3 5409 6691 6667
-3 6692 5397 6670
-3 5411 5412 6692
-3 5411 6692 6670
-3 5399 6674 5414
-3 6674 6693 5414
-3 6694 6675 5379
-3 6724 6723 6676
-3 6695 6724 6676
-3 6728 6727 6695
-3 6677 6729 6695
-3 6729 6728 6695
-3 6677 5415 6729
-3 5417 6696 6697
-3 5417 6698 6696
-3 6699 6698 5417
-3 6700 6699 5417
-3 5400 6701 6678
-3 5400 6702 6701
-3 5420 4814 6682
-3 6703 5420 6682
-3 6648 6704 6683
-3 5403 6705 6704
-3 5403 6704 6648
-3 5407 6684 6706
-3 5407 6706 5427
-3 6707 5427 6706
-3 5385 6707 6708
-3 5385 6708 6709
-3 6685 5385 6709
-3 5408 6710 6711
-3 6710 5408 6687
-3 6688 6658 6712
-3 6689 6713 4845
-3 6714 5409 6715
-3 6714 6691 5409
-3 6692 6716 5428
-3 5412 6716 6692
-3 5412 6717 6716
-3 5412 5411 6717
-3 6745 6717 5411
-3 6718 6745 5411
-3 6718 5411 6719
-3 6719 5411 5414
-3 6719 5414 6693
-3 5379 6720 6694
-3 6676 6722 6721
-3 6723 6722 6676
-3 6725 6724 6695
-3 6726 6725 6695
-3 6727 6726 6695
-3 6729 5415 6730
-3 5415 5429 6730
-3 6731 5429 6732
-3 6732 5429 5417
-3 6732 5417 6697
-3 5400 6733 6702
-3 5400 6734 6733
-3 6735 5420 6703
-3 5403 6736 6705
-3 5403 5431 6736
-3 5431 6737 6736
-3 5431 6738 6737
-3 5408 6711 6739
-3 6712 6658 6740
-3 6713 6741 4845
-3 6715 5409 6742
-3 5409 4199 6742
-3 5428 6743 4199
-3 4199 6743 6742
-3 6716 6744 5428
-3 6744 6743 5428
-3 6717 6744 6716
-3 5444 6746 6720
-3 6676 6747 4828
-3 6747 6676 6721
-3 6766 6749 6748
-3 5429 6766 6748
-3 5429 6748 6730
-3 6766 5429 6767
-3 6750 5429 6731
-3 6767 5429 6750
-3 5400 6751 6734
-3 5435 6752 6751
-3 5435 6751 5400
-3 6753 5420 6735
-3 6753 6754 5420
-3 5431 6755 6738
-3 6771 6756 6755
-3 5431 6771 6755
-3 6771 5431 6757
-3 6758 6774 5432
-3 5439 6758 5432
-3 6782 6739 6759
-3 6740 6658 6760
-3 6741 6761 4845
-3 6763 6746 5444
-3 4828 6765 6764
-3 4828 6747 6765
-3 5435 6768 6752
-3 6768 5435 6769
-3 5420 6754 5438
-3 6754 6770 5438
-3 6772 6771 6757
-3 5432 6772 6757
-3 6773 6772 5432
-3 6774 6773 5432
-3 5439 6775 6758
-3 6775 5439 6776
-3 5443 6777 6778
-3 5443 6779 6777
-3 6780 6779 5440
-3 6759 6781 6782
-3 6783 6760 4422
-3 4422 6760 6658
-3 6761 6784 4845
-3 5444 6785 6786
-3 6762 5444 6786
-3 6763 5444 6762
-3 5434 4828 6787
-3 6788 4828 6764
-3 6787 4828 6788
-3 6789 6791 5446
-3 6790 6791 6789
-3 5446 6792 5441
-3 6791 6792 5446
-3 6792 6793 5441
-3 4206 5441 6794
-3 5441 6793 6794
-3 4206 6794 6795
-3 6796 4206 6795
-3 5435 6797 6769
-3 5436 6797 5435
-3 6798 5436 6799
-3 6799 5436 5438
-3 6799 5438 6770
-3 6800 6776 5439
-3 6801 5443 6802
-3 6802 5443 6778
-3 5440 6803 6780
-3 5440 6804 6803
-3 6804 5440 6782
-3 4422 6805 6783
-3 6784 6806 4845
-3 6807 6808 6809
-3 6809 6810 6807
-3 5444 6811 6785
-3 6787 6827 5434
-3 6812 6787 6788
-3 6812 6813 6787
-3 6813 6827 6787
-3 6812 6814 6813
-3 5446 6815 6789
-3 6816 4206 6796
-3 5436 6817 6797
-3 6798 6817 5436
-3 5439 6818 6800
-3 6819 6818 5447
-3 5443 6801 5447
-3 5447 6801 6820
-3 6805 4422 6821
-3 6822 4845 6806
-3 6807 6823 6808
-3 6810 6823 6807
-3 5456 6824 6825
-3 6811 5444 5456
-3 6825 6811 5456
-3 6826 6846 6827
-3 6846 5434 6827
-3 6828 6827 6813
-3 6814 6828 6813
-3 6815 5451 6829
-3 6816 6830 4206
-3 5447 6831 6819
-3 6831 5447 6820
-3 5454 5453 6832
-3 6821 4422 6833
-3 6822 6834 4845
-3 6858 6835 6836
-3 6836 6837 6858
-3 6882 6838 6839
-3 6882 6839 6840
-3 6840 6841 5455
-3 5456 6842 6843
-3 5456 6843 6844
-3 6844 6824 5456
-3 5434 6846 6845
-3 5451 6847 6829
-3 6848 6847 5451
-3 6849 4846 6830
-3 6850 4846 6849
-3 5459 6832 6851
-3 5459 5454 6832
-3 6851 6832 6852
-3 5453 5458 6832
-3 6852 6832 5458
-3 5460 5459 6853
-3 5459 6851 6853
-3 5460 6853 6854
-3 6854 6855 5460
-3 6833 4422 6856
-3 6834 6857 4845
-3 6859 6835 6858
-3 6860 6858 6837
-3 6860 6861 6858
-3 6882 6862 6863
-3 6863 6838 6882
-3 6864 5455 6841
-3 6864 6865 5455
-3 5456 6866 6842
-3 5434 6868 6867
-3 5434 6845 6868
-3 5451 6869 6848
-3 6870 4846 6871
-3 6871 4846 6850
-3 6870 5462 4846
-3 6872 6852 5458
-3 5458 5471 6872
-3 5460 6855 5464
-3 6855 6873 5464
-3 5467 5466 6874
-3 5467 6874 5465
-3 6875 6856 4422
-3 6857 6876 4845
-3 6878 6879 5475
-3 6879 6880 5475
-3 6880 6859 5475
-3 6858 5475 6859
-3 6858 5476 5475
-3 6858 5469 5476
-3 5469 6858 6927
-3 6927 6858 6861
-3 6927 6861 6881
-3 6882 6883 6884
-3 6862 6882 6884
-3 6885 5455 6865
-3 6866 5456 6886
-3 5434 6887 4850
-3 5434 6888 6887
-3 6867 6888 5434
-3 6889 6890 5478
-3 5470 6891 6892
-3 5470 6890 6891
-3 5451 6893 6869
-3 6893 5451 5479
-3 6894 6893 5479
-3 6895 6870 6871
-3 6896 6895 6871
-3 6897 6870 6895
-3 5462 6870 6897
-3 5462 6898 4859
-3 5462 6897 6898
-3 5471 6900 6899
-3 5471 6899 6872
-3 5464 6901 5471
-3 6873 6901 5464
-3 5466 5465 6874
-3 4422 6902 6875
-3 6876 6903 4845
-3 5473 5472 6904
-3 5473 6904 5474
-3 5475 6877 6878
-3 5475 5474 6877
-3 5474 6905 6877
-3 5469 6927 5477
-3 6906 6927 6881
-3 6906 6907 6927
-3 6882 6908 6909
-3 6883 6882 6909
-3 4864 6910 6911
-3 6885 6910 4864
-3 6885 4864 5455
-3 5456 6912 6913
-3 6913 6886 5456
-3 6887 6914 4850
-3 6889 5478 6915
-3 6892 6949 5470
-3 6892 6916 6949
-3 5479 6917 6894
-3 6918 5479 6919
-3 6896 5479 6895
-3 6896 6919 5479
-3 5479 6920 6895
-3 6920 6897 6895
-3 5480 6898 6920
-3 6898 6897 6920
-3 4859 6898 5480
-3 5471 6921 6900
-3 6922 6921 5471
-3 6901 6922 5471
-3 6902 4422 6923
-3 6903 6924 4845
-3 5474 6925 6905
-3 5475 6925 5474
-3 6926 6925 5475
-3 5476 5477 6927
-3 6928 6927 6907
-3 6928 6929 6927
-3 6928 6930 6929
-3 4874 6931 6932
-3 6932 6933 4874
-3 6934 6935 6936
-3 6936 6937 6938
-3 6935 6937 6936
-3 6937 6939 6938
-3 6882 6940 6908
-3 6941 6940 6882
-3 6942 6941 6882
-3 6882 6943 6942
-3 4864 6944 6882
-3 6882 6944 6943
-3 6911 6944 4864
-3 6980 6945 6946
-3 6980 6946 6912
-3 6980 6912 5456
-3 6914 6947 4850
-3 6948 6915 5478
-3 5479 6950 6917
-3 6951 6950 5479
-3 6918 6951 5479
-3 6952 6953 6954
-3 6954 6955 6952
-3 4422 6956 6957
-3 4422 6957 6923
-3 6924 6958 4845
-3 6926 6959 6925
-3 6960 6959 6926
-3 5476 6960 6926
-3 6961 6960 5476
-3 6927 6961 5476
-3 6962 6961 6927
-3 6963 6962 6927
-3 6964 6963 6927
-3 6929 6964 6927
-3 6965 6964 6929
-3 6965 6966 6967
-3 6965 6929 6966
-3 6968 6966 6930
-3 6930 6966 6929
-3 6968 6969 6966
-3 6970 6971 6972
-3 6970 6973 6974
-3 6972 6973 6970
-3 6973 6975 6974
-3 5485 6976 6977
-3 6931 4874 6977
-3 6977 4874 5485
-3 6936 6933 6934
-3 6938 6978 6936
-3 6979 6938 6939
-3 6978 6938 6979
-3 4850 6947 6981
-3 5478 6982 6948
-3 6983 6982 5478
-3 6985 6986 6987
-3 6986 6988 6987
-3 6952 6989 6953
-3 6955 6989 6952
-3 4422 6990 6956
-3 6991 4845 6958
-3 6966 6992 6967
-3 6969 6992 6966
-3 6993 6971 6970
-3 6994 6971 6993
-3 6974 6995 6970
-3 6995 6993 6970
-3 6996 6974 6975
-3 6995 6974 6996
-3 5485 6997 6998
-3 5485 6998 6976
-3 6936 5496 6933
-3 5496 6936 6978
-3 6999 6978 6979
-3 5496 6978 6999
-3 7001 4850 6981
-3 7028 4850 7001
-3 7002 7003 7004
-3 7002 7005 7006
-3 7004 7005 7002
-3 7005 7007 7006
-3 7008 7009 5488
-3 6984 5488 7009
-3 6985 5488 6984
-3 6987 5488 6985
-3 5488 7010 7011
-3 5488 6988 7010
-3 5488 6987 6988
-3 6990 4422 7012
-3 6991 7013 4845
-3 5494 7014 7015
-3 7015 7016 5494
-3 7016 7017 5494
-3 7018 7017 7019
-3 7020 6993 7021
-3 7020 7018 6993
-3 6994 6993 7019
-3 7019 6993 7018
-3 6995 7021 6993
-3 7022 7021 6995
-3 6996 7022 6995
-3 7024 7025 5485
-3 7025 6997 5485
-3 7026 5496 6999
-3 7000 4877 7027
-3 7028 7029 4850
-3 7002 7030 7003
-3 7030 7002 7031
-3 7002 7006 7031
-3 7007 7032 7006
-3 7032 7031 7006
-3 5486 7032 7008
-3 7008 7032 7007
-3 5488 5486 7008
-3 5488 7011 5501
-3 5501 7011 7033
-3 7034 7035 7036
-3 7036 7037 7034
-3 7037 7038 7034
-3 7040 7012 4422
-3 7013 7041 4845
-3 5493 7042 7043
-3 5492 7042 5493
-3 7014 5494 7043
-3 7043 5494 5493
-3 5494 7017 5495
-3 5495 7017 7018
-3 7044 7018 7020
-3 5495 7018 7044
-3 5485 7045 7046
-3 7046 7047 5485
-3 7023 5485 7047
-3 7024 5485 7023
-3 7048 5496 7026
-3 4877 7049 7050
-3 7050 7027 4877
-3 4850 7029 7051
-3 7052 7031 5497
-3 7031 7032 5497
-3 7053 5501 7033
-3 7054 7056 7081
-3 7055 7056 7054
-3 7081 7057 5512
-3 7056 7057 7081
-3 7057 7058 5512
-3 7058 7059 5512
-3 7059 7060 5512
-3 7060 7061 5512
-3 5515 7062 7063
-3 5515 7063 7064
-3 5515 7064 7065
-3 5515 7065 7035
-3 7035 7034 5515
-3 7034 7038 7066
-3 7034 7066 5489
-3 7067 7066 7068
-3 7067 5489 7066
-3 5489 7067 5502
-3 7040 4422 7039
-3 4422 7069 7039
-3 7070 4845 7041
-3 7071 7072 5504
-3 7072 5492 5504
-3 7072 7042 5492
-3 5495 7073 5519
-3 7073 5495 7044
-3 5485 7074 7075
-3 7045 5485 7075
-3 5496 7048 4962
-3 4962 7048 7076
-3 7049 4877 7077
-3 7051 7078 4850
-3 7052 5497 7079
-3 7080 5501 7053
-3 7082 7054 7081
-3 5512 5510 7081
-3 5512 7061 7083
-3 5512 7083 5514
-3 5514 7083 7084
-3 5514 7084 7085
-3 5514 7114 5515
-3 7086 7114 5514
-3 7087 7088 5515
-3 7088 7062 5515
-3 7067 7068 7089
-3 7067 7089 5531
-3 7070 7093 4845
-3 5519 7094 7071
-3 5519 7071 5504
-3 7094 5519 7095
-3 5519 7096 7123
-3 5519 7097 7096
-3 5519 7073 7097
-3 7098 7100 5527
-3 7099 7100 7098
-3 5527 7100 5485
-3 7100 7074 5485
-3 4962 7101 7102
-3 7101 4962 7076
-3 7077 4877 7103
-3 7078 7104 4850
-3 5497 5535 7079
-3 7079 5535 7105
-3 7080 7106 5501
-3 5522 7107 7108
-3 4292 7107 5522
-3 5522 7108 7109
-3 5522 7109 7110
-3 7111 5522 7110
-3 5523 7082 7081
-3 7112 7082 5523
-3 7081 5510 5523
-3 5514 7085 7113
-3 7086 5514 7113
-3 7115 5515 7114
-3 7087 5515 7115
-3 7116 5531 7117
-3 7090 5531 7089
-3 7090 7117 5531
-3 4422 7091 7092
-3 4422 7118 7091
-3 7069 4422 7092
-3 7119 4845 7093
-3 7119 7120 4845
-3 7095 5519 7121
-3 5519 7122 7121
-3 7123 7122 5519
-3 7145 7124 5527
-3 7098 5527 7124
-3 7102 7125 4962
-3 4963 7129 7130
-3 7103 4877 4963
-3 7130 7103 4963
-3 4850 7131 7154
-3 4850 7104 7131
-3 7132 7105 5535
-3 5501 7106 5558
-3 7106 7133 5558
-3 7107 4292 7134
-3 5522 7111 7135
-3 5549 7135 7136
-3 5549 5522 7135
-3 5523 7137 7112
-3 7162 7138 7137
-3 5523 7162 7137
-3 5523 5536 7162
-3 7139 7171 5538
-3 7139 5538 7140
-3 7140 5538 5531
-3 5531 7141 7140
-3 7142 7141 5531
-3 7116 7142 5531
-3 7118 4422 7143
-3 7120 7144 4845
-3 7180 7145 5527
-3 7146 7124 7145
-3 4962 7147 7148
-3 7147 4962 7125
-3 7192 7149 7150
-3 7126 7192 7150
-3 7127 7192 7126
-3 7127 5533 7192
-3 5533 7151 5534
-3 5533 7128 7151
-3 5533 7127 7128
-3 7151 7152 5534
-3 7129 4963 7153
-3 7154 7155 4850
-3 5535 7156 7132
-3 7156 5535 7157
-3 7133 7158 5558
-3 7159 7134 4292
-3 5549 7136 7160
-3 5549 7160 7161
-3 5536 7163 7162
-3 7164 7163 5536
-3 7164 5536 4914
-3 7167 7169 7168
-3 7169 5538 7170
-3 7171 7170 5538
-3 5539 7172 7173
-3 7173 7174 5539
-3 5540 5539 7175
-3 5539 7174 7175
-3 7176 5540 7175
-3 4422 7177 7143
-3 7144 7178 4845
-3 5543 7179 7180
-3 7145 7180 7181
-3 7182 7146 7145
-3 7182 7145 7183
-3 7183 7145 7181
-3 7182 7183 7184
-3 7186 5555 4939
-3 7186 4939 7187
-3 7188 7187 4939
-3 7148 7189 4962
-3 7192 7190 7191
-3 7149 7192 7191
-3 5534 7193 5546
-3 5534 7152 7193
-3 5546 7193 5547
-3 7153 4963 7194
-3 4850 7195 7237
-3 4850 7155 7195
-3 5535 7196 7157
-3 7197 7196 5535
-3 7198 5558 7158
-3 7200 7159 4292
-3 7200 4292 7201
-3 5549 7202 7203
-3 5549 7161 7202
-3 7204 7205 5549
-3 7206 5549 7205
-3 7208 7207 7164
-3 4914 7208 7164
-3 7209 7208 4914
-3 4914 5559 7209
-3 5559 7210 7209
-3 7211 7165 7166
-3 7212 7211 7166
-3 7167 7165 7211
-3 7169 7167 7211
-3 7213 7214 7215
-3 7172 7213 7215
-3 7172 5539 7213
-3 5539 7216 7213
-3 5539 5551 7217
-3 5539 7217 7216
-3 7218 7217 5551
-3 7218 5551 5540
-3 7218 5540 7176
-3 7177 4422 7219
-3 7178 7220 4845
-3 7179 5542 7221
-3 5543 5542 7179
-3 7180 7179 7222
-3 7222 7179 7221
-3 7181 7180 7223
-3 7223 7180 7222
-3 5552 7181 7223
-3 7183 7181 5552
-3 5563 7183 5552
-3 7184 7183 5563
-3 5563 7224 7185
-3 5563 7185 7184
-3 5563 7226 7225
-3 7224 5563 7225
-3 5555 7227 7228
-3 7186 7227 5555
-3 7229 7188 4941
-3 7188 4939 4941
-3 7229 4941 7230
-3 7189 7231 4962
-3 7192 7232 7190
-3 7233 7232 7192
-3 7192 5545 7233
-3 5545 7234 7233
-3 5556 7235 5545
-3 5545 7235 7234
-3 7193 7235 5556
-3 5547 7193 5556
-3 7194 4963 7236
-3 7239 7197 4945
-3 7239 4945 7240
-3 7241 7198 7199
-3 7242 7241 7199
-3 7198 7241 5558
-3 4292 7243 7201
-3 5549 7203 7244
-3 7204 5549 7244
-3 5549 7206 7245
-3 7246 5549 7245
-3 5559 7247 7210
-3 5560 7248 7249
-3 5560 7249 5559
-3 5559 7249 7247
-3 7212 7249 7248
-3 7211 7212 7248
-3 7250 7251 7252
-3 7214 7250 7252
-3 7214 7213 7250
-3 7213 7253 7250
-3 7254 7253 7216
-3 7253 7213 7216
-3 7217 7254 7216
-3 7255 7254 7217
-3 7218 7255 7217
-3 4422 7256 7219
-3 7220 7257 5643
-3 5542 5562 7258
-3 5542 7258 7221
-3 7258 7259 7221
-3 7223 7259 5569
-3 7223 7222 7259
-3 7222 7221 7259
-3 7260 7226 4960
-3 4960 7226 5563
-3 7260 4960 7261
-3 7228 4960 5555
-3 7261 4960 7228
-3 4941 5570 7262
-3 7262 7230 4941
-3 7231 7263 4962
-3 7236 4963 7264
-3 7237 7238 4373
-3 7238 7265 4373
-3 7266 7240 4945
-3 7241 7242 7267
-3 7267 5558 7241
-3 7267 7268 5558
-3 4292 5576 7243
-3 7243 5576 7269
-3 4346 7270 7271
-3 4346 7246 7270
-3 4346 5549 7246
-3 7250 7272 7251
-3 7253 7272 7250
-3 7273 7272 7253
-3 7254 7273 7253
-3 7256 4422 7274
-3 5643 7257 7275
-3 7276 5643 7275
-3 7258 7277 7278
-3 7258 5562 7277
-3 5562 5568 7277
-3 5569 7258 7279
-3 5569 7259 7258
-3 7258 7278 7279
-3 5570 4961 7280
-3 5570 7280 7281
-3 5570 7281 7262
-3 4962 7263 7282
-3 7283 4962 7282
-3 7264 4963 7284
-3 4373 7285 7286
-3 7285 4373 7265
-3 7287 7266 4945
-3 7316 7287 4945
-3 7268 7288 5558
-3 7289 7269 5576
-3 4346 7271 7290
-3 7290 5566 4346
-3 7290 7291 5566
-3 7291 5571 5566
-3 4422 7292 7274
-3 7276 7293 5643
-3 7295 7297 7298
-3 7296 7297 7295
-3 7297 7299 7298
-3 5568 7300 7301
-3 5587 7300 5568
-3 7301 7277 5568
-3 5569 7279 7302
-3 4961 7303 7304
-3 7280 4961 7304
-3 4962 7283 7305
-3 7306 4962 7305
-3 7284 4963 7307
-3 7286 7308 4373
-3 7309 7310 7311
-3 7309 7312 7313
-3 7311 7312 7309
-3 7312 7314 7313
-3 7316 4945 7315
-3 5580 5558 7317
-3 7317 5558 7288
-3 5576 7319 7318
-3 5576 7318 7289
-3 7320 5581 7322
-3 7322 5581 7323
-3 7361 5571 7324
-3 5571 7291 7324
-3 7325 7326 7327
-3 7327 7328 7325
-3 7330 7331 7332
-3 7331 7333 7332
-3 4422 7334 7335
-3 7335 7292 4422
-3 7293 7336 5643
-3 5585 7337 7338
-3 7294 5585 7338
-3 7294 7295 5585
-3 7295 7339 5585
-3 7340 7298 7341
-3 7340 7339 7298
-3 7339 7295 7298
-3 7299 7341 7298
-3 5587 7342 7300
-3 7302 7343 7377
-3 4961 7344 7303
-3 7345 4962 7346
-3 7346 4962 7306
-3 7307 4963 7347
-3 7308 7348 4373
-3 7309 7349 7310
-3 7313 7349 7309
-3 7350 7349 7313
-3 7314 7350 7313
-3 7464 7351 7352
-3 7315 4945 7464
-3 7352 7315 7464
-3 5580 7317 7353
-3 5576 7355 7319
-3 5576 7356 7355
-3 5576 7357 7356
-3 7321 5581 7320
-3 7321 7357 5581
-3 7357 5576 5581
-3 5581 7358 7323
-3 5581 7359 7358
-3 7361 7360 5581
-3 7362 7326 7325
-3 7363 7326 7362
-3 7364 7325 7328
-3 7364 7365 7325
-3 7365 7362 7325
-3 7364 7366 7365
-3 7367 7329 7330
-3 7368 7329 7367
-3 7369 7367 7332
-3 7367 7330 7332
-3 7333 7369 7332
-3 7334 4422 7370
-3 7371 5643 7336
-3 5585 5584 7337
-3 5584 7372 7337
-3 5583 5585 7373
-3 7373 5585 7339
-3 7374 7339 7375
-3 7374 7373 7339
-3 7340 7375 7339
-3 7342 5587 7376
-3 7377 7378 7302
-3 7302 7378 5588
-3 7379 7380 4977
-3 7380 7344 4977
-3 5589 7381 7382
-3 5589 7383 7381
-3 5589 7384 7385
-3 5589 7385 7383
-3 7346 7385 7384
-3 7346 7384 7345
-3 7345 7384 7386
-3 7345 7386 5596
-3 7347 4963 7387
-3 7348 7388 4373
-3 7464 7389 7390
-3 7390 7351 7464
-3 5590 7353 7354
-3 5590 7354 7391
-3 5580 7353 5590
-3 5581 7392 7359
-3 7360 7392 5581
-3 7362 7393 7363
-3 7393 5593 7394
-3 7393 7362 5593
-3 7362 7365 5593
-3 5593 7365 7366
-3 5593 7366 7395
-3 5593 7396 5607
-3 5593 7395 7396
-3 7396 7397 5607
-3 7367 7398 7368
-3 7369 7398 7367
-3 4422 7399 7400
-3 7400 7370 4422
-3 7371 7401 5643
-3 5584 7402 7372
-3 7372 7402 7403
-3 5600 5583 7402
-3 7403 7402 5583
-3 7373 7404 5583
-3 7404 7403 5583
-3 7374 7404 7373
-3 5602 7405 7406
-3 5602 7406 7376
-3 5602 7376 5587
-3 5588 7407 7408
-3 5594 5588 7408
-3 7407 5588 7378
-3 4977 7409 7379
-3 7410 7411 7412
-3 7410 5589 7411
-3 7411 5589 7413
-3 5589 7414 7413
-3 5589 7415 7414
-3 7416 5589 7417
-3 7417 5589 7382
-3 5596 7384 5589
-3 7386 7384 5596
-3 7387 4963 7418
-3 7388 7419 4373
-3 7389 7464 7420
-3 5590 7421 7422
-3 7421 5590 7391
-3 5593 7423 7394
-3 5607 7424 7447
-3 5607 7397 7424
-3 7424 7425 7447
-3 7425 7426 7428
-3 7426 7427 7428
-3 7427 7429 7428
-3 7399 4422 7430
-3 7431 5643 7401
-3 5602 7433 7405
-3 5594 7408 7434
-3 7409 7435 7436
-3 7409 4977 7435
-3 4977 5611 7435
-3 7410 7437 7438
-3 7412 7437 7410
-3 5589 7439 7415
-3 7416 7439 5589
-3 4963 7461 7440
-3 4963 7440 7418
-3 7441 4373 7419
-3 7464 7442 7443
-3 7464 7443 7420
-3 5590 7422 7486
-3 7422 7444 7486
-3 5593 7445 7423
-3 7446 7445 5593
-3 5608 7447 7425
-3 5608 7425 7428
-3 7448 7428 7449
-3 7448 5608 7428
-3 7429 7449 7428
-3 4422 7450 7430
-3 5643 7431 7451
-3 7452 5643 7451
-3 7453 7432 7433
-3 7454 7432 7453
-3 5602 5609 7453
-3 7433 5602 7453
-3 5594 7455 5610
-3 7455 5594 7434
-3 5611 7456 7457
-3 7457 7435 5611
-3 7410 7458 7459
-3 7438 7458 7410
-3 7461 4963 7460
-3 7462 4373 7441
-3 7462 7463 4373
-3 7465 7442 7464
-3 7466 7486 7444
-3 5593 5615 7446
-3 7446 5615 7467
-3 7447 7493 5617
-3 7447 5608 7468
-3 7447 7468 7493
-3 7468 5608 7469
-3 7469 5608 7448
-3 7450 4422 7470
-3 7452 7471 5643
-3 7472 7454 7453
-3 7473 7454 7472
-3 5609 7474 7453
-3 7453 7474 7472
-3 5609 7475 7474
-3 5610 7475 5609
-3 5610 7476 7475
-3 5610 7455 7476
-3 7477 7478 5611
-3 5611 7478 7456
-3 7410 7459 7480
-3 7410 7480 5623
-3 4963 7507 7481
-3 4963 7481 7460
-3 7463 7482 4373
-3 7464 7483 7465
-3 7464 7484 7483
-3 4415 7485 7464
-3 7464 7485 7484
-3 7487 7486 7466
-3 7487 7488 7486
-3 7487 7489 7488
-3 5615 7490 7467
-3 5617 7491 7492
-3 7493 7491 5617
-3 7494 7493 7468
-3 7469 7494 7468
-3 7495 7494 7469
-3 4422 7496 7497
-3 7497 7470 4422
-3 5643 7471 7498
-3 7499 5643 7498
-3 7472 7500 7473
-3 7474 7500 7472
-3 7501 7500 7474
-3 7475 7501 7474
-3 5619 7502 7477
-3 7502 7503 7477
-3 7504 7478 7477
-3 7504 7477 7505
-3 7505 7477 7503
-3 7479 7504 7505
-3 7479 7505 5623
-3 7480 7479 5623
-3 7507 4963 7506
-3 4963 5677 7506
-3 7508 4373 7482
-3 4415 7509 7485
-3 4415 7510 7509
-3 4415 7486 7522
-3 7511 7522 7488
-3 7522 7486 7488
-3 7489 7511 7488
-3 5615 7512 7490
-3 5616 7512 5615
-3 7492 5616 5617
-3 7512 5616 7492
-3 7496 4422 7513
-3 5643 7499 7514
-3 7515 5643 7514
-3 7503 7502 5619
-3 5623 7505 7503
-3 7506 5677 7516
-3 4373 7508 7517
-3 7517 7518 4373
-3 7519 7510 4415
-3 7520 7510 7519
-3 7521 7519 7522
-3 7519 4415 7522
-3 4422 7523 7513
-3 5088 7523 4422
-3 7524 5643 7515
-3 5677 7525 7516
-3 7526 4373 7518
-3 7527 7520 7519
-3 7528 7519 7521
-3 7528 7529 7519
-3 7530 7540 5624
-3 5088 7531 7532
-3 7532 7523 5088
-3 7524 7533 5643
-3 5677 7534 7535
-3 5677 7535 7525
-3 4373 7526 7536
-3 7536 7537 4373
-3 5629 7527 7519
-3 5629 5041 7527
-3 5041 7538 7527
-3 5629 7519 7529
-3 5629 7529 7539
-3 5634 7540 7530
-3 7542 5631 5630
-3 7542 7543 5631
-3 7544 5631 7543
-3 5088 7545 7546
-3 7546 7531 5088
-3 5643 7533 7547
-3 7548 5643 7547
-3 5677 7549 7550
-3 7534 5677 7550
-3 7551 4373 7537
-3 5041 5632 7538
-3 7538 5632 7552
-3 5633 7553 7567
-3 5629 7553 5633
-3 5629 7539 7553
-3 7553 7554 7567
-3 5037 7540 5634
-3 5043 7555 7556
-3 7541 7542 5630
-3 7541 5630 7556
-3 7557 5631 7544
-3 5088 7558 7559
-3 7559 7545 5088
-3 5643 7548 7560
-3 7561 5643 7560
-3 5677 7562 7549
-3 4373 7551 7563
-3 7563 7564 4373
-3 5632 7565 7552
-3 7566 7565 5639
-3 5633 7567 5639
-3 5043 5638 7555
-3 7555 5638 7568
-3 5641 7569 7570
-3 5641 7557 7569
-3 5641 5631 7557
-3 5088 7571 7572
-3 7572 7558 5088
-3 5643 7561 7573
-3 7574 5643 7573
-3 5677 7575 7576
-3 5677 7576 7562
-3 7577 4373 7564
-3 5639 7578 7566
-3 7567 7579 5639
-3 7579 7578 5639
-3 7580 5638 7581
-3 7580 7568 5638
-3 5641 7582 7583
-3 5641 7570 7582
-3 5088 7584 7585
-3 7585 7571 5088
-3 5643 7574 7586
-3 7587 5643 7586
-3 5677 7588 7589
-3 7575 5677 7589
-3 4373 7577 7590
-3 7591 7592 7593
-3 7593 7594 7591
-3 5638 5645 7581
-3 7581 5645 7595
-3 5641 7583 7596
-3 7596 7597 5641
-3 5088 7598 7599
-3 7599 7584 5088
-3 5643 7587 7600
-3 7601 5643 7600
-3 5677 7602 7588
-3 4373 7590 7603
-3 7604 7592 7591
-3 7605 7591 7594
-3 7605 7606 7591
-3 7606 7604 7591
-3 7605 7607 7606
-3 7595 5645 7609
-3 7597 7610 5641
-3 5088 7611 7612
-3 7610 7611 5088
-3 7612 7598 5088
-3 5643 7601 7613
-3 7614 5643 7613
-3 5677 7615 7602
-3 4373 7603 7616
-3 7618 7604 7617
-3 7606 7619 7604
-3 7619 7617 7604
-3 7607 7620 7606
-3 7620 7619 7606
-3 7621 7607 7608
-3 7621 7620 7607
-3 7623 7624 5645
-3 7624 7609 5645
-3 5643 7614 7625
-3 5643 7625 7626
-3 5677 7627 7615
-3 7616 7628 7629
-3 7630 7631 7632
-3 7630 7633 7634
-3 7632 7633 7630
-3 7633 7635 7634
-3 5083 5652 7636
-3 5646 5083 7636
-3 5646 7636 7637
-3 7638 5646 7637
-3 7617 7639 7618
-3 7639 7640 7641
-3 7639 7617 7640
-3 7617 7619 7640
-3 7620 7640 7619
-3 7621 5650 7620
-3 5650 7622 7642
-3 5650 7621 7622
-3 7642 7643 5650
-3 5651 5092 7644
-3 7644 7645 5651
-3 5651 7645 7646
-3 5645 5651 7647
-3 5651 7646 7647
-3 7648 5645 7647
-3 7623 5645 7648
-3 5643 7626 7649
-3 5643 7649 7650
-3 7651 5643 7650
-3 5677 7652 7627
-3 7616 7629 7653
-3 7616 7653 7654
-3 7630 7655 7631
-3 7655 7656 7657
-3 7655 7630 7656
-3 7630 7634 7656
-3 7658 7634 7635
-3 7658 7659 7634
-3 7659 7656 7634
-3 7658 7660 7659
-3 7636 5652 7661
-3 5646 7638 7662
-3 5653 5646 7663
-3 5646 7662 7663
-3 7666 5653 7664
-3 5653 7663 7664
-3 7666 7664 7665
-3 7668 7641 7640
-3 7640 5655 7668
-3 5650 7669 5105
-3 5650 7643 7669
-3 7669 7670 5105
-3 5092 7671 7644
-3 5643 7651 7672
-3 7673 5643 7672
-3 5664 7674 7675
-3 5664 7676 7677
-3 7675 7676 5664
-3 7678 7679 7680
-3 5665 7680 7681
-3 5677 7682 7652
-3 4509 7683 7684
-3 4509 7654 7683
-3 4509 7616 7654
-3 7656 7685 7657
-3 7685 7686 7687
-3 7685 7656 7686
-3 7656 7659 7686
-3 5658 7659 7688
-3 5658 7686 7659
-3 7660 7688 7659
-3 7689 5658 7688
-3 5652 5658 7712
-3 5652 7712 7690
-3 5652 7690 7661
-3 5666 7666 7667
-3 5666 7667 7691
-3 7691 7692 5666
-3 5660 7693 7694
-3 7668 5660 7694
-3 5655 5660 7668
-3 5105 7670 7695
-3 5105 7695 5662
-3 5662 7696 7697
-3 5662 7695 7696
-3 7671 5118 7698
-3 5643 7673 7699
-3 7700 5643 7699
-3 5664 5663 7674
-3 5663 7701 7674
-3 7677 7702 5664
-3 5664 7702 5112
-3 7703 5112 7702
-3 5671 7704 7678
-3 7680 5671 7678
-3 5665 7681 7705
-3 7705 7706 5665
-3 5677 7707 7682
-3 4509 7684 7708
-3 7686 7709 7687
-3 5658 7689 7710
-3 5658 7710 7711
-3 7712 5658 7711
-3 5660 5666 7713
-3 5666 7692 7713
-3 7713 7693 5660
-3 5662 7697 7714
-3 7698 5118 7715
-3 5643 7700 7716
-3 5643 7716 7717
-3 7718 5643 7717
-3 5663 7719 7701
-3 5112 7719 5663
-3 7720 7719 5112
-3 5112 7703 7721
-3 5673 5112 7722
-3 5112 7721 7722
-3 5114 7724 7726
-3 7724 7725 7726
-3 7727 5667 7726
-3 5667 5114 7726
-3 7727 7728 5667
-3 7728 5669 5667
-3 7704 5671 5669
-3 7728 7704 5669
-3 7706 7729 5665
-3 5677 7730 7707
-3 4509 7708 7731
-3 4509 7731 7777
-3 7686 7761 7709
-3 7709 7761 7732
-3 5662 7714 7736
-3 7736 7737 5662
-3 7738 7739 5118
-3 7715 5118 7740
-3 7740 5118 7739
-3 5643 7718 7741
-3 5643 7741 7742
-3 7743 5643 7742
-3 5112 7744 7720
-3 5112 7746 7745
-3 5112 7745 7744
-3 5673 7723 7747
-3 5673 7722 7723
-3 7747 7748 5673
-3 7750 7751 5683
-3 7751 7752 5683
-3 7752 7753 5683
-3 7724 5683 7754
-3 5683 7753 7754
-3 5665 7755 7756
-3 7755 5665 7729
-3 5677 7757 7758
-3 7730 5677 7758
-3 7777 7731 7759
-3 7777 7759 7760
-3 7777 7778 7761
-3 5679 5691 7779
-3 5126 7762 7763
-3 5126 7764 7762
-3 7734 5126 7733
-3 7734 7764 5126
-3 7733 5126 5680
-3 7733 5680 7735
-3 7735 5680 7765
-3 5662 7737 7766
-3 5662 7766 5693
-3 7767 5693 7766
-3 5118 7768 7769
-3 7738 5118 7769
-3 5643 7743 7770
-3 5698 5643 7770
-3 7771 5698 7770
-3 5112 5135 7746
-3 5135 5694 7772
-3 5135 7772 7746
-3 5683 5673 7748
-3 7749 5683 7748
-3 7750 5683 7749
-3 5665 7756 5703
-3 7756 7773 5703
-3 5677 7774 7775
-3 5677 7775 7776
-3 7776 7757 5677
-3 7779 7780 5679
-3 5679 7780 5690
-3 5691 7781 7779
-3 5692 7783 7782
-3 5692 7782 5691
-3 5691 7782 7781
-3 7785 7784 5126
-3 7785 5126 7763
-3 7765 5680 7786
-3 5693 7767 7787
-3 5693 7787 7788
-3 5118 5693 7789
-3 7789 5693 7788
-3 7768 5118 7789
-3 5698 7771 7790
-3 5698 7790 7791
-3 7792 5698 7791
-3 7772 5694 5698
-3 5698 7793 7772
-3 5696 7794 7795
-3 5687 7796 5696
-3 5696 7796 7794
-3 7797 7796 5688
-3 5688 7796 5687
-3 5688 5703 7797
-3 7798 5703 7773
-3 5677 7800 7801
-3 7801 7774 5677
-3 7802 5690 7780
-3 7803 7783 5692
-3 7803 7804 7783
-3 7784 7806 5697
-3 7806 7805 5697
-3 7786 5680 7807
-3 5698 7792 7808
-3 7809 5698 7808
-3 7810 7793 5698
-3 7810 5698 7811
-3 7811 7812 7813
-3 7810 7811 7813
-3 7813 7812 7814
-3 5696 7795 5702
-3 7795 7815 5702
-3 5703 7816 7797
-3 5703 7817 7816
-3 7799 5703 7798
-3 7799 7817 5703
-3 7818 7819 5677
-3 7819 7800 5677
-3 5690 7802 7820
-3 7803 5690 7820
-3 7821 7803 7820
-3 7804 7803 7821
-3 7822 7804 7821
-3 7805 7823 5697
-3 7824 7825 5680
-3 7825 7807 5680
-3 5706 5707 7826
-3 5698 7809 7827
-3 5698 7827 7828
-3 7829 5698 7828
-3 7829 7830 5698
-3 7830 7831 5698
-3 7832 5698 7831
-3 7811 5698 7832
-3 7833 7811 7832
-3 7812 7811 7833
-3 7834 7812 7833
-3 7814 7812 7834
-3 5702 7815 7835
-3 5711 5702 7835
-3 7836 5711 7835
-3 5677 7837 7838
-3 7818 5677 7838
-3 7839 4521 7823
-3 4521 5697 7823
-3 5713 7825 7824
-3 5713 7840 7825
-3 7826 5714 5706
-3 5711 7836 7841
-3 5716 7841 7842
-3 5716 5711 7841
-3 5718 7843 5677
-3 7843 7844 5677
-3 7837 5677 7844
-3 4521 7839 7845
-3 4521 7845 7846
-3 4521 7846 7847
-3 4521 7847 7840
-3 5716 7842 7848
-3 5716 7848 7849
-3 7850 7851 5718
-3 7852 5718 7851
-3 7843 5718 7852
-3 5716 7849 7853
-3 5716 7853 5718
-3 5718 7853 7854
-3 7855 5718 7854
-3 5718 7855 7856
-3 5718 7856 7857
-3 5718 7857 7858
-3 5718 7858 7859
-3 7850 5718 7859
-
-CELL_DATA 13733
-POINT_DATA 7860
-NORMALS normals float
--0.133614 -0.057263 -0.989378 -0.0307275 -0.537162 -0.842919 -0.864861 -0.161839 -0.47521
--0.0591288 -0.790848 -0.60915 -0.72247 0.175378 -0.66879 0.236808 -0.629513 -0.740024
-0.197983 -0.368125 -0.908453 0.355323 -0.801092 -0.48166 0.285198 -0.791312 -0.540821
--0.618792 -0.400138 -0.676007 -0.398669 -0.360336 -0.843339 0 -0.0860472 -0.996291
-0.65077 -0.224068 -0.72546 -0.616992 0.576954 -0.535205 0.303636 -0.510558 -0.804448
-0.0991771 0.682572 -0.724058 0.372129 0.614105 -0.695985 -0.490425 0.764772 -0.41786
-0.0313472 0.583987 -0.811158 0.399766 -0.323516 -0.857627 0.216481 0.546615 -0.808918
-0.390625 0.179303 -0.902919 -0.088772 0.773204 -0.627914 -0.161114 0.301929 -0.939618
-0.336389 -0.421911 -0.841922 -0.529158 -0.497371 -0.687469 -0.448965 -0.270927 -0.851486
-0.456537 0.204655 -0.865847 -0.370621 0.853657 -0.365937 -0.188935 0.739997 -0.645529
-0.0329652 -0.212296 -0.976649 -0.149265 -0.468952 -0.870519 0.135512 0.597534 -0.79031
--0.431091 0.395359 -0.811081 -0.313014 -0.35348 -0.881518 0.208532 0.181332 -0.961058
-0.440965 0.440965 -0.781728 0.381019 0.634407 -0.672571 -0.260464 0.83826 -0.479039
-0 0.637398 -0.770535 0.253912 -0.463967 -0.848683 -0.745225 -0.1198 -0.655963
--0.819732 -0.123691 -0.559232 0.351087 -0.152592 -0.923826 0.299891 -0.766145 -0.568407
--0.0578228 -0.708329 -0.70351 -0.298115 -0.407947 -0.862964 0.626218 0.27526 -0.72944
--0.428964 0 -0.903322 -0.840707 0.309226 -0.444512 0.612134 -0.612134 -0.500582
-0.778143 0.124987 -0.615526 0.298546 0.138859 -0.94424 -0.483754 0.68549 -0.544138
-0.150583 0.282344 -0.947421 0.318835 -0.670203 -0.670203 -0.447214 0 -0.894427
--0.557993 -0.557993 -0.614238 -0.350425 -0.313294 -0.882638 0.678742 0.132751 -0.722279
-0.184754 -0.606401 -0.773398 -0.555685 -0.412346 -0.721932 -0.54253 -0.19323 -0.817511
--0.454534 -0.307546 -0.835951 0.309976 0.302415 -0.901366 0.791268 0.485184 -0.372145
--0.601158 0 -0.79913 -0.195297 0.328291 -0.924167 0.561633 0.64151 -0.522527
--0.430992 0.549168 -0.716003 0.450158 -0.054019 -0.891313 -0.0141727 -0.37479 -0.927001
--0.483179 0.180464 -0.856721 -0.327193 0.433721 -0.839542 0.334286 0.754839 -0.564332
-0.671316 0.671909 -0.312846 0.344796 0.158164 -0.925257 0.22389 0.743178 -0.630524
--0.553661 0.562312 -0.614218 -0.166154 -0.166154 -0.972001 -0.0172758 -0.302326 -0.953048
-0.591926 0.484469 -0.644137 -0.687459 0.261533 -0.677496 -0.505059 0.325209 -0.799471
-0.166733 0.45256 -0.876008 0.588363 0.588363 -0.55467 -0.406719 0.382316 -0.829707
-0.473568 -0.163299 -0.865486 0.720113 -0.256824 -0.644577 0.236649 -0.191878 -0.95246
-0.413754 0.227159 -0.881593 -0.417457 -0.790013 -0.449009 0.124878 -0.405854 -0.905366
--0.39225 -0.851721 -0.347435 -0.239402 -0.729666 -0.640527 -0.0931752 -0.0931752 -0.99128
-0.123225 0.432494 -0.893177 -0.249097 -0.886882 -0.389089 0.217978 -0.743821 -0.631836
-0.732431 0.259049 -0.629634 -0.737644 -0.569222 -0.363137 -0.669417 -0.68991 -0.275509
-0.821447 -0.111914 -0.559196 -0.924616 0.233679 -0.300798 -0.731344 -0.200835 -0.651768
--0.487093 0.295284 -0.821917 0.119911 -0.875437 -0.468222 -0.0338245 -0.717313 -0.69593
--0.0261782 0.279234 -0.959866 -0.0250979 0.633721 -0.773154 0.119187 0.815737 -0.566011
-0.879941 0.148971 -0.451122 0.201057 -0.61231 -0.764626 -0.220722 -0.715565 -0.662758
--0.919569 -0.0491032 -0.389849 -0.835811 -0.311849 -0.451853 0.523791 0.363162 -0.770555
-0.492487 -0.363645 -0.790708 -0.236316 -0.379469 -0.894516 0.285703 -0.82894 -0.480866
--0.603185 -0.603185 -0.521857 0.582435 0.465226 -0.666584 -0.634173 0.76534 -0.109907
--0.584343 -0.235207 -0.776673 -0.0678275 -0.131887 -0.988941 -0.269185 -0.72255 -0.636757
--0.634909 -0.317455 -0.704353 0.0535556 -0.444923 -0.893966 0.512611 -0.367788 -0.775862
-0.341278 -0.713496 -0.611925 -0.487268 -0.603938 -0.630736 -0.378509 -0.485634 -0.787966
-0.0320423 0.339926 -0.939906 -0.550019 0.821907 -0.148148 0.0585813 -0.422704 -0.904372
-0.382161 0.543608 -0.747291 0.500733 0.646371 -0.575734 0.0850264 0.786494 -0.611717
--0.159823 -0.820268 -0.549196 0.365676 -0.424613 -0.828242 0.0242708 -0.651266 -0.758462
--0.507728 0.237573 -0.828113 0.60161 -0.6034 -0.523425 -0.809091 0.35261 -0.470147
-0.216092 -0.520584 -0.826012 -0.357151 -0.0957722 -0.929124 -0.846672 0.235721 -0.477055
-0.660332 -0.623161 -0.419085 -0.68403 -0.523612 -0.507872 -0.923242 0.314121 -0.22125
--0.0158154 -0.661987 -0.749348 0.647451 -0.716615 -0.259365 -0.887292 0.0362983 -0.459778
--0.880705 0.414627 -0.229004 -0.880691 0.463666 -0.09694 0.854087 -0.349399 -0.385299
-0.591791 -0.197264 -0.781582 -0.69874 0.685205 -0.205562 -0.644528 0.34271 -0.683472
-0.519893 -0.777214 -0.354472 -0.588419 -0.588419 -0.55455 -0.814164 0.524526 -0.249018
-0.666706 -0.72418 -0.176256 -0.767549 0.610615 -0.194978 0.596127 -0.675259 -0.434347
--0.568865 0.667022 -0.481118 0.468899 -0.549215 -0.691735 -0.673848 -0.595175 -0.43783
--0.37961 -0.541691 -0.749978 0.649603 -0.356158 -0.67169 0.467638 -0.171231 -0.867176
-0.197129 0.824751 -0.530025 -0.315227 0.736623 -0.598347 -0.189691 -0.331959 -0.924024
--0.432596 -0.884943 -0.172444 -0.653129 0.0762328 -0.753399 -0.196901 -0.798542 -0.568824
-0.595899 0.595899 -0.538339 -0.0833766 -0.90672 -0.413409 0.244745 -0.840249 -0.483819
--0.0411872 0.720775 -0.691944 -0.346388 -0.148984 -0.926185 0.262214 -0.510627 -0.818843
--0.32034 -0.0488322 -0.946043 0.0269138 -0.558461 -0.829094 -0.231713 -0.311614 -0.921524
-0.415067 -0.105914 -0.903605 0.113699 0.437303 -0.892098 0.687616 -0.181196 -0.703102
--0.730426 -0.191407 -0.655623 -0.0673477 -0.43776 -0.896566 0.587931 -0.355209 -0.726749
-0.407993 0.710211 -0.573709 0.0627344 -0.643028 -0.763269 -0.716044 -0.492216 -0.494979
--0.625571 -0.657112 -0.420552 -0.125133 -0.871118 -0.474864 -0.513312 0.500792 -0.696935
-0.205739 -0.154691 -0.966303 0.139194 -0.63921 -0.756331 -0.183705 -0.7983 -0.573558
-0.129194 -0.79939 -0.586758 0.395605 -0.699374 -0.595292 0 -0.714057 -0.700088
-0.0821513 -0.670499 -0.737348 0 -0.947723 -0.319096 0 -0.424893 -0.905244
-0.232035 0.261205 -0.93698 -0.26748 0.823524 -0.500263 -0.505771 0.579733 -0.638831
--0.302437 0.55059 -0.778064 -0.0322538 0.628948 -0.776778 0.216548 0.804992 -0.552353
--0.0276135 0.796846 -0.603551 0.0606424 0.818673 -0.571049 0.42076 0.688839 -0.590307
-0.442564 0.636671 -0.631495 0.0703097 0.953021 -0.294631 -0.393632 0.883207 -0.254949
-0 0.842439 -0.538792 0.247275 0.851023 -0.463265 -0.53666 -0.712685 -0.451749
-0.330773 -0.301587 -0.894223 -0.311853 -0.648992 -0.693943 -0.0186271 -0.614693 -0.788546
-0.778019 0.198507 -0.596055 -0.721324 -0.65162 -0.234698 -0.244691 -0.700758 -0.670123
-0.722534 0.148377 -0.675225 -0.94044 -0.111906 -0.321012 -0.414019 -0.785113 -0.460636
-0.578245 -0.302339 -0.757776 0.804844 0.371467 -0.462859 -0.215747 -0.449986 -0.866583
-0.873669 0 -0.486522 -0.796789 -0.150159 -0.585304 0.577632 -0.654494 -0.48783
--0.919215 0.189644 -0.345078 -0.815376 0.574037 -0.0751172 0.94216 -0.314825 -0.114973
--0.526794 0.237428 -0.816159 0.367513 -0.929476 0.0317603 -0.438774 0.371842 -0.818053
-0.647808 -0.0398651 -0.76076 0.204368 -0.978894 -0.000987286 0.26964 -0.955995 -0.115618
-0.631516 -0.66722 -0.394976 -0.501994 0.643066 -0.578332 0.464369 0.337251 -0.818916
-0.953793 -0.124408 -0.2735 -0.151531 0.567922 -0.809013 0.764898 -0.642514 0.0458939
-0.2831 -0.886154 -0.366858 0.607346 -0.764806 0.214946 0.270611 -0.704715 -0.655855
-0.401862 -0.438789 -0.803723 -0.434244 -0.672652 -0.599143 0.726992 -0.275329 -0.629028
-0.592987 -0.393762 -0.702366 -0.474079 -0.574123 -0.667557 -0.503787 -0.440437 -0.743111
--0.457974 -0.673915 -0.57974 -0.588721 0.792639 -0.158528 0.0695623 -0.890398 -0.449836
-0.457902 -0.737537 -0.496352 0.970729 0.0507571 -0.234752 0.707754 -0.540756 -0.454606
--0.697492 -0.656992 -0.286122 -0.725648 -0.563773 -0.394455 0.985733 -0.147733 -0.0806586
--0.550024 -0.829022 -0.100971 0.512143 -0.857839 -0.0426786 0.322015 -0.946725 -0.00429354
--0.522973 -0.852252 0.0129129 -0.649531 -0.759452 0.0366402 0.14246 -0.939007 -0.313002
--0.280881 -0.853879 -0.438175 -0.0711379 -0.995931 0.0553295 -0.548838 0.804265 -0.227891
--0.74702 0 -0.664801 0.0171827 -0.326472 -0.945051 0.410419 -0.679111 -0.608575
--0.364289 0.167455 -0.916107 0.246603 -0.332377 -0.910336 0.451961 -0.335743 -0.826443
-0.144032 -0.882629 -0.44746 -0.38057 -0.225126 -0.896931 -0.575825 0.465475 -0.67213
-0.112 0.0263529 -0.993359 0.281641 -0.345346 -0.895217 -0.652357 -0.588712 -0.477334
--0.0965727 -0.915831 -0.389778 0.660328 -0.660328 -0.357678 -0.279956 0.36428 -0.888214
--0.100151 -0.0166918 -0.994832 -0.887081 -0.100325 -0.450581 0.76069 0.544434 -0.353471
--0.402301 0.504888 -0.763702 -0.349163 0.311494 -0.883774 0.441792 0.834495 -0.329298
--0.559507 -0.808386 -0.182932 -0.138395 -0.827316 -0.544421 -0.631133 -0.746974 -0.209046
--0.173925 -0.780433 -0.600562 0.767655 -0.0383828 -0.639713 -0.453607 -0.685278 -0.569767
-0.551526 -0.14722 -0.821063 0.826474 0.363649 -0.429767 0.8577 0.388891 -0.336325
-0.823711 0.279248 -0.493478 0.333318 -0.754251 -0.565689 0.0406417 -0.746792 -0.663815
-0.015947 -0.534225 -0.845192 -0.520495 0.0208198 -0.853611 0.661244 -0.495308 -0.563406
-0.913519 0.321215 -0.249607 -0.747552 0.00807074 -0.664154 0.461353 -0.53233 -0.709773
-0.292762 -0.56131 -0.774094 0.190724 -0.486347 -0.852696 -0.888497 0.430483 -0.158928
-0.994314 -0.0509905 0.0934825 0.986835 -0.131761 0.0937882 0.90288 -0.379832 0.201332
-0.619007 -0.75584 0.213394 0.869212 -0.160118 -0.467796 0.824087 -0.222516 -0.52093
-0.60237 0.798086 -0.0144975 -0.0559393 -0.964954 -0.256389 -0.379812 0.634713 -0.672965
-0.648721 -0.131186 -0.749634 0.977478 -0.153099 0.145248 -0.681476 -0.526052 -0.508782
-0.253505 -0.869394 -0.424134 -0.295363 0.210974 -0.9318 0.771082 -0.571005 0.281756
--0.520388 -0.81452 -0.256423 -0.932492 -0.332476 0.141129 -0.387589 0.66745 -0.635834
-0.72924 0.447094 -0.517992 0.490614 0.598931 -0.632913 0.554927 0.541393 -0.631625
--0.0398377 -0.632976 0.773146 0.833643 0.0106877 0.5522 0.277725 -0.55545 -0.783801
--0.428552 -0.68747 0.586284 0.232916 -0.842788 -0.485241 -0.207499 -0.735837 -0.644584
--0.128406 -0.342416 -0.930733 -0.160642 0.973546 -0.162488 -0.986898 0.0986898 0.127639
-0.451855 -0.636122 -0.62544 0.64379 0.539243 -0.542911 0.593303 0.25522 -0.763449
-0.234245 -0.669273 -0.705126 0.35794 0.188615 -0.914496 -0.643042 0.270755 -0.716372
-0.521396 -0.109909 -0.846207 0.91988 -0.041365 -0.390013 -0.946342 0.288601 -0.145419
-0.72821 0.682613 -0.0612429 -0.346952 -0.919119 -0.186664 0.0326775 -0.980326 -0.19466
-0.297089 -0.871314 -0.390576 0 -0.849343 -0.527841 0.0658001 -0.870586 -0.487596
-0.74046 0.64113 -0.20167 -0.540906 0.801701 -0.254355 0.833497 -0.00766434 -0.552471
-0.72087 -0.493227 -0.486903 -0.912475 -0.382435 0.14537 0.254155 -0.914959 -0.313458
--0.66355 -0.737278 0.126976 -0.327662 0.703275 -0.630905 -0.471757 -0.36856 -0.801005
-0.245787 -0.825896 -0.50743 -0.79949 0.588196 -0.121827 -0.554541 -0.831811 0.0239616
--0.0360758 0.742401 -0.668984 -0.522275 0.838219 0.156897 0.317629 -0.923394 0.215534
-0.290532 0.576195 -0.763931 -0.77193 0.604489 -0.196766 -0.130676 -0.659232 -0.740498
--0.459006 -0.442006 -0.770677 -0.374676 -0.769072 -0.517827 -0.376284 0.430038 -0.820657
-0.222776 -0.879965 -0.419562 -0.48734 0.46584 -0.738575 -0.249152 -0.738395 -0.626654
--0.706638 0.0936891 -0.701345 -0.382983 0.718093 -0.581091 0.0830439 -0.110725 -0.990376
-0.260005 -0.913991 -0.311476 0 0.999101 0.0423861 0.444728 -0.690636 -0.570298
-0.0428856 0.950631 -0.307347 0.815639 0.577103 0.0410385 0.942857 0.171429 0.285714
--0.728315 0.662105 0.176561 -0.722965 -0.690103 -0.032862 -0.910416 0.0343553 -0.412264
--0.128238 0.881635 -0.454175 -0.186605 0.92473 -0.331742 -0.486271 0.75559 -0.43889
--0.746592 0.409132 -0.524605 -0.67561 -0.275249 -0.683951 0.959044 0.280696 0.0380109
--0.551393 0.600772 -0.578826 0.682383 0.720548 -0.123144 -0.129602 -0.931015 -0.341196
-0.899206 0.0372805 -0.435934 -0.865383 -0.397797 -0.304745 0.355155 -0.856956 -0.373486
--0.121418 -0.689481 -0.714054 0.723358 -0.632815 -0.276221 -0.226561 -0.696637 -0.680711
-0.511263 -0.723072 -0.464519 -0.911951 -0.130058 -0.38914 0.937919 -0.290078 -0.190162
-0.760164 0.550687 -0.344809 0.766852 0.546222 -0.337015 0.934208 -0.3242 -0.148829
--0.982977 0.174299 -0.0580998 0.177826 -0.98367 -0.0277619 -0.728453 -0.67903 0.0909671
-0.778298 -0.598196 -0.190822 0.504274 0.784427 -0.361085 0.313858 -0.859187 -0.404092
-0.818402 -0.572881 -0.0450121 0.902922 0.409137 -0.131676 -0.0824148 0.970663 -0.225878
-0.26844 -0.96313 -0.017896 0.954296 0.149554 -0.258752 0.698362 -0.101079 -0.708572
--0.990127 -0.0735905 0.119306 -0.519702 0.814759 0.257057 -0.661742 0.672771 0.330871
--0.106395 -0.984152 0.14186 0.586209 0.768585 -0.256195 -0.0510752 -0.752508 -0.6566
-0.534006 -0.738057 -0.412444 -0.746554 0.590949 -0.305673 0.951414 0.0126434 0.307655
--0.405861 -0.900274 0.157425 0.402726 -0.836431 0.371747 -0.48941 -0.870062 0.0589104
-0.786062 -0.550243 -0.281672 0.894147 0.108601 0.434404 0.931719 -0.0291162 0.362012
--0.46618 -0.884546 -0.0159378 -0.294639 -0.837308 -0.460547 -0.0271759 0.570694 -0.820713
--0.646277 0.656016 -0.389832 0.838007 0.164315 0.520331 -0.451493 -0.799787 0.395594
--0.694515 -0.0292427 -0.718884 0.0571292 0.956915 -0.284694 0.463583 -0.86278 0.201745
--0.527545 -0.83658 0.147754 -0.53086 -0.812675 0.240307 0.703842 0.703842 0.0959785
-0.14104 0.967135 -0.211561 -0.0949207 -0.976327 -0.194361 0.902432 -0.258894 -0.344371
--0.166339 -0.970311 0.17558 -0.960289 0.0561572 -0.273299 0.431889 -0.431889 -0.791797
-0.629445 0.769322 0.109279 -0.972387 -0.233373 0 -0.707308 0.579529 -0.404799
-0.575168 -0.692435 -0.435564 -0.722346 0.685303 -0.0926085 0.403399 0.576284 0.71075
--0.838388 0.540438 0.0709405 0.618425 -0.531767 -0.578597 0.666068 -0.609667 -0.429721
--0.591621 0.591621 -0.547694 -0.571101 0.598297 -0.562036 -0.522678 0.709348 -0.472899
-0.248187 -0.849265 0.465997 0.749401 0.343811 -0.565856 0.327269 0.139263 -0.934613
-0.470209 -0.798609 -0.37567 -0.448116 0.426572 0.785639 -0.355483 -0.891999 0.27923
--0.816525 -0.199965 -0.541573 0.626849 -0.690813 -0.360331 0.932835 0.339604 0.120366
-0.750775 0.459982 -0.474081 -0.84453 0.341834 -0.412211 0.573251 -0.473762 -0.66853
-0.278974 -0.852913 -0.441264 0.0873541 -0.762893 -0.640597 -0.983169 0.172055 0.0614481
--0.602585 -0.71815 0.348069 -0.297116 0.847331 -0.440172 0.303829 0.717405 -0.626911
-0.653544 -0.308205 -0.691296 -0.201612 -0.632644 -0.74774 -0.279857 0.612659 -0.739141
--0.068935 -0.0771416 -0.994634 0.33931 -0.819482 -0.461863 -0.883753 -0.45613 0.10453
--0.254414 0.166439 0.952666 -0.249208 0.320836 -0.913761 -0.207199 0.148716 -0.966929
-0.304056 -0.33407 -0.892159 -0.170821 0.134216 -0.976118 0 -0.311641 -0.9502
-0.694672 -0.709144 0.120603 0.859581 -0.509036 -0.0447504 -0.781435 0.407462 0.472582
--0.647169 -0.392224 0.653706 -0.886995 0.0490504 0.459166 -0.497468 0.297268 -0.814958
-0.0882852 0.0294284 -0.99566 -0.269897 -0.304247 -0.913559 -0.719314 0.401156 -0.567152
--0.133211 -0.793344 -0.594021 0.102573 -0.981767 -0.160036 -0.479456 0.76713 -0.426184
-0.53753 0.808457 0.239703 -0.402972 0.914818 0.0268648 0.917997 -0.396562 0.00452816
-0.980883 0.0779716 0.178295 0.883936 0.441968 0.152713 -0.716192 -0.695922 -0.0525508
--0.0555452 0.864653 -0.499289 -0.243071 0.729213 -0.63966 0.952863 -0.276809 0.124209
--0.211241 -0.977383 -0.00998402 -0.540551 0.390592 -0.745146 -0.458135 0.823741 -0.33401
-0.369622 -0.870401 -0.325241 -0.146564 -0.840301 -0.521931 0.72583 -0.672963 -0.142449
--0.29592 -0.883917 -0.362107 0.647963 -0.416547 -0.637678 -0.149366 -0.852922 -0.500214
--0.746148 -0.662663 -0.0643531 0.855179 -0.117505 -0.504838 0.794308 0.21938 -0.566522
-0.239602 0.339436 -0.909601 -0.318953 0.134296 -0.938208 0.472654 -0.759727 -0.446557
-0.496001 -0.807052 -0.320392 0.576018 -0.62402 -0.528017 -0.116539 0.773139 -0.623438
-0.71045 0.333298 -0.619817 -0.105028 -0.992996 0.0541056 0.693252 -0.683712 -0.227904
--0.66256 -0.603026 0.444267 -0.0633257 -0.909588 0.410658 0.278523 -0.960424 -0.00320141
-0.329474 -0.929344 0.166631 0.23583 -0.946032 0.222277 0.17609 0.440225 0.880451
--0.741536 -0.670913 0 -0.757684 -0.651961 0.0293676 0.915488 -0.0938963 -0.391234
-0.0657912 -0.997833 0 -0.0423798 0.720457 -0.692204 0.548646 0.759664 -0.349139
--0.393073 -0.917171 -0.0655122 0.721223 0.523468 -0.453672 0.517381 0.776071 -0.360599
--0.928473 -0.295423 -0.225084 0.710282 -0.701925 -0.0529229 0.698377 0.704904 -0.124011
--0.95902 -0.139857 -0.246415 0.898349 -0.431207 -0.0838459 -0.724146 0.599293 0.341264
-0.740475 -0.598136 -0.306481 -0.762629 -0.635902 -0.11843 0.104777 -0.681047 -0.724704
-0.638241 -0.769309 0.0284929 0.994249 -0.0887288 0.0599629 0.17609 -0.968496 0.17609
-0.513226 -0.856379 -0.0566906 0.296071 0.911897 0.284228 -0.735612 0.559065 0.382518
--0.730931 0.608526 0.308926 0.89569 -0.432749 0.102317 0.124686 -0.992063 -0.0162633
--0.417759 -0.908461 -0.0132622 0.323677 -0.921233 -0.215784 -0.965722 -0.259028 0.0168931
--0.982888 -0.182016 -0.0283136 0.299775 0.930552 -0.210259 0.301131 0 0.953583
-0.976112 0.208611 -0.0607151 -0.890387 0.0460545 0.452869 0.813767 0.48358 0.322387
-0.839341 0.453698 0.299441 0.0112225 0.864131 0.503141 -0.860695 0.43913 0.257623
-0.01133 -0.940393 -0.339901 0.361886 -0.882096 -0.301571 -0.283706 -0.831774 -0.477141
-0.753653 -0.0519761 -0.655214 0.558975 -0.264243 -0.785953 0.586881 -0.8031 -0.102962
--0.895676 0.422393 0.139101 0.200534 -0.968295 0.148968 0.755142 -0.655406 0.014248
--0.409691 -0.872821 0.265211 -0.722956 0.690464 -0.0243693 -0.790186 0.603615 0.10609
--0.369077 0.918116 0.144377 -0.19593 0.979651 -0.04354 -0.218537 0.967805 0.124878
--0.13994 0.965583 0.219239 -0.102463 0.973399 0.204926 -0.297193 0.934035 0.198129
--0.522716 -0.678668 -0.515924 0.578153 -0.140245 -0.803785 -0.691431 0.718024 0.0797805
-0.435884 -0.89158 -0.12284 -0.606334 -0.785479 -0.124023 0.730789 0.501956 0.462587
-0.829482 0.47399 0.295454 0.692996 0.679921 0.239716 0 0.462566 0.886585
-0.186443 0.865288 0.465312 0.908919 -0.398649 -0.122252 -0.651332 0.195812 0.733092
-0.0958325 0.972015 0.214482 0.576707 0.527885 0.623495 -0.783524 0.547223 0.29434
--0.713561 0.5622 0.418046 -0.813596 0.355572 0.460033 -0.637132 -0.58963 -0.496385
-0.252222 0.252222 -0.934221 0.71509 0.659113 -0.232844 0.250099 -0.701892 -0.666932
-0.830773 0.288001 0.47631 0.196129 0.442546 0.875035 -0.926488 0.188352 0.325798
-0.654477 -0.711388 -0.2561 -0.433262 -0.753876 0.493919 0.660852 -0.189307 0.726249
--0.48085 -0.824314 0.298814 0.983296 -0.150169 -0.102855 0.520532 -0.753605 -0.401405
--0.491369 -0.728328 -0.477592 0.358962 0.243277 -0.90109 0.689078 0.689078 -0.224374
--0.717496 0.573997 -0.394623 0.264013 0.940669 -0.213166 -0.529192 0.797988 0.288395
--0.261115 -0.821228 0.507349 -0.680331 -0.684186 0.262753 -0.218519 -0.963269 -0.156085
-0.652871 -0.748414 0.116774 0.203874 -0.974064 -0.0981614 0.205266 -0.173687 0.963171
--0.171388 0.0507816 0.983894 -0.350738 -0.85736 0.376719 -0.855798 -0.474442 0.206192
--0.475789 -0.836182 0.272809 -0.135139 0.844618 0.518032 0.84978 0.186952 0.492872
--0.486418 0.856759 0.171352 0.307937 -0.865918 -0.394159 -0.438607 -0.758597 -0.481824
-0.659006 0.110713 -0.743945 0.69225 0.686197 -0.223436 0.231633 -0.146029 0.96178
-0.539235 0.550958 0.636923 -0.383801 -0.733736 0.56065 0.893078 -0.435089 -0.114497
-0.506432 -0.350607 0.787783 -0.604419 0.36457 0.708354 -0.873243 -0.169356 0.456909
-0.688789 -0.439653 0.576433 -0.885817 0.117133 0.449009 0 -0.999061 0.0433356
-0.871587 0.0901642 -0.481878 -0.511752 -0.0261691 -0.858735 -0.53265 -0.764754 -0.362539
--0.489831 -0.473503 -0.732025 0.450223 0.452841 -0.769568 0.769039 0.607173 -0.199799
--0.378939 0.801186 -0.463148 -0.718397 -0.689075 0.0952976 0.184114 0.97763 0.101694
--0.382269 0.888214 0.254846 0.867466 -0.485462 -0.108765 -0.560007 -0.222072 0.798171
--0.913832 -0.290254 0.284012 0.560901 -0.780385 0.276386 -0.368434 -0.846421 -0.384483
--0.38097 -0.881165 -0.280018 -0.210366 -0.839178 -0.501525 0.0851775 -0.00967926 -0.996319
-0.52573 0.738864 -0.421531 0.541798 0.823036 -0.170489 -0.601124 0.743495 -0.293029
-0.0634667 0.335467 -0.939912 -0.164716 -0.973322 -0.159725 0.874235 0.298474 0.382919
-0.975442 0.177995 0.129729 -0.932739 -0.328536 0.148533 -0.310257 -0.810372 -0.497028
-0.620221 0.334651 -0.709461 0.587911 0.732468 -0.343294 -0.74274 0.275875 -0.610107
-0.239939 0.945067 0.221985 -0.192387 0.902738 0.384774 0.908868 -0.0873912 -0.407825
--0.9459 0.169696 0.276542 -0.940466 0.175983 0.290781 0.36958 -0.90952 -0.19022
--0.460918 -0.800411 -0.383272 0.572474 0.677593 -0.461672 0.223733 -0.968343 0.110701
--0.216985 0.278012 0.935749 0.791297 0.238404 0.563038 0.79788 -0.555363 -0.234433
-0.0708869 -0.992416 0.100423 -0.555622 -0.807224 0.199185 -0.868642 -0.414275 0.271729
-0.142525 -0.891428 -0.430166 -0.668659 0.260825 -0.696323 -0.486004 0.602064 -0.633497
-0.123554 0.809965 -0.573316 0.22312 -0.80881 0.5441 0.509371 -0.709386 0.487147
--0.85552 -0.392807 0.337326 0.128324 -0.991598 0.0163322 0.04847 0.981518 0.185129
--0.160852 0.97798 0.132971 -0.783356 -0.0257743 -0.621039 0.396049 -0.203525 -0.895389
-0.800749 -0.0250234 -0.598477 0.197399 0.540055 -0.818153 -0.0079445 0.897728 -0.440478
-0.373377 0.886251 -0.274134 0.141833 -0.921916 0.360493 -0.929152 0.349305 -0.121092
--0.978305 0.142402 -0.150472 0.148585 0.728276 -0.668982 0.644562 0.528742 -0.552242
-0.41021 0.876547 -0.251779 0.329187 -0.938472 -0.104435 -0.419297 -0.898714 -0.128461
--0.403814 0.779454 -0.478942 -0.155245 0.851859 -0.500235 -0.654974 0.664606 -0.359594
-0.623948 -0.263531 -0.73569 -0.91542 -0.191728 -0.353903 0.556984 -0.718688 -0.41624
--0.299696 -0.775301 -0.555958 0.0263015 -0.836387 -0.547509 0.329968 -0.532663 -0.779353
--0.871129 -0.454099 -0.186891 0.610586 0.732157 -0.301878 0.682646 0.626428 -0.376273
-0.656219 0.686047 -0.31419 -0.702782 -0.649801 -0.289579 0.909282 -0.357218 -0.213544
--0.956792 0.278167 -0.0846846 0.741177 -0.626202 -0.241926 0.680638 -0.686146 -0.25678
-0.558265 -0.197035 -0.805927 -0.586108 -0.0572744 -0.808206 0.867414 0 -0.497587
-0.522385 -0.700066 -0.486848 0.374142 0.363513 -0.853157 0.431889 -0.431889 -0.791797
-0.831385 -0.356979 -0.42587 0.766349 0.569701 -0.2969 -0.78086 -0.496911 -0.378599
--0.0498854 -0.997708 -0.0457283 0.898977 -0.433004 -0.0659396 0.886174 -0.43135 -0.169214
--0.19776 -0.939362 -0.280161 -0.457524 0.481138 -0.747782 0.475591 -0.744403 -0.468698
-0.0990088 -0.964033 -0.246653 -0.601644 0.595687 0.532147 0.683818 0.683818 0.254532
--0.524195 0.725137 0.446537 -0.752249 -0.451349 -0.480006 0.15757 -0.601632 -0.783077
-0.290014 -0.913545 -0.285181 0.220903 -0.965483 -0.138 -0.794953 -0.539432 0.277603
--0.326052 -0.846725 -0.420413 0.903413 -0.171776 -0.392858 0.338093 0.899623 -0.276355
--0.34795 -0.394343 -0.850544 -0.548044 -0.631898 -0.548044 -0.724555 -0.169577 -0.66803
--0.0188745 -0.968891 -0.246767 -0.64358 -0.64358 -0.414258 0.356294 -0.456056 -0.815517
--0.648772 -0.689441 -0.322127 -0.465801 -0.237753 -0.852351 0.741325 0.585257 -0.328499
--0.779814 -0.582047 -0.23046 0.928625 0.19967 -0.312711 0.874323 -0.483668 -0.0403057
--0.0607823 -0.850952 -0.521715 -0.118168 -0.948487 -0.293953 -0.308258 -0.703795 -0.640039
-0.753462 0.453637 -0.475929 0.0160721 -0.962033 -0.272461 -0.830418 0.553612 -0.0626109
-0.968504 -0.141732 0.204724 0.79849 -0.598867 0.0614223 0 -0.848336 -0.529458
--0.82896 -0.524195 -0.195049 0.844479 0.52011 -0.12783 0.767202 -0.627521 -0.132732
--0.353643 0.640381 -0.681798 0.25207 -0.930719 -0.264996 0.305425 -0.916274 -0.259148
--0.384486 0.90221 0.195415 0.822951 0.565779 -0.0514344 -0.152098 -0.221233 -0.963287
--0.354471 -0.16953 -0.91957 -0.196067 0.980334 -0.0224076 0.133009 0.975401 -0.17579
-0.542551 -0.613318 -0.574003 0.0839211 -0.917138 -0.389634 0.710839 0.690135 0.135727
-0.732502 -0.138581 -0.666511 0.629762 0.414389 -0.657025 0.528107 0.55369 -0.64384
--0.491848 0.86233 -0.1203 0.379547 0.919673 -0.100726 -0.167817 0.976388 0.136033
-0.431277 -0.782524 -0.449062 -0.662868 -0.224902 -0.714161 0.22194 0.887761 -0.403264
-0.0235352 0.0823732 -0.996324 0.420952 -0.762634 -0.491111 -0.752994 0.648856 -0.109478
--0.92798 0.107075 0.356915 -0.701876 0.694926 -0.156358 -0.392322 0.603572 0.694107
--0.618742 -0.563607 0.547271 0.184252 0.982043 -0.0405227 -0.792281 0.313923 0.523205
-0.519907 0.854133 -0.0123787 -0.790345 -0.451626 0.41399 0.994274 0.0994274 0.0391684
-0.758853 -0.649703 -0.0450461 -0.771996 -0.571631 -0.277958 -0.395817 -0.918132 0.0190427
-0.108157 -0.973417 0.201894 0.375903 -0.884477 -0.276399 0.468316 -0.81339 -0.345075
-0.460938 0.784575 -0.414704 0.570948 0.741135 -0.353183 -0.572372 -0.803757 -0.162375
-0.662022 -0.165505 0.730982 0.820325 -0.392329 -0.416107 0.185374 0.98164 -0.0449392
--0.345809 0.912937 -0.216707 -0.95324 -0.300571 -0.0314884 -0.947779 -0.31749 -0.0302372
--0.0734306 -0.996558 0.0384637 -0.888005 -0.186481 -0.420323 -0.38819 -0.916742 0.094306
-0.549025 0.695432 0.463622 0.676753 -0.728811 0.104116 -0.717518 0.391374 0.576189
-0.585463 -0.712237 -0.387236 0.335432 0.934417 -0.119797 -0.371232 0.877457 0.303735
--0.662085 0.0827606 0.744845 0.848308 0.0614716 -0.525923 0.905197 -0.201155 -0.374372
--0.596285 -0.745356 0.298142 0.286282 -0.866402 -0.409134 0.135725 -0.841956 -0.522197
--0.616898 -0.663344 -0.423571 0.533046 -0.78434 -0.31729 0.637231 0.756711 -0.146032
--0.991192 0.052168 0.121725 0.384619 -0.915758 -0.115996 0.311161 -0.889033 -0.335857
--0.926151 -0.139271 -0.350498 0.98582 -0.167403 0.0116252 -0.938026 -0.343943 -0.0425586
--0.748222 -0.407409 0.523625 -0.670201 0.736762 0.0895131 0.75071 0.619153 0.230399
-0.48915 0.850043 -0.195342 0.504961 0.844554 -0.178164 -0.536778 0.782554 -0.315402
-0.688318 0.51766 -0.508179 0.294609 -0.922464 -0.249532 0.864722 0.502097 -0.0123975
-0.605492 0.749313 -0.268159 0.839586 0.529429 0.121658 0.217879 0.917911 -0.331615
-0.757777 0.277496 0.590568 0.864994 0.445953 0.230024 -0.388816 0.772288 -0.502388
-0.65577 0.733198 -0.179964 -0.415453 -0.127365 -0.900654 -0.314221 -0.287478 -0.904777
--0.449256 0.256718 -0.855725 0.106878 -0.299781 -0.948002 -0.267316 0.169883 -0.948515
-0.305573 -0.672644 -0.673925 -0.328982 -0.769959 -0.546749 -0.948924 -0.141738 -0.281875
-0.817136 -0.548751 -0.176527 -0.677952 -0.623459 -0.389462 0.685388 -0.292848 -0.666696
-0.838632 -0.00618156 -0.544664 0.843287 -0.130996 -0.521255 -0.204589 -0.7573 -0.620193
-0.357737 -0.829122 -0.429628 -0.638917 -0.610451 -0.468118 0.469127 0.69267 -0.547839
--0.268075 0.842522 -0.467217 -0.550732 -0.483631 -0.680291 0.826703 0.40761 -0.387836
-0.907922 -0.344613 -0.238578 0.0448372 -0.941581 -0.333788 -0.486454 -0.758296 -0.433993
-0.394619 -0.841407 -0.369202 -0.664798 -0.47826 -0.573857 0.276694 -0.122975 -0.953057
--0.883592 0.465557 -0.0502072 0.462115 -0.777194 -0.427106 0.603159 -0.356707 -0.713414
-0.820164 0.340068 -0.460092 0.952035 0.0115749 -0.30577 -0.0800304 0.98323 -0.163872
--0.814202 0.576286 0.0704937 0.282028 -0.568795 -0.772614 0.903205 0.418662 -0.0945708
-0.376086 0.621111 -0.687591 -0.637916 0.0609773 -0.767688 -0.57735 -0.57735 -0.57735
-0.276421 -0.900183 -0.336545 0.35853 -0.90913 -0.211988 0.30702 0.846952 -0.434063
--0.452599 -0.243188 -0.857912 -0.765682 -0.566025 -0.305526 0.66924 0.547077 -0.502816
--0.0733032 0.704525 -0.705883 -0.897898 -0.242961 -0.367082 0.770579 -0.597782 -0.221055
--0.311776 0.770271 -0.556307 0.541317 -0.589939 -0.599123 -0.485384 -0.654705 -0.579451
-0.467348 -0.233674 -0.852632 0.344958 0.936315 -0.0657063 0.905647 -0.416108 0.0815898
-0.204546 -0.920458 -0.333043 0.828805 -0.214514 -0.516784 0.493847 0.823079 -0.280457
-0.417315 -0.602789 -0.680069 -0.715093 -0.666336 -0.211277 -0.486664 -0.811107 -0.324443
--0.668648 -0.728751 -0.147754 -0.98481 -0.171271 -0.0285452 -0.583193 -0.770648 -0.256883
-0.724062 0.395093 -0.565363 0.431021 0.636194 -0.639905 0.453626 0.583736 -0.673406
-0.38199 -0.273335 -0.88282 -0.114376 0.564731 -0.817311 -0.620628 0.639645 -0.453514
--0.457017 0.888877 0.0321449 0.87115 0.195564 0.450391 -0.912988 0.300749 0.275687
-0.633054 -0.296257 -0.715174 0.571811 -0.62993 -0.525567 0 0.0634628 -0.997984
-0.649847 -0.361026 -0.668849 -0.781651 0.586238 -0.21295 -0.783687 0.391844 -0.481968
--0.898908 -0.437864 0.015454 0.714292 0.479267 -0.509989 -0.399538 -0.762754 -0.508503
--0.814241 -0.425626 -0.394784 0.3771 -0.627326 -0.681365 0.646204 -0.427328 -0.632307
--0.779839 -0.241456 -0.577538 -0.0748111 -0.654597 -0.752267 -0.176038 0.909527 -0.376525
-0.331348 0.649953 -0.683937 -0.0898383 -0.235826 -0.967634 -0.468896 -0.805914 -0.36144
-0.5891 0.0632205 -0.805583 -0.956807 -0.264417 -0.12085 -0.651873 0.641186 -0.404897
-0.00783244 -0.871638 -0.490087 0.156549 -0.834926 -0.527627 0.416594 -0.505777 -0.755407
--0.199523 -0.737045 -0.645721 0.278518 0.875341 -0.39523 -0.415601 0.373479 -0.82933
-0.857881 0.0504636 -0.511364 -0.19959 -0.471758 -0.858841 -0.0649442 -0.828039 -0.556897
-0.140919 -0.79407 -0.591265 0.517987 -0.426577 -0.741432 -0.527934 0 -0.849285
-0.901637 0.324026 -0.286458 -0.339653 -0.915176 -0.217 0.984734 -0.0364716 -0.170201
-0.885734 -0.207594 -0.415188 -0.858898 0.458079 0.229039 0.803824 -0.506112 -0.312598
--0.27654 -0.72098 -0.635384 0.0623288 -0.849938 -0.523184 -0.166814 -0.925299 -0.34058
-0.292642 -0.899488 -0.324473 -0.318389 -0.833989 -0.450655 -0.978475 -0.070904 -0.193804
--0.0285972 -0.972306 -0.231955 0.117531 -0.919095 -0.3761 -0.957871 -0.133723 -0.254168
--0.823829 -0.457683 -0.334414 0.398265 0.792466 -0.461933 0.428799 -0.227011 -0.874413
--0.170514 -0.882662 -0.437987 -0.309645 0.945233 0.103215 0.299377 0.94349 -0.142128
--0.686641 0.672336 0.276564 0.79082 0.39394 0.468417 0.198386 0.839325 0.506139
--0.599515 0.792319 0.113188 -0.505675 0.852423 0.13292 0.686569 0.473733 -0.551544
--0.317313 -0.463766 -0.827184 -0.885988 -0.437782 -0.152876 -0.462528 -0.886512 -0.012848
--0.895062 0.401235 -0.194616 0.978544 -0.144845 0.146529 -0.920899 0.327367 -0.211603
-0.872236 0.208885 -0.442234 0.262363 0.910983 -0.318237 0.856852 -0.509602 0.078169
-0.452362 0.876452 0.164924 0.258517 0.939418 -0.225084 -0.577073 -0.146094 -0.803519
-0.907065 -0.420878 0.00967536 -0.680325 0.255122 -0.687074 -0.0663093 0.582048 -0.810446
-0.241924 0.836654 -0.491408 -0.214169 0.938494 -0.270853 -0.510582 0.807553 -0.295235
--0.504783 -0.261739 -0.82261 0.188695 -0.677906 -0.71052 0.477558 -0.586803 -0.653911
--0.263785 -0.338687 -0.903166 -0.75132 0.0655221 -0.656677 0.727267 -0.595036 -0.342074
-0.126841 -0.692484 -0.710196 -0.89961 0.188291 -0.394015 0.971484 -0.139854 -0.191466
-0.937898 -0.346129 -0.0232614 -0.411939 0.56794 -0.712566 0.98726 0.13226 -0.088458
-0.84923 -0.36028 -0.386014 0.289955 -0.849693 -0.440395 -0.275267 -0.572488 -0.772324
--0.634616 0.0475962 -0.771361 -0.768179 0.303905 -0.563509 0.409018 -0.553643 -0.725385
--0.332772 -0.181342 -0.925407 0.972512 -0.230689 -0.0316632 -0.461936 0.14838 -0.874413
--0.41959 0.13741 -0.897253 0.525532 -0.586224 -0.616569 0.917388 -0.391152 -0.0734801
--0.786912 0.208901 -0.580629 0.946439 -0.259633 -0.191951 0.975783 0.118072 -0.184137
--0.0359614 0.471647 -0.881054 0.00288181 0.370312 -0.928903 -0.282292 0.341722 -0.896402
--0.530768 0 -0.847517 0.714956 -0.492864 -0.495906 0.257836 -0.699282 -0.666727
--0.389729 0.167027 -0.905656 -0.259181 0.610927 -0.74806 0.184859 0.0591548 -0.980983
--0.792411 -0.113653 -0.599307 -0.0431343 -0.197422 -0.979369 -0.533551 0.568348 -0.626342
--0.166914 -0.926267 -0.337888 -0.555622 -0.65112 -0.517037 -0.967191 -0.0541803 -0.248204
-0.355469 -0.823079 -0.442925 -0.443465 -0.518587 -0.731031 -0.962629 -0.172669 -0.208642
--0.897661 -0.368472 -0.241728 0.111658 -0.899335 -0.422764 -0.985853 0.131067 -0.104474
-0.84965 -0.515126 -0.112876 -0.31059 0.148658 -0.938848 -0.546689 -0.81886 -0.17493
-0.0932093 -0.0955993 -0.991046 0.873465 -0.11493 -0.473127 -0.570436 -0.371767 -0.732388
-0.709737 0.415677 -0.568758 -0.392645 -0.208593 -0.895722 0.867856 0.3632 -0.338986
-0.142514 0.0729142 -0.987103 0.837133 -0.107522 -0.536328 0.486846 -0.699546 -0.523084
-0.571804 0.507796 -0.644347 -0.324074 0.544199 -0.773837 0.587523 -0.587523 -0.556447
-0.988308 -0.0515375 -0.143497 0.917428 0.397619 0.0150234 -0.835169 -0.378436 -0.399098
-0.756881 -0.47434 -0.449592 0.557993 -0.557993 -0.614238 0.645238 -0.737415 -0.199717
--0.536173 -0.632409 -0.559086 -0.0521256 -0.79926 -0.598721 0.334866 -0.837718 -0.431384
-0.79371 0.163781 -0.585833 -0.655386 -0.573462 -0.491539 -0.865591 -0.0748042 -0.495132
-0.43624 -0.833989 -0.337872 -0.0930372 -0.868347 -0.487153 -0.227076 -0.866197 -0.445129
--0.221386 -0.854474 -0.469961 -0.381018 -0.847195 -0.37025 -0.570541 0.0691565 0.818352
-0.98138 -0.160694 -0.105216 -0.247 0.968627 0.0274444 -0.885824 0.420198 0.19685
--0.531494 0.341675 -0.775095 0.421847 0.888099 -0.182554 -0.0482555 0.965109 -0.257362
--0.942078 0.285478 -0.176045 0.583927 -0.237896 -0.776166 0.419812 0.257826 -0.87022
-0.35965 -0.0384092 -0.932296 0.799879 -0.131939 -0.585479 -0.56129 -0.799013 -0.215712
-0.725606 -0.0846922 -0.682878 -0.315342 -0.386549 -0.866683 -0.271599 -0.364468 -0.890728
--0.537244 -0.672859 -0.508556 -0.911339 0.0233079 0.410996 0.499059 -0.767783 -0.401807
-0.0522273 -0.377777 -0.924422 -0.117719 -0.375663 -0.919249 -0.181005 -0.837847 -0.515024
--0.158557 -0.372608 -0.914343 0.980312 -0.121694 -0.155498 -0.219502 -0.969891 0.105497
--0.903913 -0.18403 0.386102 -0.136131 -0.658635 -0.740046 0.227687 -0.607165 -0.761256
-0.0231565 -0.708202 -0.70563 0.348935 -0.747719 -0.564943 -0.147009 -0.65104 -0.744671
--0.42495 -0.459539 -0.779898 0.594258 0.556527 -0.580633 -0.325345 -0.945592 0.0025368
--0.188083 -0.442548 -0.876799 0.0850369 -0.357863 -0.929894 -0.389308 -0.448572 -0.804501
-0.670611 0.63708 0.380013 0.909109 0.37532 0.18071 -0.646918 -0.752538 0.123223
-0.255233 -0.478561 -0.84014 0.411 -0.135232 -0.901549 0.375551 -0.187775 -0.90758
--0.656132 -0.549009 -0.517764 -0.3431 -0.740116 -0.578369 -0.168283 -0.501845 -0.848429
-0.232733 0.806808 -0.543044 -0.114145 -0.984498 -0.133169 0.0698558 0.878187 0.47319
-0.960232 0.0751202 0.268908 0.511673 -0.473514 -0.71692 0.132824 -0.136849 -0.981647
--0.887468 -0.320718 -0.33097 0.193703 -0.830886 -0.52164 -0.903527 -0.172972 -0.392071
-0.658512 0.70729 -0.257104 -0.180472 0.789563 -0.586532 0.285217 0.918699 0.273208
-0.58228 0.804605 0.116456 -0.738717 -0.110808 0.664845 0.939025 -0.222655 0.262024
--0.464892 0.858465 0.216597 0.317284 -0.784144 -0.533339 0.135133 -0.713777 -0.687213
-0.199732 0.965371 -0.16783 -0.591054 -0.797923 0.118211 -0.895819 0.422518 -0.137792
--0.976474 0.205573 -0.0650983 -0.985232 0.168897 -0.0281495 0.830002 -0.536817 0.15141
-0.881484 0.336567 0.331224 -0.934465 -0.271554 -0.230288 0.493791 -0.841532 -0.219076
--0.714548 -0.519671 -0.468363 0.429581 -0.801884 -0.415261 0.437341 -0.799514 -0.411716
--0.968303 -0.162936 -0.189316 -0.0718217 -0.655373 -0.751883 0.103111 0.523737 -0.845617
-0.719326 -0.31275 -0.620288 -0.118581 0.783188 -0.610372 -0.500901 0.712981 -0.490669
-0.928063 -0.326783 -0.178641 -0.574786 -0.0334178 -0.817621 -0.35944 0.86132 -0.359069
--0.252345 -0.400784 -0.880735 -0.499005 0.483651 -0.719079 -0.210502 0.834124 -0.50983
--0.40673 0.777216 -0.480111 -0.00439597 0.84073 -0.541437 0.291792 0.827992 -0.478839
-0.302693 0.91365 -0.27133 -0.130404 0.891094 -0.43468 0.0603017 0.983449 -0.170855
--0.186761 -0.832641 -0.521373 -0.679514 -0.434134 -0.591429 0.420585 -0.723185 -0.547825
--0.245572 -0.0731492 -0.966614 -0.661545 0.340598 -0.668095 0.629657 -0.553173 -0.545465
--0.358405 -0.248571 -0.899866 0.891806 -0.452011 -0.0191974 -0.754601 0.0855841 -0.650578
-0.356064 -0.715145 -0.601486 0.995831 -0.0142262 -0.090099 -0.58215 0.429977 -0.690087
--0.724248 0.347639 -0.595493 -0.801478 0.281976 -0.527373 -0.779075 0.302749 -0.548985
--0.898627 0.149771 -0.412357 0.914188 -0.148247 -0.377205 0.992642 -0.0428094 0.113266
-0.0517198 -0.947414 -0.315805 -0.927056 0.0902244 -0.363905 -0.559794 -0.737206 -0.378363
--0.958316 -0.180477 -0.221494 -0.714704 -0.565303 -0.411863 0.646173 0.396238 -0.652269
-0.892075 0.079219 -0.444889 -0.800266 -0.561011 -0.211754 -0.996918 0.0657309 -0.0428246
--0.189974 -0.93027 -0.313859 0.290537 -0.646816 -0.705136 0.490444 -0.759708 -0.426975
-0.901897 0.167689 -0.398073 0.890305 0.39509 -0.22641 0.724946 -0.54371 -0.422885
-0.793386 -0.288132 -0.536207 -0.776237 -0.292262 -0.558605 0.976611 0.213166 0.0281372
-0.842339 0.304002 -0.445025 0.814105 0.306631 -0.493164 0.305038 0.0938579 -0.947704
-0.710796 -0.527646 -0.465143 0.374728 -0.498793 -0.781527 0.242357 -0.73988 -0.627568
--0.867817 0.0565968 -0.49365 0.726207 0.6205 -0.295979 0.927935 0.371065 -0.0353137
-0.652765 -0.293271 -0.698491 0.696431 -0.115888 -0.708204 -0.302605 0.048315 -0.951891
-0.520128 0.779495 -0.349076 0.488382 -0.586761 -0.645906 0.327712 -0.0121375 -0.9447
-0.457791 -0.3689 -0.808913 -0.00402853 -0.739235 -0.673436 0.868894 -0.408891 -0.278983
--0.641868 -0.421128 -0.640825 0.986782 0.150123 -0.0610255 -0.779776 -0.320574 -0.537756
-0.651451 -0.138391 -0.745962 -0.869597 0.0763549 -0.487823 0.710504 0.617323 -0.337781
-0.220767 -0.0229966 -0.975055 -0.0934787 -0.933175 -0.347053 0.0896729 -0.174364 -0.98059
-0.501089 -0.418718 -0.757354 0.172447 -0.172447 -0.969806 0.171111 -0.841528 -0.512397
-0.556848 -0.556848 -0.616312 0.180093 0 -0.98365 -0.244977 -0.792573 -0.558404
--0.269363 -0.778844 -0.566432 0.378509 -0.485634 -0.787966 0.286378 -0.266507 -0.920305
-0.217689 0.0473238 -0.97487 0.200596 -0.351042 -0.914621 -0.101472 -0.854825 -0.508898
-0.178932 -0.178932 -0.967454 -0.0207192 -0.361976 -0.931957 0.498923 -0.507459 -0.702539
-0.483004 -0.509034 -0.712455 0.76903 0.587655 0.251507 -0.301348 0.919499 0.252411
--0.0384775 -0.577162 -0.815723 0.082675 -0.277205 -0.957247 0.238274 -0.201616 -0.95004
--0.765755 -0.402021 -0.501995 -0.69594 -0.510917 -0.504609 -0.13824 -0.984957 0.10368
--0.502977 -0.863808 0.0291581 0.545883 -0.745784 0.381862 -0.953289 0.223045 0.203694
--0.850018 0.525734 0.032756 0.409694 -0.594898 -0.691554 -0.674859 -0.503077 0.539887
--0.0078526 -0.753849 -0.657001 0.737376 -0.63715 0.224315 -0.474709 -0.833032 0.284092
-0.279673 -0.619451 -0.733528 0.172541 -0.366033 -0.914467 0.157571 -0.0555251 -0.985945
-0 0.320807 -0.947145 -0.113267 -0.550789 -0.826923 -0.258576 -0.430959 -0.86453
--0.347626 -0.61694 -0.706075 -0.394927 0.668337 0.630364 0.862274 0.485029 -0.145708
-0.210028 0.977087 0.0344973 -0.499032 0.738152 0.453981 -0.786821 0.236416 0.570106
-0.695176 0.283864 -0.660417 -0.176292 0.557082 -0.81153 -0.534678 -0.0379013 -0.844205
-0 -0.542159 -0.840276 -0.302755 -0.513602 -0.802841 -0.291386 -0.388514 -0.874157
-0.278614 -0.767009 -0.577989 -0.228 -0.182875 -0.956333 -0.754886 -0.310732 -0.577575
-0.269663 -0.910112 0.314607 0.833897 -0.551655 -0.0171056 -0.727183 -0.650326 0.219731
-0.930932 0.241584 -0.273865 -0.529984 0.711485 0.461417 -0.849591 0 0.527442
--0.230759 0 0.973011 0.0269059 0.666241 0.745251 -0.281486 0.910101 0.304109
--0.327088 -0.727603 -0.602998 -0.0227522 -0.712902 -0.700894 0.66698 -0.618231 -0.415847
-0.478994 -0.319329 -0.817676 -0.427317 -0.0899615 -0.899615 -0.0149172 -0.615334 -0.788125
-0.0405642 -0.699732 -0.713253 0.329685 0.576949 -0.747287 -0.29226 0.670479 -0.68194
--0.0274813 -0.659552 -0.751156 -0.135381 -0.631778 -0.763235 -0.185869 -0.430745 -0.883126
--0.888935 -0.146262 -0.434054 0.968516 0.0131871 0.248601 0.562413 -0.788051 -0.250335
--0.161129 -0.986917 -0.00559477 -0.547542 -0.752558 0.365861 0.74427 0.0636547 0.664838
--0.488658 0.730359 0.477273 0.614369 -0.78882 -0.0176979 -0.570599 -0.570599 -0.59062
--0.380847 -0.914032 -0.139644 0.861457 -0.267811 -0.431473 -0.909721 0.1077 -0.40101
--0.128373 -0.826398 -0.548258 0.714629 -0.691576 0.105017 -0.0867184 -0.552259 0.82915
--0.997986 0.0608753 0.0178322 0.459158 -0.880053 0.121167 0.313637 -0.947183 0.0669092
--0.357703 -0.933826 0.00422068 0.561474 -0.827436 -0.00985042 0.911792 -0.293076 -0.287649
-0.102258 0.2876 0.952276 0.641782 -0.187839 0.743527 -0.586427 -0.662095 -0.466619
--0.970237 -0.222192 -0.0962831 0.213508 0.781899 0.585703 0.713906 0.695119 0.0845415
--0.381851 0.575194 0.723423 -0.309021 0.0457809 0.949953 -0.393099 0.48295 -0.782453
-0.634537 -0.625066 0.454594 0.953295 -0.120956 0.276763 0.873406 0.291135 0.390386
--0.280131 0.931437 0.232276 0.204539 0.562482 0.801111 -0.097859 0.831801 -0.546379
-0.907674 0 -0.419677 0.819948 0.571479 -0.0331292 -0.720129 -0.49272 0.488509
--0.537713 -0.778958 0.322628 0.668143 -0.348287 0.657481 -0.687771 0.723042 0.0646623
--0.0484929 0.994104 0.0969857 0.808223 -0.528712 -0.259305 -0.791052 0.566536 -0.230811
-0.752408 -0.165439 0.637583 -0.824815 -0.045823 0.563543 -0.940138 -0.197126 0.277998
-0.772106 -0.292395 -0.564231 0.667928 0.742142 -0.0556606 -0.836563 0.497088 0.230358
-0.186484 -0.959063 -0.213125 0.0693341 -0.990487 -0.118858 0.472632 0.836734 0.276577
--0.0268747 -0.698743 -0.714868 0.924193 -0.370082 0.0943742 -0.969623 -0.102912 0.221904
-0.248282 -0.910366 0.331042 0.948932 -0.199775 -0.24417 -0.365232 0.896478 -0.250866
--0.738858 -0.577498 -0.347254 -0.693041 -0.713791 -0.100982 -0.624894 -0.621727 -0.472189
-0.695174 -0.695174 -0.18294 -0.991053 -0.125374 -0.0457715 0.58828 -0.788073 -0.181294
--0.595792 -0.746726 -0.295689 -0.759902 -0.597864 -0.255163 0.591665 0.792456 -0.148139
--0.137568 -0.792204 -0.594548 -0.176128 -0.401005 -0.898985 0.393653 -0.719251 -0.572465
-0.55508 -0.80699 -0.201625 -0.0898359 0.285728 -0.954091 0.0976536 -0.19194 -0.976536
-0.427482 -0.61799 -0.659809 0.578262 -0.813487 -0.0620733 -0.255468 -0.271109 -0.928028
--0.523024 0.156704 -0.837789 0.683384 -0.416816 -0.599375 -0.395116 0.531363 -0.749358
--0.301731 0.484682 -0.821001 0.845864 -0.510983 -0.153006 0.819229 -0.569405 0.0681339
-0.709237 0.164138 -0.685596 0.207528 0.6127 -0.762581 0.923431 -0.310708 -0.225245
--0.162754 0.787458 -0.594492 0.652019 0.0197582 -0.757945 0.768873 -0.253047 -0.587198
--0.621695 0.321359 -0.714299 0.591213 -0.564986 -0.57555 -0.160851 0.0419611 -0.986086
-0.628373 -0.265136 -0.731334 0.729737 -0.367285 -0.576702 0.112827 -0.126101 -0.98558
--0.664376 0.408847 -0.625659 -0.410122 0.31638 -0.855397 -0.337348 0.363297 -0.868454
-0.685398 -0.602109 -0.409504 -0.697605 0.379467 -0.607743 -0.0654955 -0.688832 -0.721956
--0.871567 -0.0234853 -0.489713 0.670593 -0.741681 -0.0146125 -0.865168 0.146297 -0.479668
--0.8769 0.10167 -0.469798 -0.847356 -0.194703 -0.494043 -0.829636 0.173678 -0.530603
--0.901618 -0.0424442 -0.430445 -0.886804 -0.0928051 -0.452732 -0.811178 -0.0201535 -0.584451
--0.85455 0.278911 -0.438125 -0.661704 0.676585 -0.323081 -0.429258 -0.520739 -0.737949
--0.422608 -0.808144 -0.410251 -0.777924 0.0138915 -0.628205 -0.868429 0.0315543 -0.494808
--0.761754 -0.364631 -0.535514 0.807114 -0.417473 -0.417473 -0.609969 -0.738179 -0.288149
--0.949876 -0.0166645 -0.312182 -0.959867 0.157535 -0.232029 0.883655 -0.294552 -0.363858
--0.758329 -0.262279 -0.59678 -0.711843 -0.4919 -0.501312 -0.153665 -0.881345 -0.446786
-0.652715 -0.141231 -0.744324 -0.298263 -0.742896 -0.599287 -0.894969 0.444145 -0.0420212
--0.424483 -0.849683 -0.312815 -0.0522991 -0.780217 -0.623319 0.73675 -0.0437674 -0.674747
-0.845535 0.431687 -0.314192 -0.801317 0.489281 -0.34423 -0.927278 0.161833 -0.337588
-0.754098 0.324301 -0.571109 0.756034 0.574219 -0.314142 -0.459049 -0.86686 -0.194495
-0.776158 -0.0757228 -0.625975 -0.960802 0.277236 0 -0.725056 -0.28665 -0.6262
-0.717335 -0.531622 -0.450343 -0.812963 -0.0150549 -0.582121 -0.792509 -0.074795 -0.605256
--0.644503 -0.245979 -0.723954 -0.565292 0.0699885 -0.821916 -0.480075 -0.801048 -0.357561
-0.508248 -0.512954 -0.691782 -0.871898 -0.272468 -0.406886 0.520541 -0.362801 -0.772924
-0.522675 -0.441918 -0.729053 -0.662861 -0.628622 -0.406755 -0.758493 -0.204926 -0.618623
--0.537976 -0.37459 -0.755158 0.932353 0.346853 -0.10203 -0.816905 -0.00464811 -0.576753
--0.383825 0.119945 -0.915583 -0.292393 -0.247722 -0.923656 -0.475811 -0.254623 -0.841885
-0.943693 0.321587 0.0776246 -0.0446794 -0.854494 -0.517537 0.238988 0.942297 0.234436
--0.780142 0.61709 0.102848 0.825891 -0.560899 0.0574149 0.0991213 0.429526 0.897598
--0.964809 -0.244802 0.0960009 0.411222 -0.712785 -0.568185 0.242342 -0.693802 -0.678167
--0.163558 -0.906226 -0.389877 0.260388 -0.698313 -0.666751 -0.564163 -0.57856 -0.589057
--0.00563318 0.9982 0.0597117 -0.996706 -0.0699794 -0.0409879 -0.368071 0.926019 -0.0837409
-0.21344 -0.649488 -0.729801 -0.420871 -0.899368 -0.118338 0.97701 0.212449 -0.0178101
-0.214514 -0.477185 -0.85222 0.0847024 -0.0889375 -0.992429 -0.450341 -0.378696 -0.808568
--0.172528 -0.73739 -0.653062 -0.80767 -0.560697 0.182449 -0.302778 0.43692 -0.847011
--0.29517 -0.361763 -0.884309 -0.716899 0.109357 -0.688547 -0.00174721 -0.676172 -0.736742
-0.111441 0.984393 0.136205 0.677331 0.727815 -0.107279 0.523706 0.851896 -0.00232758
--0.55464 0.741248 0.378054 -0.961 0.0864778 0.262681 0.572965 -0.791734 -0.211823
--0.625792 -0.727271 -0.281888 -0.366019 -0.524073 -0.76901 0.299987 -0.784325 -0.542994
-0.0899026 -0.70124 -0.707234 -0.726774 -0.34349 -0.594823 -0.540466 -0.493469 -0.681458
--0.100363 -0.451634 -0.886541 0.908532 0.345828 -0.23446 -0.889587 -0.167233 0.425051
-0.111754 -0.621633 -0.775295 -0.349217 -0.133035 -0.92755 0.236301 0.843931 0.481603
-0.512517 0.772843 0.374219 -0.999969 -0.00476176 0.00634901 0.567379 -0.756505 -0.32524
--0.532288 -0.846394 -0.0169279 -0.476215 -0.878352 -0.0414483 0.632215 0.12772 0.764193
--0.0429579 0.948003 0.31535 0.956566 -0.206483 -0.205781 0.873818 0.484142 -0.0452653
--0.636874 0.770953 0.00474862 -0.506477 0.569787 -0.647166 -0.0814436 -0.977323 0.195465
--0.141925 -0.978539 -0.149395 0.415453 -0.909612 0.00232467 0.9282 -0.330592 0.170745
-0.882775 0.396348 0.252222 -0.809829 0.583077 0.0647864 -0.910695 0.395136 0.120423
-0.862701 0.38634 0.326326 0.988963 -0.0830152 0.122718 0.381722 0.819996 0.426492
--0.702105 0.706334 0.0902303 -0.635553 -0.566701 -0.524331 0.188958 0.6771 0.711218
-0.93302 0.0222148 0.359139 0.675939 -0.692629 0.251739 -0.72403 0.686661 0.0653963
--0.915396 0.349515 0.199723 -0.48367 -0.860083 -0.162235 0.862666 0.342529 0.37213
--0.851916 0.523678 -0.000835212 0.808312 -0.5819 0.0895773 0.618689 -0.471382 0.628509
--0.749072 0.650357 0.1262 0.10313 0.980641 0.166456 0.682158 -0.731202 -0.00222927
--0.951088 -0.118595 -0.285249 0.77083 -0.632254 0.0779491 0.211129 0.889759 0.404664
--0.542737 0.839349 0.0305026 0.789355 -0.612946 -0.0348831 -0.802624 -0.526311 -0.280699
-0.696452 -0.712102 -0.0886867 -0.972939 -0.023615 -0.229853 -0.531443 0.77455 0.342988
-0.590401 -0.801961 -0.0910202 0.868927 0.463428 -0.173785 0.981048 -0.151578 -0.120701
--0.80975 0.563304 -0.164297 0.649936 -0.747776 -0.135695 -0.919676 -0.326727 -0.217818
-0.832367 -0.542793 -0.111985 -0.887132 -0.3314 -0.321203 -0.919632 0.386829 -0.0681209
--0.918796 0.350723 0.181125 0.186736 -0.982362 0.00968799 -0.859083 0.501132 0.104131
--0.961772 0.225352 0.1556 0.277818 -0.884901 -0.373854 0.662087 -0.735246 -0.145098
--0.650969 -0.754723 -0.0814409 -0.647192 -0.616373 -0.448583 0.804875 -0.593398 -0.00736487
-0.120998 0.992372 0.0236056 -0.193053 0.978683 0.0700657 -0.676753 0.104116 -0.728811
--0.239465 -0.810878 -0.533979 -0.580163 0.463296 -0.669901 -0.60503 0.537085 -0.587774
--0.518402 0.439682 -0.733443 -0.562085 0.436355 -0.702606 -0.608176 0.351391 -0.711791
--0.683912 0.254025 -0.683912 -0.479149 0.199326 -0.854801 -0.272635 0.576555 -0.77023
--0.215907 0.663423 -0.716418 -0.394579 0.506252 -0.766823 -0.406585 0.609878 -0.680248
-0.297571 0.732482 -0.612309 -0.0874499 0.911977 -0.400812 -0.522842 0.692766 -0.4967
--0.814067 0.323509 -0.482323 0.826154 -0.56344 0.00224542 -0.489245 0.462437 -0.739453
-0.77798 -0.430456 -0.457661 -0.566856 0.474453 -0.673475 -0.708262 0.397687 -0.583275
-0.806212 -0.58939 0.0514062 -0.817192 0.498769 -0.288835 -0.679102 0.469527 -0.564239
--0.773952 0.348278 -0.528867 -0.910986 0.0700759 -0.40644 -0.978773 -0.13328 -0.155691
--0.78692 0.041236 -0.615676 0.955127 -0.267503 0.127183 -0.70305 0.212241 -0.67873
--0.572229 0.171218 -0.802022 -0.407421 0 -0.913241 -0.531609 -0.182043 -0.827195
--0.770144 0.0738629 -0.633579 -0.823196 -0.00460744 -0.567739 -0.800541 0.198299 -0.56552
--0.464681 0.52922 -0.709929 -0.445637 0.728326 -0.520527 -0.844319 0.360537 -0.396407
--0.803115 -0.473484 -0.361689 -0.760715 -0.41624 -0.498053 -0.900008 0.133334 -0.414979
-0.525763 -0.126183 -0.84122 -0.747258 0.161173 -0.644693 -0.551081 -0.76919 -0.323507
--0.572163 -0.754913 -0.320525 -0.897505 -0.110123 -0.427034 0.742705 -0.553222 -0.377274
--0.167768 -0.894763 -0.413828 0.59585 -0.546195 -0.588756 -0.554865 -0.615994 -0.559175
--0.566758 -0.775831 -0.277257 -0.204349 -0.819952 -0.534714 0.666597 -0.367943 -0.64828
-0.812309 0.445752 -0.376111 -0.420328 -0.754858 -0.503501 0.492021 0.00531915 -0.870567
-0.852066 0.41589 -0.317834 0.792062 0.517678 -0.323493 0.593697 -0.521295 -0.613005
--0.705055 -0.236478 -0.668562 -0.620622 0.404258 -0.671866 -0.822447 0.568842 0
-0.11671 0.729157 -0.674322 -0.331979 0.799635 -0.500373 -0.803889 0.500019 -0.322092
-0.798379 -0.0523527 -0.599875 0.369866 0.156217 -0.915858 -0.619742 0.236812 -0.748225
-0.147107 0.249524 -0.95713 -0.94483 -0.181092 -0.272951 0.797186 -0.028269 -0.603072
-0.656777 -0.402486 -0.637691 0.314249 -0.196992 -0.928677 0.42417 -0.24661 -0.871357
--0.3767 0.219742 -0.899895 0.149819 -0.301842 -0.941512 -0.636536 -0.642656 -0.426397
-0.392456 -0.364706 -0.844374 0.453076 -0.372224 -0.810044 -0.601956 -0.566373 -0.562913
--0.769846 -0.60387 -0.206587 -0.648616 -0.253806 -0.717551 -0.482492 0.516685 -0.707275
-0.579276 -0.177645 -0.795539 -0.416049 0.462771 -0.782781 -0.664953 0.31518 -0.677125
--0.309773 -0.937782 -0.156861 -0.28769 -0.939543 -0.185724 -0.654088 -0.735849 -0.175202
-0.821154 0.186192 -0.539479 -0.743262 -0.408794 -0.529574 0.532575 -0.282284 -0.797922
--0.264237 -0.397348 -0.878802 0.0706018 -0.600115 -0.796792 -0.778534 -0.257697 -0.572256
--0.0263625 -0.254837 -0.966624 0.156417 -0.449142 -0.879662 -0.72083 -0.511382 -0.46786
--0.449142 -0.156417 -0.879662 -0.55333 0.166757 -0.816099 -0.372586 -0.62904 -0.682267
--0.165314 -0.521468 -0.837104 -0.0278004 -0.185336 -0.982282 -0.2608 0.587367 -0.766148
-0.411074 -0.88683 -0.211069 0 0.211055 -0.977474 0.40504 0.495825 -0.76818
-0.272106 0.705253 -0.654658 0.880827 0.463391 0.0970186 -0.901997 0.43139 -0.0174299
--0.100298 0.254602 -0.961831 0.712622 -0.698888 0.0610383 -0.762781 -0.642749 0.0709864
-0.542105 -0.496929 -0.677631 -0.506658 -0.608718 -0.610541 -0.1159 -0.321207 -0.93989
-0.477504 0.187591 -0.85837 0.384429 -0.242307 -0.890787 0.598357 -0.295391 -0.74479
--0.294199 -0.501868 -0.813373 0.663932 0.165983 -0.729139 0.814149 0.32566 -0.480736
--0.721139 -0.655581 -0.22399 0.247493 -0.489361 0.836226 0.87133 -0.483522 -0.0836124
--0.163022 0.984484 -0.0649265 -0.905469 0.347303 0.243939 -0.847847 0.520966 0.0987452
-0.292962 -0.404503 -0.866343 0.0265558 -0.68455 -0.728482 0 -0.73366 -0.679517
--0.26173 -0.628348 -0.732582 -0.00576413 -0.201744 -0.979421 0.782567 -0.146079 -0.605185
-0.677627 -0.511417 -0.528464 0.53679 -0.84314 -0.0311772 0.00518468 -0.995459 0.0950525
--0.18027 -0.755749 -0.62956 0.131033 -0.512738 -0.848487 0 -0.263428 -0.964679
-0.0960711 -0.148345 -0.984258 0.242487 -0.664796 -0.706573 -0.196046 -0.844506 -0.498373
-0.125768 -0.440786 -0.888758 -0.244309 -0.745455 -0.620169 -0.228088 -0.740599 -0.632051
--0.122469 0.35652 -0.926226 0.257634 -0.434757 -0.862908 0.00588786 -0.812524 -0.582898
--0.25625 -0.318246 -0.912719 0.02465 0 -0.999696 0.686449 0.171612 -0.706638
--0.77205 0.353728 -0.528029 0.409933 -0.625121 -0.664213 0.471881 -0.434815 -0.766984
--0.0935671 -0.340244 -0.935671 0.13288 0 -0.991132 0.225659 0.0569847 -0.972538
-0.166533 -0.313345 -0.934923 0.463903 -0.746279 -0.477349 -0.807694 0.472775 -0.352298
-0.616546 0.784695 0.0642236 0.0344266 -0.496727 -0.867224 0.226224 -0.690792 -0.686752
-0.00989547 -0.951202 -0.308409 -0.668022 -0.276926 -0.690694 0.255987 0.252662 0.933077
-0.455952 0.237345 0.857773 -0.265447 0.245028 0.932469 -0.0574943 0.767959 0.637913
-0.904957 -0.0530101 0.422187 0.654389 0.75029 0.0940213 0.150119 -0.850672 -0.503807
-0.34337 0.587598 0.732684 0.0545363 -0.96711 0.248443 -0.830342 0.556603 0.0269394
-0.674611 0.732767 0.0891727 0.819487 0.569374 0.0652255 0.891889 -0.445384 -0.0785311
--0.482966 -0.0817328 -0.871816 -0.975184 -0.0872116 0.203494 -0.0860946 0.941769 0.325051
-0.805688 -0.591934 0.0219235 0.343258 0.86368 0.369094 -0.966533 0.250162 0.0568549
-0.591278 0.743866 0.311534 0.743494 0.650557 0.154895 0.943002 0.189716 -0.273415
-0.874134 -0.277382 -0.398683 0.67779 -0.550704 -0.487161 0.33154 0.754817 0.565979
-0.626842 -0.676591 0.386386 -0.598319 0.800793 0.0272997 0 -0.871576 -0.490261
-0.0722282 -0.967055 -0.244105 -0.139767 -0.941485 -0.306711 0.828475 0.555684 -0.0696009
-0.903477 -0.424268 -0.0610457 -0.954305 0.183792 -0.235631 -0.946472 -0.165543 -0.277104
-0.62114 0.763484 0.176852 -0.669754 0.740255 0.0587504 -0.827886 0.454002 -0.329374
-0.854212 -0.51096 0.0961315 0.763126 0.457875 0.456058 -0.639139 0.768489 0.0304352
--0.726498 0.687076 -0.0112635 0.827618 -0.529078 0.187416 -0.0556839 0.997249 0.0489344
-0.238792 0.878661 0.413442 -0.898035 0.436249 -0.0567479 0.0794507 -0.979177 -0.186817
-0.477464 -0.878192 -0.0284204 0.248372 -0.931394 0.266113 -0.953889 -0.0260367 -0.299027
-0.065624 -0.976008 -0.20761 -0.4787 -0.656139 -0.583376 0.793964 -0.53758 -0.283952
-0.870715 -0.477104 -0.119276 -0.904923 0.3541 -0.236067 0.971278 -0.182912 0.152191
-0.823809 -0.566067 0.03011 0.796188 -0.60419 0.0322235 -0.974865 -0.162277 -0.152661
-0.970984 0.192592 0.141769 0.931307 0.347631 -0.108724 -0.205526 0.976251 0.0685088
--0.798314 -0.434083 0.417452 -0.417846 -0.473559 -0.775337 0.78154 -0.623635 -0.0165593
-0.828034 -0.520319 -0.208873 -0.473877 -0.880563 -0.00707279 -0.745437 -0.64853 0.154057
-0.550147 -0.696653 -0.460449 -0.926113 0.356864 -0.122326 -0.863385 0.400411 -0.306981
--0.864079 0.29614 -0.407023 0.347919 -0.748956 -0.56393 0.167435 -0.771399 -0.61393
--0.879002 0.355188 0.318115 -0.536021 -0.716349 -0.446684 0.645486 -0.761253 -0.0619761
-0.403714 -0.847329 -0.345034 -0.246641 -0.44043 -0.863243 -0.693521 0.709105 -0.127275
--0.825708 -0.324556 -0.461378 0.982818 0.0530375 -0.176792 0.746583 -0.584152 -0.318403
--0.510715 -0.2293 -0.828608 0.906152 0.247132 -0.34324 0.122792 -0.960899 -0.248184
-0.310242 0.916184 0.253688 -0.708175 -0.465174 -0.531132 0.978202 -0.145819 -0.147844
--0.945683 0.282989 -0.160002 -0.494376 -0.861905 -0.112752 -0.539 -0.842296 0.00404395
-0.449857 0.878736 -0.159535 0.528707 0.827357 0.189603 0.537905 0.815755 0.212607
-0.064815 0.914355 0.399693 0.0703927 0.240253 0.968155 0.493916 0.631321 0.597898
--0.61754 -0.782218 -0.0823387 -0.810859 0.548522 -0.20404 -0.36257 0.611997 -0.702854
--0.778382 0.555209 -0.293027 -0.353858 0.234048 -0.905542 -0.697202 0.312684 -0.645088
--0.3748 0.3748 -0.847968 0.0431331 0.539164 -0.841096 -0.116571 0.657874 -0.744052
--0.249592 0.660891 -0.707762 0.0597491 0.336768 -0.93969 -0.577712 0.659838 -0.480483
--0.60388 0.530683 -0.594731 -0.150688 0.539966 -0.828088 -0.369478 -0.383689 -0.846326
--0.707931 0.353966 -0.611181 -0.306082 0.83371 -0.459609 -0.465637 0.456639 -0.758066
-0.153931 0.262965 -0.952447 0.213066 0.319599 -0.923287 -0.309679 0.424909 -0.850618
--0.0362285 -0.00905712 -0.999303 -0.771425 0.115714 -0.625711 -0.810519 0.0457551 -0.583922
--0.451093 0.663373 -0.597035 -0.312808 0.904909 -0.288603 -0.799353 0.583714 -0.14252
--0.593688 -0.604582 -0.531051 -0.716216 -0.648564 -0.257681 0.389333 -0.449012 -0.804243
-0.574993 0.146991 -0.804846 -0.631734 -0.539535 -0.556609 0.696127 0.126568 -0.706674
--0.661887 0.625641 -0.412891 0.134114 -0.560673 -0.817104 0.833614 0 -0.552348
--0.890851 0.234503 -0.389092 -0.912051 -0.343773 -0.223569 -0.879735 -0.149288 -0.45142
-0.516374 0.344249 -0.784124 -0.539225 -0.644543 -0.542034 -0.555452 -0.336169 -0.760567
--0.551223 0.045306 -0.833127 0.344184 -0.251519 -0.904586 -0.379469 0.236316 -0.894516
--0.0505197 0.523332 -0.85063 -0.428999 0.712708 -0.554983 -0.423668 0.738436 -0.524612
-0.414105 -0.164673 -0.895209 -0.699193 0 -0.714933 -0.503052 0.220748 -0.835589
--0.193854 0.693313 -0.694073 -0.749304 -0.194264 -0.633092 -0.559887 0.352447 -0.749872
-0.121946 0.858652 -0.497842 -0.782248 -0.349631 -0.515603 0.913806 -0.214453 -0.344917
--0.997963 0 -0.0637986 -0.934474 0.254436 -0.249039 -0.970636 0.23386 -0.0563426
--0.615577 -0.685302 -0.389135 -0.560925 -0.362052 -0.744501 0.307347 -0.53607 -0.786236
--0.669301 0 -0.742992 0.401257 -0.517128 -0.756023 0.395116 -0.531363 -0.749358
--0.632136 -0.102429 -0.768058 0.805925 -0.0215323 -0.591627 0.519204 -0.705333 -0.482631
--0.672804 -0.067374 -0.736747 0.553892 0.568681 -0.608116 -0.71218 0.0727614 -0.698216
--0.363524 -0.813978 -0.453088 0.561699 -0.27675 -0.779682 0.404642 -0.617612 -0.674404
-0.542029 -0.496095 -0.678302 0.17444 -0.0847279 -0.981016 -0.570814 -0.32865 -0.752436
--0.303507 0.360772 -0.881888 -0.410297 -0.776689 -0.477923 0.407867 -0.210306 -0.888491
-0.372813 0.135367 -0.917979 -0.317082 0.018119 -0.948225 -0.831034 0.0494128 -0.554023
-0.55003 -0.523838 -0.650432 -0.305021 -0.570503 -0.762554 -0.833039 -0.183966 -0.521731
--0.421117 -0.197667 -0.885205 -0.902386 -0.374105 -0.213882 -0.347955 -0.665913 -0.659914
--0.960518 -0.274434 -0.0457389 -0.968183 -0.212205 0.132628 0.238512 -0.0226325 -0.970876
-0.422694 -0.422694 -0.801661 0.380996 -0.627881 -0.678681 -0.864546 -0.364306 0.346181
--0.330467 -0.165233 -0.929241 -0.290911 -0.661823 -0.690914 0.0875772 -0.860865 -0.50124
-0.683175 -0.704524 -0.192143 -0.564599 -0.793711 0.226385 0 0.175069 -0.984556
--0.37607 -0.75214 -0.541162 -0.455337 -0.610873 -0.64769 -0.578046 -0.611896 -0.539857
--0.454739 0 -0.890625 0.321236 0.470648 -0.821766 0.309639 0.379102 -0.872012
--0.174146 0.245853 -0.953535 0.270138 -0.433858 -0.85953 0.0202675 0.668827 -0.743141
-0.0359715 0.373359 -0.926989 -0.315727 -0.315727 -0.894781 -0.380819 -0.635748 -0.671417
--0.423972 0.527501 -0.7362 -0.641047 -0.166119 -0.749308 -0.54974 -0.66345 -0.507562
--0.87643 -0.316259 -0.363112 0.256253 -0.169224 -0.951682 -0.82949 -0.49722 -0.254398
-0.660376 -0.23983 -0.711607 -0.115367 -0.195076 -0.973979 0.00509622 -0.225508 -0.974228
--0.23051 -0.669224 -0.706403 -0.501724 -0.666412 -0.551514 0.495783 -0.452462 -0.741268
-0.156365 -0.721412 -0.674621 -0.133386 -0.306152 -0.942592 -0.356597 -0.662251 -0.658986
-0.735799 0.674674 -0.0584333 -0.63828 0.760538 -0.119082 -0.172447 -0.172447 -0.969806
--0.492528 -0.379489 -0.783201 0.325622 0.842744 -0.428664 0.107415 0.747668 -0.655328
--0.81243 -0.183011 -0.553593 -0.983947 -0.178461 0 -0.172447 -0.172447 -0.969806
-0.082675 -0.277205 -0.957247 -0.14805 -0.345451 -0.926685 0.536267 0.701781 -0.468958
-0.312591 0.842878 -0.437999 -0.0678658 0.729558 -0.680544 -0.83351 -0.176319 -0.523615
--0.0240081 -0.970826 0.23858 -0.976271 -0.21639 0.00838721 0.121592 -0.688336 -0.715128
-0.253107 -0.523776 -0.813385 -0.221956 -0.635875 -0.739188 -0.0115213 -0.724692 -0.688976
-0.386263 0.920088 -0.0651006 0.222209 0.96929 -0.105358 -0.0538851 0.948377 -0.312533
--0.515738 0.055012 -0.854979 -0.427164 -0.768895 -0.475743 0.872329 -0.187977 -0.45134
--0.696362 0.666457 -0.266298 0.378509 -0.485634 -0.787966 -0.135512 -0.597534 -0.79031
--0.12771 -0.989754 -0.0638551 -0.14718 -0.987332 -0.0592808 -0.18581 -0.854396 -0.485264
-0.170756 -0.282894 -0.943829 -0.260393 -0.791765 -0.552542 -0.388232 0.522619 0.759042
-0.638935 -0.0418974 0.768119 -0.537887 0.758559 0.367786 0.00162546 -0.831423 -0.555637
-0.697849 0.536807 -0.474179 0.509548 -0.774121 0.375629 0.502088 -0.793742 -0.343339
-0.761545 -0.598772 -0.248035 0.718602 -0.617745 -0.319378 -0.655845 -0.139119 -0.741966
--0.526761 -0.325527 -0.78521 -0.760006 0.313617 -0.569241 0.792057 0.243343 0.559848
-0.27298 0.961115 0.0417052 -0.135909 0.96431 0.227235 -0.455563 0.754413 0.472571
-0.0211604 0.921441 -0.387941 -0.545395 0.253523 -0.798918 -0.807688 -0.264334 -0.527037
--0.401322 0.825934 0.395947 0.974495 -0.0417342 0.220496 0.984002 -0.127601 0.124329
-0.689761 0.720147 0.074952 0.398757 0.806309 0.436873 0.399496 0.559294 0.726356
-0.105949 0.994286 -0.0130398 0.676602 0.67255 0.299811 -0.109824 0.93223 -0.344797
--0.850381 -0.390716 -0.35241 0.274537 0.137269 0.951728 0.747409 0 0.664364
-0.944553 0.280813 -0.17019 -0.691431 -0.718024 -0.0797805 0.412394 -0.830269 0.374945
-0.0349829 -0.988267 0.148677 -0.17372 -0.978318 0.112766 -0.550285 -0.822469 -0.143981
-0.597449 0.74922 0.285876 0.700209 -0.65902 0.274592 -0.284758 0.801629 0.525646
--0.542715 -0.50395 0.671933 0.934404 -0.0133486 -0.355964 -0.610997 -0.73741 -0.287941
-0.936698 0.342018 -0.0749769 0.852352 -0.437889 -0.285919 -0.499767 0.866067 -0.0126647
--0.971465 0.124172 0.202084 0.603574 0.720053 0.342378 0.888564 -0.458445 -0.0167852
-0.955239 -0.114 0.272988 -0.278246 0.924176 0.261684 0.348285 0.868507 0.352693
--0.375022 0.912919 0.16105 -0.6494 -0.684822 -0.330604 0.754167 -0.270397 -0.598429
--0.16011 -0.936841 -0.310957 -0.564127 -0.798593 -0.209785 -0.838848 0.522174 0.153845
-0.509181 -0.86066 -0.000343577 0.56089 -0.820125 0.113121 -0.749457 0.356538 0.557848
-0.757747 -0.652537 0.00394044 -0.855023 0.510462 0.0914577 0.317331 -0.769286 0.554527
--0.641643 0.641643 0.420224 0.706267 -0.462727 -0.535789 -0.0413064 -0.888088 -0.457813
--0.275058 -0.933038 0.231911 -0.854788 -0.518817 0.012922 0.153124 -0.922995 -0.353035
-0.577741 -0.812855 -0.0740391 0.396683 -0.895789 0.200509 0.70818 -0.682192 0.181918
-0.428481 -0.895219 0.122423 -0.476731 0.800909 0.362316 -0.473672 0.879163 -0.0520321
-0.258292 0.926072 0.275092 0.25796 -0.51592 -0.816874 -0.742338 0.652228 -0.153402
--0.631057 0.308815 -0.711618 0.759959 -0.643043 0.094647 -0.43105 0.826179 -0.3628
-0.781053 -0.574353 -0.245103 0.325906 -0.422797 -0.845593 -0.145221 -0.875773 -0.460361
--0.250892 -0.802855 -0.540812 0.972572 -0.0342254 -0.230071 0.25179 -0.795428 -0.551268
--0.129511 -0.647553 -0.750934 0.485874 -0.85679 -0.172735 -0.682432 -0.554476 -0.476281
-0.944536 0.277064 0.176313 -0.862268 0.22419 0.454128 -0.964739 0.0639285 0.255327
--0.931844 -0.362605 -0.013577 -0.594279 -0.772562 -0.223562 0.840345 -0.541131 0.0315954
-0.337175 -0.937691 -0.083952 -0.196653 0.947336 0.252749 0.567186 0.823586 0.00258989
--0.154528 0.881383 0.446415 -0.151051 0.868543 0.472034 0.219365 0.877462 -0.426544
-0.668805 0.622144 -0.406986 -0.600171 0.493881 0.629187 0.237233 0.964443 0.116487
--0.864581 0.432291 -0.256172 0.743713 0.131362 0.655465 0.987282 -0.0806346 0.137013
--0.110199 0.539397 0.834809 -0.184052 0.94071 -0.28494 -0.806674 -0.235797 0.541919
--0.824177 0.524476 0.213675 -0.79624 0.498977 -0.342088 0.18834 0.690065 -0.698813
--0.0866422 0.880174 -0.466676 -0.647615 0.674422 -0.354612 0.766549 -0.618904 0.171349
--0.874694 0.35783 -0.326906 0.500186 0.0218937 -0.865641 -0.428552 0.220262 -0.876258
--0.633891 0.465654 -0.617534 0.317038 0.462008 -0.828273 0.45888 0.209489 -0.863449
--0.172331 0.623042 -0.762969 -0.436479 0.421808 -0.79471 -0.436819 0.422177 -0.794327
--0.204932 0.63529 -0.744587 -0.551799 0.469195 -0.689474 -0.0814733 0.537724 -0.839175
-0.0705667 0.650782 -0.755978 0.0268041 0.830926 -0.555737 -0.403932 0.580653 -0.706881
--0.45241 0.407383 -0.793325 -0.706872 -0.115358 -0.697872 0.312871 0.368741 -0.875295
--0.781045 0.292892 -0.551528 -0.643803 0.366898 -0.671493 -0.55345 0.675872 -0.486713
--0.674034 0.26364 -0.690052 -0.620867 0.46565 -0.630629 -0.648835 0.511203 -0.563635
-0.414562 0.910015 -0.00337042 -0.370703 0 -0.928751 -0.160067 0.101506 -0.981873
-0.535569 -0.494819 -0.684339 0.619153 -0.755367 -0.21464 -0.649905 -0.400235 -0.646093
-0.720422 -0.432253 -0.542355 0.408888 -0.713695 -0.568726 -0.712135 -0.577994 -0.39848
-0.83064 -0.139465 -0.539061 -0.202699 -0.719788 -0.663942 0.873608 -0.0513887 -0.48391
--0.943873 -0.330306 -0.00130685 0.917684 0 -0.397311 -0.936431 -0.211366 -0.280038
--0.635925 0.236485 -0.734626 -0.786572 -0.0172602 -0.617258 -0.806092 0.307588 -0.505575
--0.625074 0 -0.780565 -0.0319201 0.516273 -0.855829 -0.0713707 0.0356854 -0.996811
--0.537102 -0.559349 -0.631387 -0.3801 0.471936 -0.795488 -0.749884 -0.326389 -0.575451
--0.735108 -0.385716 -0.557529 -0.736127 0.114607 -0.66707 -0.65306 -0.483595 -0.582794
-0.477285 0.369327 -0.797369 -0.747115 -0.0498077 -0.662826 -0.205603 0.699771 -0.68414
--0.364781 0.674051 -0.642331 -0.522794 -0.459039 -0.71831 0.185773 0 -0.982593
--0.882847 0.0509335 -0.46689 0.671071 0.0447381 -0.740042 -0.52554 -0.21146 -0.824071
--0.497897 -0.342304 -0.796823 -0.436782 -0.288301 -0.852117 0 -0.185408 -0.982662
--0.723993 -0.00559789 -0.689784 -0.454739 0 -0.890625 -0.297124 0 -0.954839
-0.22072 0.839394 -0.496689 -0.258042 0.642919 -0.721158 -0.402083 0.467097 -0.787496
-0.133029 0.768613 -0.62573 0.131468 0.821464 -0.5549 -0.278108 0.661446 -0.696523
--0.835613 -0.33955 -0.431807 -0.151789 -0.893317 -0.423019 -0.863961 -0.2239 -0.451044
--0.839578 -0.423524 -0.340199 0.867114 -0.00530345 -0.498082 -0.904054 0.138161 -0.404472
-0.180169 -0.750704 -0.635596 0.0305688 -0.730056 -0.682704 -0.423027 -0.687823 -0.58987
--0.492764 0.236527 -0.8374 0.822643 -0.364328 -0.43649 0.0683147 -0.959512 -0.273259
--0.997079 -0.0487461 0.0587908 0.0222418 -0.578286 -0.815531 -0.76425 -0.390849 -0.51299
--0.5314 -0.442833 -0.722159 -0.177164 -0.500682 -0.847308 0.547588 -0.305631 -0.778933
-0.474633 -0.870765 -0.128421 0.397145 -0.723829 -0.564223 -0.0380044 -0.547264 -0.836097
-0.395116 -0.531363 -0.749358 -0.11476 -0.774954 -0.621511 0.0101811 -0.897637 -0.440617
-0.883631 -0.239682 -0.402181 0.978105 -0.204513 0.0385314 -0.435043 -0.791438 -0.429375
--0.333969 0.0811067 -0.939088 0.428472 -0.265245 -0.863746 -0.508177 0.182626 -0.841668
--0.772113 -0.15745 -0.615672 -0.470757 0.262312 -0.842366 0.0920962 0.446937 -0.889812
--0.0210331 0.57922 -0.8149 -0.634238 0.27247 -0.723535 0 -0.180093 -0.98365
-0.621395 -0.517209 -0.588527 -0.127733 0.58088 -0.803905 -0.261064 0.124687 -0.957235
--0.713487 -0.249232 -0.654844 -0.919597 -0.038546 -0.390967 -0.826018 -0.0225278 -0.563194
--0.636143 -0.373933 -0.674904 0.519706 -0.377321 -0.766508 -0.0341066 0.0341066 -0.998836
-0.177046 -0.481884 -0.858162 0.488382 -0.586761 -0.645906 -0.387423 -0.819548 -0.422191
--0.628337 0.7181 -0.299208 -0.97997 -0.0544428 -0.191558 0.288155 -0.288155 -0.9132
--0.328004 -0.770429 -0.546674 -0.319041 -0.738927 -0.593464 0.0421692 -0.685708 -0.726655
-0.598082 -0.642938 -0.478465 0.354843 -0.593661 -0.722255 -0.11671 -0.786079 -0.607008
-0.925631 -0.0970419 -0.365773 0.492707 0.854026 0.166973 -0.557297 0.827398 -0.0695197
-0.46927 -0.210363 -0.857632 0.570595 -0.423409 -0.703666 -0.117946 -0.451565 -0.884408
-0 -0.179487 -0.98376 0.846403 -0.50626 -0.165238 -0.644232 -0.759273 0.0920331
-0.812889 -0.452536 0.366638 -0.509134 -0.83879 0.192909 0.218713 -0.132745 -0.966718
--0.200509 -0.200509 -0.958954 0.192226 -0.973665 -0.122579 -0.516551 -0.856214 0.00846805
--0.0354702 -0.986073 0.162488 0.409464 0.394299 -0.82272 0.13231 -0.573343 -0.808561
--0.490945 -0.499693 -0.713638 -0.106641 -0.00784122 -0.994267 -0.409572 -0.253756 -0.876276
-0.625638 -0.687389 -0.368882 0.494146 -0.484163 -0.722085 -0.3461 -0.359944 -0.866404
--0.172447 -0.172447 -0.969806 -0.318335 -0.695493 -0.644167 -0.224632 -0.703848 -0.673897
-0 -0.587764 -0.809032 0.153572 -0.661029 -0.734477 0.00854327 -0.341731 -0.939759
--0.575751 -0.589459 -0.566612 0.488449 -0.636069 -0.597355 -0.30195 -0.433514 -0.849054
-0 -0.175069 -0.984556 0.230173 -0.0886227 -0.969106 0.451094 0.263138 -0.852803
--0.256417 0.682522 -0.684408 -0.349964 -0.817377 -0.457625 0.509858 -0.509858 -0.692884
-0.0929787 0.0929787 -0.991317 0.735538 0.465457 -0.492274 -0.726582 -0.59617 0.341556
-0.785634 -0.583274 -0.206328 0.139874 0.963575 0.227943 -0.602536 -0.763212 0.233363
--0.279498 -0.792159 -0.542554 -0.210776 -0.321124 -0.923284 -0.19265 -0.17179 -0.966113
-0.0960711 -0.148345 -0.984258 0.349424 -0.255216 -0.901536 0.644899 -0.12441 -0.754074
-0.858479 -0.280656 -0.429239 -0.82493 -0.434405 -0.361638 0.731604 -0.491344 -0.472585
--0.141882 -0.141882 -0.979663 0.208143 -0.976118 -0.0622036 0.728672 -0.613151 -0.305094
--0.340743 -0.908647 -0.241359 -0.0150653 -0.858722 -0.51222 -0.184493 -0.798436 -0.573117
-0 -0.185408 -0.982662 -0.423191 -0.423191 -0.801136 0.423718 -0.501943 0.754
-0.914698 -0.0531801 0.400624 -0.0418217 0.888712 0.456554 -0.968621 0.0284889 0.246903
-0.0250435 -0.751305 0.659479 -0.358429 0.907385 -0.219503 -0.996783 0.0419208 -0.0683153
--0.119944 -0.420374 -0.899388 0.934608 -0.142688 0.325805 -0.0671048 -0.971254 0.228392
-0.502134 0.819272 0.276866 0.616506 0.616506 0.489735 -0.0298865 0.999538 0.00553454
-0.289798 0.955825 -0.049147 -0.747094 0.516174 -0.418825 0.275001 -0.910122 0.309922
--0.299544 -0.948843 0.0998479 0.710932 -0.640053 0.291389 0.798598 -0.466295 0.38054
--0.0722302 -0.996777 -0.0349113 -0.268286 -0.960636 -0.0721198 -0.0161611 -0.985825 0.166998
-0.622713 0.178399 0.761842 -0.271273 0.883079 0.38286 0.113325 0.869937 -0.479965
-0.531963 0.0115144 0.846689 -0.354269 0.919412 0.170808 -0.784283 0.61792 0.0554544
--0.976588 0.151139 0.153076 -0.972625 0.196841 -0.123508 -0.72475 0.102208 0.681389
-0.828698 -0.510537 -0.229372 -0.790963 -0.0903958 0.60515 0.894124 0.0286272 0.446903
--0.275851 0.927108 0.253727 -0.542035 0.832958 0.111265 0.729044 -0.557877 0.396572
--0.639486 -0.689102 0.340876 -0.924675 -0.377418 0.0503224 -0.219365 -0.731218 -0.645909
-0.891443 0.432647 -0.134707 -0.142372 0.968598 0.203833 -0.235422 0.881707 0.408864
--0.814427 0 0.580265 -0.470187 -0.606294 0.641352 0.645084 -0.763198 0.0373523
--0.763394 0.643827 0.0521193 0.716086 0.461247 0.5239 0.849921 -0.449344 -0.275179
--0.914794 -0.333429 0.227986 0.963175 -0.157253 0.218095 0.969073 0.199515 0.145225
--0.0623225 0.996256 0.0599139 0.674192 -0.244272 0.696991 0.371349 0.516538 0.771549
--0.569795 0.776663 -0.268566 -0.718254 0.64363 -0.264293 -0.718274 0.517692 -0.464841
-0.480531 -0.835574 0.266282 0 0.890064 0.455835 0.365912 0.643118 0.672687
-0.832113 0.421851 0.360041 0.954546 0.130835 0.267813 -0.72099 0.674474 0.158928
-0.476716 -0.762746 -0.43699 -0.21813 -0.916637 -0.334956 0.858905 0.394416 0.326678
--0.816859 0.315719 0.482766 0.417419 -0.849571 0.322477 -0.454239 -0.883701 -0.112871
--0.561202 -0.810967 -0.165483 0.394132 0.878868 -0.268795 0.964523 -0.0595029 0.257206
-0.964573 -0.123663 0.233036 -0.769838 0.620974 0.147446 -0.859744 0.510178 0.0236194
--0.424986 -0.786224 -0.448596 0.89496 0.356203 -0.268636 -0.693899 0.696463 0.182875
--0.0058703 -0.817929 -0.57529 -0.113789 -0.785143 -0.608771 -0.773993 0.456103 0.43921
-0.312699 0.799121 0.513445 -0.111902 0.973338 0.200228 -0.576003 0.805213 -0.1409
--0.982313 -0.133382 0.131417 0.395951 -0.905306 -0.153767 0.498366 -0.835842 0.230216
--0.220191 0.790099 0.572066 0.624134 0.271363 0.732679 -0.419525 0.483477 0.768277
-0.632047 0.765289 0.121854 0.196978 0.875974 0.440305 -0.79877 -0.26753 0.538883
-0.297715 -0.952687 0.0612688 -0.580683 -0.763926 0.281468 -0.0227317 -0.941743 -0.335564
--0.601703 -0.791714 -0.105562 0.100041 -0.969632 -0.223169 -0.721377 0.55087 -0.41971
-0.985732 0.0490414 0.161019 -0.556792 0.82601 0.0876998 -0.596851 -0.750327 0.284215
-0.878503 0.459525 -0.130649 0.059197 -0.980263 -0.188628 -0.371376 0.00884229 -0.92844
-0.57772 -0.804488 -0.137981 0.107465 -0.0179108 -0.994048 -0.686893 0.482398 -0.543572
--0.240862 0.51314 0.823816 -0.926045 0.37362 -0.0533743 -0.412635 -0.909913 0.0423215
-0.906899 -0.378443 -0.185244 0.48306 -0.852947 -0.197825 -0.943578 0.229741 0.238493
-0.536044 -0.838564 -0.0973017 -0.818782 -0.438633 -0.370401 0.867657 -0.495804 -0.0367262
-0.569369 -0.765426 -0.299904 -0.202798 0.916731 0.344205 0.446501 0.788353 0.423246
--0.736485 0.675257 0.0402355 0.984051 0.140318 0.109339 0.943237 0.210987 0.256494
--0.579521 0.788357 0.206516 -0.71773 0.239243 0.653932 -0.987262 -0.0239204 0.157295
-0.0166855 -0.920734 -0.389833 -0.751227 0.659395 0.0292666 0.516148 0.842823 -0.152449
--0.329945 0.942416 0.0546615 0.970761 0.142024 -0.193528 -0.0254645 0.96765 0.251007
-0.98907 0.121111 -0.0841046 0.723093 0.61011 -0.323886 -0.933481 -0.283745 -0.21932
--0.798414 0.562519 -0.214725 -0.441277 0.375903 -0.814845 -0.242647 -0.0808824 -0.966737
--0.853984 0.204956 -0.478231 0.989226 -0.0613474 -0.132919 -0.277813 0.909421 -0.309472
--0.0427886 0.996974 -0.064896 -0.568726 0.820137 -0.0626494 0.181231 0.9834 -0.00891299
--0.461182 -0.733552 0.499212 -0.987359 0.0658239 0.144186 -0.90507 -0.318266 0.282053
--0.993195 0.116088 -0.00931568 0.0815103 0.151376 -0.98511 -0.949476 0.291748 -0.115663
--0.0710296 0.756256 -0.650408 0.114096 0.932051 -0.343895 -0.480534 0.439512 -0.758891
--0.736143 0.313542 -0.59982 -0.234798 0.626128 -0.743527 -0.412541 0.164372 -0.895987
--0.925036 0.143975 -0.351538 0.66157 0.0374474 -0.748948 -0.185527 0.272833 -0.944003
-0.5317 0.745858 -0.401237 0.0477638 0.987686 -0.148977 -0.505042 0.603245 -0.617274
--0.0350279 0.612227 -0.789905 0.6321 0.330034 -0.70109 0.771794 0.00627475 -0.635841
--0.650412 0.459625 -0.604739 -0.0762216 -0.70505 -0.70505 -0.496523 -0.553814 -0.668397
--0.165255 -0.694072 -0.700682 -0.792172 0.433567 -0.429515 -0.423179 0.215207 -0.880117
-0.0894459 0.673826 -0.733456 -0.895594 0.0334801 -0.443612 -0.887991 0.426662 -0.171554
--0.144472 -0.764993 -0.627626 -0.664857 -0.441506 -0.602526 -0.766713 -0.606981 -0.209104
--0.857561 -0.0751252 -0.508867 -0.282113 0.408106 -0.868252 0.0240754 -0.214672 -0.976389
-0.542341 0.198275 -0.816427 0.629121 0.351881 -0.693099 0.361147 -0.208119 -0.908988
-0.157398 -0.724033 -0.671567 -0.371133 -0.871357 -0.320932 0.406464 -0.468768 -0.784247
-0.312422 -0.551724 -0.7733 -0.455835 -0.0267213 -0.889663 -0.228108 -0.409086 -0.883525
--0.497743 -0.617619 -0.608932 -0.409339 -0.7567 -0.509752 -0.729704 -0.508382 -0.457252
-0.656527 0.025579 -0.753869 0.760126 0.302839 -0.574889 -0.842957 -0.469264 -0.263088
-0.54045 -0.237798 -0.807072 -0.629224 -0.641809 -0.438359 0.827071 0.109236 -0.551381
--0.373767 -0.289837 -0.881075 0.893271 0.0915583 -0.440096 -0.311345 0.166368 -0.935621
--0.205981 -0.137321 -0.968873 -0.694872 0.0534517 -0.717144 -0.448149 0.0206045 -0.893722
--0.499994 0.314238 -0.807007 -0.392693 0.145716 -0.908052 -0.767328 -0.00537847 -0.641233
--0.138503 -0.246228 -0.959265 -0.100131 0.807082 -0.581887 -0.816115 0.0429534 -0.576292
--0.830445 -0.337487 -0.443241 -0.335017 0.00744482 -0.942183 -0.423305 -0.100787 -0.900364
--0.297061 -0.0206124 -0.954636 0.718451 0.0671799 -0.692326 0.797564 0.118416 -0.591498
--0.604608 -0.763446 -0.227155 -0.186032 -0.677774 -0.711347 0.324318 -0.746686 -0.580756
--0.450544 -0.0813013 -0.889044 -0.457855 -0.848157 -0.266456 -0.287508 -0.713168 -0.639321
-0.401061 -0.749153 -0.527181 0.178405 -0.766553 -0.616902 0.147486 -0.516902 -0.843244
-0.332688 -0.266844 -0.904496 -0.480452 0.182781 -0.857763 0.699503 -0.14626 -0.699503
--0.652521 -0.756581 0.0424404 0 0 -1 0.574039 -0.732031 -0.366893
-0.0215465 0.797221 -0.603303 -0.366363 0.838326 -0.403718 0.540566 -0.0766156 -0.837806
-0.293806 -0.321788 -0.900073 0 -0.805683 -0.592347 0.58472 -0.577319 -0.569917
--0.643565 0.213155 -0.735112 -0.759482 -0.165432 -0.629142 -0.483722 0.668977 -0.564342
--0.206678 0.792266 -0.574106 -0.0288845 0.788133 -0.614827 -0.55797 0.52973 -0.638792
-0.759035 0.185262 -0.624135 0.363141 0.276421 -0.889786 0.481804 0.0161499 -0.87613
--0.942707 -0.306703 0.13129 0.0975776 -0.780621 -0.617341 0.408642 -0.207282 -0.888845
--0.362616 0.442157 -0.82037 0.172079 0.465394 -0.868215 0.544485 0.69033 -0.476425
--0.365771 -0.802035 -0.472177 -0.13498 -0.781247 -0.609454 -0.589435 -0.63244 -0.502579
-0.365376 0.152051 -0.918358 0.857891 -0.0919169 -0.505543 0.483016 -0.438554 -0.75787
-0.479833 -0.125979 -0.868268 0.428564 -0.767844 -0.476182 -0.669657 -0.685368 -0.286061
--0.584652 -0.733349 -0.346961 -0.630364 0.775832 0.0269386 0.702414 0.702414 -0.115015
-0.587823 -0.182105 -0.788227 0.762597 -0.0649019 -0.64361 0.574273 -0.19292 -0.795608
-0.452318 -0.452318 -0.768646 -0.568191 -0.409674 -0.71367 -0.552606 -0.566003 -0.611774
--0.552647 -0.82897 -0.0859673 0.761816 0.128864 -0.634847 0.379944 0.293593 -0.877181
--0.825219 0.5639 0.0320919 -0.449142 -0.156417 -0.879662 0.72444 -0.10363 -0.681503
-0.324992 -0.181527 -0.928131 -0.540602 -0.422114 -0.727715 0.51775 -0.285291 -0.806563
--0.554546 -0.284383 -0.782052 -0.133974 -0.173529 -0.975673 -0.330467 -0.165233 -0.929241
--0.244907 0.379966 -0.89199 -0.024013 -0.515648 -0.856464 0.0603724 -0.603724 -0.794904
-0.561852 -0.494688 -0.663028 -0.432075 0.0652188 -0.899476 -0.757459 0.269319 -0.594746
--0.188802 0.0917038 -0.977724 -0.253825 0.779287 -0.572961 0.263356 -0.784216 0.561826
-0.60898 -0.750797 0.255827 0.276018 0.552036 0.78681 -0.513996 0.747631 0.420542
--0.532352 -0.760503 0.371801 -0.133219 -0.666095 -0.733873 -0.589831 0.518208 -0.619322
-0.124862 -0.264413 -0.956293 0.165416 -0.478328 -0.862461 -0.875574 0.149034 -0.459521
--0.543368 0.123027 -0.830431 -0.497284 0.0252588 -0.86722 0.764705 -0.0791655 -0.6395
-0.607932 -0.645026 -0.46299 -0.581591 0.803149 -0.129242 -0.424753 0.817144 0.389694
-0.83265 0.550926 0.0563447 -0.270036 0.938696 0.214314 0.149199 -0.0239454 -0.988517
-0.194734 -0.301523 -0.933361 -0.110504 0 -0.993876 -0.256578 -0.843645 -0.471625
--0.400846 -0.754534 -0.519616 0.786517 -0.32386 -0.525837 0.555913 -0.526654 -0.643115
--0.261925 -0.641027 -0.721443 -0.612827 0.779962 -0.126898 0.514418 -0.163678 0.841774
--0.0646994 -0.139931 -0.988045 0.646157 -0.332785 -0.68683 0.913205 -0.145859 -0.380502
-0.0755444 -0.522145 -0.849504 -0.806435 0.280012 -0.520823 -0.354884 0 -0.93491
--0.181037 -0.929324 -0.321844 0.445548 -0.661135 -0.603645 -0.208956 0.46676 0.859344
--0.704145 0.631129 0.325356 0.109766 -0.259888 -0.95938 -0.788177 -0.498977 -0.360276
--0.401809 -0.385644 -0.830559 0.568719 -0.290243 -0.769622 0.549939 -0.46946 -0.690778
--0.363265 -0.690573 -0.625418 0.910828 -0.27297 -0.309644 -0.142386 0.987209 -0.0717203
-0.699557 -0.679852 0.220049 -0.853627 0.284542 0.436298 0.324002 -0.616962 -0.717203
--0.582605 -0.543416 -0.604376 -0.0985291 0.239285 -0.965937 0.0603236 -0.475492 -0.877649
--0.25542 0 -0.96683 0.481442 -0.813153 -0.327104 -0.518022 -0.84937 -0.101115
--0.971218 -0.194552 -0.137422 0.461727 -0.887022 -0.000247841 -0.175985 -0.984321 -0.0119312
--0.151461 -0.731338 -0.664984 -0.408019 -0.848249 -0.337629 0.0300072 -0.49762 -0.866876
-0 -0.25542 -0.96683 0.232757 -0.411802 -0.881047 -0.362132 -0.641275 -0.676482
-0.606449 -0.741216 0.287783 0.293729 -0.917009 0.269849 -0.160886 -0.326504 -0.931403
--0.535961 -0.375173 -0.756301 -0.408275 -0.898718 0.160057 0.104298 -0.208596 -0.972425
--0.271329 -0.407547 -0.871944 0.235196 -0.0306778 -0.971464 -0.0768463 0.922156 0.379109
--0.694839 0.191197 0.693284 -0.629876 -0.404648 0.66296 0.171286 -0.236777 -0.956346
-0.16836 -0.274186 -0.946825 0 -0.724005 -0.689795 -0.0958648 -0.636026 -0.76569
--0.0688492 0.907334 -0.414734 0.0720212 0.916019 -0.394616 -0.300483 0.832339 -0.465749
-0.445947 -0.876246 -0.182551 0.0776202 -0.993539 -0.0827949 -0.548156 -0.754604 0.360691
-0.0170736 0.273177 -0.961812 -0.335984 -0.0912549 -0.937437 -0.441987 -0.338543 -0.830684
-0.126111 -0.693611 -0.709225 0.635762 0.771252 0.031267 -0.163299 0.701899 -0.693304
--0.387619 0.113702 -0.914781 -0.6267 -0.586958 -0.512569 0.636046 0.158279 -0.755244
-0.482455 0.0331458 -0.875293 0.714132 -0.0892666 -0.694296 0.779214 -0.25568 0.572235
--0.418474 -0.89534 -0.152467 0.292683 -0.097561 -0.951219 -0.206772 -0.935644 -0.286035
-0.134147 0.972568 -0.190042 0.0410159 0.750004 0.66016 0.200766 0.790517 0.578597
-0.325909 0.678978 0.657854 0.209063 0.928485 -0.306933 0.890858 -0.206446 0.404663
-0.839116 0.427626 0.336184 0.129066 0.530605 0.837735 0.801616 0.248904 0.543561
-0.290777 0.717249 0.633247 -0.555659 0.782755 0.280246 -0.981049 0.178373 0.0756732
-0.535912 -0.602901 0.591024 -0.613857 -0.371237 0.696679 -0.868085 -0.0190788 0.496049
-0.637757 -0.699839 0.3217 0.715899 0.166664 0.678021 -0.941787 -0.0425323 -0.333508
--0.390771 0.882853 -0.260514 -0.660552 0.590438 -0.46374 0.623763 0.733839 0.269074
-0.0144218 -0.973473 0.228346 -0.923465 -0.259298 -0.282802 0.602693 0.609244 0.515346
-0.646749 -0.729533 0.222482 -0.389103 -0.915112 -0.105682 -0.557366 -0.804395 -0.20565
-0.0460165 -0.966347 0.253091 0.473718 0.702629 0.530946 -0.36819 0.911494 0.183346
-0.920294 -0.0626903 0.386172 0.566078 0.649209 0.508019 -0.400389 0.883808 0.242017
-0.107032 0.791103 0.602246 0.851886 -0.387471 0.352357 -0.698937 0.712301 -0.0641472
-0.436605 0.703781 -0.560418 0.827097 -0.232813 0.511575 0.00514209 0.742175 0.670186
--0.97065 0.0500804 -0.235226 -0.994384 0.057813 -0.0886466 -0.805787 0.401439 0.435377
-0.0855229 0.958325 0.27258 -0.829449 0.32249 0.456086 -0.105929 0.658274 0.745288
--0.670837 0.213448 0.710223 0.937375 0.124064 0.325478 0.88404 0.276743 0.376678
--0.463262 0.8165 0.344551 0.76058 -0.645527 0.0693831 0.982153 -0.0637072 -0.176965
-0.710444 -0.647925 -0.274705 -0.120542 -0.98945 0.0803614 -0.340571 -0.84512 0.412048
-0.745192 0.628883 -0.2218 -0.892643 -0.241861 0.380384 0.497432 0.834363 0.237485
-0.792949 0.109914 -0.599292 0.509942 0.747914 -0.424951 -0.0398567 0.99841 -0.0398567
--0.185057 0.981606 0.0469347 0.215159 0.66063 0.719218 0.924525 -0.365326 0.108587
--0.919617 -0.391427 0.0330119 -0.0499747 -0.998357 0.0280161 -0.249731 -0.968003 0.0245767
-0.726701 -0.0641207 -0.683954 0.208396 -0.968932 -0.133201 0.171561 -0.981113 -0.0893546
-0.983822 -0.168166 -0.0617616 0.645454 0.368348 0.66911 -0.449547 0.877687 0.166053
--0.137044 -0.939732 -0.313244 0.663553 -0.744598 -0.0726025 -0.421637 -0.737865 -0.527046
-0.942883 0.0574669 0.328129 0.905207 -0.373301 0.203091 -0.257075 0.956559 0.137505
--0.129518 0.979908 0.151673 0.757905 -0.606733 -0.239697 -0.864204 -0.251266 -0.435909
--0.279377 0.95525 0.0971923 0.164566 0.919298 0.357505 0.416017 0.886297 0.203487
--0.505457 0.315911 0.80294 -0.466701 0.132768 0.874393 0.656575 -0.366616 0.659168
-0.272729 0.873174 0.403962 -0.829695 -0.140709 0.540191 -0.801073 -0.563995 0.200476
-0.857995 -0.472093 -0.202419 -0.908661 0.147067 0.390777 -0.0739412 -0.985882 0.15023
--0.906681 0.0546992 -0.418256 -0.676726 0.502087 -0.53847 0.909123 0.284535 -0.304198
--0.69733 -0.686764 0.205149 -0.554284 -0.832311 0.00531262 0.766618 -0.622362 -0.157995
--0.0734825 -0.981516 0.176708 -0.18421 -0.97222 -0.144412 0.578781 -0.720523 0.381916
-0.980987 -0.158048 -0.112632 -0.663863 0.743847 -0.0773174 0.00736467 -0.979502 -0.201301
-0.974387 0.111722 -0.19516 -0.563754 -0.317517 -0.762472 0.821896 -0.115656 0.557773
-0.840799 -0.450428 0.300285 -0.653473 0.756901 -0.00861895 -0.647625 0.761127 0.0356083
-0.422265 0.777187 0.466555 -0.721025 0.675819 0.152945 -0.692976 0.702392 0.162573
-0.722882 -0.684516 0.0942304 0.541656 -0.0492415 0.839157 0.713851 -0.695309 0.0834371
-0.879118 0.295715 0.37377 0.96499 -0.236752 0.112882 0.730211 -0.683181 -0.00742588
--0.870976 0.491082 0.0154428 -0.918998 0.370755 -0.134103 -0.95269 -0.0790501 -0.293485
-0.950151 0.160415 0.267358 -0.632724 0.764542 0.12303 0.371687 -0.877865 -0.301995
--0.746607 -0.411175 -0.522985 -0.996271 0.0379532 0.0774877 -0.973645 0.216366 -0.0721218
-0.496914 -0.819696 -0.284912 -0.945534 -0.280158 -0.16576 0.13028 0.70514 0.696997
-0.188894 -0.554088 0.810744 -0.868409 -0.169371 0.466026 0.190266 -0.874654 0.445846
--0.409669 0.718718 0.561797 -0.249379 0.892778 0.375177 -0.286159 0.950614 0.120193
-0.368298 0.909472 -0.192918 0.309305 0.565341 0.76467 -0.153646 -0.171722 0.97309
-0.920076 -0.26439 0.289066 0.866675 0.454878 -0.204843 -0.161646 0.971446 -0.173678
--0.313982 0.921559 -0.228351 0.540462 0.808422 0.23314 -0.935596 -0.165529 0.311865
--0.315534 0.919775 -0.23335 0.123151 0.985211 -0.119136 0.423102 -0.883142 0.202597
--0.814527 -0.550356 0.183452 -0.870338 0.490779 0.040604 0.635008 0.759741 0.139853
-0.346862 0.923006 0.166572 0.138148 0.989628 -0.0393882 -0.835204 -0.528989 0.150352
-0.256576 -0.837052 0.483231 0.41113 -0.828846 0.379456 0.339057 -0.856564 0.389023
-0.0881929 -0.264579 0.960323 0.89914 -0.167889 0.404178 0.0615907 0.588961 0.805811
--0.126984 0.991592 0.0248987 -0.87468 0.471182 0.113674 0.250648 -0.943617 0.216246
--0.214176 -0.942376 0.257012 -0.975106 0.0286796 0.219877 -0.713099 0.693524 0.102537
--0.907426 0.36297 0.211733 -0.70946 0.701444 0.0681402 0.0514998 -0.885796 0.461209
-0.477187 -0.827124 0.296916 -0.717137 0.358569 0.597614 0.403604 -0.861021 0.309429
--0.291659 0.556803 -0.777757 -0.986657 -0.130252 0.0976888 0.69208 0.0768978 -0.717713
--0.666319 -0.0888426 -0.740355 0 0.999989 0.00476185 -0.22439 0.940992 -0.253344
--0.717168 0.649934 -0.251507 -0.514956 0.836804 -0.185956 -0.407553 -0.584159 -0.701897
--0.847143 -0.331942 -0.414927 0.0431467 0.848553 -0.527349 -0.519903 0.852641 -0.0519903
--0.10897 0.796083 -0.595296 0.329238 -0.93284 -0.146328 -0.280591 -0.795009 -0.5378
-0.391983 0.744768 -0.540065 -0.525994 0.713849 -0.462332 -0.187814 -0.77597 -0.602159
-0.557839 0.424072 -0.713427 -0.844915 -0.455553 -0.28034 0.0729597 -0.496126 -0.86518
--0.00704243 0.640861 -0.767625 -0.481616 0.854254 -0.195693 -0.703482 0.572602 -0.420999
--0.484667 -0.274155 -0.830624 0.204732 0.584948 -0.784806 -0.816358 -0.19948 -0.542004
-0.313793 -0.926031 -0.209764 -0.685239 -0.711043 -0.157691 0.803183 -0.274421 -0.528762
-0.877625 0.0706135 -0.474119 -0.798958 -0.510612 -0.317714 0.00539076 0 -0.999985
--0.0771935 -0.439117 -0.895107 0.183726 -0.110869 -0.976705 0.668356 0.200917 -0.716193
-0.604408 -0.304476 -0.736196 -0.869006 -0.025559 -0.494141 0.623928 0.0605303 -0.779134
--0.941095 0.218178 -0.25834 -0.743661 0.40669 -0.530633 -0.294724 -0.854699 -0.427349
--0.873177 0.311768 -0.374649 0.782583 -0.0622195 -0.619429 -0.843976 -0.53427 0.047538
--0.628695 0.603547 -0.490382 0.762248 -0.31208 -0.567083 -0.861042 -0.315841 -0.398561
--0.778741 -0.507254 -0.369128 -0.42219 0.509539 -0.74975 0.172483 0.172483 -0.969793
-0.553028 -0.563979 -0.613259 0.420491 -0.591386 -0.688077 -0.59626 0.59626 -0.537538
-0 -0.143589 -0.989637 0 -0.432897 -0.901444 -0.042924 -0.126906 -0.990986
--0.556175 -0.498639 -0.664852 -0.586204 -0.103807 -0.803486 -0.5199 -0.0879433 -0.849688
--0.313539 0 -0.949575 -0.579962 -0.297416 -0.758411 -0.469937 -0.16366 -0.867396
--0.155191 -0.39592 -0.905076 -0.427715 -0.427715 -0.796316 -0.298438 -0.235307 -0.924968
--0.25542 0 -0.96683 -0.423431 0 -0.905928 -0.132191 0 -0.991224
--0.707368 -0.485599 -0.513638 -0.330467 -0.165233 -0.929241 -0.674422 -0.513411 -0.530626
-0 0.230805 -0.973 -0.0597167 0.17915 -0.982008 -0.586297 -0.377836 -0.716586
--0.172447 -0.172447 -0.969806 0.175069 0 -0.984556 -0.133423 0.222371 -0.965789
-0.643257 0.757345 0.112469 0.665527 0.744119 0.0579688 -0.947659 -0.299019 -0.11194
-0.0212536 0.17503 -0.984334 -0.0969803 0.562486 -0.8211 -0.455376 -0.885453 0.0927618
-0.982315 -0.0605536 0.177175 -0.61987 -0.783887 0.0358197 0.626527 0 -0.7794
-0 -0.195557 -0.980692 -0.498237 0.486937 -0.717393 -0.845802 -0.127289 -0.518089
-0.501584 0 -0.865109 0 -0.0480727 -0.998844 0.247475 0.247475 -0.936756
-0.171035 -0.95851 0.228047 -0.544173 -0.229125 -0.80708 0.521558 0.462619 -0.716911
--0.675914 -0.667248 0.312923 0.52245 -0.8127 0.258 -0.195557 0 -0.980692
--0.984739 -0.0599483 0.163388 0.472562 -0.836072 0.278691 0.411622 -0.886571 0.211088
--0.218638 -0.881923 0.417624 0.694576 -0.694576 0.187425 0.232311 -0.546207 -0.804791
-0.111943 -0.567709 -0.815583 0.655627 0.109967 -0.747034 -0.561904 -0.275844 -0.779855
--0.149572 0.202363 -0.967821 0.0857304 0.0857304 -0.992623 -0.296679 0.941633 0.159089
--0.446721 0.887487 0.113169 0.856361 -0.324379 -0.401775 0.576977 0.0940259 -0.81133
-0.0688846 0.251578 -0.965382 -0.172447 0.172447 -0.969806 0.300108 0.200072 -0.932688
--0.738603 0.281173 -0.612705 0.0425635 -0.998883 0.0205271 0.229846 -0.919382 0.31923
-0.126139 -0.986587 0.103614 0.124193 -0.989536 0.0734473 0.452953 0.0654266 -0.88913
--0.00508037 0 -0.999987 0.538409 0.198361 -0.819004 -0.865946 0.382366 -0.322387
--0.789659 0.0535362 -0.611205 0.93286 -0.237879 -0.270529 0.620645 -0.746713 -0.239207
-0.599293 0.724146 -0.341264 -0.732201 -0.666237 -0.141456 -0.430444 -0.901882 -0.0364397
-0.0901019 -0.95508 0.282319 0.682593 0.0374693 -0.729837 0.815201 0 -0.579178
-0.0259785 -0.929042 -0.36906 -0.71174 0.652429 -0.260312 -0.231655 -0.817109 -0.527892
-0.0174929 -0.552483 -0.833341 0.74628 -0.564577 -0.35259 0.726239 -0.0264488 -0.686933
--0.927635 0.334059 0.167029 -0.0436685 -0.375549 -0.925773 0.219376 -0.383615 -0.897058
--0.425108 0.242417 -0.872076 0.329003 0.310726 -0.891743 0.109489 0 -0.993988
-0.397227 -0.687096 -0.608366 -0.546354 -0.714462 -0.437083 0.583549 0.12799 -0.801928
-0.655027 0.154953 -0.739547 0.817504 0.099876 -0.567197 -0.278014 0.636506 -0.719422
-0.424149 0.678248 -0.600064 -0.635402 -0.394892 -0.66357 -0.390559 -0.386314 -0.835599
-0.739463 0.225398 -0.634343 0.722494 -0.125552 -0.679882 0.804525 -0.496023 -0.326649
-0.545706 -0.36951 -0.752108 0 0.132589 -0.991171 0.605665 0.223876 -0.763577
--0.284537 -0.785047 -0.550218 0.294689 -0.678677 -0.672723 0.149357 0.460874 -0.874807
-0.687954 0 -0.725754 -0.299843 -0.465393 -0.832768 0.598635 -0.603424 -0.526798
-0.731639 -0.529377 -0.429494 0.602229 -0.356157 -0.714473 0.333962 0.305576 -0.89168
--0.242339 0.314525 -0.917794 -0.497679 -0.130162 -0.857539 -0.294744 -0.126319 -0.94719
--0.428243 0.817554 0.384986 0.622071 -0.429014 -0.654962 0.326843 -0.362795 -0.87267
--0.3676 -0.197415 -0.908789 0.822263 -0.369475 -0.432865 -0.35897 0.166963 -0.918294
-0.725959 -0.436415 0.531531 0.798561 -0.293901 0.525284 0 -0.676436 0.736502
--0.604206 0.609241 0.513575 -0.231295 -0.762899 -0.603728 0.449134 -0.691834 -0.56537
--0.0518748 0.10375 -0.99325 0.602678 0.0827511 -0.793682 -0.530196 0.151803 -0.834175
-0.165497 -0.803841 0.571358 -0.444921 -0.289552 0.847469 0.783503 0.383416 0.488995
-0.483077 -0.634039 0.603847 0.163302 0.969816 0.181077 -0.1954 0.98043 0.0239965
--0.389313 0.908397 -0.152481 0.299667 -0.466149 -0.832409 0.137031 -0.236868 -0.961829
-0.601839 -0.0947777 -0.792974 -0.161495 -0.77245 -0.614199 -0.183883 -0.348838 -0.918966
--0.280702 0.573879 -0.769331 -0.487241 0.648067 -0.585325 0.643089 -0.749384 0.157672
-0.565406 -0.824767 -0.00864536 -0.911609 0.104184 -0.397635 -0.891602 -0.253777 -0.375025
-0.517288 -0.660717 -0.543936 0.525293 -0.233464 -0.818267 0.676675 0.0424282 -0.735059
--0.306654 -0.403031 -0.862282 0 -0.278157 -0.960536 0.10493 -0.314791 -0.943343
--0.172439 -0.623969 -0.762186 0.668872 -0.536069 -0.515015 0.726475 0.152053 -0.670159
--0.84123 -0.387913 -0.376637 0.59115 0.698632 -0.403057 0.823398 0.385968 -0.415987
-0.106888 0.956368 -0.271909 0.47685 0.541508 -0.692375 -0.136187 -0.00567446 -0.990667
--0.661598 -0.497522 -0.561035 0 -0.285738 -0.958308 0.843392 -0.526448 -0.107438
-0.274146 -0.609214 -0.744112 -0.468236 -0.717962 -0.515059 0.751858 0.273403 -0.599967
-0.954202 -0.148505 -0.2597 -0.734667 -0.0192657 -0.678154 0.155893 -0.568552 -0.807741
--0.430524 -0.527604 -0.732314 -0.704419 -0.351344 -0.616727 -0.941018 -0.27882 -0.191689
-0.562007 -0.589422 -0.580284 0.556402 -0.525144 -0.643926 0.979045 -0.0559454 -0.195809
--0.916496 -0.212826 -0.338733 -0.910914 -0.179862 -0.371328 0.54976 -0.326371 -0.768925
-0.823957 -0.324067 -0.46484 0.0953891 -0.317964 -0.943292 -0.738019 0.546491 -0.395823
-0.329136 -0.738063 -0.58901 0.495584 -0.650275 -0.575794 -0.760372 -0.230097 -0.607363
-0.972335 -0.152681 0.176788 -0.247391 0.965624 -0.0798036 0.227384 -0.968006 0.106113
-0.901801 -0.332075 0.276552 -0.0711611 -0.947658 0.311257 0.140252 -0.918653 0.369331
--0.621543 -0.779547 0.0774018 0.91459 0.250573 -0.317392 0.804573 -0.378622 -0.457502
-0.671444 -0.400009 -0.623824 0.293508 0.905397 -0.306774 -0.14704 0.974141 -0.171547
--0.769258 -0.415815 0.485118 -0.813039 0.492103 0.31113 -0.745524 0.635176 0.201857
-0.0947376 -0.720748 -0.686692 0.334992 -0.937977 -0.0893311 -0.0170181 -0.991306 0.130472
-0.186891 0.409954 -0.892754 0.298121 0.95278 -0.0577442 -0.564954 0.695328 -0.444237
--0.285975 -0.222425 -0.932065 0.833103 0.484642 0.266575 0.559668 0.822328 0.102707
-0.82239 0.216711 0.526033 -0.859304 -0.394815 -0.325142 0.870448 0.387098 0.304099
-0.326204 -0.820714 0.469062 -0.272914 -0.94649 0.172265 -0.307926 -0.835799 0.454557
--0.377904 -0.920267 0.101474 0.379991 0.923864 0.0456229 0.27047 0.959923 0.0734368
--0.907951 0.36318 0.209104 -0.54294 -0.827151 -0.145045 -0.567032 -0.808855 -0.155656
-0.860864 0.479826 -0.16935 -0.656845 0.749181 -0.0853409 0.339534 0.881557 0.327985
-0.0530097 0.689127 0.722699 -0.67747 0.164435 0.716935 -0.790441 -0.234205 0.565995
-0.0322058 0.955438 -0.29343 -0.590012 0.590012 -0.551156 0.884118 -0.463081 -0.0623758
--0.67414 0.735736 -0.0650186 -0.91007 0.201826 0.361991 -0.414751 0.582894 0.698725
-0.775483 -0.178623 0.605574 0.1426 0.901463 0.408692 -0.895211 0.0354038 0.444234
-0.494864 0.345619 0.797281 0.151667 0.933473 0.325 0.494524 0.450187 0.743491
--0.11886 0.984361 -0.13002 -0.742923 0.309996 -0.593269 -0.826573 -0.275524 -0.490778
--0.713162 -0.665618 -0.219892 0.107999 -0.862893 0.493712 -0.668426 -0.42153 0.612796
-0.732081 0.0170251 0.681005 -0.761813 0.627981 0.158997 -0.60463 0.763136 0.228136
-0.814006 -0.0307172 0.580043 0.886447 0.0448204 0.460654 0.430911 -0.899216 0.0756766
--0.834017 -0.476581 -0.278006 -0.764471 -0.420901 0.488289 0.924827 -0.288031 0.248461
-0.450952 0.742645 0.495097 0.305142 0.933735 0.187154 -0.0974951 0.822038 0.561025
--0.171133 0.677401 0.715431 0.820962 -0.56521 0.0809879 0.790612 -0.611033 0.0396472
--0.853855 0.492772 -0.167656 0.646857 0.757603 -0.0872544 -0.877944 0.231183 0.419248
-0.781429 0.603208 0.159713 0.123034 0.954677 0.271024 -0.602238 0.663367 0.444132
-0.34682 0.829648 0.437492 -0.613503 0.560385 0.556402 -0.930951 -0.131847 0.340508
-0.912091 -0.165588 0.375061 -0.143247 0.962328 0.231093 0.527443 0.704356 0.475065
--0.73662 0.673403 -0.0626066 0.625738 -0.779689 0.0231755 -0.976936 0.0585186 -0.205357
--0.89319 -0.443772 0.0726446 -0.912663 -0.0641022 0.403654 -0.90457 -0.120245 0.409015
--0.965814 -0.207253 0.155725 0.858966 -0.460974 0.222893 0.701885 -0.712257 0.00691512
--0.0340011 -0.827361 -0.560641 -0.77167 -0.338782 -0.538287 -0.920225 -0.319336 -0.226298
--0.732257 -0.679953 -0.0382439 -0.334789 -0.932627 -0.134624 0.981843 0.0730674 -0.175057
-0.983404 0.0459665 -0.175508 0.718093 0.695021 0.0358886 0.456378 0.889457 0.0242122
--0.1093 0.976869 0.183793 0.556377 -0.828232 0.0669081 0.797056 -0.599337 -0.0741447
--0.275749 0.624835 -0.730441 0.548589 -0.822883 -0.148032 -0.300049 -0.862642 -0.40721
--0.0534147 -0.986391 -0.155496 0.823127 0.469235 0.319814 0.476461 0.682057 0.554783
-0.120242 0.901814 0.415057 -0.969943 -0.0365535 0.240573 0.530243 0.845 -0.0694078
-0.963615 0.235028 -0.127307 -0.222518 -0.971662 -0.0797357 0.242703 0.955643 -0.166858
-0.707656 0.647572 0.282617 0.86375 0.462908 0.199128 0.730136 0.380012 0.567884
--0.908267 0.17841 0.378445 0.897266 0.327638 0.295917 0.62797 0.65202 0.424882
--0.969913 -0.13204 -0.204533 0.309728 0.939509 -0.14626 -0.584816 0.811083 -0.0116035
--0.992025 0.114754 0.0521341 -0.201264 0.967781 -0.151305 -0.487205 0.867834 -0.097441
-0.836936 0.531264 -0.131514 0.742367 0.667217 -0.060933 -0.217208 -0.87413 0.434416
-0.306422 -0.94591 0.106581 0.252596 -0.8055 0.536064 0.24317 -0.940582 0.23701
-0.939034 0.195763 -0.282652 -0.749052 0.542011 -0.380979 0.921365 0.165175 -0.351857
-0.740634 -0.384329 -0.551138 -0.363888 -0.907528 -0.209711 0.17328 -0.958524 -0.226288
--0.30323 -0.952143 0.0384092 0.880712 -0.439715 -0.176057 0.661341 -0.740603 -0.118893
-0.101353 -0.994637 0.0206142 0.161383 -0.981749 -0.100616 -0.2495 -0.842061 -0.478208
--0.145196 -0.923357 -0.355428 -0.868831 -0.186722 -0.45855 0.810466 -0.25963 -0.525107
--0.265396 -0.940805 -0.210834 0.648096 -0.363566 -0.669172 0.960941 -0.0105021 -0.276555
--0.946306 -0.226291 0.230862 -0.652514 0.00526221 0.757758 -0.0437809 -0.718007 0.694657
--0.938791 -0.336283 0.0747297 -0.2118 -0.969823 -0.120763 -0.275402 -0.950996 -0.14057
--0.440281 -0.522193 0.730388 -0.718678 0.327717 0.613272 0.672565 -0.325607 0.664558
--0.907898 0.41903 -0.0116397 -0.970987 -0.18132 -0.15591 0.48366 -0.870587 0.0902831
-0.525126 -0.0145868 0.850899 0.749726 -0.646576 0.140888 0.598312 0.444461 0.666691
--0.655326 -0.6746 -0.339799 0.823216 0.128127 0.553081 -0.154807 0.877656 0.453601
--0.895835 0.440452 0.0590113 -0.84036 0.503562 -0.200553 -0.708394 0.702903 -0.0640667
-0.921436 -0.36737 0.126472 0.864675 -0.498321 0.063357 -0.975243 -0.019477 -0.220276
--0.503076 -0.416689 -0.757155 0.674162 -0.732531 -0.0943632 -0.904376 0.222616 -0.364069
-0.868548 -0.388027 -0.308316 -0.747161 0.633011 -0.202603 -0.053242 0.298155 -0.953031
-0.605262 -0.671463 -0.427545 -0.961025 0.187517 -0.203144 0.899104 0.422028 0.116211
-0.801056 0.585719 -0.12346 -0.403295 0.88985 0.213356 -0.565497 0.759382 0.321795
-0.987215 0.0881084 0.13283 -0.949529 0.170702 0.263165 -0.934238 -0.356579 0.00713159
--0.299684 0.789167 0.536101 0.361516 0.893748 0.265558 -0.195447 0.951177 0.23888
-0.833412 -0.507814 0.218061 -0.258731 -0.668066 0.697672 0.698858 -0.624862 0.348059
--0.148604 0.652564 0.743019 0.14157 -0.37752 0.915116 -0.37459 0 0.927191
--0.768366 0.555973 0.317029 0.919919 0.215046 0.327879 -0.990085 0.119177 -0.0743582
-0.950314 -0.266088 0.161553 -0.239335 -0.73077 0.639291 0.260221 -0.785937 0.560881
-0.491809 -0.412485 0.766799 0.378423 0.6775 0.630706 0.380476 0.88647 0.263457
-0.756507 -0.65393 0.0085481 -0.326836 -0.884379 -0.333244 0.708466 0.655496 0.261536
-0.492276 0.868449 0.0588254 0.345989 0.851543 0.393911 0.407102 -0.693581 0.594318
--0.576904 -0.457104 0.676932 0.847669 0.337882 0.409015 0.742929 0.611445 0.272381
-0.700824 -0.712007 -0.0434908 0.475483 0.832095 0.285541 0.658145 0.658145 0.365636
-0.832426 0.0582116 0.55107 0.788202 0.0297435 0.614698 0.651707 0.465797 0.59859
--0.0346193 0.979726 0.19733 -0.147418 0.967433 0.205771 -0.718491 -0.694857 0.030725
--0.938765 0.235545 -0.251475 0.691282 -0.628592 0.356372 0.780483 -0.537356 0.319523
--0.572271 -0.45088 0.684991 -0.841616 0.255035 0.476066 0.463893 0.884295 0.0531544
-0.771709 0.6288 0.0952727 -0.100257 0.989198 0.10694 -0.166482 0.965594 0.199778
-0.387115 0.883912 0.262378 -0.480241 0.865153 -0.144492 -0.626087 0.779017 -0.0338703
--0.202675 0.97863 -0.0347442 -0.282004 0.952066 -0.118506 -0.425091 0.902906 -0.0637087
-0.5488 0.832523 0.0756593 -0.222703 0.960615 -0.166196 0.404422 0.913358 0.0471237
--0.440282 -0.87416 0.204931 0.172043 -0.927122 0.332936 0.582501 -0.701441 0.410699
-0.338416 -0.0273719 0.940598 0.223578 -0.91511 0.33554 0.337478 0.826822 0.449971
-0.951425 -0.214495 0.220867 -0.720844 -0.503891 0.475897 -0.772683 -0.576238 0.266292
-0.157717 -0.97259 -0.17086 -0.847561 0.530647 -0.0073701 0.441633 -0.883266 -0.157482
--0.707635 0.70381 0.0624759 0.566219 -0.724761 0.392579 0.507093 0.169031 0.845154
--0.379071 0.324918 0.866449 -0.934703 0.354203 0.0295169 0.8 0.6 0
--0.968274 -0.0305771 0.248014 0.323587 -0.846305 0.423153 0.923508 -0.382918 0.0225246
--0.945638 0.3199 0.0585897 -0.92389 -0.148236 0.352779 -0.821489 0.410744 0.395532
-0.567814 0.786203 -0.243869 -0.797812 -0.602791 0.0118194 0.663011 0.279608 -0.694432
--0.630759 -0.608627 0.481369 -0.875577 -0.430516 0.219137 0.123613 -0.988903 0.0824086
-0.571771 0.177228 -0.801042 -0.77956 -0.625426 -0.0335932 -0.87093 -0.45754 0.17927
-0.354707 -0.36259 -0.861807 0.030052 -0.957909 -0.285494 -0.839178 0.342522 -0.422444
-0.566257 -0.452559 -0.688871 -0.369468 -0.385142 -0.845671 -0.461181 -0.0272888 -0.886886
--0.407831 0.480728 -0.776257 -0.387238 -0.741126 -0.548433 0.35976 0.299397 -0.883705
-0.0221855 0.192274 -0.98109 -0.167261 0.957948 0.233151 0.0790021 0.974359 0.210672
-0.0416105 0.970912 0.235793 -0.619476 -0.77877 -0.0988212 0.717143 -0.250568 -0.650325
-0.757263 -0.028576 -0.652485 -0.912356 -0.36374 0.187882 -0.0381181 0.0889423 -0.995307
--0.311458 -0.934374 -0.173032 0.817402 0.19659 -0.541486 -0.223864 0.466699 -0.855615
-0.809424 -0.57816 0.102784 0.748834 -0.157649 -0.643735 -0.487377 -0.433224 -0.758143
--0.9674 -0.107489 -0.22931 0.539375 -0.353275 0.764377 0.524331 0.635553 0.566701
--0.666895 -0.611321 0.426072 -0.990641 0.130815 -0.0389483 0.391348 -0.535529 0.748368
--0.157112 -0.843336 -0.513908 -0.912871 -0.365148 0.182574 -0.749074 -0.0995502 -0.654964
-0.322788 0.0370075 -0.945748 -0.263274 0.614305 -0.743852 -0.453511 0.717401 -0.528833
-0.839846 0.311148 -0.444798 -0.965111 -0.161247 -0.206301 -0.735422 0.0232851 -0.677209
--0.862863 0.21461 -0.457613 -0.0959334 0.419003 -0.902903 0.319076 -0.0299134 -0.947257
--0.730122 0.540831 -0.417642 -0.655516 0.460633 -0.598429 -0.76833 -0.18568 -0.61253
--0.851079 -0.499786 -0.160866 -0.676383 -0.697941 -0.235342 0.28543 0.924404 -0.252995
--0.865371 -0.397553 -0.305099 -0.85425 -0.470042 -0.222078 -0.643708 -0.743483 -0.181311
--0.320134 -0.147363 -0.935841 -0.795769 -0.51946 -0.311308 -0.632008 -0.0574552 -0.772829
--0.183694 0.671357 -0.718009 -0.592225 -0.744157 0.309032 -0.0817317 -0.687508 0.721563
-0.143158 -0.823156 0.549472 -0.133221 -0.717342 -0.683866 -0.336195 -0.770448 -0.541648
--0.0824786 -0.412393 -0.907265 -0.813482 -0.171921 -0.5556 -0.777154 -0.16239 -0.607997
-0.107518 -0.295676 0.949219 0.478444 -0.722357 0.499291 0.411476 -0.257172 -0.874386
--0.564649 -0.0996439 -0.819294 0.651038 0.421969 -0.630945 -0.645161 -0.415147 0.641421
--0.109675 -0.250687 0.961836 0.281709 -0.888291 0.362738 -0.155999 -0.189428 -0.969423
-0.293346 -0.258835 -0.9203 0.263598 -0.263598 -0.927918 0.0433038 0.158781 -0.986364
-0.810293 0.23402 -0.53727 -0.0708804 -0.432877 -0.898662 0.142177 -0.277062 -0.950275
-0 0.253012 0.967463 -0.379967 -0.287542 0.879173 -0.660942 -0.710266 -0.242236
--0.00861109 -0.999963 -0.000717591 0.461757 -0.799194 -0.384797 0.388164 -0.659411 -0.643822
--0.75955 -0.379775 -0.528068 -0.502656 -0.677047 -0.537535 0.175132 0.916075 0.360742
-0.283368 0.902466 0.324436 0.715145 -0.552612 -0.428004 0.236102 -0.681105 0.693074
-0.19549 0 0.980706 0 -0.706566 0.707647 0.618815 -0.374817 0.690348
--0.866634 -0.312135 -0.389251 -0.873185 -0.478844 0.0908622 -0.31719 -0.261072 -0.911719
-0.619827 0.216219 -0.754363 0.388103 0.388103 -0.835914 -0.85118 -0.275382 -0.446831
-0.133732 -0.105788 -0.985355 0.441379 0.891117 0.105329 0.533347 -0.478644 -0.697453
-0.399762 -0.261913 0.878403 0.647459 0.00130273 0.762099 -0.587672 0.402092 0.702114
--0.626249 0.0447321 0.778338 0 -0.501806 0.86498 -0.39884 0.16758 -0.901579
-0.835364 0.271903 -0.477741 0 0.423036 -0.906113 0.360268 0.838057 -0.409717
-0.40156 -0.558507 0.725824 -0.179132 -0.569009 0.802584 0.00613572 -0.654477 0.756057
-0 -0.652141 0.758097 0 -0.724005 0.689795 0.311837 -0.623673 0.716791
-0.39968 -0.325454 0.856934 0.150796 0.552918 -0.819477 -0.138478 -0.553913 -0.820978
--0.31691 -0.636168 -0.703462 -0.715076 0.667754 -0.206811 0.343255 -0.899886 0.269038
--0.058261 -0.802942 0.593203 -0.552275 -0.591443 0.587526 -0.359813 -0.768692 0.528817
--0.0479092 -0.910276 0.411221 0.0980957 -0.972334 0.212002 -0.500128 -0.823847 -0.266735
--0.434547 -0.880381 -0.189997 -0.73962 0.325635 -0.589003 -0.274968 0 -0.961453
--0.0337316 -0.464146 -0.885116 0.837203 0.141188 -0.528353 -0.00184239 0.182397 -0.983223
-0.963078 0.266531 0.0379815 -0.880658 -0.470216 -0.0577807 -0.345702 -0.888949 0.300432
-0.496918 0.175992 -0.849764 -0.263281 -0.623355 0.736282 0.405375 -0.585225 0.70227
--0.138413 -0.989816 -0.0332621 -0.156821 -0.374803 -0.913745 0.704014 -0.179153 -0.687218
--0.160456 -0.677765 -0.717558 0.996562 0.0683127 0.0468813 0.801537 -0.0716319 -0.593639
-0.379186 0.315167 -0.869993 -0.1138 -0.710198 -0.694744 0.218208 -0.293741 -0.930646
-0.394224 0.194032 -0.898298 0.167283 0.683469 -0.710553 0 0.760034 -0.649884
--0.0681252 0.346465 -0.935586 -0.30227 -0.0259089 -0.95287 -0.455913 -0.644806 -0.613489
-0.215119 0.225875 -0.950108 0.630857 -0.376284 -0.67855 0.929806 0.170964 -0.325932
--0.779166 0.35014 -0.519905 -0.35576 0 -0.934577 0.355314 0.87052 -0.34051
-0.220674 -0.299486 -0.92823 -0.799715 -0.336722 -0.497066 0.0233819 -0.140291 -0.989834
--0.243373 0.491565 -0.836142 -0.519122 0.849473 -0.0943858 0.491325 0.164189 -0.855361
-0.199089 -0.170648 -0.965009 -0.216983 -0.760268 -0.6123 0.334149 -0.942425 -0.0134376
-0.949603 -0.279794 -0.14131 -0.584431 -0.652191 -0.482791 -0.027351 -0.537903 -0.842563
-0.189589 0.108735 -0.975824 0.740397 0.498254 -0.451171 0.777968 0.563356 -0.278201
-0.597671 -0.605605 -0.525387 0.362821 0.571128 -0.736324 0.922932 -0.229862 -0.308805
-0.385831 -0.90522 -0.178076 -0.602383 -0.761838 -0.238197 0.582575 -0.588123 -0.560998
-0.266404 -0.133202 -0.954613 0.314997 -0.0633957 -0.946973 0.850919 0.33429 -0.4052
--0.987785 -0.104239 -0.115821 0.622746 -0.404558 -0.669717 -0.375952 -0.621059 -0.68771
-0.813313 -0.240297 -0.529886 -0.244476 -0.700173 -0.670812 -0.277144 -0.705624 -0.65214
-0.73243 0.0415295 -0.679574 0.986537 0.0544296 0.154217 0.615961 0.733768 0.286663
-0.616041 0.773443 0.149261 0.70385 -0.0454097 -0.708896 -0.587203 -0.268107 -0.763748
-0.843237 -0.527389 0.103983 -0.866153 0.278655 -0.414886 -0.767205 0.639724 0.0463568
--0.694629 0.7113 0.107436 -0.313249 -0.865523 -0.390827 -0.638247 -0.707328 -0.303856
-0.512049 -0.753581 0.412215 0.0742819 -0.909603 0.408784 -0.433559 0.872504 -0.225307
-0.736309 -0.412988 -0.535994 0.183294 -0.843305 -0.505213 -0.0189262 -0.480949 -0.876544
-0.1776 -0.350125 -0.919712 -0.0818006 -0.96252 -0.258581 -0.219074 -0.955087 -0.199537
--0.527875 -0.842354 -0.10857 0.247274 -0.931592 -0.266443 -0.542872 -0.67582 -0.498556
-0.294744 -0.126319 -0.94719 -0.234806 -0.712455 -0.661267 0.820648 0.562414 -0.101129
-0.191893 0.965237 -0.177465 0.796596 0.411286 0.443034 -0.642803 0.653822 0.39915
--0.732479 0.644874 0.218203 0.916885 0.216487 0.335342 0.678735 0.709587 0.189223
--0.923451 0.383319 0.0174236 0.490758 -0.457144 -0.741739 -0.236099 -0.607113 -0.75873
--0.399497 0.916087 0.0344394 0.949939 -0.0436419 -0.309373 -0.68483 -0.249029 0.68483
-0.352752 0.647048 -0.67594 0.478836 -0.85027 0.218534 -0.74563 0.664583 0.0486281
-0.563337 0.826227 0 0.720216 -0.330099 0.610183 -0.187108 0.982319 -0.00623695
--0.315064 0.933941 -0.168785 0.245169 -0.964484 0.0982987 0.119944 -0.420374 -0.899388
-0 -0.589777 -0.807566 0 -0.699193 -0.714933 -0.378538 -0.614196 -0.692439
-0.965134 0.23815 0.10863 0.971272 0.129503 -0.19965 -0.111979 0.993081 -0.0353619
--0.886187 -0.158973 0.435201 -0.937662 0.317595 0.141153 -0.866843 -0.298306 0.399496
--0.877954 0.45548 0.147426 0.90494 -0.397534 0.151822 -0.999671 0 -0.0256326
--0.271329 -0.407547 -0.871944 0.245978 -0.70176 -0.668601 0.155893 -0.568552 -0.807741
--0.557396 -0.405064 -0.72473 0.390873 0.870007 -0.30051 0.811941 -0.582687 -0.0350249
--0.298246 -0.898246 0.322807 0.649004 -0.7604 0.0242166 -0.68699 -0.610088 0.394763
-0.452039 -0.880077 0.145346 -0.802921 -0.00613586 0.596055 -0.964678 0.15152 -0.215495
-0.0744809 -0.9757 0.206064 -0.356966 -0.474504 0.804625 -0.188334 -0.867437 -0.460525
-0.719104 -0.563221 0.407028 -0.982481 -0.104459 -0.154336 0.242026 -0.892469 0.380686
--0.564821 -0.800404 0.200825 0.627277 -0.466811 -0.623387 0.637568 0 -0.770394
--0.142326 0.906669 -0.397107 0.159465 0.955366 -0.248689 -0.76274 -0.290672 -0.577701
-0.74587 0.617038 -0.250883 -0.81045 -0.479654 -0.336309 0.402746 -0.684668 0.607475
-0.658069 -0.731188 -0.17975 0.159197 0.987019 -0.0212262 -0.608463 0.571842 0.550245
-0.81123 0.504278 0.295989 -0.931872 -0.337191 0.133854 0.361893 0.932219 0.000763488
--0.760264 0.410953 -0.503107 -0.299494 0.861957 0.409064 0.258938 0.490132 0.832299
--0.601025 0.758216 0.252739 -0.60909 0.673264 0.419195 0.330928 0.931923 0.148347
-0.370937 0.928658 4.67317e-018 -0.737688 -0.436198 0.515313 -0.717518 -0.0326145 0.695776
--0.411705 0.799192 -0.437941 -0.832317 -0.392603 -0.391294 0.807314 -0.438668 0.394733
--0.167761 -0.0524254 0.984433 0.883076 0.0169618 0.468924 0.398877 0.656771 0.63996
--0.550062 0.741453 0.38429 0.269297 0.96283 -0.0209044 -0.780604 -0.483975 0.395506
--0.406482 -0.269789 0.872918 0.439425 -0.0298928 0.897782 0.20025 0.810206 0.550878
-0.71028 0.325003 0.6244 0.163913 0.980285 0.11034 0.706998 -0.255723 0.659363
--0.681199 0.618602 0.391536 -0.0740353 0.329794 0.941146 -0.43931 0.761009 0.47736
--0.435495 0.899894 0.0231236 0.805272 0.368949 -0.464127 -0.0156035 0.915408 -0.402225
-0.781356 -0.612276 0.120833 0.814023 -0.260067 0.519357 0.473539 0.796306 0.376374
-0.298136 0.951485 0.076104 -0.445801 -0.655864 0.609183 -0.273077 -0.109231 0.955771
-0.314567 -0.56075 0.765903 -0.202444 0.91642 0.345239 -0.145551 0.836917 0.527622
-0.345219 -0.455689 0.82047 0.109863 -0.576781 0.809477 -0.291199 0 0.956663
--0.689988 0.605675 0.396327 -0.779207 0.611971 -0.135381 -0.947068 0 -0.321033
-0.905529 -0.405661 -0.124326 -0.957779 0.191881 -0.214105 0.570971 0.401648 0.71601
--0.609188 -0.793025 -0.00120155 0.22393 -0.453529 0.862651 -0.298246 -0.561404 0.77193
--0.016947 -0.995634 0.091796 0.114627 -0.984316 -0.134102 0.76324 0.626272 0.158896
--0.780768 -0.0803318 0.619635 -0.0273474 -0.683685 0.729264 0.852852 0.497026 0.160027
-0.764328 0.60805 0.214659 -0.785482 0.607238 -0.119501 -0.798365 -0.10563 -0.592837
-0.424906 -0.465741 0.776235 0.275393 -0.768981 0.576912 -0.912551 0.323436 -0.250278
--0.691563 -0.720303 -0.053888 0.814957 0.568197 0.114 0.938593 -0.152877 0.309309
--0.0306653 0.967137 0.252399 0 0.999012 0.0444406 -0.122325 0.960364 0.250475
--0.575306 -0.815582 0.0620429 0.542611 -0.663519 0.515088 -0.614936 0.786501 0.0571884
-0.309303 0.662791 0.681938 0.453619 -0.857548 -0.242571 0.325035 -0.787823 -0.523152
--0.36419 -0.582704 -0.726513 -0.753345 0.120135 -0.646559 -0.0994293 -0.867548 0.487313
-0.192513 -0.941751 -0.275761 -0.768165 0.584621 -0.26104 -0.515661 0.515661 -0.684242
--0.632944 0.637947 0.438641 -0.568495 0.59692 0.566127 -0.648077 0.761306 0.0202524
-0.159836 -0.82674 -0.539402 -0.908765 0.024747 -0.416574 0.145153 -0.79507 -0.588892
--0.802954 -0.370481 -0.466914 -0.734038 -0.250939 0.631045 -0.621609 0.359879 0.695766
--0.632406 -0.213986 0.744494 0.182029 0.923914 0.336525 0.799461 0.572663 -0.181438
-0.862405 -0.311735 0.398847 -0.388229 0.915205 0.108064 -0.31451 0.904216 -0.288925
--0.371498 -0.894791 0.247665 0.204669 0.96003 0.190926 -0.483809 0.743171 0.462196
-0.469073 0.835769 -0.285415 0.993743 -0.106441 -0.0338403 0.553575 0.609784 0.567202
-0.544186 0.493953 0.678139 -0.369926 0.908427 -0.194719 -0.441629 0.612082 -0.655987
-0.949654 0.260179 -0.174537 0.626501 -0.750153 -0.211582 -0.0895616 -0.993198 -0.0744118
--0.689787 0.338757 0.639874 -0.765414 -0.634917 -0.104983 0.668823 0.412376 -0.618564
--0.238575 0.865341 -0.440758 0.758853 -0.457257 0.463743 0.778364 -0.333329 0.532016
--0.474954 -0.633272 -0.611052 -0.785467 0.499843 -0.364964 0.0092984 -0.920542 -0.390533
--0.527143 -0.811955 0.250699 0.858022 -0.269183 -0.437423 -0.486986 0.872854 0.031162
--0.660371 -0.609574 -0.438554 -0.678026 -0.620321 -0.394313 -0.5705 0.801753 0.178105
-0.977199 0.068692 -0.200906 0.903148 -0.401399 -0.152326 -0.701963 0.447823 0.553808
--0.567391 0.769922 0.292039 -0.532566 0.790644 0.302086 0.649099 -0.74896 -0.133149
--0.538312 -0.820533 -0.192213 0.472901 -0.858963 0.196334 0.599272 -0.414755 0.684727
--0.0792451 -0.871696 -0.483598 0.136622 -0.914773 -0.380165 -0.835916 0.0272952 -0.548179
-0.789339 0.592004 0.162715 0.638063 0.749724 0.175467 0.172341 0.982346 -0.0727664
--0.449201 -0.711235 0.540705 0.119806 -0.907281 -0.403097 0.505122 -0.842952 -0.185157
--0.675275 -0.369933 -0.638086 -0.253837 -0.930737 0.263239 0.313045 -0.922659 0.225173
--0.515346 -0.804469 -0.295377 -0.0862739 0.901083 0.424979 0.724233 0.485998 0.489175
-0.257861 0.759646 0.597031 0.932992 0.115541 0.340845 0.215433 -0.0615522 0.974577
--0.360523 0.733178 0.576605 -0.246761 0.856111 0.454074 -0.418989 0.80354 0.422815
-0.40057 0.35215 0.845893 -0.927404 0.345937 0.1423 -0.343669 -0.862136 0.372308
--0.351982 -0.854814 0.381314 -0.286761 -0.742204 0.605724 -0.469965 -0.724208 0.504634
--0.533947 -0.158207 0.830585 -0.0396385 -0.87771 0.47755 0.486597 0.71118 0.507392
--0.78616 0.54793 0.285876 0.749396 0.659043 -0.0637784 -0.843981 0.279303 0.457915
-0.0431624 0.156464 0.98674 0.917384 0.352563 -0.184676 0.0663639 0.859781 0.506332
-0.982786 -0.133659 0.127544 0.330211 0.749706 0.573499 0.407645 0.733761 0.543526
--0.325328 0.325328 0.887875 0.691598 0.296399 -0.658665 -0.0286735 0.93189 0.361605
-0.811029 0.575569 0.104649 -0.835007 0.544827 0.0769864 -0.605674 0.795532 -0.0169357
-0.526432 -0.723844 -0.446005 -0.858721 0.511499 0.0311131 0.95516 -0.294414 -0.0314641
-0.654318 -0.752291 -0.0769786 -0.184002 0.950676 0.249717 -0.766319 0.484996 0.421348
-0.814556 -0.30927 0.490766 0.747596 -0.142399 0.648708 0.150572 0.983936 0.0959089
--0.707383 0.697349 -0.115389 -0.0524396 -0.830294 0.554853 -0.422703 -0.329105 0.8444
--0.0389351 0.49591 0.867501 -0.367122 -0.453782 0.811975 -0.39595 -0.444575 0.803478
-0.325111 -0.0237886 0.945377 -0.222089 0.888354 0.401875 -0.013383 0.843126 0.537549
-0.059459 0.959272 0.276154 0.465452 -0.717806 0.517792 0.500189 -0.180068 0.846987
--0.137309 0.52635 0.839108 -0.337721 0.621407 0.706963 -0.0715918 0.8342 0.546795
-0.437739 0.835922 0.331087 -0.313847 0.936785 0.154704 -0.316154 0.839023 0.442818
-0.826227 0.338002 0.450669 -0.363858 0.909645 -0.200385 0.509167 0.737621 0.443468
--0.889945 -0.0778334 -0.449378 -0.639379 0.715837 -0.280664 0.0616832 0.953938 -0.293593
-0.916946 -0.16374 -0.363867 0.805817 0.351409 -0.476624 -0.421712 0.822072 -0.382566
-0.659112 0.483905 -0.57568 0.0866908 0.99413 0.0647366 -0.620591 0.663146 -0.418456
-0.596674 0.769434 0.227927 -0.306038 -0.889423 -0.339511 -0.198727 -0.817677 -0.540288
--0.16199 0.241365 -0.956819 -0.0259789 0.777923 -0.627823 0.128085 0.577638 -0.806182
-0.241196 -0.952135 0.187785 0.615898 -0.784377 0.0736399 0.490558 -0.865848 -0.0982902
-0.397915 -0.862814 0.311793 -0.076443 0.0955537 -0.992485 0.344402 -0.593367 0.727532
-0.304721 0.557874 -0.77196 0.34759 -0.385168 0.854884 0.350881 -0.818723 0.454504
-0.719072 0.694651 0.0198988 -0.409496 0.834609 0.368431 0.669983 0.736982 -0.0893311
-0.771905 0.500695 -0.391748 0.851906 0.377427 -0.363049 -0.718531 0.695165 -0.0214196
--0.673618 0.721355 0.16089 -0.340565 0.936554 -0.0829582 -0.703328 0.708697 -0.0554788
--0.62385 0.779813 0.0519875 0.904023 -0.420476 0.0770872 -0.274518 -0.877431 -0.39339
-0.664087 -0.193795 -0.722102 -0.277649 -0.771865 -0.571957 -0.855761 0.403953 0.323256
--0.980981 -0.161503 0.107669 -0.329698 -0.941995 -0.0627997 -0.318638 -0.88094 -0.349877
--0.913812 0 -0.406138 -0.843795 0.281265 -0.457056 -0.809858 -0.0449921 -0.584898
-0.642086 -0.713429 -0.280615 -0.677066 -0.112844 -0.727219 -0.479839 -0.221464 -0.848945
--0.593281 -0.741602 -0.313121 -0.810737 -0.585093 -0.0192656 0.700229 -0.0479288 -0.712308
-0.868324 0.183022 -0.460996 -0.990763 0.0176472 0.134455 -0.989301 -0.058887 0.133477
--0.596471 -0.796965 -0.0952348 0.0651251 -0.716376 -0.694668 0.432176 -0.85327 -0.291811
--0.16173 -0.549883 -0.819434 -0.808247 -0.153567 -0.568467 -0.739123 -0.558113 -0.377104
--0.00482716 -0.391 -0.920378 0.751728 0.381391 -0.538001 -0.782525 0.595786 0.180811
--0.0433646 0.520375 -0.852836 -0.72194 -0.469261 -0.508524 0.8223 0.441605 -0.358898
--0.558705 -0.649001 0.516379 -0.122262 -0.217176 -0.968445 0.771176 0.396563 -0.498021
--0.485481 -0.729729 0.48146 -0.739498 -0.372247 -0.560869 -0.753035 -0.637183 0.164123
--0.384129 -0.85523 0.34789 -0.408185 -0.910361 0.0680309 -0.890682 -0.435701 -0.129811
--0.417446 -0.834891 0.358742 0.569232 0.182244 -0.801724 0.0217289 0.999528 -0.0217289
-0.293995 0.930985 0.216413 0.428122 0.887267 -0.171662 -0.571268 0.736852 -0.361527
-0.899559 0.311847 0.30585 0.779239 0.618808 -0.0993148 -0.939353 0.139904 -0.313118
-0.797465 -0.194225 0.57125 -0.280294 -0.779216 0.560587 -0.90969 -0.414222 -0.0297458
--0.962264 -0.226415 -0.150943 0.418821 -0.732937 0.536091 -0.672912 -0.716482 0.183962
--0.159153 -0.925074 0.344831 -0.363915 0.166424 0.916444 -0.284834 0.575146 0.766861
--0.922282 0.372087 0.104631 0.922211 -0.269318 0.277479 0.807698 -0.0695976 -0.585474
--0.481251 -0.704689 0.521355 -0.756467 -0.550158 0.353673 -0.442581 -0.785225 0.433063
--0.539279 -0.41483 0.732867 0.747241 -0.314455 -0.585448 0.842745 -0.256488 -0.473281
--0.677798 -0.551429 0.48633 0.0859382 -0.880866 0.465499 -0.52058 -0.77123 0.366334
--0.0380571 -0.938742 0.342514 0.713643 -0.198685 -0.671743 -0.350684 -0.769412 0.533878
--0.138461 -0.860866 0.48963 -0.592205 -0.572016 0.56753 0.298066 0.938909 -0.172066
-0.292737 0.360292 -0.885717 -0.609509 -0.0156955 -0.792624 -0.975401 -0.220289 -0.00809461
-0.226415 -0.509434 -0.830189 -0.63785 -0.494817 0.590172 0.277409 -0.569419 0.773826
-0.681484 -0.453204 0.574618 -0.446719 0.824045 -0.348412 0.51393 -0.765361 0.387425
--0.84761 -0.081501 0.524323 0.783492 0.61996 0.042307 -0.827831 -0.477595 -0.294276
--0.441068 -0.866097 0.235236 -0.551845 0 0.833947 0.175069 0 0.984556
-0 -0.454739 0.890625 0.17378 -0.568735 0.803953 -0.493062 -0.571798 0.655696
-0.940981 0.209107 0.266136 0.451165 -0.892154 0.0226148 -0.892489 -0.435089 0.118999
-0 -0.195557 0.980692 0.751783 0.573536 0.325388 0.752332 0.596134 0.280393
-0.197539 0.395078 0.897157 -0.561401 -0.800219 0.210897 -0.246252 -0.969016 -0.0191884
-0.809813 0.524227 0.263417 0.910246 0.379269 0.166156 -0.759757 0.291306 0.5813
--0.172447 -0.172447 0.969806 -0.196671 -0.763545 0.615078 0.959401 0.266693 0.0917839
-0.4073 -0.492154 0.769345 0.80829 0.11547 0.57735 -0.990492 -0.137568 0
--0.281662 -0.537523 0.794818 -0.280577 -0.542448 0.79185 0.121636 -0.429782 0.894702
-0.132161 0.0213975 0.990997 -0.507118 -0.507118 0.696895 0.0118686 0.999929 0.00098905
--0.0506589 -0.905106 0.422158 0.932648 0.185624 0.309373 -0.673277 -0.0968744 0.733016
-0.945484 0.297152 0.133268 0.919568 0.33984 0.197241 -0.868611 -0.38537 -0.311456
-0.368731 -0.538557 -0.757624 -0.0650865 0.0735761 -0.995163 0.337086 0.204659 -0.91896
-0.314574 -0.340888 -0.885911 -0.876715 0.23123 0.421787 -0.0176222 -0.418527 0.908033
--0.135326 -0.582698 0.801342 0.540635 -0.138302 0.829811 -0.499233 0.0274447 0.866033
--0.159867 -0.188933 0.968889 0.947565 0.0485338 0.315855 -0.782687 -0.538732 0.311719
--0.904768 0.392635 0.165021 0.363733 0.544511 -0.755781 0.0826539 0.870818 -0.484608
--0.0118038 0.755442 -0.65511 0.385896 -0.0110256 -0.922476 0.569415 -0.251897 0.782505
-0.0355019 -0.443773 0.895436 -0.180905 -0.671932 0.718179 0.787789 -0.342626 0.511855
-0.656553 -0.632645 0.410729 -0.982679 -0.0289023 0.183048 0.56552 0.557749 -0.607538
-0.489065 0.619483 -0.614049 -0.449277 -0.587709 0.672866 -0.210012 -0.926893 0.31107
-0.562404 0.778392 0.278941 0.605463 0.762982 0.226433 -0.0221856 0.321691 0.946585
--0.27345 0.626657 0.729744 -0.143918 0.949248 0.279671 0.882628 -0.233014 -0.408256
-0.583178 -0.479771 -0.655532 -0.0129257 -0.843399 -0.537133 0.313224 -0.792495 -0.523299
-0.137234 -0.772338 -0.620211 0.129915 -0.75587 -0.641702 0.529696 -0.815144 0.23444
--0.376512 -0.909517 0.176119 0.867327 -0.412509 0.278532 0.433694 -0.501216 0.748794
-0.882248 0.0577171 0.467234 0 -0.689184 0.724587 0.620613 -0.297554 0.725466
-0.673255 0.290017 0.68016 0.684599 0.489865 0.539775 0.648062 -0.539542 -0.537504
-0.024134 -0.877121 -0.479664 -0.377302 -0.747617 -0.546545 -0.405857 -0.789166 -0.460973
--0.270585 -0.947047 -0.172874 -0.309803 -0.727292 -0.612428 -0.370652 -0.833377 0.409999
-0.449384 -0.755973 -0.475983 -0.0992201 -0.988232 -0.116418 0.163172 -0.979035 0.121923
-0.965393 0.0546449 0.25501 0.955532 -0.241761 0.168849 0.268769 0.761512 0.589799
--0.717536 0.694877 -0.0478357 -0.878072 -0.435326 0.1987 -0.918316 -0.395168 0.0232011
--0.201291 0.978272 0.0496517 0.217787 -0.745062 -0.630437 0.247182 -0.72645 -0.641226
--0.0932922 -0.713411 -0.694508 -0.124591 -0.662302 -0.738805 -0.126111 -0.693611 -0.709225
--0.819069 0.565132 -0.0987529 -0.93673 0.326121 -0.12721 0.80039 -0.0188981 0.599181
-0.773185 -0.036082 0.633153 -0.974482 -0.214048 0.0675941 -0.118932 -0.793781 -0.596462
-0.660087 0.660087 0.358566 -0.683426 0.729604 0.024628 0.825296 0.293417 -0.482486
-0.400152 0.639933 -0.656022 -0.330778 0.873827 -0.356389 0.728524 -0.414529 0.54536
--0.993146 0.0522708 -0.104542 0.42005 -0.725105 0.545692 0.53976 -0.725303 0.42731
-0.480591 -0.756341 0.443825 -0.920498 0.114466 -0.373605 -0.37285 0.915915 -0.1486
-0 0.80975 -0.586775 0.279475 0.784908 -0.553003 0.0700335 0.964906 -0.253084
--0.229426 0.964466 -0.131031 0.0737118 -0.986604 -0.145533 0.840993 -0.434513 -0.322381
-0.52657 -0.182274 -0.830361 0.312081 -0.92946 -0.196747 -0.334275 -0.315173 -0.888215
-0.27134 0.943793 -0.188759 -0.401074 0.860683 -0.313632 -0.378267 0.342242 0.860107
-0.976251 -0.205526 -0.0685088 -0.122878 0.988872 0.0838688 -0.872789 0.417421 0.252982
-0.976102 0.0377658 0.214006 0.651681 0.75762 -0.0363829 0.364101 -0.7756 0.51563
-0.742195 -0.656862 0.13296 -0.871366 -0.309023 0.381085 0.146872 -0.78273 0.604783
-0.877004 -0.372166 0.303901 0.957069 0.0118614 0.289617 0.558115 -0.796969 0.230971
--0.82509 -0.437877 0.357057 -0.399533 -0.528 0.749392 -0.730739 0.540921 0.416443
-0 0.845299 0.534293 0.134867 0.990863 0.000917466 0.606041 0.795429 0.00252517
-0.836213 0.470829 -0.28119 -0.445512 0.860086 0.248538 0.423396 -0.729626 0.537012
--0.305044 -0.934501 0.183457 0.806679 0.590989 0.000539224 0.342321 -0.222509 0.912856
-0.241416 0.64858 0.721846 0.200802 0.312538 0.928439 -0.535649 -0.204807 0.819228
--0.982708 0.1121 0.147371 -0.0159597 -0.877784 0.478791 0.67601 -0.720258 -0.155687
--0.49998 0.862466 0.0785683 -0.533904 0.782134 0.321267 -0.826654 0.296921 0.477997
-0.226547 -0.841459 0.490534 -0.495535 -0.31297 0.810244 -0.299892 -0.886638 0.352048
-0.54181 -0.725035 0.425165 0.245359 -0.500156 0.830447 0.363325 0.835104 -0.413033
--0.590006 0.548805 -0.592204 -0.116529 0.169081 0.978689 -0.706242 0.684456 0.180948
--0.309995 0.476063 -0.822962 0.95009 -0.19489 -0.243613 0.475945 0.655064 -0.586828
-0.728125 -0.630945 0.267849 -0.0407481 0.890951 0.452267 -0.582969 0.80907 0.0745233
--0.0549774 0.923621 -0.379344 -0.513722 0.834798 -0.197997 -0.557588 0.811228 -0.176081
-0.765321 0.26353 0.587227 -0.675956 0.731082 -0.0927525 -0.58211 0.40905 0.702727
--0.594237 0.801932 -0.0615391 0.723883 -0.685921 -0.0742002 -0.896904 0.294657 -0.329758
--0.638909 0.729387 -0.244521 -0.666179 0.460368 -0.586743 -0.678242 0.413304 -0.607592
-0.960313 0.122187 0.250738 0.913422 0.404416 0.0459035 -0.4968 0.867295 0.0314359
-0.876056 0.259828 -0.40622 -0.341332 0.898593 -0.275723 -0.872526 -0.119972 -0.473609
-0.584025 0.805516 0.100298 0.222134 -0.456384 0.861609 -0.311531 -0.914709 -0.2574
-0 -0.983582 -0.180463 -0.174272 -0.894402 -0.411915 0.0946618 0.636816 0.765183
--0.989303 -0.0594693 -0.133204 -0.20138 -0.47599 0.856084 0.892971 0.140995 0.427462
-0.222449 0.826241 0.517535 0.530197 0.745678 -0.403554 0.774297 0.526993 -0.350347
-0.494518 -0.85912 -0.131778 0.620653 -0.776792 -0.106695 -0.426685 -0.694779 -0.578983
-0.764098 0.363617 0.532858 0.361256 -0.794763 0.487695 -0.622033 -0.551448 0.55586
-0.959018 0 -0.283346 -0.194219 -0.920341 0.339488 0.208337 -0.876339 0.434311
--0.928985 0.364538 0.0640229 -0.707637 0.435469 0.556432 0.714521 0.136193 0.68623
-0.608432 -0.0612033 0.791242 -0.74959 -0.617309 -0.23884 -0.597472 -0.792565 -0.121933
--0.501535 -0.844691 -0.186976 0.84596 -0.484014 0.223791 -0.862354 -0.505442 -0.029558
--0.879617 -0.473284 -0.0477132 0.92322 0.0869844 -0.374296 0.78666 -0.248249 -0.565277
--0.44754 -0.888317 0.102961 -0.342413 -0.924516 -0.167402 -0.0276609 0.874084 -0.484987
--0.325084 0.945244 -0.0288963 0.774788 -0.615273 0.145408 -0.424469 -0.859505 0.28474
-0.873828 0.160835 -0.458865 0.630084 -0.422443 -0.651564 0.195384 -0.784541 -0.58849
--0.508922 0.675479 0.533597 -0.0545349 0.974688 0.216818 -0.177901 0.899011 0.400164
--0.476704 0.727146 0.493976 -0.908257 -0.416233 0.0426587 0.751682 -0.652623 0.0951742
--0.435742 -0.86247 0.257439 0.507963 -0.736138 -0.447297 0.0781703 -0.906776 -0.414303
--0.335164 -0.918402 -0.210247 -0.596191 -0.122268 0.793478 -0.649051 0.102482 0.75381
-0.888894 0.165376 0.427221 -0.918033 -0.393443 -0.0491803 0.527496 0.805815 0.269091
--0.929075 0.360048 0.0847665 -0.633245 -0.697642 0.335107 -0.17146 -0.925188 0.338568
--0.377802 -0.763377 0.523947 -0.278163 0.960533 0.00144877 0.636431 -0.383329 0.669338
-0.354603 -0.839506 0.411687 -0.952117 0.07129 0.297306 0.0171572 0.998693 0.0481355
-0 -0.974802 -0.22307 0.271945 -0.960733 -0.055124 -0.334501 -0.836773 0.433497
-0.599162 0.800444 -0.0171635 0.212221 -0.88361 0.417367 0.677376 -0.693698 0.244835
-0.0219415 -0.727446 0.685814 -0.269743 0.351839 0.896352 -0.34553 0.8828 0.318234
--0.0328036 0.880377 0.47314 -0.689033 0.714695 -0.120185 0.605622 -0.175543 0.776149
-0.535361 0.414935 0.735675 -0.885942 0.3648 -0.286406 -0.277827 0.845221 -0.456524
--0.169461 0.782128 -0.599632 0.584915 -0.779887 -0.222825 0.302739 -0.930641 -0.205563
-0.185381 -0.975458 0.118806 0.976954 -0.144377 0.157211 0.631576 -0.672323 0.386125
--0.86472 -0.0238269 -0.50169 -0.64589 -0.25329 -0.720188 -0.557171 0.78004 0.284777
--0.708727 0.590606 0.385863 -0.848634 -0.494632 0.187508 -0.969816 0.231324 -0.0771081
-0.194631 0.915417 -0.352322 -0.327382 0.944849 -0.00897883 0.605589 -0.789899 0.0965432
-0.629575 -0.198813 0.751072 -0.554213 -0.810811 0.188235 -0.943854 0.328847 0.0316199
-0.365393 -0.917264 0.158477 0.149393 -0.953978 -0.260014 -0.0996518 -0.866971 -0.488294
-0.950321 0.10182 0.294147 -0.357663 -0.925321 0.125933 0.733973 0.53509 -0.418286
-0.137962 0.984228 -0.110729 0.0876307 0.820962 0.564219 -0.561393 0.773908 0.293093
-0 -0.914429 0.404747 0 -0.62788 0.77831 0.495251 -0.839773 0.222504
--0.757878 0.611192 0.228178 0.891005 -0.18472 0.414716 0.665947 -0.745266 -0.0330495
-0.63056 -0.677268 -0.379081 -0.0272008 -0.994528 -0.100869 0.815211 -0.490259 0.308346
--0.553932 0.658963 0.50885 -0.667498 -0.451267 -0.592287 0.84932 -0.116523 0.514857
--0.91859 0.380106 0.108225 -0.871966 0.38644 0.300564 0.768589 -0.638718 0.0361996
-0.619813 0.215587 0.754555 -0.34832 0.34832 0.870257 0 0.863779 -0.503871
--0.889261 -0.370525 -0.26819 0.879936 -0.288775 0.377255 -0.163912 0.861059 0.481363
-0.802858 -0.539062 0.254621 0.810407 -0.476505 0.340858 -0.870374 0.486587 -0.0753867
--0.746696 0.662248 0.0622247 -0.460255 -0.887635 -0.0164377 -0.127855 -0.990877 -0.0426184
--0.76004 0.649094 -0.0318809 0.763761 -0.609075 -0.213767 0.33931 0.0657978 0.938371
-0.995588 -0.060645 0.0715948 -0.249263 0.926948 -0.280421 -0.60159 0.767546 -0.221275
-0.749145 0.649551 0.129868 -0.317376 0.372175 0.872214 0.563123 -0.412957 0.715792
--0.501663 0.0876942 0.860607 0.907507 0.380871 0.177113 0.947121 0.282254 0.152627
--0.154801 -0.942629 -0.295781 -0.95041 -0.256197 -0.176308 0.892504 -0.0263146 0.450272
--0.0551289 0.98707 0.150511 -0.670795 0.585071 0.455769 -0.92149 0.356335 0.154539
-0.67505 0.319615 0.664947 0.838591 0.268349 0.474083 -0.525761 -0.467343 0.710751
-0.819567 -0.402838 0.407469 -0.579188 -0.780295 -0.235966 0.778029 -0.602345 -0.178473
--0.389986 -0.91729 0.0805604 -0.365704 -0.683289 -0.631962 0.744031 -0.644087 0.177679
-0 -0.993263 0.115881 0.112211 -0.94756 0.29923 0.879996 0.118177 0.460046
-0.693532 -0.704541 0.150449 -0.725772 -0.652632 0.217544 -0.815089 -0.565128 0.127516
--0.168956 -0.92926 0.328526 0.816034 0.1515 0.557796 -0.935008 -0.189282 0.299887
-0.575748 0.663926 -0.477197 -0.710934 0.680731 -0.176572 0.946574 0.153445 0.28364
-0.446711 0.893423 0.0473785 -0.685454 0.697804 -0.2079 0.604175 -0.648929 0.462455
-0.847875 -0.529405 0.0289518 0.86957 -0.48236 -0.105723 -0.817904 -0.505664 0.274477
-0.655328 0.602811 0.455153 -0.665534 0.543604 0.511428 0.719596 0.474341 0.507131
--0.725722 0.302971 0.617686 -0.974869 0.141911 0.171733 0.815892 -0.565685 -0.119664
--0.642664 -0.731708 0.227126 0.92752 -0.209047 0.30985 -0.608522 0.0747307 0.790011
--0.394443 0.661272 0.63807 -0.295373 0.945194 0.139154 -0.78874 0.613802 0.0337069
--0.385115 0.135504 -0.912866 -0.221351 0.544863 -0.808782 -0.0461717 0.998767 0.0182257
-0.416136 0.808493 0.416136 -0.826732 0.300275 0.475761 -0.963011 -0.249362 0.10212
-0.886783 -0.446581 0.119088 0.854321 -0.0678032 0.515305 0.224021 0.950944 0.213353
-0.46955 0.812992 0.344336 0.641377 0.408994 0.649123 -0.8007 0.402122 0.444046
-0.902565 0.357773 -0.239532 -0.307914 -0.902323 -0.301667 -0.241942 -0.957545 -0.156751
-0.958194 -0.283909 -0.0354887 -0.498761 -0.546262 0.672931 0.166099 -0.861342 0.480105
--0.0416921 -0.481354 0.875534 -0.920533 0.38377 -0.0730684 0.612958 -0.290349 -0.734833
--0.343579 -0.343579 -0.874017 -0.511089 -0.584102 -0.630565 -0.609956 -0.43874 -0.659894
-0.603958 -0.795944 -0.0413304 -0.917812 -0.12132 0.378026 0.931316 -0.334376 -0.144373
-0.674781 0.687675 -0.267907 0.537652 0.752712 -0.379941 -0.560346 0.828218 -0.00820018
-0.586744 0.757878 -0.285223 -0.714804 -0.0238268 -0.698919 0.790435 -0.59912 0.127544
--0.562124 0.811274 0.160782 0.154868 -0.542037 0.825961 0.668151 0.70991 0.222717
--0.240452 0.951187 -0.193456 -0.429097 0.894287 0.126991 -0.335591 -0.929912 -0.150475
--0.210184 0.97459 -0.0774362 -0.760155 -0.305761 -0.573301 0.479909 -0.87477 0.0668227
--0.721273 0.656607 -0.220527 -0.357147 0.664399 0.656521 0.28204 0.378991 0.881374
-0.702879 -0.711184 -0.0133378 0.713275 0.394178 0.579536 -0.685865 0.727432 -0.0207838
--0.568874 0.733732 -0.37151 0.371274 0.85945 0.351429 -0.715244 0.694207 -0.0806402
--0.175969 0.907842 -0.380601 0.698151 -0.713006 -0.0648637 0.389244 0.758469 -0.522699
-0.953043 -0.0914082 -0.28871 0.636914 0.756475 0.148613 0.00965772 0.950078 -0.311864
--0.274688 0.864996 -0.419915 -0.161561 0.98637 0.0311784 0.659398 -0.67938 -0.321928
-0.535644 -0.84238 0.0590073 -0.347294 -0.88035 -0.323064 -0.607834 -0.487768 -0.626594
--0.154945 -0.985868 0.0636907 -0.615443 -0.553899 -0.560737 -0.464606 -0.872205 -0.152968
-0.359253 0.146086 -0.921735 0.0444477 0.112427 -0.992665 -0.355045 -0.0730133 -0.931994
-0.0674104 0.269642 -0.960598 -0.191121 0.210233 -0.958788 -0.228765 0.591634 -0.773069
-0.00978398 0.743583 -0.668572 0.437264 0.896952 -0.0654027 0.415123 0.909468 -0.0232384
--0.538665 0.819915 -0.193856 -0.551434 0.797567 -0.244556 0.595659 -0.0374086 -0.802366
-0.414913 -0.827079 -0.379192 0.30393 -0.649204 -0.697252 0.542147 -0.715456 -0.44068
--0.522983 0.298517 -0.798359 -0.0838339 0.854366 -0.512866 0.257119 0.817507 -0.515337
--0.301512 0.819938 -0.486612 0.115936 0.830872 -0.544253 -0.568658 0.434602 -0.69839
--0.129469 0 -0.991583 0 -0.286888 -0.957964 0.396823 -0.235874 -0.887071
-0.455331 -0.659765 -0.597816 -0.0958466 -0.443734 -0.891018 0.492498 0.357252 -0.79361
--0.245426 -0.47449 -0.845355 0.115963 0.552531 -0.825386 0.419206 0.375752 -0.826484
-0.693484 -0.1517 -0.70432 -0.116862 0.629659 -0.768032 -0.205244 0.840999 -0.500595
-0.576685 0.0678454 -0.814144 -0.199622 0.829201 -0.522089 0.0382157 0.636928 -0.769975
--0.132784 0.708183 -0.69343 -0.509512 0.445823 -0.735962 0.551977 -0.296608 -0.779324
--0.621821 -0.74489 0.241819 0.173984 -0.951112 0.255176 0.0641335 0.689436 -0.721502
-0.384586 0.590081 -0.709858 -0.977292 0.141508 0.157723 -0.254904 -0.892165 0.372915
--0.299088 -0.94711 -0.116312 -0.326407 -0.940819 0.0912019 0.633746 -0.660714 -0.402272
-0.768 -0.6 -0.224 0.26906 -0.858646 0.436272 -0.570063 -0.819726 -0.0554806
--0.399285 -0.613471 -0.681341 0.514472 0.35586 -0.780181 0.833419 0.44824 -0.323255
-0.84591 0.422955 -0.324878 -0.745351 -0.643481 -0.174311 0.507703 0.58509 -0.632382
-0.641742 0.647196 -0.411466 -0.846289 -0.531477 -0.0364195 -0.0377937 0.259517 -0.964999
-0.474143 0.720697 -0.505752 0.811386 -0.298932 0.502287 0.319102 -0.78366 0.532964
--0.326634 0.0130654 -0.945061 0.480956 0.775735 -0.408554 0.816645 0.576703 -0.0224507
--0.831019 -0.250951 0.496417 -0.490006 -0.601371 -0.631068 0.893498 0.0845509 -0.441036
-0.763268 -0.637292 -0.106215 -0.0642451 -0.936143 -0.3457 -0.431452 -0.748863 -0.503044
--0.796918 -0.446582 -0.4068 0.886277 -0.276366 0.371665 -0.426638 -0.781221 -0.455712
-0.607777 0.00542658 -0.794089 0.802224 0.36572 -0.471896 -0.869659 0.49359 0.00783477
--0.71059 0.688726 -0.14394 0.885195 -0.42083 -0.198322 0.587107 -0.569098 0.575701
-0.561558 0.505402 0.65515 0.815869 0.273909 -0.509247 -0.98744 0.143628 0.0658293
--0.773334 -0.559509 -0.298167 -0.643952 -0.13365 -0.753302 -0.0106825 -0.758459 -0.651634
--0.0861221 0.5844 0.806882 0.89086 0.222715 0.395938 0.414513 -0.612759 0.672834
--0.933702 0.322464 0.155617 0.403577 -0.828969 -0.387216 -0.589968 -0.543392 -0.597213
-0.0960738 0.288221 0.952732 -0.759953 -0.595639 0.260164 0.058722 -0.998274 0
--0.823847 -0.561068 0.0804908 -0.0323125 0.972067 -0.23247 -0.555582 0.694477 -0.457198
--0.971022 -0.0357431 -0.236302 -0.924955 -0.295986 -0.238433 -0.22434 -0.931012 0.287903
-0.933969 0.324859 0.148894 0.851205 0.206353 -0.482564 -0.753044 -0.331278 0.568489
-0.750727 -0.034124 0.65973 -0.625343 -0.606951 0.490465 -0.446065 -0.592582 0.670725
--0.923537 -0.0157474 0.383186 -0.341077 0.420397 0.840793 0.207583 0.928019 0.309339
-0.548625 0.648375 0.527844 0.970118 0.191682 -0.148761 0.246795 0.943394 0.221585
--0.805546 0.109847 0.582262 -0.0574128 -0.80059 0.596456 0.939336 -0.34205 -0.0254657
--0.611717 -0.694063 0.379578 0.00944936 -0.982733 0.184787 0.837139 -0.335124 -0.432309
-0.867052 -0.144121 -0.476917 -0.62838 -0.583709 0.51422 -0.814936 -0.382599 0.435313
--0.762198 -0.396171 0.51196 0.666667 -0.133333 -0.733333 0.0066872 -0.595161 0.803579
--0.264305 -0.816942 0.512591 -0.624136 -0.289599 0.725663 0.322258 -0.314065 0.893036
--0.396763 -0.523727 0.75385 0.0234246 -0.726164 0.687123 0.174694 -0.744069 0.644859
-0.699113 0.636239 -0.326253 0.710531 -0.4222 -0.562933 -0.492213 -0.118658 0.862349
--0.155189 -0.731085 0.664403 -0.310017 -0.75782 0.574106 -0.852302 -0.171869 0.494006
--0.0637487 -0.812796 0.57905 0.22359 0.941931 -0.250547 -0.644618 -0.738952 -0.196006
-0.506935 0.76695 -0.393452 -0.467142 0.27479 -0.840398 -0.200632 -0.72536 -0.658483
--0.191611 -0.8191 -0.540704 0.358312 -0.879151 -0.314177 0.143058 0.839276 -0.524548
--0.461237 -0.864036 -0.201748 -0.550213 -0.431616 -0.714824 -0.269224 -0.423066 -0.865179
-0.0698754 -0.635866 0.76863 0.172456 -0.426183 0.888047 0.66742 0.725401 -0.168358
-0.386712 0.858631 -0.336461 -0.576683 0.384455 -0.720854 -0.435259 -0.0423404 -0.899309
--0.155511 -0.459672 0.874367 -0.433461 -0.791066 0.431655 -0.604078 0.745775 0.280909
--0.996926 -0.0772811 -0.0128802 -0.060117 -0.865685 0.496967 0.6506 0.74819 -0.13012
--0.50084 -0.797035 -0.337483 -0.98064 0.0492949 0.189512 0.0126828 -0.674 -0.738622
-0.6305 -0.339879 0.697819 0 -0.472408 0.88138 -0.445054 -0.376861 0.812344
-0.573308 0.806359 0.145269 -0.317861 0.946014 0.063428 0.555598 0.811046 0.183071
-0.554127 0.829097 0.0744419 -0.390133 -0.23242 0.890942 -0.908379 -0.416506 -0.0370227
--0.768679 -0.361731 -0.527525 0.404002 -0.404002 -0.820709 0.513144 -0.372556 -0.77323
-0.542005 -0.527357 -0.654313 -0.347528 -0.538328 -0.767742 -0.286044 -0.618654 -0.731741
--0.156417 -0.449142 0.879662 0.284843 -0.0931216 0.95404 -0.397439 0.228527 0.888717
--0.152511 0.0538274 0.986835 -0.258021 -0.488103 0.833775 -0.840079 0.294433 0.455606
--0.931626 0.2465 0.267042 0.473692 0.68183 0.557426 0.225875 -0.309977 0.923523
--0.779569 -0.550896 0.297969 0.389904 -0.322095 -0.862687 -0.457239 -0.452489 -0.765628
--0.769422 -0.129357 0.625505 0 -0.454739 0.890625 0.712958 -0.235879 0.660343
-0.590895 -0.401198 0.699916 -0.692747 0.161911 0.70277 -0.347437 -0.820281 0.454341
-0.488719 -0.57264 0.658207 -0.153549 0.472832 0.867671 -0.243055 -0.884449 0.39834
--0.0845631 0.819611 -0.566645 0.735378 0.1329 -0.664498 0.241294 -0.487415 -0.839168
--0.343322 -0.672138 -0.656019 -0.365424 -0.637432 -0.67834 -0.0832131 0.254534 0.963477
-0.120501 -0.271127 0.954971 0.309647 -0.465699 0.829001 0.604564 -0.310033 0.733745
-0.325999 -0.10161 0.939894 0.338341 0.931664 0.132394 0.71773 -0.118145 0.686225
--0.242618 -0.679331 0.692565 0.516544 0.843397 -0.147862 0.484088 0.633273 -0.603842
-0.661233 0.418971 -0.622281 0.31461 0.750833 -0.58075 -0.206203 0.904889 -0.372366
-0.0224029 0.847576 -0.530201 -0.190866 0.438992 -0.877984 0.275766 -0.529172 -0.802453
-0.31833 -0.48339 -0.815475 0.0705311 -0.712364 -0.698257 -0.131773 -0.779013 -0.613004
--0.193575 -0.71323 -0.67367 -0.489911 0.553631 0.67341 -0.276104 -0.516582 0.810499
--0.285549 -0.095183 0.953626 -0.0892342 0 0.996011 0.539156 -0.589431 0.601566
--0.474298 -0.380462 0.793908 -0.986091 -0.152084 0.0670476 0.420109 0.904591 -0.0722769
-0.441151 0.893024 -0.0888429 -0.43675 0.780551 -0.447202 0.415877 -0.883738 -0.214603
--0.188738 0.924816 -0.330292 0.121147 0.987349 -0.102302 -0.779696 0.60643 0.155939
--0.48517 -0.749809 -0.449885 -0.381799 0 0.924245 0.494724 -0.169152 0.852429
--0.456887 -0.45452 0.764635 0.0189 -0.7686 0.63945 -0.305122 0 0.952313
--0.883178 -0.0334176 0.467846 0.975461 0.0248701 0.218765 0.696289 0.690828 0.194779
-0.443242 0.89612 -0.0224833 -0.369419 -0.181656 -0.911335 0.451936 -0.885795 -0.105452
--0.72774 -0.610632 0.312287 0 -0.61519 -0.788379 0.133662 -0.61917 -0.773798
-0.113717 -0.760903 -0.638824 -0.369801 -0.665642 -0.648204 -0.0342371 -0.725827 0.687025
--0.167154 -0.297295 0.94004 0.16328 -0.569211 0.805815 0.743706 0.424975 0.516041
-0.490768 -0.208642 0.84594 0.287294 -0.721474 -0.63003 -0.742765 -0.427652 -0.515184
--0.676961 0.132552 0.723985 -0.164613 -0.420322 0.892318 -0.572824 -0.329707 0.750444
-0.272078 -0.743681 0.610665 0.659524 0.544182 0.51855 0.339597 0.25412 0.905592
--0.245284 -0.531449 0.810801 -0.310388 -0.843483 0.438401 -0.955175 -0.212261 -0.206365
--0.783488 0 0.621407 -0.31772 0.926235 0.202838 -0.397139 0.917528 0.0205417
-0.400384 0.85243 0.336236 0.123878 0.916698 0.379893 -0.310369 -0.846462 0.432636
-0.845257 0.432523 0.313791 0.655033 0.74668 0.115764 -0.407329 -0.878302 0.250337
-0.991945 -0.101338 0.0760036 -0.997329 0 0.0730367 0.898404 0.431997 0.0790521
--0.727004 0.2812 0.626412 -0.975467 -0.00950748 -0.21994 0.728168 0.102717 0.677658
-0.59963 -0.237136 0.764337 -0.766545 0.178928 0.61676 0.568873 -0.644363 0.511057
--0.0122066 -0.772068 0.635422 -0.331944 -0.881242 0.336491 -0.0746191 -0.983867 0.162596
--0.859657 -0.459269 0.223746 0.799719 0.517609 -0.304188 0.646401 -0.609812 0.458579
--0.432498 -0.900382 -0.0475093 -0.364245 0.610786 -0.70304 -0.915037 -0.174293 0.36377
-0.824065 0.560746 -0.0804965 -0.489021 0.789957 -0.3699 0.975721 -0.136391 0.171363
--0.853388 0.426694 -0.299434 0.608354 -0.01767 0.793469 0.659089 0.0063374 0.752038
--0.948889 0.289914 0.124741 -0.314891 0.944674 0.0918433 0.831238 0.465312 -0.304185
-0.094667 0.9493 -0.299779 0.809295 -0.012302 0.587273 -0.845043 -0.423074 0.326971
-0.808137 -0.493278 -0.321855 -0.129371 0.954112 -0.270062 -0.873153 0.293771 0.388975
--0.916029 0.373197 -0.147017 -0.573422 -0.798089 0.185045 -0.728867 -0.684582 -0.0100463
-0.662043 0.367159 0.65337 0.0576586 0.897827 0.436558 -0.932517 0.345674 -0.104506
-0.773286 -0.594163 0.221355 -0.160785 0.920046 0.3573 -0.652284 -0.489828 0.578441
--0.719465 -0.527608 0.451664 -0.197394 -0.958769 0.204443 0.625048 -0.644351 0.440598
--0.450171 -0.467825 0.760583 -0.681206 -0.390797 0.619061 -0.269787 -0.926849 0.261084
-0.488812 -0.852821 0.183738 0.24203 -0.96812 0.0645413 0.152247 0.792952 -0.589956
--0.1013 0.964653 -0.243274 0.36482 0.781757 -0.505729 0.120654 0.890714 0.43826
--0.750137 0.641055 -0.162306 -0.300564 0.826551 -0.475893 0.889031 0.457648 0.0135305
-0.0175601 -0.807767 -0.589241 -0.627992 -0.250176 -0.736912 -0.832573 -0.0101197 -0.553822
--0.180239 0.959128 -0.218146 -0.975822 0.203105 0.0807432 0.446144 0.892288 0.0691209
--0.18645 -0.849383 -0.493747 -0.47971 -0.830184 -0.284029 -0.873968 -0.0771149 0.479826
--0.812278 0.330308 0.48073 0.642143 0.762545 0.0785956 0.685601 0.713303 -0.145431
-0.293974 0.551202 0.780869 -0.42041 -0.371525 0.827783 0.728482 0.0466762 -0.683473
--0.891428 -0.445714 -0.0818219 0.916834 -0.00274091 0.399259 0.532432 -0.846287 -0.0177477
-0.494079 -0.868381 0.0424209 -0.487983 0.486076 0.724985 0.620801 0.558721 0.549942
-0.311032 -0.948301 -0.0631279 0.699592 -0.699592 -0.145405 0.584159 -0.767357 -0.264427
-0.425544 -0.830331 -0.35981 0.464224 -0.858815 -0.216638 -0.188658 -0.981024 -0.044719
--0.659388 -0.746212 -0.0915165 0.771295 -0.290089 -0.566527 0.48177 0.404687 -0.777256
--0.194547 0.960578 -0.1986 -0.0345892 0.992606 0.116346 0.330335 0.739792 0.586163
--0.554409 0.671126 0.492159 0.104307 0.382459 0.918066 -0.464886 0.757472 0.458385
-0.696904 -0.420772 0.580754 0.82618 -0.563304 -0.0107296 -0.701191 -0.643716 -0.306531
--0.637416 -0.762623 -0.11003 0.58002 0.305686 -0.755071 0.385464 0.566682 -0.72821
-0.488593 0.576477 -0.654944 0.232487 0.854254 -0.464974 0.864582 0.27765 0.418818
--0.717908 0.683609 0.131478 0.481512 -0.502773 0.71789 0.654403 -0.364243 -0.662634
-0.566525 0.446772 -0.692419 -0.334364 -0.675893 0.656787 0.383583 -0.280166 0.879984
--0.82266 0.558234 0.107729 0.157532 0.984574 0.0761404 0.0894869 0.995541 0.029829
--0.456209 0.82688 -0.328851 -0.873372 0.487054 0 0.61682 0.106348 0.779887
-0.906605 -0.215459 0.362829 -0.735083 -0.479402 0.479402 -0.697206 -0.681626 0.222015
-0.337685 -0.92096 -0.194425 -0.78914 -0.39457 -0.470715 -0.451943 0.795246 -0.404142
-0.423041 0.867963 -0.260146 0.0770327 -0.99661 0.0288872 0.182021 -0.982915 0.0273032
--0.406562 -0.877078 -0.255814 0.998458 -0.0264492 0.0488051 -0.985628 -0.0467954 0.162321
--0.225258 -0.946086 -0.232767 0.908438 -0.417071 -0.0281424 0.19366 -0.937125 0.290332
-0.384013 -0.776411 -0.49972 0.370627 0.688307 -0.623594 0.881539 -0.467803 0.0636275
--0.935347 0.289678 -0.203008 0.930651 -0.101641 0.351509 -0.990077 0.12673 0.0607247
-0.505532 -0.767014 0.395129 0.780537 -0.617513 -0.0971554 -0.87798 0.432438 0.205299
-0.0433967 -0.902651 0.42818 0.291171 -0.934174 0.206246 0.979034 -0.19221 0.067442
--0.933366 0.35779 -0.0285195 0.978478 0.181628 -0.0979368 0.976701 0.111094 0.183614
-0.722059 -0.499788 0.478375 0.726421 0.682865 0.0775144 0.275503 0.771407 0.573611
-0.117289 0.640673 0.758803 0.217482 -0.931812 0.290565 0.109131 -0.992576 0.0536996
--0.850588 0.514502 0.108571 -0.755283 0.422272 0.501233 0.795559 0.595362 -0.112382
--0.965902 0.0616179 0.251468 0.393091 -0.91277 -0.111043 0.627833 0.623675 0.465677
-0.815527 0.547 0.188964 -0.129827 0.536618 0.833778 -0.629313 0.0646238 0.77446
--0.627186 -0.677179 0.384795 0.142175 -0.95994 0.241455 0.838717 -0.279572 0.467325
--0.828097 0.559978 -0.0260671 -0.793616 0.605257 0.0619489 -0.732389 0.642249 -0.226102
--0.919556 0.276615 -0.279107 -0.80546 0.577246 0.134243 0.85064 -0.515539 -0.103108
--0.529412 0.705882 0.470588 0.204655 0.708985 0.674875 -0.0936265 0.206624 0.973931
--0.430175 -0.0977054 0.897442 -0.87821 -0.40941 0.247247 0.817799 -0.572902 0.0546677
-0.274368 -0.00783907 0.961593 0.468355 0.212223 0.857674 -0.867086 -0.412898 -0.278706
-0.333247 0.773089 0.539704 -0.738222 0.0025812 0.674553 -0.729397 -0.388927 0.562775
--0.0345494 -0.958747 -0.282154 -0.759089 -0.498152 -0.41908 -0.883272 0.430186 -0.186469
-0.782948 -0.445471 0.434221 -0.702032 0.226257 0.675247 -0.818275 0.221564 0.53041
--0.759455 -0.607564 0.232583 0.038568 -0.994504 -0.0973383 0.741072 -0.553145 -0.380582
--0.402702 -0.434919 -0.805405 -0.591824 -0.313319 -0.742681 0.179559 -0.193371 -0.964555
-0.779622 -0.507457 0.366984 -0.0705151 -0.564121 0.822676 0.555662 0.789844 0.259586
-0.701905 0.712266 -0.00259006 -0.393066 -0.426583 -0.814571 -0.638362 -0.0640302 -0.767069
--0.156625 0.86731 -0.472485 -0.154957 0.923893 -0.349871 -0.566104 0.299702 -0.767923
--0.0540124 -0.900207 0.432099 0.717203 0.646973 0.258931 0.0387284 0.96821 -0.247124
--0.852252 0.233952 -0.467903 0.770828 -0.513885 -0.376492 -0.433293 0.0772538 -0.897936
--0.441542 -0.532343 -0.722254 0.586711 0.369167 -0.720754 -0.597891 -0.0128579 -0.801474
-0.817247 0.0674791 -0.572323 -0.284468 -0.924521 -0.253651 -0.0394122 -0.992603 -0.114831
-0.586584 -0.782685 -0.208143 0.210896 -0.723071 -0.657793 0.784555 -0.564991 -0.255458
--0.985826 0.125934 -0.110848 0.428532 0.836033 0.342651 0.544306 0.834603 0.0846699
--0.0273532 0.877789 0.478266 0.213399 0.87769 0.429093 -0.616112 0.724439 -0.309184
-0.725074 0.623471 0.292493 0.158607 0.929215 0.33377 0.241388 0.836883 0.491283
-0.277472 0.501692 0.819337 -0.586161 0.806416 0.0781548 -0.76939 0.377436 0.515346
-0.999076 0 -0.042971 0.901624 -0.276498 -0.332599 0.674453 0.551825 -0.490511
--0.302206 0.910816 -0.28122 -0.823832 0.322169 -0.466378 0.54395 0.390528 -0.742701
--0.786183 0.293769 -0.543706 0.923501 0.340491 0.17667 0.972855 0.221754 0.0661684
-0.249189 0.386672 0.887913 0.461058 0.675504 0.57543 -0.07817 -0.986144 -0.146318
--0.251057 -0.502114 -0.827558 0.781083 0.414068 -0.467395 0.162452 0.699794 -0.695628
-0.389264 -0.528137 -0.754682 -0.636464 -0.603463 -0.48036 0.922692 0.168944 -0.346551
--0.218208 0.877029 0.428024 0.0545856 0.846076 0.53026 -0.968434 -0.220467 -0.11632
-0.783573 -0.602749 -0.150687 0.166574 -0.760448 -0.627672 0.318941 0.528531 -0.786722
-0.707104 -0.335421 -0.622493 0.531772 -0.335856 -0.777444 0.705496 -0.264561 -0.657483
-0.90796 -0.0974804 -0.407561 0.141996 -0.812534 -0.565355 0.12281 -0.973037 -0.195237
--0.830287 -0.0919985 -0.549691 -0.907136 0.412125 -0.0851879 0.813701 0.28835 -0.504723
--0.980578 0.155423 0.119629 -0.21579 0.951074 0.221118 0.884389 -0.365954 -0.289714
-0.175323 0.91001 -0.375692 -0.294649 0.955378 -0.0208338 0.803538 0.583107 -0.119636
--0.0328396 0.97026 0.239828 -0.762362 0.39702 0.511057 -0.644103 0.644103 -0.412629
--0.861474 0.501651 0.0787934 0.757674 0.631395 -0.165134 -0.173715 0.98398 -0.0400881
-0.0590994 0.98105 0.184521 -0.485725 0.794409 0.364672 -0.601819 0.71081 0.364093
-0.0892751 0.982026 0.166297 0.755531 -0.458715 0.46771 -0.778652 0.593134 0.204679
-0.253929 0.948003 0.191858 0.253345 0.957082 0.140747 -0.01281 0.999179 0.03843
--0.784161 0.61138 -0.106327 -0.472775 0.8678 0.152994 -0.20039 0.901035 0.384682
--0.450055 0.725713 0.520376 -0.466501 0.641439 0.609043 -0.307698 -0.946762 -0.0946762
-0.606794 0.794186 0.0327193 -0.768634 0.409112 0.491761 -0.83657 0.375603 0.398841
-0.0107634 0.8826 0.470002 -0.305333 0.395137 0.866394 0.0352067 0.95058 0.308477
-0.69164 0.332688 0.641056 0.845559 0.383356 0.371575 0.673364 -0.424423 0.605348
-0.810594 0.583705 0.0471877 0.558877 0.0745169 0.825896 -0.753087 0.423041 0.503881
-0.457134 -0.0489787 0.888048 -0.556414 -0.529127 0.640647 -0.88778 0.333531 0.317181
--0.997911 0.0636821 -0.0108395 -0.0206386 -0.97591 0.217196 0.576738 -0.814743 -0.059724
--0.688388 0.697176 0.20017 0.46534 0.850908 0.24375 0.204143 0.74805 0.631464
-0.620335 0.592866 0.513512 -0.0176425 -0.970336 0.241114 0.792424 -0.255187 0.554025
--0.988113 -0.0306392 -0.150643 -0.291551 0.892875 0.34318 0.188902 -0.981878 0.0152229
-0.992506 0.0577038 0.107714 -0.903829 0.0703452 -0.422071 0.506059 -0.857637 0.0914458
-0.888234 -0.41419 -0.198715 0.0314464 0.993183 0.112246 0.0985576 0.995086 -0.00950994
-0.00309445 0.996412 0.0845815 0.0966845 0.995281 0.00821502 0.970079 -0.0928306 -0.22434
-0.0858495 0.985225 0.148193 0.459898 -0.813099 0.356881 0.420206 -0.452529 0.786539
--0.67743 -0.658185 0.328451 -0.603843 -0.738414 0.300196 0.538519 -0.817208 0.20535
--0.856362 0.486709 -0.172505 0.440858 -0.896412 0.0457186 -0.496167 -0.857016 -0.139077
--0.493412 -0.695837 -0.521878 0.121931 0.738758 -0.66285 0 0.69568 -0.718351
-0.117862 0.833876 -0.53922 -0.301478 0.836417 -0.457731 0.415422 0.671664 -0.613427
-0.431768 -0.895729 0.106048 0.732543 0.0261622 -0.680218 -0.0326107 -0.605627 -0.79508
--0.827311 -0.15551 -0.539791 0.779259 -0.610771 0.140407 0.529982 -0.714323 -0.457013
-0.54406 -0.746676 -0.382718 0.444184 -0.895533 -0.026866 -0.612625 -0.722253 -0.321001
-0.471829 0.688978 -0.55017 -0.223669 0.688465 -0.689919 -0.13129 0.774159 -0.619226
-0.0911533 0.299504 -0.949731 0.892607 -0.318788 -0.318788 0.0223457 -0.938521 -0.344497
--0.444963 -0.874583 -0.192647 -0.60169 -0.575867 -0.553486 0.342074 0.724872 -0.597951
--0.270215 0.628249 -0.72958 0.121069 0.407716 -0.905047 -0.23157 0.605852 -0.76113
--0.342352 0.569403 -0.747379 0.117507 0.568803 -0.814036 0.023847 0.7614 -0.647843
--0.526226 0.585519 -0.616648 -0.231181 0.854087 -0.46593 -0.784243 0.54556 -0.295512
-0.9009 -0.345628 -0.262526 -0.35482 -0.906762 -0.227786 -0.227612 -0.699695 -0.677215
-0.202606 0.162084 -0.965753 0.331769 0.539125 -0.774128 0.330417 0.788996 -0.517987
-0.22223 0.864528 -0.450783 -0.0817823 0.324208 -0.942444 0.112184 0.518025 -0.847977
--0.129178 0.172871 -0.976437 -0.715707 0.486015 -0.50155 0.0109128 0.979177 -0.202714
--0.10432 0.799788 -0.591148 -0.33193 -0.86539 -0.375397 0.188744 0.0330303 -0.981471
-0.475564 0.466758 -0.745638 0.464235 0.714406 -0.523554 0.182576 0.845068 -0.50252
-0.0765634 0.796955 -0.599166 -0.168661 0.748856 -0.640912 -0.0476265 0.483069 -0.874286
-0.356329 -0.344451 -0.868552 -0.390794 0.256037 -0.884152 -0.696654 0.171308 -0.696654
--0.126787 0.235461 -0.963578 -0.803303 0.087633 -0.589089 -0.98186 -0.11417 0.151381
--0.191918 -0.967673 0.163636 -0.00956072 -0.984755 0.173686 -0.389125 0.243203 -0.888501
--0.574119 -0.812714 0.0994146 0.00366827 0.201755 -0.979429 0.243627 0.705803 -0.665198
-0.427219 0.759135 -0.491119 -0.337822 0.445311 -0.829201 0.186444 0.445845 -0.875477
-0.329095 0.329095 -0.885095 -0.285756 0.417995 -0.862336 0.312529 0.659652 -0.683509
--0.428604 -0.898519 0.0946715 0.889324 0.0896797 -0.448398 -0.474634 0.443728 -0.76015
-0 -0.241626 -0.970369 0.664454 0.45961 -0.589287 0.0151411 0.847901 -0.529938
-0.101695 0.38983 -0.915254 0.0947333 0.271776 -0.957686 0.334016 0.513871 -0.79017
--0.798846 -0.589048 0.121934 0.652356 -0.753425 -0.0823527 0.478811 -0.806061 0.34786
-0.552936 0.535923 -0.638003 0.430075 -0.900803 0.0599109 -0.812626 0.58231 -0.0235386
-0.739027 0.451547 -0.499944 0.0858603 -0.932198 0.351618 0.592979 -0.662741 -0.45733
-0.229178 -0.965324 -0.125006 -0.865837 0.151789 -0.476745 -0.290488 0.544665 -0.786738
-0.566408 0.82264 0.0494483 0.238092 0.965783 -0.102838 -0.931211 0.271112 -0.243608
-0.913181 0.391363 0.11373 0.844132 0.522029 0.122177 -0.85241 -0.522741 -0.0118208
-0.773164 0.629435 -0.0776468 0.42169 -0.901543 0.0969401 -0.40193 -0.818801 0.409899
-0.877593 -0.00566189 -0.479373 0.996265 -0.0797012 -0.0332089 -0.630452 -0.302759 0.71475
-0.469776 -0.058722 0.88083 0.885716 -0.36621 0.285303 0.806559 -0.12566 -0.577644
--0.0478107 -0.273204 0.960767 -0.125909 -0.924588 0.359562 0.739254 -0.576042 0.348825
-0.810052 -0.236301 -0.536635 0.851356 -0.0949053 -0.515931 0.8308 -0.200538 -0.519187
--0.981549 0.0885608 0.169468 -0.779176 0.446306 0.440108 -0.266874 0.951168 0.155106
--0.220171 0.798397 0.560435 -0.198288 0.925346 0.323137 -0.313712 0.686775 0.655686
--0.669239 -0.540294 0.5101 -0.528226 0.136947 0.837988 -0.711376 0.643626 0.282292
--0.868 -0.432311 0.244301 -0.64222 -0.725087 0.248601 0.0137037 -0.986669 0.162161
--0.429028 -0.899734 0.0800853 -0.796435 -0.584053 0.156759 -0.930467 -0.266065 0.251875
--0.928756 -0.321726 0.184132 -0.459829 -0.887945 -0.0105708 0.65052 -0.359335 -0.669106
--0.595695 -0.689505 0.411983 -0.592954 -0.67838 0.433828 -0.932875 -0.201208 0.298764
--0.548243 0.146952 0.823307 -0.124359 0.683972 0.71883 -0.622472 0.77809 0.0842931
-0.294561 -0.13105 -0.946604 0.434018 0.648209 0.625663 0.560395 0.557255 0.612719
--0.768221 0 0.640184 -0.0907617 0.0819377 0.992496 -0.794135 -0.560566 0.234767
-0.744918 -0.157802 -0.648225 0.267261 -0.455916 -0.848947 -0.2543 -0.736411 -0.626921
-0.195894 -0.138278 -0.970827 -0.435293 -0.114005 0.893041 0.0790537 -0.837969 0.539961
--0.345503 -0.877873 0.331611 -0.773505 -0.630704 0.0624754 -0.194607 0.7914 -0.579495
-0.463032 -0.40981 -0.785912 -0.53091 -0.3492 0.772136 -0.48301 -0.802979 0.34918
--0.373332 -0.919782 0.120931 -0.691705 -0.620847 -0.368909 -0.378586 0.107728 0.919276
-0.772425 0 0.635105 0.311129 -0.677475 -0.666503 0 -0.913276 -0.407341
-0.69236 0.437533 -0.573761 -0.426071 -0.809534 -0.403879 0.51719 -0.292749 -0.804247
--0.275126 -0.776825 0.566435 -0.641663 -0.278551 -0.714617 0.420445 -0.544391 -0.725855
-0 -0.352946 -0.935644 0.399175 -0.536822 -0.743291 -0.378509 -0.485634 -0.787966
--0.564532 0.0903252 0.820454 0.00265338 -0.934652 0.355553 -0.0899031 -0.611341 0.786244
--0.8985 -0.252409 0.359149 0.673672 0.688717 -0.26802 -0.294485 -0.0631039 -0.95357
--0.830727 -0.420057 -0.365301 0.658488 0.719872 0.219496 -0.213353 0.963834 0.159703
--0.627803 0.700068 0.340248 0.546366 -0.561496 -0.621456 0.397347 -0.397347 -0.827182
--0.363614 -0.886822 0.285187 0.898894 -0.254554 0.356641 0.506943 -0.699884 0.50316
--0.573804 -0.538189 -0.617334 -0.483412 -0.0303714 -0.874866 0.598451 -0.619825 0.507615
-0.832499 0.445981 0.328705 -0.691032 -0.707291 0.149046 0.172447 -0.172447 -0.969806
--0.147857 -0.535454 -0.831521 -0.796696 -0.534456 0.282193 -0.197786 -0.928159 0.315279
-0.780603 -0.617143 0.0989653 0.820248 -0.568277 0.0652267 -0.973758 -0.0226455 0.226455
-0.919315 0.315586 0.235088 -0.600009 0.695182 -0.395868 0.307166 -0.557185 -0.771488
--0.357909 -0.586027 -0.726962 -0.991927 0.0148882 0.12593 -0.0436156 0.992255 -0.116308
-0.112852 0.94439 -0.308857 0 -0.699193 -0.714933 0.425581 -0.816792 0.389526
-0.554604 -0.805184 0.209984 -0.249555 -0.960203 0.125428 -0.907917 -0.0466872 0.416542
--0.819624 -0.015762 0.572686 0.897071 -0.135263 0.420675 -0.184387 0.964488 -0.189115
-0.785175 0.141838 -0.602812 -0.138233 0.990354 -0.00946802 -0.189037 -0.578924 0.793166
-0.80907 0.367141 0.458926 0.712364 0.274947 0.64571 -0.0772307 -0.724038 0.685423
--0.537326 -0.828757 0.156341 0.644661 0.764466 0.00190166 -0.633842 -0.741595 0.219732
--0.918632 -0.260508 -0.29707 -0.7758 -0.123306 -0.618813 -0.869091 -0.364103 -0.334829
-0.974566 -0.0251501 0.222683 0.856428 0.260562 0.445689 0 0.286582 0.958056
--0.622242 -0.656182 0.426896 -0.357277 -0.849524 0.388152 0.37847 0.879466 0.288617
-0.498339 0.839761 0.215544 -0.144164 -0.677962 0.720822 0.23215 -0.747922 0.621868
--0.0706076 -0.723728 0.686463 -0.717444 0.105168 0.688631 -0.689846 0.489349 0.533526
--0.731974 -0.671632 0.114562 0.0533486 0.906926 0.417897 0.494058 0.56507 0.660759
-0.729844 0.00793309 0.683568 -0.482697 -0.848026 -0.218757 -0.419436 -0.885477 -0.200009
--0.00301935 0.960153 0.279458 0.440196 0.752001 0.490635 -0.518201 0.782381 0.345467
--0.205353 -0.966659 0.152971 0.211218 -0.766884 0.606033 -0.834638 0.244123 0.493745
-0.799797 -0.307182 0.515716 0.527763 -0.0232623 0.849073 0.32594 -0.211257 0.921484
--0.274095 -0.713168 0.645185 -0.883103 -0.186223 0.43064 -0.551854 -0.827781 -0.101173
-0.968937 0.238534 0.0652922 -0.743488 0.529791 0.408102 0.545829 -0.433453 0.71707
--0.0797452 0 0.996815 0.391437 -0.669001 0.631834 -0.994407 -0.0678005 0.0809839
-0.652413 -0.609865 0.449913 -0.0276256 -0.910692 0.412161 -0.462232 -0.850126 0.252242
-0.270156 -0.689204 0.672319 -0.107629 0.522768 0.845654 -0.85372 0.357847 -0.378295
-0.362319 -0.687358 0.629495 0.0133976 -0.697707 0.716258 0.0683529 -0.772767 0.630998
-0.0312361 -0.777431 0.628192 -0.367265 -0.477998 0.797894 -0.38953 0.174335 0.904364
--0.158268 0.939195 0.304735 -0.657367 -0.734704 0.167564 0.338555 -0.63728 0.692283
-0.862128 0.00451376 0.50667 0.623929 -0.736236 0.26205 0.290356 -0.758885 0.582912
-0.778424 -0.346822 0.523231 -0.606172 -0.589621 0.533762 0.75355 -0.58685 0.29626
-0.246752 -0.809346 0.532984 -0.52009 -0.821074 0.235252 -0.709675 -0.68583 0.161238
-0.724845 -0.50997 0.463175 -0.916951 -0.395842 0.0501066 0.676329 0.736447 -0.0150295
-0.767536 -0.167899 0.618626 -0.726525 -0.676171 0.122286 0.807047 0.590411 -0.00949268
-0.536529 0.75552 -0.375935 0.189109 0.866118 0.462686 0.442605 -0.872192 0.208285
-0.762131 -0.568369 -0.31002 -0.913272 -0.258988 -0.31442 0.69705 -0.0279752 0.716477
-0.789299 -0.613216 0.0311944 0.605487 -0.630201 0.486037 0.760199 -0.612195 0.21752
--0.0822578 0.740321 0.667202 -0.856848 0.386508 -0.341209 0.413355 0.908883 0.0554045
-0.863375 -0.234283 0.446873 0.839448 -0.395966 0.372208 0.172774 0.777482 0.604708
--0.370247 0.887797 0.273373 -0.0265889 0.868572 0.49485 -0.703839 0.614933 -0.355624
-0.703157 -0.559768 0.438439 -0.295777 -0.371963 0.879863 -0.402732 -0.826118 0.394127
-0.751439 -0.644091 0.143131 -0.202927 0.96954 -0.137164 0.159409 0.299785 -0.940594
--0.345135 0.446563 0.825508 -0.755784 0.644915 0.113472 -0.0127457 -0.939996 0.340948
-0.554481 -0.73529 -0.389744 0.0383201 0.996322 -0.0766402 0 -0.993884 0.110432
-0.0623914 0.0594204 0.996281 -0.198595 -0.0379667 0.979346 -0.552502 -0.357105 0.753139
-0.95364 -0.283515 0.100948 0.0788381 -0.996887 -0.00103734 -0.623823 -0.516158 -0.586879
-0.619117 -0.711247 -0.332898 -0.587694 0.350116 -0.729407 0.425525 -0.633559 -0.646167
--0.792719 0.125052 -0.596623 0.549647 0.682485 0.48177 0.284613 0.868068 0.406759
-0.125081 0.646252 0.752803 -0.482884 0.46248 0.743596 0.0495907 0.963994 -0.261258
--0.220279 0.885436 -0.409244 -0.769262 -0.210159 -0.603382 0.463245 0.863706 -0.198534
-0.457551 0.889148 0.00801034 0.106283 0.978284 0.177943 -0.824598 0.385214 0.414305
--0.970146 -0.233118 0.0668742 0.99625 0.0510898 -0.0698227 -0.35326 0.855806 0.377895
--0.221715 0.565373 0.794478 -0.193881 0.320325 0.927255 -0.925243 0.0155069 0.379057
--0.843303 0.0018575 -0.537435 -0.894793 -0.13778 -0.424691 0.799902 0.47053 -0.372503
--0.316261 0.67903 0.662493 0.597121 0.11642 0.793658 -0.584023 0.460358 0.668572
--0.651687 0.267705 0.709675 0.730825 0.375507 0.56999 0.678212 0.452142 0.579306
-0.440507 0.652459 0.616645 -0.343026 0.883311 0.319524 0.00573542 0.81443 0.580234
--0.074976 0.995877 -0.0510706 0.256632 0.946919 -0.193609 0.713131 0.671647 -0.200836
-0.233665 0.826294 -0.512483 -0.883754 0.0489375 -0.465386 0.536882 -0.649454 -0.538486
--0.412153 0.527015 0.743226 0.47761 0.365454 0.798957 -0.198993 0.979813 0.0191922
-0.83459 -0.316449 0.45091 0.520414 0.122544 0.845075 0.585649 0.151293 0.79632
--0.742989 -0.398677 -0.53761 0.250072 0.953478 0.168357 -0.0907066 0.379318 0.920809
-0.0711989 -0.750327 0.657221 0.238656 -0.765445 0.59761 -0.858499 -0.505471 -0.086474
--0.148188 0.254037 0.955775 0.230954 0.798552 0.555855 -0.227606 0.878812 0.419385
-0.830754 -0.527494 0.177759 0.483491 -0.84246 0.237692 -0.547495 -0.79833 -0.250835
--0.596855 -0.778153 -0.195557 0.657571 0.553195 0.511444 -0.588348 0.784465 0.196116
-0.751382 -0.253756 -0.609125 0.69777 0.279108 -0.659709 0.569258 0.597721 -0.564514
-0.57905 0.539268 0.611466 0.355506 -0.0334594 0.934075 -0.695148 0.718065 0.0339511
-0.258622 0.862073 0.435826 -0.32263 0.897752 -0.299919 -0.594266 0.779492 -0.198089
--0.906621 -0.139084 -0.398364 0.426953 -0.760511 0.489218 -0.229504 -0.944247 -0.236062
--0.527683 -0.828512 -0.187401 -0.532891 -0.444664 -0.719932 -0.352344 -0.932926 -0.0741776
--0.257656 -0.96621 -0.00715711 -0.25711 -0.939012 -0.228365 -0.969541 0.153364 -0.19097
-0.799125 -0.599344 0.0467573 0.777426 -0.628471 0.025166 -0.966318 -0.256574 -0.0199928
-0.894109 0.296593 -0.335562 0.690268 -0.711399 -0.132067 0.686383 -0.11969 -0.717323
-0.713259 0.632277 -0.302469 -0.712278 0.651226 -0.261847 0.255656 -0.941177 -0.220965
-0.828486 0.555535 0.0706461 -0.666811 -0.742253 -0.0665188 0.837255 0.52587 -0.149886
--0.935068 -0.289133 -0.205059 0.703161 -0.689533 -0.173519 -0.949556 -0.0091597 -0.313465
-0.590602 0.309984 0.74505 -0.830706 -0.480177 0.281704 0.508962 -0.840972 0.18364
-0.259785 0 -0.965666 0.837165 0.429937 0.338096 -0.454403 -0.495712 0.740126
--0.77485 -0.478956 -0.412563 -0.0814985 -0.995301 0.0522949 0.714269 0.236299 -0.658774
--0.634238 -0.369972 0.678869 0.781088 0.618361 0.0867875 0.474481 0.800686 0.365746
-0.520859 -0.129625 0.843744 0.90976 0.304175 0.282514 -0.746589 -0.603824 0.279288
-0.126534 -0.989943 -0.063267 -0.503895 -0.852012 -0.142002 0.410782 -0.898505 -0.15475
--0.356862 -0.172444 -0.918103 0.655409 0.607867 0.448259 -0.46487 -0.542042 0.700061
-0.00422915 -0.90081 -0.434193 -0.191351 -0.867457 -0.459242 0.821086 -0.454422 -0.345425
--0.546042 0.58859 -0.596154 -0.93058 0.113535 -0.348038 -0.753609 -0.628008 -0.194111
-0.438023 0.109506 0.892269 0.777655 0.330412 0.534866 -0.889174 -0.0967962 -0.447213
-0.160625 -0.103259 -0.981599 -0.0679258 -0.666908 -0.742038 -0.728188 0.305994 0.613279
--0.833474 -0.0123217 0.552422 -0.107566 0.0759289 0.991294 -0.180939 -0.719548 0.670456
--0.350117 -0.73456 0.58124 0.775063 0.60803 -0.171976 0.547788 -0.620137 -0.561568
--0.852937 -0.0140401 -0.521824 -0.941919 -0.217366 0.256009 0.682862 -0.72604 0.0810265
-0.226125 -0.767773 0.599494 -0.77116 -0.632747 0.0703052 0.881302 0.375022 -0.287517
-0.886711 0.28195 -0.366398 0.880522 0.266924 -0.391705 0.329377 -0.838118 -0.434821
--0.0988595 -0.97384 -0.204605 -0.467157 -0.647056 -0.602564 0.463428 0.868927 -0.173785
--0.538635 0.817571 -0.203591 0.504489 -0.246379 -0.827519 -0.159358 -0.830206 -0.534194
--0.520467 -0.546931 -0.655729 0.395295 0.796767 0.45706 -0.168681 0.984547 0.0470471
--0.256167 0.966621 0.004627 0.989896 -0.134516 0.0448385 -0.826469 0.373294 0.421427
-0.343333 -0.924358 -0.166385 0.844812 -0.0808081 -0.528926 -0.666903 0.283434 -0.689134
-0.999991 -0.00306746 -0.00306746 0.970461 -0.206424 -0.124882 -0.19123 -0.956151 0.221827
--0.207602 0.851885 -0.480826 -0.936313 0.317231 -0.150605 0.106412 -0.127695 -0.986088
--0.680817 0.732192 -0.0195712 0.139002 -0.914116 -0.380882 0.911713 0.363804 -0.190858
--0.0763092 0.985661 -0.150499 -0.0643992 0.965988 -0.250441 -0.532559 0.817202 -0.220369
-0.0588725 0.408645 0.910793 -0.376454 0.792696 0.479494 0.564532 0.8054 -0.18065
-0.888415 0.376903 -0.262037 0.042241 0.995884 -0.0801862 0.978205 -0.0670004 -0.196534
-0.558875 0.62795 0.541607 0.362945 0.798117 0.480917 -0.342674 0.920935 -0.185615
-0.686221 0.721715 0.0907074 0.728373 0.681881 -0.067155 0.296334 0.931334 -0.211667
--0.560047 0.665716 0.493123 -0.728108 0.6721 0.134687 0.809224 0.325276 0.489237
-0.26383 0.906776 0.328863 -0.983703 0.14414 0.107479 -0.429642 0.839754 0.331996
--0.563812 0.82589 0.00459786 -0.812234 0.54149 0.216943 0.298822 0.914343 0.273281
-0.258055 0.918501 0.299606 0.892747 0.334366 0.301996 -0.85362 0.219279 0.472493
--0.700469 0.62234 0.349337 0.724669 0.537697 0.430972 -0.851145 -0.338675 0.401063
-0.452102 0.322536 0.83161 0.640457 0.751488 -0.158367 -0.418052 -0.8813 -0.220325
--0.341742 -0.93979 -0.00251281 0.932318 -0.334771 -0.136788 -0.147033 0.952039 0.268335
--0.43836 -0.769566 0.464337 0.170428 0.806892 0.565579 0.381367 0.560659 0.734998
-0.368843 -0.319411 0.872887 -0.24938 -0.798426 0.54802 -0.0984517 -0.950836 0.293628
-0.66899 -0.561804 0.48665 -0.573497 0.517834 -0.634783 -0.934294 0.219331 -0.281048
-0.566153 -0.781677 -0.261631 0.839666 -0.138027 -0.525271 -0.312362 0.94996 0.00261234
-0.910303 -0.40317 0.0938195 0.401091 -0.0668485 0.913596 -0.754771 -0.55993 0.341759
--0.994941 0.0826658 -0.0570787 0.725394 0.6883 0.00686926 0.265795 0.9093 0.320198
-0 -0.185408 0.982662 -0.368689 -0.345428 0.862988 -0.823699 -0.0296295 0.566252
--0.706004 -0.644612 -0.293316 -0.313848 -0.849235 -0.424617 0.157286 0.259059 0.952969
--0.568035 0.0908856 0.817971 0.897795 -0.439829 0.0226716 -0.304582 0.64458 0.701246
--0.241642 0.283963 0.927887 -0.393831 0.65717 0.64267 -0.384949 0.88418 0.264652
-0.501991 -0.00994041 -0.864816 0.892835 0.275335 0.356421 0.996713 0.0228604 0.0777253
-0.235249 0.88545 0.400794 0.0265536 0.862992 -0.504519 -0.461695 0.619809 -0.634567
-0.015591 0.930263 -0.366562 -0.279485 -0.960092 0.0105233 -0.274154 -0.961669 0.00568194
--0.201044 -0.979353 0.0211785 -0.0885584 -0.996071 0 0 -1 0
-0 -0.999816 -0.0191892 -0.0667311 -0.997587 -0.0191465 -0.0785018 -0.996512 -0.0283222
-0 -0.999901 -0.014081 0.111426 -0.993624 -0.0171897 0.182745 -0.983081 0.0124766
-0.14425 -0.988923 0.0349697 0.209281 -0.975923 0.061447 0.20126 -0.977087 0.0692509
-0 -0.995197 0.0978883 -0.10444 -0.974769 0.197275 0 -0.983175 0.182666
-0 -0.990057 0.140664 0.0975198 -0.991451 0.0866843 -0.446082 -0.894992 0
--0.465128 -0.885243 0 -0.308237 -0.951157 -0.0170229 -0.263313 -0.964684 0.00718127
-0.1499 -0.983638 0.0999335 0.0198833 -0.994163 0.106044 -0.0851522 -0.991866 0.0946136
-0.354005 -0.919619 0.170241 0.608501 -0.760931 0.22519 0.607536 -0.761714 0.225149
--0.682813 -0.716331 0.143649 -0.43741 -0.874004 0.211633 0.30826 -0.943021 0.12525
-0.695662 -0.664041 0.274049 -0.564745 -0.825265 0 -0.610299 -0.792104 0.0102787
--0.46671 -0.884401 -0.00408499 0.430166 -0.866834 0.252104 0.146086 -0.980865 0.128695
--0.235457 -0.963758 0.125423 -0.698113 -0.704852 0.125786 0.796187 -0.442326 0.412837
-0.73523 -0.487031 0.471421 0.825203 -0.255697 0.503645 0.0075539 -0.89136 0.453234
--0.712932 -0.697357 0.0736295 -0.669195 -0.738447 0.0829133 0.863017 -0.249821 0.439079
-0.924922 -0.0660658 0.374373 -0.725353 0.565463 0.392574 -0.532116 -0.821564 0.20466
--0.668001 -0.705112 0.237892 0.336973 -0.937546 0.0863569 0.399804 -0.914306 0.0648134
--0.328104 -0.944567 0.0118388 -0.388972 -0.92125 0 -0.437541 -0.898948 0.0212141
-0.842528 -0.454397 0.289257 -0.919454 -0.060292 0.388549 -0.916877 -0.297229 0.266443
-0.614886 -0.788568 0.0086409 0.769212 -0.638913 -0.0101843 -0.489603 -0.870405 0.0518098
--0.517831 -0.854646 0.0378242 -0.475235 -0.879761 -0.0131553 -0.454792 0.773371 -0.441658
-0.457439 0.470894 -0.754327 0.637711 0.755443 -0.150434 0.195588 0.97794 -0.0733455
--0.351294 0.91877 -0.180151 0.569061 -0.803759 0.173612 -0.73254 -0.656961 0.17829
-0.15325 -0.973776 0.168149 -0.661326 -0.726081 0.188294 0.883769 -0.459398 -0.0889158
-0.908735 -0.400459 -0.117617 -0.487417 -0.870388 0.0696311 -0.486002 -0.872009 0.05833
-0.30655 0.892601 -0.330593 0.287824 0.897735 -0.33351 0.198127 0.936202 -0.290295
-0.140983 0.94177 -0.305276 0.0184246 0.95071 -0.309534 -0.266425 0.916503 -0.298396
--0.439484 0.867163 -0.23427 -0.453132 0.863108 -0.22297 0.928792 -0.271056 -0.252733
--0.708115 -0.624926 -0.328695 -0.366922 -0.927089 0.0766459 0.975779 -0.110088 -0.18904
--0.515842 -0.851813 0.0912198 -0.894821 -0.434946 0.100591 0.168938 -0.985625 0.00180683
-0.610801 -0.790751 0.0404458 0.62596 -0.778972 0.0370939 -0.679775 -0.722261 0.127458
--0.474595 -0.877109 0.0737466 0.460456 0.850674 -0.253641 0.29013 0.924335 -0.24785
-0.180154 0.948812 -0.259422 0.165823 0.939665 -0.299219 0.282149 0.900644 -0.330502
--0.455763 0.862374 -0.220434 -0.311262 0.92517 -0.217201 -0.24785 0.95001 -0.189871
--0.214222 0.959033 -0.185375 -0.184099 0.796646 -0.575728 0.589037 -0.674199 -0.445523
--0.0897068 -0.937437 -0.336401 0.961929 0.166077 -0.217051 -0.987045 0.150574 0.0554062
-0.604209 -0.796135 0.0331723 0.544451 -0.83808 0.0345683 -0.28431 -0.948035 0.142823
--0.222907 -0.964731 0.140025 0.149932 -0.97456 0.166591 -0.448672 -0.88538 0.12164
-0.327741 0.853608 -0.404893 0.356679 0.857281 -0.37128 0.427049 0.847627 -0.314894
-0.479715 0.839502 -0.255168 -0.180057 0.964724 -0.19206 -0.17241 0.949471 -0.262258
--0.401497 0.867562 -0.293492 -0.390424 0.877381 -0.278874 0.879973 0.436878 -0.186507
--0.8848 0.465867 0.00985042 0.536194 -0.843495 0.0318177 0.605344 -0.794767 0.0436388
-0.616143 -0.78655 0.0413109 -0.609367 -0.781239 0.135415 -0.454729 -0.878828 0.144508
--0.333345 -0.935307 0.118666 0.596007 0.736388 -0.320169 0.359282 0.851087 -0.382842
--0.381715 0.880964 -0.279637 -0.388603 0.850528 -0.354387 -0.421969 0.843939 -0.331223
--0.430517 0.844565 -0.318378 -0.111816 0.901373 -0.418359 0.764673 0.614553 -0.193905
-0.875611 0.446136 -0.185119 -0.87505 0.483939 0.009489 -0.87991 0.475038 0.00987847
-0.583376 -0.811049 0.043256 0.455673 -0.888468 0.0546554 -0.784014 -0.607878 0.125727
--0.812292 -0.56948 0.125995 0.52514 0.8029 -0.2821 0.470129 0.831596 -0.295679
-0.588126 0.743735 -0.317752 -0.329969 0.889279 -0.316708 -0.0609368 0.962802 -0.263247
--0.0487821 0.963446 -0.263423 -0.26952 0.919791 -0.285207 -0.465079 0.84739 -0.256188
--0.106709 0.895169 -0.432764 0.619572 0.756938 -0.207787 0.687799 0.699214 -0.195019
--0.90749 0.418979 -0.0303091 0.398396 -0.915758 0.051644 0.452701 -0.891031 0.0335334
-0.526696 -0.849625 0.02701 -0.846911 -0.50641 0.162144 0.632236 0.632236 -0.447834
-0.0810448 0.921649 -0.379466 0.311677 0.885447 -0.344734 0.533229 0.797007 -0.283632
--0.467859 0.846086 -0.255435 -0.257223 0.932138 -0.254863 -0.105308 0.967076 -0.231677
--0.149137 0.955078 -0.256094 -0.234589 0.927496 -0.291064 -0.210937 0.922849 -0.322265
-0.462607 0.856168 -0.230153 0.607283 0.764151 -0.217441 -0.915423 0.401011 -0.0345132
--0.917805 0.394702 -0.0429383 0.545751 -0.837912 0.00765966 0.536292 -0.837903 -0.101538
-0.514291 -0.852072 -0.0973555 -0.438949 -0.893575 0.0940605 -0.643464 -0.747248 0.166055
-0.331179 0.804293 -0.49339 0.652385 0.671787 -0.350849 -0.167097 0.925588 -0.339655
--0.139846 0.929562 -0.341113 -0.277767 0.902352 -0.329555 -0.162397 0.924959 -0.343624
-0.042895 0.93654 -0.347926 0.197486 0.895271 -0.399361 0.0469726 0.935839 -0.349284
-0.206169 0.91721 -0.34091 0.452113 0.861337 -0.231715 -0.906546 0.412737 -0.0884435
-0.478404 -0.874821 -0.0762803 0.525524 -0.849231 -0.0512869 0.582049 -0.812504 -0.0325002
--0.674652 -0.73764 0.0270694 -0.745972 -0.665709 0.0188854 0.565346 0.785774 -0.250884
-0.545339 0.80327 -0.239507 0.336209 0.906564 -0.255159 0.504298 0.800663 -0.323452
--0.863022 0.501553 -0.0603085 0.674282 -0.738209 -0.019787 0.792273 -0.607985 -0.0515567
--0.83483 -0.548247 0.0498406 0.640116 0.735073 -0.223426 0.569923 0.786184 -0.238962
--0.860948 0.505315 -0.058522 -0.828601 0.553486 -0.0841081 0.847111 -0.511494 -0.144143
-0.838008 -0.525074 -0.148458 -0.845244 -0.528173 0.0812146 0.607048 0.767285 -0.2068
-0.56719 0.795933 -0.211626 0.637268 0.737754 -0.222729 -0.873019 0.481051 -0.0801752
--0.889695 0.44926 -0.0812946 0.720579 -0.633612 -0.281605 0.559646 -0.819889 -0.12074
-0.563916 -0.818588 -0.109145 -0.846393 -0.523492 0.097849 -0.838657 -0.535475 0.0996064
-0.778682 0.597046 -0.192849 0.722873 0.660975 -0.201412 -0.944739 0.320337 -0.0696634
-0.635403 -0.769735 -0.0614203 0.706902 -0.706216 -0.0393486 -0.747686 -0.657963 0.0897223
-0.84117 0.510537 -0.178283 -0.985739 0.165025 -0.0329462 0.82516 -0.564333 0.0252922
-0.842692 -0.537594 0.0293678 -0.766405 -0.637963 0.0750128 0.879043 0.439522 -0.184673
-0.843606 0.506872 -0.177228 -0.98623 0.1627 -0.029661 0.892631 -0.450742 -0.00643918
--0.787627 -0.611447 0.0759991 -0.844881 -0.529365 0.0771261 0.879973 0.436878 -0.186507
--0.987768 0.15465 -0.0199549 -0.985775 0.165093 0.0315033 0.901295 -0.433181 -0.00465786
-0.906341 -0.422545 -0.0011836 -0.894208 -0.440431 0.0800783 0.917305 0.346811 -0.195637
-0.882356 0.432583 -0.185256 -0.996776 -0.0190001 0.0779493 0.860584 -0.507798 0.0391984
--0.875593 -0.477047 0.0759135 0.914808 0.347158 -0.206418 -0.918262 -0.375653 0.125218
--0.647596 0.627359 0.432481 -0.574074 0.683601 0.450698 -0.628074 0.664893 0.404278
--0.658946 0.629894 0.411126 0.833918 -0.547733 0.0675979 0.840194 -0.537841 0.0692894
--0.895805 -0.441217 0.0534809 0.914241 0.355832 -0.19377 -0.958697 -0.265429 0.102213
--0.485848 -0.696872 0.527562 -0.374688 -0.745019 0.551866 -0.538516 -0.66768 0.514008
-0.915806 -0.384406 0.116326 -0.911935 -0.4079 0.0446234 0.946198 0.252955 -0.201799
-0.916367 0.351076 -0.192397 -0.980923 -0.115036 0.156704 -0.462568 -0.72496 0.510357
-0.938309 -0.327317 0.11153 0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338
-0.951038 0.208849 -0.227835 -0.973728 -0.156552 0.165366 0.935161 -0.334447 0.116703
--0.947121 -0.318063 0.0424084 -0.946323 -0.320875 0.0388939 0.939721 0.268262 -0.21204
--0.970249 -0.173227 0.169145 0.937562 -0.330556 0.108213 -0.940597 -0.336391 0.0460259
-0.938056 0.283766 -0.198817 -0.970969 -0.173905 0.164244 0.942445 -0.316493 0.107842
-0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338 0.965795 0.178257 -0.188318
-0.94359 0.267626 -0.194972 -0.958271 -0.238916 0.156961 0.932844 -0.333618 0.136021
--0.955365 -0.292313 0.0427776 -0.964187 -0.262245 0.0396281 0.977703 0.0987872 -0.185307
--0.927979 -0.331878 0.169444 0.934909 -0.329621 0.131511 -0.967903 -0.24577 0.0525545
-0.982451 0.085296 -0.165878 -0.9542 -0.24866 0.166347 0.939229 -0.315413 0.135511
-0.937489 -0.317879 0.141657 -0.968373 -0.243346 0.0550971 0.983436 0.0874351 -0.158771
--0.970969 -0.173905 0.164244 0.951928 0.306221 -0.00782675 0.744662 0.667362 0.0103067
--0.447367 0.858657 -0.250141 -0.920055 0.277962 -0.276109 0.930883 -0.332917 0.150409
--0.959368 -0.259522 0.11073 0.980586 0.0876947 -0.175389 -0.984588 -0.0919425 0.148774
-0.972924 0.205659 -0.105466 -0.939769 -0.284404 -0.189602 0.91166 -0.378968 0.158931
--0.95251 -0.284331 0.108994 -0.94166 -0.319294 0.106431 0.976638 0.0810446 -0.199021
--0.960915 -0.208065 0.182621 0.807409 0.585228 -0.0748237 -0.999142 -0.0344532 0.0229688
-0.907595 -0.389554 0.156585 0.898921 -0.414243 0.14263 -0.935161 -0.334447 0.116703
-0.968309 -0.00756491 -0.249642 -0.943049 -0.298862 0.146083 0.827908 0.551939 -0.0996556
-0.829409 0.553701 -0.0741315 -0.988999 0.0766979 0.126484 0.923209 -0.350874 0.156754
--0.938228 -0.330791 0.101521 0.81747 0 -0.575971 0.886783 -0.136041 -0.441712
-0.953334 -0.135022 -0.270043 -0.914936 -0.375234 0.148631 0.979671 0.163446 -0.116317
--0.963879 -0.205729 0.169155 0.970969 -0.173905 0.164244 -0.942445 -0.316493 0.107842
--0.94166 -0.319294 0.106431 0.940581 -0.229456 -0.250316 -0.915144 -0.379766 0.135234
--0.912054 -0.39573 0.107493 0.975988 -0.184472 -0.115832 0.994562 -0.07154 -0.0756873
--0.924056 -0.334353 0.185281 -0.96241 -0.212743 0.168844 0.973323 -0.159799 0.164642
--0.932844 -0.333618 0.136021 0.958965 -0.188685 -0.211623 -0.929024 -0.353084 0.110664
-0.981489 0.19151 0.00177324 -0.914695 0.195669 0.353619 0.927322 -0.339685 0.157127
--0.942986 -0.305259 0.132647 0.967742 -0.176726 -0.179562 -0.944318 -0.324169 0.0563772
-0.778301 0.622885 -0.0791354 0.799704 0.595128 -0.0793504 -0.8851 0.366684 0.286604
--0.827431 0.48322 0.286107 -0.5688 -0.724941 0.388494 0.558626 0.791388 0.248278
-0.034426 0.998353 0.0459013 -0.617527 -0.693453 0.371191 0.920138 -0.349707 0.176216
--0.936023 -0.320393 0.145633 -0.927877 -0.338893 0.155552 0.979754 -0.101184 -0.172753
-0.981068 -0.085914 -0.173564 -0.938781 -0.343883 0.0208414 0.886292 0.462413 -0.0256896
--0.678384 -0.345007 0.648664 -0.819457 -0.320657 0.475047 -0.940819 -0.210288 0.26578
-0.686347 0.630996 0.361624 0.751684 0.602857 0.267457 0.706789 0.660391 0.25364
--0.819705 0.102463 0.563547 -0.8922 -0.181026 0.413774 -0.627888 -0.689446 0.361138
-0.933945 -0.320608 0.157981 -0.918705 -0.372095 0.13239 0.981989 -0.0742681 -0.173727
--0.917171 -0.398376 0.00965761 0.947075 0.290642 0.136296 -0.226875 -0.948751 0.22
--0.557122 -0.793708 0.244218 0.587346 0.306441 0.749079 0.874185 0.417752 0.247557
--0.906806 -0.303399 0.292664 -0.913171 -0.31716 0.255985 0.927322 -0.339685 0.157127
--0.956602 -0.274784 0.0969827 0.94461 -0.272176 -0.183391 -0.933106 -0.359366 0.0130463
--0.943618 -0.330819 0.0119795 0.368099 -0.609268 0.70235 0.913666 0.201007 0.353284
--0.66647 -0.719787 0.194228 -0.65525 -0.721163 0.224879 -0.297492 -0.946762 0.12305
-0.898269 0.175236 0.402994 0.92303 0.26147 0.282221 0.910131 0.340691 0.23578
--0.414276 -0.659075 0.627691 -0.768872 -0.586989 0.253535 -0.867554 -0.438009 0.23558
-0.920138 -0.349707 0.176216 -0.982641 -0.175995 0.0586652 0.91092 -0.365516 -0.19137
--0.969412 -0.230631 0.0839648 -0.755723 -0.432203 0.49202 0.948314 0.0278916 0.316105
--0.785132 -0.42864 0.44703 0.556362 -0.568725 0.605816 0.656064 -0.498123 0.566969
-0.276547 -0.769146 0.576139 -0.543138 -0.78524 0.297319 0.970969 -0.173905 0.164244
--0.982995 -0.179131 0.0404011 0.929544 -0.325885 -0.172474 -0.928036 -0.356484 0.108025
--0.781546 -0.390773 0.486295 0.32972 -0.74187 0.583879 0.982172 -0.0879557 0.166139
--0.984305 -0.174911 0.0234358 0.925966 -0.337834 -0.168689 0.922301 -0.342488 -0.17906
--0.840928 -0.522527 0.140736 0.960749 -0.239534 0.139946 -0.995476 -0.0885055 0.0345593
-0.893041 -0.408998 -0.187614 -0.8376 -0.529841 0.133024 -0.899114 -0.436794 0.0283632
-0.935161 -0.334447 0.116703 -0.997618 0 0.0689857 0.843606 -0.506872 -0.177228
-0.84233 -0.508536 -0.178528 -0.994726 -0.101503 -0.014764 0.344364 0.0153051 0.938711
-0.384816 0.25161 0.888037 0.45747 0.0714796 0.886348 0.334283 -0.276146 0.90111
-0.388453 -0.371265 0.843367 -0.0610664 0.692086 0.719227 0.341072 -0.259577 0.903488
--0.531593 0.607067 0.590659 -0.487994 -0.350143 0.799538 -0.848697 -0.414609 0.328348
-0.963556 -0.255241 0.0800755 -0.994649 0 0.103311 0.886275 -0.419608 -0.196078
--0.437057 0.874115 -0.211907 0.405084 0.914226 0.00991031 0.488817 0.86761 0.091162
-0.210173 0.928038 0.307526 -0.469168 0.310748 0.82663 0.0414232 0.925119 0.377412
--0.66882 0.299209 0.680554 -0.802416 0.0272005 0.596145 -0.797353 -0.246454 0.550898
-0.144292 -0.272552 0.95126 0.319219 -0.520209 0.792137 0.0466797 -0.855794 0.515206
--0.598057 -0.628148 0.497754 0.994258 -0.089038 0.0593587 -0.994649 0 0.103311
-0.816194 -0.5454 -0.190699 0.813785 -0.548357 -0.192508 -0.67218 -0.640671 -0.371099
--0.557019 -0.768686 -0.314406 -0.0780157 -0.84517 -0.528773 -0.740772 -0.666695 0.082308
-0 -0.853639 -0.520865 0 -0.999504 0.0314805 0 -0.994853 0.101328
-0 -0.909398 0.415926 0 -0.934997 0.354654 -0.147687 -0.912182 0.382248
--0.837426 -0.233381 0.494218 0.995086 0 0.0990135 -0.994649 0 0.103311
-0.835057 -0.518216 -0.184747 -0.926832 -0.344868 -0.148485 -0.0234658 -0.863541 -0.503732
--0.00729327 -0.99772 0.0670981 0.0127155 -0.925688 0.378074 0.995086 0 0.0990135
--0.994649 0 0.103311 0.820178 -0.547229 -0.166876 0.811536 -0.559388 -0.168805
--0.956952 -0.264351 -0.119839 -0.982107 -0.175595 -0.0680601 0.995086 0 0.0990135
--0.994649 0 0.103311 0.803754 -0.56963 -0.17176 -0.932644 -0.351766 -0.0802274
-0.994258 0.089038 0.0593587 -0.994649 0 0.103311 0.797774 -0.57796 -0.171809
-0.754661 -0.632201 -0.175526 -0.297991 -0.736701 -0.60702 -0.39539 -0.691932 -0.604067
-0.0430287 -0.774517 -0.631088 0.48321 -0.683083 -0.547637 0.485352 -0.7371 -0.470232
-0.578083 -0.662522 -0.476323 -0.928843 -0.368139 -0.0415336 -0.975413 -0.220063 0.0118953
-0.98126 0.175193 0.0802233 -0.994649 0 0.103311 0.718864 -0.672108 -0.177497
-0.695091 -0.695091 -0.183567 -0.551784 -0.551784 -0.625355 -0.58159 -0.63064 -0.513855
--0.626391 -0.584163 -0.516128 0 -0.40364 -0.914918 -0.245541 -0.613852 -0.750264
-0.773549 -0.0521494 -0.631587 -0.627189 -0.137893 0.766564 -0.935451 0.350794 0.0433079
--0.898769 0.436471 0.0413227 0.982812 0.158012 0.0954571 -0.994649 0 0.103311
-0.185375 0.17796 0.96642 0.857402 -0.483663 0.175877 -0.338906 0.897994 0.280623
--0.712029 0.66542 0.224121 -0.780361 0.588177 0.212333 0.695091 -0.695091 -0.183567
-0.695091 -0.695091 -0.183567 -0.40364 0 -0.914918 -0.613852 -0.245541 -0.750264
-0 0 -1 0.382859 -0.316729 -0.867814 0.6379 -0.38274 -0.668276
--0.837997 0.535257 -0.106115 0.979643 0.159679 0.12166 -0.994649 0 0.103311
-0.738928 -0.627898 0.244395 -0.713958 -0.294895 0.63506 -0.909343 0.239301 0.340339
-0.695091 -0.695091 -0.183567 0.673365 -0.714803 -0.188773 -0.564888 -0.451911 -0.690419
--0.522083 -0.540085 -0.660104 0 -0.342852 -0.939389 -0.229748 -0.742263 -0.629493
-0.0276674 -0.774687 -0.631739 0.58132 -0.72818 -0.36307 0.529586 -0.781548 -0.329728
--0.912074 0.372537 -0.171281 -0.961153 0.247659 -0.121864 0.973547 0.173 0.149255
--0.994649 0 0.103311 0.748742 -0.614416 0.248752 0.635278 -0.541163 0.550967
-0.674978 -0.528131 0.51525 0.4346 -0.39114 0.811253 0.647272 -0.736992 -0.194632
-0.592917 -0.77952 -0.201986 -0.374299 -0.374299 -0.848411 -0.522083 -0.540085 -0.660104
--0.484928 -0.464723 -0.740863 0 0 -1 -0.32432 -0.32432 -0.888613
--0.15923 -0.641385 -0.750514 0.129084 -0.619922 -0.773973 0.547381 -0.800591 -0.243777
-0.437088 -0.782692 -0.443111 0.570316 -0.795567 -0.204483 0.571862 -0.794706 -0.20351
--0.940204 -0.335531 -0.0586132 0.971269 0.176995 0.15909 -0.991959 -0.073494 0.103032
-0.890045 0.193488 0.412774 -0.601734 0.657157 0.45394 -0.559559 0.742089 0.36905
-0.593383 -0.776323 -0.212648 0.690387 -0.682013 -0.241294 0.695867 -0.676604 -0.240784
--0.334529 -0.559575 -0.758265 -0.351027 -0.604546 -0.715055 -0.229748 -0.742263 -0.629493
--0.511382 -0.665985 -0.543095 0 0.208691 -0.977982 0.576997 -0.552269 -0.601726
-0.695706 -0.683943 -0.219579 0.765076 -0.601888 -0.228887 -0.88332 -0.466227 -0.04877
--0.696474 -0.717474 0.012444 0.982172 0.0879557 0.166139 -0.991745 -0.0846403 0.0963246
-0.80803 0.512788 0.290062 -0.0340272 0.782625 0.621563 -0.650659 0.679684 0.338633
--0.575574 0.698237 0.425652 0.573936 -0.783507 -0.238148 0.570736 -0.786242 -0.23682
--0.304518 -0.790296 -0.531697 -0.352924 -0.764669 -0.53919 -0.269052 -0.739894 -0.616578
--0.336836 -0.759934 -0.555916 0.22181 -0.208763 -0.95248 -0.201876 -0.232063 -0.951521
-0.689665 -0.515507 -0.508541 0.911446 -0.334489 -0.239547 -0.32526 -0.94218 0.0806431
--0.310025 -0.947492 0.0783771 -0.513201 -0.857889 0.0255324 0.985993 0 0.166785
--0.995816 0 0.0913839 0.922812 -0.350879 0.159065 -0.769477 -0.246993 0.588982
--0.680666 -0.490079 0.544533 0.607283 -0.764151 -0.217441 0.598502 -0.772542 -0.21207
--0.266017 -0.752103 -0.602972 -0.278994 -0.80958 -0.516471 -0.404761 -0.769046 -0.494708
--0.0803889 -0.840429 -0.535926 -0.334393 -0.759983 -0.557321 0.968851 -0.186702 -0.162698
--0.442193 -0.895896 0.0428444 -0.484923 -0.87324 0.0479871 -0.375434 -0.9257 0.0461502
--0.346325 -0.934029 0.0874559 0.985993 0 0.166785 -0.991745 0.0846403 0.0963246
-0.492928 -0.860757 0.126966 0.0776973 -0.99064 0.112229 -0.0571247 -0.991282 0.11873
--0.493055 -0.84793 0.19471 -0.653859 -0.553454 0.515904 0.590372 -0.780377 -0.20609
-0.572871 -0.793442 -0.205594 -0.324841 -0.593574 -0.736307 -0.45913 -0.688695 -0.561159
--0.404494 -0.674157 -0.617977 -0.281767 -0.569727 -0.772022 -0.350017 -0.725961 -0.592004
-0.985853 -0.159009 -0.0530029 -0.864813 -0.480157 0.146788 -0.692506 -0.714244 0.101443
-0.983335 -0.0733832 0.166335 -0.991959 0.073494 0.103032 0.00402836 -0.993661 0.112346
-0.587596 -0.69129 -0.420535 0.58271 -0.785392 -0.208824 0.56284 -0.791292 -0.238892
-0.562033 -0.79094 -0.241935 -0.226493 -0.82773 -0.513385 -0.241248 -0.861599 -0.446595
--0.365597 -0.8165 -0.446841 -0.0694331 -0.883694 -0.462887 -0.292104 -0.823202 -0.48684
--0.431539 -0.721202 -0.541887 0.961957 -0.269611 0.0441523 -0.73451 -0.576341 0.358227
--0.952994 -0.155379 0.260117 0.970003 -0.163404 0.179981 -0.994649 0 0.103311
-0.521358 -0.801554 -0.292741 0.471267 -0.826425 -0.308107 -0.517718 -0.711862 -0.474575
--0.457399 -0.73991 -0.493274 -0.350017 -0.725961 -0.592004 0.938158 -0.332209 0.097448
--0.711954 -0.561604 0.421571 -0.738749 -0.211071 0.640077 -0.776984 0.365639 0.512449
-0.526008 0.850448 0.00736319 0.561594 0.827147 -0.0209819 -0.398197 0.911999 -0.0984787
--0.996499 -0.0379831 -0.0744768 0.973268 -0.0957941 0.20874 -0.994649 0 0.103311
-0.432317 -0.845277 -0.314021 0.277767 -0.902352 -0.329555 0.29672 -0.896508 -0.328984
-0.30655 -0.892601 -0.330593 -0.211224 -0.895818 -0.391017 -0.246372 -0.893097 -0.376401
--0.19087 -0.90133 -0.388809 -0.380769 -0.826024 -0.415571 0.91681 -0.368812 0.153092
--0.574699 -0.549468 0.606471 0.00420699 -0.37863 0.925539 -0.202648 0.572181 0.794696
-0 0.447214 0.894427 -0.630304 0.467218 0.620019 -0.614424 0.384409 0.688995
--0.597018 0.447763 0.665641 0.345204 0.927614 0.14271 0.219501 0.969407 0.109858
--0.229929 0.965862 0.119341 -0.518612 0.842456 0.14598 0.761176 0.567208 0.314463
-0.480353 0.857773 0.182992 0.412654 0.903095 0.118895 -0.83391 -0.525598 -0.168348
--0.73334 -0.668785 -0.122223 0.977765 0 0.209704 -0.990783 0.0880882 0.102909
-0.318775 -0.888499 -0.330079 0.414728 -0.854726 -0.312161 0.393909 -0.871766 -0.291306
--0.167097 -0.925588 -0.339655 -0.210937 -0.922849 -0.322265 0 -0.938787 -0.344499
--0.123661 -0.931581 -0.341855 -0.122384 -0.945694 -0.301139 -0.20314 -0.91973 -0.335902
--0.28152 -0.89949 -0.334162 0.896953 -0.419203 0.140515 0.871755 -0.470252 0.137501
--0.268549 -0.960267 0.0759533 0.175164 -0.967724 0.181186 0.856429 -0.394109 0.333477
-0.445689 -0.869571 0.212622 -0.336085 -0.93357 0.124476 0.0232069 -0.999117 -0.0350139
-0.373427 -0.908543 -0.187355 0 -0.357789 0.933803 -0.323885 -0.689561 0.647769
--0.677957 0.0739589 0.731372 0.94085 -0.210308 0.265652 0.847716 0.493216 0.195232
--0.82378 0.554737 0.116848 -0.850412 0.525255 0.0301072 0.724963 0.626742 0.285698
-0.717732 0.67434 0.173569 0.683848 0.706168 0.183517 0.425656 0.243232 0.871582
--0.379604 -0.827626 0.413445 -0.799874 -0.599905 0.017775 -0.784501 -0.613566 0.0899658
-0.97202 -0.108245 0.208472 -0.980301 0.1742 0.0930774 0.342227 -0.896509 -0.28134
-0.149137 -0.955078 -0.256094 0.0528742 -0.971123 -0.232647 0 -0.972483 -0.232972
-0 -0.90031 -0.435249 -0.0528742 -0.971123 -0.232647 -0.149137 -0.955078 -0.256094
--0.234589 -0.927496 -0.291064 0.78306 -0.599178 0.166741 -0.502994 -0.864119 0.0171964
--0.441164 -0.896792 0.0337502 -0.327019 -0.94308 0.0604809 0.970338 -0.188498 0.15137
--0.82888 -0.559316 0.0110834 -0.893176 -0.448092 -0.0380928 0.963121 0.216896 -0.159229
--0.759243 -0.172095 0.627641 -0.150614 -0.506612 0.848917 -0.326814 -0.673139 0.663383
-0.987592 -0.127364 0.091869 0.984198 -0.176688 0.0116819 -0.391963 0.905571 -0.162192
--0.806214 0.586434 -0.0781912 -0.444323 0.654278 -0.611962 -0.927756 -0.0655707 -0.367382
-0.601259 0.720474 0.345551 0.73298 0.662853 0.152857 0.686924 0.703664 0.18164
--0.284726 -0.260999 0.922394 -0.571962 -0.784995 0.237995 -0.573067 -0.796486 0.192884
--0.621233 -0.762161 0.182152 0.938767 -0.287472 0.18994 -0.981345 0.178831 0.0705833
-0.803877 -0.572697 0.160625 0.832671 -0.512363 0.210101 -0.544894 -0.838298 0.0186288
--0.480725 -0.876849 0.00632533 0.994235 0.0699282 0.081284 -0.973598 0.122971 -0.192316
-0.738164 0.649585 -0.182081 0.860037 0.474696 -0.187086 -0.991592 -0.0517088 0.118626
-0.961565 0.272979 -0.0295963 -0.799181 0.592106 -0.103538 -0.967347 0.190745 -0.166901
--0.911891 -0.333191 -0.239664 0.860748 0.472624 0.189049 0.865778 0.469974 0.171908
-0.863642 0.474633 0.169839 0.114888 0.0774826 0.990352 -0.7072 -0.65397 0.268685
--0.693397 -0.690052 0.207434 -0.602114 -0.772772 0.200705 0.965312 -0.182386 0.186835
--0.994258 0.089038 0.0593587 0.750582 -0.592685 0.292147 -0.397157 -0.917569 -0.0182601
--0.388419 -0.921292 -0.0187255 -0.450752 -0.892649 0 0.929841 0.356706 0.0903121
--0.39972 -0.799439 0.448466 -0.0508834 -0.85371 0.518257 -0.692984 0.694726 -0.192689
-0.0248318 0.980858 -0.193137 0.162674 0.967991 -0.191129 0.662743 0.717365 -0.214845
--0.984132 -0.176639 0.0168228 0.856534 0.514883 -0.0352879 0.936277 0.349317 -0.0369269
--0.942913 -0.331188 0.035067 0.403378 0.541117 0.737887 0.994668 0.0219412 0.100767
--0.704075 -0.656962 0.26959 -0.603306 -0.784298 0.14456 -0.724981 -0.660808 0.194253
-0.981579 0.0849699 0.17112 -0.998223 0 0.0595954 0.727857 -0.618455 0.296204
-0.0147027 -0.940973 0.338162 0.0770382 -0.969719 0.231757 0.582397 -0.804078 0.119466
-0.66045 -0.737666 0.140195 -0.582227 -0.812493 0.0294295 -0.179542 -0.980125 -0.0843751
-0.229626 -0.971496 -0.0588786 0.08238 -0.99386 -0.073869 -0.01356 -0.997112 -0.0747306
--0.00279177 -0.997221 -0.0744473 -0.178722 -0.983813 -0.0130727 -0.416589 -0.909073 0.00627838
-0.765165 0.633543 0.114658 0.792715 0.598654 0.114961 -0.575386 -0.405201 0.710453
--0.0360068 -0.711135 0.702133 0.631299 -0.26971 0.72713 0.13398 0.973679 -0.184389
--0.786589 -0.587223 -0.190908 0.683335 0.729251 -0.0352922 0.72863 0.683751 -0.0397755
--0.798233 -0.578233 0.168732 -0.866879 -0.482376 0.125837 0.323581 -0.942908 0.0788656
--0.502939 -0.858277 0.102046 0.973728 0.156552 0.165366 -0.998223 0 0.0595954
-0.777952 0.529219 -0.3387 0.749279 0.613653 -0.249019 0.309423 0.948679 -0.0653135
-0.20013 0.979296 0.0304582 0.089334 0.982674 0.162392 -0.235125 0.953014 0.190998
--0.546514 0.805437 0.229332 -0.568801 0.78387 0.249027 0.485678 -0.857445 0.170016
--0.159158 -0.968464 0.191691 -0.636435 -0.766822 0.0832775 0.799041 0.585829 0.135416
--0.0232585 -0.424468 0.905144 0.756611 0.346981 0.554206 -0.707849 -0.671763 -0.218369
--0.847774 -0.51472 -0.127839 -0.656344 -0.725433 -0.207267 0.407615 0.912807 0.0251809
-0.530167 0.847803 -0.012388 -0.558937 -0.792326 0.24456 -0.621979 -0.753065 0.214559
-0.322649 0.875361 -0.360058 0.278898 0.756639 -0.591366 -0.26714 0.252299 -0.930044
--0.327934 0.213539 -0.92025 -0.509336 -0.0836223 -0.856495 -0.744883 -0.440047 -0.501506
--0.865884 -0.368839 -0.337938 0.974931 0.158911 0.155747 -0.998223 0 0.0595954
-0.886257 -0.418595 -0.198309 -0.819473 -0.281649 0.499138 -0.916385 -0.078894 0.392447
--0.898507 -0.211238 0.384791 0.989082 -0.0196767 0.146045 0.938853 0.309822 0.150217
--0.784379 -0.182088 0.592953 0 -0.471215 0.882018 0.604551 -0.453413 0.654931
--0.170221 -0.958912 0.226962 0.340323 0.850809 0.400381 0.0535363 0.963654 0.261733
-0.322316 0.799344 0.507111 0.240544 0.955847 0.168803 0.119379 0.967217 0.224141
-0.0841203 0.96101 0.263407 0.242414 0.965428 0.0958381 -0.667303 -0.696589 0.263574
--0.78311 -0.594693 0.181875 -0.583646 -0.781176 0.221631 0.418615 0.897032 0.141753
-0.409875 0.900101 0.147717 0.327479 0.936939 0.122079 -0.0806806 0.996095 0.035858
--0.478523 0.849237 -0.223185 -0.616534 0.561904 -0.551498 -0.560483 0.552552 -0.616884
-0.43921 0.380418 -0.813865 0.323313 0.0668923 -0.943925 0.281222 0.55646 -0.781836
--0.414636 -0.763803 -0.494653 -0.560148 -0.737139 -0.37797 -0.491984 -0.242527 -0.836141
--0.484683 -0.846938 -0.218583 0.972022 0.172729 0.159181 -0.982641 0.175995 0.0586652
-0.524648 -0.851137 -0.0176141 0.283137 -0.958311 0.0383739 -0.286332 -0.94321 0.16843
--0.486938 -0.844547 0.222782 -0.889608 -0.255526 0.378556 0.959574 -0.242135 0.143488
-0.882036 -0.450006 0.139671 -0.742364 0.593891 0.310143 0.918054 0.0612036 0.391703
--0.299391 -0.953943 -0.0189158 -0.408799 -0.907228 -0.0991028 -0.149332 -0.981512 0.119729
--0.188888 -0.969078 0.158775 -0.214925 -0.965081 0.149754 -0.06556 -0.971108 0.22946
-0.891861 0.0964174 0.441913 0.942344 -0.105825 0.317474 -0.98989 0.00856306 0.141576
-0.574859 0.817835 0.0261383 0.550082 0.833389 0.0536054 0.453329 0.880641 0.137707
--0.874919 -0.271263 -0.401164 -0.337804 -0.855989 -0.391372 -0.25232 -0.820983 -0.512173
--0.290521 -0.933019 -0.212304 0.972073 0.177141 0.153934 -0.929024 0.353084 0.110664
-0.180625 -0.981099 0.0694205 0.0125628 -0.995155 0.0975114 -0.158983 -0.977415 0.139228
--0.314324 0.679726 0.662701 0.0455877 0.747638 0.662541 -0.27552 0.74046 0.613032
--0.470453 0.623969 0.623969 0.852567 0.518954 0.0617802 0.078002 0.972492 0.219486
--0.282537 0.936832 0.206202 0.0781423 0.967762 0.239436 0.290705 0.935707 0.19986
-0.162957 0.972994 0.163484 -0.649065 0.740365 0.174855 -0.859571 0.508927 0.0461662
-0.938298 -0.295476 0.179694 -0.323151 -0.799539 0.506271 0.539562 -0.756329 0.369918
-0.0591047 -0.990004 0.12806 -0.447683 0.826491 0.34131 -0.372896 0.864362 0.337382
--0.623361 -0.749652 -0.222359 -0.841719 -0.497379 -0.210055 0.923711 -0.300417 0.237713
--0.747978 0.635781 0.190556 0.615968 0.782256 -0.0930588 0.645985 0.760378 -0.0672901
--0.924648 -0.344908 -0.161446 0.982172 0.0879557 0.166139 -0.93006 0.340688 0.137551
--0.468715 0.338517 0.815912 0.998236 -0.0576002 -0.0143583 -0.338731 0.193561 0.920758
--0.981036 -0.193008 -0.0177724 0.970405 -0.193783 0.144095 -0.191495 -0.833568 0.518164
--0.464684 -0.883052 0.0654866 -0.676968 -0.734808 0.0421014 -0.0893582 -0.994723 0.0504072
--0.0905864 -0.990233 0.10598 -0.180049 -0.978796 0.0976737 0.527412 -0.846036 0.0778419
-0.750225 -0.653257 0.102071 -0.877754 0.455368 -0.148952 0.615922 -0.74676 0.250977
-0.408844 -0.906834 0.102467 -0.738009 0.654412 0.164583 -0.228873 0.972709 -0.0381454
-0.337487 0.935758 -0.102269 0.581949 0.807511 -0.0962396 -0.913794 -0.406131 -0.0061535
--0.90515 -0.419733 0.0672855 0.985993 0 0.166785 -0.973323 0.159799 0.164642
-0.893689 -0.438371 -0.0956583 0.734908 -0.666249 -0.126582 -0.34802 -0.912492 0.215037
-0 -0.9837 0.179816 -0.256757 -0.960868 0.103963 -0.534985 -0.841855 0.0712107
-0.992076 0.0888426 0.0888426 -0.77454 -0.580905 0.250276 -0.731025 -0.629021 0.264453
--0.151516 -0.925564 0.346949 0.144294 -0.945232 0.292771 0.0801606 -0.921847 0.379173
--0.0369768 -0.90593 0.421809 -0.288508 -0.601059 0.745313 -0.0283629 -0.855615 0.516835
-0.630647 -0.667527 0.395845 0.752454 -0.620057 0.222132 -0.859289 -0.492892 0.136672
--0.858604 -0.506671 0.0779977 0.78356 -0.609436 0.12092 0.773686 -0.613753 0.157216
--0.83706 0.506832 -0.206039 0.397346 -0.914024 0.0817053 0.640441 -0.765318 0.0642225
-0.626561 -0.775742 0.0751431 -0.904265 -0.368404 0.215833 0.985993 0 0.166785
--0.985993 0 0.166785 0.127883 -0.989553 -0.0665629 -0.234956 -0.971224 0.0389789
--0.222632 -0.960744 0.165547 -0.0664783 -0.986728 0.148152 0.854386 0.515038 0.0689927
--0.883359 -0.419596 0.208844 0.746926 -0.630354 0.211557 0.391488 -0.897001 0.205246
--0.644467 -0.731907 0.221299 0.74956 -0.643764 0.154037 0.728101 -0.667812 0.154586
--0.84479 0.495855 -0.20114 -0.939313 0.337442 -0.0618315 0.577231 -0.812488 0.0816531
-0.54668 -0.829782 0.112265 0.0757077 -0.791146 0.606924 0.122598 -0.98078 0.151787
--0.935367 -0.344489 0.0801019 0.982172 0.0879557 0.166139 -0.991737 0 0.128284
-0.698525 0.709022 0.0966993 0.709161 0.698746 0.0940498 -0.921047 -0.292973 0.256591
--0.924892 -0.296325 0.238257 0.433101 -0.880099 0.194548 -0.605116 -0.759848 0.237625
-0.759829 -0.631018 0.156451 0.772156 -0.617008 0.151905 -0.968309 -0.239311 0.0714704
-0.526635 -0.840004 0.130571 0.163394 -0.972194 0.167751 -0.29119 -0.934755 0.203569
--0.25437 -0.951374 0.173732 0.796281 -0.566678 0.21169 0.828117 -0.516914 0.216846
--0.183889 -0.981474 0.0537944 -0.320398 -0.946777 0.0309718 0.2411 -0.966844 0.0841678
-0.233528 -0.969895 0.069054 -0.903472 -0.428388 0.0148887 -0.611621 -0.79001 -0.0424737
-0.95884 0.249869 0.134877 -0.995086 0 0.0990135 0.842244 0.527974 0.108947
-0.749169 0.654664 0.100806 -0.763318 -0.501609 0.407103 -0.924073 -0.100311 0.368819
-0.925196 0.201129 0.321807 0.380651 0.827094 0.413547 -0.0736462 0.97213 0.222575
--0.113333 0.988034 0.104615 0.125218 0.990362 0.059194 0.0616862 0.99647 -0.0569411
--0.604642 0.77921 -0.165047 -0.654665 0.737226 -0.167066 0.595467 -0.782614 0.181476
--0.473794 -0.85559 0.208531 -0.6647 -0.724096 0.184008 0.840159 -0.507061 0.192413
--0.64744 -0.761694 -0.0253898 -0.490858 -0.871197 0.00863829 0.167001 -0.983267 0.0727743
--0.236405 -0.971655 0 0.932844 0.333618 0.136021 -0.982641 0.175995 0.0586652
--0.39749 0.0709803 0.914857 0.80754 0.13459 0.574251 -0.39443 0.302396 0.867745
--0.663323 0.151617 0.732813 0.89597 0.443798 0.0167471 -0.912339 -0.180567 0.36747
--0.861592 -0.292516 0.414841 -0.899625 -0.282235 0.333194 0.886292 -0.462413 0.0256896
--0.841918 0.528263 -0.110055 -0.0856621 -0.980355 0.177669 0.73686 -0.653738 0.172233
--0.147438 -0.989063 0.0040955 -0.406043 -0.912823 -0.043394 0.960749 0.239534 0.139946
--0.929024 0.353084 0.110664 -0.320564 0.0674871 0.94482 0.39365 0.919182 -0.0119893
-0.726182 0.68718 -0.0210488 -0.724245 -0.654157 0.218052 -0.449876 -0.736161 0.505646
--0.84227 -0.409501 0.350558 0.746128 -0.664265 -0.0452199 -0.848602 0.516435 -0.114763
--0.352292 -0.935056 -0.0395094 0.922438 -0.359595 0.140711 0.987849 0.0884641 0.127781
--0.934583 0.342345 0.096723 0.257508 0.835331 0.485707 0.0494662 0.831032 0.554021
--0.217452 0.848061 0.483226 0.322634 0.939848 0.112221 0.0790893 0.996705 0.0179748
--0.180111 0.978306 -0.102358 -0.333222 0.928936 -0.161372 0.916886 0.387913 0.0940396
-0.161262 0.983526 0.0816756 0.238774 0.971075 0 -0.777287 -0.606089 0.168764
--0.74616 -0.633307 0.205349 0.776905 -0.629617 -0.00107903 0.762229 -0.64725 0.00859036
--0.872436 0.473766 -0.120006 -0.863423 0.485162 -0.13827 0.901675 0.430157 -0.0441187
-0.983641 0.178108 -0.026986 -0.213526 0.97368 0.0797165 -0.264783 0.957141 0.117354
--0.398744 0.886098 0.236293 0.992076 0.0888426 0.0888426 -0.964809 0.244802 0.0960009
-0.195266 0.78616 0.586365 0.747579 0.615653 0.249193 -0.883377 0.376598 0.278961
--0.841635 0.479792 0.247892 0.631517 0.758482 0.16091 0.509108 0.846123 0.157752
--0.73302 0.640187 -0.229873 -0.985746 0.0789435 -0.148572 0.94526 0.322741 0.0481914
--0.707235 -0.681672 0.18746 -0.749768 -0.638475 0.173774 0.745203 -0.66536 0.0443573
--0.561706 0.6366 -0.528419 -0.843485 0.316307 -0.434147 0.907987 -0.404496 0.109285
--0.869999 -0.39875 0.29 -0.80228 0.566315 -0.188772 0.965174 0.25152 0.0719457
--0.98126 0.175193 0.0802233 0.420999 0.90047 0.109148 0.214094 0.961517 0.172189
-0.177858 0.966364 0.185763 0.289185 0.937659 0.19279 -0.887417 0.371686 0.272656
-0.867886 0.286595 0.405756 0.879213 0.432113 0.200654 0.713733 0.678553 0.173641
--0.743582 -0.659084 -0.112664 0.796122 0.601769 0.0637452 -0.783658 -0.602979 0.149319
--0.730793 -0.660824 0.171037 0.560643 0.824475 -0.076951 0.0938288 0.995588 0.000955
--0.771634 0.635276 0.031711 -0.801444 0.59723 0.031681 0.727177 -0.677801 0.108628
-0.717909 -0.686696 0.11426 -0.403455 -0.14483 -0.903464 -0.754303 -0.258618 -0.603443
--0.739379 -0.285893 -0.609577 -0.902111 0.0674808 -0.426194 0.898344 -0.425962 0.107401
-0.530778 -0.836912 0.133612 -0.654043 -0.744256 0.135319 0.935161 0.334447 0.116703
--0.968373 0.243346 0.0550971 0.271817 -0.888631 -0.369392 0.905576 -0.424178 -0.00248785
--0.898645 0.246485 0.362881 -0.878041 0.269225 0.395679 0.942709 0.00771658 0.333528
-0.944479 0.0718895 0.320611 -0.532907 -0.836714 -0.126171 -0.418588 -0.906668 -0.0523235
-0.688407 0.716801 0.110871 0.762943 0.642586 0.0707184 -0.90686 -0.392522 0.153399
-0.998228 -0.0462258 0.0374804 -0.997735 -0.057916 0.0342231 0.491553 -0.849046 0.193642
--0.451911 -0.891608 0.0284989 -0.72445 -0.678208 -0.123311 -0.154193 -0.90974 -0.385483
-0.521877 -0.84215 0.135751 0.0316642 -0.987177 0.156458 0.94166 0.319294 0.106431
--0.945479 0.321611 0.051337 0.504367 -0.852206 0.139136 0.0773271 -0.947258 0.311004
--0.270119 -0.764532 0.585257 -0.393708 0.51711 0.759994 -0.337067 0.41068 0.847188
--0.511949 0.500043 0.698473 0.749796 0.644924 0.147914 0.372719 0.873962 0.311884
--0.27968 0.925729 0.254567 -0.387366 0.867965 0.31078 -0.209284 0.863295 0.459262
--0.221396 0.846047 0.484962 -0.225881 0.797226 0.55983 -0.22643 0.769375 0.597321
--0.370753 0.750334 0.547303 0.936041 -0.0744578 0.343924 0.22259 -0.926929 0.302087
--0.0853507 -0.971545 0.220943 -0.27938 -0.954058 0.108262 -0.394411 -0.91891 -0.00662875
-0.899368 0.412949 0.143561 0.751775 0.647856 0.122955 -0.938592 -0.319268 0.130814
-0.733675 -0.669384 0.116817 -0.938927 -0.333841 0.0834602 0.137194 -0.968931 0.205791
--0.146459 -0.97814 0.147622 -0.020719 -0.80804 0.588764 0.150539 -0.784057 0.602156
-0.0168332 -0.52183 0.852883 -0.249279 -0.807447 0.534686 0.937562 0.330556 0.108213
-0.942445 0.316493 0.107842 -0.93994 0.336695 0.0561158 0.236437 -0.956391 0.171506
-0.0787831 -0.982312 0.169871 -0.0329484 -0.98484 0.170308 -0.0917315 -0.974491 0.204825
--0.187575 -0.935656 0.298936 -0.22054 -0.803395 0.5531 -0.0340662 0.0170331 0.999274
--0.393818 -0.393818 0.830551 0.120903 -0.70527 0.698553 -0.70527 0.120903 0.698553
--0.671994 -0.186091 0.716794 0.954748 0.168736 0.244917 0.953272 0.197675 0.228465
-0.935294 0.277849 0.219148 -0.580904 0.783082 0.22211 -0.792735 0.0468434 0.607764
--0.94386 0.152858 0.292854 0.667641 0.731633 0.137727 0.784931 0.605469 0.131491
--0.600932 0.348833 0.719164 -0.714862 0.194962 0.671537 0.987926 0.0177048 0.153913
--0.960602 -0.241393 0.137742 0.729484 -0.66932 0.140939 0.173191 -0.899037 0.402166
-0.424978 0.882816 0.200076 0.39292 0.894521 0.21318 -0.103486 0.952782 0.285478
--0.21034 0.893083 0.397692 -0.539139 0.787489 0.298648 -0.0822085 -0.829234 0.552823
-0.935161 0.334447 0.116703 -0.944881 0.32297 0.0537605 -0.223261 -0.458925 0.859967
-0.784895 -0.242509 0.570201 0.829037 -0.138173 0.541854 -0.661083 -0.669713 0.338309
--0.687977 -0.651833 0.319062 0.573134 0.807597 0.138941 0.65065 0.744605 0.149055
--0.9574 -0.109048 0.267382 0.991783 0.117286 0.0510981 -0.951919 -0.257508 0.165949
-0.895763 0.0453551 0.442212 0.912843 0.0370907 0.406624 0.882829 -0.0764655 0.463428
--0.517766 0.534577 0.667941 -0.0185995 0.658955 0.751953 -0.034456 0.955934 0.291551
-0.343907 0.910341 0.230234 0.45066 0.870621 0.197292 -0.777171 0.564647 0.277809
--0.92431 0.299776 0.236187 0.915302 0.380062 0.133326 -0.945479 0.321611 0.051337
-0.61184 0.772478 0.170087 0.0868562 0.959366 0.268465 -0.18378 0.966933 0.176819
--0.0796151 0.987227 0.138 -0.133291 0.911708 0.388616 -0.0562991 0.925181 0.375327
--0.264587 0.841867 0.470376 0.609402 -0.370421 0.701012 -0.666254 -0.674645 0.317743
-0.299222 0.933099 0.199481 0.18655 0.967198 0.172417 0.474731 0.864116 0.167134
--0.969563 -0.217657 0.112126 0.949223 0.314029 0.019032 -0.946577 -0.28256 0.155408
--0.937489 -0.317879 0.141657 0.902487 -0.0638929 0.425952 0.83711 -0.413388 0.358269
-0.403713 0.858964 0.314954 -0.982239 0.010807 0.187322 0.170172 0.96184 0.214256
-0.322634 0.939848 0.112221 0.235282 0.957355 0.167672 -0.251342 0.952172 0.173767
--0.650482 0.757175 0.0596562 0.890888 0.428295 0.151266 0.907316 0.395497 0.142689
--0.916348 0.396628 0.0547073 0.79735 0.601228 -0.0525137 0.816542 0.569431 0.0949051
--0.936468 -0.248335 0.247703 0.622716 0.770025 0.138877 0.639269 0.757837 0.130452
-0.328412 0.921155 0.208854 -0.90309 -0.429338 -0.00986984 0.962071 0.272799 0
-0.952346 0.304588 0.0162447 -0.900467 -0.409868 0.145494 0.882518 -0.468838 -0.0367716
--0.984232 -0.0461571 0.170751 0.756585 0.596597 0.267678 0.734355 0.622262 0.271132
-0.230891 0.935931 0.265936 0.189247 0.96344 0.189657 0.189054 0.962454 0.194782
--0.189464 0.964546 0.183723 -0.487393 0.856514 0.169799 -0.391319 0.904234 0.170972
-0.734944 0.673608 -0.0781624 0.68022 0.730716 -0.0579226 0.216172 0.976324 0.00774349
-0.0927428 0.99513 0.0333874 -0.705545 0.70769 0.0371716 -0.849536 0.263464 -0.457029
--0.909507 0.196297 -0.36642 0.898921 0.414243 0.14263 -0.907331 0.412992 0.0786651
-0.972589 0.00495136 -0.232478 0.963906 0.19031 -0.18619 -0.849418 -0.501891 0.163079
-0.479853 0.870845 0.106634 0.620652 0.778636 0.0922828 -0.847093 -0.529328 -0.0473859
-0.936479 0.350724 0 -0.886935 -0.436849 0.150029 0.979753 -0.188784 -0.0666717
--0.98167 0.0994456 0.162586 0.905524 0.109557 0.409908 0.967228 0.00614113 0.253834
--0.430995 0.889658 0.150838 -0.4468 0.880649 0.157567 -0.423661 0.90028 -0.100031
--0.290129 0.928414 -0.232104 0.462084 0.873942 -0.15068 0.625276 0.769006 -0.132889
--0.676037 -0.730851 -0.0939666 -0.627252 -0.774974 -0.0772701 0.915704 0.380649 0.12881
-0.910762 0.390913 0.133042 -0.94485 0.320375 0.0679584 0.935441 -0.261671 -0.237653
-0.463751 -0.879528 -0.106609 -0.646283 -0.752002 0.129656 -0.833262 -0.528879 0.161124
-0.556124 0.826158 0.0904978 0.545323 0.831994 0.102023 0.496161 0.858403 0.130261
--0.84961 -0.52248 -0.0719597 -0.829593 -0.549583 -0.0986588 0.922822 0.385228 0
--0.904864 -0.404737 0.131941 0.979963 -0.199179 0 -0.988907 0.0111331 0.148118
-0.950273 0.291417 0.109809 0.32035 0.944621 0.0711888 -0.209442 0.977802 -0.00608843
--0.334132 0.942514 0.00479042 -0.417537 0.908529 0.0154643 0.876575 -0.443532 0.186803
--0.372264 0.908099 -0.191772 -0.0882881 0.975584 -0.201101 0.304687 0.935642 -0.178157
--0.435788 -0.896981 0.0742598 -0.528449 -0.84741 0.0513582 0.904864 0.404737 0.131941
--0.94561 0.317556 0.0705679 -0.940309 0.331525 0.0768753 0.328661 -0.943846 0.0337088
--0.130234 -0.985437 0.109332 -0.613055 -0.778677 0.133517 0.737178 0.641024 -0.213675
--0.941726 -0.325287 -0.0856723 0.0731249 0.967077 0.24375 0.0333514 0.9682 0.247945
--0.0491532 0.966679 0.251227 0.950925 0.309421 0 0.935084 0.354427 0
--0.915704 -0.380649 0.12881 0.957916 -0.280314 0.0618193 -0.986087 -0.143278 0.084281
-0.961897 -0.242722 0.125856 -0.567532 0.82305 0.0222562 -0.790305 0.609033 -0.0670562
-0.832218 -0.523935 0.181399 0.668505 -0.724698 0.167072 -0.336249 -0.939275 0.0685467
--0.373255 -0.914115 0.158351 -0.308917 -0.940954 0.13848 -0.346823 -0.931835 0.106756
-0.891109 0.438905 0.115268 -0.909999 0.407034 0.0788965 0.655354 0.472465 -0.589311
-0.715155 0.131873 -0.686413 -0.970202 -0.240965 0.0253648 -0.980567 -0.182926 0.0709014
-0.55495 0.793739 0.249016 0.564847 0.796469 0.215836 -0.74402 0.6392 0.194569
--0.795926 0.597597 0.0968449 0.987001 0.160715 0 -0.910762 -0.390913 0.133042
--0.898921 -0.414243 0.14263 0.9271 -0.356142 0.11683 0.855212 -0.493465 0.158443
--0.966198 -0.256732 -0.0234648 0.835548 -0.538439 0.109282 -0.752948 0.649358 -0.106788
--0.63996 0.734769 -0.224867 0.644276 -0.746059 0.168239 0.421389 -0.893143 0.157251
-0.302968 -0.939202 0.161583 -0.0432635 -0.822006 -0.567833 -0.730952 -0.472755 -0.49215
--0.00879051 -0.959924 -0.280124 -0.0714231 -0.975179 -0.209583 -0.187769 -0.964695 -0.18468
--0.312614 -0.94709 -0.0727582 -0.331391 -0.941849 0.0556724 0.69814 0.679073 0.226847
-0.704182 0.678293 0.209874 0.136649 0.976065 0.169185 -0.782013 0.616988 0.0882119
--0.962902 0.26848 0.0271878 0.87301 0.47564 0.1078 -0.894208 0.440431 0.0800783
-0.58504 0.645561 -0.490896 0.565425 0.565425 -0.60049 0.345295 0 -0.938494
-0.183808 -0.76865 -0.612692 0 -0.87317 -0.487416 0.256686 -0.81284 -0.52288
-0.369262 -0.812376 -0.45132 -0.324628 -0.945655 -0.018819 0.125901 -0.99192 -0.0155877
-0.279469 -0.958763 -0.051678 -0.979733 -0.139762 0.143489 0.842539 -0.401381 0.359194
-0.816503 0.468688 0.337126 0.656996 -0.399171 0.639546 -0.987105 0.151862 -0.0506207
-1 0 0 -0.872008 -0.466563 0.148061 0.62707 -0.777092 0.0539647
-0.618165 -0.784549 0.0485288 -0.925432 -0.311053 -0.216385 -0.912262 -0.334167 -0.236878
-0.834184 -0.540728 0.108402 0.871034 -0.478699 0.110216 -0.603543 0.766511 -0.219538
--0.219701 0.957567 -0.186539 -0.164018 0.973854 -0.157183 -0.109557 0.99348 -0.031539
--0.307155 0.950999 0.035441 0.17421 -0.968971 0.175348 0.166698 -0.972992 0.15968
-0.353095 -0.920885 0.165211 0.54846 -0.822689 0.14958 -0.77583 -0.573902 -0.262153
--0.890532 -0.287568 -0.352502 0.620804 0.64591 0.444301 0.626694 0.663362 0.408907
-0.618814 0.673415 0.404453 0.726395 -0.333287 0.601057 0.229135 -0.910085 0.345316
--0.682228 -0.730959 0.0162435 0.894208 0.440431 0.0800783 -0.907331 0.412992 0.0786651
-0.681032 0.376741 -0.627902 -0.241627 -0.638585 -0.730634 -0.366851 -0.791307 -0.489135
-0.567982 -0.743976 -0.351989 0.601696 -0.75212 -0.268843 0.561811 -0.783055 -0.266819
--0.544378 -0.838636 -0.0185274 -0.466562 -0.881284 -0.0752192 0.821962 -0.557699 -0.115544
-0.99236 -0.0870827 -0.0874017 -0.994794 0.0306877 0.0971778 0.779985 -0.548672 0.300969
-0.314976 -0.926439 0.206159 0.0796151 -0.987227 0.138 -0.118885 -0.990709 0.0660473
-1 0 0 -0.866056 -0.478626 0.144445 -0.876693 -0.463248 0.129658
-0.692094 -0.711521 -0.12142 0.673143 -0.641088 -0.368626 -0.840155 0.228775 -0.491734
--0.794007 0.174681 -0.582271 0.904379 -0.415125 0.0988393 -0.188828 0.964867 -0.182688
--0.540485 0.83688 0.0866467 -0.750966 0.659385 -0.0355224 0.472117 -0.881286 0.020983
--0.689591 -0.678858 -0.252224 -0.76161 -0.58942 -0.269323 0.690456 0.0470766 0.721841
-0.844057 0.19916 0.497899 0.776658 0.44287 0.44796 -0.227808 -0.672703 0.703971
--0.686188 -0.648067 0.330387 -0.470251 -0.853687 0.223791 0.865962 0.49676 0.0577907
--0.94485 0.320375 0.0679584 0.810314 0.450174 -0.375145 -0.385487 -0.416151 -0.82354
--0.124783 -0.945051 -0.302172 -0.435675 -0.89242 -0.117358 0.845825 0.506554 -0.167283
--0.90183 0.432091 -0.00038614 1 0 0 -0.89611 -0.430805 0.106743
-0.933381 0.285803 -0.217065 -0.863862 0.284682 -0.41557 -0.920171 0.288747 -0.264404
-0.909999 -0.407034 0.0788965 -0.76547 0.642157 -0.0411043 -0.682768 0.720467 -0.121474
-0.487663 -0.624719 0.609845 -0.232717 -0.867757 0.439137 0.87627 0.474048 0.0861905
--0.946459 0.317841 0.056505 -0.942007 0.332123 0.0481338 0.477676 0.877509 0.0424601
-0.0474296 0.986536 -0.156518 -0.909538 0.400197 -0.112176 0.665187 0.741896 -0.0843615
-0.837273 0.520343 -0.16798 -0.897915 0.440169 0.000488263 -0.814913 0.579494 0.0102154
-1 0 0 -0.946887 -0.315629 0.0615072 -0.964187 -0.262245 0.0396281
-0.913814 0.396829 -0.0864277 -0.982288 0.0762009 -0.171185 0.88096 -0.463637 0.0945998
--0.765014 0.639602 -0.0752473 -0.938451 0.345317 -0.00812512 0.802708 0.596364 -0.00310001
--0.911935 0.4079 0.0446234 0.405731 0.894223 0.189072 0.330252 0.920704 0.207937
-0.0132112 0.95121 0.308262 -0.855886 0.109428 0.505455 -0.880425 0 0.474186
--0.894675 -0.0378345 0.445112 0.784203 0.615061 0.0820082 0.523255 0.850394 0.0550795
--0.978238 -0.19341 0.0751261 0.748462 0.656814 0.0916485 0.683425 0.727721 -0.0579108
--0.84381 0.536501 -0.0122825 -0.875652 0.482762 -0.0132554 1 0 0
--0.998383 -0.0380227 0.0422474 0.68437 -0.28888 0.669467 0.756813 -0.24925 0.604242
-0.701308 -0.137098 0.699551 -0.622639 0.437793 0.648582 -0.623985 0.339192 0.703983
--0.666768 0.35864 0.653298 0.78887 0.613957 -0.0272198 0.909601 0.407789 -0.0795857
--0.964919 -0.225766 -0.134017 0.874059 -0.476451 0.0949511 0.466345 -0.875391 0.12733
--0.191218 -0.978682 -0.0749441 -0.18324 -0.980797 -0.0667926 0.185905 -0.979727 -0.0746564
-0.206426 -0.976194 -0.0665889 -0.91413 -0.36041 0.185666 -0.392605 0.326002 0.859991
--0.111041 0.142767 0.983508 -0.441563 0.454179 0.773786 -0.493862 0.409681 0.766982
-0.804592 0.572029 0.159418 0.789212 0.592309 0.162218 -0.696034 0.685325 0.214164
--0.671285 0.706616 0.223762 -0.817155 0.547715 0.179627 0.754161 0.651321 0.0837957
-0.77317 0.634173 0.00579153 -0.896946 0.441779 0.0178497 0.862379 0.493586 0.112583
-0.599199 0.783999 0.162192 -0.452839 0.251577 0.855363 -0.832275 -0.488101 0.262824
--0.89702 -0.0967048 0.431281 0.883359 0.462319 0.0770532 -0.887349 -0.450996 0.0959912
-0.627455 0.778103 0.029252 -0.944143 0.328398 -0.0273665 -0.993313 0.0180057 -0.114036
-0.999408 0 -0.0344137 -0.998955 -0.0284287 0.0357992 0.670098 -0.383875 0.635302
--0.640411 0.15137 0.752968 0.682656 0.730145 0.0294609 0.709228 0.704913 -0.00970806
--0.862109 -0.49602 -0.103594 -0.793538 -0.602136 -0.0879165 0.320821 -0.937495 0.13482
-0.0602766 -0.997713 0.0305881 -0.110478 -0.993817 0.0110316 0.467763 -0.883552 0.0230994
-0.402916 -0.895479 0.189144 0.238213 -0.944344 0.226869 -0.786527 -0.566171 0.246628
-0.857732 -0.219715 0.464781 0.859164 -0.271201 0.433921 -0.390518 0.836011 0.385462
--0.0214505 0.87782 0.478511 -0.315553 0.930052 0.188225 0.940861 0.0775968 0.329786
-0.966406 -0.211753 0.145674 -0.816968 -0.576683 0 0.934871 0.354583 0.0169167
--0.877317 0.477987 0.0429295 0.995081 0.0990068 -0.003342 -0.506055 -0.815438 0.281014
--0.580456 -0.792608 0.186665 -0.702755 -0.679441 0.210938 0.873762 0.479722 0.0800368
--0.879136 -0.467433 0.0928828 -0.839357 -0.533423 0.104593 0.792351 0.598665 -0.117385
-0.608994 0.793169 -0.00289584 -0.386139 -0.91992 -0.0681422 -0.501173 -0.864928 -0.0269448
-0.0353772 -0.995515 -0.0877355 0.225014 -0.964347 -0.139295 0.131541 -0.978663 -0.157849
--0.92299 -0.301215 -0.239498 0.994016 0.0808006 -0.0735061 -0.999674 0.0237077 -0.00948307
-0.786206 0.614147 0.0685787 0.745826 0.664091 0.0522191 -0.827312 -0.561551 0.0146811
-0.398312 -0.895884 0.196823 0.890365 -0.257455 0.375455 0.947689 -0.238664 0.211953
--0.311313 0.939372 0.143747 -0.421666 0.893895 0.152152 -0.474223 0.868607 0.143646
-0.783056 -0.613877 0.099896 0.955642 0.293845 0.0201067 0.948216 0.31657 0.0258831
--0.869706 0.493266 0.0173076 0.397071 -0.887569 -0.233571 -0.210322 -0.974072 0.0833535
--0.42977 -0.883827 0.184791 0.817617 0.557814 0.142637 0.870774 0.484908 0.0813462
--0.896909 -0.426012 0.118609 -0.899513 -0.419499 0.122055 0.838843 0.514054 -0.17914
--0.46401 -0.882192 -0.0801993 -0.427994 -0.899229 -0.0905994 -0.449055 -0.888681 -0.0927182
-0.0184781 -0.999355 0.0307968 0.203288 -0.969071 0.139911 0.141264 -0.979215 0.145544
--0.374923 -0.917243 0.134529 -0.648587 -0.760662 0.0269943 0.963864 0.247301 -0.0990371
--0.991303 0.122134 -0.0490118 0.903905 0.418992 0.086033 -0.941562 -0.336377 0.0176268
--0.999317 -0.03624 0.00724799 0.927754 -0.36205 0.0905126 -0.511409 0.843703 0.163175
--0.212154 0.960347 0.180896 -0.00765895 0.967216 0.253839 -0.178031 0.922856 0.341529
--0.812055 0.165164 0.559721 -0.928033 -0.164527 0.334195 0.912076 0.407963 -0.0410359
--0.83404 0.551393 0.0185342 0.893366 0.421589 0.155434 0.885165 0.440939 0.148513
--0.926284 -0.338503 0.165572 0.822803 0.530898 -0.202835 0.843827 0.497414 -0.201334
--0.687959 -0.713822 -0.13104 -0.695958 -0.70123 -0.154657 -0.211188 -0.96277 0.168743
-0.9139 0.395713 -0.0905412 -0.966118 0.249114 -0.0675129 0.943885 0.305949 0.124405
-0.911594 0.4008 0.0914105 -0.933941 0.352142 0.061242 0.919684 -0.392399 0.0143062
-0.916233 -0.400521 0.0100402 -0.471059 -0.203593 0.858285 -0.915223 -0.345325 0.207646
--0.919381 -0.326333 0.219647 0.869706 0.493266 -0.0173076 -0.856248 0.516528 0.00617672
--0.863412 0.5045 0 0.949901 0 0.312551 0.966694 0.133233 0.218522
--0.829007 -0.531972 0.172494 0.854524 0.481433 -0.194963 0.840974 0.507777 -0.186883
--0.696513 -0.697582 -0.168075 -0.691162 -0.703023 -0.167489 0.904852 0.419322 -0.0735652
-0.913292 0.397282 -0.089807 -0.965403 0.252157 -0.0664415 -0.943215 0.327134 -0.0577045
-0.881904 -0.386588 0.269806 0.893837 -0.441355 0.0791225 -0.844528 0.50902 0.166346
-0.886347 -0.463017 0.0020044 -0.0828959 -0.828959 0.553133 -0.804999 -0.542142 0.240952
-0.808104 0.58812 -0.0329227 -0.837432 0.546542 0 0.534473 -0.749104 0.391386
-0.728828 -0.596314 0.336482 -0.379356 -0.895194 0.233918 -0.453989 -0.868649 0.198353
--0.766829 -0.616239 0.179505 0.801561 0.389275 -0.453834 0.674657 -0.500177 -0.542827
--0.273896 -0.903855 -0.328675 -0.502434 -0.846655 -0.175317 0.943631 0.313417 -0.106444
--0.965631 0.253008 -0.0595312 0.480927 -0.874065 0.0687038 0.33854 -0.939856 0.0453944
-0.457787 -0.884002 0.0947145 -0.792912 -0.448754 0.412202 -0.873995 0.430419 0.225547
--0.914481 0.145486 0.37757 -0.924688 0.260226 0.277912 0.705414 -0.705414 0.0691582
--0.559827 -0.828604 -0.00296991 -0.535111 -0.844212 -0.0310209 0.0216605 -0.982702 0.183924
-0.0438133 -0.986753 0.156204 -0.478183 -0.847161 0.231646 0.792308 0.609598 0.0252596
-0.806769 0.590681 -0.014824 -0.821657 0.569983 0 -0.758782 0.651344 0
-0.419925 -0.835832 0.353621 -0.381501 -0.902954 0.197816 0.369933 -0.494845 -0.786307
-0.147043 -0.735215 -0.661693 0.364599 -0.798177 -0.479563 0.0134744 -0.881226 -0.472503
-0.937113 0.329655 -0.114662 0.942484 0.315008 -0.111777 -0.943881 0.312655 -0.106472
-0.708104 -0.689293 0.153176 0.666982 -0.698981 0.257993 -0.652166 -0.652166 0.386469
--0.195227 -0.980728 -0.00765596 0.810902 0.584913 0.0177246 -0.759496 0.650492 -0.00500152
--0.788524 0.61494 -0.00882193 0.902719 0.410994 -0.127212 -0.930072 0.35149 -0.106866
--0.899866 0.424305 -0.101025 0.436202 0.00411512 0.899839 0.534324 0.0360218 0.844512
-0.235431 -0.0692444 0.969421 -0.599185 -0.607869 0.52103 0.812685 0.582424 -0.0180597
--0.835147 0.548455 -0.0415496 0.88482 0.44965 -0.122098 -0.878117 0.462348 -0.123063
-0.806244 0.35495 0.473267 -0.785754 0.522178 0.331542 -0.769256 0.56541 0.297584
-0.924872 -0.305423 -0.226558 0.725795 0.687257 -0.0299738 0.785491 0.618516 -0.0210092
--0.786373 0.615992 -0.0465999 0.851665 0.50546 -0.138482 0.884147 0.450915 -0.122307
--0.869551 0.480897 -0.112332 -0.87569 0.47276 -0.0983109 0.931887 -0.298993 0.2054
--0.774241 0.584113 0.243645 -0.309426 -0.618853 -0.721995 0.376057 0.924474 0.0626762
-0.143217 0.984764 0.0986342 -0.452387 0.891597 0.0200085 -0.542807 0.839708 0.0158348
-0.687566 0.726122 0 0.707008 0.707008 -0.0166846 -0.762011 0.646569 -0.0358951
--0.725795 0.687257 -0.0299738 0.794815 0.590631 -0.13937 0.806362 0.57469 -0.139682
--0.878117 0.462348 -0.123063 0.818428 -0.574589 0.00482848 -0.889982 0.389367 0.237329
--0.942235 0.240827 0.232799 0.949207 0.244655 -0.197863 0.743874 0.66668 -0.0467846
--0.70665 0.698237 -0.114503 0.632487 0.773272 0.0448425 0.666306 0.745471 0.0175922
--0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846 0.799405 0.586597 -0.129831
--0.850808 0.513854 -0.109911 -0.824838 0.555611 -0.104586 0.793489 -0.607421 -0.0376137
-0.702593 -0.711259 -0.0217755 -0.953977 -0.0681412 0.292034 0.968046 -0.154887 -0.197223
--0.70948 0.695059 -0.116324 -0.750326 0.641609 -0.159214 0.780173 0.619123 0.0895342
-0.649066 0.758225 0.0617139 -0.706805 0.706805 -0.0291896 -0.706805 0.706805 -0.0291896
-0.836657 0.530563 -0.136042 0.811074 0.570608 -0.128706 -0.733792 0.668275 -0.122299
-0.567254 -0.815787 0.11276 -0.496535 -0.722233 0.481489 0.915373 -0.377906 -0.138846
-0.909728 -0.394216 -0.130341 -0.77009 0.621238 -0.145001 -0.809467 0.575253 -0.117678
-0.794994 0.605489 0.0369765 0.819705 0.568624 0.0689241 -0.706805 0.706805 -0.0291896
--0.706805 0.706805 -0.0291896 0.789101 0.598476 -0.138368 0.806362 0.57469 -0.139682
--0.702247 0.702247 -0.117041 0.381865 0.816705 0.432633 0.468256 0.784886 0.405822
-0.374228 0.83328 0.406938 0.15149 0.908938 0.388435 0.976021 -0.206743 -0.0681131
--0.837875 0.54286 -0.0571733 -0.825293 0.564318 -0.0209006 0.699576 0.714556 -0.00188929
-0.726079 0.687511 0.011738 -0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846
-0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662 0.972209 0.0920126 0.215275
--0.431596 0.868096 0.245225 0.0797681 0.765773 0.638144 -0.566086 0.804585 0.179415
--0.589585 0.787992 0.177364 0.973088 0.221881 -0.0621977 -0.458034 0.883862 0.0948273
-0.0732056 0.995596 0.0585645 0.532326 0.846239 -0.022555 -0.687257 0.725795 -0.0299738
--0.64644 0.761859 -0.0410583 0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662
-0.959724 0.0239931 0.279919 0.982839 -0.150106 0.107219 0.432905 0.132964 0.891579
--0.388253 0.745925 0.541161 -0.619265 0.76639 0.170755 -0.615557 0.769446 0.170418
-0.510862 0.849929 -0.128996 0.719484 0.682962 -0.126123 -0.631207 0.773877 -0.05188
--0.62591 0.777172 -0.0651199 0.702247 0.702247 -0.117041 -0.598023 0.788504 -0.143633
--0.57469 0.806362 -0.139682 0.805703 -0.523707 0.276721 0.81319 -0.521513 0.258352
-0.547421 0.646952 0.530833 -0.510677 0.805299 0.301169 -0.276292 0.621658 0.732942
--0.797498 0.531665 0.285184 0.834017 0.476581 -0.278006 -0.433011 0.899851 -0.0526229
--0.42302 0.905901 -0.0199538 0.968 -0.23474 0.0887333 0.915018 -0.223407 0.335903
-0.963438 -0.255693 0.0800511 -0.675917 0.724073 0.137311 -0.672087 0.729168 0.128893
-0.952642 0.156456 -0.26076 0.458781 0.873746 -0.161518 0.00928327 0.99994 0.00574678
--0.0698733 0.996454 -0.0468715 0.215983 0.970446 -0.107639 -0.625859 0.77732 -0.0638284
--0.597383 0.801148 -0.0360066 -0.580015 0.813834 -0.0354454 0.702247 0.702247 -0.117041
--0.525649 0.839674 -0.136532 -0.570557 0.811923 -0.123471 0.806603 -0.531971 0.257679
-0.7963 -0.482163 0.365275 0.754212 -0.612311 0.237149 -0.828484 0.49962 0.252972
--0.778659 0.562949 0.27709 -0.803751 0.547575 0.232693 0.972897 0.201475 -0.113487
--0.440032 0.897903 -0.0118928 0.0335315 0.997962 -0.0542891 0.309552 0.950768 0.0147406
--0.0730282 0.994077 0.08048 -0.472144 0.872894 0.123031 -0.445174 0.890348 0.0953944
-0.918071 0.367722 0.148076 -0.607681 0.791702 0.0627037 -0.542928 0.837084 0.0672356
-0.96818 0.142503 -0.205721 -0.504826 0.862411 -0.0373945 -0.512535 0.858496 -0.0170845
-0.629993 0.760337 0.158102 0.146781 0.974779 0.168109 -0.405681 0.901513 0.150658
--0.420219 0.89516 0.148677 0.722843 0.687674 0.0678445 0.702802 0.708286 0.0663365
--0.13555 0.988715 -0.0637881 -0.511905 0.856869 -0.0610642 0.702247 0.702247 -0.117041
--0.593961 0.795024 -0.123073 -0.702247 0.702247 -0.117041 0.831794 -0.521423 0.190361
-0.814657 0.569062 0.111816 0.96461 -0.208999 0.160768 -0.468793 0.882546 0.0366937
--0.254913 0.96691 0.0102551 0.324573 0.933702 -0.151171 -0.396089 0.902252 0.170454
--0.36321 0.928204 0.0807134 0.41152 0.909894 -0.0523878 0.74245 0.669215 -0.0303041
--0.431545 0.896854 0.0970712 -0.647366 0.745287 0.159575 -0.754312 0.641948 0.137538
-0.965728 0.181539 -0.185507 -0.547652 0.836428 -0.0215729 -0.509393 0.860512 -0.00614652
-0.893389 -0.447659 0.0381625 -0.683946 0.72111 0.110537 -0.640153 0.766706 0.0486504
-0.888531 0.45377 0.0678611 -0.708849 0.702835 -0.0596345 -0.974618 0.223189 0.017505
-0.702247 0.702247 -0.117041 -0.702247 0.702247 -0.117041 0.996896 0.0750352 0.0238207
--0.238509 0.971074 0.0113576 0.0596535 0.997654 -0.033598 0.243225 0.957762 -0.153403
-0.0867785 0.995858 -0.0271308 -0.789815 0.600173 0.126428 0.871693 0.460363 -0.167982
--0.500058 0.865992 0 -0.468148 0.88365 0 -0.449818 0.893022 0.01323
-0.678991 -0.734044 -0.0122341 0.542535 -0.837459 -0.065714 -0.5071 0.86187 0.00534493
--0.438332 0.895684 0.0749286 -0.42997 0.899028 0.0829143 0.322186 0.946591 0.0127059
-0.307146 0.950664 -0.0435743 -0.181453 0.967752 -0.174733 -0.14762 0.984136 -0.0984136
-0.673835 0.737049 0.0520059 -0.858604 -0.512637 -0.00168354 0.702247 0.702247 -0.117041
--0.665916 0.731202 -0.147981 0.982715 0.181589 -0.0360245 -0.0643781 -0.981086 -0.182556
--0.1195 -0.979236 -0.163759 0.113419 -0.975399 -0.189031 -0.793613 0.595728 0.123635
--0.709686 0.695789 0.11056 0.563008 0.811297 -0.157541 0.528451 0.835585 -0.150126
-0.814319 0.555351 -0.168733 -0.457502 0.888747 0.0286436 -0.550553 0.834103 0.0340962
--0.574767 0.817704 0.0316554 0.534635 -0.840508 -0.0878206 0.649105 -0.740743 -0.173095
-0.737686 -0.658186 -0.150372 -0.363244 0.915201 0.174532 -0.412962 0.880654 0.232187
--0.105526 0.972834 0.206056 0.169772 0.969818 0.175016 0.204462 0.965997 0.158256
-0.15206 0.975996 0.155917 0.173893 0.978574 0.110246 0.292003 0.955725 0.0363921
--0.856901 -0.512676 -0.0537089 -0.812914 -0.577504 -0.0752371 0.479499 0.871225 -0.10511
-0.562478 0.818834 -0.114587 -0.616715 0.771145 -0.158106 -0.535488 0.82647 -0.173781
-0.670118 0.713468 -0.204708 -0.473457 -0.880601 0.0195039 -0.495026 -0.867695 0.0453174
--0.321311 -0.943506 -0.0809718 0.993584 0.111048 -0.0214302 -0.695781 0.712525 0.0905384
--0.599816 0.800085 -0.00925335 0.682727 0.717103 -0.14017 0.673821 0.719973 -0.166148
--0.626889 0.778445 0.0321482 -0.537073 0.843487 0.00904544 0.858828 -0.496212 -0.127234
--0.915686 -0.391304 -0.0916567 0.624353 0.77943 -0.0516923 0.441226 0.896205 -0.0462237
-0.312499 0.946568 -0.0797052 -0.158298 0.966672 -0.201214 0.624981 0.752234 -0.208669
--0.385295 -0.917935 0.0945696 -0.920835 -0.381253 -0.0819083 0.188245 -0.982101 0.00645411
-0.925438 -0.37178 -0.0731078 0.944088 -0.322686 -0.0676105 -0.653123 -0.748006 0.117973
--0.576251 -0.81473 0.0644219 0.99542 0.0704722 0.0645995 -0.58365 0.811376 -0.0319472
--0.227703 0.961412 -0.154397 0.478233 0.861316 -0.171546 -0.497727 0.867334 0
--0.392374 0.919676 0.0154814 -0.397157 0.917569 0.0182601 0.772741 -0.624267 -0.11473
--0.860065 -0.500567 0.0985965 -0.945583 -0.301323 0.12279 0.36121 -0.916403 0.17243
-0.454101 -0.876765 0.158353 -0.887808 -0.448053 -0.105099 -0.717029 -0.691722 -0.0859632
-0.74326 0.66433 -0.0789303 0.727248 0.684071 -0.0561823 -0.679343 0.71428 -0.168218
-0.160269 0.910797 -0.380476 0.884122 0.424657 -0.194924 -0.856608 -0.48949 0.163163
--0.681658 -0.718998 0.13559 0.989926 0 0.141587 -0.478352 0.878168 0
--0.397157 0.917569 -0.0182601 0.75075 -0.637123 -0.174499 0.685822 0.636443 -0.35297
-0.99177 -0.0627702 -0.111592 0.979575 -0.171037 -0.105732 0.986894 -0.119791 -0.108119
--0.917159 0.374499 0.136269 0.443643 -0.887287 0.126107 -0.12786 -0.991428 -0.0268939
-0.64434 0.759385 -0.090338 0.704894 0.704894 -0.0790535 -0.42833 0.888728 -0.163391
--0.0259677 0.969837 -0.242365 0.850593 0.47778 -0.219586 -0.962319 0.271423 0.0164499
-0.909347 0.199221 0.365238 0.965527 0.200753 0.165701 0.992061 0.0646997 0.107833
--0.321976 0.946552 -0.0192389 -0.326273 0.945081 -0.0192006 -0.175995 0.982641 -0.0586652
-0.0976805 0.993085 -0.0651203 0.183147 0.976783 -0.11114 0.0580726 0.97562 -0.211643
-0.265251 0.89973 -0.346594 0.990571 -0.0466412 -0.128819 -0.910502 0.391643 0.132668
--0.784732 0.617641 0.0521165 0.499462 0.85805 -0.119529 0.615386 0.781235 -0.104747
--0.493157 0.867277 -0.0680217 0.662902 0.745765 0.0662903 -0.800862 0.597836 -0.0348297
--0.82467 0.555207 -0.108002 0.394016 0.910313 -0.12681 0.47473 0.87152 -0.122816
--0.207983 0.974714 -0.0817076 0 0.99922 -0.0394837 0.217662 0.976024 0
--0.78792 0.597133 -0.150381 -0.738577 0.656931 -0.151476 0.335756 0.93732 -0.0932657
-0.325028 0.941474 -0.0893519 0.319809 0.940182 -0.117386 -0.312036 0.934975 -0.168689
-0.0745504 0.984242 -0.160342 0.158075 0.973779 -0.163606 0.0663259 0.99153 -0.111663
-0 0.995211 -0.0977514 0.0882513 0.992617 -0.0832084 0.254057 0.962565 -0.0944677
-
diff --git a/Modules/ContourModel/Testing/Data/testNrrd.ascii b/Modules/ContourModel/Testing/Data/testNrrd.ascii
deleted file mode 100644
index f78381e84b..0000000000
--- a/Modules/ContourModel/Testing/Data/testNrrd.ascii
+++ /dev/null
@@ -1,8 +0,0 @@
-2 2
-2 2
-2 2
-2 2
-1 1
-1 1
-1 1
-1 1
\ No newline at end of file
diff --git a/Modules/ContourModel/Testing/Data/testNrrd.nhdr b/Modules/ContourModel/Testing/Data/testNrrd.nhdr
deleted file mode 100644
index d62bdcaba6..0000000000
--- a/Modules/ContourModel/Testing/Data/testNrrd.nhdr
+++ /dev/null
@@ -1,20 +0,0 @@
-NRRD0005
-content: SomeIDNumber42
-type: short
-dimension: 4
-space: right-anterior-superior
-sizes: 2 2 2 2
-thicknesses: NaN NaN 2.5 NaN
-space directions: (2,0,0) (0,2.5,0) (0,0,2) none
-centerings: cell cell cell none
-kinds: space space space list
-endian: little
-encoding: ascii
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-data file: testNrrd.ascii
-measurement frame: (1,0,0) (0,0,1) (0,1,0)
-modality:=DWMRI
-DWMRI_b-value:=1000
-DWMRI_gradient_0000:= 0 0 0
-DWMRI_gradient_0001:= 1 0 1
\ No newline at end of file
diff --git a/Modules/ContourModel/Testing/Data/testimage.dcm b/Modules/ContourModel/Testing/Data/testimage.dcm
deleted file mode 100644
index ecf7b12d33..0000000000
Binary files a/Modules/ContourModel/Testing/Data/testimage.dcm and /dev/null differ
diff --git a/Modules/ContourModel/Testing/Data/vtkUnstructuredGrid.vtk b/Modules/ContourModel/Testing/Data/vtkUnstructuredGrid.vtk
deleted file mode 100644
index 392ef94c61..0000000000
Binary files a/Modules/ContourModel/Testing/Data/vtkUnstructuredGrid.vtk and /dev/null differ
diff --git a/Modules/DICOMReader/mitkDICOMImageBlockDescriptor.cpp b/Modules/DICOMReader/mitkDICOMImageBlockDescriptor.cpp
index ece478572e..0c709d0536 100644
--- a/Modules/DICOMReader/mitkDICOMImageBlockDescriptor.cpp
+++ b/Modules/DICOMReader/mitkDICOMImageBlockDescriptor.cpp
@@ -1,773 +1,776 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkDICOMImageBlockDescriptor.h"
#include "mitkStringProperty.h"
#include "mitkLevelWindowProperty.h"
#include <gdcmUIDs.h>
mitk::DICOMImageBlockDescriptor
::DICOMImageBlockDescriptor()
:m_ReaderImplementationLevel(SOPClassUnknown)
,m_PropertyList(PropertyList::New())
,m_TagCache(NULL)
,m_PropertiesOutOfDate(true)
{
}
mitk::DICOMImageBlockDescriptor
::~DICOMImageBlockDescriptor()
{
}
mitk::DICOMImageBlockDescriptor
::DICOMImageBlockDescriptor(const DICOMImageBlockDescriptor& other)
:m_ImageFrameList( other.m_ImageFrameList )
,m_MitkImage( other.m_MitkImage )
,m_SliceIsLoaded( other.m_SliceIsLoaded )
,m_ReaderImplementationLevel( other.m_ReaderImplementationLevel )
,m_TiltInformation( other.m_TiltInformation )
,m_PropertyList( other.m_PropertyList->Clone() )
,m_TagCache( other.m_TagCache )
,m_PropertiesOutOfDate( other.m_PropertiesOutOfDate )
{
if (m_MitkImage)
{
m_MitkImage = m_MitkImage->Clone();
}
}
mitk::DICOMImageBlockDescriptor&
mitk::DICOMImageBlockDescriptor
::operator=(const DICOMImageBlockDescriptor& other)
{
if (this != &other)
{
m_ImageFrameList = other.m_ImageFrameList;
m_MitkImage = other.m_MitkImage;
m_SliceIsLoaded = other.m_SliceIsLoaded;
m_ReaderImplementationLevel = other.m_ReaderImplementationLevel;
m_TiltInformation = other.m_TiltInformation;
if (other.m_PropertyList)
{
m_PropertyList = other.m_PropertyList->Clone();
}
if (other.m_MitkImage)
{
m_MitkImage = other.m_MitkImage->Clone();
}
m_TagCache = other.m_TagCache;
m_PropertiesOutOfDate = other.m_PropertiesOutOfDate;
}
return *this;
}
mitk::DICOMTagList
mitk::DICOMImageBlockDescriptor::GetTagsOfInterest()
{
DICOMTagList completeList;
completeList.push_back( DICOMTag(0x0018,0x1164) ); // pixel spacing
completeList.push_back( DICOMTag(0x0028,0x0030) ); // imager pixel spacing
completeList.push_back( DICOMTag(0x0008,0x0018) ); // sop instance UID
completeList.push_back( DICOMTag(0x0008,0x0016) ); // sop class UID
completeList.push_back( DICOMTag(0x0020,0x0011) ); // series number
completeList.push_back( DICOMTag(0x0008,0x1030) ); // study description
completeList.push_back( DICOMTag(0x0008,0x103e) ); // series description
completeList.push_back( DICOMTag(0x0008,0x0060) ); // modality
completeList.push_back( DICOMTag(0x0018,0x0024) ); // sequence name
completeList.push_back( DICOMTag(0x0020,0x0037) ); // image orientation
completeList.push_back( DICOMTag(0x0020,0x1041) ); // slice location
completeList.push_back( DICOMTag(0x0020,0x0012) ); // acquisition number
completeList.push_back( DICOMTag(0x0020,0x0013) ); // instance number
completeList.push_back( DICOMTag(0x0020,0x0032) ); // image position patient
completeList.push_back( DICOMTag(0x0028,0x1050) ); // window center
completeList.push_back( DICOMTag(0x0028,0x1051) ); // window width
completeList.push_back( DICOMTag(0x0008,0x0008) ); // image type
completeList.push_back( DICOMTag(0x0028,0x0004) ); // photometric interpretation
return completeList;
}
void
mitk::DICOMImageBlockDescriptor
::SetTiltInformation(const GantryTiltInformation& info)
{
m_TiltInformation = info;
}
const mitk::GantryTiltInformation
mitk::DICOMImageBlockDescriptor
::GetTiltInformation() const
{
return m_TiltInformation;
}
void
mitk::DICOMImageBlockDescriptor
::SetImageFrameList(const DICOMImageFrameList& framelist)
{
m_ImageFrameList = framelist;
m_SliceIsLoaded.resize(framelist.size());
m_SliceIsLoaded.assign(framelist.size(), false);
m_PropertiesOutOfDate = true;
}
const mitk::DICOMImageFrameList&
mitk::DICOMImageBlockDescriptor
::GetImageFrameList() const
{
return m_ImageFrameList;
}
void
mitk::DICOMImageBlockDescriptor
::SetMitkImage(Image::Pointer image)
{
if (m_MitkImage != image)
{
if (m_TagCache.IsNull())
{
MITK_ERROR << "Unable to describe MITK image with properties without a tag-cache object!";
m_MitkImage = NULL;
return;
}
if (m_ImageFrameList.empty())
{
MITK_ERROR << "Unable to describe MITK image with properties without a frame list!";
m_MitkImage = NULL;
return;
}
// Should verify that the image matches m_ImageFrameList and m_TagCache
// however, this is hard to do without re-analyzing all
// TODO we should at least make sure that the number of frames is identical (plus rows/columns, orientation)
// without gantry tilt correction, we can also check image origin
m_MitkImage = this->DescribeImageWithProperties( this->FixupSpacing(image) );
}
}
mitk::Image::Pointer
mitk::DICOMImageBlockDescriptor
::GetMitkImage() const
{
return m_MitkImage;
}
mitk::Image::Pointer
mitk::DICOMImageBlockDescriptor
::FixupSpacing(Image* mitkImage)
{
if (mitkImage)
{
Vector3D imageSpacing = mitkImage->GetGeometry()->GetSpacing();
ScalarType desiredSpacingX = imageSpacing[0];
ScalarType desiredSpacingY = imageSpacing[1];
this->GetDesiredMITKImagePixelSpacing( desiredSpacingX, desiredSpacingY ); // prefer pixel spacing over imager pixel spacing
MITK_DEBUG << "Loaded image with spacing " << imageSpacing[0] << ", " << imageSpacing[1];
MITK_DEBUG << "Found correct spacing info " << desiredSpacingX << ", " << desiredSpacingY;
imageSpacing[0] = desiredSpacingX;
imageSpacing[1] = desiredSpacingY;
mitkImage->GetGeometry()->SetSpacing( imageSpacing );
}
return mitkImage;
}
void
mitk::DICOMImageBlockDescriptor
::SetSliceIsLoaded(unsigned int index, bool isLoaded)
{
if (index < m_SliceIsLoaded.size())
{
m_SliceIsLoaded[index] = isLoaded;
}
else
{
std::stringstream ss;
ss << "Index " << index << " out of range (" << m_SliceIsLoaded.size() << " indices reserved)";
throw std::invalid_argument( ss.str() );
}
}
bool
mitk::DICOMImageBlockDescriptor
::IsSliceLoaded(unsigned int index) const
{
if (index < m_SliceIsLoaded.size())
{
return m_SliceIsLoaded[index];
}
else
{
std::stringstream ss;
ss << "Index " << index << " out of range (" << m_SliceIsLoaded.size() << " indices reserved)";
throw std::invalid_argument( ss.str() );
}
}
bool
mitk::DICOMImageBlockDescriptor
::AllSlicesAreLoaded() const
{
bool allLoaded = true;
for (BoolList::const_iterator iter = m_SliceIsLoaded.begin();
iter != m_SliceIsLoaded.end();
++iter)
{
allLoaded &= *iter;
}
return allLoaded;
}
/*
PS defined IPS defined PS==IPS
0 0 --> UNKNOWN spacing, loader will invent
0 1 --> spacing as at detector surface
1 0 --> spacing as in patient
1 1 0 --> detector surface spacing CORRECTED for geometrical magnifications: spacing as in patient
1 1 1 --> detector surface spacing NOT corrected for geometrical magnifications: spacing as at detector
*/
mitk::PixelSpacingInterpretation
mitk::DICOMImageBlockDescriptor
::GetPixelSpacingInterpretation() const
{
if ( m_ImageFrameList.empty() || m_TagCache.IsNull() )
{
MITK_ERROR << "Invalid call to GetPixelSpacingInterpretation. Need to have initialized tag-cache!";
return SpacingUnknown;
}
std::string pixelSpacing = this->GetPixelSpacing();
std::string imagerPixelSpacing = this->GetImagerPixelSpacing();
if (pixelSpacing.empty())
{
if (imagerPixelSpacing.empty())
{
return SpacingUnknown;
}
else
{
return SpacingAtDetector;
}
}
else // Pixel Spacing defined
{
if (imagerPixelSpacing.empty())
{
return SpacingInPatient;
}
else if (pixelSpacing != imagerPixelSpacing)
{
return SpacingInPatient;
}
else
{
return SpacingAtDetector;
}
}
}
std::string
mitk::DICOMImageBlockDescriptor
::GetPixelSpacing() const
{
if ( m_ImageFrameList.empty() || m_TagCache.IsNull() )
{
MITK_ERROR << "Invalid call to GetPixelSpacing. Need to have initialized tag-cache!";
return std::string("");
}
static const DICOMTag tagPixelSpacing(0x0028,0x0030);
return m_TagCache->GetTagValue( m_ImageFrameList.front(), tagPixelSpacing );
}
std::string
mitk::DICOMImageBlockDescriptor
::GetImagerPixelSpacing() const
{
if ( m_ImageFrameList.empty() || m_TagCache.IsNull() )
{
MITK_ERROR << "Invalid call to GetImagerPixelSpacing. Need to have initialized tag-cache!";
return std::string("");
}
static const DICOMTag tagImagerPixelSpacing(0x0018,0x1164);
return m_TagCache->GetTagValue( m_ImageFrameList.front(), tagImagerPixelSpacing );
}
void
mitk::DICOMImageBlockDescriptor
::GetDesiredMITKImagePixelSpacing( ScalarType& spacingX, ScalarType& spacingY) const
{
std::string pixelSpacing = this->GetPixelSpacing();
// preference for "in patient" pixel spacing
if ( !DICOMStringToSpacing( pixelSpacing, spacingX, spacingY ) )
{
std::string imagerPixelSpacing = this->GetImagerPixelSpacing();
// fallback to "on detector" spacing
if ( !DICOMStringToSpacing( imagerPixelSpacing, spacingX, spacingY ) )
{
// last resort: invent something
spacingX = spacingY = 1.0;
}
}
}
void
mitk::DICOMImageBlockDescriptor
::SetProperty(const std::string& key, BaseProperty* value)
{
m_PropertyList->SetProperty(key, value);
}
mitk::BaseProperty*
mitk::DICOMImageBlockDescriptor
::GetProperty(const std::string& key) const
{
this->UpdateImageDescribingProperties();
return m_PropertyList->GetProperty(key);
}
std::string
mitk::DICOMImageBlockDescriptor
::GetPropertyAsString(const std::string& key) const
{
this->UpdateImageDescribingProperties();
mitk::BaseProperty::Pointer property = m_PropertyList->GetProperty(key);
if (property.IsNotNull())
{
return property->GetValueAsString();
}
else
{
return std::string("");
}
}
void
mitk::DICOMImageBlockDescriptor
::SetFlag(const std::string& key, bool value)
{
m_PropertyList->ReplaceProperty(key, BoolProperty::New(value));
}
bool
mitk::DICOMImageBlockDescriptor
::GetFlag(const std::string& key, bool defaultValue) const
{
this->UpdateImageDescribingProperties();
BoolProperty::ConstPointer boolProp = dynamic_cast<BoolProperty*>( this->GetProperty(key) );
if (boolProp.IsNotNull())
{
return boolProp->GetValue();
}
else
{
return defaultValue;
}
}
void
mitk::DICOMImageBlockDescriptor
::SetIntProperty(const std::string& key, int value)
{
m_PropertyList->ReplaceProperty(key, IntProperty::New(value));
}
int
mitk::DICOMImageBlockDescriptor
::GetIntProperty(const std::string& key, int defaultValue) const
{
this->UpdateImageDescribingProperties();
IntProperty::ConstPointer intProp = dynamic_cast<IntProperty*>( this->GetProperty(key) );
if (intProp.IsNotNull())
{
return intProp->GetValue();
}
else
{
return defaultValue;
}
}
double
mitk::DICOMImageBlockDescriptor
::stringtodouble(const std::string& str) const
{
double d;
std::string trimmedstring(str);
try
{
trimmedstring = trimmedstring.erase(trimmedstring.find_last_not_of(" \n\r\t")+1);
}
catch(...)
{
// no last not of
}
std::string firstcomponent(trimmedstring);
try
{
firstcomponent = trimmedstring.erase(trimmedstring.find_first_of("\\"));
}
catch(...)
{
// no last not of
}
std::istringstream converter(firstcomponent);
if ( !firstcomponent.empty() && (converter >> d) && converter.eof() )
{
return d;
}
else
{
throw std::invalid_argument("Argument is not a convertable number");
}
}
mitk::Image::Pointer
mitk::DICOMImageBlockDescriptor
::DescribeImageWithProperties(Image* mitkImage)
{
// TODO: this is a collection of properties that have been provided by the
// legacy DicomSeriesReader.
// We should at some point clean up this collection and name them in a more
// consistent way!
if (!mitkImage) return mitkImage;
// first part: add some tags that describe individual slices
// these propeties are defined at analysis time (see UpdateImageDescribingProperties())
std::string propertyKeySliceLocation = "dicom.image.0020.1041";
std::string propertyKeyInstanceNumber = "dicom.image.0020.0013";
std::string propertyKeySOPInstanceUID = "dicom.image.0008.0018";
mitkImage->SetProperty( propertyKeySliceLocation.c_str(), this->GetProperty("sliceLocationForSlices") );
mitkImage->SetProperty( propertyKeyInstanceNumber.c_str(), this->GetProperty("instanceNumberForSlices") );
mitkImage->SetProperty( propertyKeySOPInstanceUID.c_str(), this->GetProperty("SOPInstanceUIDForSlices") );
mitkImage->SetProperty( "files", this->GetProperty("filenamesForSlices") );
// second part: add properties that describe the whole image block
mitkImage->SetProperty("dicomseriesreader.SOPClassUID",
StringProperty::New( this->GetSOPClassUID() ) );
mitkImage->SetProperty("dicomseriesreader.SOPClass",
StringProperty::New( this->GetSOPClassUIDAsName() ));
mitkImage->SetProperty("dicomseriesreader.PixelSpacingInterpretationString",
StringProperty::New( PixelSpacingInterpretationToString( this->GetPixelSpacingInterpretation() )) );
mitkImage->SetProperty("dicomseriesreader.PixelSpacingInterpretation",
GenericProperty<PixelSpacingInterpretation>::New( this->GetPixelSpacingInterpretation() ));
mitkImage->SetProperty("dicomseriesreader.ReaderImplementationLevelString",
StringProperty::New( ReaderImplementationLevelToString( m_ReaderImplementationLevel ) ));
mitkImage->SetProperty("dicomseriesreader.ReaderImplementationLevel",
GenericProperty<ReaderImplementationLevel>::New( m_ReaderImplementationLevel ));
mitkImage->SetProperty("dicomseriesreader.GantyTiltCorrected",
BoolProperty::New( this->GetTiltInformation().IsRegularGantryTilt() ));
mitkImage->SetProperty("dicomseriesreader.3D+t",
BoolProperty::New( this->GetFlag("3D+t",false) ));
// level window
std::string windowCenter = this->GetPropertyAsString("windowCenter");
std::string windowWidth = this->GetPropertyAsString("windowWidth");
try
{
double level = stringtodouble( windowCenter );
double window = stringtodouble( windowWidth );
mitkImage->SetProperty("levelwindow", LevelWindowProperty::New(LevelWindow(level,window)) );
}
catch (...)
{
// nothing, no levelwindow to be predicted...
}
+ std::string modality = this->GetPropertyAsString( "modality" );
+ mitkImage->SetProperty("modality", StringProperty::New( modality ));
+
mitkImage->SetProperty("dicom.pixel.PhotometricInterpretation", this->GetProperty("photometricInterpretation") );
mitkImage->SetProperty("dicom.image.imagetype", this->GetProperty("imagetype") );
mitkImage->SetProperty("dicom.study.StudyDescription", this->GetProperty("studyDescription") );
mitkImage->SetProperty("dicom.series.SeriesDescription", this->GetProperty("seriesDescription") );
mitkImage->SetProperty("dicom.pixel.Rows", this->GetProperty("rows") );
mitkImage->SetProperty("dicom.pixel.Columns", this->GetProperty("columns") );
// third part: get something from ImageIO. BUT this needs to be created elsewhere. or not at all!
return mitkImage;
}
void
mitk::DICOMImageBlockDescriptor
::SetReaderImplementationLevel(const ReaderImplementationLevel& level)
{
m_ReaderImplementationLevel = level;
}
mitk::ReaderImplementationLevel
mitk::DICOMImageBlockDescriptor
::GetReaderImplementationLevel() const
{
return m_ReaderImplementationLevel;
}
std::string
mitk::DICOMImageBlockDescriptor
::GetSOPClassUID() const
{
if ( !m_ImageFrameList.empty() && m_TagCache.IsNotNull() )
{
static const DICOMTag tagSOPClassUID(0x0008,0x0016);
return m_TagCache->GetTagValue( m_ImageFrameList.front(), tagSOPClassUID );
}
else
{
MITK_ERROR << "Invalid call to DICOMImageBlockDescriptor::GetSOPClassUID(). Need to have initialized tag-cache!";
return std::string("");
}
}
std::string
mitk::DICOMImageBlockDescriptor
::GetSOPClassUIDAsName() const
{
if ( !m_ImageFrameList.empty() && m_TagCache.IsNotNull() )
{
gdcm::UIDs uidKnowledge;
uidKnowledge.SetFromUID( this->GetSOPClassUID().c_str() );
const char* name = uidKnowledge.GetName();
if (name)
{
return std::string(name);
}
else
{
return std::string("");
}
}
else
{
MITK_ERROR << "Invalid call to DICOMImageBlockDescriptor::GetSOPClassUIDAsName(). Need to have initialized tag-cache!";
return std::string("");
}
}
void
mitk::DICOMImageBlockDescriptor
::SetTagCache(DICOMTagCache* privateCache)
{
// this must only be used during loading and never afterwards
m_TagCache = privateCache;
}
#define printPropertyRange(label, property_name) \
{ \
std::string first = this->GetPropertyAsString( #property_name "First"); \
std::string last = this->GetPropertyAsString( #property_name "Last"); \
if (!first.empty() || !last.empty()) \
{ \
if (first == last) \
{ \
os << " " label ": '" << first << "'" << std::endl; \
} \
else \
{ \
os << " " label ": '" << first << "' - '" << last << "'" << std::endl; \
} \
} \
}
#define printProperty(label, property_name) \
{ \
std::string first = this->GetPropertyAsString( #property_name ); \
if (!first.empty()) \
{ \
os << " " label ": '" << first << "'" << std::endl; \
} \
}
#define printBool(label, commands) \
{ \
os << " " label ": '" << (commands?"yes":"no") << "'" << std::endl; \
}
void
mitk::DICOMImageBlockDescriptor
::Print(std::ostream& os, bool filenameDetails) const
{
os << " Number of Frames: '" << m_ImageFrameList.size() << "'" << std::endl;
os << " SOP class: '" << this->GetSOPClassUIDAsName() << "'" << std::endl;
printProperty("Series Number", seriesNumber);
printProperty("Study Description", studyDescription);
printProperty("Series Description", seriesDescription);
printProperty("Modality", modality);
printProperty("Sequence Name", sequenceName);
printPropertyRange("Slice Location", sliceLocation);
printPropertyRange("Acquisition Number", acquisitionNumber);
printPropertyRange("Instance Number", instanceNumber);
printPropertyRange("Image Position", imagePositionPatient);
printProperty("Image Orientation", orientation);
os << " Pixel spacing interpretation: '" << PixelSpacingInterpretationToString(this->GetPixelSpacingInterpretation()) << "'" << std::endl;
printBool("Gantry Tilt", this->GetTiltInformation().IsRegularGantryTilt())
//printBool("3D+t", this->GetFlag("3D+t",false))
//os << " MITK image loaded: '" << (this->GetMitkImage().IsNotNull() ? "yes" : "no") << "'" << std::endl;
if (filenameDetails)
{
os << " Files in this image block:" << std::endl;
for (DICOMImageFrameList::const_iterator frameIter = m_ImageFrameList.begin();
frameIter != m_ImageFrameList.end();
++frameIter)
{
os << " " << (*frameIter)->Filename;
if ((*frameIter)->FrameNo > 0)
{
os << ", " << (*frameIter)->FrameNo;
}
os << std::endl;
}
}
}
#define storeTagValueToProperty(tag_name, tag_g, tag_e) \
{ \
const DICOMTag t(tag_g, tag_e); \
std::string tagValue = m_TagCache->GetTagValue( firstFrame, t ); \
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty(#tag_name, StringProperty::New( tagValue ) ); \
}
#define storeTagValueRangeToProperty(tag_name, tag_g, tag_e) \
{ \
const DICOMTag t(tag_g, tag_e); \
std::string tagValueFirst = m_TagCache->GetTagValue( firstFrame, t ); \
std::string tagValueLast = m_TagCache->GetTagValue( lastFrame, t ); \
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty(#tag_name "First", StringProperty::New( tagValueFirst ) ); \
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty(#tag_name "Last", StringProperty::New( tagValueLast ) ); \
}
void
mitk::DICOMImageBlockDescriptor
::UpdateImageDescribingProperties() const
{
if (!m_PropertiesOutOfDate) return;
if (!m_ImageFrameList.empty())
{
if (m_TagCache.IsNull())
{
MITK_ERROR << "Invalid call to DICOMImageBlockDescriptor::UpdateImageDescribingProperties(). Need to have initialized tag-cache!";
return;
}
DICOMImageFrameInfo::Pointer firstFrame = m_ImageFrameList.front();
DICOMImageFrameInfo::Pointer lastFrame = m_ImageFrameList.back();
// see macros above
storeTagValueToProperty(seriesNumber,0x0020,0x0011)
storeTagValueToProperty(studyDescription,0x0008,0x1030)
storeTagValueToProperty(seriesDescription,0x0008,0x103e)
storeTagValueToProperty(modality,0x0008,0x0060)
storeTagValueToProperty(sequenceName,0x0018,0x0024)
storeTagValueToProperty(orientation,0x0020,0x0037)
storeTagValueToProperty(rows,0x0028,0x0010)
storeTagValueToProperty(columns,0x0028,0x0011)
storeTagValueRangeToProperty(sliceLocation,0x0020,0x1041)
storeTagValueRangeToProperty(acquisitionNumber,0x0020,0x0012)
storeTagValueRangeToProperty(instanceNumber,0x0020,0x0013)
storeTagValueRangeToProperty(imagePositionPatient,0x0020,0x0032)
storeTagValueToProperty(windowCenter,0x0028,0x1050)
storeTagValueToProperty(windowWidth,0x0028,0x1051)
storeTagValueToProperty(imageType,0x0008,0x0008)
storeTagValueToProperty(photometricInterpretation,0x0028,0x0004)
// some per-image attributes
// frames are just numbered starting from 0. timestep 1 (the second time-step) has frames starting at (number-of-frames-per-timestep)
std::string propertyKeySliceLocation = "dicom.image.0020.1041";
std::string propertyKeyInstanceNumber = "dicom.image.0020.0013";
std::string propertyKeySOPInstanceNumber = "dicom.image.0008.0018";
StringLookupTable sliceLocationForSlices;
StringLookupTable instanceNumberForSlices;
StringLookupTable SOPInstanceUIDForSlices;
StringLookupTable filenamesForSlices;
const DICOMTag tagSliceLocation(0x0020,0x1041);
const DICOMTag tagInstanceNumber(0x0020,0x0013);
const DICOMTag tagSOPInstanceNumber(0x0008,0x0018);
unsigned int slice(0);
for (DICOMImageFrameList::const_iterator frameIter = m_ImageFrameList.begin();
frameIter != m_ImageFrameList.end();
++slice, ++frameIter)
{
std::string sliceLocation = m_TagCache->GetTagValue( *frameIter, tagSliceLocation );
sliceLocationForSlices.SetTableValue(slice, sliceLocation);
std::string instanceNumber = m_TagCache->GetTagValue( *frameIter, tagInstanceNumber );
instanceNumberForSlices.SetTableValue(slice, instanceNumber);
std::string sopInstanceUID = m_TagCache->GetTagValue( *frameIter, tagSOPInstanceNumber );
SOPInstanceUIDForSlices.SetTableValue(slice, sopInstanceUID);
std::string filename = (*frameIter)->Filename;
filenamesForSlices.SetTableValue(slice, filename);
MITK_DEBUG << "Tag info for slice " << slice
<< ": SL '" << sliceLocation
<< "' IN '" << instanceNumber
<< "' SOP instance UID '" << sopInstanceUID << "'";
}
// add property or properties with proper names
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty( "sliceLocationForSlices", StringLookupTableProperty::New( sliceLocationForSlices ) );
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty( "instanceNumberForSlices", StringLookupTableProperty::New( instanceNumberForSlices ) );
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty( "SOPInstanceUIDForSlices", StringLookupTableProperty::New( SOPInstanceUIDForSlices ) );
const_cast<DICOMImageBlockDescriptor*>(this)->SetProperty( "filenamesForSlices", StringLookupTableProperty::New( filenamesForSlices ) );
m_PropertiesOutOfDate = false;
}
}
diff --git a/Modules/DICOMReader/mitkITKDICOMSeriesReaderHelper.cpp b/Modules/DICOMReader/mitkITKDICOMSeriesReaderHelper.cpp
index 50cb1c8d22..fe9e969246 100644
--- a/Modules/DICOMReader/mitkITKDICOMSeriesReaderHelper.cpp
+++ b/Modules/DICOMReader/mitkITKDICOMSeriesReaderHelper.cpp
@@ -1,219 +1,189 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//#define MBILOG_ENABLE_DEBUG
#include "mitkITKDICOMSeriesReaderHelper.h"
#include "mitkITKDICOMSeriesReaderHelper.txx"
#define switch3DCase(IOType, T) \
case IOType: return LoadDICOMByITK< T >(filenames, correctTilt, tiltInfo, io);
bool
mitk::ITKDICOMSeriesReaderHelper
::CanHandleFile(const std::string& filename)
{
MITK_DEBUG << "ITKDICOMSeriesReaderHelper::CanHandleFile " << filename;
itk::GDCMImageIO::Pointer tester = itk::GDCMImageIO::New();
- if ( tester->CanReadFile(filename.c_str()) )
- {
- tester->SetFileName( filename.c_str() );
- tester->ReadImageInformation();
-
- std::string numberOfFrames;
- if (tester->GetValueFromTag("0028|0008", numberOfFrames))
- {
- std::istringstream converter(numberOfFrames);
- int i;
- if (converter >> i)
- {
- MITK_DEBUG << "Number of Frames for " << filename << ": " << numberOfFrames;
- return (i <= 1); // cannot handle multi-frame
- }
- else
- {
- return true; // we assume single-frame
- }
- }
- else
- {
- MITK_DEBUG << "No Number of Frames tag for " << filename;
- // friendly old single-frame file
- return true;
- }
- }
-
- MITK_DEBUG << "GDCMImageIO found: No DICOM in " << filename;
- // does not seem to be DICOM
- return false;
+ return tester->CanReadFile(filename.c_str());
}
mitk::Image::Pointer
mitk::ITKDICOMSeriesReaderHelper
::Load( const StringContainer& filenames, bool correctTilt, const GantryTiltInformation& tiltInfo )
{
if( filenames.empty() )
{
MITK_DEBUG << "Calling LoadDicomSeries with empty filename string container. Probably invalid application logic.";
return NULL; // this is not actually an error but the result is very simple
}
typedef itk::GDCMImageIO DcmIoType;
DcmIoType::Pointer io = DcmIoType::New();
try
{
if (io->CanReadFile(filenames.front().c_str()))
{
io->SetFileName(filenames.front().c_str());
io->ReadImageInformation();
if (io->GetPixelType() == itk::ImageIOBase::SCALAR)
{
switch (io->GetComponentType())
{
switch3DCase(DcmIoType::UCHAR, unsigned char)
switch3DCase(DcmIoType::CHAR, char)
switch3DCase(DcmIoType::USHORT, unsigned short)
switch3DCase(DcmIoType::SHORT, short)
switch3DCase(DcmIoType::UINT, unsigned int)
switch3DCase(DcmIoType::INT, int)
switch3DCase(DcmIoType::ULONG, long unsigned int)
switch3DCase(DcmIoType::LONG, long int)
switch3DCase(DcmIoType::FLOAT, float)
switch3DCase(DcmIoType::DOUBLE, double)
default:
MITK_ERROR << "Found unsupported DICOM scalar pixel type: (enum value) " << io->GetComponentType();
}
}
else if (io->GetPixelType() == itk::ImageIOBase::RGB)
{
switch (io->GetComponentType())
{
switch3DCase(DcmIoType::UCHAR, itk::RGBPixel<unsigned char>)
switch3DCase(DcmIoType::CHAR, itk::RGBPixel<char>)
switch3DCase(DcmIoType::USHORT, itk::RGBPixel<unsigned short>)
switch3DCase(DcmIoType::SHORT, itk::RGBPixel<short>)
switch3DCase(DcmIoType::UINT, itk::RGBPixel<unsigned int>)
switch3DCase(DcmIoType::INT, itk::RGBPixel<int>)
switch3DCase(DcmIoType::ULONG, itk::RGBPixel<long unsigned int>)
switch3DCase(DcmIoType::LONG, itk::RGBPixel<long int>)
switch3DCase(DcmIoType::FLOAT, itk::RGBPixel<float>)
switch3DCase(DcmIoType::DOUBLE, itk::RGBPixel<double>)
default:
MITK_ERROR << "Found unsupported DICOM scalar pixel type: (enum value) " << io->GetComponentType();
}
}
MITK_ERROR << "Unsupported DICOM pixel type";
return NULL;
}
}
catch(itk::MemoryAllocationError& e)
{
MITK_ERROR << "Out of memory. Cannot load DICOM series: " << e.what();
}
catch(std::exception& e)
{
MITK_ERROR << "Error encountered when loading DICOM series:" << e.what();
}
catch(...)
{
MITK_ERROR << "Unspecified error encountered when loading DICOM series.";
}
return NULL;
}
#define switch3DnTCase(IOType, T) \
case IOType: return LoadDICOMByITK3DnT< T >(filenamesLists, correctTilt, tiltInfo, io);
mitk::Image::Pointer
mitk::ITKDICOMSeriesReaderHelper
::Load3DnT( const StringContainerList& filenamesLists, bool correctTilt, const GantryTiltInformation& tiltInfo )
{
if( filenamesLists.empty() || filenamesLists.front().empty() )
{
MITK_DEBUG << "Calling LoadDicomSeries with empty filename string container. Probably invalid application logic.";
return NULL; // this is not actually an error but the result is very simple
}
typedef itk::GDCMImageIO DcmIoType;
DcmIoType::Pointer io = DcmIoType::New();
try
{
if (io->CanReadFile(filenamesLists.front().front().c_str()))
{
io->SetFileName(filenamesLists.front().front().c_str());
io->ReadImageInformation();
if (io->GetPixelType() == itk::ImageIOBase::SCALAR)
{
switch (io->GetComponentType())
{
switch3DnTCase(DcmIoType::UCHAR, unsigned char)
switch3DnTCase(DcmIoType::CHAR, char)
switch3DnTCase(DcmIoType::USHORT, unsigned short)
switch3DnTCase(DcmIoType::SHORT, short)
switch3DnTCase(DcmIoType::UINT, unsigned int)
switch3DnTCase(DcmIoType::INT, int)
switch3DnTCase(DcmIoType::ULONG, long unsigned int)
switch3DnTCase(DcmIoType::LONG, long int)
switch3DnTCase(DcmIoType::FLOAT, float)
switch3DnTCase(DcmIoType::DOUBLE, double)
default:
MITK_ERROR << "Found unsupported DICOM scalar pixel type: (enum value) " << io->GetComponentType();
}
}
else if (io->GetPixelType() == itk::ImageIOBase::RGB)
{
switch (io->GetComponentType())
{
switch3DnTCase(DcmIoType::UCHAR, itk::RGBPixel<unsigned char>)
switch3DnTCase(DcmIoType::CHAR, itk::RGBPixel<char>)
switch3DnTCase(DcmIoType::USHORT, itk::RGBPixel<unsigned short>)
switch3DnTCase(DcmIoType::SHORT, itk::RGBPixel<short>)
switch3DnTCase(DcmIoType::UINT, itk::RGBPixel<unsigned int>)
switch3DnTCase(DcmIoType::INT, itk::RGBPixel<int>)
switch3DnTCase(DcmIoType::ULONG, itk::RGBPixel<long unsigned int>)
switch3DnTCase(DcmIoType::LONG, itk::RGBPixel<long int>)
switch3DnTCase(DcmIoType::FLOAT, itk::RGBPixel<float>)
switch3DnTCase(DcmIoType::DOUBLE, itk::RGBPixel<double>)
default:
MITK_ERROR << "Found unsupported DICOM scalar pixel type: (enum value) " << io->GetComponentType();
}
}
MITK_ERROR << "Unsupported DICOM pixel type";
return NULL;
}
}
catch(itk::MemoryAllocationError& e)
{
MITK_ERROR << "Out of memory. Cannot load DICOM series: " << e.what();
}
catch(std::exception& e)
{
MITK_ERROR << "Error encountered when loading DICOM series:" << e.what();
}
catch(...)
{
MITK_ERROR << "Unspecified error encountered when loading DICOM series.";
}
return NULL;
}
diff --git a/Modules/DicomRT/CMakeLists.txt b/Modules/DicomRT/CMakeLists.txt
new file mode 100644
index 0000000000..56e50c2ab7
--- /dev/null
+++ b/Modules/DicomRT/CMakeLists.txt
@@ -0,0 +1,12 @@
+# CREATE MODULE HERE
+IF (NOT DEFINED DCMTK_dcmrt_LIBRARY OR DCMTK_dcmrt_LIBRARY)
+MITK_CREATE_MODULE(
+ INCLUDE_DIRS DataStructures
+ DEPENDS MitkSegmentation MitkSceneSerializationBase
+ PACKAGE_DEPENDS DCMTK
+ QT_MODULE
+)
+ADD_SUBDIRECTORY(Testing)
+ELSE()
+MESSAGE("MITK DicomRT Support disabled because the DCMTK dcmrt library not found")
+ENDIF()
diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h b/Modules/DicomRT/DataStructures/mitkDoseValueType.h
similarity index 63%
rename from Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h
rename to Modules/DicomRT/DataStructures/mitkDoseValueType.h
index f99fdb6099..ed3ba8680a 100644
--- a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h
+++ b/Modules/DicomRT/DataStructures/mitkDoseValueType.h
@@ -1,27 +1,37 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef mitkGetDataStorage_h
-#define mitkGetDataStorage_h
-#include <mitkDataStorage.h>
+#ifndef _MITK_DOSE_VALUE_TYPE_H_
+#define _MITK_DOSE_VALUE_TYPE_H_
namespace mitk
{
- DataStorage::Pointer GetDataStorage();
-}
-#endif
+/**
+ \brief Represents absolute dose values (in Gy).
+*/
+typedef double DoseValueAbs;
+
+/**
+\brief Represents relative dose values (in %).
+*/
+typedef double DoseValueRel;
+
+
+} // namespace mitk
+
+#endif //_MITK_DOSE_VALUE_TYPE_H_
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.cpp
new file mode 100644
index 0000000000..fa4feb2218
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.cpp
@@ -0,0 +1,79 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#include "mitkIsoDoseLevel.h"
+
+mitk::IsoDoseLevel::IsoDoseLevel() :
+m_DoseValue (0.0),
+ m_VisibleIsoLine ( true ),
+ m_VisibleColorWash (true)
+{
+ m_Color.Fill(0);
+}
+
+mitk::IsoDoseLevel::IsoDoseLevel( const IsoDoseLevel & other )
+{
+ if (&other != this)
+ {
+ this->m_Color = other.m_Color;
+ this->m_DoseValue = other.m_DoseValue;
+ this->m_VisibleColorWash = other.m_VisibleColorWash;
+ this->m_VisibleIsoLine = other.m_VisibleIsoLine;
+ }
+}
+
+mitk::IsoDoseLevel::IsoDoseLevel(const DoseValueType & value, const ColorType& color, bool visibleIsoLine, bool visibleColorWash):
+ m_DoseValue (value),
+ m_Color (color),
+ m_VisibleIsoLine ( visibleIsoLine ),
+ m_VisibleColorWash ( visibleColorWash )
+{
+};
+
+mitk::IsoDoseLevel::~IsoDoseLevel()
+{
+}
+
+bool mitk::IsoDoseLevel::operator == ( const IsoDoseLevel& right) const
+{
+ bool result = this->m_DoseValue == right.m_DoseValue;
+
+ result = result && (this->m_Color == right.m_Color);
+ result = result && (this->m_VisibleColorWash == right.m_VisibleColorWash);
+ result = result && (this->m_VisibleIsoLine == right.m_VisibleIsoLine);
+
+ return result;
+}
+
+bool mitk::IsoDoseLevel::operator <( const IsoDoseLevel& right) const
+{
+ return this->m_DoseValue < right.m_DoseValue;
+}
+
+bool mitk::IsoDoseLevel::operator > ( const IsoDoseLevel& right) const
+{
+ return this->m_DoseValue > right.m_DoseValue;
+}
+
+void mitk::IsoDoseLevel::PrintSelf(std::ostream &os, itk::Indent indent) const
+{
+ Superclass::PrintSelf(os,indent);
+ os<<indent<< "DoseValue: " << m_DoseValue<< std::endl;
+ os<<indent<< "Color: " << m_Color<< std::endl;
+ os<<indent<< "VisibleIsoLine: " << m_VisibleIsoLine<< std::endl;
+ os<<indent<< "VisibleColorWash: " << m_VisibleColorWash<< std::endl;
+};
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.h
new file mode 100644
index 0000000000..9c89d53f84
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.h
@@ -0,0 +1,104 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#ifndef _MITK_DOSE_ISO_LEVEL_H_
+#define _MITK_DOSE_ISO_LEVEL_H_
+
+#include <itkRGBPixel.h>
+#include <itkObject.h>
+#include <itkObjectFactory.h>
+
+#include "mitkCommon.h"
+#include "mitkDoseValueType.h"
+#include "MitkDicomRTExports.h"
+
+namespace mitk
+{
+
+ /**
+ \brief Stores values needed for the representation/visualization of dose iso levels.
+ *
+ * The dose iso level is defined in the topology of a dose distribution by the dose value
+ * that indicates the lower boundary of the iso level. The upper boundary is implicitly defined
+ * by the next IsoDoseLevel greater (higher dose value) than the current iso level.
+ * Color and the visibility options are used to indicate the visualization style.
+ */
+ class MitkDicomRT_EXPORT IsoDoseLevel: public itk::Object
+ {
+ public:
+ typedef ::itk::RGBPixel<float> ColorType;
+ typedef DoseValueRel DoseValueType;
+
+ mitkClassMacro(IsoDoseLevel, itk::Object);
+ itkNewMacro(Self);
+ mitkNewMacro4Param(Self,DoseValueType, ColorType, bool, bool);
+
+ /** Checks if current dose iso level instances is greater
+ according to the dose values.*/
+ bool operator> ( const IsoDoseLevel& right ) const;
+ /** Checks if current dose iso level instances is lesser
+ according to the dose values.*/
+ bool operator< ( const IsoDoseLevel& right ) const;
+
+ bool operator == ( const IsoDoseLevel& right) const;
+
+ itkSetMacro(DoseValue,DoseValueType);
+ itkGetConstMacro(DoseValue,DoseValueType);
+
+ itkSetMacro(Color,ColorType);
+ itkGetConstMacro(Color,ColorType);
+
+ itkSetMacro(VisibleIsoLine,bool);
+ itkGetConstMacro(VisibleIsoLine,bool);
+ itkBooleanMacro(VisibleIsoLine);
+
+ itkSetMacro(VisibleColorWash,bool);
+ itkGetConstMacro(VisibleColorWash,bool);
+ itkBooleanMacro(VisibleColorWash);
+
+ protected:
+ IsoDoseLevel();
+ IsoDoseLevel(const IsoDoseLevel & other);
+ IsoDoseLevel(const DoseValueType & value, const ColorType& color, bool visibleIsoLine = true, bool visibleColorWash = true );
+ virtual ~IsoDoseLevel();
+
+ mitkCloneMacro(IsoDoseLevel);
+
+ void PrintSelf(std::ostream &os, itk::Indent indent) const;
+
+ private:
+ /** Relative dose value and lower boundary of the iso level instance
+ */
+ DoseValueType m_DoseValue;
+
+ /** RGB color code that should be used for the iso level.*/
+ ColorType m_Color;
+
+ /** indicates if an iso line should be shown for the iso level
+ (the lower boundary indicated by m_DoseValue)*/
+ bool m_VisibleIsoLine;
+
+ /** indicates if a color wash should be shown for the iso level.*/
+ bool m_VisibleColorWash;
+
+ /** Not implemented on purpose*/
+ IsoDoseLevel& operator = (const IsoDoseLevel& source);
+ };
+
+} // namespace mitk
+
+#endif //_MITK_DOSE_ISO_LEVEL_H_
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.cpp
new file mode 100644
index 0000000000..0d0f8b2764
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.cpp
@@ -0,0 +1,145 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <algorithm>
+
+#include "mitkIsoDoseLevelCollections.h"
+#include "mitkExceptionMacro.h"
+
+namespace mitk
+{
+/** "Private" functor used in std::find_if to find IsoDoseLevels with a given reference value */
+class EqualDoseFunctor
+{
+public:
+ typedef IsoDoseLevel::DoseValueType DoseValueType;
+
+ EqualDoseFunctor(const DoseValueType& refValue) : m_refValue(refValue)
+ {};
+
+ bool operator () (const IsoDoseLevel* level)
+ {
+ return level->GetDoseValue() == m_refValue;
+ }
+
+protected:
+ DoseValueType m_refValue;
+};
+
+/** "Private" binary function used in std::sort to check the order of IsoDoseLeveles */
+bool lesserIsoDoseLevel(const IsoDoseLevel* first, const IsoDoseLevel* second)
+{
+ return first->GetDoseValue() < second->GetDoseValue();
+}
+}
+
+mitk::IsoDoseLevelSet::IsoDoseLevelSet(const IsoDoseLevelSet & other)
+{
+ if (&other != this)
+ {
+ this->m_IsoLevels = other.m_IsoLevels;
+ }
+};
+
+const mitk::IsoDoseLevel& mitk::IsoDoseLevelSet::GetIsoDoseLevel(IsoLevelIndexType index) const
+{
+ if (index < this->m_IsoLevels.size())
+ {
+ return *(this->m_IsoLevels[index].GetPointer());
+ }
+ else
+ {
+ mitkThrow() << "Try to access non existing dose iso level.";
+ }
+};
+
+const mitk::IsoDoseLevel& mitk::IsoDoseLevelSet::GetIsoDoseLevel(DoseValueType value) const
+{
+ InternalVectorType::const_iterator pos = std::find_if(this->m_IsoLevels.begin(), this->m_IsoLevels.end(), EqualDoseFunctor(value));
+
+ if (pos != this->m_IsoLevels.end())
+ {
+ return *(pos->GetPointer());
+ }
+ else
+ {
+ mitkThrow() << "Try to access non existing dose iso level.";
+ }
+};
+
+void mitk::IsoDoseLevelSet::SetIsoDoseLevel(const IsoDoseLevel* level)
+{
+ if (!level)
+ {
+ mitkThrow() << "Cannot set iso level. Passed null pointer.";
+ }
+
+ this->DeleteIsoDoseLevel(level->GetDoseValue());
+
+ this->m_IsoLevels.push_back(level->Clone());
+
+ std::sort(this->m_IsoLevels.begin(), this->m_IsoLevels.end(),lesserIsoDoseLevel);
+};
+
+bool mitk::IsoDoseLevelSet::DoseLevelExists(IsoLevelIndexType index) const
+{
+ return index < this->m_IsoLevels.size();
+};
+
+
+bool mitk::IsoDoseLevelSet::DoseLevelExists(DoseValueType value) const
+{
+ InternalVectorType::const_iterator pos = std::find_if(this->m_IsoLevels.begin(), this->m_IsoLevels.end(), EqualDoseFunctor(value));
+ return pos != this->m_IsoLevels.end();
+};
+
+void mitk::IsoDoseLevelSet::DeleteIsoDoseLevel(DoseValueType value)
+{
+ InternalVectorType::iterator pos = std::find_if(this->m_IsoLevels.begin(), this->m_IsoLevels.end(), EqualDoseFunctor(value));
+
+ if (pos != this->m_IsoLevels.end())
+ {
+ this->m_IsoLevels.erase(pos);
+ }
+};
+
+void mitk::IsoDoseLevelSet::DeleteIsoDoseLevel(IsoLevelIndexType index)
+{
+ if (DoseLevelExists(index))
+ {
+ this->m_IsoLevels.erase(this->m_IsoLevels.begin()+index);
+ }
+};
+
+mitk::IsoDoseLevelSet::ConstIterator mitk::IsoDoseLevelSet::Begin(void) const
+{
+ return ConstIterator(this->m_IsoLevels.begin());
+};
+
+mitk::IsoDoseLevelSet::ConstIterator mitk::IsoDoseLevelSet::End(void) const
+{
+ return ConstIterator(this->m_IsoLevels.end());
+};
+
+mitk::IsoDoseLevelSet::IsoLevelIndexType mitk::IsoDoseLevelSet::Size(void) const
+{
+ return this->m_IsoLevels.size();
+};
+
+void mitk::IsoDoseLevelSet::Reset(void)
+{
+ this->m_IsoLevels.clear();
+};
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.h
new file mode 100644
index 0000000000..dc98dd1b9b
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.h
@@ -0,0 +1,158 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#ifndef _MITK_DOSE_ISO_LEVEL_COLLECTIONS_H_
+#define _MITK_DOSE_ISO_LEVEL_COLLECTIONS_H_
+
+#include <set>
+#include <itkVectorContainer.h>
+
+#include "mitkIsoDoseLevel.h"
+
+namespace mitk
+{
+ /**
+ \class IsoDoseLevelVector
+ \brief Simple vector that stores dose iso levels.
+ *
+ * This class is for example used to store the user defined free iso values.
+ */
+ typedef ::itk::VectorContainer<unsigned int, mitk::IsoDoseLevel::Pointer> IsoDoseLevelVector;
+
+
+ /**
+ \class IsoDoseLevelSet
+ \brief Stores values needed for the representation/visualization of dose iso levels.
+ *
+ * Set of dose iso levels sorted by the dose values of the iso levels (low to high values).
+ * This data structure is used to represent the dose iso level setup used for the
+ * visualization of a dose distribution.
+ */
+class MitkDicomRT_EXPORT IsoDoseLevelSet:
+ public itk::Object
+{
+public:
+ mitkClassMacro(IsoDoseLevelSet, itk::Object);
+ itkNewMacro(Self);
+
+private:
+ /** Quick access to the STL vector type that was inherited. */
+ typedef std::vector< IsoDoseLevel::Pointer > InternalVectorType;
+ typedef InternalVectorType::size_type size_type;
+ typedef InternalVectorType::iterator VectorIterator;
+ typedef InternalVectorType::const_iterator VectorConstIterator;
+
+ InternalVectorType m_IsoLevels;
+
+protected:
+ IsoDoseLevelSet() {};
+ IsoDoseLevelSet(const IsoDoseLevelSet & other);
+
+ virtual ~IsoDoseLevelSet() {};
+
+ mitkCloneMacro(IsoDoseLevelSet);
+
+public:
+ typedef size_type IsoLevelIndexType;
+ typedef IsoDoseLevel::DoseValueType DoseValueType;
+
+ /** Convenient typedefs for the iterator and const iterator. */
+ class ConstIterator;
+
+ /** Friends to this class. */
+ friend class ConstIterator;
+
+ /** \class ConstIterator
+ * Simulate STL-vector style const iteration where dereferencing the iterator
+ * gives read access to the value.
+ */
+ class ConstIterator
+ {
+public:
+ ConstIterator() {}
+ ConstIterator(const VectorConstIterator & i): m_Iter(i) {}
+ ConstIterator(const ConstIterator & r) { m_Iter = r.m_Iter; }
+ const IsoDoseLevel & operator*() { return *(m_Iter->GetPointer()); }
+ const IsoDoseLevel * operator->() { return m_Iter->GetPointer(); }
+ ConstIterator & operator++() {++m_Iter; return *this; }
+ ConstIterator operator++(int) { ConstIterator temp(*this); ++m_Iter; return temp; }
+ ConstIterator & operator--() {--m_Iter; return *this; }
+ ConstIterator operator--(int) { ConstIterator temp(*this); --m_Iter; return temp; }
+ ConstIterator & operator=(const ConstIterator & r) {m_Iter = r.m_Iter; return *this; }
+ bool operator==(const ConstIterator & r) const { return m_Iter == r.m_Iter; }
+ bool operator!=(const ConstIterator & r) const { return m_Iter != r.m_Iter; }
+
+ const IsoDoseLevel & Value(void) const { return *(m_Iter->GetPointer()); }
+
+private:
+ VectorConstIterator m_Iter;
+ };
+
+ /* Declare the public interface routines. */
+
+ /**
+ * Read the element from the given index.
+ * It is assumed that the index exists.
+ */
+ const IsoDoseLevel& GetIsoDoseLevel(IsoLevelIndexType) const;
+ const IsoDoseLevel& GetIsoDoseLevel(DoseValueType) const;
+
+ /**
+ * Set the element value at the given index.
+ * It is assumed that the index exists.
+ */
+ void SetIsoDoseLevel(const IsoDoseLevel*);
+
+ /**
+ * Check if the index range of the vector is large enough to allow the
+ * given index without expansion.
+ */
+ bool DoseLevelExists(IsoLevelIndexType) const;
+ bool DoseLevelExists(DoseValueType) const;
+
+ /**
+ * Delete the element defined by the index identifier. In practice, it
+ * doesn't make sense to delete a vector index. Instead, this method just
+ * overwrites the index with the default element.
+ */
+ void DeleteIsoDoseLevel(DoseValueType);
+ void DeleteIsoDoseLevel(IsoLevelIndexType);
+
+ /**
+ * Get a begin const iterator for the vector.
+ */
+ ConstIterator Begin(void) const;
+
+ /**
+ * Get an end const iterator for the vector.
+ */
+ ConstIterator End(void) const;
+
+ /**
+ * Get the number of elements currently stored in the vector.
+ */
+ IsoLevelIndexType Size(void) const;
+
+ /**
+ * Clear the elements. The final size will be zero.
+ */
+ void Reset(void);
+};
+
+}
+
+#endif //_MITK_DOSE_ISO_LEVEL_COLLECTIONS_H_
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.cpp
new file mode 100644
index 0000000000..8d15835b82
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.cpp
@@ -0,0 +1,107 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#include "mitkIsoDoseLevelSetProperty.h"
+
+
+mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty()
+{
+}
+
+mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty(const mitk::IsoDoseLevelSetProperty& other)
+ : BaseProperty(other)
+ , m_IsoLevelSet(other.m_IsoLevelSet)
+{
+}
+
+mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty(IsoDoseLevelSet* levelSet) : m_IsoLevelSet(levelSet)
+{
+}
+
+mitk::IsoDoseLevelSetProperty::~IsoDoseLevelSetProperty()
+{
+}
+
+bool mitk::IsoDoseLevelSetProperty::IsEqual(const BaseProperty& property) const
+{
+ return this->m_IsoLevelSet == static_cast<const Self&>(property).m_IsoLevelSet;
+}
+
+bool mitk::IsoDoseLevelSetProperty::Assign(const BaseProperty& property)
+{
+ this->m_IsoLevelSet = static_cast<const Self&>(property).m_IsoLevelSet;
+ return true;
+}
+
+const mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetIsoDoseLevelSet() const
+{
+ return m_IsoLevelSet;
+}
+
+const mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetValue() const
+{
+ return GetIsoDoseLevelSet();
+}
+
+mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetIsoDoseLevelSet()
+{
+ return m_IsoLevelSet;
+}
+
+mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetValue()
+{
+ return GetIsoDoseLevelSet();
+}
+
+
+void mitk::IsoDoseLevelSetProperty::SetIsoDoseLevelSet(IsoDoseLevelSet* levelSet)
+{
+ if(m_IsoLevelSet != levelSet)
+ {
+ m_IsoLevelSet = levelSet;
+ Modified();
+ }
+}
+
+void mitk::IsoDoseLevelSetProperty::SetValue(IsoDoseLevelSet* levelSet)
+{
+ SetIsoDoseLevelSet(levelSet);
+}
+
+std::string mitk::IsoDoseLevelSetProperty::GetValueAsString() const
+{
+ std::stringstream myStr;
+
+ myStr << "IsoDoseLevels: ";
+
+ if (m_IsoLevelSet.IsNotNull())
+ {
+ myStr << m_IsoLevelSet->Size() << std::endl;
+
+ for (IsoDoseLevelSet::ConstIterator pos = m_IsoLevelSet->Begin(); pos != m_IsoLevelSet->End(); ++pos)
+ {
+ myStr << " " << 100*(pos->GetDoseValue()) << "% : ("<<pos->GetColor()<< "); iso line: " << pos->GetVisibleIsoLine() << "; color wash: "<<pos->GetVisibleColorWash() << std::endl;
+ }
+ }
+ return myStr.str();
+}
+
+itk::LightObject::Pointer mitk::IsoDoseLevelSetProperty::InternalClone() const
+{
+ itk::LightObject::Pointer result(new Self(*this));
+ return result;
+}
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.h
new file mode 100644
index 0000000000..a6f7c5357a
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.h
@@ -0,0 +1,80 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#ifndef _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_
+#define _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_
+
+#include "mitkBaseProperty.h"
+#include "mitkIsoDoseLevelCollections.h"
+#include "MitkDicomRTExports.h"
+
+namespace mitk {
+
+/**
+\brief Property class for dose iso level sets.
+*/
+class MitkDicomRT_EXPORT IsoDoseLevelSetProperty : public BaseProperty
+{
+
+protected:
+ IsoDoseLevelSet::Pointer m_IsoLevelSet;
+
+ IsoDoseLevelSetProperty();
+
+ IsoDoseLevelSetProperty(const IsoDoseLevelSetProperty& other);
+
+ IsoDoseLevelSetProperty(IsoDoseLevelSet* levelSet);
+
+public:
+ mitkClassMacro(IsoDoseLevelSetProperty, BaseProperty);
+
+ itkNewMacro(IsoDoseLevelSetProperty);
+ mitkNewMacro1Param(IsoDoseLevelSetProperty, IsoDoseLevelSet*);
+
+ typedef IsoDoseLevelSet ValueType;
+
+ virtual ~IsoDoseLevelSetProperty();
+
+ const IsoDoseLevelSet * GetIsoDoseLevelSet() const;
+ const IsoDoseLevelSet * GetValue() const;
+ IsoDoseLevelSet * GetIsoDoseLevelSet();
+ IsoDoseLevelSet * GetValue();
+
+
+ void SetIsoDoseLevelSet(IsoDoseLevelSet* levelSet);
+ void SetValue(IsoDoseLevelSet* levelSet);
+
+ virtual std::string GetValueAsString() const;
+
+ using BaseProperty::operator=;
+
+private:
+
+ // purposely not implemented
+ IsoDoseLevelSetProperty& operator=(const IsoDoseLevelSetProperty&);
+
+ itk::LightObject::Pointer InternalClone() const;
+
+ virtual bool IsEqual(const BaseProperty& property) const;
+ virtual bool Assign(const BaseProperty& property);
+
+};
+
+} // namespace mitk
+
+
+#endif /* _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_ */
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.cpp
new file mode 100644
index 0000000000..cc4b577bc7
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.cpp
@@ -0,0 +1,107 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#include "mitkIsoDoseLevelVectorProperty.h"
+
+
+mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty()
+{
+}
+
+mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty(const mitk::IsoDoseLevelVectorProperty& other)
+ : BaseProperty(other)
+ , m_IsoLevelVector(other.m_IsoLevelVector)
+{
+}
+
+mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty(IsoDoseLevelVector* levelVector) : m_IsoLevelVector(levelVector)
+{
+}
+
+mitk::IsoDoseLevelVectorProperty::~IsoDoseLevelVectorProperty()
+{
+}
+
+bool mitk::IsoDoseLevelVectorProperty::IsEqual(const BaseProperty& property) const
+{
+ return this->m_IsoLevelVector == static_cast<const Self&>(property).m_IsoLevelVector;
+}
+
+bool mitk::IsoDoseLevelVectorProperty::Assign(const BaseProperty& property)
+{
+ this->m_IsoLevelVector = static_cast<const Self&>(property).m_IsoLevelVector;
+ return true;
+}
+
+const mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetIsoDoseLevelVector() const
+{
+ return m_IsoLevelVector;
+}
+
+const mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetValue() const
+{
+ return GetIsoDoseLevelVector();
+}
+
+mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetIsoDoseLevelVector()
+{
+ return m_IsoLevelVector;
+}
+
+mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetValue()
+{
+ return GetIsoDoseLevelVector();
+}
+
+
+void mitk::IsoDoseLevelVectorProperty::SetIsoDoseLevelVector(IsoDoseLevelVector* levelVector)
+{
+ if(m_IsoLevelVector != levelVector)
+ {
+ m_IsoLevelVector = levelVector;
+ Modified();
+ }
+}
+
+void mitk::IsoDoseLevelVectorProperty::SetValue(IsoDoseLevelVector* levelVector)
+{
+ SetIsoDoseLevelVector(levelVector);
+}
+
+std::string mitk::IsoDoseLevelVectorProperty::GetValueAsString() const
+{
+ std::stringstream myStr;
+
+ myStr << "IsoDoseLevels: ";
+
+ if (m_IsoLevelVector.IsNotNull())
+ {
+ myStr << m_IsoLevelVector->Size() << std::endl;
+
+ for (IsoDoseLevelVector::ConstIterator pos = m_IsoLevelVector->Begin(); pos != m_IsoLevelVector->End(); ++pos)
+ {
+ myStr << " " << 100*(pos->Value()->GetDoseValue()) << "% : ("<<pos->Value()->GetColor()<< "); iso line: " << pos->Value()->GetVisibleIsoLine() << std::endl;
+ }
+ }
+ return myStr.str();
+}
+
+itk::LightObject::Pointer mitk::IsoDoseLevelVectorProperty::InternalClone() const
+{
+ itk::LightObject::Pointer result(new Self(*this));
+ return result;
+}
diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.h
new file mode 100644
index 0000000000..3a680bcf7a
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.h
@@ -0,0 +1,81 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#ifndef _MITK_DOSE_ISO_LEVEL_VECTOR_PROPERTY_H_
+#define _MITK_DOSE_ISO_LEVEL_VECTOR_PROPERTY_H_
+
+#include "mitkBaseProperty.h"
+#include "mitkIsoDoseLevelCollections.h"
+#include "MitkDicomRTExports.h"
+
+namespace mitk {
+
+/**
+\brief Property class for dose iso level vector.
+*/
+class MitkDicomRT_EXPORT IsoDoseLevelVectorProperty : public BaseProperty
+{
+
+protected:
+ IsoDoseLevelVector::Pointer m_IsoLevelVector;
+
+ IsoDoseLevelVectorProperty();
+
+ IsoDoseLevelVectorProperty(const IsoDoseLevelVectorProperty& other);
+
+ IsoDoseLevelVectorProperty(IsoDoseLevelVector* levelVector);
+
+public:
+ mitkClassMacro(IsoDoseLevelVectorProperty, BaseProperty);
+
+ itkNewMacro(IsoDoseLevelVectorProperty);
+ mitkNewMacro1Param(IsoDoseLevelVectorProperty, IsoDoseLevelVector*);
+
+ typedef IsoDoseLevelVector ValueType;
+
+ virtual ~IsoDoseLevelVectorProperty();
+
+ const IsoDoseLevelVector * GetIsoDoseLevelVector() const;
+ const IsoDoseLevelVector * GetValue() const;
+ IsoDoseLevelVector * GetIsoDoseLevelVector();
+ IsoDoseLevelVector * GetValue();
+
+
+ void SetIsoDoseLevelVector(IsoDoseLevelVector* levelVector);
+ void SetValue(IsoDoseLevelVector* levelVector);
+
+ virtual std::string GetValueAsString() const;
+
+ using BaseProperty::operator=;
+
+private:
+
+ // purposely not implemented
+ IsoDoseLevelVectorProperty& operator=(const IsoDoseLevelVectorProperty&);
+
+ itk::LightObject::Pointer InternalClone() const;
+
+ virtual bool IsEqual(const BaseProperty& property) const;
+ virtual bool Assign(const BaseProperty& property);
+
+};
+
+} // namespace mitk
+
+
+
+#endif /* _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_ */
diff --git a/Modules/DicomRT/DataStructures/mitkRTConstants.cpp b/Modules/DicomRT/DataStructures/mitkRTConstants.cpp
new file mode 100644
index 0000000000..1dfd7b57d0
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkRTConstants.cpp
@@ -0,0 +1,28 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkRTConstants.h"
+
+const std::string mitk::Constants::DOSE_PROPERTY_NAME = "dose";
+const std::string mitk::Constants::PRESCRIBED_DOSE_PROPERTY_NAME = "dose.PrescribedDose";
+const std::string mitk::Constants::REFERENCE_DOSE_PROPERTY_NAME = "dose.ReferenceDose";
+const std::string mitk::Constants::DOSE_TYPE_PROPERTY_NAME = "dose.type";
+const std::string mitk::Constants::DOSE_SUMMATION_TYPE_PROPERTY_NAME = "dose.summationType";
+const std::string mitk::Constants::DOSE_FRACTION_COUNT_PROPERTY_NAME = "dose.fractionCount";
+const std::string mitk::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME = "dose.showIsoLines";
+const std::string mitk::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME = "dose.showColorWash";
+const std::string mitk::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME = "dose.isoLevels";
+const std::string mitk::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME = "dose.freeIsoValues";
diff --git a/Modules/DicomRT/DataStructures/mitkRTConstants.h b/Modules/DicomRT/DataStructures/mitkRTConstants.h
new file mode 100644
index 0000000000..72dde62f8f
--- /dev/null
+++ b/Modules/DicomRT/DataStructures/mitkRTConstants.h
@@ -0,0 +1,87 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef _MITK_RT_CONSTANTS_H_
+#define _MITK_RT_CONSTANTS_H_
+
+#include <string>
+
+#include "MitkDicomRTExports.h"
+
+namespace mitk
+{
+struct MitkDicomRT_EXPORT Constants
+{
+ /**
+ * Name of the property that indicates if a data/node is a dose.
+ */
+ static const std::string DOSE_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes the prescribed dose associated with the data node
+ * If a RTPLAN file exists the value can be extracted from the tag (300A,0026) - Target Prescription Dose in the plan file.
+ */
+ static const std::string PRESCRIBED_DOSE_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes the reference dose that should be used for relative dose vizualization/evaluation purpose.
+ * It is often the prescribed dose but may differ e.g. when to dose distributions sould be compared using the same reference.
+ */
+ static const std::string REFERENCE_DOSE_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes the optional string property holding the information from the tag (3004,0004) - Dose Type.
+ * This contains useful information for medical doctors
+ */
+ static const std::string DOSE_TYPE_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes the optional string property holding the information from the tag (3004,000A) - Dose Summation Type.
+ * This contains useful information for medical doctors
+ */
+ static const std::string DOSE_SUMMATION_TYPE_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes the number of fractions.
+ * It is for example in DICOM stored in tag (300A,0078) - Number of Fractions Prescribed (from the RTPLAN file if this file exists).
+ * This value could be used to further scale the dose according to dose summation type.
+ * For example a given plan consists of 8 fractions. Scaling the fraction dose by 8 gives the complete planned dose.
+ */
+ static const std::string DOSE_FRACTION_COUNT_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes if the iso line rendering should be activated for the node.
+ */
+ static const std::string DOSE_SHOW_ISOLINES_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes if the color wash rendering should be activated for the node.
+ */
+ static const std::string DOSE_SHOW_COLORWASH_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes if the set of iso levels should be used to visualize the dose distribution.
+ */
+ static const std::string DOSE_ISO_LEVELS_PROPERTY_NAME;
+
+ /**
+ * Name of the property that encodes user defined iso values that mark special dose values in the distribution.
+ */
+ static const std::string DOSE_FREE_ISO_VALUES_PROPERTY_NAME;
+};
+}
+
+#endif
diff --git a/Modules/Ext/Testing/CMakeLists.txt b/Modules/DicomRT/Testing/CMakeLists.txt
similarity index 100%
rename from Modules/Ext/Testing/CMakeLists.txt
rename to Modules/DicomRT/Testing/CMakeLists.txt
diff --git a/Modules/DicomRT/Testing/files.cmake b/Modules/DicomRT/Testing/files.cmake
new file mode 100644
index 0000000000..f9c7fa5d99
--- /dev/null
+++ b/Modules/DicomRT/Testing/files.cmake
@@ -0,0 +1,4 @@
+SET(MODULE_TESTS
+ mitkRTStructureSetReaderTest.cpp
+ mitkRTDoseReaderTest.cpp
+)
diff --git a/Modules/DicomRT/Testing/mitkRTDoseReaderTest.cpp b/Modules/DicomRT/Testing/mitkRTDoseReaderTest.cpp
new file mode 100644
index 0000000000..9ada1d9033
--- /dev/null
+++ b/Modules/DicomRT/Testing/mitkRTDoseReaderTest.cpp
@@ -0,0 +1,54 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkTestingMacros.h>
+#include <mitkTestFixture.h>
+
+#include <mitkRTDoseReader.h>
+#include <mitkIOUtil.h>
+
+class mitkRTDoseReaderTestSuite : public mitk::TestFixture
+{
+ CPPUNIT_TEST_SUITE(mitkRTDoseReaderTestSuite);
+ MITK_TEST(TestDoseImage);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ mitk::RTDoseReader::Pointer m_rtDoseReader;
+
+public:
+
+ void setUp()
+ {
+ m_rtDoseReader = mitk::RTDoseReader::New();
+ CPPUNIT_ASSERT_MESSAGE("Failed to initialize RTDoseReader", m_rtDoseReader.IsNotNull());
+ }
+
+ void TestDoseImage()
+ {
+ mitk::Image::Pointer refImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("RT/Dose/RT_Dose.nrrd"));
+
+ mitk::DataNode::Pointer node = m_rtDoseReader->LoadRTDose(GetTestDataFilePath("RT/Dose/RD.dcm").c_str());
+ mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
+
+ MITK_ASSERT_EQUAL(refImage, image, "referece-Image and image should be equal");
+
+ }
+
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkRTDoseReader)
diff --git a/Modules/DicomRT/Testing/mitkRTStructureSetReaderTest.cpp b/Modules/DicomRT/Testing/mitkRTStructureSetReaderTest.cpp
new file mode 100644
index 0000000000..3930f10237
--- /dev/null
+++ b/Modules/DicomRT/Testing/mitkRTStructureSetReaderTest.cpp
@@ -0,0 +1,165 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkTestingMacros.h"
+#include <mitkTestFixture.h>
+
+#include "mitkRTStructureSetReader.h"
+#include <mitkContourModelSet.h>
+#include <mitkContourModelSetReader.h>
+#include <mitkStringProperty.h>
+
+class mitkRTStructureSetReaderTestSuite : public mitk::TestFixture
+{
+ CPPUNIT_TEST_SUITE(mitkRTStructureSetReaderTestSuite);
+// MITK_TEST(TestBody);
+ MITK_TEST(TestStructureSets);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ mitk::RTStructureSetReader::Pointer m_rtStructureReader;
+
+public:
+
+ void setUp()
+ {
+ m_rtStructureReader = mitk::RTStructureSetReader::New();
+ CPPUNIT_ASSERT_MESSAGE("Failed to initialize RTStructureSetReader", m_rtStructureReader.IsNotNull());
+ }
+
+ void TestStructureSets()
+ {
+ std::deque<mitk::ContourModelSet::Pointer> contourModelVectorCorrect;
+ std::deque<mitk::ContourModelSet::Pointer> contourModelVectorCorrectSequ;
+ std::deque<mitk::DataNode::Pointer> contourModelVectorTest;
+ std::deque<mitk::ContourModelSet::Pointer> contourModelVectorTestDel;
+
+ LoadData(contourModelVectorCorrect);
+
+ contourModelVectorTest = m_rtStructureReader->ReadStructureSet(GetTestDataFilePath("RT/StructureSet/RS.dcm").c_str());
+
+ //Deleting all empty contourmodelsets - empty contourmodelsets cant be
+ //saved so we have reference for the comparison
+ for(unsigned int i=0; i<contourModelVectorTest.size();++i)
+ {
+ if(dynamic_cast<mitk::ContourModelSet*>(contourModelVectorTest.at(i)->GetData())->GetSize()>0){
+ contourModelVectorTestDel.push_back(dynamic_cast<mitk::ContourModelSet*>(contourModelVectorTest.at(i)->GetData()));
+ }
+ }
+
+ //Loop for ordering the loaded contourmodelsets(contourModelVectorCorrect)
+ for(unsigned int i=0; i<contourModelVectorTestDel.size();++i)
+ {
+ mitk::BaseProperty::Pointer name = contourModelVectorTestDel.at(i)->GetProperty("name");
+ for(unsigned int j=0; j<contourModelVectorCorrect.size();++j)
+ {
+ mitk::BaseProperty::Pointer tmp = contourModelVectorCorrect.at(j)->GetProperty("name");
+ if(tmp->GetValueAsString().compare(name->GetValueAsString()) == 0)
+ contourModelVectorCorrectSequ.push_back(contourModelVectorCorrect.at(j));
+ }
+ }
+
+ //Testing wheather the two deques are equal
+ bool equal = true;
+ for(unsigned int i=0;i<contourModelVectorCorrectSequ.size();++i)
+ {
+ if(!Compare(contourModelVectorCorrectSequ.at(i),contourModelVectorTestDel.at(i)))
+ equal = false;
+ }
+
+ CPPUNIT_ASSERT(equal);
+ }
+
+ bool Compare(mitk::ContourModelSet::Pointer c1, mitk::ContourModelSet::Pointer c2){
+ if(c1->GetSize()!=c2->GetSize())
+ {
+ MITK_INFO << "Number of ContourModelSets different" << std::endl;
+ return false;
+ }
+ else
+ {
+ for(int i=0;i<c1->GetSize();++i)
+ {
+ mitk::ContourModel::Pointer cm1 = c1->GetContourModelAt(i);
+ mitk::ContourModel::Pointer cm2 = c2->GetContourModelAt(i);
+ if(cm1->GetNumberOfVertices()!=cm2->GetNumberOfVertices())
+ {
+ MITK_INFO << "Number of Vertices different" << std::endl;
+ return false;
+ }
+ else
+ {
+ float ep = 0.001;
+ for(int j=0;j<cm1->GetNumberOfVertices();++j)
+ {
+ mitk::Point3D p1 = cm1->GetVertexAt(i)->Coordinates;
+ mitk::Point3D p2 = cm2->GetVertexAt(i)->Coordinates;
+ if(abs(p1[0]-p2[0]) > ep || abs(p1[0]-p2[0]) > ep || abs(p1[0]-p2[0]) > ep)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ void LoadData(std::deque<mitk::ContourModelSet::Pointer> &r)
+ {
+ mitk::ContourModelSetReader::Pointer reader = mitk::ContourModelSetReader::New();
+
+ reader->SetFileName(GetTestDataFilePath("RT/StructureSet/BODY.cnt_set"));
+ reader->Update();
+ mitk::ContourModelSet::Pointer cnt_set = reader->GetOutput();
+ cnt_set->SetProperty("name", mitk::StringProperty::New("BODY"));
+ r.push_back(cnt_set);
+
+ reader->SetFileName(GetTestDataFilePath("RT/StructureSet/Bladder.cnt_set"));
+ reader->Update();
+ cnt_set = reader->GetOutput();
+ cnt_set->SetProperty("name", mitk::StringProperty::New("Bladder"));
+ r.push_back(cnt_set);
+
+ reader->SetFileName(GetTestDataFilePath("RT/StructureSet/Femoral Head Lt.cnt_set"));
+ reader->Update();
+ cnt_set = reader->GetOutput();
+ cnt_set->SetProperty("name", mitk::StringProperty::New("Femoral Head Lt"));
+ r.push_back(cnt_set);
+
+ reader->SetFileName(GetTestDataFilePath("RT/StructureSet/Femoral Head RT.cnt_set"));
+ reader->Update();
+ cnt_set = reader->GetOutput();
+ cnt_set->SetProperty("name", mitk::StringProperty::New("Femoral Head RT"));
+ r.push_back(cnt_set);
+
+ reader->SetFileName(GetTestDataFilePath("RT/StructureSet/PTV.cnt_set"));
+ reader->Update();
+ cnt_set = reader->GetOutput();
+ cnt_set->SetProperty("name", mitk::StringProperty::New("PTV"));
+ r.push_back(cnt_set);
+
+ reader->SetFileName(GetTestDataFilePath("RT/StructureSet/Rectum.cnt_set"));
+ reader->Update();
+ cnt_set = reader->GetOutput();
+ cnt_set->SetProperty("name", mitk::StringProperty::New("Rectum"));
+ r.push_back(cnt_set);
+ }
+
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkRTStructureSetReader)
diff --git a/Modules/DicomRT/files.cmake b/Modules/DicomRT/files.cmake
new file mode 100644
index 0000000000..f638320b1f
--- /dev/null
+++ b/Modules/DicomRT/files.cmake
@@ -0,0 +1,26 @@
+SET(CPP_FILES
+ mitkRTDoseReader.cpp
+ mitkRTStructureSetReader.cpp
+ DataStructures/mitkRTConstants.cpp
+ DataStructures/mitkIsoDoseLevel.cpp
+ DataStructures/mitkIsoDoseLevelCollections.cpp
+ DataStructures/mitkIsoDoseLevelSetProperty.cpp
+ DataStructures/mitkIsoDoseLevelVectorProperty.cpp
+)
+
+set(H_FILES
+ mitkRTDoseReader.h
+ mitkRTStructureSetReader.h
+ DataStructures/mitkIsoDoseLevel.h
+ DataStructures/mitkIsoDoseLevelCollections.h
+ DataStructures/mitkIsoDoseLevelSetProperty.h
+ DataStructures/mitkIsoDoseLevelVectorProperty.h
+ DataStructures/mitkDoseValueType.h
+ DataStructures/mitkRTConstants.h
+)
+
+set(TPP_FILES
+)
+
+set(MOC_H_FILES
+)
diff --git a/Modules/DicomRT/mitkRTDoseReader.cpp b/Modules/DicomRT/mitkRTDoseReader.cpp
new file mode 100644
index 0000000000..96833dae43
--- /dev/null
+++ b/Modules/DicomRT/mitkRTDoseReader.cpp
@@ -0,0 +1,145 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#include "mitkRTDoseReader.h"
+
+#include <mitkIOUtil.h>
+#include <mitkDataNodeFactory.h>
+#include <mitkImagePixelWriteAccessor.h>
+#include <mitkImageAccessByItk.h>
+#include <itkImageIterator.h>
+#include <itkImageRegionIterator.h>
+
+#include <DataStructures/mitkRTConstants.h>
+
+namespace mitk
+{
+
+ RTDoseReader::RTDoseReader(){}
+
+ RTDoseReader::~RTDoseReader(){}
+
+ mitk::DataNode::Pointer RTDoseReader::
+ LoadRTDose(const char* filename)
+ {
+ DcmFileFormat fileformat;
+ OFCondition outp = fileformat.loadFile(filename, EXS_Unknown);
+ if(outp.bad())
+ {
+ MITK_ERROR << "Cant read the file" << std::endl;
+ }
+ DcmDataset *dataset = fileformat.getDataset();
+
+ std::string name = filename;
+ itk::FilenamesContainer file;
+ file.push_back(name);
+
+ mitk::DicomSeriesReader* reader = new mitk::DicomSeriesReader;
+
+ mitk::DataNode::Pointer originalNode = reader->LoadDicomSeries(file,false);
+
+ if(originalNode.IsNull())
+ {
+ MITK_ERROR << "Error reading the dcm file" << std::endl;
+ return 0;
+ }
+
+ mitk::Image::Pointer originalImage
+ = dynamic_cast<mitk::Image*>(originalNode->GetData());
+
+ DRTDoseIOD doseObject;
+ OFCondition result = doseObject.read(*dataset);
+
+ if(result.bad())
+ {
+ MITK_ERROR << "Error reading the Dataset" << std::endl;
+ return 0;
+ }
+
+ OFString gridScaling;
+ Float32 gridscale;
+
+ doseObject.getDoseGridScaling(gridScaling);
+ gridscale = OFStandard::atof(gridScaling.c_str());
+
+ AccessByItk_1(originalImage, MultiplayGridScaling, gridscale);
+
+ double prescripeDose = this->GetMaxDoseValue(dataset);
+
+ originalNode->SetName("RT Dose");
+ originalNode->SetFloatProperty(mitk::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescripeDose);
+ originalNode->SetFloatProperty(mitk::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), 40);
+ originalNode->SetBoolProperty(mitk::Constants::DOSE_PROPERTY_NAME.c_str(),true);
+ return originalNode;
+ }
+
+ template<typename TPixel, unsigned int VImageDimension>
+ void RTDoseReader::MultiplayGridScaling(itk::Image<TPixel,
+ VImageDimension>* image,
+ Float32 gridscale)
+ {
+ typedef itk::Image<TPixel, VImageDimension> InputImageType;
+ itk::ImageRegionIterator<InputImageType> it(image,
+ image->GetRequestedRegion());
+ for(it=it.Begin(); !it.IsAtEnd(); ++it)
+ {
+ it.Set(it.Get()*gridscale);
+ }
+ }
+
+ double RTDoseReader::GetMaxDoseValue(DcmDataset* dataSet)
+ {
+ DRTDoseIOD doseObject;
+ OFCondition result = doseObject.read(*dataSet);
+ if(result.bad())
+ {
+ MITK_ERROR << "Error reading the RT Dose dataset" << std::endl;
+ return 0;
+ }
+
+ Uint16 rows, columns, frames;
+ OFString nrframes, gridScaling;
+ const Uint16 *pixelData = NULL;
+ Float32 gridscale;
+
+ Uint16 &rows_ref = rows;
+ Uint16 &columns_ref = columns;
+
+ doseObject.getRows(rows_ref);
+ doseObject.getColumns(columns_ref);
+ doseObject.getNumberOfFrames(nrframes);
+ doseObject.getDoseGridScaling(gridScaling);
+
+ frames = atoi(nrframes.c_str());
+ gridscale = OFStandard::atof(gridScaling.c_str());
+ dataSet->findAndGetUint16Array(DCM_PixelData, pixelData, 0);
+
+ int size = columns*rows*frames;
+ double highest = 0;
+
+ for(int i=0; i<size; ++i)
+ {
+ if((pixelData[i]*gridscale)>highest)
+ {
+ highest = pixelData[i] * gridscale;
+ }
+ }
+
+ return highest;
+ }
+
+}
diff --git a/Modules/DicomRT/mitkRTDoseReader.h b/Modules/DicomRT/mitkRTDoseReader.h
new file mode 100644
index 0000000000..af90d0d14d
--- /dev/null
+++ b/Modules/DicomRT/mitkRTDoseReader.h
@@ -0,0 +1,86 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#ifndef mitkDicomRTReader_h
+#define mitkDicomRTReader_h
+
+#include <itkObject.h>
+#include <itkObjectFactory.h>
+#include <mitkCommon.h>
+#include <MitkDicomRTExports.h>
+
+#include "dcmtk/dcmrt/drtdose.h"
+
+#include <itkGDCMSeriesFileNames.h>
+#include <mitkDicomSeriesReader.h>
+#include <mitkImage.h>
+
+namespace mitk
+{
+
+ class MitkDicomRT_EXPORT RTDoseReader: public itk::Object
+ {
+
+ public:
+
+ mitkClassMacro( RTDoseReader, itk::Object );
+ itkNewMacro( Self );
+
+ template<typename TPixel, unsigned int VImageDimension>
+ void MultiplayGridScaling( itk::Image< TPixel, VImageDimension>* image, Float32 gridscale);
+
+ /**
+ * @brief Get the maximum dose value from the dose file
+ * @param dataSet The DcmDataset of the DicomRTDose file
+ * @return The dose value
+ *
+ * Checks all pixel values for the maximum value
+ */
+ double GetMaxDoseValue(DcmDataset* dataSet);
+
+ /**
+ * @brief Reads a DcmDataset from a DicomRT dose file
+ * @param dataset DcmDataset-object from DCMTK
+ * @param filename The path with the dose file used for getting the geometry
+ * @return Returns a mitkDataNode::Pointer in which a mitk::Image is stored
+ *
+ * The method reads the PixelData from the DicomRT dose file and scales
+ * them with a factor for getting Gray-values instead of pixel-values.
+ * The Gray-values are stored in a mitkImage with a vtkColorTransferFunc.
+ * Relative values are used for coloring the image. The relative values are
+ * relative to a PrescriptionDose definied in the RT-Plan. If there is no
+ * RT-Plan file PrescriptionDose is set to 80% of the maximum dose.
+ */
+ mitk::DataNode::Pointer LoadRTDose(const char* filename);
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~RTDoseReader();
+
+ protected:
+
+ /**
+ * Constructor.
+ */
+ RTDoseReader();
+
+ };
+
+}
+
+#endif
diff --git a/Modules/DicomRT/mitkRTStructureSetReader.cpp b/Modules/DicomRT/mitkRTStructureSetReader.cpp
new file mode 100644
index 0000000000..cda808bfc9
--- /dev/null
+++ b/Modules/DicomRT/mitkRTStructureSetReader.cpp
@@ -0,0 +1,248 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkRTStructureSetReader.h"
+#include <mitkIOUtil.h>
+
+#include <mitkBaseRenderer.h>
+
+namespace mitk
+{
+ RTStructureSetReader::RTStructureSetReader(){}
+
+ RTStructureSetReader::~RTStructureSetReader(){}
+
+ RTStructureSetReader::RoiEntry::RoiEntry()
+ {
+ Number = 0;
+ DisplayColor[0]=1.0;
+ DisplayColor[1]=0.0;
+ DisplayColor[2]=0.0;
+ ContourModelSet=mitk::ContourModelSet::New();
+ }
+
+ RTStructureSetReader::RoiEntry::RoiEntry(const RoiEntry &src)
+ {
+ Number=src.Number;
+ Name=src.Name;
+ Description=src.Description;
+ DisplayColor[0]=src.DisplayColor[0];
+ DisplayColor[1]=src.DisplayColor[1];
+ DisplayColor[2]=src.DisplayColor[2];
+ ContourModelSet=mitk::ContourModelSet::New();
+ SetPolyData(src.ContourModelSet);
+ }
+
+ RTStructureSetReader::RoiEntry::~RoiEntry(){}
+
+ RTStructureSetReader::RoiEntry& RTStructureSetReader::
+ RoiEntry::operator =(const RoiEntry &src)
+ {
+ Number=src.Number;
+ Name=src.Name;
+ Description=src.Description;
+ DisplayColor[0]=src.DisplayColor[0];
+ DisplayColor[1]=src.DisplayColor[1];
+ DisplayColor[2]=src.DisplayColor[2];
+ SetPolyData(src.ContourModelSet);
+ return (*this);
+ }
+
+ void RTStructureSetReader::RoiEntry::
+ SetPolyData(mitk::ContourModelSet::Pointer roiPolyData)
+ {
+ if (roiPolyData == this->ContourModelSet)
+ return;
+ this->ContourModelSet = roiPolyData;
+ }
+
+ size_t RTStructureSetReader::GetNumberOfROIs()
+ {
+ return this->ROISequenceVector.size();
+ }
+
+ RTStructureSetReader::RoiEntry* RTStructureSetReader::
+ FindRoiByNumber(unsigned int roiNum)
+ {
+ for(unsigned int i=0; i<this->ROISequenceVector.size(); ++i)
+ {
+ if(this->ROISequenceVector[i].Number == roiNum)
+ return &this->ROISequenceVector[i];
+ }
+ return NULL;
+ }
+
+ RTStructureSetReader::ContourModelSetNodes RTStructureSetReader::
+ ReadStructureSet(const char* filepath)
+ {
+ DcmFileFormat file;
+ OFCondition output = file.loadFile(filepath, EXS_Unknown);
+ if(output.bad())
+ {
+ MITK_ERROR << "Cant read the file" << std::endl;
+ }
+ DcmDataset *dataset = file.getDataset();
+
+ DRTStructureSetIOD structureSetObject;
+ OFCondition outp = structureSetObject.read(*dataset);
+ if(!outp.good())
+ {
+ MITK_ERROR << "Error reading the file" << std::endl;
+ RTStructureSetReader::ContourModelSetNodes x;
+ return x;
+ }
+ DRTStructureSetROISequence &roiSequence =
+ structureSetObject.getStructureSetROISequence();
+ if(!roiSequence.gotoFirstItem().good())
+ {
+ MITK_ERROR << "Error reading the structure sequence" << std::endl;
+ RTStructureSetReader::ContourModelSetNodes x;
+ return x;
+ }
+ do{
+ DRTStructureSetROISequence::Item &currentSequence =
+ roiSequence.getCurrentItem();
+ if(!currentSequence.isValid())
+ {
+ continue;
+ }
+ OFString roiName;
+ OFString roiDescription;
+ Sint32 roiNumber;
+ RoiEntry roi;
+
+ currentSequence.getROIName(roiName);
+ currentSequence.getROIDescription(roiDescription);
+ currentSequence.getROINumber(roiNumber);
+
+ roi.Name = roiName.c_str();
+ roi.Description = roiDescription.c_str();
+ roi.Number = roiNumber;
+
+ this->ROISequenceVector.push_back(roi);
+ }
+ while(roiSequence.gotoNextItem().good());
+
+ Sint32 refRoiNumber;
+ DRTROIContourSequence &roiContourSeqObject =
+ structureSetObject.getROIContourSequence();
+ if(!roiContourSeqObject.gotoFirstItem().good())
+ {
+ MITK_ERROR << "Error reading the contour sequence" << std::endl;
+ RTStructureSetReader::ContourModelSetNodes x;
+ return x;
+ }
+ do
+ {
+ mitk::ContourModelSet::Pointer contourSet = mitk::ContourModelSet::New();
+ DRTROIContourSequence::Item &currentRoiObject =
+ roiContourSeqObject.getCurrentItem();
+ if(!currentRoiObject.isValid())
+ {
+ continue;
+ }
+ currentRoiObject.getReferencedROINumber(refRoiNumber);
+ DRTContourSequence &contourSeqObject =
+ currentRoiObject.getContourSequence();
+
+ if(contourSeqObject.gotoFirstItem().good())
+ {
+ do
+ {
+ DRTContourSequence::Item &contourItem =
+ contourSeqObject.getCurrentItem();
+ if(!contourItem.isValid())
+ {
+ continue;
+ }
+ OFString contourNumber;
+ OFString numberOfPoints;
+ OFVector<Float64> contourData_LPS;
+ mitk::ContourModel::Pointer contourSequence =
+ mitk::ContourModel::New();
+
+ contourItem.getContourNumber(contourNumber);
+ contourItem.getNumberOfContourPoints(numberOfPoints);
+ contourItem.getContourData(contourData_LPS);
+
+ for(unsigned int i=0; i<contourData_LPS.size()/3;i++)
+ {
+ mitk::Point3D point;
+ point[0] = contourData_LPS.at(3*i);
+ point[1] = contourData_LPS.at(3*i+1);
+ point[2] = contourData_LPS.at(3*i+2);
+ contourSequence->AddVertex(point);
+ }
+ contourSequence->Close();
+ contourSet->AddContourModel(contourSequence);
+ }
+ while(contourSeqObject.gotoNextItem().good());
+ }
+ else
+ {
+ MITK_ERROR << "Error reading contourSeqObject" << std::endl;
+ }
+ RoiEntry* refROI = this->FindRoiByNumber(refRoiNumber);
+ if(refROI==NULL)
+ {
+ MITK_ERROR << "Can not find references ROI" << std::endl;
+ continue;
+ }
+ Sint32 roiColor;
+ for(int j=0;j<3;j++)
+ {
+ currentRoiObject.getROIDisplayColor(roiColor, j);
+ refROI->DisplayColor[j] = roiColor/255.0;
+ }
+ refROI->ContourModelSet = contourSet;
+ contourSet->SetProperty("name", mitk::StringProperty::New(refROI->Name));
+ contourSet->SetProperty("contour.color", mitk::ColorProperty::New(
+ refROI->DisplayColor[0],
+ refROI->DisplayColor[1],
+ refROI->DisplayColor[2]));
+
+ }
+ while(roiContourSeqObject.gotoNextItem().good());
+
+ std::deque<mitk::DataNode::Pointer> nodes;
+
+ for(unsigned int i=0; i<ROISequenceVector.size();i++)
+ {
+ mitk::DataNode::Pointer node = mitk::DataNode::New();
+ node->SetData(ROISequenceVector.at(i).ContourModelSet);
+ node->SetProperty("name",
+ ROISequenceVector.at(i).ContourModelSet->GetProperty("name"));
+ node->SetProperty("color",
+ ROISequenceVector.at(i).ContourModelSet->GetProperty("contour.color"));
+ node->SetProperty("contour.color",
+ ROISequenceVector.at(i).ContourModelSet->GetProperty("contour.color"));
+
+ /*The StructureSets should only be visible in the axial-view and the
+ 3D-view because in the other views they are just points and lines*/
+ node->SetVisibility(true, mitk::BaseRenderer::GetInstance
+ ( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")));
+ node->SetVisibility(false, mitk::BaseRenderer::GetInstance
+ ( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")));
+ node->SetVisibility(false, mitk::BaseRenderer::GetInstance
+ ( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
+ node->SetVisibility(true, mitk::BaseRenderer::GetInstance
+ ( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4")));
+ nodes.push_back(node);
+ }
+
+ return nodes;
+ }
+}
diff --git a/Modules/DicomRT/mitkRTStructureSetReader.h b/Modules/DicomRT/mitkRTStructureSetReader.h
new file mode 100644
index 0000000000..9741553474
--- /dev/null
+++ b/Modules/DicomRT/mitkRTStructureSetReader.h
@@ -0,0 +1,93 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef MITKRTSTRUCTURESETREADER_H
+#define MITKRTSTRUCTURESETREADER_H
+
+#include <itkObject.h>
+#include <itkObjectFactory.h>
+
+#include <MitkDicomRTExports.h>
+#include <mitkContourModelSet.h>
+#include <mitkProperties.h>
+
+#include "dcmtk/dcmrt/drtstrct.h"
+
+#include <mitkDataNode.h>
+
+namespace mitk
+{
+ class MitkDicomRT_EXPORT RTStructureSetReader: public itk::Object
+ {
+ typedef std::deque<mitk::DataNode::Pointer> ContourModelSetNodes;
+
+ /**
+ * Represent a region of interest (ROI)
+ */
+ class RoiEntry
+ {
+ public:
+ RoiEntry();
+ RoiEntry( const RoiEntry& src);
+ virtual ~RoiEntry();
+ RoiEntry &operator=(const RoiEntry &src);
+
+ void SetPolyData(ContourModelSet::Pointer roiPolyData);
+
+ unsigned int Number;
+ std::string Name;
+ std::string Description;
+ double DisplayColor[3];
+ mitk::ContourModelSet::Pointer ContourModelSet;
+ };
+
+ public:
+ mitkClassMacro( RTStructureSetReader, itk::Object )
+ itkNewMacro( Self )
+
+ /**
+ * @brief Reading a RT StructureSet from the DICOM file and returns the ROIs
+ * (region of interest) as a ContourModelSet. One ContourModelSet represent
+ * one ROI. A ContourModelSet contains ContourModels which represent the
+ * single structures.
+ * @param filepath to the RT StructureSet (.dmc) file
+ * @return Returns a std::deque filled with ContourModelSet::Pointer the
+ * deque contains all ROIs from the DICOM file
+ */
+ ContourModelSetNodes ReadStructureSet(const char* filepath);
+
+ protected:
+ /**
+ * containing the ROIs meta information like name number and description
+ */
+ std::vector<RoiEntry> ROISequenceVector;
+
+ RTStructureSetReader();
+ virtual ~RTStructureSetReader();
+
+ /**
+ * Returns the number of ROIs from the ROISequenceVector
+ */
+ size_t GetNumberOfROIs();
+
+ /**
+ * Returns the relevant ROI from the ROISequenceVector by its number
+ */
+ RoiEntry* FindRoiByNumber(unsigned int roiNum);
+ };
+}
+
+#endif // MITKRTSTRUCTURESETREADER_H
diff --git a/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkThresholder.cpp b/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkThresholder.cpp
index 30220d9f90..0090e9cd5c 100644
--- a/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkThresholder.cpp
+++ b/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkThresholder.cpp
@@ -1,249 +1,251 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkConnectomicsNetworkThresholder.h"
#include <mitkConnectomicsStatisticsCalculator.h>
#include "vnl/vnl_random.h"
mitk::ConnectomicsNetworkThresholder::ConnectomicsNetworkThresholder()
: m_Network( 0 )
, m_ThresholdingScheme( mitk::ConnectomicsNetworkThresholder::ThresholdBased )
, m_TargetThreshold( 0.0 )
, m_TargetDensity( 1.0 )
{
}
mitk::ConnectomicsNetworkThresholder::~ConnectomicsNetworkThresholder()
{
}
mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::GetThresholdedNetwork()
{
mitk::ConnectomicsNetwork::Pointer result;
if( ! CheckValidity() )
{
MITK_ERROR << "Aborting";
return m_Network;
}
switch(m_ThresholdingScheme)
{
case RandomRemovalOfWeakest :
{
result = ThresholdByRandomRemoval( m_Network, m_TargetDensity );
break;
}
case LargestLowerThanDensity :
{
result = ThresholdBelowDensity( m_Network, m_TargetDensity );
break;
}
case ThresholdBased :
{
result = Threshold( m_Network, m_TargetThreshold );
break;
}
default :
{
MITK_ERROR << "Specified unknown Thresholding Scheme";
result = m_Network;
}
}
return result;
}
bool mitk::ConnectomicsNetworkThresholder::CheckValidity()
{
bool valid(true);
if( m_Network.IsNull() )
{
valid = false;
MITK_ERROR << "Network is NULL.";
}
switch(m_ThresholdingScheme)
{
case RandomRemovalOfWeakest :
case LargestLowerThanDensity :
{
if( m_TargetDensity < 0.0 )
{
valid = false;
MITK_ERROR << "Target density is negative.";
}
if( m_TargetDensity > 1.0 )
{
valid = false;
MITK_ERROR << "Target density is larger than 1.";
}
break;
}
case ThresholdBased :
{
if( m_TargetThreshold < 0 )
{
valid = false;
MITK_ERROR << "Target threshold is negative.";
}
break;
}
default :
{
valid = false;
MITK_ERROR << "Specified unknown Thresholding Scheme";
}
}
return valid;
}
mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::ThresholdByRandomRemoval( mitk::ConnectomicsNetwork::Pointer input, double targetDensity )
{
mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
result->ImportNetwort( input );
mitk::ConnectomicsStatisticsCalculator::Pointer calculator = mitk::ConnectomicsStatisticsCalculator::New();
calculator->SetNetwork( result );
calculator->Update();
//the random number generator
vnl_random rng( (unsigned int) rand() );
bool notBelow( targetDensity < calculator->GetConnectionDensity() );
double minWeight( result->GetMaximumWeight() );
int count( 0 );
while( notBelow )
{
// result = Threshold( result, loop );
std::vector< EdgeDescriptorType > candidateVector;
+ minWeight = result->GetMaximumWeight();
+ count = 0;
// determine minimum weight and number of edges having that weight
NetworkType* boostGraph = result->GetBoostGraph();
EdgeIteratorType iterator, end;
// sets iterator to start end end to end
boost::tie(iterator, end) = boost::edges( *boostGraph );
for ( ; iterator != end; ++iterator)
{
double tempWeight;
// the value of an iterator is a descriptor
tempWeight = (*boostGraph)[ *iterator ].weight;
if( mitk::Equal( tempWeight, minWeight ) )
{
candidateVector.push_back( *iterator );
count++;
}
else if( tempWeight < minWeight )
{
candidateVector.clear();
candidateVector.push_back( *iterator );
minWeight = tempWeight;
count = 1;
}
}
// Which to delete
int deleteNumber( rng.lrand32( count - 1 ) );
boost::remove_edge( candidateVector.at( deleteNumber ), *boostGraph );
calculator->SetNetwork( result );
calculator->Update();
notBelow = targetDensity < calculator->GetConnectionDensity();
}
result->UpdateIDs();
return result;
}
mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::ThresholdBelowDensity( mitk::ConnectomicsNetwork::Pointer input, double targetDensity )
{
mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
result->ImportNetwort( input );
mitk::ConnectomicsStatisticsCalculator::Pointer calculator = mitk::ConnectomicsStatisticsCalculator::New();
calculator->SetNetwork( result );
calculator->Update();
bool notBelow( targetDensity < calculator->GetConnectionDensity() );
for( int loop( 1 ); notBelow; loop++ )
{
result = Threshold( result, loop );
calculator->SetNetwork( result );
calculator->Update();
notBelow = targetDensity < calculator->GetConnectionDensity();
}
return result;
}
mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::Threshold( mitk::ConnectomicsNetwork::Pointer input, double targetThreshold )
{
mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
result->ImportNetwort( input );
NetworkType* boostGraph = result->GetBoostGraph();
EdgeIteratorType iterator, end;
// set to true if iterators are invalidated by deleting an edge
bool edgeHasBeenRemoved( true );
// if no edge has been removed in the last loop, we are done
while( edgeHasBeenRemoved )
{
edgeHasBeenRemoved = false;
// sets iterator to start and end to end
boost::tie(iterator, end) = boost::edges( *boostGraph );
bool endReached( false );
while( !edgeHasBeenRemoved && !endReached )
{
if( iterator != end )
{
// If the edge is below the target threshold it is deleted
if( (*boostGraph)[ *iterator ].weight < targetThreshold )
{
edgeHasBeenRemoved = true;
// this invalidates all iterators
boost::remove_edge( *iterator, *boostGraph );
}
else
{
++iterator;
}
}
else
{
endReached = true;
}
}
}
result->UpdateIDs();
return result;
}
diff --git a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp
index 550ecdd3c7..58bc9b97f5 100644
--- a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp
+++ b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp
@@ -1,112 +1,119 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Testing
#include "mitkTestingMacros.h"
#include "mitkTestFixture.h"
// std includes
#include <string>
// MITK includes
#include <mitkBaseDataIOFactory.h>
#include "mitkConnectomicsNetworkCreator.h"
#include <mitkCoreObjectFactory.h>
+// VTK includes
+#include <vtkDebugLeaks.h>
+
class mitkConnectomicsNetworkCreationTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkConnectomicsNetworkCreationTestSuite);
+
+ /// \todo Fix VTK memory leaks. Bug 18097.
+ vtkDebugLeaks::SetExitError(0);
+
MITK_TEST(CreateNetworkFromFibersAndParcellation);
CPPUNIT_TEST_SUITE_END();
private:
std::string m_ParcellationPath;
std::string m_FiberPath;
std::string m_ReferenceNetworkPath;
public:
/**
* @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called).
*/
void setUp()
{
m_ReferenceNetworkPath = GetTestDataFilePath("DiffusionImaging/Connectomics/reference.cnf");
m_ParcellationPath = GetTestDataFilePath("DiffusionImaging/Connectomics/parcellation.nrrd");
m_FiberPath = GetTestDataFilePath("DiffusionImaging/Connectomics/fiberBundle.fib");
}
void tearDown()
{
m_ReferenceNetworkPath = "";
m_ParcellationPath = "";
m_FiberPath = "";
}
void CreateNetworkFromFibersAndParcellation()
{
const std::string s1="", s2="";
// load fiber image
std::vector<mitk::BaseData::Pointer> fiberInfile =
mitk::BaseDataIO::LoadBaseDataFromFile( m_FiberPath, s1, s2, false );
if( fiberInfile.empty() )
{
std::string errorMessage = "Fiber Image at " + m_FiberPath + " could not be read. Aborting.";
CPPUNIT_ASSERT_MESSAGE( errorMessage, false );
}
mitk::BaseData* fiberBaseData = fiberInfile.at(0);
mitk::FiberBundleX* fiberBundle = dynamic_cast<mitk::FiberBundleX*>( fiberBaseData );
// load parcellation
std::vector<mitk::BaseData::Pointer> parcellationInFile =
mitk::BaseDataIO::LoadBaseDataFromFile( m_ParcellationPath, s1, s2, false );
if( parcellationInFile.empty() )
{
std::string errorMessage = "Parcellation at " + m_ParcellationPath + " could not be read. Aborting.";
CPPUNIT_ASSERT_MESSAGE( errorMessage, false );
}
mitk::BaseData* parcellationBaseData = parcellationInFile.at(0);
mitk::Image* parcellationImage = dynamic_cast<mitk::Image*>( parcellationBaseData );
// do creation
mitk::ConnectomicsNetworkCreator::Pointer connectomicsNetworkCreator = mitk::ConnectomicsNetworkCreator::New();
connectomicsNetworkCreator->SetSegmentation( parcellationImage );
connectomicsNetworkCreator->SetFiberBundle( fiberBundle );
connectomicsNetworkCreator->CalculateCenterOfMass();
connectomicsNetworkCreator->SetEndPointSearchRadius( 15 );
connectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation();
// load network
std::vector<mitk::BaseData::Pointer> referenceFile =
mitk::BaseDataIO::LoadBaseDataFromFile( m_ReferenceNetworkPath, s1, s2, false );
if( referenceFile.empty() )
{
std::string errorMessage = "Reference Network at " + m_ReferenceNetworkPath + " could not be read. Aborting.";
CPPUNIT_ASSERT_MESSAGE( errorMessage, false );
}
mitk::BaseData* referenceBaseData = referenceFile.at(0);
mitk::ConnectomicsNetwork* referenceNetwork = dynamic_cast<mitk::ConnectomicsNetwork*>( referenceBaseData );
mitk::ConnectomicsNetwork::Pointer network = connectomicsNetworkCreator->GetNetwork();
CPPUNIT_ASSERT_MESSAGE( "Comparing created and reference network.", mitk::Equal( network.GetPointer(), referenceNetwork, mitk::eps, true) );
}
};
MITK_TEST_SUITE_REGISTRATION(mitkConnectomicsNetworkCreation)
diff --git a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp
index 1c66f05ea5..9d6b132968 100644
--- a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp
+++ b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp
@@ -1,525 +1,531 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTestingMacros.h"
#include "mitkConnectomicsNetwork.h"
#include "mitkConnectomicsSyntheticNetworkGenerator.h"
#include "mitkConnectomicsSimulatedAnnealingManager.h"
#include "mitkConnectomicsSimulatedAnnealingPermutationModularity.h"
#include "mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h"
+
+#include <vtkDebugLeaks.h>
+
#include <vector>
#include <string>
#include <utility>
/**Documentation
* Test for synthetic connectomics generation and connectomics network functionality
*/
int mitkConnectomicsNetworkTest(int argc, char* argv[])
{
// Test begins
MITK_TEST_BEGIN("mitkConnectomicsNetworkTest");
+ /// \todo Fix VTK memory leaks. Bug 18097.
+ vtkDebugLeaks::SetExitError(0);
+
// Typedefs
typedef mitk::ConnectomicsNetwork::VertexDescriptorType VertexType;
typedef mitk::ConnectomicsNetwork::EdgeDescriptorType EdgeType;
typedef mitk::ConnectomicsNetwork::NetworkNode NodeType;
// The test network
std::vector< NodeType > inNodes;
NodeType node;
node.id = 0;
node.label = "1-1";
node.coordinates.clear();
node.coordinates.push_back( 0 );
node.coordinates.push_back( 0 );
node.coordinates.push_back( 0 );
inNodes.push_back(node);
node.id = 1;
node.label = "2-1";
node.coordinates.clear();
node.coordinates.push_back( 10 );
node.coordinates.push_back( 0 );
node.coordinates.push_back( 0 );
inNodes.push_back(node);
node.id = 2;
node.label = "3-1";
node.coordinates.clear();
node.coordinates.push_back( 20 );
node.coordinates.push_back( 10 );
node.coordinates.push_back( 0 );
inNodes.push_back(node);
node.id = 3;
node.label = "4-1";
node.coordinates.clear();
node.coordinates.push_back( 30 );
node.coordinates.push_back( 20 );
node.coordinates.push_back( 0 );
inNodes.push_back(node);
node.id = 4;
node.label = "5-1";
node.coordinates.clear();
node.coordinates.push_back( 40 );
node.coordinates.push_back( 50 );
node.coordinates.push_back( 0 );
inNodes.push_back(node);
node.id = 5;
node.label = "6-2";
node.coordinates.clear();
node.coordinates.push_back( 0 );
node.coordinates.push_back( 0 );
node.coordinates.push_back( 10 );
inNodes.push_back(node);
node.id = 6;
node.label = "7-2";
node.coordinates.clear();
node.coordinates.push_back( 0 );
node.coordinates.push_back( 10 );
node.coordinates.push_back( 20 );
inNodes.push_back(node);
node.id = 7;
node.label = "8-2";
node.coordinates.clear();
node.coordinates.push_back( 0 );
node.coordinates.push_back( 20 );
node.coordinates.push_back( 30 );
inNodes.push_back(node);
node.id = 8;
node.label = "9-2";
node.coordinates.clear();
node.coordinates.push_back( 0 );
node.coordinates.push_back( 30 );
node.coordinates.push_back( 40 );
inNodes.push_back(node);
node.id = 9;
node.label = "10-3";
node.coordinates.clear();
node.coordinates.push_back( 20 );
node.coordinates.push_back( 0 );
node.coordinates.push_back( 10 );
inNodes.push_back(node);
node.id = 10;
node.label = "11-3";
node.coordinates.clear();
node.coordinates.push_back( 30 );
node.coordinates.push_back( 0 );
node.coordinates.push_back( 20 );
inNodes.push_back(node);
node.id = 11;
node.label = "12-3";
node.coordinates.clear();
node.coordinates.push_back( 40 );
node.coordinates.push_back( 0 );
node.coordinates.push_back( 30 );
inNodes.push_back(node);
std::vector< mitk::ConnectomicsNetwork::NetworkEdge > inEdges;
mitk::ConnectomicsNetwork::NetworkEdge edge;
edge.sourceId = 0;
edge.targetId = 1;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 0;
edge.targetId = 2;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 0;
edge.targetId = 4;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 1;
edge.targetId = 4;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 1;
edge.targetId = 3;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 2;
edge.targetId = 3;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 3;
edge.targetId = 4;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 4;
edge.targetId = 5;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 5;
edge.targetId = 6;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 5;
edge.targetId = 7;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 5;
edge.targetId = 8;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 7;
edge.targetId = 8;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 6;
edge.targetId = 8;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 6;
edge.targetId = 9;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 3;
edge.targetId = 10;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 9;
edge.targetId = 10;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 10;
edge.targetId = 11;
edge.weight = 2;
inEdges.push_back( edge );
edge.sourceId = 9;
edge.targetId = 11;
edge.weight = 2;
inEdges.push_back( edge );
// further variables
double eps(0.001);
try
{
// Testing synthetic network generation
mitk::ConnectomicsSyntheticNetworkGenerator::Pointer generator = mitk::ConnectomicsSyntheticNetworkGenerator::New();
MITK_TEST_CONDITION_REQUIRED(generator.IsNotNull(),"Synthetic network generator has been instantiated")
// first and second parameter
std::vector< std::pair<int, double> > parameterVector;
// name and isRandom
std::vector< std::pair<std::string, bool> > messageVector;
// order of results is # vertices, # edges, # self loops, average degree, connection density
// global clustering coefficient
std::vector< std::vector< double > > resultVector;
int numberOfOptions = 3;
parameterVector.resize(numberOfOptions);
messageVector.resize(numberOfOptions);
resultVector.resize(numberOfOptions);
// Create regular lattice network in the form of a cube with sidelength 5 and distance 10 between nodes
parameterVector[0] = std::pair< int, double>(5, 10);
messageVector[0] = std::pair<std::string, bool>("Regular Lattice Network", false);
resultVector[0].push_back( 5 * 5 * 5 );
resultVector[0].push_back( 300 );
resultVector[0].push_back( 0 );
resultVector[0].push_back( 4.8 );
resultVector[0].push_back(0.0387);
resultVector[0].push_back(0);
// Create a heterogeneous sphere network with 1 central node and 49 nodes on the surface and radius 10
parameterVector[1] = std::pair< int, double>(50, 10);
messageVector[1] = std::pair<std::string, bool>("Heterogeneous Sphere Network", false);
resultVector[1].push_back( 50 );
resultVector[1].push_back( 49 );
resultVector[1].push_back( 0 );
resultVector[1].push_back( 1.96 );
resultVector[1].push_back(0.0400);
resultVector[1].push_back(0);
// Create random network with 50 nodes and edges between them generated with a 0.1 likelihood
parameterVector[2] = std::pair< int, double>(50, 0.1);
messageVector[2] = std::pair<std::string, bool>("Random Network", true);
resultVector[2].push_back( 50 );
for(int loop(0); loop < numberOfOptions; loop++)
{
mitk::ConnectomicsNetwork::Pointer network =
generator->CreateSyntheticNetwork(loop, parameterVector[loop].first, parameterVector[loop].second);
bool generationWorked = generator->WasGenerationSuccessfull() && network.IsNotNull();
std::string message = messageVector[loop].first + " has been instantiated";
MITK_TEST_CONDITION_REQUIRED(generationWorked,message)
bool verticesCloseEnough( std::abs(resultVector[loop][0] - network->GetNumberOfVertices()) < eps);
MITK_TEST_CONDITION_REQUIRED( verticesCloseEnough, "Expected number of vertices")
if(!messageVector[loop].second)
{
bool edgesCloseEnough( std::abs(resultVector[loop][1] - network->GetNumberOfEdges()) < eps);
MITK_TEST_CONDITION_REQUIRED( edgesCloseEnough, "Expected number of edges")
bool selfLoopsCloseEnough( std::abs(resultVector[loop][2] - network->GetNumberOfSelfLoops()) < eps);
MITK_TEST_CONDITION_REQUIRED( selfLoopsCloseEnough, "Expected number of self loops")
bool avDegCloseEnough( std::abs(resultVector[loop][3] - network->GetAverageDegree()) < eps);
MITK_TEST_CONDITION_REQUIRED( avDegCloseEnough, "Expected average degree")
bool conDensCloseEnough( std::abs(resultVector[loop][4] - network->GetConnectionDensity()) < eps);
MITK_TEST_CONDITION_REQUIRED( conDensCloseEnough, "Expected connection density")
bool clustCoeffCloseEnough( std::abs(resultVector[loop][5] - network->GetGlobalClusteringCoefficient()) < eps);
MITK_TEST_CONDITION_REQUIRED( clustCoeffCloseEnough, "Expected global clustering coefficient")
}
}
}
catch (...)
{
MITK_ERROR << "Unhandled exception caught while testing synthetic network generation [FAILED]" ;
return EXIT_FAILURE;
}
try
{
// Testing network interface
// Create network
mitk::ConnectomicsNetwork::Pointer network = mitk::ConnectomicsNetwork::New();
std::vector< VertexType > vertexVector;
vertexVector.resize( inNodes.size() );
for(unsigned int loop(0); loop < inNodes.size(); loop++)
{
VertexType newVertex = network->AddVertex( inNodes[loop].id );
vertexVector[ inNodes[loop].id ] = newVertex;
network->SetLabel( newVertex, inNodes[loop].label );
network->SetCoordinates( newVertex, inNodes[loop].coordinates );
}
for(unsigned int loop(0); loop < inEdges.size(); loop++)
{
int sourceId = inEdges[loop].sourceId;
int targetId = inEdges[loop].targetId;
VertexType sourceVertex = vertexVector[ sourceId ];
VertexType targetVertex = vertexVector[ targetId ];
// there are two methods to add nodes
if( loop % 2 == 0 )
{
network->AddEdge(sourceVertex, targetVertex);
for( int remaining( inEdges[loop].weight ); remaining > 1; remaining-- )
{
network->IncreaseEdgeWeight( sourceVertex, targetVertex );
}
}
else
{
network->AddEdge(sourceVertex, targetVertex, sourceId, targetId, inEdges[loop].weight );
}
}
// Test whether network parameters are as expected
MITK_TEST_CONDITION_REQUIRED( inNodes.size() == (unsigned int)network->GetNumberOfVertices(), "Expected number of vertices")
MITK_TEST_CONDITION_REQUIRED( inEdges.size() == (unsigned int)network->GetNumberOfEdges(), "Expected number of edges")
MITK_TEST_CONDITION_REQUIRED( 0 == network->GetNumberOfSelfLoops(), "Expected number of self loops")
bool avDegCloseEnough( std::abs(3 - network->GetAverageDegree()) < eps);
MITK_TEST_CONDITION_REQUIRED( avDegCloseEnough, "Expected average degree")
bool conDensCloseEnough( std::abs(0.2727 - network->GetConnectionDensity()) < eps);
MITK_TEST_CONDITION_REQUIRED( conDensCloseEnough, "Expected connection density")
bool clustCoeffCloseEnough( std::abs(0.4583 - network->GetGlobalClusteringCoefficient()) < eps);
MITK_TEST_CONDITION_REQUIRED( clustCoeffCloseEnough, "Expected global clustering coefficient")
MITK_TEST_CONDITION_REQUIRED( network->GetMaximumWeight() == 2, "Expected maximum weight")
MITK_TEST_CONDITION_REQUIRED( network->GetVectorOfAllVertexDescriptors().size() == vertexVector.size(), "Expected number of vertex descriptors")
}
catch (...)
{
MITK_ERROR << "Unhandled exception caught while testing network interface [FAILED]" ;
return EXIT_FAILURE;
}
try
{
// Testing modularity calculation
typedef std::map< VertexType, int > ToModuleMapType;
// Create network
mitk::ConnectomicsNetwork::Pointer network = mitk::ConnectomicsNetwork::New();
std::vector< VertexType > vertexVector;
vertexVector.resize( inNodes.size() );
for(unsigned int loop(0); loop < inNodes.size(); loop++)
{
VertexType newVertex = network->AddVertex( inNodes[loop].id );
vertexVector[ inNodes[loop].id ] = newVertex;
network->SetLabel( newVertex, inNodes[loop].label );
network->SetCoordinates( newVertex, inNodes[loop].coordinates );
}
for(unsigned int loop(0); loop < inEdges.size(); loop++)
{
int sourceId = inEdges[loop].sourceId;
int targetId = inEdges[loop].targetId;
VertexType sourceVertex = vertexVector[ sourceId ];
VertexType targetVertex = vertexVector[ targetId ];
// there are two methods to add nodes
if( loop % 2 == 0 )
{
network->AddEdge(sourceVertex, targetVertex);
for( int remaining( inEdges[loop].weight ); remaining > 1; remaining-- )
{
network->IncreaseEdgeWeight( sourceVertex, targetVertex );
}
}
else
{
network->AddEdge(sourceVertex, targetVertex, sourceId, targetId, inEdges[loop].weight );
}
}
// Simulated annealing classes
mitk::ConnectomicsSimulatedAnnealingManager::Pointer manager = mitk::ConnectomicsSimulatedAnnealingManager::New();
mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Pointer permutation = mitk::ConnectomicsSimulatedAnnealingPermutationModularity::New();
mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::Pointer costFunction = mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::New();
// Test whether modularity calculation behaves as expected
ToModuleMapType threeModuleSolution;
std::vector< VertexType > vertexInVector = network->GetVectorOfAllVertexDescriptors();
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 0 ], 0 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 1 ], 0 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 2 ], 0 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 3 ], 0 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 4 ], 0 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 5 ], 1 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 6 ], 1 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 7 ], 1 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 8 ], 1 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 9 ], 2 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 10 ], 2 ) );
threeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 11 ], 2 ) );
bool threeModuleModularity( std::abs(0.4753 - costFunction->CalculateModularity( network, &threeModuleSolution )) < eps);
MITK_TEST_CONDITION_REQUIRED( threeModuleModularity, "Expected three module modularity")
bool correctNumberOfModules( permutation->getNumberOfModules( &threeModuleSolution ) == 3 );
MITK_TEST_CONDITION_REQUIRED( correctNumberOfModules, "Expected number of modules")
bool correctNumberOfVertices( permutation->getNumberOfVerticesInModule( &threeModuleSolution, 0 ) == 5
&& permutation->getNumberOfVerticesInModule( &threeModuleSolution, 1 ) == 4
&& permutation->getNumberOfVerticesInModule( &threeModuleSolution, 2 ) == 3 );
MITK_TEST_CONDITION_REQUIRED( correctNumberOfVertices, "Expected number of vertices per module")
ToModuleMapType oneModuleSolution;
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 0 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 1 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 2 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 3 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 4 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 5 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 6 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 7 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 8 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 9 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 10 ], 0 ) );
oneModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 11 ], 0 ) );
bool oneModuleModularity( std::abs(0.0 - costFunction->CalculateModularity( network, &oneModuleSolution )) < eps);
MITK_TEST_CONDITION_REQUIRED( oneModuleModularity, "Expected one module modularity")
ToModuleMapType badTwoModuleSolution;
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 0 ], 0 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 1 ], 0 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 2 ], 0 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 3 ], 0 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 4 ], 0 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 5 ], 1 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 6 ], 1 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 7 ], 1 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 8 ], 0 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 9 ], 1 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 10 ], 1 ) );
badTwoModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 11 ], 0 ) );
bool badTwoModuleModularity( std::abs(0.097222 - costFunction->CalculateModularity( network, &badTwoModuleSolution )) < eps);
MITK_TEST_CONDITION_REQUIRED( badTwoModuleModularity, "Expected bad two module modularity")
ToModuleMapType noInternalLinksThreeModuleSolution;
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 0 ], 0 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 1 ], 2 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 2 ], 1 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 3 ], 0 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 4 ], 1 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 5 ], 2 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 6 ], 0 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 7 ], 0 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 8 ], 1 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 9 ], 2 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 10 ], 1 ) );
noInternalLinksThreeModuleSolution.insert( std::pair<VertexType, int>( vertexInVector[ 11 ], 0 ) );
bool noInternalThreeModuleModularity( std::abs(-0.3395 - costFunction->CalculateModularity( network, &noInternalLinksThreeModuleSolution )) < eps);
MITK_TEST_CONDITION_REQUIRED( noInternalThreeModuleModularity, "Expected three module modularity containing no internal links")
}
catch (...)
{
MITK_ERROR << "Unhandled exception caught while testing modularity calculation [FAILED]" ;
return EXIT_FAILURE;
}
// Test ends
MITK_TEST_END();
}
diff --git a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp
index 37186f892c..102c26eeb1 100644
--- a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp
+++ b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp
@@ -1,137 +1,143 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Testing
#include "mitkTestingMacros.h"
#include "mitkTestFixture.h"
// std includes
#include <string>
#include <sstream>
// MITK includes
#include <mitkBaseDataIOFactory.h>
#include <mitkConnectomicsStatisticsCalculator.h>
+// VTK includes
+#include <vtkDebugLeaks.h>
class mitkConnectomicsStatisticsCalculatorTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkConnectomicsStatisticsCalculatorTestSuite);
+
+ /// \todo Fix VTK memory leaks. Bug 18097.
+ vtkDebugLeaks::SetExitError(0);
+
MITK_TEST(StatisticsCalculatorUpdate);
CPPUNIT_TEST_SUITE_END();
private:
mitk::ConnectomicsNetwork::Pointer m_Network;
std::string m_NetworkPath;
public:
/**
* @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called).
*/
void setUp()
{
//load network
m_NetworkPath = GetTestDataFilePath("DiffusionImaging/Connectomics/reference.cnf");
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> networkFile =
mitk::BaseDataIO::LoadBaseDataFromFile( m_NetworkPath, s1, s2, false );
if( networkFile.empty() )
{
std::string errorMessage = "File at " + m_NetworkPath + " could not be read. Aborting.";
CPPUNIT_ASSERT_MESSAGE( errorMessage, !networkFile.empty() );
return;
}
mitk::BaseData* networkBaseData = networkFile.at(0);
mitk::ConnectomicsNetwork* network = dynamic_cast<mitk::ConnectomicsNetwork*>( networkBaseData );
if( !network )
{
std::string errorMessage = "Read file at " + m_NetworkPath + " could not be recognized as network. Aborting.";
CPPUNIT_ASSERT_MESSAGE( errorMessage, network);
return;
}
m_Network = network;
}
void tearDown()
{
m_Network = NULL;
m_NetworkPath = "";
}
void StatisticsCalculatorUpdate()
{
mitk::ConnectomicsStatisticsCalculator::Pointer statisticsCalculator = mitk::ConnectomicsStatisticsCalculator::New();
statisticsCalculator->SetNetwork( m_Network );
statisticsCalculator->Update();
double eps( 0.0001 );
CPPUNIT_ASSERT_MESSAGE( "GetNumberOfVertices", mitk::Equal( statisticsCalculator->GetNumberOfVertices( ), 4 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetNumberOfEdges" , mitk::Equal( statisticsCalculator->GetNumberOfEdges( ), 5 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageDegree", mitk::Equal( statisticsCalculator->GetAverageDegree( ), 2.5 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetConnectionDensity", mitk::Equal( statisticsCalculator->GetConnectionDensity( ), 0.833333 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetNumberOfConnectedComponents", mitk::Equal( statisticsCalculator->GetNumberOfConnectedComponents( ), 1 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageComponentSize", mitk::Equal( statisticsCalculator->GetAverageComponentSize( ), 4 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetLargestComponentSize", mitk::Equal( statisticsCalculator->GetLargestComponentSize( ), 4 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetRatioOfNodesInLargestComponent", mitk::Equal( statisticsCalculator->GetRatioOfNodesInLargestComponent( ), 1 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetHopPlotExponent", mitk::Equal( statisticsCalculator->GetHopPlotExponent( ), 0.192645 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetEffectiveHopDiameter", mitk::Equal( statisticsCalculator->GetEffectiveHopDiameter( ), 1 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageClusteringCoefficientsC", mitk::Equal( statisticsCalculator->GetAverageClusteringCoefficientsC( ), 0.833333 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageClusteringCoefficientsD", mitk::Equal( statisticsCalculator->GetAverageClusteringCoefficientsD( ), 0.916667 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageClusteringCoefficientsE", mitk::Equal( statisticsCalculator->GetAverageClusteringCoefficientsE( ), 0.833333 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageVertexBetweennessCentrality", mitk::Equal( statisticsCalculator->GetAverageVertexBetweennessCentrality( ), 0.25 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageEdgeBetweennessCentrality", mitk::Equal( statisticsCalculator->GetAverageEdgeBetweennessCentrality( ), 1.4 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetNumberOfIsolatedPoints" , mitk::Equal( statisticsCalculator->GetNumberOfIsolatedPoints( ), 0 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetRatioOfIsolatedPoints", mitk::Equal( statisticsCalculator->GetRatioOfIsolatedPoints( ), 0 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetNumberOfEndPoints", mitk::Equal( statisticsCalculator->GetNumberOfEndPoints( ), 0 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetRatioOfEndPoints", mitk::Equal( statisticsCalculator->GetRatioOfEndPoints( ), 0 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetDiameter", mitk::Equal( statisticsCalculator->GetDiameter( ), 2 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetDiameter90", mitk::Equal( statisticsCalculator->GetDiameter90( ), 2 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetRadius" , mitk::Equal( statisticsCalculator->GetRadius( ), 1 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetRadius90", mitk::Equal( statisticsCalculator->GetRadius90( ), 1 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageEccentricity", mitk::Equal( statisticsCalculator->GetAverageEccentricity( ), 1.5 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAverageEccentricity90", mitk::Equal( statisticsCalculator->GetAverageEccentricity90( ), 1.5 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetAveragePathLength" , mitk::Equal( statisticsCalculator->GetAveragePathLength( ), 1.16667 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetNumberOfCentralPoints" , mitk::Equal( statisticsCalculator->GetNumberOfCentralPoints( ), 2 , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetRatioOfCentralPoints", mitk::Equal( statisticsCalculator->GetRatioOfCentralPoints( ), 0.5 , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetSpectralRadius( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetSecondLargestEigenValue( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetAdjacencyTrace( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetAdjacencyEnergy( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetLaplacianTrace( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetLaplacianEnergy( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetLaplacianSpectralGap( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianTrace( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianEnergy( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianNumberOf2s( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianNumberOf1s( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianNumberOf0s( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianLowerSlope( ), , eps, true ) );
// CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianUpperSlope( ), , eps, true ) );
CPPUNIT_ASSERT_MESSAGE( "GetSmallWorldness", mitk::Equal( statisticsCalculator->GetSmallWorldness( ), 1.72908 , eps, true ) );
}
};
MITK_TEST_SUITE_REGISTRATION(mitkConnectomicsStatisticsCalculator)
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkAddArtifactsToDwiImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkAddArtifactsToDwiImageFilter.cpp
index a8c4330d70..7a58a8a5be 100644
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkAddArtifactsToDwiImageFilter.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkAddArtifactsToDwiImageFilter.cpp
@@ -1,336 +1,336 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef __itkAddArtifactsToDwiImageFilter_txx
#define __itkAddArtifactsToDwiImageFilter_txx
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "itkAddArtifactsToDwiImageFilter.h"
#include <itkImageRegionConstIterator.h>
#include <itkImageRegionConstIteratorWithIndex.h>
#include <itkImageRegionIterator.h>
#include <boost/progress.hpp>
#include <itkImageDuplicator.h>
#include <itkResampleDwiImageFilter.h>
#include <itkCropImageFilter.h>
#define _USE_MATH_DEFINES
#include <math.h>
namespace itk {
template< class TPixelType >
AddArtifactsToDwiImageFilter< TPixelType >
::AddArtifactsToDwiImageFilter()
: m_UseConstantRandSeed(false)
{
this->SetNumberOfRequiredInputs( 1 );
m_RandGen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
m_RandGen->SetSeed();
}
template< class TPixelType >
void AddArtifactsToDwiImageFilter< TPixelType >
::GenerateData()
{
if (m_UseConstantRandSeed) // always generate the same random numbers?
m_RandGen->SetSeed(0);
else
m_RandGen->SetSeed();
m_StartTime = clock();
m_StatusText = "Starting simulation\n";
typename InputImageType::Pointer inputImage = static_cast< InputImageType* >( this->ProcessObject::GetInput(0) );
itk::ImageRegion<3> inputRegion = inputImage->GetLargestPossibleRegion();
typename itk::ImageDuplicator<InputImageType>::Pointer duplicator = itk::ImageDuplicator<InputImageType>::New();
duplicator->SetInputImage( inputImage );
duplicator->Update();
typename InputImageType::Pointer outputImage = duplicator->GetOutput();
// is input slize size even?
int xMax=inputRegion.GetSize(0); int yMax=inputRegion.GetSize(1);
if ( xMax%2 == 1 )
xMax += 1;
if ( yMax%2 == 1 )
yMax += 1;
// create slice object
typename SliceType::Pointer slice = SliceType::New();
ImageRegion<2> sliceRegion;
sliceRegion.SetSize(0, xMax);
sliceRegion.SetSize(1, yMax);
slice->SetLargestPossibleRegion( sliceRegion );
slice->SetBufferedRegion( sliceRegion );
slice->SetRequestedRegion( sliceRegion );
slice->Allocate();
slice->FillBuffer(0.0);
ImageRegion<2> upsampledSliceRegion;
- if (m_Parameters.m_DoAddGibbsRinging)
+ if ( m_Parameters.m_SignalGen.m_DoAddGibbsRinging)
{
upsampledSliceRegion.SetSize(0, xMax*2);
upsampledSliceRegion.SetSize(1, yMax*2);
}
// frequency map slice
typename SliceType::Pointer fMapSlice = NULL;
- if (m_Parameters.m_FrequencyMap.IsNotNull())
+ if ( m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull())
{
fMapSlice = SliceType::New();
fMapSlice->SetLargestPossibleRegion( sliceRegion );
fMapSlice->SetBufferedRegion( sliceRegion );
fMapSlice->SetRequestedRegion( sliceRegion );
fMapSlice->Allocate();
fMapSlice->FillBuffer(0.0);
}
- m_Parameters.m_SignalScale = 1;
- m_Parameters.m_DoSimulateRelaxation = false;
+ m_Parameters.m_SignalGen.m_SignalScale = 1;
+ m_Parameters.m_SignalGen.m_DoSimulateRelaxation = false;
- if (m_Parameters.m_Spikes>0 || m_Parameters.m_FrequencyMap.IsNotNull() || m_Parameters.m_KspaceLineOffset>0.0 || m_Parameters.m_DoAddGibbsRinging || m_Parameters.m_EddyStrength>0 || m_Parameters.m_CroppingFactor<1.0)
+ if ( m_Parameters.m_SignalGen.m_Spikes>0 || m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull() || m_Parameters.m_SignalGen.m_KspaceLineOffset>0.0 || m_Parameters.m_SignalGen.m_DoAddGibbsRinging || m_Parameters.m_SignalGen.m_EddyStrength>0 || m_Parameters.m_SignalGen.m_CroppingFactor<1.0)
{
- ImageRegion<3> croppedRegion = inputRegion; croppedRegion.SetSize(1, croppedRegion.GetSize(1)*m_Parameters.m_CroppingFactor);
+ ImageRegion<3> croppedRegion = inputRegion; croppedRegion.SetSize(1, croppedRegion.GetSize(1)* m_Parameters.m_SignalGen.m_CroppingFactor);
itk::Point<double,3> shiftedOrigin = inputImage->GetOrigin(); shiftedOrigin[1] += (inputRegion.GetSize(1)-croppedRegion.GetSize(1))*inputImage->GetSpacing()[1]/2;
outputImage = InputImageType::New();
outputImage->SetSpacing( inputImage->GetSpacing() );
outputImage->SetOrigin( shiftedOrigin );
outputImage->SetDirection( inputImage->GetDirection() );
outputImage->SetLargestPossibleRegion( croppedRegion );
outputImage->SetBufferedRegion( croppedRegion );
outputImage->SetRequestedRegion( croppedRegion );
outputImage->SetVectorLength( inputImage->GetVectorLength() );
outputImage->Allocate();
typename InputImageType::PixelType temp;
temp.SetSize(inputImage->GetVectorLength());
temp.Fill(0.0);
outputImage->FillBuffer(temp);
int tempY=croppedRegion.GetSize(1);
tempY += tempY%2;
croppedRegion.SetSize(1, tempY);
m_StatusText += this->GetTime()+" > Adjusting complex signal\n";
- if (m_Parameters.m_FrequencyMap.IsNotNull())
+ if ( m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull())
m_StatusText += "Simulating distortions\n";
- if (m_Parameters.m_DoAddGibbsRinging)
+ if ( m_Parameters.m_SignalGen.m_DoAddGibbsRinging)
m_StatusText += "Simulating ringing artifacts\n";
- if (m_Parameters.m_EddyStrength>0)
+ if ( m_Parameters.m_SignalGen.m_EddyStrength>0)
m_StatusText += "Simulating eddy currents\n";
- if (m_Parameters.m_Spikes>0)
+ if ( m_Parameters.m_SignalGen.m_Spikes>0)
m_StatusText += "Simulating spikes\n";
- if (m_Parameters.m_CroppingFactor<1.0)
+ if ( m_Parameters.m_SignalGen.m_CroppingFactor<1.0)
m_StatusText += "Simulating aliasing artifacts\n";
- if (m_Parameters.m_KspaceLineOffset>0)
+ if ( m_Parameters.m_SignalGen.m_KspaceLineOffset>0)
m_StatusText += "Simulating ghosts\n";
std::vector< unsigned int > spikeVolume;
- for (unsigned int i=0; i<m_Parameters.m_Spikes; i++)
+ for (unsigned int i=0; i< m_Parameters.m_SignalGen.m_Spikes; i++)
spikeVolume.push_back(m_RandGen->GetIntegerVariate()%inputImage->GetVectorLength());
std::sort (spikeVolume.begin(), spikeVolume.end());
std::reverse (spikeVolume.begin(), spikeVolume.end());
- FiberfoxParameters<double> doubleParam = m_Parameters.CopyParameters<double>();
+ FiberfoxParameters<double> doubleParam = m_Parameters.CopyParameters<double>();
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
unsigned long lastTick = 0;
boost::progress_display disp(inputImage->GetVectorLength()*inputRegion.GetSize(2));
for (unsigned int g=0; g<inputImage->GetVectorLength(); g++)
{
std::vector< unsigned int > spikeSlice;
while (!spikeVolume.empty() && spikeVolume.back()==g)
{
spikeSlice.push_back(m_RandGen->GetIntegerVariate()%inputImage->GetLargestPossibleRegion().GetSize(2));
spikeVolume.pop_back();
}
std::sort (spikeSlice.begin(), spikeSlice.end());
std::reverse (spikeSlice.begin(), spikeSlice.end());
for (unsigned int z=0; z<inputRegion.GetSize(2); z++)
{
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
std::vector< SliceType::Pointer > compartmentSlices;
// extract slice from channel g
for (unsigned int y=0; y<inputRegion.GetSize(1); y++)
for (unsigned int x=0; x<inputRegion.GetSize(0); x++)
{
typename SliceType::IndexType index2D;
index2D[0]=x; index2D[1]=y;
typename InputImageType::IndexType index3D;
index3D[0]=x; index3D[1]=y; index3D[2]=z;
SliceType::PixelType pix2D = (SliceType::PixelType)inputImage->GetPixel(index3D)[g];
slice->SetPixel(index2D, pix2D);
if (fMapSlice.IsNotNull())
- fMapSlice->SetPixel(index2D, m_Parameters.m_FrequencyMap->GetPixel(index3D));
+ fMapSlice->SetPixel(index2D, m_Parameters.m_SignalGen.m_FrequencyMap->GetPixel(index3D));
}
- if (m_Parameters.m_DoAddGibbsRinging)
+ if ( m_Parameters.m_SignalGen.m_DoAddGibbsRinging)
{
itk::ResampleImageFilter<SliceType, SliceType>::Pointer resampler = itk::ResampleImageFilter<SliceType, SliceType>::New();
resampler->SetInput(slice);
resampler->SetOutputParametersFromImage(slice);
resampler->SetSize(upsampledSliceRegion.GetSize());
resampler->SetOutputSpacing(slice->GetSpacing()/2);
itk::NearestNeighborInterpolateImageFunction<SliceType, double>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<SliceType, double>::New();
resampler->SetInterpolator(nn_interpolator);
resampler->Update();
typename SliceType::Pointer upslice = resampler->GetOutput();
compartmentSlices.push_back(upslice);
if (fMapSlice.IsNotNull())
{
itk::ResampleImageFilter<SliceType, SliceType>::Pointer resampler = itk::ResampleImageFilter<SliceType, SliceType>::New();
resampler->SetInput(fMapSlice);
resampler->SetOutputParametersFromImage(fMapSlice);
resampler->SetSize(upsampledSliceRegion.GetSize());
resampler->SetOutputSpacing(fMapSlice->GetSpacing()/2);
itk::NearestNeighborInterpolateImageFunction<SliceType, double>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<SliceType, double>::New();
resampler->SetInterpolator(nn_interpolator);
resampler->Update();
fMapSlice = resampler->GetOutput();
}
}
else
compartmentSlices.push_back(slice);
// fourier transform slice
typename ComplexSliceType::Pointer fSlice;
itk::Size<2> outSize; outSize.SetElement(0, xMax); outSize.SetElement(1, croppedRegion.GetSize()[1]);
typename itk::KspaceImageFilter< SliceType::PixelType >::Pointer idft = itk::KspaceImageFilter< SliceType::PixelType >::New();
idft->SetUseConstantRandSeed(m_UseConstantRandSeed);
idft->SetParameters(doubleParam);
idft->SetCompartmentImages(compartmentSlices);
idft->SetFrequencyMapSlice(fMapSlice);
- idft->SetDiffusionGradientDirection(m_Parameters.GetGradientDirection(g));
+ idft->SetDiffusionGradientDirection( m_Parameters.m_SignalGen.GetGradientDirection(g));
idft->SetZ((double)z-(double)inputRegion.GetSize(2)/2.0);
idft->SetOutSize(outSize);
int numSpikes = 0;
while (!spikeSlice.empty() && spikeSlice.back()==z)
{
numSpikes++;
spikeSlice.pop_back();
}
idft->SetSpikesPerSlice(numSpikes);
idft->Update();
fSlice = idft->GetOutput();
// inverse fourier transform slice
typename SliceType::Pointer newSlice;
typename itk::DftImageFilter< SliceType::PixelType >::Pointer dft = itk::DftImageFilter< SliceType::PixelType >::New();
dft->SetInput(fSlice);
dft->Update();
newSlice = dft->GetOutput();
// put slice back into channel g
for (unsigned int y=0; y<outputImage->GetLargestPossibleRegion().GetSize(1); y++)
for (unsigned int x=0; x<outputImage->GetLargestPossibleRegion().GetSize(0); x++)
{
typename InputImageType::IndexType index3D;
index3D[0]=x; index3D[1]=y; index3D[2]=z;
typename InputImageType::PixelType pix3D = outputImage->GetPixel(index3D);
typename SliceType::IndexType index2D;
index2D[0]=x; index2D[1]=y;
double signal = newSlice->GetPixel(index2D);
if (signal>0)
signal = floor(signal+0.5);
else
signal = ceil(signal-0.5);
pix3D[g] = signal;
outputImage->SetPixel(index3D, pix3D);
}
++disp;
unsigned long newTick = 50*disp.count()/disp.expected_count();
for (unsigned int tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
}
}
m_StatusText += "\n\n";
}
- if (m_Parameters.m_NoiseModel!=NULL)
+ if ( m_Parameters.m_NoiseModel!=NULL)
{
m_StatusText += this->GetTime()+" > Adding noise\n";
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
unsigned long lastTick = 0;
ImageRegionIterator<InputImageType> it1 (outputImage, outputImage->GetLargestPossibleRegion());
boost::progress_display disp(outputImage->GetLargestPossibleRegion().GetNumberOfPixels());
while(!it1.IsAtEnd())
{
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
++disp;
unsigned long newTick = 50*disp.count()/disp.expected_count();
for (unsigned int tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
typename InputImageType::PixelType signal = it1.Get();
m_Parameters.m_NoiseModel->AddNoise(signal);
it1.Set(signal);
++it1;
}
m_StatusText += "\n\n";
}
this->SetNthOutput(0, outputImage);
m_StatusText += "Finished simulation\n";
m_StatusText += "Simulation time: "+GetTime();
}
template< class TPixelType >
std::string AddArtifactsToDwiImageFilter< TPixelType >::GetTime()
{
unsigned long total = (double)(clock() - m_StartTime)/CLOCKS_PER_SEC;
unsigned long hours = total/3600;
unsigned long minutes = (total%3600)/60;
unsigned long seconds = total%60;
std::string out = "";
out.append(boost::lexical_cast<std::string>(hours));
out.append(":");
out.append(boost::lexical_cast<std::string>(minutes));
out.append(":");
out.append(boost::lexical_cast<std::string>(seconds));
return out;
}
}
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp
index 924e1a7e17..5935ffc6c2 100644
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp
@@ -1,249 +1,241 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "itkFibersFromPlanarFiguresFilter.h"
#define _USE_MATH_DEFINES
#include <math.h>
// MITK
#include <itkOrientationDistributionFunction.h>
#include <itkDiffusionQballGeneralizedFaImageFilter.h>
#include <mitkStandardFileLocations.h>
#include <mitkFiberBuilder.h>
#include <mitkMetropolisHastingsSampler.h>
#include <itkTensorImageToQBallImageFilter.h>
#include <mitkGibbsEnergyComputer.h>
#include <mitkRotationOperation.h>
#include <mitkInteractionConst.h>
// ITK
#include <itkImageDuplicator.h>
#include <itkResampleImageFilter.h>
#include <itkTimeProbe.h>
#include <itkMersenneTwisterRandomVariateGenerator.h>
// MISC
#include <math.h>
namespace itk{
FibersFromPlanarFiguresFilter::FibersFromPlanarFiguresFilter()
- : m_FiberDistribution(DISTRIBUTE_UNIFORM)
- , m_Density(1000)
- , m_FiberSampling(1)
- , m_Tension(0)
- , m_Continuity(0)
- , m_Bias(0)
- , m_Variance(0.1)
{
}
FibersFromPlanarFiguresFilter::~FibersFromPlanarFiguresFilter()
{
}
void FibersFromPlanarFiguresFilter::GeneratePoints()
{
Statistics::MersenneTwisterRandomVariateGenerator::Pointer randGen = Statistics::MersenneTwisterRandomVariateGenerator::New();
randGen->SetSeed((unsigned int)0);
m_2DPoints.clear();
int count = 0;
- while (count < m_Density)
+ while (count < m_Parameters.m_Density)
{
mitk::Vector2D p;
- switch (m_FiberDistribution) {
- case DISTRIBUTE_GAUSSIAN:
- p[0] = randGen->GetNormalVariate(0, m_Variance);
- p[1] = randGen->GetNormalVariate(0, m_Variance);
+ switch (m_Parameters.m_Distribution) {
+ case FiberGenerationParameters::DISTRIBUTE_GAUSSIAN:
+ p[0] = randGen->GetNormalVariate(0, m_Parameters.m_Variance);
+ p[1] = randGen->GetNormalVariate(0, m_Parameters.m_Variance);
break;
default:
p[0] = randGen->GetUniformVariate(-1, 1);
p[1] = randGen->GetUniformVariate(-1, 1);
}
if (sqrt(p[0]*p[0]+p[1]*p[1]) <= 1)
{
m_2DPoints.push_back(p);
count++;
}
}
}
-// perform global tracking
void FibersFromPlanarFiguresFilter::GenerateData()
{
// check if enough fiducials are available
- for (unsigned int i=0; i<m_Fiducials.size(); i++)
- if (m_Fiducials.at(i).size()<2)
+ for (unsigned int i=0; i<m_Parameters.m_Fiducials.size(); i++)
+ if (m_Parameters.m_Fiducials.at(i).size()<2)
itkExceptionMacro("At least 2 fiducials needed per fiber bundle!");
- for (unsigned int i=0; i<m_Fiducials.size(); i++)
+ for (unsigned int i=0; i<m_Parameters.m_Fiducials.size(); i++)
{
vtkSmartPointer<vtkCellArray> m_VtkCellArray = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPoints> m_VtkPoints = vtkSmartPointer<vtkPoints>::New();
- vector< mitk::PlanarEllipse::Pointer > bundle = m_Fiducials.at(i);
+ vector< mitk::PlanarEllipse::Pointer > bundle = m_Parameters.m_Fiducials.at(i);
vector< unsigned int > fliplist;
- if (i<m_FlipList.size())
- fliplist = m_FlipList.at(i);
+ if (i<m_Parameters.m_FlipList.size())
+ fliplist = m_Parameters.m_FlipList.at(i);
else
fliplist.resize(bundle.size(), 0);
if (fliplist.size()<bundle.size())
fliplist.resize(bundle.size(), 0);
GeneratePoints();
- for (int j=0; j<m_Density; j++)
+ for (int j=0; j<m_Parameters.m_Density; j++)
{
vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
mitk::PlanarEllipse::Pointer figure = bundle.at(0);
mitk::Point2D p0 = figure->GetControlPoint(0);
mitk::Point2D p1 = figure->GetControlPoint(1);
mitk::Point2D p2 = figure->GetControlPoint(2);
mitk::Point2D p3 = figure->GetControlPoint(3);
double r1 = p0.EuclideanDistanceTo(p1);
double r2 = p0.EuclideanDistanceTo(p2);
mitk::Vector2D eDir = p1-p0; eDir.Normalize();
mitk::Vector2D tDir = p3-p0; tDir.Normalize();
// apply twist
vnl_matrix_fixed<double, 2, 2> tRot;
tRot[0][0] = tDir[0];
tRot[1][1] = tRot[0][0];
tRot[1][0] = sin(acos(tRot[0][0]));
tRot[0][1] = -tRot[1][0];
if (tDir[1]<0)
tRot.inplace_transpose();
m_2DPoints[j].SetVnlVector(tRot*m_2DPoints[j].GetVnlVector());
// apply new ellipse shape
vnl_vector_fixed< double, 2 > newP;
newP[0] = m_2DPoints.at(j)[0];
newP[1] = m_2DPoints.at(j)[1];
double alpha = acos(eDir[0]);
if (eDir[1]>0)
alpha = 2*M_PI-alpha;
vnl_matrix_fixed<double, 2, 2> eRot;
eRot[0][0] = cos(alpha);
eRot[1][1] = eRot[0][0];
eRot[1][0] = sin(alpha);
eRot[0][1] = -eRot[1][0];
newP = eRot*newP;
newP[0] *= r1;
newP[1] *= r2;
newP = eRot.transpose()*newP;
p0[0] += newP[0];
p0[1] += newP[1];
const mitk::PlaneGeometry* planeGeo = figure->GetPlaneGeometry();
mitk::Point3D w, wc;
planeGeo->Map(p0, w);
wc = figure->GetWorldControlPoint(0);
vtkIdType id = m_VtkPoints->InsertNextPoint(w.GetDataPointer());
container->GetPointIds()->InsertNextId(id);
vnl_vector_fixed< double, 3 > n = planeGeo->GetNormalVnl();
for (unsigned int k=1; k<bundle.size(); k++)
{
figure = bundle.at(k);
p0 = figure->GetControlPoint(0);
p1 = figure->GetControlPoint(1);
p2 = figure->GetControlPoint(2);
p3 = figure->GetControlPoint(3);
r1 = p0.EuclideanDistanceTo(p1);
r2 = p0.EuclideanDistanceTo(p2);
eDir = p1-p0; eDir.Normalize();
mitk::Vector2D tDir2 = p3-p0; tDir2.Normalize();
mitk::Vector2D temp; temp.SetVnlVector(tRot.transpose() * tDir2.GetVnlVector());
// apply twist
tRot[0][0] = tDir[0]*tDir2[0] + tDir[1]*tDir2[1];
tRot[1][1] = tRot[0][0];
tRot[1][0] = sin(acos(tRot[0][0]));
tRot[0][1] = -tRot[1][0];
if (temp[1]<0)
tRot.inplace_transpose();
m_2DPoints[j].SetVnlVector(tRot*m_2DPoints[j].GetVnlVector());
tDir = tDir2;
// apply new ellipse shape
newP[0] = m_2DPoints.at(j)[0];
newP[1] = m_2DPoints.at(j)[1];
// calculate normal
mitk::PlaneGeometry* planeGeo = const_cast<mitk::PlaneGeometry*>(figure->GetPlaneGeometry());
mitk::Vector3D perp = wc-planeGeo->ProjectPointOntoPlane(wc); perp.Normalize();
vnl_vector_fixed< double, 3 > n2 = planeGeo->GetNormalVnl();
wc = figure->GetWorldControlPoint(0);
// is flip needed?
if (dot_product(perp.GetVnlVector(),n2)>0 && dot_product(n,n2)<=0.00001)
newP[0] *= -1;
if (fliplist.at(k)>0)
newP[0] *= -1;
n = n2;
alpha = acos(eDir[0]);
if (eDir[1]>0)
alpha = 2*M_PI-alpha;
eRot[0][0] = cos(alpha);
eRot[1][1] = eRot[0][0];
eRot[1][0] = sin(alpha);
eRot[0][1] = -eRot[1][0];
newP = eRot*newP;
newP[0] *= r1;
newP[1] *= r2;
newP = eRot.transpose()*newP;
p0[0] += newP[0];
p0[1] += newP[1];
mitk::Point3D w;
planeGeo->Map(p0, w);
vtkIdType id = m_VtkPoints->InsertNextPoint(w.GetDataPointer());
container->GetPointIds()->InsertNextId(id);
}
m_VtkCellArray->InsertNextCell(container);
}
vtkSmartPointer<vtkPolyData> fiberPolyData = vtkSmartPointer<vtkPolyData>::New();
fiberPolyData->SetPoints(m_VtkPoints);
fiberPolyData->SetLines(m_VtkCellArray);
mitk::FiberBundleX::Pointer mitkFiberBundle = mitk::FiberBundleX::New(fiberPolyData);
- mitkFiberBundle->DoFiberSmoothing(m_FiberSampling, m_Tension, m_Continuity, m_Bias);
+ mitkFiberBundle->DoFiberSmoothing(m_Parameters.m_Sampling, m_Parameters.m_Tension, m_Parameters.m_Continuity, m_Parameters.m_Bias);
m_FiberBundles.push_back(mitkFiberBundle);
}
}
}
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.h b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.h
index 8d561d7d0b..f7e9451f76 100644
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.h
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.h
@@ -1,106 +1,87 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef itkFibersFromPlanarFiguresFilter_h
#define itkFibersFromPlanarFiguresFilter_h
// MITK
#include <mitkPlanarEllipse.h>
#include <mitkFiberBundleX.h>
+#include <mitkFiberfoxParameters.h>
// ITK
#include <itkProcessObject.h>
// VTK
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyLine.h>
using namespace std;
namespace itk{
/**
* \brief Generates artificial fibers distributed in and interpolated between the input planar figures. */
class FibersFromPlanarFiguresFilter : public ProcessObject
{
public:
- enum FiberDistribution{
- DISTRIBUTE_UNIFORM, // distribute fibers uniformly in the ROIs
- DISTRIBUTE_GAUSSIAN // distribute fibers using a 2D gaussian
- };
-
typedef FibersFromPlanarFiguresFilter Self;
typedef ProcessObject Superclass;
typedef SmartPointer< Self > Pointer;
typedef SmartPointer< const Self > ConstPointer;
- typedef vector< vector< mitk::PlanarEllipse::Pointer > > FiducialListType;
- typedef vector< vector< unsigned int > > FlipListType;
typedef mitk::FiberBundleX::Pointer FiberType;
typedef vector< mitk::FiberBundleX::Pointer > FiberContainerType;
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
itkTypeMacro( FibersFromPlanarFiguresFilter, ProcessObject )
virtual void Update(){
this->GenerateData();
}
// input
- void SetFlipList(FlipListType fliplist){ m_FlipList = fliplist; } ///< contains flags indicating a flip of the 2D fiber x-coordinates (needed to resolve some unwanted fiber twisting)
- void SetFiducials(FiducialListType fiducials){ m_Fiducials = fiducials; } ///< container of the planar ellipses used as fiducials for the fiber generation process
- itkSetMacro(Density, int) ///< number of fibers per bundle
- itkSetMacro(FiberSampling, double) ///< sampling points of the fibers per cm
- itkSetMacro(Tension, double) ///< tension parameter of the Kochanek-Bartels splines
- itkSetMacro(Continuity, double) ///< continuity parameter of the Kochanek-Bartels splines
- itkSetMacro(Bias, double) ///< bias parameter of the Kochanek-Bartels splines
- itkSetMacro(FiberDistribution, FiberDistribution) ///< flag to switch between uniform and gaussian distribution of the fiber waypoints inside of the fiducials
- itkSetMacro(Variance, double) ///< variance of the gaussian waypoint distribution
+ void SetParameters( FiberGenerationParameters param ) ///< Simulation parameters.
+ {
+ m_Parameters = param;
+ }
// output
FiberContainerType GetFiberBundles(){ return m_FiberBundles; }
protected:
void GenerateData();
FibersFromPlanarFiguresFilter();
virtual ~FibersFromPlanarFiguresFilter();
void GeneratePoints();
- FiberDistribution m_FiberDistribution; ///< flag to switch between uniform and gaussian distribution of the fiber waypoints inside of the fiducials
- FlipListType m_FlipList; ///< contains flags indicating a flip of the 2D fiber x-coordinates (needed to resolve some unwanted fiber twisting)
- FiducialListType m_Fiducials; ///< container of the planar ellipses used as fiducials for the fiber generation process
- FiberContainerType m_FiberBundles; ///< container for the output fiber bundles
- int m_Density; ///< number of fibers per bundle
- double m_FiberSampling; ///< sampling points of the fibers per cm
- double m_Tension; ///< tension parameter of the Kochanek-Bartels splines
- double m_Continuity; ///< continuity parameter of the Kochanek-Bartels splines
- double m_Bias; ///< bias parameter of the Kochanek-Bartels splines
- double m_Variance; ///< variance of the gaussian waypoint distribution
- vector< mitk::Vector2D > m_2DPoints; ///< container for the 2D fiber waypoints
+ FiberContainerType m_FiberBundles; ///< container for the output fiber bundles
+ vector< mitk::Vector2D > m_2DPoints; ///< container for the 2D fiber waypoints
+ FiberGenerationParameters m_Parameters;
};
}
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkFibersFromPlanarFiguresFilter.cpp"
#endif
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkKspaceImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkKspaceImageFilter.cpp
index 6888736d7e..77448fc7c4 100644
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkKspaceImageFilter.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkKspaceImageFilter.cpp
@@ -1,220 +1,220 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef __itkKspaceImageFilter_txx
#define __itkKspaceImageFilter_txx
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "itkKspaceImageFilter.h"
#include <itkImageRegionConstIterator.h>
#include <itkImageRegionConstIteratorWithIndex.h>
#include <itkImageRegionIterator.h>
#include <itkImageFileWriter.h>
#define _USE_MATH_DEFINES
#include <math.h>
namespace itk {
template< class TPixelType >
KspaceImageFilter< TPixelType >
::KspaceImageFilter()
: m_FrequencyMapSlice(NULL)
, m_Z(0)
, m_UseConstantRandSeed(false)
, m_SpikesPerSlice(0)
, m_IsBaseline(true)
{
m_DiffusionGradientDirection.Fill(0.0);
m_RandGen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
m_RandGen->SetSeed();
}
template< class TPixelType >
void KspaceImageFilter< TPixelType >
::BeforeThreadedGenerateData()
{
if (m_UseConstantRandSeed) // always generate the same random numbers?
m_RandGen->SetSeed(0);
else
m_RandGen->SetSeed();
typename OutputImageType::Pointer outputImage = OutputImageType::New();
itk::ImageRegion<2> region; region.SetSize(0, m_OutSize[0]); region.SetSize(1, m_OutSize[1]);
outputImage->SetLargestPossibleRegion( region );
outputImage->SetBufferedRegion( region );
outputImage->SetRequestedRegion( region );
outputImage->Allocate();
double gamma = 42576000; // Gyromagnetic ratio in Hz/T
- if (m_Parameters.m_EddyStrength>0 && m_DiffusionGradientDirection.GetNorm()>0.001)
+ if ( m_Parameters.m_SignalGen.m_EddyStrength>0 && m_DiffusionGradientDirection.GetNorm()>0.001)
{
m_DiffusionGradientDirection.Normalize();
- m_DiffusionGradientDirection = m_DiffusionGradientDirection * m_Parameters.m_EddyStrength/1000 * gamma;
+ m_DiffusionGradientDirection = m_DiffusionGradientDirection * m_Parameters.m_SignalGen.m_EddyStrength/1000 * gamma;
m_IsBaseline = false;
}
this->SetNthOutput(0, outputImage);
m_Spike = vcl_complex<double>(0,0);
- m_Transform = m_Parameters.m_ImageDirection;
+ m_Transform = m_Parameters.m_SignalGen.m_ImageDirection;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
- m_Transform[i][j] *= m_Parameters.m_ImageSpacing[j];
+ m_Transform[i][j] *= m_Parameters.m_SignalGen.m_ImageSpacing[j];
}
template< class TPixelType >
void KspaceImageFilter< TPixelType >
::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, ThreadIdType)
{
typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0));
ImageRegionIterator< OutputImageType > oit(outputImage, outputRegionForThread);
typedef ImageRegionConstIterator< InputImageType > InputIteratorType;
double kxMax = outputImage->GetLargestPossibleRegion().GetSize(0); // k-space size in x-direction
double kyMax = outputImage->GetLargestPossibleRegion().GetSize(1); // k-space size in y-direction
double xMax = m_CompartmentImages.at(0)->GetLargestPossibleRegion().GetSize(0); // scanner coverage in x-direction
double yMax = m_CompartmentImages.at(0)->GetLargestPossibleRegion().GetSize(1); // scanner coverage in y-direction
double numPix = kxMax*kyMax;
- double dt = m_Parameters.m_tLine/kxMax;
- double fromMaxEcho = - m_Parameters.m_tLine*kyMax/2;
+ double dt = m_Parameters.m_SignalGen.m_tLine/kxMax;
+ double fromMaxEcho = - m_Parameters.m_SignalGen.m_tLine*kyMax/2;
double upsampling = xMax/kxMax; // discrepany between k-space resolution and image resolution
double yMaxFov = kyMax*upsampling; // actual FOV in y-direction (in x-direction xMax==FOV)
int xRingingOffset = xMax-kxMax;
int yRingingOffset = yMaxFov-kyMax;
while( !oit.IsAtEnd() )
{
itk::Index< 2 > kIdx;
kIdx[0] = oit.GetIndex()[0];
kIdx[1] = oit.GetIndex()[1];
double t = fromMaxEcho + ((double)kIdx[1]*kxMax+(double)kIdx[0])*dt; // dephasing time
// rearrange slice
if( kIdx[0] < kxMax/2 )
kIdx[0] = kIdx[0] + kxMax/2;
else
kIdx[0] = kIdx[0] - kxMax/2;
if( kIdx[1] < kyMax/2 )
kIdx[1] = kIdx[1] + kyMax/2;
else
kIdx[1] = kIdx[1] - kyMax/2;
// calculate eddy current decay factors
double eddyDecay = 0;
- if (m_Parameters.m_EddyStrength>0)
- eddyDecay = exp(-(m_Parameters.m_tEcho/2 + t)/m_Parameters.m_Tau) * t/1000;
+ if ( m_Parameters.m_SignalGen.m_EddyStrength>0)
+ eddyDecay = exp(-( m_Parameters.m_SignalGen.m_tEcho/2 + t)/ m_Parameters.m_SignalGen.m_Tau) * t/1000;
// calcualte signal relaxation factors
std::vector< double > relaxFactor;
- if (m_Parameters.m_DoSimulateRelaxation)
+ if ( m_Parameters.m_SignalGen.m_DoSimulateRelaxation)
for (unsigned int i=0; i<m_CompartmentImages.size(); i++)
- relaxFactor.push_back(exp(-(m_Parameters.m_tEcho+t)/m_T2.at(i) -fabs(t)/m_Parameters.m_tInhom));
+ relaxFactor.push_back(exp(-( m_Parameters.m_SignalGen.m_tEcho+t)/m_T2.at(i) -fabs(t)/ m_Parameters.m_SignalGen.m_tInhom));
double kx = kIdx[0];
double ky = kIdx[1];
if (oit.GetIndex()[1]%2 == 1) // reverse readout direction and add ghosting
{
kIdx[0] = kxMax-kIdx[0]-1; // reverse readout direction
- kx = (double)kIdx[0]-m_Parameters.m_KspaceLineOffset; // add gradient delay induced offset
+ kx = (double)kIdx[0]- m_Parameters.m_SignalGen.m_KspaceLineOffset; // add gradient delay induced offset
}
else
- kx += m_Parameters.m_KspaceLineOffset; // add gradient delay induced offset
+ kx += m_Parameters.m_SignalGen.m_KspaceLineOffset; // add gradient delay induced offset
// add gibbs ringing offset (cropps k-space)
if (kx>=kxMax/2)
kx += xRingingOffset;
if (ky>=kyMax/2)
ky += yRingingOffset;
vcl_complex<double> s(0,0);
InputIteratorType it(m_CompartmentImages.at(0), m_CompartmentImages.at(0)->GetLargestPossibleRegion() );
while( !it.IsAtEnd() )
{
double x = it.GetIndex()[0]-xMax/2;
double y = it.GetIndex()[1]-yMax/2;
vcl_complex<double> f(0, 0);
// sum compartment signals and simulate relaxation
for (unsigned int i=0; i<m_CompartmentImages.size(); i++)
- if (m_Parameters.m_DoSimulateRelaxation)
- f += std::complex<double>( m_CompartmentImages.at(i)->GetPixel(it.GetIndex()) * relaxFactor.at(i) * m_Parameters.m_SignalScale, 0);
+ if ( m_Parameters.m_SignalGen.m_DoSimulateRelaxation)
+ f += std::complex<double>( m_CompartmentImages.at(i)->GetPixel(it.GetIndex()) * relaxFactor.at(i) * m_Parameters.m_SignalGen.m_SignalScale, 0);
else
- f += std::complex<double>( m_CompartmentImages.at(i)->GetPixel(it.GetIndex()) * m_Parameters.m_SignalScale );
+ f += std::complex<double>( m_CompartmentImages.at(i)->GetPixel(it.GetIndex()) * m_Parameters.m_SignalGen.m_SignalScale );
// simulate eddy currents and other distortions
double omega_t = 0;
- if ( m_Parameters.m_EddyStrength>0 && !m_IsBaseline)
+ if ( m_Parameters.m_SignalGen.m_EddyStrength>0 && !m_IsBaseline)
{
itk::Vector< double, 3 > pos; pos[0] = x; pos[1] = y; pos[2] = m_Z;
pos = m_Transform*pos/1000; // vector from image center to current position (in meter)
omega_t += (m_DiffusionGradientDirection[0]*pos[0]+m_DiffusionGradientDirection[1]*pos[1]+m_DiffusionGradientDirection[2]*pos[2])*eddyDecay;
}
if (m_FrequencyMapSlice.IsNotNull()) // simulate distortions
omega_t += m_FrequencyMapSlice->GetPixel(it.GetIndex())*t/1000;
if (y<-yMaxFov/2)
y += yMaxFov;
else if (y>=yMaxFov/2)
y -= yMaxFov;
// actual DFT term
s += f * exp( std::complex<double>(0, 2 * M_PI * (kx*x/xMax + ky*y/yMaxFov + omega_t )) );
++it;
}
s /= numPix;
if (m_SpikesPerSlice>0 && sqrt(s.imag()*s.imag()+s.real()*s.real()) > sqrt(m_Spike.imag()*m_Spike.imag()+m_Spike.real()*m_Spike.real()) )
m_Spike = s;
outputImage->SetPixel(kIdx, s);
++oit;
}
}
template< class TPixelType >
void KspaceImageFilter< TPixelType >
::AfterThreadedGenerateData()
{
typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0));
double kxMax = outputImage->GetLargestPossibleRegion().GetSize(0); // k-space size in x-direction
double kyMax = outputImage->GetLargestPossibleRegion().GetSize(1); // k-space size in y-direction
- m_Spike *= m_Parameters.m_SpikeAmplitude;
+ m_Spike *= m_Parameters.m_SignalGen.m_SpikeAmplitude;
itk::Index< 2 > spikeIdx;
for (unsigned int i=0; i<m_SpikesPerSlice; i++)
{
spikeIdx[0] = m_RandGen->GetIntegerVariate()%(int)kxMax;
spikeIdx[1] = m_RandGen->GetIntegerVariate()%(int)kyMax;
outputImage->SetPixel(spikeIdx, m_Spike);
}
}
}
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp
index caef447cf8..a097c33135 100755
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp
@@ -1,1238 +1,1301 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "itkTractsToDWIImageFilter.h"
#include <boost/progress.hpp>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyLine.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkResampleImageFilter.h>
#include <itkNearestNeighborInterpolateImageFunction.h>
#include <itkBSplineInterpolateImageFunction.h>
#include <itkCastImageFilter.h>
#include <itkImageFileWriter.h>
#include <itkRescaleIntensityImageFilter.h>
#include <itkWindowedSincInterpolateImageFunction.h>
#include <itkResampleDwiImageFilter.h>
#include <itkKspaceImageFilter.h>
#include <itkDftImageFilter.h>
#include <itkAddImageFilter.h>
#include <itkConstantPadImageFilter.h>
#include <itkCropImageFilter.h>
#include <mitkAstroStickModel.h>
#include <vtkTransform.h>
#include <iostream>
#include <fstream>
#include <itkImageDuplicator.h>
#include <itksys/SystemTools.hxx>
#include <mitkIOUtil.h>
#include <itkDiffusionTensor3DReconstructionImageFilter.h>
#include <itkDiffusionTensor3D.h>
#include <itkTractDensityImageFilter.h>
#include <boost/lexical_cast.hpp>
#include <itkTractsToVectorImageFilter.h>
namespace itk
{
template< class PixelType >
TractsToDWIImageFilter< PixelType >::TractsToDWIImageFilter()
: m_FiberBundle(NULL)
, m_StatusText("")
, m_UseConstantRandSeed(false)
, m_RandGen(itk::Statistics::MersenneTwisterRandomVariateGenerator::New())
{
m_RandGen->SetSeed();
}
template< class PixelType >
TractsToDWIImageFilter< PixelType >::~TractsToDWIImageFilter()
{
}
template< class PixelType >
TractsToDWIImageFilter< PixelType >::DoubleDwiType::Pointer TractsToDWIImageFilter< PixelType >::DoKspaceStuff( std::vector< DoubleDwiType::Pointer >& images )
{
int numFiberCompartments = m_Parameters.m_FiberModelList.size();
// create slice object
ImageRegion<2> sliceRegion;
sliceRegion.SetSize(0, m_UpsampledImageRegion.GetSize()[0]);
sliceRegion.SetSize(1, m_UpsampledImageRegion.GetSize()[1]);
Vector< double, 2 > sliceSpacing;
sliceSpacing[0] = m_UpsampledSpacing[0];
sliceSpacing[1] = m_UpsampledSpacing[1];
// frequency map slice
SliceType::Pointer fMapSlice = NULL;
- if (m_Parameters.m_FrequencyMap.IsNotNull())
+ if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull())
{
fMapSlice = SliceType::New();
ImageRegion<2> region;
region.SetSize(0, m_UpsampledImageRegion.GetSize()[0]);
region.SetSize(1, m_UpsampledImageRegion.GetSize()[1]);
fMapSlice->SetLargestPossibleRegion( region );
fMapSlice->SetBufferedRegion( region );
fMapSlice->SetRequestedRegion( region );
fMapSlice->Allocate();
fMapSlice->FillBuffer(0.0);
}
DoubleDwiType::Pointer newImage = DoubleDwiType::New();
- newImage->SetSpacing( m_Parameters.m_ImageSpacing );
- newImage->SetOrigin( m_Parameters.m_ImageOrigin );
- newImage->SetDirection( m_Parameters.m_ImageDirection );
- newImage->SetLargestPossibleRegion( m_Parameters.m_ImageRegion );
- newImage->SetBufferedRegion( m_Parameters.m_ImageRegion );
- newImage->SetRequestedRegion( m_Parameters.m_ImageRegion );
+ newImage->SetSpacing( m_Parameters.m_SignalGen.m_ImageSpacing );
+ newImage->SetOrigin( m_Parameters.m_SignalGen.m_ImageOrigin );
+ newImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
+ newImage->SetLargestPossibleRegion( m_Parameters.m_SignalGen.m_ImageRegion );
+ newImage->SetBufferedRegion( m_Parameters.m_SignalGen.m_ImageRegion );
+ newImage->SetRequestedRegion( m_Parameters.m_SignalGen.m_ImageRegion );
newImage->SetVectorLength( images.at(0)->GetVectorLength() );
newImage->Allocate();
std::vector< unsigned int > spikeVolume;
- for (unsigned int i=0; i<m_Parameters.m_Spikes; i++)
+ for (unsigned int i=0; i<m_Parameters.m_SignalGen.m_Spikes; i++)
spikeVolume.push_back(m_RandGen->GetIntegerVariate()%images.at(0)->GetVectorLength());
std::sort (spikeVolume.begin(), spikeVolume.end());
std::reverse (spikeVolume.begin(), spikeVolume.end());
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
unsigned long lastTick = 0;
boost::progress_display disp(2*images.at(0)->GetVectorLength()*images.at(0)->GetLargestPossibleRegion().GetSize(2));
for (unsigned int g=0; g<images.at(0)->GetVectorLength(); g++)
{
std::vector< unsigned int > spikeSlice;
while (!spikeVolume.empty() && spikeVolume.back()==g)
{
spikeSlice.push_back(m_RandGen->GetIntegerVariate()%images.at(0)->GetLargestPossibleRegion().GetSize(2));
spikeVolume.pop_back();
}
std::sort (spikeSlice.begin(), spikeSlice.end());
std::reverse (spikeSlice.begin(), spikeSlice.end());
for (unsigned int z=0; z<images.at(0)->GetLargestPossibleRegion().GetSize(2); z++)
{
std::vector< SliceType::Pointer > compartmentSlices;
std::vector< double > t2Vector;
for (unsigned int i=0; i<images.size(); i++)
{
DiffusionSignalModel<double>* signalModel;
if (i<numFiberCompartments)
signalModel = m_Parameters.m_FiberModelList.at(i);
else
signalModel = m_Parameters.m_NonFiberModelList.at(i-numFiberCompartments);
SliceType::Pointer slice = SliceType::New();
slice->SetLargestPossibleRegion( sliceRegion );
slice->SetBufferedRegion( sliceRegion );
slice->SetRequestedRegion( sliceRegion );
slice->SetSpacing(sliceSpacing);
slice->Allocate();
slice->FillBuffer(0.0);
// extract slice from channel g
for (unsigned int y=0; y<images.at(0)->GetLargestPossibleRegion().GetSize(1); y++)
for (unsigned int x=0; x<images.at(0)->GetLargestPossibleRegion().GetSize(0); x++)
{
SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y;
DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z;
slice->SetPixel(index2D, images.at(i)->GetPixel(index3D)[g]);
if (fMapSlice.IsNotNull() && i==0)
- fMapSlice->SetPixel(index2D, m_Parameters.m_FrequencyMap->GetPixel(index3D));
+ fMapSlice->SetPixel(index2D, m_Parameters.m_SignalGen.m_FrequencyMap->GetPixel(index3D));
}
compartmentSlices.push_back(slice);
t2Vector.push_back(signalModel->GetT2());
}
if (this->GetAbortGenerateData())
return NULL;
// create k-sapce (inverse fourier transform slices)
- itk::Size<2> outSize; outSize.SetElement(0, m_Parameters.m_ImageRegion.GetSize(0)); outSize.SetElement(1, m_Parameters.m_ImageRegion.GetSize(1));
+ itk::Size<2> outSize; outSize.SetElement(0, m_Parameters.m_SignalGen.m_ImageRegion.GetSize(0)); outSize.SetElement(1, m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1));
itk::KspaceImageFilter< SliceType::PixelType >::Pointer idft = itk::KspaceImageFilter< SliceType::PixelType >::New();
idft->SetCompartmentImages(compartmentSlices);
idft->SetT2(t2Vector);
idft->SetUseConstantRandSeed(m_UseConstantRandSeed);
idft->SetParameters(m_Parameters);
idft->SetZ((double)z-(double)images.at(0)->GetLargestPossibleRegion().GetSize(2)/2.0);
- idft->SetDiffusionGradientDirection(m_Parameters.GetGradientDirection(g));
+ idft->SetDiffusionGradientDirection(m_Parameters.m_SignalGen.GetGradientDirection(g));
idft->SetFrequencyMapSlice(fMapSlice);
idft->SetOutSize(outSize);
int numSpikes = 0;
while (!spikeSlice.empty() && spikeSlice.back()==z)
{
numSpikes++;
spikeSlice.pop_back();
}
idft->SetSpikesPerSlice(numSpikes);
idft->Update();
ComplexSliceType::Pointer fSlice;
fSlice = idft->GetOutput();
++disp;
unsigned long newTick = 50*disp.count()/disp.expected_count();
for (unsigned long tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
// fourier transform slice
SliceType::Pointer newSlice;
itk::DftImageFilter< SliceType::PixelType >::Pointer dft = itk::DftImageFilter< SliceType::PixelType >::New();
dft->SetInput(fSlice);
dft->Update();
newSlice = dft->GetOutput();
// put slice back into channel g
for (unsigned int y=0; y<fSlice->GetLargestPossibleRegion().GetSize(1); y++)
for (unsigned int x=0; x<fSlice->GetLargestPossibleRegion().GetSize(0); x++)
{
DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z;
SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y;
DoubleDwiType::PixelType pix3D = newImage->GetPixel(index3D);
pix3D[g] = newSlice->GetPixel(index2D);
newImage->SetPixel(index3D, pix3D);
}
++disp;
newTick = 50*disp.count()/disp.expected_count();
for (unsigned long tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
}
}
m_StatusText += "\n\n";
return newImage;
}
template< class PixelType >
void TractsToDWIImageFilter< PixelType >::GenerateData()
{
m_TimeProbe.Start();
m_StatusText = "Starting simulation\n";
// check input data
if (m_FiberBundle.IsNull())
itkExceptionMacro("Input fiber bundle is NULL!");
if (m_Parameters.m_FiberModelList.empty())
itkExceptionMacro("No diffusion model for fiber compartments defined!");
if (m_Parameters.m_NonFiberModelList.empty())
itkExceptionMacro("No diffusion model for non-fiber compartments defined!");
- int baselineIndex = m_Parameters.GetFirstBaselineIndex();
+ int baselineIndex = m_Parameters.m_SignalGen.GetFirstBaselineIndex();
if (baselineIndex<0)
itkExceptionMacro("No baseline index found!");
- if (!m_Parameters.m_SimulateKspaceAcquisition)
- m_Parameters.m_DoAddGibbsRinging = false;
+ if (!m_Parameters.m_SignalGen.m_SimulateKspaceAcquisition)
+ m_Parameters.m_SignalGen.m_DoAddGibbsRinging = false;
if (m_UseConstantRandSeed) // always generate the same random numbers?
m_RandGen->SetSeed(0);
else
m_RandGen->SetSeed();
// initialize output dwi image
- ImageRegion<3> croppedRegion = m_Parameters.m_ImageRegion; croppedRegion.SetSize(1, croppedRegion.GetSize(1)*m_Parameters.m_CroppingFactor);
- itk::Point<double,3> shiftedOrigin = m_Parameters.m_ImageOrigin; shiftedOrigin[1] += (m_Parameters.m_ImageRegion.GetSize(1)-croppedRegion.GetSize(1))*m_Parameters.m_ImageSpacing[1]/2;
+ ImageRegion<3> croppedRegion = m_Parameters.m_SignalGen.m_ImageRegion; croppedRegion.SetSize(1, croppedRegion.GetSize(1)*m_Parameters.m_SignalGen.m_CroppingFactor);
+ itk::Point<double,3> shiftedOrigin = m_Parameters.m_SignalGen.m_ImageOrigin; shiftedOrigin[1] += (m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1)-croppedRegion.GetSize(1))*m_Parameters.m_SignalGen.m_ImageSpacing[1]/2;
typename OutputImageType::Pointer outImage = OutputImageType::New();
- outImage->SetSpacing( m_Parameters.m_ImageSpacing );
+ outImage->SetSpacing( m_Parameters.m_SignalGen.m_ImageSpacing );
outImage->SetOrigin( shiftedOrigin );
- outImage->SetDirection( m_Parameters.m_ImageDirection );
+ outImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
outImage->SetLargestPossibleRegion( croppedRegion );
outImage->SetBufferedRegion( croppedRegion );
outImage->SetRequestedRegion( croppedRegion );
- outImage->SetVectorLength( m_Parameters.GetNumVolumes() );
+ outImage->SetVectorLength( m_Parameters.m_SignalGen.GetNumVolumes() );
outImage->Allocate();
typename OutputImageType::PixelType temp;
- temp.SetSize(m_Parameters.GetNumVolumes());
+ temp.SetSize(m_Parameters.m_SignalGen.GetNumVolumes());
temp.Fill(0.0);
outImage->FillBuffer(temp);
// ADJUST GEOMETRY FOR FURTHER PROCESSING
// is input slize size a power of two?
- unsigned int x=m_Parameters.m_ImageRegion.GetSize(0); unsigned int y=m_Parameters.m_ImageRegion.GetSize(1);
+ unsigned int x=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(0); unsigned int y=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1);
ItkDoubleImgType::SizeType pad; pad[0]=x%2; pad[1]=y%2; pad[2]=0;
- m_Parameters.m_ImageRegion.SetSize(0, x+pad[0]);
- m_Parameters.m_ImageRegion.SetSize(1, y+pad[1]);
- if (m_Parameters.m_FrequencyMap.IsNotNull() && (pad[0]>0 || pad[1]>0))
+ m_Parameters.m_SignalGen.m_ImageRegion.SetSize(0, x+pad[0]);
+ m_Parameters.m_SignalGen.m_ImageRegion.SetSize(1, y+pad[1]);
+ if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull() && (pad[0]>0 || pad[1]>0))
{
itk::ConstantPadImageFilter<ItkDoubleImgType, ItkDoubleImgType>::Pointer zeroPadder = itk::ConstantPadImageFilter<ItkDoubleImgType, ItkDoubleImgType>::New();
- zeroPadder->SetInput(m_Parameters.m_FrequencyMap);
+ zeroPadder->SetInput(m_Parameters.m_SignalGen.m_FrequencyMap);
zeroPadder->SetConstant(0);
zeroPadder->SetPadUpperBound(pad);
zeroPadder->Update();
- m_Parameters.m_FrequencyMap = zeroPadder->GetOutput();
+ m_Parameters.m_SignalGen.m_FrequencyMap = zeroPadder->GetOutput();
}
- if (m_Parameters.m_MaskImage.IsNotNull() && (pad[0]>0 || pad[1]>0))
+ if (m_Parameters.m_SignalGen.m_MaskImage.IsNotNull() && (pad[0]>0 || pad[1]>0))
{
itk::ConstantPadImageFilter<ItkUcharImgType, ItkUcharImgType>::Pointer zeroPadder = itk::ConstantPadImageFilter<ItkUcharImgType, ItkUcharImgType>::New();
- zeroPadder->SetInput(m_Parameters.m_MaskImage);
+ zeroPadder->SetInput(m_Parameters.m_SignalGen.m_MaskImage);
zeroPadder->SetConstant(0);
zeroPadder->SetPadUpperBound(pad);
zeroPadder->Update();
- m_Parameters.m_MaskImage = zeroPadder->GetOutput();
+ m_Parameters.m_SignalGen.m_MaskImage = zeroPadder->GetOutput();
}
// Apply in-plane upsampling for Gibbs ringing artifact
double upsampling = 1;
- if (m_Parameters.m_DoAddGibbsRinging)
+ if (m_Parameters.m_SignalGen.m_DoAddGibbsRinging)
upsampling = 2;
- m_UpsampledSpacing = m_Parameters.m_ImageSpacing;
+ m_UpsampledSpacing = m_Parameters.m_SignalGen.m_ImageSpacing;
m_UpsampledSpacing[0] /= upsampling;
m_UpsampledSpacing[1] /= upsampling;
- m_UpsampledImageRegion = m_Parameters.m_ImageRegion;
- m_UpsampledImageRegion.SetSize(0, m_Parameters.m_ImageRegion.GetSize()[0]*upsampling);
- m_UpsampledImageRegion.SetSize(1, m_Parameters.m_ImageRegion.GetSize()[1]*upsampling);
- m_UpsampledOrigin = m_Parameters.m_ImageOrigin;
- m_UpsampledOrigin[0] -= m_Parameters.m_ImageSpacing[0]/2; m_UpsampledOrigin[0] += m_UpsampledSpacing[0]/2;
- m_UpsampledOrigin[1] -= m_Parameters.m_ImageSpacing[1]/2; m_UpsampledOrigin[1] += m_UpsampledSpacing[1]/2;
- m_UpsampledOrigin[2] -= m_Parameters.m_ImageSpacing[2]/2; m_UpsampledOrigin[2] += m_UpsampledSpacing[2]/2;
+ m_UpsampledImageRegion = m_Parameters.m_SignalGen.m_ImageRegion;
+ m_UpsampledImageRegion.SetSize(0, m_Parameters.m_SignalGen.m_ImageRegion.GetSize()[0]*upsampling);
+ m_UpsampledImageRegion.SetSize(1, m_Parameters.m_SignalGen.m_ImageRegion.GetSize()[1]*upsampling);
+ m_UpsampledOrigin = m_Parameters.m_SignalGen.m_ImageOrigin;
+ m_UpsampledOrigin[0] -= m_Parameters.m_SignalGen.m_ImageSpacing[0]/2; m_UpsampledOrigin[0] += m_UpsampledSpacing[0]/2;
+ m_UpsampledOrigin[1] -= m_Parameters.m_SignalGen.m_ImageSpacing[1]/2; m_UpsampledOrigin[1] += m_UpsampledSpacing[1]/2;
+ m_UpsampledOrigin[2] -= m_Parameters.m_SignalGen.m_ImageSpacing[2]/2; m_UpsampledOrigin[2] += m_UpsampledSpacing[2]/2;
// generate double images to store the individual compartment signals
m_CompartmentImages.clear();
int numFiberCompartments = m_Parameters.m_FiberModelList.size();
int numNonFiberCompartments = m_Parameters.m_NonFiberModelList.size();
for (int i=0; i<numFiberCompartments+numNonFiberCompartments; i++)
{
DoubleDwiType::Pointer doubleDwi = DoubleDwiType::New();
doubleDwi->SetSpacing( m_UpsampledSpacing );
doubleDwi->SetOrigin( m_UpsampledOrigin );
- doubleDwi->SetDirection( m_Parameters.m_ImageDirection );
+ doubleDwi->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
doubleDwi->SetLargestPossibleRegion( m_UpsampledImageRegion );
doubleDwi->SetBufferedRegion( m_UpsampledImageRegion );
doubleDwi->SetRequestedRegion( m_UpsampledImageRegion );
- doubleDwi->SetVectorLength( m_Parameters.GetNumVolumes() );
+ doubleDwi->SetVectorLength( m_Parameters.m_SignalGen.GetNumVolumes() );
doubleDwi->Allocate();
DoubleDwiType::PixelType pix;
- pix.SetSize(m_Parameters.GetNumVolumes());
+ pix.SetSize(m_Parameters.m_SignalGen.GetNumVolumes());
pix.Fill(0.0);
doubleDwi->FillBuffer(pix);
m_CompartmentImages.push_back(doubleDwi);
}
// initialize output volume fraction images
m_VolumeFractions.clear();
for (int i=0; i<numFiberCompartments+numNonFiberCompartments; i++)
{
ItkDoubleImgType::Pointer doubleImg = ItkDoubleImgType::New();
doubleImg->SetSpacing( m_UpsampledSpacing );
doubleImg->SetOrigin( m_UpsampledOrigin );
- doubleImg->SetDirection( m_Parameters.m_ImageDirection );
+ doubleImg->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
doubleImg->SetLargestPossibleRegion( m_UpsampledImageRegion );
doubleImg->SetBufferedRegion( m_UpsampledImageRegion );
doubleImg->SetRequestedRegion( m_UpsampledImageRegion );
doubleImg->Allocate();
doubleImg->FillBuffer(0);
m_VolumeFractions.push_back(doubleImg);
}
// get volume fraction images
ItkDoubleImgType::Pointer sumImage = ItkDoubleImgType::New();
bool foundVolumeFractionImage = false;
for (int i=0; i<numNonFiberCompartments; i++) // look if a volume fraction image is set
{
if (m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage().IsNotNull())
{
foundVolumeFractionImage = true;
itk::ConstantPadImageFilter<ItkDoubleImgType, ItkDoubleImgType>::Pointer zeroPadder = itk::ConstantPadImageFilter<ItkDoubleImgType, ItkDoubleImgType>::New();
zeroPadder->SetInput(m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage());
zeroPadder->SetConstant(0);
zeroPadder->SetPadUpperBound(pad);
zeroPadder->Update();
m_Parameters.m_NonFiberModelList[i]->SetVolumeFractionImage(zeroPadder->GetOutput());
sumImage->SetSpacing( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetSpacing() );
sumImage->SetOrigin( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetOrigin() );
sumImage->SetDirection( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetDirection() );
sumImage->SetLargestPossibleRegion( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion() );
sumImage->SetBufferedRegion( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion() );
sumImage->SetRequestedRegion( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion() );
sumImage->Allocate();
sumImage->FillBuffer(0);
break;
}
}
if (!foundVolumeFractionImage)
{
sumImage->SetSpacing( m_UpsampledSpacing );
sumImage->SetOrigin( m_UpsampledOrigin );
- sumImage->SetDirection( m_Parameters.m_ImageDirection );
+ sumImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
sumImage->SetLargestPossibleRegion( m_UpsampledImageRegion );
sumImage->SetBufferedRegion( m_UpsampledImageRegion );
sumImage->SetRequestedRegion( m_UpsampledImageRegion );
sumImage->Allocate();
sumImage->FillBuffer(0.0);
}
for (int i=0; i<numNonFiberCompartments; i++)
{
if (m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage().IsNull())
{
ItkDoubleImgType::Pointer doubleImg = ItkDoubleImgType::New();
doubleImg->SetSpacing( sumImage->GetSpacing() );
doubleImg->SetOrigin( sumImage->GetOrigin() );
doubleImg->SetDirection( sumImage->GetDirection() );
doubleImg->SetLargestPossibleRegion( sumImage->GetLargestPossibleRegion() );
doubleImg->SetBufferedRegion( sumImage->GetLargestPossibleRegion() );
doubleImg->SetRequestedRegion( sumImage->GetLargestPossibleRegion() );
doubleImg->Allocate();
doubleImg->FillBuffer(1.0/numNonFiberCompartments);
m_Parameters.m_NonFiberModelList[i]->SetVolumeFractionImage(doubleImg);
}
ImageRegionIterator<ItkDoubleImgType> it(m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage(), m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion());
while(!it.IsAtEnd())
{
sumImage->SetPixel(it.GetIndex(), sumImage->GetPixel(it.GetIndex())+it.Get());
++it;
}
}
for (int i=0; i<numNonFiberCompartments; i++)
{
ImageRegionIterator<ItkDoubleImgType> it(m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage(), m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion());
while(!it.IsAtEnd())
{
if (sumImage->GetPixel(it.GetIndex())>0)
it.Set(it.Get()/sumImage->GetPixel(it.GetIndex()));
++it;
}
}
// resample mask image and frequency map to fit upsampled geometry
- if (m_Parameters.m_DoAddGibbsRinging)
+ if (m_Parameters.m_SignalGen.m_DoAddGibbsRinging)
{
- if (m_Parameters.m_MaskImage.IsNotNull())
+ if (m_Parameters.m_SignalGen.m_MaskImage.IsNotNull())
{
// rescale mask image (otherwise there are problems with the resampling)
itk::RescaleIntensityImageFilter<ItkUcharImgType,ItkUcharImgType>::Pointer rescaler = itk::RescaleIntensityImageFilter<ItkUcharImgType,ItkUcharImgType>::New();
- rescaler->SetInput(0,m_Parameters.m_MaskImage);
+ rescaler->SetInput(0,m_Parameters.m_SignalGen.m_MaskImage);
rescaler->SetOutputMaximum(100);
rescaler->SetOutputMinimum(0);
rescaler->Update();
// resample mask image
itk::ResampleImageFilter<ItkUcharImgType, ItkUcharImgType>::Pointer resampler = itk::ResampleImageFilter<ItkUcharImgType, ItkUcharImgType>::New();
resampler->SetInput(rescaler->GetOutput());
- resampler->SetOutputParametersFromImage(m_Parameters.m_MaskImage);
+ resampler->SetOutputParametersFromImage(m_Parameters.m_SignalGen.m_MaskImage);
resampler->SetSize(m_UpsampledImageRegion.GetSize());
resampler->SetOutputSpacing(m_UpsampledSpacing);
resampler->SetOutputOrigin(m_UpsampledOrigin);
itk::NearestNeighborInterpolateImageFunction<ItkUcharImgType, double>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<ItkUcharImgType, double>::New();
resampler->SetInterpolator(nn_interpolator);
resampler->Update();
- m_Parameters.m_MaskImage = resampler->GetOutput();
+ m_Parameters.m_SignalGen.m_MaskImage = resampler->GetOutput();
itk::ImageFileWriter<ItkUcharImgType>::Pointer w = itk::ImageFileWriter<ItkUcharImgType>::New();
w->SetFileName("/local/mask_ups.nrrd");
- w->SetInput(m_Parameters.m_MaskImage);
+ w->SetInput(m_Parameters.m_SignalGen.m_MaskImage);
w->Update();
}
// resample frequency map
- if (m_Parameters.m_FrequencyMap.IsNotNull())
+ if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull())
{
itk::ResampleImageFilter<ItkDoubleImgType, ItkDoubleImgType>::Pointer resampler = itk::ResampleImageFilter<ItkDoubleImgType, ItkDoubleImgType>::New();
- resampler->SetInput(m_Parameters.m_FrequencyMap);
- resampler->SetOutputParametersFromImage(m_Parameters.m_FrequencyMap);
+ resampler->SetInput(m_Parameters.m_SignalGen.m_FrequencyMap);
+ resampler->SetOutputParametersFromImage(m_Parameters.m_SignalGen.m_FrequencyMap);
resampler->SetSize(m_UpsampledImageRegion.GetSize());
resampler->SetOutputSpacing(m_UpsampledSpacing);
resampler->SetOutputOrigin(m_UpsampledOrigin);
itk::NearestNeighborInterpolateImageFunction<ItkDoubleImgType, double>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<ItkDoubleImgType, double>::New();
resampler->SetInterpolator(nn_interpolator);
resampler->Update();
- m_Parameters.m_FrequencyMap = resampler->GetOutput();
+ m_Parameters.m_SignalGen.m_FrequencyMap = resampler->GetOutput();
}
}
// no input tissue mask is set -> create default
- bool maskImageSet = true;
- if (m_Parameters.m_MaskImage.IsNull())
+ m_MaskImageSet = true;
+ if (m_Parameters.m_SignalGen.m_MaskImage.IsNull())
{
m_StatusText += "No tissue mask set\n";
MITK_INFO << "No tissue mask set";
- m_Parameters.m_MaskImage = ItkUcharImgType::New();
- m_Parameters.m_MaskImage->SetSpacing( m_UpsampledSpacing );
- m_Parameters.m_MaskImage->SetOrigin( m_UpsampledOrigin );
- m_Parameters.m_MaskImage->SetDirection( m_Parameters.m_ImageDirection );
- m_Parameters.m_MaskImage->SetLargestPossibleRegion( m_UpsampledImageRegion );
- m_Parameters.m_MaskImage->SetBufferedRegion( m_UpsampledImageRegion );
- m_Parameters.m_MaskImage->SetRequestedRegion( m_UpsampledImageRegion );
- m_Parameters.m_MaskImage->Allocate();
- m_Parameters.m_MaskImage->FillBuffer(1);
- maskImageSet = false;
+ m_Parameters.m_SignalGen.m_MaskImage = ItkUcharImgType::New();
+ m_Parameters.m_SignalGen.m_MaskImage->SetSpacing( m_UpsampledSpacing );
+ m_Parameters.m_SignalGen.m_MaskImage->SetOrigin( m_UpsampledOrigin );
+ m_Parameters.m_SignalGen.m_MaskImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
+ m_Parameters.m_SignalGen.m_MaskImage->SetLargestPossibleRegion( m_UpsampledImageRegion );
+ m_Parameters.m_SignalGen.m_MaskImage->SetBufferedRegion( m_UpsampledImageRegion );
+ m_Parameters.m_SignalGen.m_MaskImage->SetRequestedRegion( m_UpsampledImageRegion );
+ m_Parameters.m_SignalGen.m_MaskImage->Allocate();
+ m_Parameters.m_SignalGen.m_MaskImage->FillBuffer(1);
+ m_MaskImageSet = false;
}
else
{
m_StatusText += "Using tissue mask\n";
MITK_INFO << "Using tissue mask";
}
- m_Parameters.m_ImageRegion = croppedRegion;
- x=m_Parameters.m_ImageRegion.GetSize(0); y=m_Parameters.m_ImageRegion.GetSize(1);
+ m_Parameters.m_SignalGen.m_ImageRegion = croppedRegion;
+ x=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(0); y=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1);
if ( x%2 == 1 )
- m_Parameters.m_ImageRegion.SetSize(0, x+1);
+ m_Parameters.m_SignalGen.m_ImageRegion.SetSize(0, x+1);
if ( y%2 == 1 )
- m_Parameters.m_ImageRegion.SetSize(1, y+1);
+ m_Parameters.m_SignalGen.m_ImageRegion.SetSize(1, y+1);
// resample fiber bundle for sufficient voxel coverage
m_StatusText += "\n"+this->GetTime()+" > Resampling fibers ...\n";
double segmentVolume = 0.0001;
float minSpacing = 1;
if(m_UpsampledSpacing[0]<m_UpsampledSpacing[1] && m_UpsampledSpacing[0]<m_UpsampledSpacing[2])
minSpacing = m_UpsampledSpacing[0];
else if (m_UpsampledSpacing[1] < m_UpsampledSpacing[2])
minSpacing = m_UpsampledSpacing[1];
else
minSpacing = m_UpsampledSpacing[2];
- FiberBundleType fiberBundle = m_FiberBundle->GetDeepCopy();
+ m_FiberBundleWorkingCopy = m_FiberBundle->GetDeepCopy();
double volumeAccuracy = 10;
- fiberBundle->ResampleFibers(minSpacing/volumeAccuracy);
- double mmRadius = m_Parameters.m_AxonRadius/1000;
+ m_FiberBundleWorkingCopy->ResampleFibers(minSpacing/volumeAccuracy);
+ double mmRadius = m_Parameters.m_SignalGen.m_AxonRadius/1000;
if (mmRadius>0)
segmentVolume = M_PI*mmRadius*mmRadius*minSpacing/volumeAccuracy;
double maxVolume = 0;
- double voxelVolume = m_UpsampledSpacing[0]*m_UpsampledSpacing[1]*m_UpsampledSpacing[2];
+ m_VoxelVolume = m_UpsampledSpacing[0]*m_UpsampledSpacing[1]*m_UpsampledSpacing[2];
- ofstream logFile;
- if (m_Parameters.m_DoAddMotion)
+ if (m_Parameters.m_SignalGen.m_DoAddMotion)
{
std::string fileName = "fiberfox_motion_0.log";
std::string filePath = mitk::IOUtil::GetTempPath();
- if (m_Parameters.m_OutputPath.size()>0)
- filePath = m_Parameters.m_OutputPath;
+ if (m_Parameters.m_Misc.m_OutputPath.size()>0)
+ filePath = m_Parameters.m_Misc.m_OutputPath;
int c = 1;
while (itksys::SystemTools::FileExists((filePath+fileName).c_str()))
{
fileName = "fiberfox_motion_";
fileName += boost::lexical_cast<std::string>(c);
fileName += ".log";
c++;
}
- logFile.open((filePath+fileName).c_str());
- logFile << "0 rotation: 0,0,0; translation: 0,0,0\n";
+ m_Logfile.open((filePath+fileName).c_str());
+ m_Logfile << "0 rotation: 0,0,0; translation: 0,0,0\n";
- if (m_Parameters.m_DoRandomizeMotion)
+ if (m_Parameters.m_SignalGen.m_DoRandomizeMotion)
{
m_StatusText += "Adding random motion artifacts:\n";
- m_StatusText += "Maximum rotation: +/-" + boost::lexical_cast<std::string>(m_Parameters.m_Rotation) + "°\n";
- m_StatusText += "Maximum translation: +/-" + boost::lexical_cast<std::string>(m_Parameters.m_Translation) + "mm\n";
+ m_StatusText += "Maximum rotation: +/-" + boost::lexical_cast<std::string>(m_Parameters.m_SignalGen.m_Rotation) + "°\n";
+ m_StatusText += "Maximum translation: +/-" + boost::lexical_cast<std::string>(m_Parameters.m_SignalGen.m_Translation) + "mm\n";
}
else
{
m_StatusText += "Adding linear motion artifacts:\n";
- m_StatusText += "Maximum rotation: " + boost::lexical_cast<std::string>(m_Parameters.m_Rotation) + "°\n";
- m_StatusText += "Maximum translation: " + boost::lexical_cast<std::string>(m_Parameters.m_Translation) + "mm\n";
+ m_StatusText += "Maximum rotation: " + boost::lexical_cast<std::string>(m_Parameters.m_SignalGen.m_Rotation) + "°\n";
+ m_StatusText += "Maximum translation: " + boost::lexical_cast<std::string>(m_Parameters.m_SignalGen.m_Translation) + "mm\n";
}
m_StatusText += "Motion logfile: " + (filePath+fileName) + "\n";
MITK_INFO << "Adding motion artifacts";
- MITK_INFO << "Maximum rotation: " << m_Parameters.m_Rotation;
- MITK_INFO << "Maxmimum translation: " << m_Parameters.m_Translation;
+ MITK_INFO << "Maximum rotation: " << m_Parameters.m_SignalGen.m_Rotation;
+ MITK_INFO << "Maxmimum translation: " << m_Parameters.m_SignalGen.m_Translation;
}
maxVolume = 0;
m_StatusText += "\n"+this->GetTime()+" > Generating " + boost::lexical_cast<std::string>(numFiberCompartments+numNonFiberCompartments) + "-compartment diffusion-weighted signal.\n";
+ MITK_INFO << "Generating " << numFiberCompartments+numNonFiberCompartments << "-compartment diffusion-weighted signal.";
int numFibers = m_FiberBundle->GetNumFibers();
- boost::progress_display disp(numFibers*m_Parameters.GetNumVolumes());
+ boost::progress_display disp(numFibers*m_Parameters.m_SignalGen.GetNumVolumes());
// get transform for motion artifacts
- FiberBundleType fiberBundleTransformed = fiberBundle;
- DoubleVectorType rotation = m_Parameters.m_Rotation/m_Parameters.GetNumVolumes();
- DoubleVectorType translation = m_Parameters.m_Translation/m_Parameters.GetNumVolumes();
+ m_FiberBundleTransformed = m_FiberBundleWorkingCopy;
+ m_Rotation = m_Parameters.m_SignalGen.m_Rotation/m_Parameters.m_SignalGen.GetNumVolumes();
+ m_Translation = m_Parameters.m_SignalGen.m_Translation/m_Parameters.m_SignalGen.GetNumVolumes();
// creat image to hold transformed mask (motion artifact)
- ItkUcharImgType::Pointer tempTissueMask = ItkUcharImgType::New();
+ m_MaskImage = ItkUcharImgType::New();
itk::ImageDuplicator<ItkUcharImgType>::Pointer duplicator = itk::ImageDuplicator<ItkUcharImgType>::New();
- duplicator->SetInputImage(m_Parameters.m_MaskImage);
+ duplicator->SetInputImage(m_Parameters.m_SignalGen.m_MaskImage);
duplicator->Update();
- tempTissueMask = duplicator->GetOutput();
+ m_MaskImage = duplicator->GetOutput();
// second upsampling needed for motion artifacts
- ImageRegion<3> upsampledImageRegion = m_UpsampledImageRegion;
- DoubleVectorType upsampledSpacing = m_UpsampledSpacing;
+ ImageRegion<3> upsampledImageRegion = m_UpsampledImageRegion;
+ DoubleVectorType upsampledSpacing = m_UpsampledSpacing;
upsampledSpacing[0] /= 4;
upsampledSpacing[1] /= 4;
upsampledSpacing[2] /= 4;
upsampledImageRegion.SetSize(0, m_UpsampledImageRegion.GetSize()[0]*4);
upsampledImageRegion.SetSize(1, m_UpsampledImageRegion.GetSize()[1]*4);
upsampledImageRegion.SetSize(2, m_UpsampledImageRegion.GetSize()[2]*4);
itk::Point<double,3> upsampledOrigin = m_UpsampledOrigin;
upsampledOrigin[0] -= m_UpsampledSpacing[0]/2; upsampledOrigin[0] += upsampledSpacing[0]/2;
upsampledOrigin[1] -= m_UpsampledSpacing[1]/2; upsampledOrigin[1] += upsampledSpacing[1]/2;
upsampledOrigin[2] -= m_UpsampledSpacing[2]/2; upsampledOrigin[2] += upsampledSpacing[2]/2;
- ItkUcharImgType::Pointer upsampledTissueMask = ItkUcharImgType::New();
+ m_UpsampledMaskImage = ItkUcharImgType::New();
itk::ResampleImageFilter<ItkUcharImgType, ItkUcharImgType>::Pointer upsampler = itk::ResampleImageFilter<ItkUcharImgType, ItkUcharImgType>::New();
- upsampler->SetInput(m_Parameters.m_MaskImage);
- upsampler->SetOutputParametersFromImage(m_Parameters.m_MaskImage);
+ upsampler->SetInput(m_Parameters.m_SignalGen.m_MaskImage);
+ upsampler->SetOutputParametersFromImage(m_Parameters.m_SignalGen.m_MaskImage);
upsampler->SetSize(upsampledImageRegion.GetSize());
upsampler->SetOutputSpacing(upsampledSpacing);
upsampler->SetOutputOrigin(upsampledOrigin);
itk::NearestNeighborInterpolateImageFunction<ItkUcharImgType, double>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<ItkUcharImgType, double>::New();
upsampler->SetInterpolator(nn_interpolator);
upsampler->Update();
- upsampledTissueMask = upsampler->GetOutput();
+ m_UpsampledMaskImage = upsampler->GetOutput();
unsigned long lastTick = 0;
- switch (m_Parameters.m_DiffusionDirectionMode)
+ int signalModelSeed = m_RandGen->GetIntegerVariate();
+ switch (m_Parameters.m_SignalGen.m_DiffusionDirectionMode)
{
- case(FiberfoxParameters<>::FIBER_TANGENT_DIRECTIONS):
+ case(SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS): // use fiber tangent directions to determine diffusion direction
{
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
- for (unsigned int g=0; g<m_Parameters.GetNumVolumes(); g++)
+ for (unsigned int g=0; g<m_Parameters.m_SignalGen.GetNumVolumes(); g++)
{
+ // Set signal model random generator seeds to get same configuration in each voxel
+ for (int i=0; i<m_Parameters.m_FiberModelList.size(); i++)
+ m_Parameters.m_FiberModelList.at(i)->SetSeed(signalModelSeed);
+ for (int i=0; i<m_Parameters.m_NonFiberModelList.size(); i++)
+ m_Parameters.m_NonFiberModelList.at(i)->SetSeed(signalModelSeed);
+
ItkDoubleImgType::Pointer intraAxonalVolumeImage = ItkDoubleImgType::New();
intraAxonalVolumeImage->SetSpacing( m_UpsampledSpacing );
intraAxonalVolumeImage->SetOrigin( m_UpsampledOrigin );
- intraAxonalVolumeImage->SetDirection( m_Parameters.m_ImageDirection );
+ intraAxonalVolumeImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
intraAxonalVolumeImage->SetLargestPossibleRegion( m_UpsampledImageRegion );
intraAxonalVolumeImage->SetBufferedRegion( m_UpsampledImageRegion );
intraAxonalVolumeImage->SetRequestedRegion( m_UpsampledImageRegion );
intraAxonalVolumeImage->Allocate();
intraAxonalVolumeImage->FillBuffer(0);
- vtkPolyData* fiberPolyData = fiberBundleTransformed->GetFiberPolyData();
+ vtkPolyData* fiberPolyData = m_FiberBundleTransformed->GetFiberPolyData();
// generate fiber signal (if there are any fiber models present)
if (!m_Parameters.m_FiberModelList.empty())
for( int i=0; i<numFibers; i++ )
{
vtkCell* cell = fiberPolyData->GetCell(i);
int numPoints = cell->GetNumberOfPoints();
vtkPoints* points = cell->GetPoints();
if (numPoints<2)
continue;
for( int j=0; j<numPoints; j++)
{
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
double* temp = points->GetPoint(j);
itk::Point<float, 3> vertex = GetItkPoint(temp);
itk::Vector<double> v = GetItkVector(temp);
itk::Vector<double, 3> dir(3);
if (j<numPoints-1)
dir = GetItkVector(points->GetPoint(j+1))-v;
else
dir = v-GetItkVector(points->GetPoint(j-1));
if (dir.GetSquaredNorm()<0.0001 || dir[0]!=dir[0] || dir[1]!=dir[1] || dir[2]!=dir[2])
continue;
itk::Index<3> idx;
itk::ContinuousIndex<float, 3> contIndex;
- tempTissueMask->TransformPhysicalPointToIndex(vertex, idx);
- tempTissueMask->TransformPhysicalPointToContinuousIndex(vertex, contIndex);
+ m_MaskImage->TransformPhysicalPointToIndex(vertex, idx);
+ m_MaskImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);
- if (!tempTissueMask->GetLargestPossibleRegion().IsInside(idx) || tempTissueMask->GetPixel(idx)<=0)
+ if (!m_MaskImage->GetLargestPossibleRegion().IsInside(idx) || m_MaskImage->GetPixel(idx)<=0)
continue;
// generate signal for each fiber compartment
for (int k=0; k<numFiberCompartments; k++)
{
m_Parameters.m_FiberModelList[k]->SetFiberDirection(dir);
DoubleDwiType::PixelType pix = m_CompartmentImages.at(k)->GetPixel(idx);
pix[g] += segmentVolume*m_Parameters.m_FiberModelList[k]->SimulateMeasurement(g);
m_CompartmentImages.at(k)->SetPixel(idx, pix);
}
// update fiber volume image
double vol = intraAxonalVolumeImage->GetPixel(idx) + segmentVolume;
intraAxonalVolumeImage->SetPixel(idx, vol);
if (g==0 && vol>maxVolume)
maxVolume = vol;
}
// progress report
++disp;
unsigned long newTick = 50*disp.count()/disp.expected_count();
for (unsigned int tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
}
// generate non-fiber signal
- ImageRegionIterator<ItkUcharImgType> it3(tempTissueMask, tempTissueMask->GetLargestPossibleRegion());
+ ImageRegionIterator<ItkUcharImgType> it3(m_MaskImage, m_MaskImage->GetLargestPossibleRegion());
double fact = 1;
- if (m_Parameters.m_AxonRadius<0.0001 || maxVolume>voxelVolume)
- fact = voxelVolume/maxVolume;
+ if (m_Parameters.m_SignalGen.m_AxonRadius<0.0001 || maxVolume>m_VoxelVolume)
+ fact = m_VoxelVolume/maxVolume;
while(!it3.IsAtEnd())
{
if (it3.Get()>0)
{
DoubleDwiType::IndexType index = it3.GetIndex();
- // get fiber volume fraction
- double intraAxonalVolume = intraAxonalVolumeImage->GetPixel(index)*fact;
-
- for (int i=0; i<numFiberCompartments; i++)
- {
- DoubleDwiType::PixelType pix = m_CompartmentImages.at(i)->GetPixel(index);
- pix[g] *= fact;
- m_CompartmentImages.at(i)->SetPixel(index, pix);
- }
-
- if (intraAxonalVolume>0.0001 && m_Parameters.m_DoDisablePartialVolume) // only fiber in voxel
- {
- DoubleDwiType::PixelType pix = m_CompartmentImages.at(0)->GetPixel(index);
- pix[g] *= voxelVolume/intraAxonalVolume;
- m_CompartmentImages.at(0)->SetPixel(index, pix);
- m_VolumeFractions.at(0)->SetPixel(index, 1);
- for (int i=1; i<numFiberCompartments; i++)
+ // adjust intra-axonal signal to abtain an only-fiber voxel
+ if (fabs(fact-1.0)>0.0001)
+ for (int i=0; i<numFiberCompartments; i++)
{
DoubleDwiType::PixelType pix = m_CompartmentImages.at(i)->GetPixel(index);
- pix[g] = 0;
+ pix[g] *= fact;
m_CompartmentImages.at(i)->SetPixel(index, pix);
}
- }
- else
- {
- m_VolumeFractions.at(0)->SetPixel(index, intraAxonalVolume/voxelVolume);
-
- itk::Point<double, 3> point;
- tempTissueMask->TransformIndexToPhysicalPoint(index, point);
- if (m_Parameters.m_DoAddMotion)
- {
- if (m_Parameters.m_DoRandomizeMotion && g>0)
- point = fiberBundle->TransformPoint(point.GetVnlVector(), -rotation[0],-rotation[1],-rotation[2],-translation[0],-translation[1],-translation[2]);
- else
- point = fiberBundle->TransformPoint(point.GetVnlVector(), -rotation[0]*g,-rotation[1]*g,-rotation[2]*g,-translation[0]*g,-translation[1]*g,-translation[2]*g);
- }
-
- if (m_Parameters.m_DoDisablePartialVolume)
- {
- int maxVolumeIndex = 0;
- double maxWeight = 0;
- for (int i=0; i<numNonFiberCompartments; i++)
- {
- double weight = 0;
- if (numNonFiberCompartments>1)
- {
- DoubleDwiType::IndexType newIndex;
- m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->TransformPhysicalPointToIndex(point, newIndex);
- if (!m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion().IsInside(newIndex))
- continue;
- weight = m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetPixel(newIndex);
- }
-
- if (weight>maxWeight)
- {
- maxWeight = weight;
- maxVolumeIndex = i;
- }
- }
- DoubleDwiType::Pointer doubleDwi = m_CompartmentImages.at(maxVolumeIndex+numFiberCompartments);
- DoubleDwiType::PixelType pix = doubleDwi->GetPixel(index);
- pix[g] += m_Parameters.m_NonFiberModelList[maxVolumeIndex]->SimulateMeasurement(g);
- doubleDwi->SetPixel(index, pix);
- m_VolumeFractions.at(maxVolumeIndex+numFiberCompartments)->SetPixel(index, 1);
- }
- else
- {
- double extraAxonalVolume = voxelVolume-intraAxonalVolume; // non-fiber volume
- double interAxonalVolume = 0;
- if (numFiberCompartments>1)
- interAxonalVolume = extraAxonalVolume * intraAxonalVolume/voxelVolume; // inter-axonal fraction of non fiber compartment scales linearly with f
- double other = extraAxonalVolume - interAxonalVolume; // rest of compartment
- double singleinter = interAxonalVolume/(numFiberCompartments-1);
-
- // adjust non-fiber and intra-axonal signal
- for (int i=1; i<numFiberCompartments; i++)
- {
- DoubleDwiType::PixelType pix = m_CompartmentImages.at(i)->GetPixel(index);
- if (intraAxonalVolume>0) // remove scaling by intra-axonal volume from inter-axonal compartment
- pix[g] /= intraAxonalVolume;
- pix[g] *= singleinter;
- m_CompartmentImages.at(i)->SetPixel(index, pix);
- m_VolumeFractions.at(i)->SetPixel(index, singleinter/voxelVolume);
- }
-
- for (int i=0; i<numNonFiberCompartments; i++)
- {
- double weight = 1;
- if (numNonFiberCompartments>1)
- {
- DoubleDwiType::IndexType newIndex;
- m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->TransformPhysicalPointToIndex(point, newIndex);
- if (!m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion().IsInside(newIndex))
- continue;
- weight = m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetPixel(newIndex);
- }
-
- DoubleDwiType::Pointer doubleDwi = m_CompartmentImages.at(i+numFiberCompartments);
- DoubleDwiType::PixelType pix = doubleDwi->GetPixel(index);
-
- pix[g] += m_Parameters.m_NonFiberModelList[i]->SimulateMeasurement(g)*other*weight;
- doubleDwi->SetPixel(index, pix);
- m_VolumeFractions.at(i+numFiberCompartments)->SetPixel(index, other/voxelVolume*weight);
- }
- }
- }
+ // simulate other compartments
+ SimulateNonFiberSignal(index, intraAxonalVolumeImage->GetPixel(index)*fact, g);
}
++it3;
}
// move fibers
- if (m_Parameters.m_DoAddMotion && g<m_Parameters.GetNumVolumes()-1)
- {
- if (m_Parameters.m_DoRandomizeMotion)
- {
- fiberBundleTransformed = fiberBundle->GetDeepCopy();
- rotation[0] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_Rotation[0]*2)-m_Parameters.m_Rotation[0];
- rotation[1] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_Rotation[1]*2)-m_Parameters.m_Rotation[1];
- rotation[2] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_Rotation[2]*2)-m_Parameters.m_Rotation[2];
- translation[0] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_Translation[0]*2)-m_Parameters.m_Translation[0];
- translation[1] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_Translation[1]*2)-m_Parameters.m_Translation[1];
- translation[2] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_Translation[2]*2)-m_Parameters.m_Translation[2];
- }
-
- // rotate mask image
- if (maskImageSet)
- {
- ImageRegionIterator<ItkUcharImgType> maskIt(upsampledTissueMask, upsampledTissueMask->GetLargestPossibleRegion());
- tempTissueMask->FillBuffer(0);
-
- while(!maskIt.IsAtEnd())
- {
- if (maskIt.Get()<=0)
- {
- ++maskIt;
- continue;
- }
-
- DoubleDwiType::IndexType index = maskIt.GetIndex();
- itk::Point<double, 3> point;
- upsampledTissueMask->TransformIndexToPhysicalPoint(index, point);
- if (m_Parameters.m_DoRandomizeMotion)
- point = fiberBundle->TransformPoint(point.GetVnlVector(), rotation[0],rotation[1],rotation[2],translation[0],translation[1],translation[2]);
- else
- point = fiberBundle->TransformPoint(point.GetVnlVector(), rotation[0]*(g+1),rotation[1]*(g+1),rotation[2]*(g+1),translation[0]*(g+1),translation[1]*(g+1),translation[2]*(g+1));
-
- tempTissueMask->TransformPhysicalPointToIndex(point, index);
- if (tempTissueMask->GetLargestPossibleRegion().IsInside(index))
- tempTissueMask->SetPixel(index,100);
- ++maskIt;
- }
- }
-
- // rotate fibers
- if (logFile.is_open())
- {
- logFile << g+1 << " rotation: " << rotation[0] << "," << rotation[1] << "," << rotation[2] << ";";
- logFile << " translation: " << translation[0] << "," << translation[1] << "," << translation[2] << "\n";
- }
- fiberBundleTransformed->TransformFibers(rotation[0],rotation[1],rotation[2],translation[0],translation[1],translation[2]);
- }
+ SimulateMotion(g);
}
break;
}
- case (FiberfoxParameters<>::MAIN_FIBER_DIRECTIONS):
+ case (SignalGenerationParameters::MAIN_FIBER_DIRECTIONS): // use main fiber directions to determine voxel-wise diffusion directions
{
typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
+ // calculate main fiber directions
itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
- fOdfFilter->SetFiberBundle(fiberBundle);
- fOdfFilter->SetMaskImage(tempTissueMask);
- fOdfFilter->SetAngularThreshold(cos(45*M_PI/180));
+ fOdfFilter->SetFiberBundle(m_FiberBundleTransformed);
+ fOdfFilter->SetMaskImage(m_MaskImage);
+ fOdfFilter->SetAngularThreshold(cos(m_Parameters.m_SignalGen.m_FiberSeparationThreshold*M_PI/180.0));
fOdfFilter->SetNormalizeVectors(false);
- fOdfFilter->SetUseWorkingCopy(false);
+ fOdfFilter->SetUseWorkingCopy(true);
fOdfFilter->SetSizeThreshold(0);
fOdfFilter->SetMaxNumDirections(3);
fOdfFilter->Update();
ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();
- {
- ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage();
- typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
- WriterType::Pointer writer = WriterType::New();
- writer->SetFileName("/local/NumDirections.nrrd");
- writer->SetInput(numDirImage);
- writer->Update();
- }
-
+ // allocate image storing intra-axonal volume fraction information
ItkDoubleImgType::Pointer intraAxonalVolumeImage = ItkDoubleImgType::New();
intraAxonalVolumeImage->SetSpacing( m_UpsampledSpacing );
intraAxonalVolumeImage->SetOrigin( m_UpsampledOrigin );
- intraAxonalVolumeImage->SetDirection( m_Parameters.m_ImageDirection );
+ intraAxonalVolumeImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
intraAxonalVolumeImage->SetLargestPossibleRegion( m_UpsampledImageRegion );
intraAxonalVolumeImage->SetBufferedRegion( m_UpsampledImageRegion );
intraAxonalVolumeImage->SetRequestedRegion( m_UpsampledImageRegion );
intraAxonalVolumeImage->Allocate();
intraAxonalVolumeImage->FillBuffer(0);
- itk::TractDensityImageFilter< ItkDoubleImgType >::Pointer generator = itk::TractDensityImageFilter< ItkDoubleImgType >::New();
- generator->SetFiberBundle(fiberBundle);
- generator->SetBinaryOutput(false);
- generator->SetOutputAbsoluteValues(false);
- generator->SetInputImage(intraAxonalVolumeImage);
- generator->SetUseImageGeometry(true);
- generator->Update();
- intraAxonalVolumeImage = generator->GetOutput();
+ // determine intra-axonal volume fraction using the tract density
+ itk::TractDensityImageFilter< ItkDoubleImgType >::Pointer tdiFilter = itk::TractDensityImageFilter< ItkDoubleImgType >::New();
+ tdiFilter->SetFiberBundle(m_FiberBundleTransformed);
+ tdiFilter->SetBinaryOutput(false);
+ tdiFilter->SetOutputAbsoluteValues(false);
+ tdiFilter->SetInputImage(intraAxonalVolumeImage);
+ tdiFilter->SetUseImageGeometry(true);
+ tdiFilter->Update();
+ intraAxonalVolumeImage = tdiFilter->GetOutput();
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
- boost::progress_display disp(tempTissueMask->GetLargestPossibleRegion().GetNumberOfPixels());
- ImageRegionIterator< ItkUcharImgType > it(tempTissueMask, tempTissueMask->GetLargestPossibleRegion());
- while(!it.IsAtEnd())
+ boost::progress_display disp(m_MaskImage->GetLargestPossibleRegion().GetNumberOfPixels()*m_Parameters.m_SignalGen.GetNumVolumes());
+
+ for (unsigned int g=0; g<m_Parameters.m_SignalGen.GetNumVolumes(); g++)
{
- ++disp;
- unsigned long newTick = 50*disp.count()/disp.expected_count();
- for (unsigned int tick = 0; tick<(newTick-lastTick); tick++)
- m_StatusText += "*";
- lastTick = newTick;
+ // Set signal model random generator seeds to get same configuration in each voxel
+ for (int i=0; i<m_Parameters.m_FiberModelList.size(); i++)
+ m_Parameters.m_FiberModelList.at(i)->SetSeed(signalModelSeed);
+ for (int i=0; i<m_Parameters.m_NonFiberModelList.size(); i++)
+ m_Parameters.m_NonFiberModelList.at(i)->SetSeed(signalModelSeed);
- if (this->GetAbortGenerateData())
+ if (m_Parameters.m_SignalGen.m_DoAddMotion && g>0) // if fibers have moved we need a new TDI and new directions
{
- m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
- return;
+ fOdfFilter->SetFiberBundle(m_FiberBundleTransformed);
+ fOdfFilter->SetMaskImage(m_MaskImage);
+ fOdfFilter->Update();
+ directionImageContainer = fOdfFilter->GetDirectionImageContainer();
+
+ tdiFilter->SetFiberBundle(m_FiberBundleTransformed);
+ tdiFilter->Update();
+ intraAxonalVolumeImage = tdiFilter->GetOutput();
}
- if (it.Get()>0)
+ ImageRegionIterator< ItkUcharImgType > it(m_MaskImage, m_MaskImage->GetLargestPossibleRegion());
+ while(!it.IsAtEnd())
{
- int count = 0;
- DoubleDwiType::PixelType pix = m_CompartmentImages.at(0)->GetPixel(it.GetIndex());
- for (unsigned int i=0; i<directionImageContainer->Size(); i++)
+ ++disp;
+ unsigned long newTick = 50*disp.count()/disp.expected_count();
+ for (unsigned int tick = 0; tick<(newTick-lastTick); tick++)
+ m_StatusText += "*";
+ lastTick = newTick;
+
+ if (this->GetAbortGenerateData())
{
- itk::Vector< double, 3> dir;
- dir.CastFrom(directionImageContainer->GetElement(i)->GetPixel(it.GetIndex()));
- double norm = dir.GetNorm();
- if (norm>0.0001)
- {
- int modelIndex = m_RandGen->GetIntegerVariate(m_Parameters.m_FiberModelList.size()-1);
- m_Parameters.m_FiberModelList.at(modelIndex)->SetFiberDirection(dir);
- pix += m_Parameters.m_FiberModelList.at(modelIndex)->SimulateMeasurement()*norm;
- count++;
- }
+ m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
+ return;
}
- if (count>0)
- pix /= count;
- pix *= intraAxonalVolumeImage->GetPixel(it.GetIndex());
- // GM/CSF
+ if (it.Get()>0)
{
- int modelIndex = m_RandGen->GetIntegerVariate(m_Parameters.m_NonFiberModelList.size()-1);
- pix += (1-intraAxonalVolumeImage->GetPixel(it.GetIndex()))*m_Parameters.m_NonFiberModelList.at(modelIndex)->SimulateMeasurement();
- }
+ // generate fiber signal
+ for (int c=0; c<m_Parameters.m_FiberModelList.size(); c++)
+ {
+ int count = 0;
+ DoubleDwiType::PixelType pix = m_CompartmentImages.at(c)->GetPixel(it.GetIndex());
+ for (unsigned int i=0; i<directionImageContainer->Size(); i++)
+ {
+ itk::Vector< double, 3> dir;
+ dir.CastFrom(directionImageContainer->GetElement(i)->GetPixel(it.GetIndex()));
+ double norm = dir.GetNorm();
+ if (norm>0.0001)
+ {
+ m_Parameters.m_FiberModelList.at(c)->SetFiberDirection(dir);
+ pix[g] += m_Parameters.m_FiberModelList.at(c)->SimulateMeasurement(g)*norm;
+ count++;
+ }
+ }
+ if (count>0)
+ pix[g] /= count;
+ pix[g] *= intraAxonalVolumeImage->GetPixel(it.GetIndex())*m_VoxelVolume;
+ m_CompartmentImages.at(c)->SetPixel(it.GetIndex(), pix);
+ }
- m_CompartmentImages.at(0)->SetPixel(it.GetIndex(), pix);
+ // simulate other compartments
+ SimulateNonFiberSignal(it.GetIndex(), intraAxonalVolumeImage->GetPixel(it.GetIndex())*m_VoxelVolume, g);
+ }
+ ++it;
}
- ++it;
+
+ SimulateMotion(g);
}
+
+ itk::ImageFileWriter< ItkUcharImgType >::Pointer wr = itk::ImageFileWriter< ItkUcharImgType >::New();
+ wr->SetInput(fOdfFilter->GetNumDirectionsImage());
+ wr->SetFileName(mitk::IOUtil::GetTempPath()+"/NumDirections_MainFiberDirections.nrrd");
+ wr->Update();
break;
}
- case (FiberfoxParameters<>::RANDOM_DIRECTIONS):
+ case (SignalGenerationParameters::RANDOM_DIRECTIONS):
{
ItkUcharImgType::Pointer numDirectionsImage = ItkUcharImgType::New();
numDirectionsImage->SetSpacing( m_UpsampledSpacing );
numDirectionsImage->SetOrigin( m_UpsampledOrigin );
- numDirectionsImage->SetDirection( m_Parameters.m_ImageDirection );
+ numDirectionsImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection );
numDirectionsImage->SetLargestPossibleRegion( m_UpsampledImageRegion );
numDirectionsImage->SetBufferedRegion( m_UpsampledImageRegion );
numDirectionsImage->SetRequestedRegion( m_UpsampledImageRegion );
numDirectionsImage->Allocate();
numDirectionsImage->FillBuffer(0);
+ double sepAngle = cos(m_Parameters.m_SignalGen.m_FiberSeparationThreshold*M_PI/180.0);
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
- boost::progress_display disp(tempTissueMask->GetLargestPossibleRegion().GetNumberOfPixels());
- ImageRegionIterator<ItkUcharImgType> it(tempTissueMask, tempTissueMask->GetLargestPossibleRegion());
+ boost::progress_display disp(m_MaskImage->GetLargestPossibleRegion().GetNumberOfPixels());
+ ImageRegionIterator<ItkUcharImgType> it(m_MaskImage, m_MaskImage->GetLargestPossibleRegion());
while(!it.IsAtEnd())
{
++disp;
unsigned long newTick = 50*disp.count()/disp.expected_count();
for (unsigned int tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
if (it.Get()>0)
{
int numFibs = m_RandGen->GetIntegerVariate(2)+1;
DoubleDwiType::PixelType pix = m_CompartmentImages.at(0)->GetPixel(it.GetIndex());
double volume = m_RandGen->GetVariateWithClosedRange(0.3);
- double sum = 0;
+ // double sum = 0;
std::vector< double > fractions;
for (int i=0; i<numFibs; i++)
{
// fractions.push_back(1);
fractions.push_back(0.5+m_RandGen->GetVariateWithClosedRange(0.5));
- sum += fractions.at(i);
+ // sum += fractions.at(i);
}
- for (int i=0; i<numFibs; i++)
- fractions[i] /= sum;
+ // for (int i=0; i<numFibs; i++)
+ // fractions[i] /= sum;
std::vector< itk::Vector<double, 3> > directions;
for (int i=0; i<numFibs; i++)
{
DoubleVectorType fib;
fib[0] = m_RandGen->GetVariateWithClosedRange(2)-1.0;
fib[1] = m_RandGen->GetVariateWithClosedRange(2)-1.0;
fib[2] = m_RandGen->GetVariateWithClosedRange(2)-1.0;
fib.Normalize();
double min = 0;
for (unsigned int d=0; d<directions.size(); d++)
{
double angle = fabs(fib*directions[d]);
if (angle>min)
min = angle;
}
- if (min<0.5)
+ if (min<sepAngle)
{
m_Parameters.m_FiberModelList.at(0)->SetFiberDirection(fib);
pix += m_Parameters.m_FiberModelList.at(0)->SimulateMeasurement()*fractions[i];
directions.push_back(fib);
}
else
i--;
}
pix *= (1-volume);
+ m_CompartmentImages.at(0)->SetPixel(it.GetIndex(), pix);
// CSF/GM
{
- // int modelIndex = m_RandGen->GetIntegerVariate(m_Parameters.m_NonFiberModelList.size()-1);
pix += volume*m_Parameters.m_NonFiberModelList.at(0)->SimulateMeasurement();
}
- m_CompartmentImages.at(0)->SetPixel(it.GetIndex(), pix);
numDirectionsImage->SetPixel(it.GetIndex(), numFibs);
}
++it;
}
itk::ImageFileWriter< ItkUcharImgType >::Pointer wr = itk::ImageFileWriter< ItkUcharImgType >::New();
wr->SetInput(numDirectionsImage);
- wr->SetFileName("/local/NumDirections.nrrd");
+ wr->SetFileName(mitk::IOUtil::GetTempPath()+"/NumDirections_RandomDirections.nrrd");
wr->Update();
}
}
- if (logFile.is_open())
+ if (m_Logfile.is_open())
{
- logFile << "DONE";
- logFile.close();
+ m_Logfile << "DONE";
+ m_Logfile.close();
}
m_StatusText += "\n\n";
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
- // do k-space stuff
DoubleDwiType::Pointer doubleOutImage;
- if ( m_Parameters.m_SimulateKspaceAcquisition )
+ if ( m_Parameters.m_SignalGen.m_SimulateKspaceAcquisition ) // do k-space stuff
{
m_StatusText += this->GetTime()+" > Adjusting complex signal\n";
MITK_INFO << "Adjusting complex signal:";
- if (m_Parameters.m_DoSimulateRelaxation)
+ if (m_Parameters.m_SignalGen.m_DoSimulateRelaxation)
m_StatusText += "Simulating signal relaxation\n";
- if (m_Parameters.m_FrequencyMap.IsNotNull())
+ if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull())
m_StatusText += "Simulating distortions\n";
- if (m_Parameters.m_DoAddGibbsRinging)
+ if (m_Parameters.m_SignalGen.m_DoAddGibbsRinging)
m_StatusText += "Simulating ringing artifacts\n";
- if (m_Parameters.m_EddyStrength>0)
+ if (m_Parameters.m_SignalGen.m_EddyStrength>0)
m_StatusText += "Simulating eddy currents\n";
- if (m_Parameters.m_Spikes>0)
+ if (m_Parameters.m_SignalGen.m_Spikes>0)
m_StatusText += "Simulating spikes\n";
- if (m_Parameters.m_CroppingFactor<1.0)
+ if (m_Parameters.m_SignalGen.m_CroppingFactor<1.0)
m_StatusText += "Simulating aliasing artifacts\n";
- if (m_Parameters.m_KspaceLineOffset>0)
+ if (m_Parameters.m_SignalGen.m_KspaceLineOffset>0)
m_StatusText += "Simulating ghosts\n";
doubleOutImage = DoKspaceStuff(m_CompartmentImages);
- m_Parameters.m_SignalScale = 1; // already scaled in DoKspaceStuff
+ m_Parameters.m_SignalGen.m_SignalScale = 1; // already scaled in DoKspaceStuff
}
- else
+ else // don't do k-space stuff, just sum compartments
{
m_StatusText += this->GetTime()+" > Summing compartments\n";
MITK_INFO << "Summing compartments";
doubleOutImage = m_CompartmentImages.at(0);
for (unsigned int i=1; i<m_CompartmentImages.size(); i++)
{
itk::AddImageFilter< DoubleDwiType, DoubleDwiType, DoubleDwiType>::Pointer adder = itk::AddImageFilter< DoubleDwiType, DoubleDwiType, DoubleDwiType>::New();
adder->SetInput1(doubleOutImage);
adder->SetInput2(m_CompartmentImages.at(i));
adder->Update();
doubleOutImage = adder->GetOutput();
}
}
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
m_StatusText += this->GetTime()+" > Finalizing image\n";
MITK_INFO << "Finalizing image";
- if (m_Parameters.m_SignalScale>1)
+ if (m_Parameters.m_SignalGen.m_SignalScale>1)
m_StatusText += " Scaling signal\n";
if (m_Parameters.m_NoiseModel!=NULL)
m_StatusText += " Adding noise\n";
unsigned int window = 0;
unsigned int min = itk::NumericTraits<unsigned int>::max();
ImageRegionIterator<OutputImageType> it4 (outImage, outImage->GetLargestPossibleRegion());
- DoubleDwiType::PixelType signal; signal.SetSize(m_Parameters.GetNumVolumes());
+ DoubleDwiType::PixelType signal; signal.SetSize(m_Parameters.m_SignalGen.GetNumVolumes());
boost::progress_display disp2(outImage->GetLargestPossibleRegion().GetNumberOfPixels());
m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n";
m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*";
lastTick = 0;
while(!it4.IsAtEnd())
{
if (this->GetAbortGenerateData())
{
m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n";
return;
}
++disp2;
unsigned long newTick = 50*disp2.count()/disp2.expected_count();
for (unsigned long tick = 0; tick<(newTick-lastTick); tick++)
m_StatusText += "*";
lastTick = newTick;
typename OutputImageType::IndexType index = it4.GetIndex();
- signal = doubleOutImage->GetPixel(index)*m_Parameters.m_SignalScale;
+ signal = doubleOutImage->GetPixel(index)*m_Parameters.m_SignalGen.m_SignalScale;
if (m_Parameters.m_NoiseModel!=NULL)
m_Parameters.m_NoiseModel->AddNoise(signal);
for (unsigned int i=0; i<signal.Size(); i++)
{
if (signal[i]>0)
signal[i] = floor(signal[i]+0.5);
else
signal[i] = ceil(signal[i]-0.5);
- if ( (!m_Parameters.IsBaselineIndex(i) || signal.Size()==1) && signal[i]>window)
+ if ( (!m_Parameters.m_SignalGen.IsBaselineIndex(i) || signal.Size()==1) && signal[i]>window)
window = signal[i];
- if ( (!m_Parameters.IsBaselineIndex(i) || signal.Size()==1) && signal[i]<min)
+ if ( (!m_Parameters.m_SignalGen.IsBaselineIndex(i) || signal.Size()==1) && signal[i]<min)
min = signal[i];
}
it4.Set(signal);
++it4;
}
window -= min;
unsigned int level = window/2 + min;
m_LevelWindow.SetLevelWindow(level, window);
this->SetNthOutput(0, outImage);
m_StatusText += "\n\n";
m_StatusText += "Finished simulation\n";
m_StatusText += "Simulation time: "+GetTime();
m_TimeProbe.Stop();
}
+template< class PixelType >
+void TractsToDWIImageFilter< PixelType >::SimulateMotion(int g)
+{
+ if (m_Parameters.m_SignalGen.m_DoAddMotion && g<m_Parameters.m_SignalGen.GetNumVolumes()-1)
+ {
+ if (m_Parameters.m_SignalGen.m_DoRandomizeMotion)
+ {
+ m_FiberBundleTransformed = m_FiberBundleWorkingCopy->GetDeepCopy();
+ m_Rotation[0] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Rotation[0]*2)-m_Parameters.m_SignalGen.m_Rotation[0];
+ m_Rotation[1] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Rotation[1]*2)-m_Parameters.m_SignalGen.m_Rotation[1];
+ m_Rotation[2] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Rotation[2]*2)-m_Parameters.m_SignalGen.m_Rotation[2];
+ m_Translation[0] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Translation[0]*2)-m_Parameters.m_SignalGen.m_Translation[0];
+ m_Translation[1] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Translation[1]*2)-m_Parameters.m_SignalGen.m_Translation[1];
+ m_Translation[2] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Translation[2]*2)-m_Parameters.m_SignalGen.m_Translation[2];
+ }
+
+ // rotate mask image
+ if (m_MaskImageSet)
+ {
+ ImageRegionIterator<ItkUcharImgType> maskIt(m_UpsampledMaskImage, m_UpsampledMaskImage->GetLargestPossibleRegion());
+ m_MaskImage->FillBuffer(0);
+
+ while(!maskIt.IsAtEnd())
+ {
+ if (maskIt.Get()<=0)
+ {
+ ++maskIt;
+ continue;
+ }
+
+ DoubleDwiType::IndexType index = maskIt.GetIndex();
+ itk::Point<double, 3> point;
+ m_UpsampledMaskImage->TransformIndexToPhysicalPoint(index, point);
+ if (m_Parameters.m_SignalGen.m_DoRandomizeMotion)
+ point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), m_Rotation[0],m_Rotation[1],m_Rotation[2],m_Translation[0],m_Translation[1],m_Translation[2]);
+ else
+ point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), m_Rotation[0]*(g+1),m_Rotation[1]*(g+1),m_Rotation[2]*(g+1),m_Translation[0]*(g+1),m_Translation[1]*(g+1),m_Translation[2]*(g+1));
+
+ m_MaskImage->TransformPhysicalPointToIndex(point, index);
+ if (m_MaskImage->GetLargestPossibleRegion().IsInside(index))
+ m_MaskImage->SetPixel(index,100);
+ ++maskIt;
+ }
+ }
+
+ // rotate fibers
+ if (m_Logfile.is_open())
+ {
+ m_Logfile << g+1 << " rotation: " << m_Rotation[0] << "," << m_Rotation[1] << "," << m_Rotation[2] << ";";
+ m_Logfile << " translation: " << m_Translation[0] << "," << m_Translation[1] << "," << m_Translation[2] << "\n";
+ }
+ m_FiberBundleTransformed->TransformFibers(m_Rotation[0],m_Rotation[1],m_Rotation[2],m_Translation[0],m_Translation[1],m_Translation[2]);
+ }
+}
+
+template< class PixelType >
+void TractsToDWIImageFilter< PixelType >::SimulateNonFiberSignal(ItkUcharImgType::IndexType index, double intraAxonalVolume, int g)
+{
+ int numFiberCompartments = m_Parameters.m_FiberModelList.size();
+ int numNonFiberCompartments = m_Parameters.m_NonFiberModelList.size();
+
+ if (intraAxonalVolume>0.0001 && m_Parameters.m_SignalGen.m_DoDisablePartialVolume) // only fiber in voxel
+ {
+ DoubleDwiType::PixelType pix = m_CompartmentImages.at(0)->GetPixel(index);
+ if (g>=0)
+ pix[g] *= m_VoxelVolume/intraAxonalVolume;
+ else
+ pix *= m_VoxelVolume/intraAxonalVolume;
+ m_CompartmentImages.at(0)->SetPixel(index, pix);
+ m_VolumeFractions.at(0)->SetPixel(index, 1);
+ for (int i=1; i<numFiberCompartments; i++)
+ {
+ DoubleDwiType::PixelType pix = m_CompartmentImages.at(i)->GetPixel(index);
+ if (g>=0)
+ pix[g] = 0.0;
+ else
+ pix.Fill(0.0);
+ m_CompartmentImages.at(i)->SetPixel(index, pix);
+ }
+ }
+ else
+ {
+ m_VolumeFractions.at(0)->SetPixel(index, intraAxonalVolume/m_VoxelVolume);
+
+ itk::Point<double, 3> point;
+ m_MaskImage->TransformIndexToPhysicalPoint(index, point);
+ if (m_Parameters.m_SignalGen.m_DoAddMotion)
+ {
+ if (m_Parameters.m_SignalGen.m_DoRandomizeMotion && g>0)
+ point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), -m_Rotation[0],-m_Rotation[1],-m_Rotation[2],-m_Translation[0],-m_Translation[1],-m_Translation[2]);
+ else if (g>=0)
+ point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), -m_Rotation[0]*g,-m_Rotation[1]*g,-m_Rotation[2]*g,-m_Translation[0]*g,-m_Translation[1]*g,-m_Translation[2]*g);
+ }
+
+ if (m_Parameters.m_SignalGen.m_DoDisablePartialVolume)
+ {
+ int maxVolumeIndex = 0;
+ double maxWeight = 0;
+ for (int i=0; i<numNonFiberCompartments; i++)
+ {
+ double weight = 0;
+ if (numNonFiberCompartments>1)
+ {
+ DoubleDwiType::IndexType newIndex;
+ m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->TransformPhysicalPointToIndex(point, newIndex);
+ if (!m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion().IsInside(newIndex))
+ continue;
+ weight = m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetPixel(newIndex);
+ }
+
+ if (weight>maxWeight)
+ {
+ maxWeight = weight;
+ maxVolumeIndex = i;
+ }
+ }
+ DoubleDwiType::Pointer doubleDwi = m_CompartmentImages.at(maxVolumeIndex+numFiberCompartments);
+ DoubleDwiType::PixelType pix = doubleDwi->GetPixel(index);
+
+ if (g>=0)
+ pix[g] += m_Parameters.m_NonFiberModelList[maxVolumeIndex]->SimulateMeasurement(g);
+ else
+ pix += m_Parameters.m_NonFiberModelList[maxVolumeIndex]->SimulateMeasurement();
+ doubleDwi->SetPixel(index, pix);
+ m_VolumeFractions.at(maxVolumeIndex+numFiberCompartments)->SetPixel(index, 1);
+ }
+ else
+ {
+ double extraAxonalVolume = m_VoxelVolume-intraAxonalVolume; // non-fiber volume
+ double interAxonalVolume = 0;
+ if (numFiberCompartments>1)
+ interAxonalVolume = extraAxonalVolume * intraAxonalVolume/m_VoxelVolume; // inter-axonal fraction of non fiber compartment scales linearly with f
+ double other = extraAxonalVolume - interAxonalVolume; // rest of compartment
+ double singleinter = interAxonalVolume/(numFiberCompartments-1);
+
+ // adjust non-fiber and intra-axonal signal
+ for (int i=1; i<numFiberCompartments; i++)
+ {
+ DoubleDwiType::PixelType pix = m_CompartmentImages.at(i)->GetPixel(index);
+ if (intraAxonalVolume>0) // remove scaling by intra-axonal volume from inter-axonal compartment
+ {
+ if (g>=0)
+ pix[g] /= intraAxonalVolume;
+ else
+ pix /= intraAxonalVolume;
+ }
+ if (g>=0)
+ pix[g] *= singleinter;
+ else
+ pix *= singleinter;
+ m_CompartmentImages.at(i)->SetPixel(index, pix);
+ m_VolumeFractions.at(i)->SetPixel(index, singleinter/m_VoxelVolume);
+ }
+
+ for (int i=0; i<numNonFiberCompartments; i++)
+ {
+ double weight = 1;
+ if (numNonFiberCompartments>1)
+ {
+ DoubleDwiType::IndexType newIndex;
+ m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->TransformPhysicalPointToIndex(point, newIndex);
+ if (!m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion().IsInside(newIndex))
+ continue;
+ weight = m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetPixel(newIndex);
+ }
+
+ DoubleDwiType::Pointer doubleDwi = m_CompartmentImages.at(i+numFiberCompartments);
+ DoubleDwiType::PixelType pix = doubleDwi->GetPixel(index);
+
+ if (g>=0)
+ pix[g] += m_Parameters.m_NonFiberModelList[i]->SimulateMeasurement(g)*other*weight;
+ else
+ pix += m_Parameters.m_NonFiberModelList[i]->SimulateMeasurement()*other*weight;
+ doubleDwi->SetPixel(index, pix);
+ m_VolumeFractions.at(i+numFiberCompartments)->SetPixel(index, other/m_VoxelVolume*weight);
+ }
+ }
+ }
+}
+
template< class PixelType >
itk::Point<float, 3> TractsToDWIImageFilter< PixelType >::GetItkPoint(double point[3])
{
itk::Point<float, 3> itkPoint;
itkPoint[0] = point[0];
itkPoint[1] = point[1];
itkPoint[2] = point[2];
return itkPoint;
}
template< class PixelType >
itk::Vector<double, 3> TractsToDWIImageFilter< PixelType >::GetItkVector(double point[3])
{
itk::Vector<double, 3> itkVector;
itkVector[0] = point[0];
itkVector[1] = point[1];
itkVector[2] = point[2];
return itkVector;
}
template< class PixelType >
vnl_vector_fixed<double, 3> TractsToDWIImageFilter< PixelType >::GetVnlVector(double point[3])
{
vnl_vector_fixed<double, 3> vnlVector;
vnlVector[0] = point[0];
vnlVector[1] = point[1];
vnlVector[2] = point[2];
return vnlVector;
}
template< class PixelType >
vnl_vector_fixed<double, 3> TractsToDWIImageFilter< PixelType >::GetVnlVector(Vector<float,3>& vector)
{
vnl_vector_fixed<double, 3> vnlVector;
vnlVector[0] = vector[0];
vnlVector[1] = vector[1];
vnlVector[2] = vector[2];
return vnlVector;
}
template< class PixelType >
double TractsToDWIImageFilter< PixelType >::RoundToNearest(double num) {
return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5);
}
template< class PixelType >
std::string TractsToDWIImageFilter< PixelType >::GetTime()
{
m_TimeProbe.Stop();
unsigned long total = RoundToNearest(m_TimeProbe.GetTotal());
unsigned long hours = total/3600;
unsigned long minutes = (total%3600)/60;
unsigned long seconds = total%60;
std::string out = "";
out.append(boost::lexical_cast<std::string>(hours));
out.append(":");
out.append(boost::lexical_cast<std::string>(minutes));
out.append(":");
out.append(boost::lexical_cast<std::string>(seconds));
m_TimeProbe.Start();
return out;
}
}
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h
index dfb640ad23..aa56645ad8 100755
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h
@@ -1,111 +1,132 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef __itkTractsToDWIImageFilter_h__
#define __itkTractsToDWIImageFilter_h__
#include <mitkFiberBundleX.h>
#include <itkVnlForwardFFTImageFilter.h>
#include <itkVectorImage.h>
#include <cmath>
#include <mitkFiberfoxParameters.h>
#include <itkTimeProbe.h>
#include <mitkRawShModel.h>
#include <mitkDiffusionImage.h>
#include <itkAnalyticalDiffusionQballReconstructionImageFilter.h>
namespace itk
{
/**
* \brief Generates artificial diffusion weighted image volume from the input fiberbundle using a generic multicompartment model.
* See "Fiberfox: Facilitating the creation of realistic white matter software phantoms" (DOI: 10.1002/mrm.25045) for details.
*/
template< class PixelType >
class TractsToDWIImageFilter : public ImageSource< itk::VectorImage< PixelType, 3 > >
{
public:
typedef TractsToDWIImageFilter Self;
typedef ImageSource< itk::VectorImage< PixelType, 3 > > Superclass;
typedef SmartPointer< Self > Pointer;
typedef SmartPointer< const Self > ConstPointer;
typedef typename Superclass::OutputImageType OutputImageType;
typedef itk::Image<double, 3> ItkDoubleImgType;
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef mitk::FiberBundleX::Pointer FiberBundleType;
typedef itk::VectorImage< double, 3 > DoubleDwiType;
typedef itk::Matrix<double, 3, 3> MatrixType;
typedef itk::Image< double, 2 > SliceType;
typedef itk::VnlForwardFFTImageFilter<SliceType>::OutputImageType ComplexSliceType;
typedef itk::Vector< double,3> DoubleVectorType;
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
itkTypeMacro( TractsToDWIImageFilter, ImageSource )
/** Input */
itkSetMacro( FiberBundle, FiberBundleType ) ///< Input fiber bundle
itkSetMacro( UseConstantRandSeed, bool ) ///< Seed for random generator.
void SetParameters( FiberfoxParameters<double> param ) ///< Simulation parameters.
{ m_Parameters = param; }
/** Output */
FiberfoxParameters<double> GetParameters(){ return m_Parameters; }
std::vector< ItkDoubleImgType::Pointer > GetVolumeFractions() ///< one double image for each compartment containing the corresponding volume fraction per voxel
{ return m_VolumeFractions; }
mitk::LevelWindow GetLevelWindow(){ return m_LevelWindow; }
itkGetMacro( StatusText, std::string )
void GenerateData();
protected:
TractsToDWIImageFilter();
virtual ~TractsToDWIImageFilter();
itk::Point<float, 3> GetItkPoint(double point[3]);
itk::Vector<double, 3> GetItkVector(double point[3]);
vnl_vector_fixed<double, 3> GetVnlVector(double point[3]);
vnl_vector_fixed<double, 3> GetVnlVector(Vector< float, 3 >& vector);
double RoundToNearest(double num);
std::string GetTime();
/** Transform generated image compartment by compartment, channel by channel and slice by slice using DFT and add k-space artifacts. */
DoubleDwiType::Pointer DoKspaceStuff(std::vector< DoubleDwiType::Pointer >& images);
+ /** Generate signal of non-fiber compartments. */
+ void SimulateNonFiberSignal(ItkUcharImgType::IndexType index, double intraAxonalVolume, int g=-1);
+
+ /** Move fibers to simulate headmotion */
+ void SimulateMotion(int g=-1);
+
+ // input
mitk::FiberfoxParameters<double> m_Parameters;
- itk::Vector<double,3> m_UpsampledSpacing;
- itk::Point<double,3> m_UpsampledOrigin;
- ImageRegion<3> m_UpsampledImageRegion;
FiberBundleType m_FiberBundle;
+
+ // output
mitk::LevelWindow m_LevelWindow;
std::vector< ItkDoubleImgType::Pointer > m_VolumeFractions;
std::string m_StatusText;
+
+ // MISC
itk::TimeProbe m_TimeProbe;
bool m_UseConstantRandSeed;
- itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer m_RandGen;
+ bool m_MaskImageSet;
+ ofstream m_Logfile;
- std::vector< DoubleDwiType::Pointer > m_CompartmentImages;
+ // signal generation
+ FiberBundleType m_FiberBundleWorkingCopy; ///< we work on an upsampled version of the input bundle
+ FiberBundleType m_FiberBundleTransformed; ///< transformed bundle simulating headmotion
+ itk::Vector<double,3> m_UpsampledSpacing;
+ itk::Point<double,3> m_UpsampledOrigin;
+ ImageRegion<3> m_UpsampledImageRegion;
+ double m_VoxelVolume;
+ std::vector< DoubleDwiType::Pointer > m_CompartmentImages;
+ ItkUcharImgType::Pointer m_MaskImage; ///< copy of mask image (changes for each motion step)
+ ItkUcharImgType::Pointer m_UpsampledMaskImage; ///< helper image for motion simulation
+ DoubleVectorType m_Rotation;
+ DoubleVectorType m_Translation;
+ itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer m_RandGen;
};
}
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkTractsToDWIImageFilter.cpp"
#endif
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.cpp
index 9f44d41d0a..975a40f5ec 100644
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.cpp
@@ -1,556 +1,563 @@
#include "itkTractsToVectorImageFilter.h"
// VTK
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>
// ITK
#include <itkTimeProbe.h>
#include <itkImageRegionIterator.h>
// misc
#define _USE_MATH_DEFINES
#include <math.h>
#include <boost/progress.hpp>
namespace itk{
static bool CompareVectorLengths(const vnl_vector_fixed< double, 3 >& v1, const vnl_vector_fixed< double, 3 >& v2)
{
return (v1.magnitude()>v2.magnitude());
}
template< class PixelType >
TractsToVectorImageFilter< PixelType >::TractsToVectorImageFilter():
m_AngularThreshold(0.7),
m_Epsilon(0.999),
m_MaskImage(NULL),
m_NormalizeVectors(false),
m_UseWorkingCopy(true),
m_MaxNumDirections(3),
m_SizeThreshold(0.2),
- m_NumDirectionsImage(NULL)
+ m_NumDirectionsImage(NULL),
+ m_CreateDirectionImages(true)
{
this->SetNumberOfRequiredOutputs(1);
}
template< class PixelType >
TractsToVectorImageFilter< PixelType >::~TractsToVectorImageFilter()
{
}
template< class PixelType >
vnl_vector_fixed<double, 3> TractsToVectorImageFilter< PixelType >::GetVnlVector(double point[])
{
vnl_vector_fixed<double, 3> vnlVector;
vnlVector[0] = point[0];
vnlVector[1] = point[1];
vnlVector[2] = point[2];
return vnlVector;
}
template< class PixelType >
itk::Point<double, 3> TractsToVectorImageFilter< PixelType >::GetItkPoint(double point[])
{
itk::Point<double, 3> itkPoint;
itkPoint[0] = point[0];
itkPoint[1] = point[1];
itkPoint[2] = point[2];
return itkPoint;
}
template< class PixelType >
void TractsToVectorImageFilter< PixelType >::GenerateData()
{
mitk::BaseGeometry::Pointer geometry = m_FiberBundle->GetGeometry();
// calculate new image parameters
itk::Vector<double> spacing;
itk::Point<double> origin;
itk::Matrix<double, 3, 3> direction;
ImageRegion<3> imageRegion;
if (!m_MaskImage.IsNull())
{
spacing = m_MaskImage->GetSpacing();
imageRegion = m_MaskImage->GetLargestPossibleRegion();
origin = m_MaskImage->GetOrigin();
direction = m_MaskImage->GetDirection();
}
else
{
spacing = geometry->GetSpacing();
origin = geometry->GetOrigin();
mitk::BaseGeometry::BoundsArrayType bounds = geometry->GetBounds();
origin[0] += bounds.GetElement(0);
origin[1] += bounds.GetElement(2);
origin[2] += bounds.GetElement(4);
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
direction[j][i] = geometry->GetMatrixColumn(i)[j];
imageRegion.SetSize(0, geometry->GetExtent(0));
imageRegion.SetSize(1, geometry->GetExtent(1));
imageRegion.SetSize(2, geometry->GetExtent(2));
m_MaskImage = ItkUcharImgType::New();
m_MaskImage->SetSpacing( spacing );
m_MaskImage->SetOrigin( origin );
m_MaskImage->SetDirection( direction );
m_MaskImage->SetRegions( imageRegion );
m_MaskImage->Allocate();
m_MaskImage->FillBuffer(1);
}
OutputImageType::RegionType::SizeType outImageSize = imageRegion.GetSize();
m_OutImageSpacing = m_MaskImage->GetSpacing();
m_ClusteredDirectionsContainer = ContainerType::New();
// initialize num directions image
m_NumDirectionsImage = ItkUcharImgType::New();
m_NumDirectionsImage->SetSpacing( spacing );
m_NumDirectionsImage->SetOrigin( origin );
m_NumDirectionsImage->SetDirection( direction );
m_NumDirectionsImage->SetRegions( imageRegion );
m_NumDirectionsImage->Allocate();
m_NumDirectionsImage->FillBuffer(0);
// initialize direction images
m_DirectionImageContainer = DirectionImageContainerType::New();
// resample fiber bundle
double minSpacing = 1;
if(m_OutImageSpacing[0]<m_OutImageSpacing[1] && m_OutImageSpacing[0]<m_OutImageSpacing[2])
minSpacing = m_OutImageSpacing[0];
else if (m_OutImageSpacing[1] < m_OutImageSpacing[2])
minSpacing = m_OutImageSpacing[1];
else
minSpacing = m_OutImageSpacing[2];
if (m_UseWorkingCopy)
m_FiberBundle = m_FiberBundle->GetDeepCopy();
// resample fiber bundle for sufficient voxel coverage
m_FiberBundle->ResampleFibers(minSpacing/10);
// iterate over all fibers
vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
int numFibers = m_FiberBundle->GetNumFibers();
m_DirectionsContainer = ContainerType::New();
MITK_INFO << "Generating directions from tractogram";
boost::progress_display disp(numFibers);
for( int i=0; i<numFibers; i++ )
{
++disp;
vtkCell* cell = fiberPolyData->GetCell(i);
int numPoints = cell->GetNumberOfPoints();
vtkPoints* points = cell->GetPoints();
if (numPoints<2)
continue;
vnl_vector_fixed<double, 3> dir;
itk::Point<double, 3> worldPos;
vnl_vector<double> v;
for( int j=0; j<numPoints-1; j++)
{
// get current position along fiber in world coordinates
double* temp = points->GetPoint(j);
worldPos = GetItkPoint(temp);
itk::Index<3> index;
m_MaskImage->TransformPhysicalPointToIndex(worldPos, index);
if (!m_MaskImage->GetLargestPossibleRegion().IsInside(index) || m_MaskImage->GetPixel(index)==0)
continue;
// get fiber tangent direction at this position
v = GetVnlVector(temp);
dir = GetVnlVector(points->GetPoint(j+1))-v;
if (dir.is_zero())
continue;
dir.normalize();
// add direction to container
unsigned int idx = index[0] + outImageSize[0]*(index[1] + outImageSize[1]*index[2]);
DirectionContainerType::Pointer dirCont;
if (m_DirectionsContainer->IndexExists(idx))
{
dirCont = m_DirectionsContainer->GetElement(idx);
if (dirCont.IsNull())
{
dirCont = DirectionContainerType::New();
dirCont->push_back(dir);
m_DirectionsContainer->InsertElement(idx, dirCont);
}
else
dirCont->push_back(dir);
}
else
{
dirCont = DirectionContainerType::New();
dirCont->push_back(dir);
m_DirectionsContainer->InsertElement(idx, dirCont);
}
}
}
vtkSmartPointer<vtkCellArray> m_VtkCellArray = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPoints> m_VtkPoints = vtkSmartPointer<vtkPoints>::New();
itk::ImageRegionIterator<ItkUcharImgType> dirIt(m_NumDirectionsImage, m_NumDirectionsImage->GetLargestPossibleRegion());
MITK_INFO << "Clustering directions";
boost::progress_display disp2(outImageSize[0]*outImageSize[1]*outImageSize[2]);
while(!dirIt.IsAtEnd())
{
++disp2;
OutputImageType::IndexType index = dirIt.GetIndex();
int idx = index[0]+(index[1]+index[2]*outImageSize[1])*outImageSize[0];
if (!m_DirectionsContainer->IndexExists(idx))
{
++dirIt;
continue;
}
DirectionContainerType::Pointer dirCont = m_DirectionsContainer->GetElement(idx);
if (dirCont.IsNull() || dirCont->empty())
{
++dirIt;
continue;
}
std::vector< double > lengths; lengths.resize(dirCont->size(), 1); // all peaks have size 1
- DirectionContainerType::Pointer directions = FastClustering(dirCont, lengths);
- std::sort( directions->begin(), directions->end(), CompareVectorLengths );
+ DirectionContainerType::Pointer directions;
+ if (m_MaxNumDirections>0)
+ {
+ directions = FastClustering(dirCont, lengths);
+ std::sort( directions->begin(), directions->end(), CompareVectorLengths );
+ }
+ else
+ directions = dirCont;
unsigned int numDir = directions->size();
if (m_MaxNumDirections>0 && numDir>m_MaxNumDirections)
numDir = m_MaxNumDirections;
int count = 0;
for (unsigned int i=0; i<numDir; i++)
{
vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
itk::ContinuousIndex<double, 3> center;
center[0] = index[0];
center[1] = index[1];
center[2] = index[2];
itk::Point<double> worldCenter;
m_MaskImage->TransformContinuousIndexToPhysicalPoint( center, worldCenter );
DirectionType dir = directions->at(i);
if (dir.magnitude()<m_SizeThreshold)
continue;
count++;
- if (dir.magnitude()<0.4)
- continue;
-
- if (i==m_DirectionImageContainer->size())
+ if (m_CreateDirectionImages && i<10)
{
- ItkDirectionImageType::Pointer directionImage = ItkDirectionImageType::New();
- directionImage->SetSpacing( spacing );
- directionImage->SetOrigin( origin );
- directionImage->SetDirection( direction );
- directionImage->SetRegions( imageRegion );
- directionImage->Allocate();
- Vector< float, 3 > nullVec; nullVec.Fill(0.0);
- directionImage->FillBuffer(nullVec);
- m_DirectionImageContainer->InsertElement(i, directionImage);
- }
+ if (i==m_DirectionImageContainer->size())
+ {
+ ItkDirectionImageType::Pointer directionImage = ItkDirectionImageType::New();
+ directionImage->SetSpacing( spacing );
+ directionImage->SetOrigin( origin );
+ directionImage->SetDirection( direction );
+ directionImage->SetRegions( imageRegion );
+ directionImage->Allocate();
+ Vector< float, 3 > nullVec; nullVec.Fill(0.0);
+ directionImage->FillBuffer(nullVec);
+ m_DirectionImageContainer->InsertElement(i, directionImage);
+ }
- // set direction image pixel
- ItkDirectionImageType::Pointer directionImage = m_DirectionImageContainer->GetElement(i);
- Vector< float, 3 > pixel;
- pixel.SetElement(0, dir[0]);
- pixel.SetElement(1, dir[1]);
- pixel.SetElement(2, dir[2]);
- directionImage->SetPixel(index, pixel);
+ // set direction image pixel
+ ItkDirectionImageType::Pointer directionImage = m_DirectionImageContainer->GetElement(i);
+ Vector< float, 3 > pixel;
+ pixel.SetElement(0, dir[0]);
+ pixel.SetElement(1, dir[1]);
+ pixel.SetElement(2, dir[2]);
+ directionImage->SetPixel(index, pixel);
+ }
// add direction to vector field (with spacing compensation)
itk::Point<double> worldStart;
worldStart[0] = worldCenter[0]-dir[0]/2*minSpacing;
worldStart[1] = worldCenter[1]-dir[1]/2*minSpacing;
worldStart[2] = worldCenter[2]-dir[2]/2*minSpacing;
vtkIdType id = m_VtkPoints->InsertNextPoint(worldStart.GetDataPointer());
container->GetPointIds()->InsertNextId(id);
itk::Point<double> worldEnd;
worldEnd[0] = worldCenter[0]+dir[0]/2*minSpacing;
worldEnd[1] = worldCenter[1]+dir[1]/2*minSpacing;
worldEnd[2] = worldCenter[2]+dir[2]/2*minSpacing;
id = m_VtkPoints->InsertNextPoint(worldEnd.GetDataPointer());
container->GetPointIds()->InsertNextId(id);
m_VtkCellArray->InsertNextCell(container);
}
dirIt.Set(count);
++dirIt;
}
vtkSmartPointer<vtkPolyData> directionsPolyData = vtkSmartPointer<vtkPolyData>::New();
directionsPolyData->SetPoints(m_VtkPoints);
directionsPolyData->SetLines(m_VtkCellArray);
m_OutputFiberBundle = mitk::FiberBundleX::New(directionsPolyData);
}
template< class PixelType >
TractsToVectorImageFilter< PixelType >::DirectionContainerType::Pointer TractsToVectorImageFilter< PixelType >::FastClustering(DirectionContainerType::Pointer inDirs, std::vector< double > lengths)
{
DirectionContainerType::Pointer outDirs = DirectionContainerType::New();
if (inDirs->size()<2)
return inDirs;
DirectionType oldMean, currentMean;
std::vector< int > touched;
// initialize
touched.resize(inDirs->size(), 0);
bool free = true;
currentMean = inDirs->at(0); // initialize first seed
currentMean.normalize();
double length = lengths.at(0);
touched[0] = 1;
std::vector< double > newLengths;
bool meanChanged = false;
double max = 0;
while (free)
{
oldMean.fill(0.0);
// start mean-shift clustering
double angle = 0;
while (fabs(dot_product(currentMean, oldMean))<0.99)
{
oldMean = currentMean;
currentMean.fill(0.0);
for (unsigned int i=0; i<inDirs->size(); i++)
{
angle = dot_product(oldMean, inDirs->at(i));
if (angle>=m_AngularThreshold)
{
currentMean += inDirs->at(i);
if (meanChanged)
length += lengths.at(i);
touched[i] = 1;
meanChanged = true;
}
else if (-angle>=m_AngularThreshold)
{
currentMean -= inDirs->at(i);
if (meanChanged)
length += lengths.at(i);
touched[i] = 1;
meanChanged = true;
}
}
if(!meanChanged)
currentMean = oldMean;
else
currentMean.normalize();
}
// found stable mean
outDirs->push_back(currentMean);
newLengths.push_back(length);
if (length>max)
max = length;
// find next unused seed
free = false;
for (unsigned int i=0; i<touched.size(); i++)
if (touched[i]==0)
{
currentMean = inDirs->at(i);
free = true;
meanChanged = false;
length = lengths.at(i);
touched[i] = 1;
break;
}
}
if (inDirs->size()==outDirs->size())
{
if (!m_NormalizeVectors && max>0)
for (unsigned int i=0; i<outDirs->size(); i++)
outDirs->SetElement(i, outDirs->at(i)*newLengths.at(i)/max);
return outDirs;
}
else
return FastClustering(outDirs, newLengths);
}
//template< class PixelType >
//std::vector< DirectionType > TractsToVectorImageFilter< PixelType >::Clustering(std::vector< DirectionType >& inDirs)
//{
// std::vector< DirectionType > outDirs;
// if (inDirs.empty())
// return outDirs;
// DirectionType oldMean, currentMean, workingMean;
// std::vector< DirectionType > normalizedDirs;
// std::vector< int > touched;
// for (std::size_t i=0; i<inDirs.size(); i++)
// {
// normalizedDirs.push_back(inDirs[i]);
// normalizedDirs.back().normalize();
// }
// // initialize
// double max = 0.0;
// touched.resize(inDirs.size(), 0);
// for (std::size_t j=0; j<inDirs.size(); j++)
// {
// currentMean = inDirs[j];
// oldMean.fill(0.0);
// // start mean-shift clustering
// double angle = 0.0;
// int counter = 0;
// while ((currentMean-oldMean).magnitude()>0.0001)
// {
// counter = 0;
// oldMean = currentMean;
// workingMean = oldMean;
// workingMean.normalize();
// currentMean.fill(0.0);
// for (std::size_t i=0; i<normalizedDirs.size(); i++)
// {
// angle = dot_product(workingMean, normalizedDirs[i]);
// if (angle>=m_AngularThreshold)
// {
// currentMean += inDirs[i];
// counter++;
// }
// else if (-angle>=m_AngularThreshold)
// {
// currentMean -= inDirs[i];
// counter++;
// }
// }
// }
// // found stable mean
// if (counter>0)
// {
// bool add = true;
// DirectionType normMean = currentMean;
// normMean.normalize();
// for (std::size_t i=0; i<outDirs.size(); i++)
// {
// DirectionType dir = outDirs[i];
// dir.normalize();
// if ((normMean-dir).magnitude()<=0.0001)
// {
// add = false;
// break;
// }
// }
// currentMean /= counter;
// if (add)
// {
// double mag = currentMean.magnitude();
// if (mag>0)
// {
// if (mag>max)
// max = mag;
// outDirs.push_back(currentMean);
// }
// }
// }
// }
// if (m_NormalizeVectors)
// for (std::size_t i=0; i<outDirs.size(); i++)
// outDirs[i].normalize();
// else if (max>0)
// for (std::size_t i=0; i<outDirs.size(); i++)
// outDirs[i] /= max;
// if (inDirs.size()==outDirs.size())
// return outDirs;
// else
// return FastClustering(outDirs);
//}
//template< class PixelType >
//TractsToVectorImageFilter< PixelType >::DirectionContainerType::Pointer TractsToVectorImageFilter< PixelType >::MeanShiftClustering(DirectionContainerType::Pointer dirCont)
//{
// DirectionContainerType::Pointer container = DirectionContainerType::New();
// double max = 0;
// for (DirectionContainerType::ConstIterator it = dirCont->Begin(); it!=dirCont->End(); ++it)
// {
// vnl_vector_fixed<double, 3> mean = ClusterStep(dirCont, it.Value());
// if (mean.is_zero())
// continue;
// bool addMean = true;
// for (DirectionContainerType::ConstIterator it2 = container->Begin(); it2!=container->End(); ++it2)
// {
// vnl_vector_fixed<double, 3> dir = it2.Value();
// double angle = fabs(dot_product(mean, dir)/(mean.magnitude()*dir.magnitude()));
// if (angle>=m_Epsilon)
// {
// addMean = false;
// break;
// }
// }
// if (addMean)
// {
// if (m_NormalizeVectors)
// mean.normalize();
// else if (mean.magnitude()>max)
// max = mean.magnitude();
// container->InsertElement(container->Size(), mean);
// }
// }
// // max normalize voxel directions
// if (max>0 && !m_NormalizeVectors)
// for (std::size_t i=0; i<container->Size(); i++)
// container->ElementAt(i) /= max;
// if (container->Size()<dirCont->Size())
// return MeanShiftClustering(container);
// else
// return container;
//}
//template< class PixelType >
//vnl_vector_fixed<double, 3> TractsToVectorImageFilter< PixelType >::ClusterStep(DirectionContainerType::Pointer dirCont, vnl_vector_fixed<double, 3> currentMean)
//{
// vnl_vector_fixed<double, 3> newMean; newMean.fill(0);
// for (DirectionContainerType::ConstIterator it = dirCont->Begin(); it!=dirCont->End(); ++it)
// {
// vnl_vector_fixed<double, 3> dir = it.Value();
// double angle = dot_product(currentMean, dir)/(currentMean.magnitude()*dir.magnitude());
// if (angle>=m_AngularThreshold)
// newMean += dir;
// else if (-angle>=m_AngularThreshold)
// newMean -= dir;
// }
// if (fabs(dot_product(currentMean, newMean)/(currentMean.magnitude()*newMean.magnitude()))>=m_Epsilon || newMean.is_zero())
// return newMean;
// else
// return ClusterStep(dirCont, newMean);
//}
}
diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.h b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.h
index 21d931e14c..3a3eab15be 100644
--- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.h
+++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToVectorImageFilter.h
@@ -1,108 +1,110 @@
#ifndef __itkTractsToVectorImageFilter_h__
#define __itkTractsToVectorImageFilter_h__
// MITK
#include <mitkFiberBundleX.h>
// ITK
#include <itkImageSource.h>
#include <itkVectorImage.h>
// VTK
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyLine.h>
using namespace mitk;
namespace itk{
/**
* \brief Extracts the voxel-wise main directions of the input fiber bundle. */
template< class PixelType >
class TractsToVectorImageFilter : public ImageSource< VectorImage< float, 3 > >
{
public:
typedef TractsToVectorImageFilter Self;
typedef ProcessObject Superclass;
typedef SmartPointer< Self > Pointer;
typedef SmartPointer< const Self > ConstPointer;
typedef itk::Vector<float,3> OutputVectorType;
typedef itk::Image<OutputVectorType, 3> OutputImageType;
typedef std::vector< OutputImageType::Pointer > OutputImageContainerType;
typedef vnl_vector_fixed< double, 3 > DirectionType;
typedef VectorContainer< unsigned int, DirectionType > DirectionContainerType;
typedef VectorContainer< unsigned int, DirectionContainerType::Pointer > ContainerType;
typedef Image< Vector< float, 3 >, 3> ItkDirectionImageType;
typedef VectorContainer< unsigned int, ItkDirectionImageType::Pointer > DirectionImageContainerType;
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::Image<double, 3> ItkDoubleImgType;
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
itkTypeMacro( TractsToVectorImageFilter, ImageSource )
itkSetMacro( SizeThreshold, float)
itkGetMacro( SizeThreshold, float)
itkSetMacro( AngularThreshold, float) ///< cluster directions that are closer together than the specified threshold
itkGetMacro( AngularThreshold, float) ///< cluster directions that are closer together than the specified threshold
itkSetMacro( NormalizeVectors, bool) ///< Normalize vectors to length 1
itkGetMacro( NormalizeVectors, bool) ///< Normalize vectors to length 1
itkSetMacro( UseWorkingCopy, bool) ///< Do not modify input fiber bundle. Use a copy.
itkGetMacro( UseWorkingCopy, bool) ///< Do not modify input fiber bundle. Use a copy.
itkSetMacro( MaxNumDirections, unsigned long) ///< If more directions are extracted, only the largest are kept.
itkGetMacro( MaxNumDirections, unsigned long) ///< If more directions are extracted, only the largest are kept.
itkSetMacro( MaskImage, ItkUcharImgType::Pointer) ///< only process voxels inside mask
itkSetMacro( FiberBundle, FiberBundleX::Pointer) ///< input fiber bundle
itkGetMacro( ClusteredDirectionsContainer, ContainerType::Pointer) ///< output directions
itkGetMacro( NumDirectionsImage, ItkUcharImgType::Pointer) ///< number of directions per voxel
itkGetMacro( OutputFiberBundle, FiberBundleX::Pointer) ///< vector field for visualization purposes
itkGetMacro( DirectionImageContainer, DirectionImageContainerType::Pointer) ///< output directions
+ itkSetMacro( CreateDirectionImages, bool)
void GenerateData();
protected:
DirectionContainerType::Pointer FastClustering(DirectionContainerType::Pointer inDirs, std::vector< double > lengths); ///< cluster fiber directions
// std::vector< DirectionType > Clustering(std::vector< DirectionType >& inDirs);
// DirectionContainerType::Pointer MeanShiftClustering(DirectionContainerType::Pointer dirCont);
// vnl_vector_fixed<double, 3> ClusterStep(DirectionContainerType::Pointer dirCont, vnl_vector_fixed<double, 3> currentMean);
vnl_vector_fixed<double, 3> GetVnlVector(double point[3]);
itk::Point<double, 3> GetItkPoint(double point[3]);
TractsToVectorImageFilter();
virtual ~TractsToVectorImageFilter();
FiberBundleX::Pointer m_FiberBundle; ///< input fiber bundle
float m_AngularThreshold; ///< cluster directions that are closer together than the specified threshold
float m_Epsilon; ///< epsilon for vector equality check
ItkUcharImgType::Pointer m_MaskImage; ///< only voxels inside the binary mask are processed
bool m_NormalizeVectors; ///< normalize vectors to length 1
itk::Vector<float> m_OutImageSpacing; ///< spacing of output image
ContainerType::Pointer m_DirectionsContainer; ///< container for fiber directions
bool m_UseWorkingCopy; ///< do not modify input fiber bundle but work on copy
unsigned long m_MaxNumDirections; ///< if more directions per voxel are extracted, only the largest are kept
float m_SizeThreshold;
+ bool m_CreateDirectionImages;
// output datastructures
ContainerType::Pointer m_ClusteredDirectionsContainer; ///< contains direction vectors for each voxel
ItkUcharImgType::Pointer m_NumDirectionsImage; ///< shows number of fibers per voxel
DirectionImageContainerType::Pointer m_DirectionImageContainer; ///< contains images that contain the output directions
FiberBundleX::Pointer m_OutputFiberBundle; ///< vector field for visualization purposes
};
}
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkTractsToVectorImageFilter.cpp"
#endif
#endif // __itkTractsToVectorImageFilter_h__
diff --git a/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt
index 5e35107b8e..56f846586b 100644
--- a/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt
+++ b/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt
@@ -1,65 +1,65 @@
set(_module_deps MitkDiffusionCore MitkGraphAlgorithms)
mitk_check_module_dependencies(
MODULES ${_module_deps}
MISSING_DEPENDENCIES_VAR _missing_deps
)
# Enable OpenMP support
find_package(OpenMP)
if(NOT OPENMP_FOUND)
message("OpenMP is not available.")
endif()
if(OPENMP_FOUND)
message(STATUS "Found OpenMP.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
if(NOT _missing_deps)
set(lut_url http://mitk.org/download/data/FibertrackingLUT.tar.gz)
set(lut_tarball ${CMAKE_CURRENT_BINARY_DIR}/FibertrackingLUT.tar.gz)
message("Downloading FiberTracking LUT ${lut_url}...")
file(DOWNLOAD ${lut_url} ${lut_tarball}
EXPECTED_MD5 38ecb6d4a826c9ebb0f4965eb9aeee44
- TIMEOUT 20
+ TIMEOUT 60
STATUS status
SHOW_PROGRESS
)
list(GET status 0 status_code)
list(GET status 1 status_msg)
if(NOT status_code EQUAL 0)
message(SEND_ERROR "${status_msg} (error code ${status_code})")
else()
message("done.")
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Resources)
message("Unpacking FiberTracking LUT tarball...")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf ../FibertrackingLUT.tar.gz
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Resources
RESULT_VARIABLE result
ERROR_VARIABLE err_msg)
if(result)
message(SEND_ERROR "Unpacking FibertrackingLUT.tar.gz failed: ${err_msg}")
else()
message("done.")
endif()
endif()
MITK_CREATE_MODULE(
SUBPROJECTS MITK-DTI
INCLUDE_DIRS Algorithms Algorithms/GibbsTracking Algorithms/StochasticTracking IODataStructures IODataStructures/FiberBundleX IODataStructures/PlanarFigureComposite Interactions SignalModels Rendering ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${_module_deps}
PACKAGE_DEPENDS ITK|ITKFFT ITK|ITKDiffusionTensorImage
#WARNINGS_AS_ERRORS
)
if(MODULE_IS_ENABLED)
add_subdirectory(Testing)
endif()
diff --git a/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.cpp b/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.cpp
index 41425b0fd2..d443e5924a 100644
--- a/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.cpp
@@ -1,471 +1,689 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
-#include <mitkStickModel.h>
-#include <mitkTensorModel.h>
-#include <mitkAstroStickModel.h>
-#include <mitkBallModel.h>
-#include <mitkDotModel.h>
+#include <itkImageFileWriter.h>
+#include <itkImageFileReader.h>
template< class ScalarType >
mitk::FiberfoxParameters< ScalarType >::FiberfoxParameters()
- : m_SignalScale(100)
- , m_tEcho(100)
- , m_tLine(1)
- , m_tInhom(50)
- , m_Bvalue(1000)
- , m_SimulateKspaceAcquisition(false)
- , m_AxonRadius(0)
- , m_DiffusionDirectionMode(FIBER_TANGENT_DIRECTIONS)
- , m_Spikes(0)
- , m_SpikeAmplitude(1)
- , m_KspaceLineOffset(0)
- , m_EddyStrength(0)
- , m_Tau(70)
- , m_CroppingFactor(1)
- , m_DoAddGibbsRinging(false)
- , m_DoSimulateRelaxation(true)
- , m_DoDisablePartialVolume(false)
- , m_DoAddMotion(false)
- , m_DoRandomizeMotion(true)
- , m_NoiseModel(NULL)
- , m_FrequencyMap(NULL)
- , m_MaskImage(NULL)
- , m_ResultNode(mitk::DataNode::New())
- , m_ParentNode(NULL)
- , m_SignalModelString("")
- , m_ArtifactModelString("")
- , m_OutputPath("")
- , m_NumBaseline(1)
- , m_NumGradients(6)
+ : m_NoiseModel(NULL)
{
- m_ImageDirection.SetIdentity();
- m_ImageOrigin.Fill(0.0);
- m_ImageRegion.SetSize(0, 11);
- m_ImageRegion.SetSize(1, 11);
- m_ImageRegion.SetSize(2, 3);
- m_ImageSpacing.Fill(2.0);
- m_Translation.Fill(0.0);
- m_Rotation.Fill(0.0);
-
- GenerateGradientHalfShell();
}
template< class ScalarType >
mitk::FiberfoxParameters< ScalarType >::~FiberfoxParameters()
{
// if (m_NoiseModel!=NULL)
// delete m_NoiseModel;
}
-template< class ScalarType >
-void mitk::FiberfoxParameters< ScalarType >::GenerateGradientHalfShell()
+void mitk::SignalGenerationParameters::GenerateGradientHalfShell()
{
int NPoints = 2*m_NumGradients;
m_GradientDirections.clear();
m_NumBaseline = NPoints/20;
if (m_NumBaseline==0)
m_NumBaseline=1;
GradientType g;
g.Fill(0.0);
for (unsigned int i=0; i<m_NumBaseline; i++)
m_GradientDirections.push_back(g);
if (NPoints==0)
return;
vnl_vector<double> theta; theta.set_size(NPoints);
vnl_vector<double> phi; phi.set_size(NPoints);
double C = sqrt(4*M_PI);
phi(0) = 0.0;
phi(NPoints-1) = 0.0;
for(int i=0; i<NPoints; i++)
{
theta(i) = acos(-1.0+2.0*i/(NPoints-1.0)) - M_PI / 2.0;
if( i>0 && i<NPoints-1)
{
phi(i) = (phi(i-1) + C /
sqrt(NPoints*(1-(-1.0+2.0*i/(NPoints-1.0))*(-1.0+2.0*i/(NPoints-1.0)))));
- // % (2*DIST_m_GradientDirections_PI);
}
}
for(int i=0; i<NPoints; i++)
{
g[2] = sin(theta(i));
if (g[2]<0)
continue;
g[0] = cos(theta(i)) * cos(phi(i));
g[1] = cos(theta(i)) * sin(phi(i));
m_GradientDirections.push_back(g);
}
}
-template< class ScalarType >
-std::vector< int > mitk::FiberfoxParameters< ScalarType >::GetBaselineIndices()
+std::vector< int > mitk::SignalGenerationParameters::GetBaselineIndices()
{
std::vector< int > result;
for( unsigned int i=0; i<this->m_GradientDirections.size(); i++)
if (m_GradientDirections.at(i).GetNorm()<0.0001)
result.push_back(i);
return result;
}
-template< class ScalarType >
-unsigned int mitk::FiberfoxParameters< ScalarType >::GetFirstBaselineIndex()
+unsigned int mitk::SignalGenerationParameters::GetFirstBaselineIndex()
{
for( unsigned int i=0; i<this->m_GradientDirections.size(); i++)
if (m_GradientDirections.at(i).GetNorm()<0.0001)
return i;
return -1;
}
-template< class ScalarType >
-bool mitk::FiberfoxParameters< ScalarType >::IsBaselineIndex(unsigned int idx)
+bool mitk::SignalGenerationParameters::IsBaselineIndex(unsigned int idx)
{
if (m_GradientDirections.size()>idx && m_GradientDirections.at(idx).GetNorm()<0.0001)
return true;
return false;
}
-template< class ScalarType >
-unsigned int mitk::FiberfoxParameters< ScalarType >::GetNumWeightedVolumes()
+unsigned int mitk::SignalGenerationParameters::GetNumWeightedVolumes()
{
return m_NumGradients;
}
-template< class ScalarType >
-unsigned int mitk::FiberfoxParameters< ScalarType >::GetNumBaselineVolumes()
+unsigned int mitk::SignalGenerationParameters::GetNumBaselineVolumes()
{
return m_NumBaseline;
}
-template< class ScalarType >
-unsigned int mitk::FiberfoxParameters< ScalarType >::GetNumVolumes()
+unsigned int mitk::SignalGenerationParameters::GetNumVolumes()
{
return m_GradientDirections.size();
}
-template< class ScalarType >
-typename mitk::FiberfoxParameters< ScalarType >::GradientListType mitk::FiberfoxParameters< ScalarType >::GetGradientDirections()
+mitk::SignalGenerationParameters::GradientListType mitk::SignalGenerationParameters::GetGradientDirections()
{
return m_GradientDirections;
}
-template< class ScalarType >
-typename mitk::FiberfoxParameters< ScalarType >::GradientType mitk::FiberfoxParameters< ScalarType >::GetGradientDirection(unsigned int i)
+mitk::SignalGenerationParameters::GradientType mitk::SignalGenerationParameters::GetGradientDirection(unsigned int i)
{
return m_GradientDirections.at(i);
}
-template< class ScalarType >
-void mitk::FiberfoxParameters< ScalarType >::SetNumWeightedGradients(int numGradients)
+void mitk::SignalGenerationParameters::SetNumWeightedVolumes(int numGradients)
{
m_NumGradients = numGradients;
GenerateGradientHalfShell();
}
-template< class ScalarType >
-void mitk::FiberfoxParameters< ScalarType >::SetGradienDirections(GradientListType gradientList)
+void mitk::SignalGenerationParameters::SetGradienDirections(GradientListType gradientList)
{
m_GradientDirections = gradientList;
m_NumGradients = 0;
m_NumBaseline = 0;
for( unsigned int i=0; i<this->m_GradientDirections.size(); i++)
{
if (m_GradientDirections.at(i).GetNorm()>0.0001)
m_NumGradients++;
else
m_NumBaseline++;
}
}
-template< class ScalarType >
-void mitk::FiberfoxParameters< ScalarType >::SetGradienDirections(mitk::DiffusionImage<short>::GradientDirectionContainerType::Pointer gradientList)
+void mitk::SignalGenerationParameters::SetGradienDirections(mitk::DiffusionImage<short>::GradientDirectionContainerType::Pointer gradientList)
{
m_NumGradients = 0;
m_NumBaseline = 0;
m_GradientDirections.clear();
for( unsigned int i=0; i<gradientList->Size(); i++)
{
GradientType g;
g[0] = gradientList->at(i)[0];
g[1] = gradientList->at(i)[1];
g[2] = gradientList->at(i)[2];
m_GradientDirections.push_back(g);
if (m_GradientDirections.at(i).GetNorm()>0.0001)
m_NumGradients++;
else
m_NumBaseline++;
}
}
template< class ScalarType >
-void mitk::FiberfoxParameters< ScalarType >::LoadParameters(string filename)
+void mitk::FiberfoxParameters< ScalarType >::SaveParameters(string filename)
{
+ if(filename.empty())
+ return;
+ if(".ffp"!=filename.substr(filename.size()-4, 4))
+ filename += ".ffp";
+
boost::property_tree::ptree parameters;
- boost::property_tree::xml_parser::read_xml(filename, parameters);
- m_FiberModelList.clear();
- m_NonFiberModelList.clear();
+ // fiber generation parameters
+ parameters.put("fiberfox.fibers.distribution", m_FiberGen.m_Distribution);
+ parameters.put("fiberfox.fibers.variance", m_FiberGen.m_Variance);
+ parameters.put("fiberfox.fibers.density", m_FiberGen.m_Density);
+ parameters.put("fiberfox.fibers.spline.sampling", m_FiberGen.m_Sampling);
+ parameters.put("fiberfox.fibers.spline.tension", m_FiberGen.m_Tension);
+ parameters.put("fiberfox.fibers.spline.continuity", m_FiberGen.m_Continuity);
+ parameters.put("fiberfox.fibers.spline.bias", m_FiberGen.m_Bias);
+ parameters.put("fiberfox.fibers.rotation.x", m_FiberGen.m_Rotation[0]);
+ parameters.put("fiberfox.fibers.rotation.y", m_FiberGen.m_Rotation[1]);
+ parameters.put("fiberfox.fibers.rotation.z", m_FiberGen.m_Rotation[2]);
+ parameters.put("fiberfox.fibers.translation.x", m_FiberGen.m_Translation[0]);
+ parameters.put("fiberfox.fibers.translation.y", m_FiberGen.m_Translation[1]);
+ parameters.put("fiberfox.fibers.translation.z", m_FiberGen.m_Translation[2]);
+ parameters.put("fiberfox.fibers.scale.x", m_FiberGen.m_Scale[0]);
+ parameters.put("fiberfox.fibers.scale.y", m_FiberGen.m_Scale[1]);
+ parameters.put("fiberfox.fibers.scale.z", m_FiberGen.m_Scale[2]);
+
+ // image generation parameters
+ parameters.put("fiberfox.image.basic.size.x", m_SignalGen.m_ImageRegion.GetSize(0));
+ parameters.put("fiberfox.image.basic.size.y", m_SignalGen.m_ImageRegion.GetSize(1));
+ parameters.put("fiberfox.image.basic.size.z", m_SignalGen.m_ImageRegion.GetSize(2));
+ parameters.put("fiberfox.image.basic.spacing.x", m_SignalGen.m_ImageSpacing[0]);
+ parameters.put("fiberfox.image.basic.spacing.y", m_SignalGen.m_ImageSpacing[1]);
+ parameters.put("fiberfox.image.basic.spacing.z", m_SignalGen.m_ImageSpacing[2]);
+ parameters.put("fiberfox.image.basic.origin.x", m_SignalGen.m_ImageOrigin[0]);
+ parameters.put("fiberfox.image.basic.origin.y", m_SignalGen.m_ImageOrigin[1]);
+ parameters.put("fiberfox.image.basic.origin.z", m_SignalGen.m_ImageOrigin[2]);
+ parameters.put("fiberfox.image.basic.direction.1", m_SignalGen.m_ImageDirection[0][0]);
+ parameters.put("fiberfox.image.basic.direction.2", m_SignalGen.m_ImageDirection[0][1]);
+ parameters.put("fiberfox.image.basic.direction.3", m_SignalGen.m_ImageDirection[0][2]);
+ parameters.put("fiberfox.image.basic.direction.4", m_SignalGen.m_ImageDirection[1][0]);
+ parameters.put("fiberfox.image.basic.direction.5", m_SignalGen.m_ImageDirection[1][1]);
+ parameters.put("fiberfox.image.basic.direction.6", m_SignalGen.m_ImageDirection[1][2]);
+ parameters.put("fiberfox.image.basic.direction.7", m_SignalGen.m_ImageDirection[2][0]);
+ parameters.put("fiberfox.image.basic.direction.8", m_SignalGen.m_ImageDirection[2][1]);
+ parameters.put("fiberfox.image.basic.direction.9", m_SignalGen.m_ImageDirection[2][2]);
+ parameters.put("fiberfox.image.basic.numgradients", m_SignalGen.GetNumWeightedVolumes());
+ for( unsigned int i=0; i<this->m_SignalGen.GetNumVolumes(); i++)
+ {
+ parameters.put("fiberfox.image.gradients."+boost::lexical_cast<string>(i)+".x", m_SignalGen.GetGradientDirection(i)[0]);
+ parameters.put("fiberfox.image.gradients."+boost::lexical_cast<string>(i)+".y", m_SignalGen.GetGradientDirection(i)[1]);
+ parameters.put("fiberfox.image.gradients."+boost::lexical_cast<string>(i)+".z", m_SignalGen.GetGradientDirection(i)[2]);
+ }
+
+ parameters.put("fiberfox.image.signalScale", m_SignalGen.m_SignalScale);
+ parameters.put("fiberfox.image.tEcho", m_SignalGen.m_tEcho);
+ parameters.put("fiberfox.image.tLine", m_SignalGen.m_tLine);
+ parameters.put("fiberfox.image.tInhom", m_SignalGen.m_tInhom);
+ parameters.put("fiberfox.image.bvalue", m_SignalGen.m_Bvalue);
+ parameters.put("fiberfox.image.simulatekspace", m_SignalGen.m_SimulateKspaceAcquisition);
+ parameters.put("fiberfox.image.axonRadius", m_SignalGen.m_AxonRadius);
+ parameters.put("fiberfox.image.diffusiondirectionmode", m_SignalGen.m_DiffusionDirectionMode);
+ parameters.put("fiberfox.image.fiberseparationthreshold", m_SignalGen.m_FiberSeparationThreshold);
+ parameters.put("fiberfox.image.doSimulateRelaxation", m_SignalGen.m_DoSimulateRelaxation);
+ parameters.put("fiberfox.image.doDisablePartialVolume", m_SignalGen.m_DoDisablePartialVolume);
+ parameters.put("fiberfox.image.artifacts.spikesnum", m_SignalGen.m_Spikes);
+ parameters.put("fiberfox.image.artifacts.spikesscale", m_SignalGen.m_SpikeAmplitude);
+ parameters.put("fiberfox.image.artifacts.kspaceLineOffset", m_SignalGen.m_KspaceLineOffset);
+ parameters.put("fiberfox.image.artifacts.eddyStrength", m_SignalGen.m_EddyStrength);
+ parameters.put("fiberfox.image.artifacts.eddyTau", m_SignalGen.m_Tau);
+ parameters.put("fiberfox.image.artifacts.aliasingfactor", m_SignalGen.m_CroppingFactor);
+ parameters.put("fiberfox.image.artifacts.addringing", m_SignalGen.m_DoAddGibbsRinging);
+ parameters.put("fiberfox.image.artifacts.doAddMotion", m_SignalGen.m_DoAddMotion);
+ parameters.put("fiberfox.image.artifacts.randomMotion", m_SignalGen.m_DoRandomizeMotion);
+ parameters.put("fiberfox.image.artifacts.translation0", m_SignalGen.m_Translation[0]);
+ parameters.put("fiberfox.image.artifacts.translation1", m_SignalGen.m_Translation[1]);
+ parameters.put("fiberfox.image.artifacts.translation2", m_SignalGen.m_Translation[2]);
+ parameters.put("fiberfox.image.artifacts.rotation0", m_SignalGen.m_Rotation[0]);
+ parameters.put("fiberfox.image.artifacts.rotation1", m_SignalGen.m_Rotation[1]);
+ parameters.put("fiberfox.image.artifacts.rotation2", m_SignalGen.m_Rotation[2]);
+
+ parameters.put("fiberfox.image.artifacts.addnoise", m_Misc.m_CheckAddNoiseBox);
+ parameters.put("fiberfox.image.artifacts.addghosts", m_Misc.m_CheckAddGhostsBox);
+ parameters.put("fiberfox.image.artifacts.addaliasing", m_Misc.m_CheckAddAliasingBox);
+ parameters.put("fiberfox.image.artifacts.addspikes", m_Misc.m_CheckAddSpikesBox);
+ parameters.put("fiberfox.image.artifacts.addeddycurrents", m_Misc.m_CheckAddEddyCurrentsBox);
+ parameters.put("fiberfox.image.artifacts.doAddDistortions", m_Misc.m_CheckAddDistortionsBox);
+ parameters.put("fiberfox.image.outputvolumefractions", m_Misc.m_CheckOutputVolumeFractionsBox);
+ parameters.put("fiberfox.image.showadvanced", m_Misc.m_CheckAdvancedSignalOptionsBox);
+ parameters.put("fiberfox.image.signalmodelstring", m_Misc.m_SignalModelString);
+ parameters.put("fiberfox.image.artifactmodelstring", m_Misc.m_ArtifactModelString);
+ parameters.put("fiberfox.image.outpath", m_Misc.m_OutputPath);
+ parameters.put("fiberfox.fibers.realtime", m_Misc.m_CheckRealTimeFibersBox);
+ parameters.put("fiberfox.fibers.showadvanced", m_Misc.m_CheckAdvancedFiberOptionsBox);
+ parameters.put("fiberfox.fibers.constantradius", m_Misc.m_CheckConstantRadiusBox);
+ parameters.put("fiberfox.fibers.includeFiducials", m_Misc.m_CheckIncludeFiducialsBox);
+
if (m_NoiseModel!=NULL)
- delete m_NoiseModel;
+ {
+ parameters.put("fiberfox.image.artifacts.noisevariance", m_NoiseModel->GetNoiseVariance());
+ if (dynamic_cast<mitk::RicianNoiseModel<ScalarType>*>(m_NoiseModel))
+ parameters.put("fiberfox.image.artifacts.noisetype", "rice");
+ else if (dynamic_cast<mitk::ChiSquareNoiseModel<ScalarType>*>(m_NoiseModel))
+ parameters.put("fiberfox.image.artifacts.noisetype", "chisquare");
+ }
- BOOST_FOREACH( boost::property_tree::ptree::value_type const& v1, parameters.get_child("fiberfox") )
+ for (int i=0; i<m_FiberModelList.size()+m_NonFiberModelList.size(); i++)
{
- if( v1.first == "image" )
+ mitk::DiffusionSignalModel<ScalarType>* signalModel = NULL;
+ if (i<m_FiberModelList.size())
+ {
+ signalModel = m_FiberModelList.at(i);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".type", "fiber");
+ }
+ else
{
- m_ImageRegion.SetSize(0, v1.second.get<int>("basic.size.x"));
- m_ImageRegion.SetSize(1, v1.second.get<int>("basic.size.y"));
- m_ImageRegion.SetSize(2, v1.second.get<int>("basic.size.z"));
- m_ImageSpacing[0] = v1.second.get<double>("basic.spacing.x");
- m_ImageSpacing[1] = v1.second.get<double>("basic.spacing.y");
- m_ImageSpacing[2] = v1.second.get<double>("basic.spacing.z");
- m_NumGradients = v1.second.get<int>("basic.numgradients");
- GenerateGradientHalfShell();
- m_Bvalue = v1.second.get<int>("basic.bvalue");
- m_SignalScale = v1.second.get<int>("signalScale");
- m_tEcho = v1.second.get<double>("tEcho");
- m_tLine = v1.second.get<double>("tLine");
- m_tInhom = v1.second.get<double>("tInhom");
- m_AxonRadius = v1.second.get<double>("axonRadius");
- m_DoSimulateRelaxation = v1.second.get<bool>("doSimulateRelaxation");
- m_DoDisablePartialVolume = v1.second.get<bool>("doDisablePartialVolume");
- if (v1.second.get<bool>("artifacts.addnoise"))
+ signalModel = m_NonFiberModelList.at(i-m_FiberModelList.size());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".type", "non-fiber");
+ }
+
+ if (dynamic_cast<mitk::StickModel<ScalarType>*>(signalModel))
+ {
+ mitk::StickModel<ScalarType>* model = dynamic_cast<mitk::StickModel<ScalarType>*>(signalModel);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".model", "stick");
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".d", model->GetDiffusivity());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".t2", model->GetT2());
+ }
+ else if (dynamic_cast<mitk::TensorModel<ScalarType>*>(signalModel))
+ {
+ mitk::TensorModel<ScalarType>* model = dynamic_cast<mitk::TensorModel<ScalarType>*>(signalModel);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".model", "tensor");
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".d1", model->GetDiffusivity1());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".d2", model->GetDiffusivity2());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".d3", model->GetDiffusivity3());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".t2", model->GetT2());
+ }
+ else if (dynamic_cast<mitk::RawShModel<ScalarType>*>(signalModel))
+ {
+ mitk::RawShModel<ScalarType>* model = dynamic_cast<mitk::RawShModel<ScalarType>*>(signalModel);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".model", "prototype");
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".minFA", model->GetFaRange().first);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".maxFA", model->GetFaRange().second);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".minADC", model->GetAdcRange().first);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".maxADC", model->GetAdcRange().second);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".maxNumSamples", model->GetMaxNumKernels());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".numSamples", model->GetNumberOfKernels());
+ int shOrder = model->GetShOrder();
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".numCoeffs", (shOrder*shOrder + shOrder + 2)/2 + shOrder);
+
+ for (unsigned int j=0; j<model->GetNumberOfKernels(); j++)
{
- switch (v1.second.get<int>("artifacts.noisedistribution"))
- {
- case 0:
- {
- m_NoiseModel = new mitk::RicianNoiseModel< ScalarType >();
- break;
- }
- case 1:
- {
- m_NoiseModel = new mitk::ChiSquareNoiseModel< ScalarType >();
- break;
+ vnl_vector< double > coeffs = model->GetCoefficients(j);
+ for (unsigned int k=0; k<coeffs.size(); k++)
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".kernels."+boost::lexical_cast<string>(j)+".coeffs."+boost::lexical_cast<string>(k), coeffs[k]);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".kernels."+boost::lexical_cast<string>(j)+".B0", model->GetBaselineSignal(j));
+ }
+ }
+ else if (dynamic_cast<mitk::BallModel<ScalarType>*>(signalModel))
+ {
+ mitk::BallModel<ScalarType>* model = dynamic_cast<mitk::BallModel<ScalarType>*>(signalModel);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".model", "ball");
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".d", model->GetDiffusivity());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".t2", model->GetT2());
+ }
+ else if (dynamic_cast<mitk::AstroStickModel<ScalarType>*>(signalModel))
+ {
+ mitk::AstroStickModel<ScalarType>* model = dynamic_cast<mitk::AstroStickModel<ScalarType>*>(signalModel);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".model", "astrosticks");
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".d", model->GetDiffusivity());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".t2", model->GetT2());
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".randomize", model->GetRandomizeSticks());
+ }
+ else if (dynamic_cast<mitk::DotModel<ScalarType>*>(signalModel))
+ {
+ mitk::DotModel<ScalarType>* model = dynamic_cast<mitk::DotModel<ScalarType>*>(signalModel);
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".model", "dot");
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".t2", model->GetT2());
+ }
+
+ if (signalModel!=NULL)
+ {
+ parameters.put("fiberfox.image.compartments."+boost::lexical_cast<string>(i)+".ID", signalModel->m_CompartmentId);
+
+ if (signalModel->GetVolumeFractionImage().IsNotNull())
+ {
+ try{
+ itk::ImageFileWriter<ItkDoubleImgType>::Pointer writer = itk::ImageFileWriter<ItkDoubleImgType>::New();
+ writer->SetFileName(filename+"_VOLUME"+boost::lexical_cast<string>(signalModel->m_CompartmentId)+".nrrd");
+ writer->SetInput(signalModel->GetVolumeFractionImage());
+ writer->Update();
+ MITK_INFO << "Volume fraction image for compartment "+boost::lexical_cast<string>(signalModel->m_CompartmentId)+" saved.";
}
- default:
+ catch(...)
{
- m_NoiseModel = new mitk::RicianNoiseModel< ScalarType >();
- }
}
- m_NoiseModel->SetNoiseVariance(v1.second.get<double>("artifacts.noisevariance"));
}
+ }
+ }
- m_KspaceLineOffset = v1.second.get<double>("artifacts.kspaceLineOffset");
- m_CroppingFactor = (100-v1.second.get<double>("artifacts.aliasingfactor"))/100;
- m_Spikes = v1.second.get<int>("artifacts.spikesnum");
- m_SpikeAmplitude = v1.second.get<double>("artifacts.spikesscale");
- m_EddyStrength = v1.second.get<double>("artifacts.eddyStrength");
- m_DoAddGibbsRinging = v1.second.get<bool>("artifacts.addringing");
- m_DoAddMotion = v1.second.get<bool>("artifacts.doAddMotion");
- m_DoRandomizeMotion = v1.second.get<bool>("artifacts.randomMotion");
- m_Translation[0] = v1.second.get<double>("artifacts.translation0");
- m_Translation[1] = v1.second.get<double>("artifacts.translation1");
- m_Translation[2] = v1.second.get<double>("artifacts.translation2");
- m_Rotation[0] = v1.second.get<double>("artifacts.rotation0");
- m_Rotation[1] = v1.second.get<double>("artifacts.rotation1");
- m_Rotation[2] = v1.second.get<double>("artifacts.rotation2");
-
- // compartment 1
- switch (v1.second.get<int>("compartment1.index"))
- {
- case 0:
- {
- mitk::StickModel<double>* stickModel = new mitk::StickModel<double>();
- stickModel->SetGradientList(m_GradientDirections);
- stickModel->SetBvalue(m_Bvalue);
- stickModel->SetDiffusivity(v1.second.get<double>("compartment1.stick.d"));
- stickModel->SetT2(v1.second.get<double>("compartment1.stick.t2"));
- m_FiberModelList.push_back(stickModel);
- break;
- }
- case 1:
- {
- mitk::TensorModel<double>* zeppelinModel = new mitk::TensorModel<double>();
- zeppelinModel->SetGradientList(m_GradientDirections);
- zeppelinModel->SetBvalue(m_Bvalue);
- zeppelinModel->SetDiffusivity1(v1.second.get<double>("compartment1.zeppelin.d1"));
- zeppelinModel->SetDiffusivity2(v1.second.get<double>("compartment1.zeppelin.d2"));
- zeppelinModel->SetDiffusivity3(v1.second.get<double>("compartment1.zeppelin.d2"));
- zeppelinModel->SetT2(v1.second.get<double>("compartment1.zeppelin.t2"));
- m_FiberModelList.push_back(zeppelinModel);
- break;
- }
- case 2:
- {
- mitk::TensorModel<double>* tensorModel = new mitk::TensorModel<double>();
- tensorModel->SetGradientList(m_GradientDirections);
- tensorModel->SetBvalue(m_Bvalue);
- tensorModel->SetDiffusivity1(v1.second.get<double>("compartment1.tensor.d1"));
- tensorModel->SetDiffusivity2(v1.second.get<double>("compartment1.tensor.d2"));
- tensorModel->SetDiffusivity3(v1.second.get<double>("compartment1.tensor.d3"));
- tensorModel->SetT2(v1.second.get<double>("compartment1.tensor.t2"));
- m_FiberModelList.push_back(tensorModel);
- break;
- }
- }
+ boost::property_tree::xml_writer_settings<char> writerSettings(' ', 2);
+ boost::property_tree::xml_parser::write_xml(filename, parameters, std::locale(), writerSettings);
- // compartment 2
- switch (v1.second.get<int>("compartment2.index"))
+ try{
+ itk::ImageFileWriter<ItkDoubleImgType>::Pointer writer = itk::ImageFileWriter<ItkDoubleImgType>::New();
+ writer->SetFileName(filename+"_FMAP.nrrd");
+ writer->SetInput(m_SignalGen.m_FrequencyMap);
+ writer->Update();
+ }
+ catch(...)
+ {
+ MITK_INFO << "No frequency map saved.";
+ }
+ try{
+ itk::ImageFileWriter<ItkUcharImgType>::Pointer writer = itk::ImageFileWriter<ItkUcharImgType>::New();
+ writer->SetFileName(filename+"_MASK.nrrd");
+ writer->SetInput(m_SignalGen.m_MaskImage);
+ writer->Update();
+ }
+ catch(...)
+ {
+ MITK_INFO << "No mask image saved.";
+ }
+}
+
+template< class ScalarType >
+void mitk::FiberfoxParameters< ScalarType >::LoadParameters(string filename)
+{
+ if(filename.empty())
+ return;
+
+ boost::property_tree::ptree parameterTree;
+ boost::property_tree::xml_parser::read_xml(filename, parameterTree);
+
+ m_FiberModelList.clear();
+ m_NonFiberModelList.clear();
+ if (m_NoiseModel!=NULL)
+ delete m_NoiseModel;
+
+ BOOST_FOREACH( boost::property_tree::ptree::value_type const& v1, parameterTree.get_child("fiberfox") )
+ {
+ if( v1.first == "fibers" )
+ {
+ m_Misc.m_CheckRealTimeFibersBox = v1.second.get<bool>("realtime", m_Misc.m_CheckRealTimeFibersBox);
+ m_Misc.m_CheckAdvancedFiberOptionsBox = v1.second.get<bool>("showadvanced", m_Misc.m_CheckAdvancedFiberOptionsBox);
+ m_Misc.m_CheckConstantRadiusBox = v1.second.get<bool>("constantradius", m_Misc.m_CheckConstantRadiusBox);
+ m_Misc.m_CheckIncludeFiducialsBox = v1.second.get<bool>("includeFiducials", m_Misc.m_CheckIncludeFiducialsBox);
+
+ switch (v1.second.get<unsigned int>("distribution", 0))
{
case 0:
- {
- mitk::StickModel<double>* stickModel = new mitk::StickModel<double>();
- stickModel->SetGradientList(m_GradientDirections);
- stickModel->SetBvalue(m_Bvalue);
- stickModel->SetDiffusivity(v1.second.get<double>("compartment2.stick.d"));
- stickModel->SetT2(v1.second.get<double>("compartment2.stick.t2"));
- m_FiberModelList.push_back(stickModel);
+ m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
break;
- }
case 1:
- {
- mitk::TensorModel<double>* zeppelinModel = new mitk::TensorModel<double>();
- zeppelinModel->SetGradientList(m_GradientDirections);
- zeppelinModel->SetBvalue(m_Bvalue);
- zeppelinModel->SetDiffusivity1(v1.second.get<double>("compartment2.zeppelin.d1"));
- zeppelinModel->SetDiffusivity2(v1.second.get<double>("compartment2.zeppelin.d2"));
- zeppelinModel->SetDiffusivity3(v1.second.get<double>("compartment2.zeppelin.d2"));
- zeppelinModel->SetT2(v1.second.get<double>("compartment2.zeppelin.t2"));
- m_FiberModelList.push_back(zeppelinModel);
+ m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_GAUSSIAN;
break;
+ default:
+ m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
}
- case 2:
- {
- mitk::TensorModel<double>* tensorModel = new mitk::TensorModel<double>();
- tensorModel->SetGradientList(m_GradientDirections);
- tensorModel->SetBvalue(m_Bvalue);
- tensorModel->SetDiffusivity1(v1.second.get<double>("compartment2.tensor.d1"));
- tensorModel->SetDiffusivity2(v1.second.get<double>("compartment2.tensor.d2"));
- tensorModel->SetDiffusivity3(v1.second.get<double>("compartment2.tensor.d3"));
- tensorModel->SetT2(v1.second.get<double>("compartment2.tensor.t2"));
- m_FiberModelList.push_back(tensorModel);
- break;
- }
- }
-
- // compartment 3
- switch (v1.second.get<int>("compartment3.index"))
+ m_FiberGen.m_Variance = v1.second.get<double>("variance", m_FiberGen.m_Variance);
+ m_FiberGen.m_Density = v1.second.get<unsigned int>("density", m_FiberGen.m_Density);
+ m_FiberGen.m_Sampling = v1.second.get<double>("spline.sampling", m_FiberGen.m_Sampling);
+ m_FiberGen.m_Tension = v1.second.get<double>("spline.tension", m_FiberGen.m_Tension);
+ m_FiberGen.m_Continuity = v1.second.get<double>("spline.continuity", m_FiberGen.m_Continuity);
+ m_FiberGen.m_Bias = v1.second.get<double>("spline.bias", m_FiberGen.m_Bias);
+ m_FiberGen.m_Rotation[0] = v1.second.get<double>("rotation.x", m_FiberGen.m_Rotation[0]);
+ m_FiberGen.m_Rotation[1] = v1.second.get<double>("rotation.y", m_FiberGen.m_Rotation[1]);
+ m_FiberGen.m_Rotation[2] = v1.second.get<double>("rotation.z", m_FiberGen.m_Rotation[2]);
+ m_FiberGen.m_Translation[0] = v1.second.get<double>("translation.x", m_FiberGen.m_Translation[0]);
+ m_FiberGen.m_Translation[1] = v1.second.get<double>("translation.y", m_FiberGen.m_Translation[1]);
+ m_FiberGen.m_Translation[2] = v1.second.get<double>("translation.z", m_FiberGen.m_Translation[2]);
+ m_FiberGen.m_Scale[0] = v1.second.get<double>("scale.x", m_FiberGen.m_Scale[0]);
+ m_FiberGen.m_Scale[1] = v1.second.get<double>("scale.y", m_FiberGen.m_Scale[1]);
+ m_FiberGen.m_Scale[2] = v1.second.get<double>("scale.z", m_FiberGen.m_Scale[2]);
+ }
+ else if ( v1.first == "image" )
+ {
+ m_Misc.m_SignalModelString = v1.second.get<string>("signalmodelstring", m_Misc.m_SignalModelString);
+ m_Misc.m_ArtifactModelString = v1.second.get<string>("artifactmodelstring", m_Misc.m_ArtifactModelString);
+ m_Misc.m_OutputPath = v1.second.get<string>("outpath", m_Misc.m_OutputPath);
+ m_Misc.m_CheckOutputVolumeFractionsBox = v1.second.get<bool>("outputvolumefractions", m_Misc.m_CheckOutputVolumeFractionsBox);
+ m_Misc.m_CheckAdvancedSignalOptionsBox = v1.second.get<bool>("showadvanced", m_Misc.m_CheckAdvancedSignalOptionsBox);
+ m_Misc.m_CheckAddDistortionsBox = v1.second.get<bool>("artifacts.doAddDistortions", m_Misc.m_CheckAddDistortionsBox);
+ m_Misc.m_CheckAddNoiseBox = v1.second.get<bool>("artifacts.addnoise", m_Misc.m_CheckAddNoiseBox);
+ m_Misc.m_CheckAddGhostsBox = v1.second.get<bool>("artifacts.addghosts", m_Misc.m_CheckAddGhostsBox);
+ m_Misc.m_CheckAddAliasingBox = v1.second.get<bool>("artifacts.addaliasing", m_Misc.m_CheckAddAliasingBox);
+ m_Misc.m_CheckAddSpikesBox = v1.second.get<bool>("artifacts.addspikes", m_Misc.m_CheckAddSpikesBox);
+ m_Misc.m_CheckAddEddyCurrentsBox = v1.second.get<bool>("artifacts.addeddycurrents", m_Misc.m_CheckAddEddyCurrentsBox);
+
+ m_SignalGen.m_ImageRegion.SetSize(0, v1.second.get<int>("basic.size.x",m_SignalGen.m_ImageRegion.GetSize(0)));
+ m_SignalGen.m_ImageRegion.SetSize(1, v1.second.get<int>("basic.size.y",m_SignalGen.m_ImageRegion.GetSize(1)));
+ m_SignalGen.m_ImageRegion.SetSize(2, v1.second.get<int>("basic.size.z",m_SignalGen.m_ImageRegion.GetSize(2)));
+ m_SignalGen.m_ImageSpacing[0] = v1.second.get<double>("basic.spacing.x",m_SignalGen.m_ImageSpacing[0]);
+ m_SignalGen.m_ImageSpacing[1] = v1.second.get<double>("basic.spacing.y",m_SignalGen.m_ImageSpacing[1]);
+ m_SignalGen.m_ImageSpacing[2] = v1.second.get<double>("basic.spacing.z",m_SignalGen.m_ImageSpacing[2]);
+ m_SignalGen.m_ImageOrigin[0] = v1.second.get<double>("basic.origin.x",m_SignalGen.m_ImageOrigin[0]);
+ m_SignalGen.m_ImageOrigin[1] = v1.second.get<double>("basic.origin.y",m_SignalGen.m_ImageOrigin[1]);
+ m_SignalGen.m_ImageOrigin[2] = v1.second.get<double>("basic.origin.z",m_SignalGen.m_ImageOrigin[2]);
+ m_SignalGen.m_ImageDirection[0][0] = v1.second.get<double>("basic.direction.1",m_SignalGen.m_ImageDirection[0][0]);
+ m_SignalGen.m_ImageDirection[0][1] = v1.second.get<double>("basic.direction.2",m_SignalGen.m_ImageDirection[0][1]);
+ m_SignalGen.m_ImageDirection[0][2] = v1.second.get<double>("basic.direction.3",m_SignalGen.m_ImageDirection[0][2]);
+ m_SignalGen.m_ImageDirection[1][0] = v1.second.get<double>("basic.direction.4",m_SignalGen.m_ImageDirection[1][0]);
+ m_SignalGen.m_ImageDirection[1][1] = v1.second.get<double>("basic.direction.5",m_SignalGen.m_ImageDirection[1][1]);
+ m_SignalGen.m_ImageDirection[1][2] = v1.second.get<double>("basic.direction.6",m_SignalGen.m_ImageDirection[1][2]);
+ m_SignalGen.m_ImageDirection[2][0] = v1.second.get<double>("basic.direction.7",m_SignalGen.m_ImageDirection[2][0]);
+ m_SignalGen.m_ImageDirection[2][1] = v1.second.get<double>("basic.direction.8",m_SignalGen.m_ImageDirection[2][1]);
+ m_SignalGen.m_ImageDirection[2][2] = v1.second.get<double>("basic.direction.9",m_SignalGen.m_ImageDirection[2][2]);
+
+ m_SignalGen.m_SignalScale = v1.second.get<double>("signalScale", m_SignalGen.m_SignalScale);
+ m_SignalGen.m_tEcho = v1.second.get<double>("tEcho", m_SignalGen.m_tEcho);
+ m_SignalGen.m_tLine = v1.second.get<double>("tLine", m_SignalGen.m_tLine);
+ m_SignalGen.m_tInhom = v1.second.get<double>("tInhom", m_SignalGen.m_tInhom);
+ m_SignalGen.m_Bvalue = v1.second.get<double>("bvalue", m_SignalGen.m_Bvalue);
+ m_SignalGen.m_SimulateKspaceAcquisition = v1.second.get<bool>("simulatekspace", m_SignalGen.m_SimulateKspaceAcquisition);
+
+ m_SignalGen.m_AxonRadius = v1.second.get<double>("axonRadius", m_SignalGen.m_AxonRadius);
+ switch (v1.second.get<int>("diffusiondirectionmode", 0))
{
case 0:
- {
- mitk::BallModel<double>* ballModel = new mitk::BallModel<double>();
- ballModel->SetGradientList(m_GradientDirections);
- ballModel->SetBvalue(m_Bvalue);
- ballModel->SetDiffusivity(v1.second.get<double>("compartment3.ball.d"));
- ballModel->SetT2(v1.second.get<double>("compartment3.ball.t2"));
- m_NonFiberModelList.push_back(ballModel);
+ m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS;
break;
- }
case 1:
- {
- mitk::AstroStickModel<double>* astrosticksModel = new mitk::AstroStickModel<double>();
- astrosticksModel->SetGradientList(m_GradientDirections);
- astrosticksModel->SetBvalue(m_Bvalue);
- astrosticksModel->SetDiffusivity(v1.second.get<double>("compartment3.astrosticks.d"));
- astrosticksModel->SetT2(v1.second.get<double>("compartment3.astrosticks.t2"));
- astrosticksModel->SetRandomizeSticks(v1.second.get<bool>("compartment3.astrosticks.randomize"));
- m_NonFiberModelList.push_back(astrosticksModel);
+ m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::MAIN_FIBER_DIRECTIONS;
break;
- }
case 2:
- {
- mitk::DotModel<double>* dotModel = new mitk::DotModel<double>();
- dotModel->SetGradientList(m_GradientDirections);
- dotModel->SetT2(v1.second.get<double>("compartment3.dot.t2"));
- m_NonFiberModelList.push_back(dotModel);
+ m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::RANDOM_DIRECTIONS;
break;
+ default:
+ m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS;
}
+ m_SignalGen.m_FiberSeparationThreshold = v1.second.get<double>("fiberseparationthreshold", m_SignalGen.m_FiberSeparationThreshold);
+ m_SignalGen.m_Spikes = v1.second.get<unsigned int>("artifacts.spikesnum", m_SignalGen.m_Spikes);
+ m_SignalGen.m_SpikeAmplitude = v1.second.get<double>("artifacts.spikesscale", m_SignalGen.m_SpikeAmplitude);
+ m_SignalGen.m_KspaceLineOffset = v1.second.get<double>("artifacts.kspaceLineOffset", m_SignalGen.m_KspaceLineOffset);
+ m_SignalGen.m_EddyStrength = v1.second.get<double>("artifacts.eddyStrength", m_SignalGen.m_EddyStrength);
+ m_SignalGen.m_Tau = v1.second.get<double>("artifacts.eddyTau", m_SignalGen.m_Tau);
+ m_SignalGen.m_CroppingFactor = v1.second.get<double>("artifacts.aliasingfactor", m_SignalGen.m_CroppingFactor);
+ m_SignalGen.m_DoAddGibbsRinging = v1.second.get<bool>("artifacts.addringing", m_SignalGen.m_DoAddGibbsRinging);
+ m_SignalGen.m_DoSimulateRelaxation = v1.second.get<bool>("doSimulateRelaxation", m_SignalGen.m_DoSimulateRelaxation);
+ m_SignalGen.m_DoDisablePartialVolume = v1.second.get<bool>("doDisablePartialVolume", m_SignalGen.m_DoDisablePartialVolume);
+ m_SignalGen.m_DoAddMotion = v1.second.get<bool>("artifacts.doAddMotion", m_SignalGen.m_DoAddMotion);
+ m_SignalGen.m_DoRandomizeMotion = v1.second.get<bool>("artifacts.randomMotion", m_SignalGen.m_DoRandomizeMotion);
+ m_SignalGen.m_Translation[0] = v1.second.get<double>("artifacts.translation0", m_SignalGen.m_Translation[0]);
+ m_SignalGen.m_Translation[1] = v1.second.get<double>("artifacts.translation1", m_SignalGen.m_Translation[1]);
+ m_SignalGen.m_Translation[2] = v1.second.get<double>("artifacts.translation2", m_SignalGen.m_Translation[2]);
+ m_SignalGen.m_Rotation[0] = v1.second.get<double>("artifacts.rotation0", m_SignalGen.m_Rotation[0]);
+ m_SignalGen.m_Rotation[1] = v1.second.get<double>("artifacts.rotation1", m_SignalGen.m_Rotation[1]);
+ m_SignalGen.m_Rotation[2] = v1.second.get<double>("artifacts.rotation2", m_SignalGen.m_Rotation[2]);
+// m_SignalGen.SetNumWeightedVolumes(v1.second.get<unsigned int>("numgradients", m_SignalGen.GetNumWeightedVolumes()));
+ SignalGenerationParameters::GradientListType gradients;
+ BOOST_FOREACH( boost::property_tree::ptree::value_type const& v2, v1.second.get_child("gradients") )
+ {
+ SignalGenerationParameters::GradientType g;
+ g[0] = v2.second.get<double>("x");
+ g[1] = v2.second.get<double>("y");
+ g[2] = v2.second.get<double>("z");
+ gradients.push_back(g);
}
+ m_SignalGen.SetGradienDirections(gradients);
- // compartment 4
- switch (v1.second.get<int>("compartment4.index"))
- {
- case 0:
+ try
{
- mitk::BallModel<double>* ballModel = new mitk::BallModel<double>();
- ballModel->SetGradientList(m_GradientDirections);
- ballModel->SetBvalue(m_Bvalue);
- ballModel->SetDiffusivity(v1.second.get<double>("compartment4.ball.d"));
- ballModel->SetT2(v1.second.get<double>("compartment4.ball.t2"));
- m_NonFiberModelList.push_back(ballModel);
- break;
+ if (v1.second.get<string>("artifacts.noisetype")=="rice")
+ {
+ m_NoiseModel = new mitk::RicianNoiseModel<ScalarType>();
+ m_NoiseModel->SetNoiseVariance(v1.second.get<double>("artifacts.noisevariance"));
+ }
}
- case 1:
+ catch(...) {}
+ try
{
- mitk::AstroStickModel<double>* astrosticksModel = new mitk::AstroStickModel<double>();
- astrosticksModel->SetGradientList(m_GradientDirections);
- astrosticksModel->SetBvalue(m_Bvalue);
- astrosticksModel->SetDiffusivity(v1.second.get<double>("compartment4.astrosticks.d"));
- astrosticksModel->SetT2(v1.second.get<double>("compartment4.astrosticks.t2"));
- astrosticksModel->SetRandomizeSticks(v1.second.get<bool>("compartment4.astrosticks.randomize"));
- m_NonFiberModelList.push_back(astrosticksModel);
- break;
+ if (v1.second.get<string>("artifacts.noisetype")=="chisquare")
+ {
+ m_NoiseModel = new mitk::ChiSquareNoiseModel<ScalarType>();
+ m_NoiseModel->SetNoiseVariance(v1.second.get<double>("artifacts.noisevariance"));
+ }
}
- case 2:
+ catch(...){ }
+
+ BOOST_FOREACH( boost::property_tree::ptree::value_type const& v2, v1.second.get_child("compartments") )
{
- mitk::DotModel<double>* dotModel = new mitk::DotModel<double>();
- dotModel->SetGradientList(m_GradientDirections);
- dotModel->SetT2(v1.second.get<double>("compartment4.dot.t2"));
- m_NonFiberModelList.push_back(dotModel);
- break;
- }
+ mitk::DiffusionSignalModel<ScalarType>* signalModel = NULL;
+
+ std::string model = v2.second.get<string>("model");
+ if (model=="stick")
+ {
+ mitk::StickModel<ScalarType>* model = new mitk::StickModel<ScalarType>();
+ model->SetDiffusivity(v2.second.get<double>("d"));
+ model->SetT2(v2.second.get<double>("t2"));
+ model->m_CompartmentId = v2.second.get<unsigned int>("ID");
+ if (v2.second.get<string>("type")=="fiber")
+ m_FiberModelList.push_back(model);
+ else if (v2.second.get<string>("type")=="non-fiber")
+ m_NonFiberModelList.push_back(model);
+ signalModel = model;
+ }
+ else if (model=="tensor")
+ {
+ mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
+ model->SetDiffusivity1(v2.second.get<double>("d1"));
+ model->SetDiffusivity2(v2.second.get<double>("d2"));
+ model->SetDiffusivity3(v2.second.get<double>("d3"));
+ model->SetT2(v2.second.get<double>("t2"));
+ model->m_CompartmentId = v2.second.get<unsigned int>("ID");
+ if (v2.second.get<string>("type")=="fiber")
+ m_FiberModelList.push_back(model);
+ else if (v2.second.get<string>("type")=="non-fiber")
+ m_NonFiberModelList.push_back(model);
+ signalModel = model;
+ }
+ else if (model=="ball")
+ {
+ mitk::BallModel<ScalarType>* model = new mitk::BallModel<ScalarType>();
+ model->SetDiffusivity(v2.second.get<double>("d"));
+ model->SetT2(v2.second.get<double>("t2"));
+ model->m_CompartmentId = v2.second.get<unsigned int>("ID");
+ if (v2.second.get<string>("type")=="fiber")
+ m_FiberModelList.push_back(model);
+ else if (v2.second.get<string>("type")=="non-fiber")
+ m_NonFiberModelList.push_back(model);
+ signalModel = model;
+ }
+ else if (model=="astrosticks")
+ {
+ mitk::AstroStickModel<ScalarType>* model = new AstroStickModel<ScalarType>();
+ model->SetDiffusivity(v2.second.get<double>("d"));
+ model->SetT2(v2.second.get<double>("t2"));
+ model->SetRandomizeSticks(v2.second.get<bool>("randomize"));
+ model->m_CompartmentId = v2.second.get<unsigned int>("ID");
+ if (v2.second.get<string>("type")=="fiber")
+ m_FiberModelList.push_back(model);
+ else if (v2.second.get<string>("type")=="non-fiber")
+ m_NonFiberModelList.push_back(model);
+ signalModel = model;
+ }
+ else if (model=="dot")
+ {
+ mitk::DotModel<ScalarType>* model = new mitk::DotModel<ScalarType>();
+ model->SetT2(v2.second.get<double>("t2"));
+ model->m_CompartmentId = v2.second.get<unsigned int>("ID");
+ if (v2.second.get<string>("type")=="fiber")
+ m_FiberModelList.push_back(model);
+ else if (v2.second.get<string>("type")=="non-fiber")
+ m_NonFiberModelList.push_back(model);
+ signalModel = model;
+ }
+ else if (model=="prototype")
+ {
+ mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
+ model->SetMaxNumKernels(v2.second.get<unsigned int>("maxNumSamples"));
+ model->SetFaRange(v2.second.get<double>("minFA"), v2.second.get<double>("maxFA"));
+ model->SetAdcRange(v2.second.get<double>("minADC"), v2.second.get<double>("maxADC"));
+ model->m_CompartmentId = v2.second.get<unsigned int>("ID");
+ unsigned int numCoeffs = v2.second.get<unsigned int>("numCoeffs");
+ unsigned int numSamples = v2.second.get<unsigned int>("numSamples");
+
+ for (unsigned int j=0; j<numSamples; j++)
+ {
+ vnl_vector< double > coeffs(numCoeffs);
+ for (unsigned int k=0; k<numCoeffs; k++)
+ {
+ coeffs[k] = v2.second.get<double>("kernels."+boost::lexical_cast<string>(j)+".coeffs."+boost::lexical_cast<string>(k));
+ }
+ model->SetShCoefficients( coeffs, v2.second.get<double>("kernels."+boost::lexical_cast<string>(j)+".B0") );
+ }
+
+ if (v2.second.get<string>("type")=="fiber")
+ m_FiberModelList.push_back(model);
+ else if (v2.second.get<string>("type")=="non-fiber")
+ m_NonFiberModelList.push_back(model);
+ signalModel = model;
+ }
+
+ if (signalModel!=NULL)
+ {
+ signalModel->SetGradientList(gradients);
+ try{
+ itk::ImageFileReader<ItkDoubleImgType>::Pointer reader = itk::ImageFileReader<ItkDoubleImgType>::New();
+ reader->SetFileName(filename+"_VOLUME"+v2.second.get<string>("ID")+".nrrd");
+ reader->Update();
+ signalModel->SetVolumeFractionImage(reader->GetOutput());
+ }
+ catch(...)
+ {
+ }
+ }
}
}
}
+
+ try{
+ itk::ImageFileReader<ItkDoubleImgType>::Pointer reader = itk::ImageFileReader<ItkDoubleImgType>::New();
+ reader->SetFileName(filename+"_FMAP.nrrd");
+ reader->Update();
+ m_SignalGen.m_FrequencyMap = reader->GetOutput();
+ }
+ catch(...)
+ {
+ MITK_INFO << "No frequency map saved.";
+ }
+
+ try{
+ itk::ImageFileReader<ItkUcharImgType>::Pointer reader = itk::ImageFileReader<ItkUcharImgType>::New();
+ reader->SetFileName(filename+"_MASK.nrrd");
+ reader->Update();
+ m_SignalGen.m_MaskImage = reader->GetOutput();
+ }
+ catch(...)
+ {
+ MITK_INFO << "No mask image saved.";
+ }
}
template< class ScalarType >
void mitk::FiberfoxParameters< ScalarType >::PrintSelf()
{
- MITK_INFO << "m_ImageRegion: " << m_ImageRegion;
- MITK_INFO << "m_ImageSpacing: " << m_ImageSpacing;
- MITK_INFO << "m_ImageOrigin: " << m_ImageOrigin;
- MITK_INFO << "m_ImageDirection: " << m_ImageDirection;
- MITK_INFO << "m_NumGradients: " << m_NumGradients;
- MITK_INFO << "m_Bvalue: " << m_Bvalue;
- MITK_INFO << "m_SignalScale: " << m_SignalScale;
- MITK_INFO << "m_tEcho: " << m_tEcho;
- MITK_INFO << "m_tLine: " << m_tLine;
- MITK_INFO << "m_tInhom: " << m_tInhom;
- MITK_INFO << "m_AxonRadius: " << m_AxonRadius;
- MITK_INFO << "m_KspaceLineOffset: " << m_KspaceLineOffset;
- MITK_INFO << "m_AddGibbsRinging: " << m_DoAddGibbsRinging;
- MITK_INFO << "m_EddyStrength: " << m_EddyStrength;
- MITK_INFO << "m_Spikes: " << m_Spikes;
- MITK_INFO << "m_SpikeAmplitude: " << m_SpikeAmplitude;
- MITK_INFO << "m_CroppingFactor: " << m_CroppingFactor;
- MITK_INFO << "m_DoSimulateRelaxation: " << m_DoSimulateRelaxation;
- MITK_INFO << "m_DoDisablePartialVolume: " << m_DoDisablePartialVolume;
- MITK_INFO << "m_DoAddMotion: " << m_DoAddMotion;
- MITK_INFO << "m_RandomMotion: " << m_DoRandomizeMotion;
- MITK_INFO << "m_Translation: " << m_Translation;
- MITK_INFO << "m_Rotation: " << m_Rotation;
- MITK_INFO << "m_SignalModelString: " << m_SignalModelString;
- MITK_INFO << "m_ArtifactModelString: " << m_ArtifactModelString;
- MITK_INFO << "m_OutputPath: " << m_OutputPath;
+ MITK_INFO << "Not implemented :(";
}
diff --git a/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.h b/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.h
index c2a71cd84c..05370fdaac 100644
--- a/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.h
+++ b/Modules/DiffusionImaging/FiberTracking/IODataStructures/mitkFiberfoxParameters.h
@@ -1,187 +1,321 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_FiberfoxParameters_H
#define _MITK_FiberfoxParameters_H
#include <itkImageRegion.h>
#include <itkMatrix.h>
#include <mitkDiffusionNoiseModel.h>
#include <mitkDiffusionSignalModel.h>
#include <mitkDataNode.h>
#include <mitkRicianNoiseModel.h>
#include <mitkChiSquareNoiseModel.h>
#include <mitkDiffusionImage.h>
+#include <mitkPlanarEllipse.h>
+
+#include <mitkStickModel.h>
+#include <mitkTensorModel.h>
+#include <mitkAstroStickModel.h>
+#include <mitkBallModel.h>
+#include <mitkDotModel.h>
+#include <mitkRawShModel.h>
using namespace std;
namespace mitk {
-/**
- * \brief Datastructure to manage the Fiberfox signal generation parameters.
- *
- */
-
-template< class ScalarType = double >
-class FiberfoxParameters
+/** Signal generation */
+class SignalGenerationParameters
{
public:
+ typedef itk::Image<double, 3> ItkDoubleImgType;
+ typedef itk::Image<unsigned char, 3> ItkUcharImgType;
+ typedef itk::Vector<double,3> GradientType;
+ typedef std::vector<GradientType> GradientListType;
enum DiffusionDirectionMode {
FIBER_TANGENT_DIRECTIONS,
MAIN_FIBER_DIRECTIONS,
RANDOM_DIRECTIONS
};
- typedef itk::Image<double, 3> ItkDoubleImgType;
- typedef itk::Image<unsigned char, 3> ItkUcharImgType;
- typedef std::vector< DiffusionSignalModel<double>* > DiffusionModelListType;
- typedef DiffusionSignalModel<double>::GradientListType GradientListType;
- typedef DiffusionSignalModel<double>::GradientType GradientType;
- typedef DiffusionNoiseModel<ScalarType> NoiseModelType;
- typedef DiffusionSignalModel<double>* DiffusionModelType;
-
- FiberfoxParameters();
- ~FiberfoxParameters();
-
- /** Get same parameter object with different template parameter */
- template< class OutType > FiberfoxParameters< OutType > CopyParameters()
+ SignalGenerationParameters()
+ : m_SignalScale(100)
+ , m_tEcho(100)
+ , m_tLine(1)
+ , m_tInhom(50)
+ , m_Bvalue(1000)
+ , m_SimulateKspaceAcquisition(false)
+ , m_AxonRadius(0)
+ , m_DoDisablePartialVolume(false)
+ , m_DiffusionDirectionMode(SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS)
+ , m_FiberSeparationThreshold(30)
+ , m_Spikes(0)
+ , m_SpikeAmplitude(1)
+ , m_KspaceLineOffset(0)
+ , m_EddyStrength(0)
+ , m_Tau(70)
+ , m_CroppingFactor(1)
+ , m_DoAddGibbsRinging(false)
+ , m_DoSimulateRelaxation(true)
+ , m_DoAddMotion(false)
+ , m_DoRandomizeMotion(true)
+ , m_FrequencyMap(NULL)
+ , m_MaskImage(NULL)
{
- FiberfoxParameters< OutType > out;
-
- out.m_ImageRegion = m_ImageRegion;
- out.m_ImageSpacing = m_ImageSpacing;
- out.m_ImageOrigin = m_ImageOrigin;
- out.m_ImageDirection = m_ImageDirection;
- out.SetNumWeightedGradients(m_NumGradients);
- out.m_Bvalue = m_Bvalue;
- out.m_SignalScale = m_SignalScale;
- out.m_tEcho = m_tEcho;
- out.m_tLine = m_tLine;
- out.m_tInhom = m_tInhom;
- out.m_AxonRadius = m_AxonRadius;
- out.m_KspaceLineOffset = m_KspaceLineOffset;
- out.m_DoAddGibbsRinging = m_DoAddGibbsRinging;
- out.m_EddyStrength = m_EddyStrength;
- out.m_Spikes = m_Spikes;
- out.m_SpikeAmplitude = m_SpikeAmplitude;
- out.m_CroppingFactor = m_CroppingFactor;
- out.m_DoSimulateRelaxation = m_DoSimulateRelaxation;
- out.m_DoDisablePartialVolume = m_DoDisablePartialVolume;
- out.m_DoAddMotion = m_DoAddMotion;
- out.m_DoRandomizeMotion = m_DoRandomizeMotion;
- out.m_Translation = m_Translation;
- out.m_Rotation = m_Rotation;
- if (m_NoiseModel!=NULL)
- {
- if (dynamic_cast<mitk::RicianNoiseModel<ScalarType>*>(m_NoiseModel))
- out.m_NoiseModel = new mitk::RicianNoiseModel<OutType>();
- else if (dynamic_cast<mitk::ChiSquareNoiseModel<ScalarType>*>(m_NoiseModel))
- out.m_NoiseModel = new mitk::ChiSquareNoiseModel<OutType>();
- out.m_NoiseModel->SetNoiseVariance(m_NoiseModel->GetNoiseVariance());
- }
- out.m_FrequencyMap = m_FrequencyMap;
- out.m_MaskImage = m_MaskImage;
- out.m_ResultNode = m_ResultNode;
- out.m_ParentNode = m_ParentNode;
- out.m_SignalModelString = m_SignalModelString;
- out.m_ArtifactModelString = m_ArtifactModelString;
- out.m_OutputPath = m_OutputPath;
-// out.m_DiffusionDirectionMode = m_DiffusionDirectionMode;
-// out.m_SignalGenerationMode = m_SignalGenerationMode;
- out.m_SimulateKspaceAcquisition = m_SimulateKspaceAcquisition;
-
- // TODO: copy constructor für singalmodelle und rauschen
-
- return out;
+ m_ImageRegion.SetSize(0, 12);
+ m_ImageRegion.SetSize(1, 12);
+ m_ImageRegion.SetSize(2, 3);
+ m_ImageSpacing.Fill(2.0);
+ m_ImageOrigin.Fill(0.0);
+ m_ImageDirection.SetIdentity();
+ m_Translation.Fill(0.0);
+ m_Rotation.Fill(0.0);
+ SetNumWeightedVolumes(6);
}
- /** Output image specifications */
+ /** input/output image specifications */
itk::ImageRegion<3> m_ImageRegion; ///< Image size.
itk::Vector<double,3> m_ImageSpacing; ///< Image voxel size.
itk::Point<double,3> m_ImageOrigin; ///< Image origin.
itk::Matrix<double, 3, 3> m_ImageDirection; ///< Image rotation matrix.
/** Other acquisitions parameters */
double m_SignalScale; ///< Scaling factor for output signal (before noise is added).
double m_tEcho; ///< Echo time TE.
double m_tLine; ///< k-space line readout time.
double m_tInhom; ///< T2'
double m_Bvalue; ///< Acquisition b-value
- bool m_SimulateKspaceAcquisition;///<
-
- /** Signal generation */
- DiffusionModelListType m_FiberModelList; ///< Intra- and inter-axonal compartments.
- DiffusionModelListType m_NonFiberModelList; ///< Extra-axonal compartments.
+ bool m_SimulateKspaceAcquisition;///< Flag to enable/disable k-space acquisition simulation
double m_AxonRadius; ///< Determines compartment volume fractions (0 == automatic axon radius estimation)
+ bool m_DoDisablePartialVolume; ///< Disable partial volume effects. Each voxel is either all fiber or all non-fiber.
DiffusionDirectionMode m_DiffusionDirectionMode; ///< Determines how the main diffusion direction of the signal models is selected
+ double m_FiberSeparationThreshold; ///< Used for random and and mein fiber deriction DiffusionDirectionMode
- /** Artifacts */
+ /** Artifacts and other effects */
unsigned int m_Spikes; ///< Number of spikes randomly appearing in the image
double m_SpikeAmplitude; ///< amplitude of spikes relative to the largest signal intensity (magnitude of complex)
double m_KspaceLineOffset; ///< Causes N/2 ghosts. Larger offset means stronger ghost.
double m_EddyStrength; ///< Strength of eddy current induced gradients in mT/m.
double m_Tau; ///< Eddy current decay constant (in ms)
double m_CroppingFactor; ///< FOV size in y-direction is multiplied by this factor. Causes aliasing artifacts.
bool m_DoAddGibbsRinging; ///< Add Gibbs ringing artifact
bool m_DoSimulateRelaxation; ///< Add T2 relaxation effects
- bool m_DoDisablePartialVolume; ///< Disable partial volume effects. Each voxel is either all fiber or all non-fiber.
bool m_DoAddMotion; ///< Enable motion artifacts.
bool m_DoRandomizeMotion; ///< Toggles between random and linear motion.
itk::Vector<double,3> m_Translation; ///< Maximum translational motion.
itk::Vector<double,3> m_Rotation; ///< Maximum rotational motion.
- NoiseModelType* m_NoiseModel; ///< If != NULL, noise is added to the image.
ItkDoubleImgType::Pointer m_FrequencyMap; ///< If != NULL, distortions are added to the image using this frequency map.
ItkUcharImgType::Pointer m_MaskImage; ///< Signal is only genrated inside of the mask image.
- /** Output parameters (only relevant in GUI application) */
- mitk::DataNode::Pointer m_ResultNode; ///< Stores resulting image.
- mitk::DataNode::Pointer m_ParentNode; ///< Parent node or result node.
- string m_SignalModelString; ///< Appendet to the name of the result node
- string m_ArtifactModelString; ///< Appendet to the name of the result node
- string m_OutputPath; ///< Image is automatically saved to the specified folder after simulation is finished.
+ inline void GenerateGradientHalfShell(); ///< Generates half shell of gradient directions (with m_NumGradients non-zero directions)
+ inline std::vector< int > GetBaselineIndices(); ///< Returns list of nun-diffusion-weighted image volume indices
+ inline unsigned int GetFirstBaselineIndex(); ///< Returns index of first non-diffusion-weighted image volume
+ inline bool IsBaselineIndex(unsigned int idx); ///< Checks if image volume with given index is non-diffusion-weighted volume or not.
+ inline unsigned int GetNumWeightedVolumes(); ///< Get number of diffusion-weighted image volumes
+ inline unsigned int GetNumBaselineVolumes(); ///< Get number of non-diffusion-weighted image volumes
+ inline unsigned int GetNumVolumes(); ///< Get number of baseline and diffusion-weighted image volumes
+ inline GradientListType GetGradientDirections(); ///< Return gradient direction container
+ inline GradientType GetGradientDirection(unsigned int i);
- void PrintSelf(); ///< Print parameters to stdout.
- void LoadParameters(string filename); ///< Load image generation parameters from .ffp file.
- void GenerateGradientHalfShell(); ///< Generates half shell of gradient directions (with m_NumGradients non-zero directions)
+ inline void SetNumWeightedVolumes(int numGradients); ///< Automaticall calls GenerateGradientHalfShell() afterwards.
+ inline void SetGradienDirections(GradientListType gradientList);
+ inline void SetGradienDirections(mitk::DiffusionImage<short>::GradientDirectionContainerType::Pointer gradientList);
- std::vector< int > GetBaselineIndices();
- unsigned int GetFirstBaselineIndex();
- bool IsBaselineIndex(unsigned int idx);
+protected:
- unsigned int GetNumWeightedVolumes();
- unsigned int GetNumBaselineVolumes();
- unsigned int GetNumVolumes();
- GradientListType GetGradientDirections();
- GradientType GetGradientDirection(unsigned int i);
+ unsigned int m_NumGradients; ///< Number of diffusion-weighted image volumes.
+ unsigned int m_NumBaseline; ///< Number of non-diffusion-weighted image volumes.
+ GradientListType m_GradientDirections; ///< Total number of image volumes.
+};
- void SetNumWeightedGradients(int numGradients); ///< Automaticall calls GenerateGradientHalfShell() afterwards.
- void SetGradienDirections(GradientListType gradientList);
- void SetGradienDirections(mitk::DiffusionImage<short>::GradientDirectionContainerType::Pointer gradientList);
+/** Fiber generation */
+class FiberGenerationParameters
+{
+public:
-protected:
+ enum FiberDistribution{
+ DISTRIBUTE_UNIFORM, // distribute fibers uniformly in the ROIs
+ DISTRIBUTE_GAUSSIAN // distribute fibers using a 2D gaussian
+ };
- unsigned int m_NumBaseline; ///< Number of non-diffusion-weighted image volumes.
- unsigned int m_NumGradients; ///< Number of diffusion-weighted image volumes.
- GradientListType m_GradientDirections; ///< Total number of image volumes.
+ typedef vector< vector< mitk::PlanarEllipse::Pointer > > FiducialListType;
+ typedef vector< vector< unsigned int > > FlipListType;
+
+ FiberGenerationParameters()
+ : m_Distribution(DISTRIBUTE_UNIFORM)
+ , m_Density(100)
+ , m_Variance(100)
+ , m_Sampling(1)
+ , m_Tension(0)
+ , m_Continuity(0)
+ , m_Bias(0)
+ {
+ m_Rotation.Fill(0.0);
+ m_Translation.Fill(0.0);
+ m_Scale.Fill(1.0);
+ }
+ FiberDistribution m_Distribution;
+ unsigned int m_Density;
+ double m_Variance;
+ double m_Sampling;
+ double m_Tension;
+ double m_Continuity;
+ double m_Bias;
+ mitk::Vector3D m_Rotation;
+ mitk::Vector3D m_Translation;
+ mitk::Vector3D m_Scale;
+ FlipListType m_FlipList; ///< contains flags indicating a flip of the 2D fiber x-coordinates (needed to resolve some unwanted fiber twisting)
+ FiducialListType m_Fiducials; ///< container of the planar ellipses used as fiducials for the fiber generation process
+};
+
+/** GUI persistence, input, output, ... */
+class MiscFiberfoxParameters
+{
+public:
+ MiscFiberfoxParameters()
+ : m_ResultNode(DataNode::New())
+ , m_ParentNode(NULL)
+ , m_SignalModelString("")
+ , m_ArtifactModelString("")
+ , m_OutputPath("")
+ , m_CheckOutputVolumeFractionsBox(false)
+ , m_CheckAdvancedSignalOptionsBox(false)
+ , m_CheckAddNoiseBox(false)
+ , m_CheckAddGhostsBox(false)
+ , m_CheckAddAliasingBox(false)
+ , m_CheckAddSpikesBox(false)
+ , m_CheckAddEddyCurrentsBox(false)
+ , m_CheckAddDistortionsBox(false)
+ , m_CheckRealTimeFibersBox(true)
+ , m_CheckAdvancedFiberOptionsBox(false)
+ , m_CheckConstantRadiusBox(false)
+ , m_CheckIncludeFiducialsBox(true)
+ {}
+
+ DataNode::Pointer m_ResultNode; ///< Stores resulting image.
+ DataNode::Pointer m_ParentNode; ///< Parent node of result node.
+ string m_SignalModelString; ///< Appendet to the name of the result node
+ string m_ArtifactModelString; ///< Appendet to the name of the result node
+ string m_OutputPath; ///< Image is automatically saved to the specified folder after simulation is finished.
+
+ /** member variables that store the check-state of GUI checkboxes */
+ // image generation
+ bool m_CheckOutputVolumeFractionsBox;
+ bool m_CheckAdvancedSignalOptionsBox;
+ bool m_CheckAddNoiseBox;
+ bool m_CheckAddGhostsBox;
+ bool m_CheckAddAliasingBox;
+ bool m_CheckAddSpikesBox;
+ bool m_CheckAddEddyCurrentsBox;
+ bool m_CheckAddDistortionsBox;
+ // fiber generation
+ bool m_CheckRealTimeFibersBox;
+ bool m_CheckAdvancedFiberOptionsBox;
+ bool m_CheckConstantRadiusBox;
+ bool m_CheckIncludeFiducialsBox;
+};
+
+/**
+ * \brief Datastructure to manage the Fiberfox signal generation parameters.
+ *
+ */
+template< class ScalarType = double >
+class FiberfoxParameters
+{
+public:
+
+ typedef itk::Image<double, 3> ItkDoubleImgType;
+ typedef itk::Image<unsigned char, 3> ItkUcharImgType;
+ typedef DiffusionSignalModel<ScalarType> DiffusionModelType;
+ typedef std::vector< DiffusionModelType* > DiffusionModelListType;
+ typedef DiffusionNoiseModel<ScalarType> NoiseModelType;
+
+ FiberfoxParameters();
+ ~FiberfoxParameters();
+
+ /** Get same parameter object with different template parameter */
+ template< class OutType >
+ FiberfoxParameters< OutType > CopyParameters()
+ {
+ FiberfoxParameters< OutType > out;
+
+ out.m_FiberGen = m_FiberGen;
+ out.m_SignalGen = m_SignalGen;
+ out.m_Misc = m_Misc;
+
+ if (m_NoiseModel!=NULL)
+ {
+ if (dynamic_cast<mitk::RicianNoiseModel<ScalarType>*>(m_NoiseModel))
+ out.m_NoiseModel = new mitk::RicianNoiseModel<OutType>();
+ else if (dynamic_cast<mitk::ChiSquareNoiseModel<ScalarType>*>(m_NoiseModel))
+ out.m_NoiseModel = new mitk::ChiSquareNoiseModel<OutType>();
+ out.m_NoiseModel->SetNoiseVariance(m_NoiseModel->GetNoiseVariance());
+ }
+
+ for (unsigned int i=0; i<m_FiberModelList.size()+m_NonFiberModelList.size(); i++)
+ {
+ mitk::DiffusionSignalModel<OutType>* outModel = NULL;
+ mitk::DiffusionSignalModel<ScalarType>* signalModel = NULL;
+ if (i<m_FiberModelList.size())
+ signalModel = m_FiberModelList.at(i);
+ else
+ signalModel = m_NonFiberModelList.at(i-m_FiberModelList.size());
+
+ if (dynamic_cast<mitk::StickModel<ScalarType>*>(signalModel))
+ outModel = new mitk::StickModel<OutType>(dynamic_cast<mitk::StickModel<ScalarType>*>(signalModel));
+ else if (dynamic_cast<mitk::TensorModel<ScalarType>*>(signalModel))
+ outModel = new mitk::TensorModel<OutType>(dynamic_cast<mitk::TensorModel<ScalarType>*>(signalModel));
+ else if (dynamic_cast<mitk::RawShModel<ScalarType>*>(signalModel))
+ outModel = new mitk::RawShModel<OutType>(dynamic_cast<mitk::RawShModel<ScalarType>*>(signalModel));
+ else if (dynamic_cast<mitk::BallModel<ScalarType>*>(signalModel))
+ outModel = new mitk::BallModel<OutType>(dynamic_cast<mitk::BallModel<ScalarType>*>(signalModel));
+ else if (dynamic_cast<mitk::AstroStickModel<ScalarType>*>(signalModel))
+ outModel = new mitk::AstroStickModel<OutType>(dynamic_cast<mitk::AstroStickModel<ScalarType>*>(signalModel));
+ else if (dynamic_cast<mitk::DotModel<ScalarType>*>(signalModel))
+ outModel = new mitk::DotModel<OutType>(dynamic_cast<mitk::DotModel<ScalarType>*>(signalModel));
+
+ if (i<m_FiberModelList.size())
+ out.m_FiberModelList.push_back(outModel);
+ else
+ out.m_NonFiberModelList.push_back(outModel);
+ }
+
+ return out;
+ }
+
+ /** Not templated parameters */
+ FiberGenerationParameters m_FiberGen; ///< Fiber generation parameters
+ SignalGenerationParameters m_SignalGen; ///< Signal generation parameters
+ MiscFiberfoxParameters m_Misc; ///< GUI realted and I/O parameters
+
+ /** Templated parameters */
+ DiffusionModelListType m_FiberModelList; ///< Intra- and inter-axonal compartments.
+ DiffusionModelListType m_NonFiberModelList; ///< Extra-axonal compartments.
+ NoiseModelType* m_NoiseModel; ///< If != NULL, noise is added to the image.
+
+ void PrintSelf(); ///< Print parameters to stdout.
+ void SaveParameters(string filename); ///< Save image generation parameters to .ffp file.
+ void LoadParameters(string filename); ///< Load image generation parameters from .ffp file.
};
}
#include "mitkFiberfoxParameters.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/Interactions/mitkFiberBundleInteractor.h b/Modules/DiffusionImaging/FiberTracking/Interactions/mitkFiberBundleInteractor.h
index f2467bc717..d1e41e441e 100644
--- a/Modules/DiffusionImaging/FiberTracking/Interactions/mitkFiberBundleInteractor.h
+++ b/Modules/DiffusionImaging/FiberTracking/Interactions/mitkFiberBundleInteractor.h
@@ -1,99 +1,98 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKFiberBundleINTERACTOR_H_HEADER_INCLUDED
#define MITKFiberBundleINTERACTOR_H_HEADER_INCLUDED
#include "mitkCommon.h"
-#include "MitkExtExports.h"
#include <mitkInteractor.h>
#include <mitkNumericTypes.h>
#include <MitkFiberTrackingExports.h>
#include <vtkType.h>
namespace mitk
{
class DataNode;
//##Documentation
//## @brief Just select a point, that's the only way to interact with the point
//##
//## Interact with a point: Select the point without moving to get parameters that does not change
//## All Set-operations would be done through the method "ExecuteAction", if there would be anyone.
//## the identificationnumber of this point is set by this points and evalued from an empty place in the DataStructure
//## @ingroup Interaction
class MitkFiberTracking_EXPORT FiberBundleInteractor : public Interactor
{
public:
mitkClassMacro(FiberBundleInteractor, Interactor);
mitkNewMacro2Param(Self, const char*, DataNode*);
//##Documentation
//## @brief Sets the amount of precision
void SetPrecision(unsigned int precision);
//##Documentation
//## @brief derived from mitk::Interactor; calculates Jurisdiction according to points
//##
//## standard method can not be used, since it doesn't calculate in points, only in BoundingBox of Points
virtual float CanHandleEvent(StateEvent const* stateEvent) const;
protected:
//##Documentation
//##@brief Constructor
FiberBundleInteractor(const char * type, DataNode* dataNode);
//##Documentation
//##@brief Destructor
virtual ~FiberBundleInteractor();
//##Documentation
//## @brief select the point on the given position
virtual void SelectFiber(int position);
//##Documentation
//## @brief unselect all points that exist in mesh
virtual void DeselectAllFibers();
//##Documentation
//## @brief Executes Actions
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
private:
//##Documentation
//## @brief to calculate a direction vector from last point and actual point
Point3D m_LastPoint;
//##Documentation
//## @brief to store a position
unsigned int m_LastPosition;
// Point3D m_InitialPickedPoint;
// Point2D m_InitialPickedDisplayPoint;
// double m_InitialPickedPointWorld[4];
Point3D m_CurrentPickedPoint;
Point2D m_CurrentPickedDisplayPoint;
double m_CurrentPickedPointWorld[4];
};
}
#endif /* MITKFiberBundleInteractor_H_HEADER_INCLUDED */
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.cpp b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.cpp
index 70eb8e429d..ee2b139e23 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.cpp
@@ -1,132 +1,127 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkAstroStickModel.h>
using namespace mitk;
template< class ScalarType >
AstroStickModel< ScalarType >::AstroStickModel()
: m_BValue(1000)
, m_Diffusivity(0.001)
, m_NumSticks(42)
, m_RandomizeSticks(false)
{
- m_RandGen = ItkRandGenType::New();
+ this->m_RandGen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
+ this->m_RandGen->SetSeed();
- vnl_matrix_fixed<ScalarType,3,42>* sticks = itk::PointShell<42, vnl_matrix_fixed<ScalarType, 3, 42> >::DistributePointShell();
+ vnl_matrix_fixed<double,3,42>* sticks = itk::PointShell<42, vnl_matrix_fixed<double, 3, 42> >::DistributePointShell();
for (unsigned int i=0; i<m_NumSticks; i++)
{
GradientType stick;
stick[0] = sticks->get(0,i); stick[1] = sticks->get(1,i); stick[2] = sticks->get(2,i);
stick.Normalize();
m_Sticks.push_back(stick);
}
}
template< class ScalarType >
AstroStickModel< ScalarType >::~AstroStickModel()
{
}
-template< class ScalarType >
-void AstroStickModel< ScalarType >::SetSeed(int s)
-{
- m_RandGen->SetSeed(s);
-}
-
template< class ScalarType >
ScalarType AstroStickModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
ScalarType signal = 0;
if (dir>=this->m_GradientList.size())
return signal;
ScalarType b = -m_BValue*m_Diffusivity;
if (m_RandomizeSticks) // random number of sticks
- m_NumSticks = 30 + m_RandGen->GetIntegerVariate()%31;
+ m_NumSticks = 30 + this->m_RandGen->GetIntegerVariate()%31;
GradientType g = this->m_GradientList[dir];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001) // is weighted direction
{
for (unsigned int j=0; j<m_NumSticks; j++)
{
ScalarType dot = 0;
if(m_RandomizeSticks)
dot = GetRandomDirection()*g;
else
dot = m_Sticks[j]*g;
- signal += exp( b*bVal*dot*dot );
+ signal += std::exp( (double)(b*bVal*dot*dot) );
}
signal /= m_NumSticks;
}
else // is baseline direction
signal = 1;
return signal;
}
template< class ScalarType >
typename AstroStickModel< ScalarType >::GradientType AstroStickModel< ScalarType >::GetRandomDirection()
{
GradientType vec;
- vec[0] = m_RandGen->GetNormalVariate();
- vec[1] = m_RandGen->GetNormalVariate();
- vec[2] = m_RandGen->GetNormalVariate();
+ vec[0] = this->m_RandGen->GetNormalVariate();
+ vec[1] = this->m_RandGen->GetNormalVariate();
+ vec[2] = this->m_RandGen->GetNormalVariate();
vec.Normalize();
return vec;
}
template< class ScalarType >
typename AstroStickModel< ScalarType >::PixelType AstroStickModel< ScalarType >::SimulateMeasurement()
{
PixelType signal;
signal.SetSize(this->m_GradientList.size());
ScalarType b = -m_BValue*m_Diffusivity;
if (m_RandomizeSticks)
- m_NumSticks = 30 + m_RandGen->GetIntegerVariate()%31;
+ m_NumSticks = 30 + this->m_RandGen->GetIntegerVariate()%31;
for( unsigned int i=0; i<this->m_GradientList.size(); i++)
{
GradientType g = this->m_GradientList[i];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
{
for (unsigned int j=0; j<m_NumSticks; j++)
{
ScalarType dot = 0;
if(m_RandomizeSticks)
dot = GetRandomDirection()*g;
else
dot = m_Sticks[j]*g;
- signal[i] += exp( b*bVal*dot*dot );
+ signal[i] += std::exp( (double)(b*bVal*dot*dot) );
}
signal[i] /= m_NumSticks;
}
else
signal[i] = 1;
}
return signal;
}
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.h
index b9d35f00b0..c3e6c915fc 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkAstroStickModel.h
@@ -1,110 +1,130 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_AstroStickModel_H
#define _MITK_AstroStickModel_H
#include <mitkDiffusionSignalModel.h>
#include <itkPointShell.h>
namespace mitk {
/**
* \brief Generates the diffusion signal using a collection of idealised cylinder with zero radius: e^(-bd(ng)²)
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class AstroStickModel : public DiffusionSignalModel< ScalarType >
{
public:
AstroStickModel();
+ template< class OtherType >AstroStickModel(AstroStickModel<OtherType>* model)
+ {
+ this->m_CompartmentId = model->m_CompartmentId;
+ this->m_T2 = model->GetT2();
+ this->m_FiberDirection = model->GetFiberDirection();
+ this->m_GradientList = model->GetGradientList();
+ this->m_VolumeFractionImage = model->GetVolumeFractionImage();
+ this->m_RandGen = model->GetRandomGenerator();
+
+ this->m_BValue = model->GetBvalue();
+ this->m_Diffusivity = model->GetDiffusivity();
+ this->m_Sticks = model->GetSticks();
+ this->m_NumSticks = model->GetNumSticks();
+ this->m_RandomizeSticks = model->GetRandomizeSticks();
+ }
~AstroStickModel();
typedef typename DiffusionSignalModel< ScalarType >::PixelType PixelType;
typedef typename DiffusionSignalModel< ScalarType >::GradientType GradientType;
typedef typename DiffusionSignalModel< ScalarType >::GradientListType GradientListType;
- typedef itk::Statistics::MersenneTwisterRandomVariateGenerator ItkRandGenType;
/** Actual signal generation **/
PixelType SimulateMeasurement();
ScalarType SimulateMeasurement(unsigned int dir);
+
void SetFiberDirection(GradientType fiberDirection){ this->m_FiberDirection = fiberDirection; }
void SetGradientList(GradientListType gradientList) { this->m_GradientList = gradientList; }
- void SetSeed(int s); ///< set seed for random generator that creates the stick orientations
-
void SetRandomizeSticks(bool randomize=true){ m_RandomizeSticks=randomize; } ///< Random stick configuration in each voxel
- void SetBvalue(ScalarType bValue) { m_BValue = bValue; } ///< b-value used to generate the artificial signal
- void SetDiffusivity(ScalarType diffusivity) { m_Diffusivity = diffusivity; } ///< Scalar diffusion constant
+ bool GetRandomizeSticks() { return m_RandomizeSticks; }
+
+ void SetBvalue(double bValue) { m_BValue = bValue; } ///< b-value used to generate the artificial signal
+ double GetBvalue() { return m_BValue; }
+
+ void SetDiffusivity(double diffusivity) { m_Diffusivity = diffusivity; } ///< Scalar diffusion constant
+ double GetDiffusivity() { return m_Diffusivity; }
+
void SetNumSticks(unsigned int order)
{
vnl_matrix<double> sticks;
switch (order)
{
case 1:
m_NumSticks = 12;
sticks = itk::PointShell<12, vnl_matrix_fixed<double, 3, 12> >::DistributePointShell()->as_matrix();
break;
case 2:
m_NumSticks = 42;
sticks = itk::PointShell<42, vnl_matrix_fixed<double, 3, 42> >::DistributePointShell()->as_matrix();
break;
case 3:
m_NumSticks = 92;
sticks = itk::PointShell<92, vnl_matrix_fixed<double, 3, 92> >::DistributePointShell()->as_matrix();
break;
case 4:
m_NumSticks = 162;
sticks = itk::PointShell<162, vnl_matrix_fixed<double, 3, 162> >::DistributePointShell()->as_matrix();
break;
case 5:
m_NumSticks = 252;
sticks = itk::PointShell<252, vnl_matrix_fixed<double, 3, 252> >::DistributePointShell()->as_matrix();
break;
default:
m_NumSticks = 42;
sticks = itk::PointShell<42, vnl_matrix_fixed<double, 3, 42> >::DistributePointShell()->as_matrix();
break;
}
for (int i=0; i<m_NumSticks; i++)
{
GradientType stick;
stick[0] = sticks.get(0,i); stick[1] = sticks.get(1,i); stick[2] = sticks.get(2,i);
stick.Normalize();
m_Sticks.push_back(stick);
}
}
+ unsigned int GetNumSticks(){ return m_NumSticks; }
+ GradientListType GetSticks(){ return m_Sticks; }
protected:
GradientType GetRandomDirection();
- ScalarType m_BValue; ///< b-value used to generate the artificial signal
- ScalarType m_Diffusivity; ///< Scalar diffusion constant
+ double m_BValue; ///< b-value used to generate the artificial signal
+ double m_Diffusivity; ///< Scalar diffusion constant
GradientListType m_Sticks; ///< Stick container
unsigned int m_NumSticks; ///< Number of sticks
bool m_RandomizeSticks;
- ItkRandGenType::Pointer m_RandGen; ///< Random number generator
};
}
#include "mitkAstroStickModel.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.cpp b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.cpp
index 75286968be..4218159dfa 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.cpp
@@ -1,73 +1,73 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkBallModel.h>
using namespace mitk;
template< class ScalarType >
BallModel< ScalarType >::BallModel()
: m_Diffusivity(0.001)
, m_BValue(1000)
{
}
template< class ScalarType >
BallModel< ScalarType >::~BallModel()
{
}
template< class ScalarType >
ScalarType BallModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
ScalarType signal = 0;
if (dir>=this->m_GradientList.size())
return signal;
GradientType g = this->m_GradientList[dir];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
- signal = exp( -m_BValue * bVal * m_Diffusivity );
+ signal = std::exp( -m_BValue * bVal * m_Diffusivity );
else
signal = 1;
return signal;
}
template< class ScalarType >
typename BallModel< ScalarType >::PixelType BallModel< ScalarType >::SimulateMeasurement()
{
PixelType signal;
signal.SetSize(this->m_GradientList.size());
for( unsigned int i=0; i<this->m_GradientList.size(); i++)
{
GradientType g = this->m_GradientList[i];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
- signal[i] = exp( -m_BValue * bVal * m_Diffusivity );
+ signal[i] = std::exp( -m_BValue * bVal * m_Diffusivity );
else
signal[i] = 1;
}
return signal;
}
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.h
index 63e7762af6..98a0bd7e33 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkBallModel.h
@@ -1,63 +1,77 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_BallModel_H
#define _MITK_BallModel_H
#include <mitkDiffusionSignalModel.h>
namespace mitk {
/**
* \brief Generates direction independent diffusion measurement employing a scalar diffusion constant d: e^(-bd)
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class BallModel : public DiffusionSignalModel< ScalarType >
{
public:
BallModel();
+ template< class OtherType >BallModel(BallModel<OtherType>* model)
+ {
+ this->m_CompartmentId = model->m_CompartmentId;
+ this->m_T2 = model->GetT2();
+ this->m_FiberDirection = model->GetFiberDirection();
+ this->m_GradientList = model->GetGradientList();
+ this->m_VolumeFractionImage = model->GetVolumeFractionImage();
+ this->m_RandGen = model->GetRandomGenerator();
+
+ this->m_BValue = model->GetBvalue();
+ this->m_Diffusivity = model->GetDiffusivity();
+ }
~BallModel();
typedef typename DiffusionSignalModel< ScalarType >::PixelType PixelType;
typedef typename DiffusionSignalModel< ScalarType >::GradientType GradientType;
typedef typename DiffusionSignalModel< ScalarType >::GradientListType GradientListType;
/** Actual signal generation **/
PixelType SimulateMeasurement();
ScalarType SimulateMeasurement(unsigned int dir);
- void SetDiffusivity(ScalarType D) { m_Diffusivity = D; }
- void SetBvalue(ScalarType bValue) { m_BValue = bValue; }
+ void SetDiffusivity(double D) { m_Diffusivity = D; }
+ double GetDiffusivity() { return m_Diffusivity; }
+ void SetBvalue(double bValue) { m_BValue = bValue; } ///< b-value used to generate the artificial signal
+ double GetBvalue() { return m_BValue; }
void SetFiberDirection(GradientType fiberDirection){ this->m_FiberDirection = fiberDirection; }
void SetGradientList(GradientListType gradientList) { this->m_GradientList = gradientList; }
protected:
- ScalarType m_Diffusivity; ///< Scalar diffusion constant
- ScalarType m_BValue; ///< b-value used to generate the artificial signal
+ double m_Diffusivity; ///< Scalar diffusion constant
+ double m_BValue; ///< b-value used to generate the artificial signal
};
}
#include "mitkBallModel.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionSignalModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionSignalModel.h
index a9a29831aa..4d733a6bec 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionSignalModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionSignalModel.h
@@ -1,72 +1,91 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_DiffusionSignalModel_H
#define _MITK_DiffusionSignalModel_H
#include <MitkFiberTrackingExports.h>
#include <itkVariableLengthVector.h>
#include <itkVector.h>
#include <itkImage.h>
+#include <itkMersenneTwisterRandomVariateGenerator.h>
#include <vnl/vnl_vector_fixed.h>
namespace mitk {
/**
* \brief Abstract class for diffusion signal models
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class DiffusionSignalModel
{
public:
DiffusionSignalModel()
: m_T2(100)
{}
~DiffusionSignalModel(){}
typedef itk::Image<double, 3> ItkDoubleImgType;
typedef itk::VariableLengthVector< ScalarType > PixelType;
typedef itk::Vector<double,3> GradientType;
typedef std::vector<GradientType> GradientListType;
+ typedef itk::Statistics::MersenneTwisterRandomVariateGenerator ItkRandGenType;
/** Realizes actual signal generation. Has to be implemented in subclass. **/
virtual PixelType SimulateMeasurement() = 0;
virtual ScalarType SimulateMeasurement(unsigned int dir) = 0;
virtual void SetFiberDirection(GradientType fiberDirection) = 0;
+ GradientType GetFiberDirection(){ return m_FiberDirection; }
+
virtual void SetGradientList(GradientListType gradientList) = 0;
+ GradientListType GetGradientList(){ return m_GradientList; }
+ GradientType GetGradientDirection(int i) { return m_GradientList.at(i); }
+
void SetT2(double T2) { m_T2 = T2; }
- void SetVolumeFractionImage(ItkDoubleImgType::Pointer img){ m_VolumeFractionImage = img; }
+ double GetT2() { return m_T2; }
+ void SetVolumeFractionImage(ItkDoubleImgType::Pointer img){ m_VolumeFractionImage = img; }
ItkDoubleImgType::Pointer GetVolumeFractionImage(){ return m_VolumeFractionImage; }
- GradientType GetGradientDirection(int i) { return m_GradientList.at(i); }
- double GetT2() { return m_T2; }
+
+ void SetRandomGenerator(ItkRandGenType::Pointer randgen){ m_RandGen = randgen; }
+ ItkRandGenType::Pointer GetRandomGenerator(){ return m_RandGen; }
+
+ void SetSeed(int s) ///< set seed for random generator
+ {
+ if (m_RandGen.IsNull())
+ m_RandGen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
+ m_RandGen->SetSeed(s);
+ }
+
+ unsigned int m_CompartmentId; ///< GUI flag. Which compartment is this model assigned to?
protected:
GradientType m_FiberDirection; ///< Needed to generate anisotropc signal to determin direction of anisotropy
GradientListType m_GradientList; ///< Diffusion gradient direction container
double m_T2; ///< Tissue specific relaxation time
ItkDoubleImgType::Pointer m_VolumeFractionImage; ///< Tissue specific volume fraction for each voxel (only relevant for non fiber compartments)
+ ItkRandGenType::Pointer m_RandGen; ///< Random number generator
};
}
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDotModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDotModel.h
index 3e4a4c9da9..382c2dd903 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDotModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDotModel.h
@@ -1,57 +1,66 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_DotModel_H
#define _MITK_DotModel_H
#include <mitkDiffusionSignalModel.h>
namespace mitk {
/**
* \brief Generates constant direction independent signal.
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class DotModel : public DiffusionSignalModel< ScalarType >
{
public:
DotModel();
+ template< class OtherType >DotModel(DotModel<OtherType>* model)
+ {
+ this->m_CompartmentId = model->m_CompartmentId;
+ this->m_T2 = model->GetT2();
+ this->m_FiberDirection = model->GetFiberDirection();
+ this->m_GradientList = model->GetGradientList();
+ this->m_VolumeFractionImage = model->GetVolumeFractionImage();
+ this->m_RandGen = model->GetRandomGenerator();
+ }
~DotModel();
typedef typename DiffusionSignalModel< ScalarType >::PixelType PixelType;
typedef typename DiffusionSignalModel< ScalarType >::GradientType GradientType;
typedef typename DiffusionSignalModel< ScalarType >::GradientListType GradientListType;
/** Actual signal generation **/
PixelType SimulateMeasurement();
ScalarType SimulateMeasurement(unsigned int dir);
void SetFiberDirection(GradientType fiberDirection){ this->m_FiberDirection = fiberDirection; }
void SetGradientList(GradientListType gradientList) { this->m_GradientList = gradientList; }
protected:
};
}
#include "mitkDotModel.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.cpp b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.cpp
index 2fdb8eae50..0d2302d1e7 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.cpp
@@ -1,257 +1,382 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkRawShModel.h>
#include <boost/math/special_functions.hpp>
#include <itkOrientationDistributionFunction.h>
#include <mitkFiberfoxParameters.h>
+#include <itkDiffusionTensor3DReconstructionImageFilter.h>
+#include <itkAdcImageFilter.h>
+#include <itkAnalyticalDiffusionQballReconstructionImageFilter.h>
using namespace mitk;
using namespace boost::math;
template< class ScalarType >
RawShModel< ScalarType >::RawShModel()
: m_ShOrder(0)
, m_ModelIndex(-1)
, m_MaxNumKernels(1000)
{
- m_RandGen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
- m_RandGen->SetSeed();
+ this->m_RandGen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
+ this->m_RandGen->SetSeed();
m_AdcRange.first = 0;
m_AdcRange.second = 0.004;
m_FaRange.first = 0;
m_FaRange.second = 1;
}
template< class ScalarType >
RawShModel< ScalarType >::~RawShModel()
{
}
template< class ScalarType >
void RawShModel< ScalarType >::Clear()
{
m_ShCoefficients.clear();
m_PrototypeMaxDirection.clear();
m_B0Signal.clear();
}
template< class ScalarType >
void RawShModel< ScalarType >::RandomModel()
{
- m_ModelIndex = m_RandGen->GetIntegerVariate(m_B0Signal.size()-1);
+ m_ModelIndex = this->m_RandGen->GetIntegerVariate(m_B0Signal.size()-1);
}
template< class ScalarType >
unsigned int RawShModel< ScalarType >::GetNumberOfKernels()
{
return m_B0Signal.size();
}
+template< class ScalarType >
+bool RawShModel< ScalarType >::SampleKernels(DiffusionImage<short>::Pointer diffImg, ItkUcharImageType::Pointer maskImage, TensorImageType::Pointer tensorImage, QballFilterType::CoefficientImageType::Pointer itkFeatureImage, ItkDoubleImageType::Pointer adcImage)
+{
+ if (diffImg.IsNull())
+ return false;
+
+ const int shOrder = 2;
+
+ if (tensorImage.IsNull())
+ {
+ typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
+ TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
+ filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
+ filter->SetBValue(diffImg->GetReferenceBValue());
+ filter->Update();
+ tensorImage = filter->GetOutput();
+ }
+
+ const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder;
+ if (itkFeatureImage.IsNull())
+ {
+ QballFilterType::Pointer qballfilter = QballFilterType::New();
+ qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
+ qballfilter->SetBValue(diffImg->GetReferenceBValue());
+ qballfilter->SetLambda(0.006);
+ qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL);
+ qballfilter->Update();
+ itkFeatureImage = qballfilter->GetCoefficientImage();
+ }
+
+ if (adcImage.IsNull())
+ {
+ itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
+ adcFilter->SetInput(diffImg->GetVectorImage());
+ adcFilter->SetGradientDirections(diffImg->GetDirections());
+ adcFilter->SetB_value(diffImg->GetReferenceBValue());
+ adcFilter->Update();
+ adcImage = adcFilter->GetOutput();
+ }
+
+ int b0Index;
+ for (unsigned int i=0; i<diffImg->GetDirectionsWithoutMeasurementFrame()->Size(); i++)
+ if ( diffImg->GetDirectionsWithoutMeasurementFrame()->GetElement(i).magnitude()<0.001 )
+ {
+ b0Index = i;
+ break;
+ }
+
+ double max = 0;
+ {
+ itk::ImageRegionIterator< itk::VectorImage< short, 3 > > it(diffImg->GetVectorImage(), diffImg->GetVectorImage()->GetLargestPossibleRegion());
+ while(!it.IsAtEnd())
+ {
+ if (maskImage.IsNotNull() && maskImage->GetPixel(it.GetIndex())<=0)
+ {
+ ++it;
+ continue;
+ }
+ if (it.Get()[b0Index]>max)
+ max = it.Get()[b0Index];
+ ++it;
+ }
+ }
+
+ MITK_INFO << "Sampling signal kernels.";
+ unsigned int count = 0;
+ itk::ImageRegionIterator< itk::Image< itk::DiffusionTensor3D< double >, 3 > > it(tensorImage, tensorImage->GetLargestPossibleRegion());
+ while(!it.IsAtEnd())
+ {
+ bool skipPixel = false;
+ if (maskImage.IsNotNull() && maskImage->GetPixel(it.GetIndex())<=0)
+ {
+ ++it;
+ continue;
+ }
+ for (unsigned int i=0; i<diffImg->GetDirections()->Size(); i++)
+ {
+ if (diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i]!=diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i] || diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i]<=0 || diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i]>diffImg->GetVectorImage()->GetPixel(it.GetIndex())[b0Index])
+ {
+ skipPixel = true;
+ break;
+ }
+ }
+ if (skipPixel)
+ {
+ ++it;
+ continue;
+ }
+
+ typedef itk::DiffusionTensor3D<double> TensorType;
+ TensorType::EigenValuesArrayType eigenvalues;
+ TensorType::EigenVectorsMatrixType eigenvectors;
+ TensorType tensor = it.Get();
+ double FA = tensor.GetFractionalAnisotropy();
+ double ADC = adcImage->GetPixel(it.GetIndex());
+ QballFilterType::CoefficientImageType::PixelType itkv = itkFeatureImage->GetPixel(it.GetIndex());
+ vnl_vector_fixed< double, NumCoeffs > coeffs;
+ for (unsigned int c=0; c<itkv.Size(); c++)
+ coeffs[c] = itkv[c]/max;
+
+ if ( this->GetMaxNumKernels()>this->GetNumberOfKernels() && FA>m_FaRange.first && FA<m_FaRange.second && ADC>m_AdcRange.first && ADC<m_AdcRange.second)
+ {
+ if (this->SetShCoefficients( coeffs, (double)diffImg->GetVectorImage()->GetPixel(it.GetIndex())[b0Index]/max ))
+ {
+ tensor.ComputeEigenAnalysis(eigenvalues, eigenvectors);
+ itk::Vector<double,3> dir;
+ dir[0] = eigenvectors(2, 0);
+ dir[1] = eigenvectors(2, 1);
+ dir[2] = eigenvectors(2, 2);
+ m_PrototypeMaxDirection.push_back(dir);
+ count++;
+ MITK_INFO << "KERNEL: " << it.GetIndex() << " (" << count << ")";
+ }
+ }
+ ++it;
+ }
+
+ if (m_ShCoefficients.size()>0)
+ return true;
+ return false;
+}
+
// convert cartesian to spherical coordinates
template< class ScalarType >
void RawShModel< ScalarType >::Cart2Sph( GradientListType gradients )
{
m_SphCoords.set_size(gradients.size(), 2);
m_SphCoords.fill(0.0);
for (unsigned int i=0; i<gradients.size(); i++)
{
GradientType g = gradients[i];
if( g.GetNorm() > 0.0001 )
{
gradients[i].Normalize();
m_SphCoords(i,0) = acos(gradients[i][2]); // theta
m_SphCoords(i,1) = atan2(gradients[i][1], gradients[i][0]); // phi
}
}
}
template< class ScalarType >
void RawShModel< ScalarType >::SetFiberDirection(GradientType fiberDirection)
{
this->m_FiberDirection = fiberDirection;
this->m_FiberDirection.Normalize();
RandomModel();
GradientType axis = itk::CrossProduct(this->m_FiberDirection, m_PrototypeMaxDirection.at(m_ModelIndex));
axis.Normalize();
vnl_quaternion<double> rotation(axis.GetVnlVector(), acos(dot_product(this->m_FiberDirection.GetVnlVector(), m_PrototypeMaxDirection.at(m_ModelIndex).GetVnlVector())));
rotation.normalize();
GradientListType gradients;
for (unsigned int i=0; i<this->m_GradientList.size(); i++)
{
GradientType dir = this->m_GradientList.at(i);
if( dir.GetNorm() > 0.0001 )
{
dir.Normalize();
vnl_vector_fixed< double, 3 > vnlDir = rotation.rotate(dir.GetVnlVector());
dir[0] = vnlDir[0]; dir[1] = vnlDir[1]; dir[2] = vnlDir[2];
dir.Normalize();
}
gradients.push_back(dir);
}
Cart2Sph( gradients );
}
template< class ScalarType >
-bool RawShModel< ScalarType >::SetShCoefficients(vnl_vector< double > shCoefficients, ScalarType b0 )
+bool RawShModel< ScalarType >::SetShCoefficients(vnl_vector< double > shCoefficients, double b0 )
{
m_ShOrder = 2;
while ( (m_ShOrder*m_ShOrder + m_ShOrder + 2)/2 + m_ShOrder <= shCoefficients.size() )
m_ShOrder += 2;
m_ShOrder -= 2;
m_ModelIndex = m_B0Signal.size();
m_B0Signal.push_back(b0);
m_ShCoefficients.push_back(shCoefficients);
-// itk::OrientationDistributionFunction<double, 10000> odf;
-// GradientListType gradients;
-// for (unsigned int i=0; i<odf.GetNumberOfComponents(); i++)
-// {
-// GradientType dir; dir[0]=odf.GetDirection(i)[0]; dir[1]=odf.GetDirection(i)[1]; dir[2]=odf.GetDirection(i)[2];
-// dir.Normalize();
-// gradients.push_back(dir);
-// }
-// Cart2Sph( this->m_GradientList );
-// PixelType signal = SimulateMeasurement();
-
-// int minDirIdx = 0;
-// double min = itk::NumericTraits<double>::max();
-// for (unsigned int i=0; i<signal.GetSize(); i++)
-// {
-// if (signal[i]>b0 || signal[i]<0)
-// {
-// MITK_INFO << "Corrupted signal value detected. Kernel rejected.";
-// m_B0Signal.pop_back();
-// m_ShCoefficients.pop_back();
-// return false;
-// }
-// if (signal[i]<min)
-// {
-// min = signal[i];
-// minDirIdx = i;
-// }
-// }
-// GradientType maxDir = this->m_GradientList.at(minDirIdx);
-// maxDir.Normalize();
-// m_PrototypeMaxDirection.push_back(maxDir);
+ // itk::OrientationDistributionFunction<double, 10000> odf;
+ // GradientListType gradients;
+ // for (unsigned int i=0; i<odf.GetNumberOfComponents(); i++)
+ // {
+ // GradientType dir; dir[0]=odf.GetDirection(i)[0]; dir[1]=odf.GetDirection(i)[1]; dir[2]=odf.GetDirection(i)[2];
+ // dir.Normalize();
+ // gradients.push_back(dir);
+ // }
+ // Cart2Sph( this->m_GradientList );
+ // PixelType signal = SimulateMeasurement();
+
+ // int minDirIdx = 0;
+ // double min = itk::NumericTraits<double>::max();
+ // for (unsigned int i=0; i<signal.GetSize(); i++)
+ // {
+ // if (signal[i]>b0 || signal[i]<0)
+ // {
+ // MITK_INFO << "Corrupted signal value detected. Kernel rejected.";
+ // m_B0Signal.pop_back();
+ // m_ShCoefficients.pop_back();
+ // return false;
+ // }
+ // if (signal[i]<min)
+ // {
+ // min = signal[i];
+ // minDirIdx = i;
+ // }
+ // }
+ // GradientType maxDir = this->m_GradientList.at(minDirIdx);
+ // maxDir.Normalize();
+ // m_PrototypeMaxDirection.push_back(maxDir);
Cart2Sph( this->m_GradientList );
m_ModelIndex = -1;
return true;
}
template< class ScalarType >
ScalarType RawShModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
ScalarType signal = 0;
if (m_ModelIndex==-1)
RandomModel();
if (dir>=this->m_GradientList.size())
return signal;
int j, m; double mag, plm;
if (this->m_GradientList[dir].GetNorm()>0.001)
{
j=0;
for (int l=0; l<=m_ShOrder; l=l+2)
for (m=-l; m<=l; m++)
{
plm = legendre_p<double>(l,abs(m),cos(m_SphCoords(dir,0)));
mag = sqrt((double)(2*l+1)/(4.0*M_PI)*factorial<double>(l-abs(m))/factorial<double>(l+abs(m)))*plm;
double basis;
if (m<0)
basis = sqrt(2.0)*mag*cos(fabs((double)m)*m_SphCoords(dir,1));
else if (m==0)
basis = mag;
else
basis = pow(-1.0, m)*sqrt(2.0)*mag*sin(m*m_SphCoords(dir,1));
signal += m_ShCoefficients.at(m_ModelIndex)[j]*basis;
j++;
}
}
else
signal = m_B0Signal.at(m_ModelIndex);
m_ModelIndex = -1;
return signal;
}
template< class ScalarType >
typename RawShModel< ScalarType >::PixelType RawShModel< ScalarType >::SimulateMeasurement()
{
if (m_ModelIndex==-1)
RandomModel();
PixelType signal;
signal.SetSize(this->m_GradientList.size());
int M = this->m_GradientList.size();
int j, m; double mag, plm;
vnl_matrix< double > shBasis;
shBasis.set_size(M, m_ShCoefficients.at(m_ModelIndex).size());
shBasis.fill(0.0);
for (int p=0; p<M; p++)
{
if (this->m_GradientList[p].GetNorm()>0.001)
{
j=0;
for (int l=0; l<=m_ShOrder; l=l+2)
for (m=-l; m<=l; m++)
{
plm = legendre_p<double>(l,abs(m),cos(m_SphCoords(p,0)));
mag = sqrt((double)(2*l+1)/(4.0*M_PI)*factorial<double>(l-abs(m))/factorial<double>(l+abs(m)))*plm;
if (m<0)
shBasis(p,j) = sqrt(2.0)*mag*cos(fabs((double)m)*m_SphCoords(p,1));
else if (m==0)
shBasis(p,j) = mag;
else
shBasis(p,j) = pow(-1.0, m)*sqrt(2.0)*mag*sin(m*m_SphCoords(p,1));
j++;
}
double val = 0;
for (unsigned int cidx=0; cidx<m_ShCoefficients.at(m_ModelIndex).size(); cidx++)
val += m_ShCoefficients.at(m_ModelIndex)[cidx]*shBasis(p,cidx);
signal[p] = val;
}
else
signal[p] = m_B0Signal.at(m_ModelIndex);
}
m_ModelIndex = -1;
return signal;
}
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.h
index ae1e6041ce..3fb5676395 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRawShModel.h
@@ -1,80 +1,114 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_RawShModel_H
#define _MITK_RawShModel_H
#include <mitkDiffusionSignalModel.h>
+#include <mitkDiffusionImage.h>
+#include <itkAnalyticalDiffusionQballReconstructionImageFilter.h>
namespace mitk {
/**
* \brief The spherical harmonic representation of a prototype diffusion weighted MR signal is used to obtain the direction dependent signal.
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class RawShModel : public DiffusionSignalModel< ScalarType >
{
public:
RawShModel();
+ template< class OtherType >RawShModel(RawShModel<OtherType>* model)
+ {
+ this->m_CompartmentId = model->m_CompartmentId;
+ this->m_T2 = model->GetT2();
+ this->m_FiberDirection = model->GetFiberDirection();
+ this->m_GradientList = model->GetGradientList();
+ this->m_VolumeFractionImage = model->GetVolumeFractionImage();
+ this->m_RandGen = model->GetRandomGenerator();
+
+ this->m_AdcRange = model->GetAdcRange();
+ this->m_FaRange = model->GetFaRange();
+ this->m_ShCoefficients = model->GetShCoefficients();
+ this->m_B0Signal = model->GetB0Signals();
+ this->m_SphCoords = model->GetSphericalCoordinates();
+ this->m_ShOrder = model->GetShOrder();
+ this->m_ModelIndex = model->GetModelIndex();
+ this->m_MaxNumKernels = model->GetMaxNumKernels();
+ }
~RawShModel();
+ typedef itk::Image< double, 3 > ItkDoubleImageType;
+ typedef itk::Image< unsigned char, 3 > ItkUcharImageType;
+ typedef itk::Image< itk::DiffusionTensor3D< double >, 3 > TensorImageType;
+ typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,2,QBALL_ODFSIZE> QballFilterType;
typedef typename DiffusionSignalModel< ScalarType >::PixelType PixelType;
typedef typename DiffusionSignalModel< ScalarType >::GradientType GradientType;
typedef typename DiffusionSignalModel< ScalarType >::GradientListType GradientListType;
typedef itk::Matrix< double, 3, 3 > MatrixType;
/** Actual signal generation **/
PixelType SimulateMeasurement();
ScalarType SimulateMeasurement(unsigned int dir);
- bool SetShCoefficients(vnl_vector< double > shCoefficients, ScalarType b0);
+ bool SetShCoefficients(vnl_vector< double > shCoefficients, double b0);
void SetFiberDirection(GradientType fiberDirection);
void SetGradientList(GradientListType gradientList) { this->m_GradientList = gradientList; }
void SetFaRange(double min, double max){ m_FaRange.first = min; m_FaRange.second = max; }
void SetAdcRange(double min, double max){ m_AdcRange.first = min; m_AdcRange.second = max; }
void SetMaxNumKernels(unsigned int max){ m_MaxNumKernels = max; }
unsigned int GetNumberOfKernels();
std::pair< double, double > GetFaRange(){ return m_FaRange; }
std::pair< double, double > GetAdcRange(){ return m_AdcRange; }
unsigned int GetMaxNumKernels(){ return m_MaxNumKernels; }
void Clear();
- vector< GradientType > m_PrototypeMaxDirection;
+
+ std::vector< vnl_vector< double > > GetShCoefficients(){ return m_ShCoefficients; }
+ std::vector< double > GetB0Signals(){ return m_B0Signal; }
+ vnl_matrix<double> GetSphericalCoordinates(){ return m_SphCoords; }
+ unsigned int GetShOrder(){ return m_ShOrder; }
+ int GetModelIndex(){ return m_ModelIndex; }
+
+ double GetBaselineSignal(int index){ return m_B0Signal.at(index); }
+ vnl_vector< double > GetCoefficients(int listIndex){ return m_ShCoefficients.at(listIndex); }
+
+ bool SampleKernels(DiffusionImage<short>::Pointer diffImg, ItkUcharImageType::Pointer maskImage, TensorImageType::Pointer tensorImage=NULL, QballFilterType::CoefficientImageType::Pointer coeffImage=NULL, ItkDoubleImageType::Pointer adcImage=NULL);
protected:
void Cart2Sph( GradientListType gradients );
void RandomModel();
- std::pair< double, double > m_AdcRange;
- std::pair< double, double > m_FaRange;
- vector< vnl_vector< double > > m_ShCoefficients;
- vector< ScalarType > m_B0Signal;
- vnl_matrix<double> m_SphCoords;
- unsigned int m_ShOrder;
- int m_ModelIndex;
- unsigned int m_MaxNumKernels;
- itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer m_RandGen;
+ std::vector< vnl_vector< double > > m_ShCoefficients;
+ std::vector< double > m_B0Signal;
+ std::vector< GradientType > m_PrototypeMaxDirection;
+ vnl_matrix<double> m_SphCoords;
+ std::pair< double, double > m_AdcRange;
+ std::pair< double, double > m_FaRange;
+ unsigned int m_ShOrder;
+ int m_ModelIndex;
+ unsigned int m_MaxNumKernels;
};
}
#include "mitkRawShModel.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.cpp b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.cpp
index eed95eece6..29b8cdbb29 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.cpp
@@ -1,82 +1,82 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkStickModel.h>
using namespace mitk;
template< class ScalarType >
StickModel< ScalarType >::StickModel()
: m_Diffusivity(0.001)
, m_BValue(1000)
{
}
template< class ScalarType >
StickModel< ScalarType >::~StickModel()
{
}
template< class ScalarType >
ScalarType StickModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
ScalarType signal = 0;
if (dir>=this->m_GradientList.size())
return signal;
this->m_FiberDirection.Normalize();
GradientType g = this->m_GradientList[dir];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
{
ScalarType dot = this->m_FiberDirection*g;
- signal = exp( -m_BValue * bVal * m_Diffusivity*dot*dot );
+ signal = std::exp( -m_BValue * bVal * m_Diffusivity*dot*dot );
}
else
signal = 1;
return signal;
}
template< class ScalarType >
typename StickModel< ScalarType >::PixelType StickModel< ScalarType >::SimulateMeasurement()
{
this->m_FiberDirection.Normalize();
PixelType signal;
signal.SetSize(this->m_GradientList.size());
for( unsigned int i=0; i<this->m_GradientList.size(); i++)
{
GradientType g = this->m_GradientList[i];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
{
ScalarType dot = this->m_FiberDirection*g;
- signal[i] = exp( -m_BValue * bVal * m_Diffusivity*dot*dot );
+ signal[i] = std::exp( -m_BValue * bVal * m_Diffusivity*dot*dot );
}
else
signal[i] = 1;
}
return signal;
}
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.h
index 6af5a320f1..7ecf8635d7 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkStickModel.h
@@ -1,62 +1,76 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_StickModel_H
#define _MITK_StickModel_H
#include <mitkDiffusionSignalModel.h>
namespace mitk {
/**
* \brief Generates the diffusion signal using an idealised cylinder with zero radius: e^(-bd(ng)²)
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class StickModel : public DiffusionSignalModel< ScalarType >
{
public:
StickModel();
+ template< class OtherType >StickModel(StickModel<OtherType>* model)
+ {
+ this->m_CompartmentId = model->m_CompartmentId;
+ this->m_T2 = model->GetT2();
+ this->m_FiberDirection = model->GetFiberDirection();
+ this->m_GradientList = model->GetGradientList();
+ this->m_VolumeFractionImage = model->GetVolumeFractionImage();
+ this->m_RandGen = model->GetRandomGenerator();
+
+ this->m_BValue = model->GetBvalue();
+ this->m_Diffusivity = model->GetDiffusivity();
+ }
~StickModel();
typedef typename DiffusionSignalModel< ScalarType >::PixelType PixelType;
typedef typename DiffusionSignalModel< ScalarType >::GradientType GradientType;
typedef typename DiffusionSignalModel< ScalarType >::GradientListType GradientListType;
/** Actual signal generation **/
PixelType SimulateMeasurement();
ScalarType SimulateMeasurement(unsigned int dir);
- void SetBvalue(ScalarType bValue) { m_BValue = bValue; } ///< b-value used to generate the artificial signal
- void SetDiffusivity(ScalarType diffusivity) { m_Diffusivity = diffusivity; } ///< Scalar diffusion constant
+ void SetBvalue(double bValue) { m_BValue = bValue; } ///< b-value used to generate the artificial signal
+ double GetBvalue() { return m_BValue; }
+ void SetDiffusivity(double diffusivity) { m_Diffusivity = diffusivity; } ///< Scalar diffusion constant
+ double GetDiffusivity() { return m_Diffusivity; }
void SetFiberDirection(GradientType fiberDirection){ this->m_FiberDirection = fiberDirection; }
void SetGradientList(GradientListType gradientList) { this->m_GradientList = gradientList; }
protected:
- ScalarType m_Diffusivity; ///< Scalar diffusion constant
- ScalarType m_BValue; ///< b-value used to generate the artificial signal
+ double m_Diffusivity; ///< Scalar diffusion constant
+ double m_BValue; ///< b-value used to generate the artificial signal
};
}
#include "mitkStickModel.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.cpp b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.cpp
index 1f83de5380..610d39661e 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.cpp
@@ -1,129 +1,129 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkTensorModel.h>
using namespace mitk;
template< class ScalarType >
TensorModel< ScalarType >::TensorModel()
: m_BValue(1000)
{
m_KernelDirection[0]=1; m_KernelDirection[1]=0; m_KernelDirection[2]=0;
m_KernelTensorMatrix.fill(0.0);
m_KernelTensorMatrix[0][0] = 0.002;
m_KernelTensorMatrix[1][1] = 0.0005;
m_KernelTensorMatrix[2][2] = 0.0005;
}
template< class ScalarType >
TensorModel< ScalarType >::~TensorModel()
{
}
template< class ScalarType >
ScalarType TensorModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
ScalarType signal = 0;
if (dir>=this->m_GradientList.size())
return signal;
ItkTensorType tensor; tensor.Fill(0.0);
this->m_FiberDirection.Normalize();
vnl_vector_fixed<double, 3> axis = itk::CrossProduct(m_KernelDirection, this->m_FiberDirection).GetVnlVector(); axis.normalize();
vnl_quaternion<double> rotation(axis, acos(m_KernelDirection*this->m_FiberDirection));
rotation.normalize();
vnl_matrix_fixed<double, 3, 3> matrix = rotation.rotation_matrix_transpose();
vnl_matrix_fixed<double, 3, 3> tensorMatrix = matrix.transpose()*m_KernelTensorMatrix*matrix;
tensor[0] = tensorMatrix[0][0]; tensor[1] = tensorMatrix[0][1]; tensor[2] = tensorMatrix[0][2];
tensor[3] = tensorMatrix[1][1]; tensor[4] = tensorMatrix[1][2]; tensor[5] = tensorMatrix[2][2];
GradientType g = this->m_GradientList[dir];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
{
itk::DiffusionTensor3D< ScalarType > S;
S[0] = g[0]*g[0];
S[1] = g[1]*g[0];
S[2] = g[2]*g[0];
S[3] = g[1]*g[1];
S[4] = g[2]*g[1];
S[5] = g[2]*g[2];
ScalarType D = tensor[0]*S[0] + tensor[1]*S[1] + tensor[2]*S[2] +
tensor[1]*S[1] + tensor[3]*S[3] + tensor[4]*S[4] +
tensor[2]*S[2] + tensor[4]*S[4] + tensor[5]*S[5];
// check for corrupted tensor and generate signal
if (D>=0)
- signal = exp ( -m_BValue * bVal * D );
+ signal = std::exp ( -m_BValue * bVal * D );
}
else
signal = 1;
return signal;
}
template< class ScalarType >
typename TensorModel< ScalarType >::PixelType TensorModel< ScalarType >::SimulateMeasurement()
{
PixelType signal; signal.SetSize(this->m_GradientList.size()); signal.Fill(0.0);
ItkTensorType tensor; tensor.Fill(0.0);
this->m_FiberDirection.Normalize();
vnl_vector_fixed<double, 3> axis = itk::CrossProduct(m_KernelDirection, this->m_FiberDirection).GetVnlVector(); axis.normalize();
vnl_quaternion<double> rotation(axis, acos(m_KernelDirection*this->m_FiberDirection));
rotation.normalize();
vnl_matrix_fixed<double, 3, 3> matrix = rotation.rotation_matrix_transpose();
vnl_matrix_fixed<double, 3, 3> tensorMatrix = matrix.transpose()*m_KernelTensorMatrix*matrix;
tensor[0] = tensorMatrix[0][0]; tensor[1] = tensorMatrix[0][1]; tensor[2] = tensorMatrix[0][2];
tensor[3] = tensorMatrix[1][1]; tensor[4] = tensorMatrix[1][2]; tensor[5] = tensorMatrix[2][2];
for( unsigned int i=0; i<this->m_GradientList.size(); i++)
{
GradientType g = this->m_GradientList[i];
ScalarType bVal = g.GetNorm(); bVal *= bVal;
if (bVal>0.0001)
{
itk::DiffusionTensor3D< ScalarType > S;
S[0] = g[0]*g[0];
S[1] = g[1]*g[0];
S[2] = g[2]*g[0];
S[3] = g[1]*g[1];
S[4] = g[2]*g[1];
S[5] = g[2]*g[2];
ScalarType D = tensor[0]*S[0] + tensor[1]*S[1] + tensor[2]*S[2] +
tensor[1]*S[1] + tensor[3]*S[3] + tensor[4]*S[4] +
tensor[2]*S[2] + tensor[4]*S[4] + tensor[5]*S[5];
// check for corrupted tensor and generate signal
if (D>=0)
- signal[i] = exp ( -m_BValue * bVal * D );
+ signal[i] = std::exp ( -m_BValue * bVal * D );
}
else
signal[i] = 1;
}
return signal;
}
diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.h
index 4ebe00bc6e..7734ba3cc3 100644
--- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.h
+++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkTensorModel.h
@@ -1,69 +1,88 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_TensorModel_H
#define _MITK_TensorModel_H
#include <mitkDiffusionSignalModel.h>
#include <itkDiffusionTensor3D.h>
namespace mitk {
/**
* \brief Generates diffusion measurement employing a second rank tensor model: e^(-bg^TDg)
*
*/
-template< class ScalarType >
+template< class ScalarType = double >
class TensorModel : public DiffusionSignalModel< ScalarType >
{
public:
TensorModel();
+ template< class OtherType >TensorModel(TensorModel<OtherType>* model)
+ {
+ this->m_CompartmentId = model->m_CompartmentId;
+ this->m_T2 = model->GetT2();
+ this->m_FiberDirection = model->GetFiberDirection();
+ this->m_GradientList = model->GetGradientList();
+ this->m_VolumeFractionImage = model->GetVolumeFractionImage();
+ this->m_RandGen = model->GetRandomGenerator();
+
+ this->m_BValue = model->GetBvalue();
+ this->m_KernelDirection = model->GetKernelDirection();
+ this->m_KernelTensorMatrix = model->GetKernelTensorMatrix();
+ }
~TensorModel();
typedef typename DiffusionSignalModel< ScalarType >::PixelType PixelType;
typedef itk::DiffusionTensor3D< ScalarType > ItkTensorType;
typedef typename DiffusionSignalModel< ScalarType >::GradientType GradientType;
typedef typename DiffusionSignalModel< ScalarType >::GradientListType GradientListType;
/** Actual signal generation **/
PixelType SimulateMeasurement();
ScalarType SimulateMeasurement(unsigned int dir);
- void SetBvalue(ScalarType bValue) { m_BValue = bValue; }
- void SetDiffusivity1(ScalarType d1){ m_KernelTensorMatrix[0][0] = d1; }
- void SetDiffusivity2(ScalarType d2){ m_KernelTensorMatrix[1][1] = d2; }
- void SetDiffusivity3(ScalarType d3){ m_KernelTensorMatrix[2][2] = d3; }
+ void SetBvalue(double bValue) { m_BValue = bValue; } ///< b-value used to generate the artificial signal
+ double GetBvalue() { return m_BValue; }
+ void SetDiffusivity1(double d1){ m_KernelTensorMatrix[0][0] = d1; }
+ void SetDiffusivity2(double d2){ m_KernelTensorMatrix[1][1] = d2; }
+ void SetDiffusivity3(double d3){ m_KernelTensorMatrix[2][2] = d3; }
+ double GetDiffusivity1() { return m_KernelTensorMatrix[0][0]; }
+ double GetDiffusivity2() { return m_KernelTensorMatrix[1][1]; }
+ double GetDiffusivity3() { return m_KernelTensorMatrix[2][2]; }
void SetFiberDirection(GradientType fiberDirection){ this->m_FiberDirection = fiberDirection; }
void SetGradientList(GradientListType gradientList) { this->m_GradientList = gradientList; }
+ GradientType GetKernelDirection(){ return m_KernelDirection; }
+ vnl_matrix_fixed<double, 3, 3> GetKernelTensorMatrix(){ return m_KernelTensorMatrix; }
protected:
/** Calculates tensor matrix from FA and ADC **/
void UpdateKernelTensor();
GradientType m_KernelDirection; ///< Direction of the kernel tensors principal eigenvector
- vnl_matrix_fixed<ScalarType, 3, 3> m_KernelTensorMatrix; ///< 3x3 matrix containing the kernel tensor values
- ScalarType m_BValue; ///< b-value used to generate the artificial signal
+ vnl_matrix_fixed<double, 3, 3> m_KernelTensorMatrix; ///< 3x3 matrix containing the kernel tensor values
+ double m_BValue; ///< b-value used to generate the artificial signal
};
}
#include "mitkTensorModel.cpp"
#endif
diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp
index 59554ecd46..e8aaee34b0 100644
--- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp
@@ -1,101 +1,106 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkIOUtil.h>
#include <mitkFiberBundleX.h>
#include <mitkPlanarFigure.h>
#include <mitkPlanarFigureComposite.h>
#include <mitkImageCast.h>
#include <mitkFiberBundleXWriter.h>
+#include <vtkDebugLeaks.h>
+
/**Documentation
* Test if fiber transfortaiom methods work correctly
*/
int mitkFiberExtractionTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("mitkFiberExtractionTest");
+ /// \todo Fix VTK memory leaks. Bug 18097.
+ vtkDebugLeaks::SetExitError(0);
+
MITK_INFO << "argc: " << argc;
MITK_TEST_CONDITION_REQUIRED(argc==13,"check for input data")
try{
mitk::FiberBundleX::Pointer groundTruthFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[1])->GetData());
mitk::FiberBundleX::Pointer testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[2])->GetData());
// test planar figure based extraction
mitk::PlanarFigure::Pointer pf1 = dynamic_cast<mitk::PlanarFigure*>(mitk::IOUtil::LoadDataNode(argv[3])->GetData());
mitk::PlanarFigure::Pointer pf2 = dynamic_cast<mitk::PlanarFigure*>(mitk::IOUtil::LoadDataNode(argv[4])->GetData());
mitk::PlanarFigure::Pointer pf3 = dynamic_cast<mitk::PlanarFigure*>(mitk::IOUtil::LoadDataNode(argv[5])->GetData());
MITK_INFO << "TEST1";
mitk::PlanarFigureComposite::Pointer pfc1 = mitk::PlanarFigureComposite::New();
pfc1->setOperationType(mitk::PFCOMPOSITION_AND_OPERATION);
pfc1->addPlanarFigure(dynamic_cast<mitk::BaseData*>(pf2.GetPointer()));
pfc1->addPlanarFigure(dynamic_cast<mitk::BaseData*>(pf3.GetPointer()));
MITK_INFO << "TEST2";
mitk::PlanarFigureComposite::Pointer pfc2 = mitk::PlanarFigureComposite::New();
pfc2->setOperationType(mitk::PFCOMPOSITION_OR_OPERATION);
pfc2->addPlanarFigure(dynamic_cast<mitk::BaseData*>(pf1.GetPointer()));
pfc2->addPlanarFigure(pfc1.GetPointer());
MITK_INFO << "TEST3";
mitk::FiberBundleX::Pointer extractedFibs = groundTruthFibs->ExtractFiberSubset(pfc2);
MITK_INFO << "TEST4";
MITK_TEST_CONDITION_REQUIRED(extractedFibs->Equals(testFibs),"check planar figure extraction")
MITK_INFO << "TEST5";
// test subtraction and addition
mitk::FiberBundleX::Pointer notExtractedFibs = groundTruthFibs->SubtractBundle(extractedFibs);
MITK_INFO << argv[11];
testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[11])->GetData());
MITK_TEST_CONDITION_REQUIRED(notExtractedFibs->Equals(testFibs),"check bundle subtraction")
mitk::FiberBundleX::Pointer joinded = extractedFibs->AddBundle(notExtractedFibs);
testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[12])->GetData());
MITK_TEST_CONDITION_REQUIRED(joinded->Equals(testFibs),"check bundle addition")
// test binary image based extraction
mitk::Image::Pointer mitkRoiImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(argv[6])->GetData());
typedef itk::Image< unsigned char, 3 > itkUCharImageType;
itkUCharImageType::Pointer itkRoiImage = itkUCharImageType::New();
mitk::CastToItkImage(mitkRoiImage, itkRoiImage);
mitk::FiberBundleX::Pointer inside = groundTruthFibs->RemoveFibersOutside(itkRoiImage, false);
mitk::FiberBundleX::Pointer outside = groundTruthFibs->RemoveFibersOutside(itkRoiImage, true);
mitk::FiberBundleX::Pointer passing = groundTruthFibs->ExtractFiberSubset(itkRoiImage, true);
mitk::FiberBundleX::Pointer ending = groundTruthFibs->ExtractFiberSubset(itkRoiImage, false);
testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[7])->GetData());
MITK_TEST_CONDITION_REQUIRED(inside->Equals(testFibs),"check inside mask extraction")
testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[8])->GetData());
MITK_TEST_CONDITION_REQUIRED(outside->Equals(testFibs),"check outside mask extraction")
testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[9])->GetData());
MITK_TEST_CONDITION_REQUIRED(passing->Equals(testFibs),"check passing mask extraction")
testFibs = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[10])->GetData());
MITK_TEST_CONDITION_REQUIRED(ending->Equals(testFibs),"check ending in mask extraction")
}
catch(...) {
return EXIT_FAILURE;
}
// always end with this!
MITK_TEST_END();
}
diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp
index 643b9da551..2e06ab9d38 100644
--- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp
@@ -1,86 +1,78 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkIOUtil.h>
#include <mitkFiberBundleX.h>
#include <mitkPlanarEllipse.h>
#include <itkFibersFromPlanarFiguresFilter.h>
/**Documentation
* Test if fiber transfortaiom methods work correctly
*/
int mitkFiberGenerationTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("mitkFiberGenerationTest");
MITK_TEST_CONDITION_REQUIRED(argc==6,"check for input data")
try{
mitk::PlanarEllipse::Pointer pf1 = dynamic_cast<mitk::PlanarEllipse*>(mitk::IOUtil::LoadDataNode(argv[1])->GetData());
mitk::PlanarEllipse::Pointer pf2 = dynamic_cast<mitk::PlanarEllipse*>(mitk::IOUtil::LoadDataNode(argv[2])->GetData());
mitk::PlanarEllipse::Pointer pf3 = dynamic_cast<mitk::PlanarEllipse*>(mitk::IOUtil::LoadDataNode(argv[3])->GetData());
mitk::FiberBundleX::Pointer uniform = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[4])->GetData());
mitk::FiberBundleX::Pointer gaussian = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(argv[5])->GetData());
-
+ FiberGenerationParameters parameters;
vector< mitk::PlanarEllipse::Pointer > fid; fid.push_back(pf1); fid.push_back(pf2); fid.push_back(pf3);
vector< unsigned int > flip; flip.push_back(0); flip.push_back(0); flip.push_back(0);
- vector< vector< mitk::PlanarEllipse::Pointer > > fiducials;
- vector< vector< unsigned int > > fliplist;
- fiducials.push_back(fid); fliplist.push_back(flip);
+ parameters.m_Fiducials.push_back(fid); parameters.m_FlipList.push_back(flip);
+ parameters.m_Density = 50;
+ parameters.m_Tension = 0;
+ parameters.m_Continuity = 0;
+ parameters.m_Bias = 0;
+ parameters.m_Sampling = 1;
+ parameters.m_Variance = 0.1;
// check uniform fiber distribution
{
itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New();
- filter->SetFiducials(fiducials);
- filter->SetFlipList(fliplist);
- filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_UNIFORM);
- filter->SetDensity(50);
- filter->SetTension(0);
- filter->SetContinuity(0);
- filter->SetBias(0);
- filter->SetFiberSampling(1);
+ parameters.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
+ filter->SetParameters(parameters);
filter->Update();
vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles();
MITK_TEST_CONDITION_REQUIRED(uniform->Equals(fiberBundles.at(0)),"check uniform bundle")
}
// check gaussian fiber distribution
{
itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New();
- filter->SetFiducials(fiducials);
- filter->SetFlipList(fliplist);
- filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_GAUSSIAN);
- filter->SetVariance(0.1);
- filter->SetDensity(50);
- filter->SetTension(0);
- filter->SetContinuity(0);
- filter->SetBias(0);
- filter->SetFiberSampling(1);
+ parameters.m_Distribution = FiberGenerationParameters::DISTRIBUTE_GAUSSIAN;
+ filter->SetParameters(parameters);
+ filter->SetParameters(parameters);
filter->Update();
vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles();
MITK_TEST_CONDITION_REQUIRED(gaussian->Equals(fiberBundles.at(0)),"check gaussian bundle")
}
}
catch(...) {
return EXIT_FAILURE;
}
// always end with this!
MITK_TEST_END();
}
diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxAddArtifactsToDwiTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxAddArtifactsToDwiTest.cpp
index bcb759106d..bef3714322 100644
--- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxAddArtifactsToDwiTest.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxAddArtifactsToDwiTest.cpp
@@ -1,181 +1,181 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkIOUtil.h>
#include <mitkFiberBundleX.h>
#include <itkAddArtifactsToDwiImageFilter.h>
#include <mitkFiberfoxParameters.h>
#include <mitkFiberBundleXReader.h>
#include <mitkStickModel.h>
#include <mitkTensorModel.h>
#include <mitkBallModel.h>
#include <mitkDotModel.h>
#include <mitkAstroStickModel.h>
#include <mitkDiffusionImage.h>
#include <itkTestingComparisonImageFilter.h>
#include <itkImageRegionConstIterator.h>
#include <mitkRicianNoiseModel.h>
#include <mitkChiSquareNoiseModel.h>
#include <mitkTestFixture.h>
/**Documentation
* Test the Fiberfox simulation functions (diffusion weighted image -> diffusion weighted image)
*/
class mitkFiberfoxAddArtifactsToDwiTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkFiberfoxAddArtifactsToDwiTestSuite);
MITK_TEST(Spikes);
MITK_TEST(GibbsRinging);
MITK_TEST(Ghost);
MITK_TEST(Aliasing);
MITK_TEST(Eddy);
MITK_TEST(RicianNoise);
MITK_TEST(ChiSquareNoise);
MITK_TEST(Distortions);
CPPUNIT_TEST_SUITE_END();
private:
mitk::DiffusionImage<short>::Pointer m_InputDwi;
FiberfoxParameters<short> m_Parameters;
public:
void setUp()
{
// reference files
m_InputDwi = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(GetTestDataFilePath("DiffusionImaging/Fiberfox/StickBall_RELAX.dwi"))->GetData());
// parameter setup
m_Parameters = FiberfoxParameters<short>();
- m_Parameters.m_ImageRegion = m_InputDwi->GetVectorImage()->GetLargestPossibleRegion();
- m_Parameters.m_ImageSpacing = m_InputDwi->GetVectorImage()->GetSpacing();
- m_Parameters.m_ImageOrigin = m_InputDwi->GetVectorImage()->GetOrigin();
- m_Parameters.m_ImageDirection = m_InputDwi->GetVectorImage()->GetDirection();
- m_Parameters.m_Bvalue = m_InputDwi->GetReferenceBValue();
- m_Parameters.SetGradienDirections(m_InputDwi->GetDirections());
+ m_Parameters.m_SignalGen.m_ImageRegion = m_InputDwi->GetVectorImage()->GetLargestPossibleRegion();
+ m_Parameters.m_SignalGen.m_ImageSpacing = m_InputDwi->GetVectorImage()->GetSpacing();
+ m_Parameters.m_SignalGen.m_ImageOrigin = m_InputDwi->GetVectorImage()->GetOrigin();
+ m_Parameters.m_SignalGen.m_ImageDirection = m_InputDwi->GetVectorImage()->GetDirection();
+ m_Parameters.m_SignalGen.m_Bvalue = m_InputDwi->GetReferenceBValue();
+ m_Parameters.m_SignalGen.SetGradienDirections(m_InputDwi->GetDirections());
}
bool CompareDwi(itk::VectorImage< short, 3 >* dwi1, itk::VectorImage< short, 3 >* dwi2)
{
typedef itk::VectorImage< short, 3 > DwiImageType;
try{
itk::ImageRegionIterator< DwiImageType > it1(dwi1, dwi1->GetLargestPossibleRegion());
itk::ImageRegionIterator< DwiImageType > it2(dwi2, dwi2->GetLargestPossibleRegion());
while(!it1.IsAtEnd())
{
if (it1.Get()!=it2.Get())
return false;
++it1;
++it2;
}
}
catch(...)
{
return false;
}
return true;
}
void StartSimulation(string testFileName)
{
mitk::DiffusionImage<short>::Pointer refImage = NULL;
if (!testFileName.empty())
CPPUNIT_ASSERT(refImage = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(testFileName)->GetData()));
itk::AddArtifactsToDwiImageFilter< short >::Pointer artifactsToDwiFilter = itk::AddArtifactsToDwiImageFilter< short >::New();
artifactsToDwiFilter->SetUseConstantRandSeed(true);
artifactsToDwiFilter->SetInput(m_InputDwi->GetVectorImage());
artifactsToDwiFilter->SetParameters(m_Parameters);
CPPUNIT_ASSERT_NO_THROW(artifactsToDwiFilter->Update());
mitk::DiffusionImage<short>::Pointer testImage = mitk::DiffusionImage<short>::New();
testImage->SetVectorImage( artifactsToDwiFilter->GetOutput() );
- testImage->SetReferenceBValue(m_Parameters.m_Bvalue);
- testImage->SetDirections(m_Parameters.GetGradientDirections());
+ testImage->SetReferenceBValue( m_Parameters.m_SignalGen.m_Bvalue);
+ testImage->SetDirections( m_Parameters.m_SignalGen.GetGradientDirections());
testImage->InitializeFromVectorImage();
if (refImage.IsNotNull())
{
CPPUNIT_ASSERT_MESSAGE(testFileName, CompareDwi(testImage->GetVectorImage(), refImage->GetVectorImage()));
}
}
void Spikes()
{
- m_Parameters.m_Spikes = 5;
- m_Parameters.m_SpikeAmplitude = 1;
+ m_Parameters.m_SignalGen.m_Spikes = 5;
+ m_Parameters.m_SignalGen.m_SpikeAmplitude = 1;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/spikes2.dwi") );
}
void GibbsRinging()
{
- m_Parameters.m_DoAddGibbsRinging = true;
+ m_Parameters.m_SignalGen.m_DoAddGibbsRinging = true;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/gibbsringing2.dwi") );
}
void Ghost()
{
- m_Parameters.m_KspaceLineOffset = 0.25;
+ m_Parameters.m_SignalGen.m_KspaceLineOffset = 0.25;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/ghost2.dwi") );
}
void Aliasing()
{
- m_Parameters.m_CroppingFactor = 0.4;
+ m_Parameters.m_SignalGen.m_CroppingFactor = 0.4;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/aliasing2.dwi") );
}
void Eddy()
{
- m_Parameters.m_EddyStrength = 0.05;
+ m_Parameters.m_SignalGen.m_EddyStrength = 0.05;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/eddy2.dwi") );
}
void RicianNoise()
{
mitk::RicianNoiseModel<short>* ricianNoiseModel = new mitk::RicianNoiseModel<short>();
ricianNoiseModel->SetNoiseVariance(1000000);
ricianNoiseModel->SetSeed(0);
m_Parameters.m_NoiseModel = ricianNoiseModel;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/riciannoise2.dwi") );
- delete m_Parameters.m_NoiseModel;
+ delete m_Parameters.m_NoiseModel;
}
void ChiSquareNoise()
{
mitk::ChiSquareNoiseModel<short>* chiSquareNoiseModel = new mitk::ChiSquareNoiseModel<short>();
chiSquareNoiseModel->SetNoiseVariance(1000000);
chiSquareNoiseModel->SetSeed(0);
m_Parameters.m_NoiseModel = chiSquareNoiseModel;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/chisquarenoise2.dwi") );
- delete m_Parameters.m_NoiseModel;
+ delete m_Parameters.m_NoiseModel;
}
void Distortions()
{
mitk::Image::Pointer mitkFMap = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode( GetTestDataFilePath("DiffusionImaging/Fiberfox/Fieldmap.nrrd") )->GetData());
typedef itk::Image<double, 3> ItkDoubleImgType;
ItkDoubleImgType::Pointer fMap = ItkDoubleImgType::New();
mitk::CastToItkImage(mitkFMap, fMap);
- m_Parameters.m_FrequencyMap = fMap;
+ m_Parameters.m_SignalGen.m_FrequencyMap = fMap;
StartSimulation( GetTestDataFilePath("DiffusionImaging/Fiberfox/distortions2.dwi") );
}
};
MITK_TEST_SUITE_REGISTRATION(mitkFiberfoxAddArtifactsToDwi)
diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp
index f67c4bc20c..1f28408a0a 100644
--- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp
+++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp
@@ -1,276 +1,276 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkIOUtil.h>
#include <mitkFiberBundleX.h>
#include <itkTractsToDWIImageFilter.h>
#include <mitkFiberfoxParameters.h>
#include <mitkFiberBundleXReader.h>
#include <mitkStickModel.h>
#include <mitkTensorModel.h>
#include <mitkBallModel.h>
#include <mitkDotModel.h>
#include <mitkAstroStickModel.h>
#include <mitkDiffusionImage.h>
#include <itkTestingComparisonImageFilter.h>
#include <itkImageRegionConstIterator.h>
#include <mitkRicianNoiseModel.h>
#include <mitkChiSquareNoiseModel.h>
/**Documentation
* Test the Fiberfox simulation functions (fiberBundle -> diffusion weighted image)
*/
bool CompareDwi(itk::VectorImage< short, 3 >* dwi1, itk::VectorImage< short, 3 >* dwi2)
{
typedef itk::VectorImage< short, 3 > DwiImageType;
try{
itk::ImageRegionIterator< DwiImageType > it1(dwi1, dwi1->GetLargestPossibleRegion());
itk::ImageRegionIterator< DwiImageType > it2(dwi2, dwi2->GetLargestPossibleRegion());
while(!it1.IsAtEnd())
{
if (it1.Get()!=it2.Get())
return false;
++it1;
++it2;
}
}
catch(...)
{
return false;
}
return true;
}
void StartSimulation(FiberfoxParameters<double> parameters, FiberBundleX::Pointer fiberBundle, mitk::DiffusionImage<short>::Pointer refImage, string message)
{
itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
tractsToDwiFilter->SetUseConstantRandSeed(true);
tractsToDwiFilter->SetParameters(parameters);
tractsToDwiFilter->SetFiberBundle(fiberBundle);
tractsToDwiFilter->Update();
mitk::DiffusionImage<short>::Pointer testImage = mitk::DiffusionImage<short>::New();
testImage->SetVectorImage( tractsToDwiFilter->GetOutput() );
- testImage->SetReferenceBValue(parameters.m_Bvalue);
- testImage->SetDirections(parameters.GetGradientDirections());
+ testImage->SetReferenceBValue(parameters.m_SignalGen.m_Bvalue);
+ testImage->SetDirections(parameters.m_SignalGen.GetGradientDirections());
testImage->InitializeFromVectorImage();
if (refImage.IsNotNull())
{
bool cond = CompareDwi(testImage->GetVectorImage(), refImage->GetVectorImage());
if (!cond)
{
MITK_INFO << "Saving test and rference image to " << mitk::IOUtil::GetTempPath();
mitk::IOUtil::SaveBaseData(testImage, mitk::IOUtil::GetTempPath()+"testImage.dwi");
mitk::IOUtil::SaveBaseData(refImage, mitk::IOUtil::GetTempPath()+"refImage.dwi");
}
MITK_TEST_CONDITION_REQUIRED(cond, message);
}
}
int mitkFiberfoxSignalGenerationTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("mitkFiberfoxSignalGenerationTest");
MITK_TEST_CONDITION_REQUIRED(argc>=19,"check for input data");
// input fiber bundle
FiberBundleXReader::Pointer fibReader = FiberBundleXReader::New();
fibReader->SetFileName(argv[1]);
fibReader->Update();
FiberBundleX::Pointer fiberBundle = dynamic_cast<FiberBundleX*>(fibReader->GetOutput());
// reference diffusion weighted images
mitk::DiffusionImage<short>::Pointer stickBall = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[2])->GetData());
mitk::DiffusionImage<short>::Pointer stickAstrosticks = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[3])->GetData());
mitk::DiffusionImage<short>::Pointer stickDot = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[4])->GetData());
mitk::DiffusionImage<short>::Pointer tensorBall = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[5])->GetData());
mitk::DiffusionImage<short>::Pointer stickTensorBall = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[6])->GetData());
mitk::DiffusionImage<short>::Pointer stickTensorBallAstrosticks = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[7])->GetData());
mitk::DiffusionImage<short>::Pointer gibbsringing = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[8])->GetData());
mitk::DiffusionImage<short>::Pointer ghost = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[9])->GetData());
mitk::DiffusionImage<short>::Pointer aliasing = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[10])->GetData());
mitk::DiffusionImage<short>::Pointer eddy = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[11])->GetData());
mitk::DiffusionImage<short>::Pointer linearmotion = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[12])->GetData());
mitk::DiffusionImage<short>::Pointer randommotion = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[13])->GetData());
mitk::DiffusionImage<short>::Pointer spikes = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[14])->GetData());
mitk::DiffusionImage<short>::Pointer riciannoise = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[15])->GetData());
mitk::DiffusionImage<short>::Pointer chisquarenoise = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[16])->GetData());
mitk::DiffusionImage<short>::Pointer distortions = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[17])->GetData());
mitk::Image::Pointer mitkFMap = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(argv[18])->GetData());
typedef itk::Image<double, 3> ItkDoubleImgType;
ItkDoubleImgType::Pointer fMap = ItkDoubleImgType::New();
mitk::CastToItkImage(mitkFMap, fMap);
FiberfoxParameters<double> parameters;
- parameters.m_SimulateKspaceAcquisition = true;
- parameters.m_SignalScale = 10000;
- parameters.m_ImageRegion = stickBall->GetVectorImage()->GetLargestPossibleRegion();
- parameters.m_ImageSpacing = stickBall->GetVectorImage()->GetSpacing();
- parameters.m_ImageOrigin = stickBall->GetVectorImage()->GetOrigin();
- parameters.m_ImageDirection = stickBall->GetVectorImage()->GetDirection();
- parameters.m_Bvalue = stickBall->GetReferenceBValue();
- parameters.SetGradienDirections(stickBall->GetDirections());
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
+ parameters.m_SignalGen.m_SignalScale = 10000;
+ parameters.m_SignalGen.m_ImageRegion = stickBall->GetVectorImage()->GetLargestPossibleRegion();
+ parameters.m_SignalGen.m_ImageSpacing = stickBall->GetVectorImage()->GetSpacing();
+ parameters.m_SignalGen.m_ImageOrigin = stickBall->GetVectorImage()->GetOrigin();
+ parameters.m_SignalGen.m_ImageDirection = stickBall->GetVectorImage()->GetDirection();
+ parameters.m_SignalGen.m_Bvalue = stickBall->GetReferenceBValue();
+ parameters.m_SignalGen.SetGradienDirections(stickBall->GetDirections());
// intra and inter axonal compartments
mitk::StickModel<double> stickModel;
- stickModel.SetBvalue(parameters.m_Bvalue);
+ stickModel.SetBvalue(parameters.m_SignalGen.m_Bvalue);
stickModel.SetT2(110);
stickModel.SetDiffusivity(0.001);
- stickModel.SetGradientList(parameters.GetGradientDirections());
+ stickModel.SetGradientList(parameters.m_SignalGen.GetGradientDirections());
mitk::TensorModel<double> tensorModel;
tensorModel.SetT2(110);
- stickModel.SetBvalue(parameters.m_Bvalue);
+ stickModel.SetBvalue(parameters.m_SignalGen.m_Bvalue);
tensorModel.SetDiffusivity1(0.001);
tensorModel.SetDiffusivity2(0.00025);
tensorModel.SetDiffusivity3(0.00025);
- tensorModel.SetGradientList(parameters.GetGradientDirections());
+ tensorModel.SetGradientList(parameters.m_SignalGen.GetGradientDirections());
// extra axonal compartment models
mitk::BallModel<double> ballModel;
ballModel.SetT2(80);
- ballModel.SetBvalue(parameters.m_Bvalue);
+ ballModel.SetBvalue(parameters.m_SignalGen.m_Bvalue);
ballModel.SetDiffusivity(0.001);
- ballModel.SetGradientList(parameters.GetGradientDirections());
+ ballModel.SetGradientList(parameters.m_SignalGen.GetGradientDirections());
mitk::AstroStickModel<double> astrosticksModel;
astrosticksModel.SetT2(80);
- astrosticksModel.SetBvalue(parameters.m_Bvalue);
+ astrosticksModel.SetBvalue(parameters.m_SignalGen.m_Bvalue);
astrosticksModel.SetDiffusivity(0.001);
astrosticksModel.SetRandomizeSticks(true);
astrosticksModel.SetSeed(0);
- astrosticksModel.SetGradientList(parameters.GetGradientDirections());
+ astrosticksModel.SetGradientList(parameters.m_SignalGen.GetGradientDirections());
mitk::DotModel<double> dotModel;
dotModel.SetT2(80);
- dotModel.SetGradientList(parameters.GetGradientDirections());
+ dotModel.SetGradientList(parameters.m_SignalGen.GetGradientDirections());
// noise models
mitk::RicianNoiseModel<double>* ricianNoiseModel = new mitk::RicianNoiseModel<double>();
ricianNoiseModel->SetNoiseVariance(1000000);
ricianNoiseModel->SetSeed(0);
// Rician noise
mitk::ChiSquareNoiseModel<double>* chiSquareNoiseModel = new mitk::ChiSquareNoiseModel<double>();
chiSquareNoiseModel->SetNoiseVariance(1000000);
chiSquareNoiseModel->SetSeed(0);
try{
// Stick-Ball
parameters.m_FiberModelList.push_back(&stickModel);
parameters.m_NonFiberModelList.push_back(&ballModel);
StartSimulation(parameters, fiberBundle, stickBall, argv[2]);
// Srick-Astrosticks
parameters.m_NonFiberModelList.clear();
parameters.m_NonFiberModelList.push_back(&astrosticksModel);
StartSimulation(parameters, fiberBundle, stickAstrosticks, argv[3]);
// Stick-Dot
parameters.m_NonFiberModelList.clear();
parameters.m_NonFiberModelList.push_back(&dotModel);
StartSimulation(parameters, fiberBundle, stickDot, argv[4]);
// Tensor-Ball
parameters.m_FiberModelList.clear();
parameters.m_FiberModelList.push_back(&tensorModel);
parameters.m_NonFiberModelList.clear();
parameters.m_NonFiberModelList.push_back(&ballModel);
StartSimulation(parameters, fiberBundle, tensorBall, argv[5]);
// Stick-Tensor-Ball
parameters.m_FiberModelList.clear();
parameters.m_FiberModelList.push_back(&stickModel);
parameters.m_FiberModelList.push_back(&tensorModel);
parameters.m_NonFiberModelList.clear();
parameters.m_NonFiberModelList.push_back(&ballModel);
StartSimulation(parameters, fiberBundle, stickTensorBall, argv[6]);
// Stick-Tensor-Ball-Astrosticks
parameters.m_NonFiberModelList.push_back(&astrosticksModel);
StartSimulation(parameters, fiberBundle, stickTensorBallAstrosticks, argv[7]);
// Gibbs ringing
parameters.m_FiberModelList.clear();
parameters.m_FiberModelList.push_back(&stickModel);
parameters.m_NonFiberModelList.clear();
parameters.m_NonFiberModelList.push_back(&ballModel);
- parameters.m_DoAddGibbsRinging = true;
+ parameters.m_SignalGen.m_DoAddGibbsRinging = true;
StartSimulation(parameters, fiberBundle, gibbsringing, argv[8]);
// Ghost
- parameters.m_DoAddGibbsRinging = false;
- parameters.m_KspaceLineOffset = 0.25;
+ parameters.m_SignalGen.m_DoAddGibbsRinging = false;
+ parameters.m_SignalGen.m_KspaceLineOffset = 0.25;
StartSimulation(parameters, fiberBundle, ghost, argv[9]);
// Aliasing
- parameters.m_KspaceLineOffset = 0;
- parameters.m_CroppingFactor = 0.4;
- parameters.m_SignalScale = 1000;
+ parameters.m_SignalGen.m_KspaceLineOffset = 0;
+ parameters.m_SignalGen.m_CroppingFactor = 0.4;
+ parameters.m_SignalGen.m_SignalScale = 1000;
StartSimulation(parameters, fiberBundle, aliasing, argv[10]);
// Eddy currents
- parameters.m_CroppingFactor = 1;
- parameters.m_SignalScale = 10000;
- parameters.m_EddyStrength = 0.05;
+ parameters.m_SignalGen.m_CroppingFactor = 1;
+ parameters.m_SignalGen.m_SignalScale = 10000;
+ parameters.m_SignalGen.m_EddyStrength = 0.05;
StartSimulation(parameters, fiberBundle, eddy, argv[11]);
// Motion (linear)
- parameters.m_EddyStrength = 0.0;
- parameters.m_DoAddMotion = true;
- parameters.m_DoRandomizeMotion = false;
- parameters.m_Translation[1] = 10;
- parameters.m_Rotation[2] = 90;
+ parameters.m_SignalGen.m_EddyStrength = 0.0;
+ parameters.m_SignalGen.m_DoAddMotion = true;
+ parameters.m_SignalGen.m_DoRandomizeMotion = false;
+ parameters.m_SignalGen.m_Translation[1] = 10;
+ parameters.m_SignalGen.m_Rotation[2] = 90;
StartSimulation(parameters, fiberBundle, linearmotion, argv[12]);
// Motion (random)
- parameters.m_DoRandomizeMotion = true;
- parameters.m_Translation[1] = 5;
- parameters.m_Rotation[2] = 45;
+ parameters.m_SignalGen.m_DoRandomizeMotion = true;
+ parameters.m_SignalGen.m_Translation[1] = 5;
+ parameters.m_SignalGen.m_Rotation[2] = 45;
StartSimulation(parameters, fiberBundle, randommotion, argv[13]);
// Spikes
- parameters.m_DoAddMotion = false;
- parameters.m_Spikes = 5;
- parameters.m_SpikeAmplitude = 1;
+ parameters.m_SignalGen.m_DoAddMotion = false;
+ parameters.m_SignalGen.m_Spikes = 5;
+ parameters.m_SignalGen.m_SpikeAmplitude = 1;
StartSimulation(parameters, fiberBundle, spikes, argv[14]);
// Rician noise
- parameters.m_Spikes = 0;
+ parameters.m_SignalGen.m_Spikes = 0;
parameters.m_NoiseModel = ricianNoiseModel;
StartSimulation(parameters, fiberBundle, riciannoise, argv[15]);
delete parameters.m_NoiseModel;
// Chi-square noise
parameters.m_NoiseModel = chiSquareNoiseModel;
StartSimulation(parameters, fiberBundle, chisquarenoise, argv[16]);
delete parameters.m_NoiseModel;
// Distortions
parameters.m_NoiseModel = NULL;
- parameters.m_FrequencyMap = fMap;
+ parameters.m_SignalGen.m_FrequencyMap = fMap;
StartSimulation(parameters, fiberBundle, distortions, argv[17]);
}
catch (std::exception &e)
{
MITK_TEST_CONDITION_REQUIRED(false, e.what());
}
// always end with this!
MITK_TEST_END();
}
diff --git a/Modules/DiffusionImaging/MiniApps/CMakeLists.txt b/Modules/DiffusionImaging/MiniApps/CMakeLists.txt
index 0959ccab4e..5f79886390 100755
--- a/Modules/DiffusionImaging/MiniApps/CMakeLists.txt
+++ b/Modules/DiffusionImaging/MiniApps/CMakeLists.txt
@@ -1,64 +1,64 @@
option(BUILD_DiffusionMiniApps "Build commandline tools for diffusion" OFF)
if(BUILD_DiffusionMiniApps OR MITK_BUILD_ALL_APPS)
# needed include directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
project( MitkDiffusionMiniApps )
# fill in the standalone executables here
set(DIFFUSIONMINIAPPS
mitkDiffusionMiniApps
)
# set additional files here
set(DIFFUSIONCORE_ADDITIONAL_FILES
MiniAppManager.cpp
FileFormatConverter.cpp
TensorReconstruction.cpp
QballReconstruction.cpp
DiffusionIndices.cpp
CopyGeometry.cpp
GibbsTracking.cpp
StreamlineTracking.cpp
FiberProcessing.cpp
LocalDirectionalFiberPlausibility.cpp
#TractogramAngularError.cpp
FiberDirectionExtraction.cpp
PeakExtraction.cpp
PeaksAngularError.cpp
MultishellMethods.cpp
- #FiberFoxProcessing.cpp
+ Fiberfox.cpp
ExportShImage.cpp
NetworkCreation.cpp
NetworkStatistics.cpp
DwiDenoising.cpp
)
# deprecated
# FOREACH(tool ${DIFFUSIONMINIAPPS})
# ADD_EXECUTABLE(
# ${tool}
# ${tool}.cpp
# ${DIFFUSIONCORE_ADDITIONAL_FILES}
# )
# TARGET_LINK_LIBRARIES(
# ${tool}
# ${ALL_LIBRARIES} )
# ENDFOREACH(tool)
mitk_create_executable(DiffusionMiniApps
DEPENDS MitkDiffusionCore MitkFiberTracking MitkConnectomics
PACKAGE_DEPENDS ITK|ITKDiffusionTensorImage
)
if(EXECUTABLE_IS_ENABLED)
MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET})
endif()
endif()
diff --git a/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp b/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp
deleted file mode 100755
index 695addd8b4..0000000000
--- a/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp
+++ /dev/null
@@ -1,545 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "MiniAppManager.h"
-#include <mitkImageCast.h>
-#include <mitkDiffusionImage.h>
-#include <mitkBaseDataIOFactory.h>
-#include <mitkFiberTrackingObjectFactory.h>
-#include <mitkIOUtil.h>
-#include <mitkNrrdDiffusionImageWriter.h>
-#include <mitkFiberBundleX.h>
-//#include "ctkCommandLineParser.h"
-#include "ctkCommandLineParser.h"
-#include <mitkRicianNoiseModel.h>
-
-#include <itkAddArtifactsToDwiImageFilter.h>
-#include <itkTractsToDWIImageFilter.h>
-
-#include "boost/property_tree/ptree.hpp"
-#include "boost/property_tree/xml_parser.hpp"
-#include "boost/foreach.hpp"
-#include <mitkStickModel.h>
-#include <mitkTensorModel.h>
-#include <mitkAstroStickModel.h>
-#include <mitkBallModel.h>
-#include <mitkDotModel.h>
-
-using namespace mitk;
-
-struct ImageParameters {
- itk::ImageRegion<3> imageRegion;
- itk::Vector<double,3> imageSpacing;
- itk::Point<double,3> imageOrigin;
- itk::Matrix<double, 3, 3> imageDirection;
- unsigned int numGradients;
- double b_value;
- unsigned int repetitions;
- double signalScale;
- double tEcho;
- double tLine;
- double tInhom;
- double axonRadius;
- unsigned int interpolationShrink;
- double kspaceLineOffset;
- double upsampling;
- double eddyStrength;
- double comp3Weight;
- double comp4Weight;
- int spikes;
- double spikeAmplitude;
-
- bool doSimulateRelaxation;
- bool doSimulateEddyCurrents;
- bool doDisablePartialVolume;
-
- mitk::RicianNoiseModel<double> ricianNoiseModel;
- mitk::DiffusionSignalModel<double>::GradientListType gradientDirections;
- itk::TractsToDWIImageFilter< short >::DiffusionModelListType fiberModelList, nonFiberModelList;
- std::string signalModelString, artifactModelString;
-
- itk::Image<double, 3>::Pointer frequencyMap;
- itk::Image<unsigned char, 3>::Pointer tissueMaskImage;
-
- mitk::DataNode::Pointer resultNode;
-};
-
-
-
-void LoadParameters(const std::string & filename,
- ImageParameters & m_ImageGenParameters,
- mitk::Image::Pointer m_fImage,
- mitk::Image::Pointer m_maskImage,
- mitk::StickModel<double> * m_StickModel1,
- mitk::StickModel<double> * m_StickModel2,
- mitk::TensorModel<double> * m_ZeppelinModel1,
- mitk::TensorModel<double> * m_ZeppelinModel2,
- mitk::TensorModel<double> * m_TensorModel1,
- mitk::TensorModel<double> * m_TensorModel2,
-
- // extra axonal compartment models
- mitk::BallModel<double> * m_BallModel1,
- mitk::BallModel<double> * m_BallModel2,
- mitk::AstroStickModel<double> * m_AstrosticksModel1,
- mitk::AstroStickModel<double> * m_AstrosticksModel2,
- mitk::DotModel<double> * m_DotModel1,
- mitk::DotModel<double> * m_DotModel2)
-{
-
-
-
- MITK_INFO << "Initialize Diffusion Models";
-
- boost::property_tree::ptree parameters;
- boost::property_tree::xml_parser::read_xml(filename, parameters);
-
- m_ImageGenParameters.nonFiberModelList.clear();
- m_ImageGenParameters.fiberModelList.clear();
- m_ImageGenParameters.signalModelString = "";
- m_ImageGenParameters.artifactModelString = "";
- m_ImageGenParameters.resultNode = mitk::DataNode::New();
- //m_ImageGenParameters.tissueMaskImage = NULL;
- //m_ImageGenParameters.frequencyMap = NULL;
- //m_ImageGenParameters.gradientDirections.clear();
- m_ImageGenParameters.spikes = 0;
- m_ImageGenParameters.spikeAmplitude = 1;
-
- MITK_INFO << "reset params";
-
- BOOST_FOREACH( boost::property_tree::ptree::value_type const& v1, parameters.get_child("fiberfox") )
- {
- if( v1.first == "image" )
- {
- MITK_INFO << "Load image params";
- m_ImageGenParameters.tEcho = v1.second.get<double>("tEcho");
- m_ImageGenParameters.tLine = v1.second.get<double>("tLine");
-
- m_ImageGenParameters.doSimulateEddyCurrents = v1.second.get<bool>("artifacts.addeddy");
- m_ImageGenParameters.eddyStrength = 0;
- if (m_ImageGenParameters.doSimulateEddyCurrents)
- {
- m_ImageGenParameters.eddyStrength = v1.second.get<double>("artifacts.eddyStrength");
- }
-
- // signal relaxation
- m_ImageGenParameters.doSimulateRelaxation = v1.second.get<bool>("doSimulateRelaxation");
- if (m_ImageGenParameters.doSimulateRelaxation)
-
- // N/2 ghosts
- if (v1.second.get<bool>("artifacts.addghost"))
- {
- m_ImageGenParameters.kspaceLineOffset = v1.second.get<double>("artifacts.kspaceLineOffset");
- }
- else
- {
- m_ImageGenParameters.kspaceLineOffset = 0;
- }
-
- if (v1.second.get<bool>("artifacts.addspikes"))
- {
- m_ImageGenParameters.spikes = v1.second.get<int>("artifacts.spikesnum");
- m_ImageGenParameters.spikeAmplitude = v1.second.get<double>("artifacts.spikesscale");
- }
-
-
- // add distortions
- if (v1.second.get<bool>("artifacts.distortions") && m_fImage)
- {
- itk::Image<double,3>::Pointer itkImg = itk::Image<double,3>::New();
- mitk::CastToItkImage< itk::Image<double,3> >(m_fImage, itkImg);
-
- if (m_ImageGenParameters.imageRegion.GetSize(0)==itkImg->GetLargestPossibleRegion().GetSize(0) &&
- m_ImageGenParameters.imageRegion.GetSize(1)==itkImg->GetLargestPossibleRegion().GetSize(1) &&
- m_ImageGenParameters.imageRegion.GetSize(2)==itkImg->GetLargestPossibleRegion().GetSize(2))
- {
- m_ImageGenParameters.frequencyMap = itkImg;
- }
- }
-
- // rician noise
- if (v1.second.get<bool>("artifacts.addnoise"))
- m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(v1.second.get<double>("artifacts.noisevariance"));
- else
- m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(0);
-
- // gibbs ringing
- m_ImageGenParameters.upsampling = 1;
- if (v1.second.get<bool>("artifacts.addringing"))
- m_ImageGenParameters.upsampling = v1.second.get<double>("artifacts.ringingupsampling");
-
- // adjusting line readout time to the adapted image size needed for the DFT
- int y = m_ImageGenParameters.imageRegion.GetSize(1);
- if ( y%2 == 1 )
- y += 1;
- if ( y>m_ImageGenParameters.imageRegion.GetSize(1) )
- m_ImageGenParameters.tLine *= (double)m_ImageGenParameters.imageRegion.GetSize(1)/y;
-
-
- // check tissue mask
- if (m_maskImage.IsNotNull())
- {
- m_ImageGenParameters.tissueMaskImage = itk::Image<unsigned char,3>::New();
- mitk::CastToItkImage<itk::Image<unsigned char,3> >(m_maskImage.GetPointer(), m_ImageGenParameters.tissueMaskImage);
- }
-
- // signal models
- m_ImageGenParameters.comp3Weight = 1;
- m_ImageGenParameters.comp4Weight = 0;
- if (v1.second.get<int>("compartment4.index") > 0)
- {
- m_ImageGenParameters.comp4Weight = v1.second.get<double>("compartment4.weight");
- m_ImageGenParameters.comp3Weight -= m_ImageGenParameters.comp4Weight;
- }
-
-
-
- // compartment 1
- switch(v1.second.get<int>("compartment1.index")){
- case 0:
- m_StickModel1->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_StickModel1->SetBvalue(m_ImageGenParameters.b_value);
- m_StickModel1->SetDiffusivity(v1.second.get<double>("compartment1.stick.d"));
- m_StickModel1->SetT2(v1.second.get<double>("compartment1.stick.t2"));
- m_ImageGenParameters.fiberModelList.push_back(m_StickModel1);
- break;
- case 1:
- m_ZeppelinModel1->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_ZeppelinModel1->SetBvalue(m_ImageGenParameters.b_value);
- m_ZeppelinModel1->SetDiffusivity1(v1.second.get<double>("compartment1.zeppelin.d1"));
- m_ZeppelinModel1->SetDiffusivity2(v1.second.get<double>("compartment1.zeppelin.d2"));
- m_ZeppelinModel1->SetDiffusivity3(v1.second.get<double>("compartment1.zeppelin.d2"));
- m_ZeppelinModel1->SetT2(v1.second.get<double>("compartment1.zeppelin.t2"));
- m_ImageGenParameters.fiberModelList.push_back(m_ZeppelinModel1);
- break;
- case 2:
- m_TensorModel1->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_TensorModel1->SetBvalue(m_ImageGenParameters.b_value);
- m_TensorModel1->SetDiffusivity1(v1.second.get<double>("compartment1.tensor.d1"));
- m_TensorModel1->SetDiffusivity2(v1.second.get<double>("compartment1.tensor.d2"));
- m_TensorModel1->SetDiffusivity3(v1.second.get<double>("compartment1.tensor.d3"));
- m_TensorModel1->SetT2(v1.second.get<double>("compartment1.tensor.t2"));
- m_ImageGenParameters.fiberModelList.push_back(m_TensorModel1);
- break;
- }
-
- // compartment 2
- switch(v1.second.get<int>("compartment2.index")){
- case 0:
- m_StickModel2->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_StickModel2->SetBvalue(m_ImageGenParameters.b_value);
- m_StickModel2->SetDiffusivity(v1.second.get<double>("compartment2.stick.d"));
- m_StickModel2->SetT2(v1.second.get<double>("compartment2.stick.t2"));
- m_ImageGenParameters.fiberModelList.push_back(m_StickModel2);
- break;
- case 1:
- m_ZeppelinModel2->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_ZeppelinModel2->SetBvalue(m_ImageGenParameters.b_value);
- m_ZeppelinModel2->SetDiffusivity1(v1.second.get<double>("compartment2.zeppelin.d1"));
- m_ZeppelinModel2->SetDiffusivity2(v1.second.get<double>("compartment2.zeppelin.d2"));
- m_ZeppelinModel2->SetDiffusivity3(v1.second.get<double>("compartment2.zeppelin.d2"));
- m_ZeppelinModel2->SetT2(v1.second.get<double>("compartment2.zeppelin.t2"));
- m_ImageGenParameters.fiberModelList.push_back(m_ZeppelinModel2);
- break;
- case 2:
- m_TensorModel2->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_TensorModel2->SetBvalue(m_ImageGenParameters.b_value);
- m_TensorModel2->SetDiffusivity1(v1.second.get<double>("compartment2.tensor.d1"));
- m_TensorModel2->SetDiffusivity2(v1.second.get<double>("compartment2.tensor.d2"));
- m_TensorModel2->SetDiffusivity3(v1.second.get<double>("compartment2.tensor.d3"));
- m_TensorModel2->SetT2(v1.second.get<double>("compartment2.tensor.t2"));
- m_ImageGenParameters.fiberModelList.push_back(m_TensorModel2);
- break;
- }
-
- // compartment 3
- switch(v1.second.get<int>("compartment3.index")){
- case 0:
- m_BallModel1->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_BallModel1->SetBvalue(m_ImageGenParameters.b_value);
- m_BallModel1->SetDiffusivity(v1.second.get<double>("compartment3.ball.d"));
- m_BallModel1->SetT2(v1.second.get<double>("compartment3.ball.t2"));
- m_BallModel1->SetWeight(m_ImageGenParameters.comp3Weight);
- m_ImageGenParameters.nonFiberModelList.push_back(m_BallModel1);
- break;
- case 1:
- m_AstrosticksModel1->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_AstrosticksModel1->SetBvalue(m_ImageGenParameters.b_value);
- m_AstrosticksModel1->SetDiffusivity(v1.second.get<double>("compartment3.astrosticks.d"));
- m_AstrosticksModel1->SetT2(v1.second.get<double>("compartment3.astrosticks.t2"));
- m_AstrosticksModel1->SetRandomizeSticks(v1.second.get<bool>("compartment3.astrosticks.randomize"));
- m_AstrosticksModel1->SetWeight(m_ImageGenParameters.comp3Weight);
- m_ImageGenParameters.nonFiberModelList.push_back(m_AstrosticksModel1);
- break;
- case 2:
- m_DotModel1->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_DotModel1->SetT2(v1.second.get<double>("compartment3.dot.t2"));
- m_DotModel1->SetWeight(m_ImageGenParameters.comp3Weight);
- m_ImageGenParameters.nonFiberModelList.push_back(m_DotModel1);
- break;
- }
-
- // compartment 4
- switch(v1.second.get<int>("compartment4.index")){
- case 0:
- m_BallModel2->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_BallModel2->SetBvalue(m_ImageGenParameters.b_value);
- m_BallModel2->SetDiffusivity(v1.second.get<double>("compartment4.ball.d"));
- m_BallModel2->SetT2(v1.second.get<double>("compartment4.ball.t2"));
- m_BallModel2->SetWeight(m_ImageGenParameters.comp4Weight);
- m_ImageGenParameters.nonFiberModelList.push_back(m_BallModel2);
- break;
- case 1:
- m_AstrosticksModel2->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_AstrosticksModel2->SetBvalue(m_ImageGenParameters.b_value);
- m_AstrosticksModel2->SetDiffusivity(v1.second.get<double>("compartment4.astrosticks.d"));
- m_AstrosticksModel2->SetT2(v1.second.get<double>("compartment4.astrosticks.t2"));
- m_AstrosticksModel2->SetRandomizeSticks(v1.second.get<bool>("compartment4.astrosticks.randomize"));
- m_AstrosticksModel2->SetWeight(m_ImageGenParameters.comp4Weight);
- m_ImageGenParameters.nonFiberModelList.push_back(m_AstrosticksModel2);
- break;
- case 2:
- m_DotModel2->SetGradientList(m_ImageGenParameters.gradientDirections);
- m_DotModel2->SetT2(v1.second.get<double>("compartment4.dot.t2"));
- m_DotModel2->SetWeight(m_ImageGenParameters.comp4Weight);
- m_ImageGenParameters.nonFiberModelList.push_back(m_DotModel2);
- break;
- }
-
- m_ImageGenParameters.signalScale = v1.second.get<int>("signalScale");
- m_ImageGenParameters.repetitions = v1.second.get<int>("repetitions");
-
- m_ImageGenParameters.tInhom = v1.second.get<double>("tInhom");
-
- m_ImageGenParameters.doDisablePartialVolume = v1.second.get<bool>("doDisablePartialVolume");
- m_ImageGenParameters.interpolationShrink = v1.second.get<int>("interpolationShrink");
- m_ImageGenParameters.axonRadius = v1.second.get<double>("axonRadius");
- }
-
- /*
-m_Controls->m_VarianceBox->setValue(v1.second.get<double>("variance"));
-
-
-
-m_Controls->m_AdvancedOptionsBox->setChecked(v1.second.get<bool>("showadvanced"));
-m_Controls->m_AdvancedOptionsBox_2->setChecked(v1.second.get<bool>("showadvanced"));
-
- m_Controls->m_VolumeFractionsBox->setChecked(v1.second.get<bool>("outputvolumefractions"));
- m_Controls->m_RealTimeFibers->setChecked(v1.second.get<bool>("realtime"));
-
- m_Controls->m_DistributionBox->setCurrentIndex(v1.second.get<int>("distribution"));
-
- m_Controls->m_FiberDensityBox->setValue(v1.second.get<int>("density"));
- m_Controls->m_IncludeFiducials->setChecked(v1.second.get<bool>("includeFiducials"));
- m_Controls->m_ConstantRadiusBox->setChecked(v1.second.get<bool>("constantradius"));
-
-
-
-
- BOOST_FOREACH( boost::property_tree::ptree::value_type const& v2, v1.second )
- {
- if( v2.first == "spline" )
- {
- m_Controls->m_FiberSamplingBox->setValue(v2.second.get<double>("sampling"));
- m_Controls->m_TensionBox->setValue(v2.second.get<double>("tension"));
- m_Controls->m_ContinuityBox->setValue(v2.second.get<double>("continuity"));
- m_Controls->m_BiasBox->setValue(v2.second.get<double>("bias"));
- }
- if( v2.first == "rotation" )
- {
- m_Controls->m_XrotBox->setValue(v2.second.get<double>("x"));
- m_Controls->m_YrotBox->setValue(v2.second.get<double>("y"));
- m_Controls->m_ZrotBox->setValue(v2.second.get<double>("z"));
- }
- if( v2.first == "translation" )
- {
- m_Controls->m_XtransBox->setValue(v2.second.get<double>("x"));
- m_Controls->m_YtransBox->setValue(v2.second.get<double>("y"));
- m_Controls->m_ZtransBox->setValue(v2.second.get<double>("z"));
- }
- if( v2.first == "scale" )
- {
- m_Controls->m_XscaleBox->setValue(v2.second.get<double>("x"));
- m_Controls->m_YscaleBox->setValue(v2.second.get<double>("y"));
- m_Controls->m_ZscaleBox->setValue(v2.second.get<double>("z"));
- }
- }
- }
- if( v1.first == "image" )
- {
- m_Controls->m_SizeX->setValue(v1.second.get<int>("basic.size.x"));
- m_Controls->m_SizeY->setValue(v1.second.get<int>("basic.size.y"));
- m_Controls->m_SizeZ->setValue(v1.second.get<int>("basic.size.z"));
- m_Controls->m_SpacingX->setValue(v1.second.get<double>("basic.spacing.x"));
- m_Controls->m_SpacingY->setValue(v1.second.get<double>("basic.spacing.y"));
- m_Controls->m_SpacingZ->setValue(v1.second.get<double>("basic.spacing.z"));
- m_Controls->m_NumGradientsBox->setValue(v1.second.get<int>("basic.numgradients"));
- m_Controls->m_BvalueBox->setValue(v1.second.get<int>("basic.bvalue"));
-*/
- }
-
-}
-
-
-int FiberFoxProcessing(int argc, char* argv[])
-{
- ctkCommandLineParser parser;
- parser.setArgumentPrefix("--", "-");
- parser.addArgument("in", "i", ctkCommandLineParser::String, "input file", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::String, "output file", us::Any(), false);
- parser.addArgument("fiberbundle", "f", ctkCommandLineParser::String, "defined fiber bundle for signal generation", us::Any(), false);
- parser.addArgument("loadparameters", "l", ctkCommandLineParser::String, "load fiber fox signal parameter file", us::Any(), false);
-
-
- map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
- if (parsedArgs.size()==0)
- return EXIT_FAILURE;
-
- // mandatory arguments
- string inName = us::any_cast<string>(parsedArgs["in"]);
- string outName = us::any_cast<string>(parsedArgs["out"]);
- string fbName = us::any_cast<string>(parsedArgs["fiberbundle"]);
- string paramName = us::any_cast<string>(parsedArgs["loadparameters"]);
-
- {
- RegisterFiberTrackingObjectFactory();
-
- ImageParameters m_ImageGenParameters;
- mitk::Image::Pointer m_maskImage = 0;
- mitk::Image::Pointer m_fImage = 0;
-
- MITK_INFO << "Loading " << inName;
- const std::string s1="", s2="";
- std::vector<BaseData::Pointer> infile = BaseDataIO::LoadBaseDataFromFile( inName, s1, s2, false );
- mitk::BaseData::Pointer baseData = infile.at(0);
-
- MITK_INFO << "Loading " << fbName;
- std::vector<BaseData::Pointer> infile2 = BaseDataIO::LoadBaseDataFromFile( fbName, s1, s2, false );
- mitk::BaseData::Pointer baseData2 = infile2.at(0);
-
- DiffusionImage<short>::Pointer dwi;
- FiberBundleX::Pointer fbi;
-
- if ( dynamic_cast<DiffusionImage<short>*>(baseData.GetPointer()) )
- dwi = dynamic_cast<DiffusionImage<short>*>(baseData.GetPointer());
- else
- MITK_ERROR << "LOADING DWI FAILD: " << inName;
-
- if ( dynamic_cast<FiberBundleX*>(baseData2.GetPointer()) )
- fbi = dynamic_cast<FiberBundleX*>(baseData2.GetPointer());
- else
- MITK_ERROR << "LOADING FBI FAILD: " << fbName;
-
-
-
- m_ImageGenParameters.imageRegion = dwi->GetVectorImage()->GetLargestPossibleRegion();
- m_ImageGenParameters.imageSpacing = dwi->GetVectorImage()->GetSpacing();
- m_ImageGenParameters.imageOrigin = dwi->GetVectorImage()->GetOrigin();
- m_ImageGenParameters.imageDirection = dwi->GetVectorImage()->GetDirection();
- m_ImageGenParameters.b_value = dwi->GetB_Value();
- mitk::DiffusionImage<short>::GradientDirectionContainerType::Pointer dirs = dwi->GetDirections();
-
- m_ImageGenParameters.numGradients = 0;
- for (int i=0; i<dirs->Size(); i++)
- {
- DiffusionSignalModel<double>::GradientType g;
- g[0] = dirs->at(i)[0];
- g[1] = dirs->at(i)[1];
- g[2] = dirs->at(i)[2];
- m_ImageGenParameters.gradientDirections.push_back(g);
- if (dirs->at(i).magnitude()>0.0001)
- m_ImageGenParameters.numGradients++;
- }
-
- mitk::StickModel<double> m_StickModel1;
- mitk::StickModel<double> m_StickModel2;
- mitk::TensorModel<double> m_ZeppelinModel1;
- mitk::TensorModel<double> m_ZeppelinModel2;
- mitk::TensorModel<double> m_TensorModel1;
- mitk::TensorModel<double> m_TensorModel2;
-
- // extra axonal compartment models
- mitk::BallModel<double> m_BallModel1;
- mitk::BallModel<double> m_BallModel2;
- mitk::AstroStickModel<double> m_AstrosticksModel1;
- mitk::AstroStickModel<double> m_AstrosticksModel2;
- mitk::DotModel<double> m_DotModel1;
- mitk::DotModel<double> m_DotModel2;
-
- LoadParameters(paramName,m_ImageGenParameters,NULL, NULL,
- &m_StickModel1,
- &m_StickModel2,
- &m_ZeppelinModel1,
- &m_ZeppelinModel2,
- &m_TensorModel1,
- &m_TensorModel2,
- &m_BallModel1,
- &m_BallModel2,
- &m_AstrosticksModel1,
- &m_AstrosticksModel2,
- &m_DotModel1,
- &m_DotModel2);
-
- MITK_INFO << "Parameter loaded";
-
- itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
-
- tractsToDwiFilter->SetSimulateEddyCurrents(m_ImageGenParameters.doSimulateEddyCurrents);
- tractsToDwiFilter->SetEddyGradientStrength(m_ImageGenParameters.eddyStrength);
- //tractsToDwiFilter->SetUpsampling(m_ImageGenParameters.upsampling);
- tractsToDwiFilter->SetSimulateRelaxation(m_ImageGenParameters.doSimulateRelaxation);
- tractsToDwiFilter->SetImageRegion(m_ImageGenParameters.imageRegion);
- tractsToDwiFilter->SetSpacing(m_ImageGenParameters.imageSpacing);
- tractsToDwiFilter->SetOrigin(m_ImageGenParameters.imageOrigin);
- tractsToDwiFilter->SetDirectionMatrix(m_ImageGenParameters.imageDirection);
- tractsToDwiFilter->SetFiberBundle(fbi);
- tractsToDwiFilter->SetFiberModels(m_ImageGenParameters.fiberModelList);
- tractsToDwiFilter->SetNonFiberModels(m_ImageGenParameters.nonFiberModelList);
- tractsToDwiFilter->SetNoiseModel(&m_ImageGenParameters.ricianNoiseModel);
- tractsToDwiFilter->SetkOffset(m_ImageGenParameters.kspaceLineOffset);
- tractsToDwiFilter->SettLine(m_ImageGenParameters.tLine);
- tractsToDwiFilter->SettInhom(m_ImageGenParameters.tInhom);
- tractsToDwiFilter->SetTE(m_ImageGenParameters.tEcho);
- tractsToDwiFilter->SetNumberOfRepetitions(m_ImageGenParameters.repetitions);
- tractsToDwiFilter->SetEnforcePureFiberVoxels(m_ImageGenParameters.doDisablePartialVolume);
- tractsToDwiFilter->SetInterpolationShrink(m_ImageGenParameters.interpolationShrink);
- tractsToDwiFilter->SetFiberRadius(m_ImageGenParameters.axonRadius);
- tractsToDwiFilter->SetSignalScale(m_ImageGenParameters.signalScale);
- if (m_ImageGenParameters.interpolationShrink>0)
- tractsToDwiFilter->SetUseInterpolation(true);
- tractsToDwiFilter->SetTissueMask(m_ImageGenParameters.tissueMaskImage);
- tractsToDwiFilter->SetFrequencyMap(m_ImageGenParameters.frequencyMap);
- tractsToDwiFilter->SetSpikeAmplitude(m_ImageGenParameters.spikeAmplitude);
- tractsToDwiFilter->SetSpikes(m_ImageGenParameters.spikes);
- tractsToDwiFilter->Update();
-
- mitk::DiffusionImage<short>::Pointer image = mitk::DiffusionImage<short>::New();
- image->SetVectorImage( tractsToDwiFilter->GetOutput() );
- image->SetB_Value(dwi->GetB_Value());
- image->SetDirections(dwi->GetDirections());
- image->InitializeFromVectorImage();
-
- MITK_INFO << "Writing " << outName;
- NrrdDiffusionImageWriter<short>::Pointer writer = NrrdDiffusionImageWriter<short>::New();
- writer->SetFileName(outName);
- writer->SetInput(image);
- writer->Update();
-
-
- }
- MITK_INFO << "DONE";
- return EXIT_SUCCESS;
-}
-RegisterDiffusionMiniApp(FiberFoxProcessing);
diff --git a/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp b/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp
new file mode 100755
index 0000000000..8dfba05cc5
--- /dev/null
+++ b/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp
@@ -0,0 +1,84 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "MiniAppManager.h"
+#include <mitkImageCast.h>
+#include <mitkDiffusionImage.h>
+#include <mitkBaseDataIOFactory.h>
+#include <mitkIOUtil.h>
+#include <mitkNrrdDiffusionImageWriter.h>
+#include <mitkFiberBundleX.h>
+#include <mitkFiberfoxParameters.h>
+#include "ctkCommandLineParser.h"
+
+#include <itkAddArtifactsToDwiImageFilter.h>
+#include <itkTractsToDWIImageFilter.h>
+
+#include "boost/property_tree/ptree.hpp"
+#include "boost/property_tree/xml_parser.hpp"
+#include "boost/foreach.hpp"
+
+/** TODO: Proritype signal komplett speichern oder bild mit speichern. */
+/** TODO: Tarball aus images und parametern? */
+/** TODO: Artefakte auf bild in miniapp */
+
+namespace mitk
+{
+int Fiberfox(int argc, char* argv[])
+{
+ ctkCommandLineParser parser;
+ parser.setArgumentPrefix("--", "-");
+ parser.addArgument("out", "o", ctkCommandLineParser::OutputFile, "Output root:", "output root", us::Any(), false);
+ parser.addArgument("parameters", "p", ctkCommandLineParser::InputFile, "Parameter file:", "fiberfox parameter file", us::Any(), false);
+ parser.addArgument("fiberbundle", "f", ctkCommandLineParser::String, "Fiberbundle:", "", us::Any(), false);
+
+ map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
+ if (parsedArgs.size()==0)
+ return EXIT_FAILURE;
+
+ string outName = us::any_cast<string>(parsedArgs["out"]);
+ string paramName = us::any_cast<string>(parsedArgs["parameters"]);
+
+ string fibFile = "";
+ if (parsedArgs.count("fiberbundle"))
+ fibFile = us::any_cast<string>(parsedArgs["fiberbundle"]);
+
+ {
+ FiberfoxParameters<double> parameters;
+ parameters.LoadParameters(paramName);
+
+ mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
+
+ itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
+ tractsToDwiFilter->SetParameters(parameters);
+ tractsToDwiFilter->SetFiberBundle(inputTractogram);
+ tractsToDwiFilter->Update();
+
+ DiffusionImage<short>::Pointer image = DiffusionImage<short>::New();
+ image->SetVectorImage( tractsToDwiFilter->GetOutput() );
+ image->SetReferenceBValue( parameters.m_SignalGen.m_Bvalue );
+ image->SetDirections( parameters.m_SignalGen.GetGradientDirections() );
+ image->InitializeFromVectorImage();
+
+ NrrdDiffusionImageWriter<short>::Pointer writer = NrrdDiffusionImageWriter<short>::New();
+ writer->SetFileName(outName);
+ writer->SetInput(image);
+ writer->Update();
+ }
+ return EXIT_SUCCESS;
+}
+}
+RegisterDiffusionMiniApp(Fiberfox);
diff --git a/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp b/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp
index 2c961df8e8..204642190a 100644
--- a/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp
+++ b/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp
@@ -1,518 +1,518 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <MiniAppManager.h>
// std includes
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <map>
#include <utility>
// boost includes
#include <boost/algorithm/string.hpp>
// ITK includes
#include <itkImageFileWriter.h>
// CTK includes
#include "ctkCommandLineParser.h"
// MITK includes
#include <mitkBaseDataIOFactory.h>
#include <mitkConnectomicsStatisticsCalculator.h>
#include <mitkConnectomicsNetworkThresholder.h>
#include <itkConnectomicsNetworkToConnectivityMatrixImageFilter.h>
int NetworkStatistics(int argc, char* argv[])
{
ctkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
parser.addArgument("inputNetwork", "i", ctkCommandLineParser::InputFile, "Input network", "input connectomics network (.cnf)", us::Any(), false);
parser.addArgument("outputFile", "o", ctkCommandLineParser::OutputFile, "Output file", "name of output file", us::Any(), false);
parser.addArgument("noGlobalStatistics", "g", ctkCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics");
parser.addArgument("createConnectivityMatriximage", "I", ctkCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image");
parser.addArgument("binaryConnectivity", "b", ctkCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix");
parser.addArgument("rescaleConnectivity", "r", ctkCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix");
parser.addArgument("localStatistics", "L", ctkCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any());
parser.addArgument("regionList", "R", ctkCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any());
parser.addArgument("granularity", "gr", ctkCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider");
- parser.addArgument("startDensity", "d", ctkCommandLineParser::Bool, "Start Density", "Largest density for the range");
+ parser.addArgument("startDensity", "d", ctkCommandLineParser::Float, "Start Density", "Largest density for the range");
parser.addArgument("thresholdStepSize", "t", ctkCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds");
parser.setCategory("Connectomics");
parser.setTitle("Network Statistics");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
//default values
bool noGlobalStatistics( false );
bool binaryConnectivity( false );
bool rescaleConnectivity( false );
bool createConnectivityMatriximage( false );
unsigned int granularity( 1 );
double startDensity( 1.0 );
unsigned int thresholdStepSize( 3 );
// parse command line arguments
std::string networkName = us::any_cast<std::string>(parsedArgs["inputNetwork"]);
std::string outName = us::any_cast<std::string>(parsedArgs["outputFile"]);
ctkCommandLineParser::StringContainerType localLabels;
if(parsedArgs.count("localStatistics"))
{
localLabels = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["localStatistics"]);
}
ctkCommandLineParser::StringContainerType unparsedRegions;
std::map< std::string, std::vector<std::string> > parsedRegions;
std::map< std::string, std::vector<std::string> >::iterator parsedRegionsIterator;
if(parsedArgs.count("regionList"))
{
unparsedRegions = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["regionList"]);
for(unsigned int index(0); index < unparsedRegions.size(); index++ )
{
std::vector< std::string > tempRegionVector;
boost::split(tempRegionVector, unparsedRegions.at(index), boost::is_any_of(";"));
std::vector< std::string >::const_iterator begin = tempRegionVector.begin();
std::vector< std::string >::const_iterator last = tempRegionVector.begin() + tempRegionVector.size();
std::vector< std::string > insertRegionVector(begin + 1, last);
if( parsedRegions.count( tempRegionVector.at(0) ) == 0 )
{
parsedRegions.insert( std::pair< std::string, std::vector<std::string> >( tempRegionVector.at(0), insertRegionVector) );
}
else
{
MITK_ERROR << "Region already exists. Skipping second occurrence.";
}
}
}
if (parsedArgs.count("noGlobalStatistics"))
noGlobalStatistics = us::any_cast<bool>(parsedArgs["noGlobalStatistics"]);
if (parsedArgs.count("binaryConnectivity"))
binaryConnectivity = us::any_cast<bool>(parsedArgs["binaryConnectivity"]);
if (parsedArgs.count("rescaleConnectivity"))
rescaleConnectivity = us::any_cast<bool>(parsedArgs["rescaleConnectivity"]);
if (parsedArgs.count("createConnectivityMatriximage"))
createConnectivityMatriximage = us::any_cast<bool>(parsedArgs["createConnectivityMatriximage"]);
if (parsedArgs.count("granularity"))
granularity = us::any_cast<unsigned int>(parsedArgs["granularity"]);
if (parsedArgs.count("startDensity"))
- startDensity = us::any_cast<double>(parsedArgs["startDensity"]);
+ startDensity = us::any_cast<float>(parsedArgs["startDensity"]);
if (parsedArgs.count("thresholdStepSize"))
thresholdStepSize = us::any_cast<unsigned int>(parsedArgs["thresholdStepSize"]);
try
{
const std::string s1="", s2="";
// load network
std::vector<mitk::BaseData::Pointer> networkFile =
mitk::BaseDataIO::LoadBaseDataFromFile( networkName, s1, s2, false );
if( networkFile.empty() )
{
std::string errorMessage = "File at " + networkName + " could not be read. Aborting.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
mitk::BaseData* networkBaseData = networkFile.at(0);
mitk::ConnectomicsNetwork* network = dynamic_cast<mitk::ConnectomicsNetwork*>( networkBaseData );
if( !network )
{
std::string errorMessage = "Read file at " + networkName + " could not be recognized as network. Aborting.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
// streams
std::stringstream globalHeaderStream;
globalHeaderStream << "NumberOfVertices "
<< "NumberOfEdges "
<< "AverageDegree "
<< "ConnectionDensity "
<< "NumberOfConnectedComponents "
<< "AverageComponentSize "
<< "LargestComponentSize "
<< "RatioOfNodesInLargestComponent "
<< "HopPlotExponent "
<< "EffectiveHopDiameter "
<< "AverageClusteringCoefficientsC "
<< "AverageClusteringCoefficientsD "
<< "AverageClusteringCoefficientsE "
<< "AverageVertexBetweennessCentrality "
<< "AverageEdgeBetweennessCentrality "
<< "NumberOfIsolatedPoints "
<< "RatioOfIsolatedPoints "
<< "NumberOfEndPoints "
<< "RatioOfEndPoints "
<< "Diameter "
<< "Diameter90 "
<< "Radius "
<< "Radius90 "
<< "AverageEccentricity "
<< "AverageEccentricity90 "
<< "AveragePathLength "
<< "NumberOfCentralPoints "
<< "RatioOfCentralPoints "
<< "SpectralRadius "
<< "SecondLargestEigenValue "
<< "AdjacencyTrace "
<< "AdjacencyEnergy "
<< "LaplacianTrace "
<< "LaplacianEnergy "
<< "LaplacianSpectralGap "
<< "NormalizedLaplacianTrace "
<< "NormalizedLaplacianEnergy "
<< "NormalizedLaplacianNumberOf2s "
<< "NormalizedLaplacianNumberOf1s "
<< "NormalizedLaplacianNumberOf0s "
<< "NormalizedLaplacianLowerSlope "
<< "NormalizedLaplacianUpperSlope "
<< "SmallWorldness"
<< std::endl;
std::stringstream localHeaderStream;
std::stringstream regionalHeaderStream;
std::stringstream globalDataStream;
std::stringstream localDataStream;
std::stringstream regionalDataStream;
std::string globalOutName = outName + "_global.txt";
std::string localOutName = outName + "_local.txt";
std::string regionalOutName = outName + "_regional.txt";
bool firstRun( true );
// iterate over all three possible methods
for(unsigned int method( 0 ); method < 3; method++)
{
// 0 - Random removal threshold
// 1 - Largest density below threshold
// 2 - Threshold based
// iterate over possible targets
for( unsigned int step( 0 ); step < granularity; step++ )
{
double targetValue( 0.0 );
bool newStep( true );
switch ( method )
{
case mitk::ConnectomicsNetworkThresholder::RandomRemovalOfWeakest :
case mitk::ConnectomicsNetworkThresholder::LargestLowerThanDensity :
targetValue = startDensity * (1 - static_cast<double>( step ) / ( granularity + 0.5 ) );
break;
case mitk::ConnectomicsNetworkThresholder::ThresholdBased :
targetValue = static_cast<double>( thresholdStepSize * step );
break;
default:
MITK_ERROR << "Invalid thresholding method called, aborting.";
return EXIT_FAILURE;
break;
}
mitk::ConnectomicsNetworkThresholder::Pointer thresholder = mitk::ConnectomicsNetworkThresholder::New();
thresholder->SetNetwork( network );
thresholder->SetTargetThreshold( targetValue );
thresholder->SetTargetDensity( targetValue );
thresholder->SetThresholdingScheme( static_cast<mitk::ConnectomicsNetworkThresholder::ThresholdingSchemes>(method) );
mitk::ConnectomicsNetwork::Pointer thresholdedNetwork = thresholder->GetThresholdedNetwork();
mitk::ConnectomicsStatisticsCalculator::Pointer statisticsCalculator = mitk::ConnectomicsStatisticsCalculator::New();
statisticsCalculator->SetNetwork( thresholdedNetwork );
statisticsCalculator->Update();
// global statistics
if( !noGlobalStatistics )
{
globalDataStream << statisticsCalculator->GetNumberOfVertices() << " "
<< statisticsCalculator->GetNumberOfEdges() << " "
<< statisticsCalculator->GetAverageDegree() << " "
<< statisticsCalculator->GetConnectionDensity() << " "
<< statisticsCalculator->GetNumberOfConnectedComponents() << " "
<< statisticsCalculator->GetAverageComponentSize() << " "
<< statisticsCalculator->GetLargestComponentSize() << " "
<< statisticsCalculator->GetRatioOfNodesInLargestComponent() << " "
<< statisticsCalculator->GetHopPlotExponent() << " "
<< statisticsCalculator->GetEffectiveHopDiameter() << " "
<< statisticsCalculator->GetAverageClusteringCoefficientsC() << " "
<< statisticsCalculator->GetAverageClusteringCoefficientsD() << " "
<< statisticsCalculator->GetAverageClusteringCoefficientsE() << " "
<< statisticsCalculator->GetAverageVertexBetweennessCentrality() << " "
<< statisticsCalculator->GetAverageEdgeBetweennessCentrality() << " "
<< statisticsCalculator->GetNumberOfIsolatedPoints() << " "
<< statisticsCalculator->GetRatioOfIsolatedPoints() << " "
<< statisticsCalculator->GetNumberOfEndPoints() << " "
<< statisticsCalculator->GetRatioOfEndPoints() << " "
<< statisticsCalculator->GetDiameter() << " "
<< statisticsCalculator->GetDiameter90() << " "
<< statisticsCalculator->GetRadius() << " "
<< statisticsCalculator->GetRadius90() << " "
<< statisticsCalculator->GetAverageEccentricity() << " "
<< statisticsCalculator->GetAverageEccentricity90() << " "
<< statisticsCalculator->GetAveragePathLength() << " "
<< statisticsCalculator->GetNumberOfCentralPoints() << " "
<< statisticsCalculator->GetRatioOfCentralPoints() << " "
<< statisticsCalculator->GetSpectralRadius() << " "
<< statisticsCalculator->GetSecondLargestEigenValue() << " "
<< statisticsCalculator->GetAdjacencyTrace() << " "
<< statisticsCalculator->GetAdjacencyEnergy() << " "
<< statisticsCalculator->GetLaplacianTrace() << " "
<< statisticsCalculator->GetLaplacianEnergy() << " "
<< statisticsCalculator->GetLaplacianSpectralGap() << " "
<< statisticsCalculator->GetNormalizedLaplacianTrace() << " "
<< statisticsCalculator->GetNormalizedLaplacianEnergy() << " "
<< statisticsCalculator->GetNormalizedLaplacianNumberOf2s() << " "
<< statisticsCalculator->GetNormalizedLaplacianNumberOf1s() << " "
<< statisticsCalculator->GetNormalizedLaplacianNumberOf0s() << " "
<< statisticsCalculator->GetNormalizedLaplacianLowerSlope() << " "
<< statisticsCalculator->GetNormalizedLaplacianUpperSlope() << " "
<< statisticsCalculator->GetSmallWorldness()
<< std::endl;
} // end global statistics
//create connectivity matrix png
if( createConnectivityMatriximage )
{
std::string connectivity_png_postfix = "_connectivity";
if( binaryConnectivity )
{
connectivity_png_postfix += "_binary";
}
else if( rescaleConnectivity )
{
connectivity_png_postfix += "_rescaled";
}
connectivity_png_postfix += ".png";
/* File format
* A png file depicting the binary connectivity matrix
*/
itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::Pointer filter = itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::New();
filter->SetInputNetwork( network );
filter->SetBinaryConnectivity( binaryConnectivity );
filter->SetRescaleConnectivity( rescaleConnectivity );
filter->Update();
typedef itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::OutputImageType connectivityMatrixImageType;
itk::ImageFileWriter< connectivityMatrixImageType >::Pointer connectivityWriter = itk::ImageFileWriter< connectivityMatrixImageType >::New();
connectivityWriter->SetInput( filter->GetOutput() );
connectivityWriter->SetFileName( outName + connectivity_png_postfix);
connectivityWriter->Update();
MITK_INFO << "Connectivity matrix image written.";
} // end create connectivity matrix png
/*
* We can either calculate local indices for specific nodes, or specific regions
*/
// Create LabelToIndex translation
std::map< std::string, int > labelToIdMap;
std::vector< mitk::ConnectomicsNetwork::NetworkNode > nodeVector = thresholdedNetwork->GetVectorOfAllNodes();
for(int loop(0); loop < nodeVector.size(); loop++)
{
labelToIdMap.insert( std::pair< std::string, int>(nodeVector.at(loop).label, nodeVector.at(loop).id) );
}
std::vector< int > degreeVector = thresholdedNetwork->GetDegreeOfNodes();
std::vector< double > ccVector = thresholdedNetwork->GetLocalClusteringCoefficients( );
std::vector< double > bcVector = thresholdedNetwork->GetNodeBetweennessVector( );
// calculate local indices
{
// only add to header for the first step of the first method
if( firstRun )
{
localHeaderStream << "Th_method " << "Th_target " << "density";
}
double density = statisticsCalculator->GetConnectionDensity();
localDataStream << "\n"
<< method << " "
<< targetValue << " "
<< density;
for(unsigned int loop(0); loop < localLabels.size(); loop++ )
{
if( network->CheckForLabel(localLabels.at( loop )) )
{
if( firstRun )
{
localHeaderStream << " "
<< localLabels.at( loop ) << "_Degree "
<< localLabels.at( loop ) << "_CC "
<< localLabels.at( loop ) << "_BC";
}
localDataStream << " " << degreeVector.at( labelToIdMap.find( localLabels.at( loop ) )->second )
<< " " << ccVector.at( labelToIdMap.find( localLabels.at( loop ) )->second )
<< " " << bcVector.at( labelToIdMap.find( localLabels.at( loop ) )->second );
}
else
{
MITK_ERROR << "Illegal label. Label: \"" << localLabels.at( loop ) << "\" not found.";
}
}
}
// calculate regional indices
{
// only add to header for the first step of the first method
if( firstRun )
{
regionalHeaderStream << "Th_method " << "Th_target " << "density";
}
double density = statisticsCalculator->GetConnectionDensity();
regionalDataStream << "\n"
<< method << " "
<< targetValue << " "
<< density;
for( parsedRegionsIterator = parsedRegions.begin(); parsedRegionsIterator != parsedRegions.end(); parsedRegionsIterator++ )
{
std::vector<std::string> regionLabelsVector = parsedRegionsIterator->second;
std::string regionName = parsedRegionsIterator->first;
double sumDegree( 0 );
double sumCC( 0 );
double sumBC( 0 );
double count( 0 );
for( int loop(0); loop < regionLabelsVector.size(); loop++ )
{
if( thresholdedNetwork->CheckForLabel(regionLabelsVector.at( loop )) )
{
sumDegree = sumDegree + degreeVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
sumCC = sumCC + ccVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
sumBC = sumBC + bcVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
count = count + 1;
}
else
{
MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at( loop ) << "\" not found.";
}
}
// only add to header for the first step of the first method
if( firstRun )
{
regionalHeaderStream << " " << regionName << "_LocalAverageDegree "
<< regionName << "_LocalAverageCC "
<< regionName << "_LocalAverageBC "
<< regionName << "_NumberOfNodes";
}
regionalDataStream << " " << sumDegree / count
<< " " << sumCC / count
<< " " << sumBC / count
<< " " << count;
}
}
firstRun = false;
}
}// end calculate local averages
if( !noGlobalStatistics )
{
MITK_INFO << "Writing to " << globalOutName;
std::ofstream glocalOutFile( globalOutName.c_str(), ios::out );
if( ! glocalOutFile.is_open() )
{
std::string errorMessage = "Could not open " + globalOutName + " for writing.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
glocalOutFile << globalHeaderStream.str() << globalDataStream.str();
glocalOutFile.close();
}
if( localLabels.size() > 0 )
{
MITK_INFO << "Writing to " << localOutName;
std::ofstream localOutFile( localOutName.c_str(), ios::out );
if( ! localOutFile.is_open() )
{
std::string errorMessage = "Could not open " + localOutName + " for writing.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
localOutFile << localHeaderStream.str() << localDataStream.str();
localOutFile.close();
}
if( parsedRegions.size() > 0 )
{
MITK_INFO << "Writing to " << regionalOutName;
std::ofstream regionalOutFile( regionalOutName.c_str(), ios::out );
if( ! regionalOutFile.is_open() )
{
std::string errorMessage = "Could not open " + regionalOutName + " for writing.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
regionalOutFile << regionalHeaderStream.str() << regionalDataStream.str();
regionalOutFile.close();
}
return EXIT_SUCCESS;
}
catch (itk::ExceptionObject e)
{
MITK_INFO << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
MITK_INFO << e.what();
return EXIT_FAILURE;
}
catch (...)
{
MITK_INFO << "ERROR!?!";
return EXIT_FAILURE;
}
MITK_INFO << "DONE";
return EXIT_SUCCESS;
}
RegisterDiffusionMiniApp(NetworkStatistics);
diff --git a/Modules/DiffusionImaging/MiniApps/files.cmake b/Modules/DiffusionImaging/MiniApps/files.cmake
index 97544eb067..98428da34c 100644
--- a/Modules/DiffusionImaging/MiniApps/files.cmake
+++ b/Modules/DiffusionImaging/MiniApps/files.cmake
@@ -1,31 +1,31 @@
set(CPP_FILES
mitkDiffusionMiniApps.cpp
MiniAppManager.cpp
BatchedFolderRegistration.cpp
DicomFolderDump.cpp
FileFormatConverter.cpp
TensorReconstruction.cpp
TensorDerivedMapsExtraction.cpp
QballReconstruction.cpp
DiffusionIndices.cpp
ExtractImageStatistics.cpp
CopyGeometry.cpp
GibbsTracking.cpp
StreamlineTracking.cpp
FiberProcessing.cpp
LocalDirectionalFiberPlausibility.cpp
#TractogramAngularError.cpp
FiberDirectionExtraction.cpp
ImageResampler.cpp
PeakExtraction.cpp
PeaksAngularError.cpp
MultishellMethods.cpp
- #FiberFoxProcessing.cpp
+ Fiberfox.cpp
ExportShImage.cpp
NetworkCreation.cpp
NetworkStatistics.cpp
DwiDenoising.cpp
FiberExtraction.cpp
FiberJoin.cpp
)
diff --git a/Modules/Ext/Algorithms/mitkAltInstantiateAccessFunctions.h b/Modules/Ext/Algorithms/mitkAltInstantiateAccessFunctions.h
deleted file mode 100644
index c7cedfbc16..0000000000
--- a/Modules/Ext/Algorithms/mitkAltInstantiateAccessFunctions.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKALTINSTANTIATEACCESSFUNCTIONS_H_HEADER_INCLUDED
-#define MITKALTINSTANTIATEACCESSFUNCTIONS_H_HEADER_INCLUDED
-
-#include <itkCastImageFilter.h>
-#include <mitkImageToItk.h>
-
-#ifndef DOXYGEN_SKIP
-//--------------------------------- instantiation functions ------------------------------
-//##Documentation
-//## @brief Instantiate access function without additional parammeters
-//## for all datatypes and dimensions
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunction_1
-//## \sa AltInstantiateAccessFunction_2
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunction(itkImgFunc) \
- AltInstantiateAccessFunctionForFixedDimension(itkImgFunc, 2) \
- AltInstantiateAccessFunctionForFixedDimension(itkImgFunc, 3)
-
-//##Documentation
-//## @brief Instantiate access function with one additional parammeter
-//## for all datatypes and dimensions
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunction
-//## \sa AltInstantiateAccessFunction_2
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunction_1(itkImgFunc, param1Type) \
- AltInstantiateAccessFunctionForFixedDimension_1(itkImgFunc, 2, param1Type) \
- AltInstantiateAccessFunctionForFixedDimension_1(itkImgFunc, 3, param1Type)
-
-//##Documentation
-//## @brief Instantiate access function with two additional parammeters
-//## for all datatypes and dimensions
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunction
-//## \sa AltInstantiateAccessFunction_1
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunction_2(itkImgFunc, param1Type, param2Type) \
- AltInstantiateAccessFunctionForFixedDimension_2(itkImgFunc, 2, param1Type, param2Type) \
- AltInstantiateAccessFunctionForFixedDimension_2(itkImgFunc, 3, param1Type, param2Type)
-
-//##Documentation
-//## @brief Instantiate access function without additional parammeters
-//## for all datatypes, but fixed dimension
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunctionForFixedDimension_1
-//## \sa AltInstantiateAccessFunctionForFixedDimension_2
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunctionForFixedDimension(itkImgFunc, dimension) \
-template void itkImgFunc(itk::Image<double, dimension>*); \
-template void itkImgFunc(itk::Image<float, dimension>*); \
-template void itkImgFunc(itk::Image<int, dimension>*); \
-template void itkImgFunc(itk::Image<unsigned int, dimension>*); \
-template void itkImgFunc(itk::Image<short, dimension>*); \
-template void itkImgFunc(itk::Image<unsigned short, dimension>*); \
-template void itkImgFunc(itk::Image<char, dimension>*); \
-template void itkImgFunc(itk::Image<unsigned char, dimension>*);
-
-//##Documentation
-//## @brief Instantiate access function with one additional parammeter
-//## for all datatypes, but fixed dimension
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunctionForFixedDimension
-//## \sa AltInstantiateAccessFunctionForFixedDimension_2
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunctionForFixedDimension_1(itkImgFunc, dimension, param1Type)\
-template void itkImgFunc(itk::Image<double, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<float, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<int, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<unsigned int, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<short, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<unsigned short, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<char, dimension>*, param1Type); \
-template void itkImgFunc(itk::Image<unsigned char, dimension>*, param1Type);
-
-//##Documentation
-//## @brief Instantiate access function with two additional parammeters
-//## for all datatypes, but fixed dimension
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunctionForFixedDimension
-//## \sa AltInstantiateAccessFunctionForFixedDimension_1
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunctionForFixedDimension_2(itkImgFunc, dimension, param1Type, param2Type)\
-template void itkImgFunc(itk::Image<double, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<float, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<int, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<unsigned int, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<short, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<unsigned short, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<char, dimension>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<unsigned char, dimension>*, param1Type, param2Type);
-
-//##Documentation
-//## @brief Instantiate access function without additional parammeters
-//## for a fixed datatype, but all dimensions
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunctionForFixedPixelType_1
-//## \sa AltInstantiateAccessFunctionForFixedPixelType_2
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunctionForFixedPixelType(itkImgFunc, pixelType) \
-template void itkImgFunc(itk::Image<pixelType, 2>*); \
-template void itkImgFunc(itk::Image<pixelType, 3>*);
-
-//##Documentation
-//## @brief Instantiate access function with one additional parammeter
-//## for a fixed datatype, but all dimensions
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunctionForFixedPixelType
-//## \sa AltInstantiateAccessFunctionForFixedPixelType_2
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunctionForFixedPixelType_1(itkImgFunc, pixelType, param1Type) \
-template void itkImgFunc(itk::Image<pixelType, 2>*, param1Type); \
-template void itkImgFunc(itk::Image<pixelType, 3>*, param1Type);
-
-//##Documentation
-//## @brief Instantiate access function with two additional parammeters
-//## for a fixed datatype, but all dimensions
-//##
-//## Use this macro once after the definition of your access function.
-//## Some compilers have memory problems without the explicit instantiation.
-//## You may need to move the access function to a separate file.
-//## \sa AltInstantiateAccessFunctionForFixedPixelType
-//## \sa AltInstantiateAccessFunctionForFixedPixelType_1
-//## @ingroup Adaptor
-#define AltInstantiateAccessFunctionForFixedPixelType_2(itkImgFunc, pixelType, param1Type, param2Type)\
-template void itkImgFunc(itk::Image<pixelType, 2>*, param1Type, param2Type); \
-template void itkImgFunc(itk::Image<pixelType, 3>*, param1Type, param2Type);
-
-#endif DOXYGEN_SKIP
-
-#endif // of MITKALTINSTANTIATEACCESSFUNCTIONS_H_HEADER_INCLUDED
diff --git a/Modules/Ext/Algorithms/mitkAngleCorrectByPointFilter.cpp b/Modules/Ext/Algorithms/mitkAngleCorrectByPointFilter.cpp
deleted file mode 100644
index 01bb587e8d..0000000000
--- a/Modules/Ext/Algorithms/mitkAngleCorrectByPointFilter.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkAngleCorrectByPointFilter.h"
-#include "mitkIpPic.h"
-#include "mitkImageTimeSelector.h"
-#include "mitkProperties.h"
-#include "mitkImageReadAccessor.h"
-#include <mitkProportionalTimeGeometry.h>
-
-mitk::AngleCorrectByPointFilter::AngleCorrectByPointFilter() : m_PreferTransducerPositionFromProperty(true)
-{
- m_Center.Fill(0);
- m_TransducerPosition.Fill(0);
-}
-
-mitk::AngleCorrectByPointFilter::~AngleCorrectByPointFilter()
-{
-}
-
-void mitk::AngleCorrectByPointFilter::GenerateOutputInformation()
-{
- mitk::Image::ConstPointer input = this->GetInput();
- mitk::Image::Pointer output = this->GetOutput();
-
- if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
- return;
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-
- unsigned int i;
- unsigned int *tmpDimensions = new unsigned int[input->GetDimension()];
-
- for(i=0;i<input->GetDimension();++i)
- tmpDimensions[i]=input->GetDimension(i);
-
- //@todo maybe we should shift the following somehow in ImageToImageFilter
- mitk::PixelType scalarPType = MakeScalarPixelType<ScalarType>();
- output->Initialize(scalarPType,
- input->GetDimension(),
- tmpDimensions,
- input->GetNumberOfChannels());
-
- output->GetSlicedGeometry()->SetSpacing(input->GetSlicedGeometry()->GetSpacing());
-
- //output->GetSlicedGeometry()->SetPlaneGeometry(mitk::Image::BuildStandardPlanePlaneGeometry(output->GetSlicedGeometry(), tmpDimensions).GetPointer(), 0);
- //output->GetSlicedGeometry()->SetEvenlySpaced();
- //set the timebounds - after SetPlaneGeometry, so that the already created PlaneGeometry will also receive this timebounds.
- //@fixme!!! will not work for not evenly timed data!
-
- ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
- timeGeometry->Initialize(output->GetSlicedGeometry(), output->GetTimeGeometry()->CountTimeSteps());
- timeGeometry->SetFirstTimePoint(output->GetTimeGeometry()->GetMinimumTimePoint());
- TimePointType stepDuration = input->GetTimeGeometry()->GetMaximumTimePoint(0) -input->GetTimeGeometry()->GetMinimumTimePoint(0);
- timeGeometry->SetStepDuration(stepDuration);
- output->SetTimeGeometry(timeGeometry);
-
- output->SetPropertyList(input->GetPropertyList()->Clone());
-
-
- delete [] tmpDimensions;
-
- m_TimeOfHeaderInitialization.Modified();
-}
-
-void mitk::AngleCorrectByPointFilter::GenerateData()
-{
- mitk::Image::ConstPointer input = this->GetInput();
- mitk::Image::Pointer output = this->GetOutput();
-
-
- if(m_PreferTransducerPositionFromProperty)
- {
- mitk::Point3iProperty::Pointer pointProp;
- pointProp = dynamic_cast<mitk::Point3iProperty*>(input->GetProperty("ORIGIN").GetPointer());
- if (pointProp.IsNotNull() )
- {
- const itk::Point<int, 3> & p = pointProp->GetValue();
- m_TransducerPosition[0] = p[0];
- m_TransducerPosition[1] = p[1];
- m_TransducerPosition[2] = p[2];
- }
- }
-
- itkDebugMacro( << "compute angle corrected image .... " );
- itkDebugMacro( << " Center[0]=" << m_Center[0] << " Center[1]=" << m_Center[1] << " Center[2]=" << m_Center[2] );
- itkDebugMacro( << " TransducerPosition[0]=" << m_TransducerPosition[0] << " TransducerPosition[1]=" << m_TransducerPosition[1] << " TransducerPosition[2]=" << m_TransducerPosition[2] );
-
- const Vector3D & spacing = input->GetSlicedGeometry()->GetSpacing();
- // MITK_INFO << " in: xres=" << spacing[0] << " yres=" << spacing[1] << " zres=" << spacing[2] << std::endl;
-
- if((spacing[0]!=spacing[1]) || (spacing[0]!=spacing[2]))
- {
- itkExceptionMacro("filter does not work for uninsotropic data: spacing: ("<< spacing[0] << "," << spacing[1] << "," << spacing[2] << ")");
- }
-
- Vector3D p;
- Vector3D tx_direction;
- Vector3D tx_position = m_TransducerPosition.GetVectorFromOrigin();
- Vector3D center = m_Center.GetVectorFromOrigin();
- Vector3D assumed_direction;
- ScalarType &x=p[0];
- ScalarType &y=p[1];
- ScalarType &z=p[2];
- Vector3D down;
- FillVector3D(down,0.0,0.0,-1.0);
-
- int xDim = input->GetDimension(0);
- int yDim = input->GetDimension(1);
- int zDim = input->GetDimension(2);
-
- mitkIpPicDescriptor* pic_out;
- pic_out = mitkIpPicNew();
- pic_out->dim = 3;
- pic_out->bpe = output->GetPixelType().GetBpe();
- //pic_out->type = output->GetPixelType().GetType();
- pic_out->n[0] = xDim;
- pic_out->n[1] = yDim;
- pic_out->n[2] = zDim;
- pic_out->data = malloc(_mitkIpPicSize(pic_out));
-
- //go!
- mitk::ImageTimeSelector::Pointer timeSelector=mitk::ImageTimeSelector::New();
- timeSelector->SetInput(input);
-
- int nstart, nmax;
- int tstart, tmax;
-
- tstart=output->GetRequestedRegion().GetIndex(3);
- nstart=output->GetRequestedRegion().GetIndex(4);
-
- tmax=tstart+output->GetRequestedRegion().GetSize(3);
- nmax=nstart+output->GetRequestedRegion().GetSize(4);
-
- int n,t;
- for(n=nstart;n<nmax;++n)//output->GetNumberOfChannels();++n)
- {
- timeSelector->SetChannelNr(n);
-
- for(t=tstart;t<tmax;++t)
- {
- timeSelector->SetTimeNr(t);
-
- timeSelector->Update();
-
- typedef unsigned char InputImagePixelType;
- typedef ScalarType OutputImagePixelType;
-
- if(input->GetPixelType().GetPixelType() != itk::ImageIOBase::SCALAR ||
- input->GetPixelType().GetComponentType()!= MapPixelComponentType<InputImagePixelType>::value)
- {
- itkExceptionMacro("only implemented for " << typeid(PixelType).name() );
- }
-
- InputImagePixelType *in;
- OutputImagePixelType *out;
-
- mitk::ImageReadAccessor tsOutAcc(timeSelector->GetOutput());
- in = (InputImagePixelType *)tsOutAcc.GetData();
- out = (OutputImagePixelType*)pic_out->data;
-
- for (z=0 ; z<zDim ; ++z)
- {
- for (y=0; y<yDim; ++y)
- {
- for (x=0; x<xDim; ++x, ++in, ++out)
- {
- tx_direction = tx_position-p;
- tx_direction.Normalize();
-
- //are we within the acquisition cone?
-// if(-tx_direction*down>vnl_math::pi_over_4)
- {
- assumed_direction = center-p;
- assumed_direction.Normalize();
- ScalarType cos_factor = tx_direction*assumed_direction;
-
- if(fabs(cos_factor)>eps)
- *out=((ScalarType)(*in)-128.0)/cos_factor;
- else
- *out=((ScalarType)(*in)-128.0)/eps;
- }
- //else
- // *out=0;
- }
- }
- }
- //output->SetPicVolume(pic_out, t, n);
- }
- }
-}
-
-void mitk::AngleCorrectByPointFilter::GenerateInputRequestedRegion()
-{
- Superclass::GenerateInputRequestedRegion();
-
- mitk::ImageToImageFilter::InputImagePointer input =
- const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() );
- mitk::Image::Pointer output = this->GetOutput();
-
- Image::RegionType requestedRegion;
- requestedRegion = output->GetRequestedRegion();
- requestedRegion.SetIndex(0, 0);
- requestedRegion.SetIndex(1, 0);
- requestedRegion.SetIndex(2, 0);
- //requestedRegion.SetIndex(3, 0);
- //requestedRegion.SetIndex(4, 0);
- requestedRegion.SetSize(0, input->GetDimension(0));
- requestedRegion.SetSize(1, input->GetDimension(1));
- requestedRegion.SetSize(2, input->GetDimension(2));
- //requestedRegion.SetSize(3, output->GetDimension(3));
- //requestedRegion.SetSize(4, output->GetNumberOfChannels());
-
- input->SetRequestedRegion( & requestedRegion );
-}
diff --git a/Modules/Ext/Algorithms/mitkAngleCorrectByPointFilter.h b/Modules/Ext/Algorithms/mitkAngleCorrectByPointFilter.h
deleted file mode 100644
index af548cf69d..0000000000
--- a/Modules/Ext/Algorithms/mitkAngleCorrectByPointFilter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKANGLECORRECTBYPOINTFILTER_H_HEADER_INCLUDED_C1F48A22
-#define MITKANGLECORRECTBYPOINTFILTER_H_HEADER_INCLUDED_C1F48A22
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkImageToImageFilter.h"
-#include "mitkVector.h"
-
-namespace mitk {
-
-//##Documentation
-//## @brief
-//## @ingroup Process
-class MitkExt_EXPORT AngleCorrectByPointFilter : public ImageToImageFilter
-{
-public:
- mitkClassMacro(AngleCorrectByPointFilter, ImageToImageFilter);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetMacro(Center, Point3D);
- itkGetConstReferenceMacro(Center, Point3D);
-
- itkSetMacro(TransducerPosition, Point3D);
- itkGetConstReferenceMacro(TransducerPosition, Point3D);
-
- itkSetMacro(PreferTransducerPositionFromProperty, bool);
- itkGetMacro(PreferTransducerPositionFromProperty, bool);
-
-protected:
-
- //##Description
- //## @brief Time when Header was last initialized
- itk::TimeStamp m_TimeOfHeaderInitialization;
-
-protected:
- AngleCorrectByPointFilter();
-
- ~AngleCorrectByPointFilter();
-
- virtual void GenerateData();
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateInputRequestedRegion();
-
- Point3D m_TransducerPosition;
- Point3D m_Center;
-
- bool m_PreferTransducerPositionFromProperty;
-};
-
-} // namespace mitk
-
-#endif /* MITKANGLECORRECTBYPOINTFILTER_H_HEADER_INCLUDED_C1F48A22 */
-
-
diff --git a/Modules/Ext/Algorithms/mitkCylindricToCartesianFilter.cpp b/Modules/Ext/Algorithms/mitkCylindricToCartesianFilter.cpp
deleted file mode 100644
index 45ac8276fd..0000000000
--- a/Modules/Ext/Algorithms/mitkCylindricToCartesianFilter.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkCylindricToCartesianFilter.h"
-#include "mitkImageTimeSelector.h"
-#include "mitkSlicedGeometry3D.h"
-#include "mitkPlaneGeometry.h"
-#include "mitkProperties.h"
-
-#include "mitkLegacyAdaptors.h"
-#include <mitkIpPicTypeMultiplex.h>
-#include <mitkProportionalTimeGeometry.h>
-
-template <class T>
-void _transform(mitkIpPicDescriptor *pic, mitkIpPicDescriptor *dest, float _outsideValue, float *fr, float *fphi, float *fz, short *rt, unsigned int *phit, unsigned int *zt, mitkIpPicDescriptor *coneCutOff_pic) //...t=truncated
-{
- T outsideValue = static_cast<T>(_outsideValue);
- register float f, ft, f0, f1, f2, f3;
-
- mitkIpInt2_t ox_size;
- mitkIpInt2_t nx_size, ny_size, nz_size;
- int oxy_size, nxy_size;
-
- T* orig, *dp, *dest_start;
-
- mitkIpInt2_t* coneCutOff=(mitkIpInt2_t*)coneCutOff_pic->data;
-
- orig=(T*)pic->data;
- ox_size=pic->n[0];
- oxy_size=ox_size*pic->n[1];
-
- nx_size=dest->n[0];
- ny_size=dest->n[1];
- nxy_size=nx_size*ny_size;
- nz_size=dest->n[2];
-
- /*nx_size=360;
- ny_size=360;
- nxy_size=nx_size*ny_size;
- nz_size=256;*/
-
- dest_start=dp=((T*)dest->data)+nxy_size*(nz_size-1);
-
- mitkIpInt2_t y;
- // int size=_mitkIpPicElements(pic);
-
- register mitkIpInt2_t x,z;
- for(y=0;y<ny_size;++y)
- {
- mitkIpInt2_t x_start;
- register mitkIpInt2_t x_end;
- int r0plusphi0=*rt;
- if(r0plusphi0>=0)
- {
- x_start=0; x_end=nx_size;
- }
- else
- {
- x_start=-r0plusphi0; x_end=nx_size+r0plusphi0;
-
- for(z=0;z<nz_size;++z,dp+=-nxy_size-x_start)
- for(x=0;x<x_start;++x,++dp)
- *dp=outsideValue;
- dp+=nxy_size*nz_size; dp+=x_end;
- for(z=0;z<nz_size;++z,dp+=-nxy_size-x_start)
- for(x=x_end;x<nx_size;++x,++dp)
- *dp=outsideValue;
- dp+=nxy_size*nz_size; dp-=x_end;
-
- fr+=x_start;
- fphi+=x_start;
- rt+=x_start;
- phit+=x_start;
- dp+=x_start;
- coneCutOff+=x_start;
- }
-
- for(x=x_start;x<x_end;++x, ++fr, ++fphi, ++rt, ++phit, ++dp, ++coneCutOff)
- {
- f=*fr;
- f3=*fphi;
- f0=1-f;
- f1=1-f3;
- f2=f0*f3;
- f0*=f1;
- f1*=f;
- f3*=f;
-
- r0plusphi0=*rt+*phit;
-
- mitkIpInt2_t z_start;
-
- z_start=*coneCutOff;
-
- T *op;
- register unsigned int step;
- unsigned int *ztp;
-
- op=orig+*rt+*phit;
-
- float *fzp;
-
- for(z=0;z<z_start;++z, dp-=nxy_size)
- *dp=outsideValue;
-
- ztp=zt+z_start;
- fzp=fz+z_start;
-
- for(z=z_start;z<nz_size;++z, dp-=nxy_size)
- {
- step=*(ztp++);
-
- register T *opt=op;
- opt+=step;
- f =*opt*f0; ++opt;
- f+=*opt*f1; opt+=oxy_size; --opt;
- f+=*opt*f2; ++opt;
- f+=*opt*f3; opt-=oxy_size; --opt;
-
- opt+=ox_size;
- ft =*opt*f0; ++opt;
- ft+=*opt*f1; opt+=oxy_size; --opt;
- ft+=*opt*f2; ++opt;
- ft+=*opt*f3;
-
- *dp=(T)((1-*fzp)*f+*fzp*ft+0.5);
- }
-
- dp+=nxy_size*nz_size;
- }
- fr+=nx_size-x_end;
- fphi+=nx_size-x_end;
- rt+=nx_size-x_end;
- phit+=nx_size-x_end;
- dp+=nx_size-x_end;
- coneCutOff+=nx_size-x_end;
- }
-}
-
-void mitk::CylindricToCartesianFilter::buildTransformShortCuts(int orig_xsize, int orig_ysize, int orig_zsize, int new_xsize, mitkIpPicDescriptor * &rt_pic, mitkIpPicDescriptor * &phit_pic, mitkIpPicDescriptor * &fr_pic, mitkIpPicDescriptor * &fphi_pic, unsigned int * &zt, float * &fz)
-{
- --orig_zsize;
-
- rt_pic=mitkIpPicNew();
- rt_pic->type=mitkIpPicInt;
- rt_pic->bpe=16;
- rt_pic->dim=2;
- rt_pic->n[0]=rt_pic->n[1]=new_xsize;
- rt_pic->data=malloc(_mitkIpPicSize(rt_pic));
-
- phit_pic=mitkIpPicNew();
- phit_pic->type=mitkIpPicUInt;
- phit_pic->bpe=32;
- phit_pic->dim=2;
- phit_pic->n[0]=phit_pic->n[1]=new_xsize;
- phit_pic->data=malloc(_mitkIpPicSize(phit_pic));
-
- fr_pic=mitkIpPicNew();
- fr_pic->type=mitkIpPicFloat;
- fr_pic->bpe=32;
- fr_pic->dim=2;
- fr_pic->n[0]=fr_pic->n[1]=new_xsize;
- fr_pic->data=malloc(_mitkIpPicSize(fr_pic));
-
- fphi_pic=mitkIpPicNew();
- fphi_pic->type=mitkIpPicFloat;
- fphi_pic->bpe=32;
- fphi_pic->dim=2;
- fphi_pic->n[0]=fphi_pic->n[1]=new_xsize;
- fphi_pic->data=malloc(_mitkIpPicSize(fphi_pic));
-
- mitkIpInt2_t *rtp=(mitkIpInt2_t*)rt_pic->data, *rt_xzero, rt, phit;
- mitkIpUInt4_t *phitp=(mitkIpUInt4_t*)phit_pic->data;
- mitkIpFloat4_t *fr=(mitkIpFloat4_t *)fr_pic->data;
- mitkIpFloat4_t *fphi=(mitkIpFloat4_t *)fphi_pic->data;
-
- mitkIpFloat4_t r, phi, scale=(double)orig_xsize/(double)new_xsize;
-
- int x,y,xy0,xy0_orig, oxy_size, new_zsize;
- oxy_size=orig_xsize*orig_ysize;
- xy0=(int)(((double)new_xsize)/2+0.5);
- xy0_orig=(int)(((double)orig_xsize)/2+0.5);
-
- new_zsize=(int)(orig_ysize/scale);
- // \bug y compared to x
- for(y=0;y<new_xsize;++y)
- {
- rt_xzero=rtp; *rtp=0;
- for(x=0;x<new_xsize;++x,++fr,++fphi,++rtp, ++phitp)
- {
- int xq=x-xy0, yq=y-xy0;
-
- r=sqrt( (double) (xq*xq+yq*yq));
-
- // float rtest=-(xy0-sqrt(xy0*xy0-yq*yq))-0.5;
- rt=(mitkIpInt2_t)(-(xy0-sqrt((double) (xy0*xy0-yq*yq)))-0.5);/*in rt steht der Index des Endes der zu �berspringenden Punkte=>anfangen bei -rt+1!*/
- // if((x>=-rt) && (x<new_xsize+rt))
- {
- if(y!=xy0)
- r=r*(y>xy0?1.0:-1.0)*scale+xy0_orig;
- else
- r=r*(x>xy0?-1.0:1.0)*scale+xy0_orig;
- rt=(mitkIpInt2_t)r;
- int xtmp=x;
- if(x>xy0)
- xtmp=new_xsize-x;
- if(rt<0)
- {
- r=rt=0;
- if(xtmp>-*rt_xzero)
- *rt_xzero=-xtmp;
- *fr=0;
- }
- else
- if(rt>orig_xsize-1)
- {
- r=rt=orig_xsize-1;
- if(xtmp>-*rt_xzero)
- *rt_xzero=-xtmp;
- *fr=0;
- }
- else
- *fr=r-rt;
- if(*fr<0)
- *fr=0;
- }
- // else
- // *fr=0;
-
- phi=orig_zsize-(yq==0?1:-atan((float)xq/yq)/M_PI+0.5)*orig_zsize;
- phit=(mitkIpUInt4_t)phi;
- *fphi=phi-phit;
-
- *rtp=rt;
- *phitp=phit*oxy_size;
- }
- }
-
- zt=(unsigned int *)malloc(sizeof(unsigned int)*new_zsize);
- fz=(float *)malloc(sizeof(float)*new_zsize);
-
- float *fzp=fz;
- unsigned int *ztp=zt;
-
- int z;
- float z_step=orig_ysize/(orig_ysize*((float)new_xsize)/orig_xsize);
- for(z=0;z<new_zsize;++z,++fzp,++ztp)
- {
- *fzp=z*z_step;
- *ztp=(unsigned int)*fzp;
- *fzp-=*ztp;
- *ztp*=orig_xsize;
- }
-}
-
-void mitk::CylindricToCartesianFilter::buildConeCutOffShortCut(int orig_xsize, int orig_ysize, mitkIpPicDescriptor *rt_pic, mitkIpPicDescriptor *fr_pic, float a, float b, mitkIpPicDescriptor * &coneCutOff_pic)
-{
- coneCutOff_pic=mitkIpPicNew();
- coneCutOff_pic->type=mitkIpPicInt;
- coneCutOff_pic->bpe=16;
- coneCutOff_pic->dim=2;
- coneCutOff_pic->n[0]=coneCutOff_pic->n[1]=rt_pic->n[0];
- coneCutOff_pic->data=malloc(_mitkIpPicSize(coneCutOff_pic));
-
- int i, size=_mitkIpPicElements(rt_pic);
- mitkIpInt2_t *rt, *ccop, ohx_size, nz_size;
- mitkIpFloat4_t *fr;
-
- a*=(float)rt_pic->n[0]/orig_xsize;
- b*=(float)rt_pic->n[0]/orig_xsize;
-
- ohx_size=orig_xsize/2;
- nz_size=orig_ysize*rt_pic->n[0]/orig_xsize;
-
- rt=(mitkIpInt2_t *)rt_pic->data; fr=(mitkIpFloat4_t*)fr_pic->data; ccop=(mitkIpInt2_t *)coneCutOff_pic->data;
-
- for(i=0; i<size; ++i, ++rt, ++ccop)
- {
- register mitkIpInt2_t cco;
- if(*rt<=ohx_size)
- cco=(mitkIpInt2_t)(a*(*rt+*fr)+b);
- else
- cco=(mitkIpInt2_t)(a*(orig_xsize-(*rt+*fr))+b);
- if(cco<0)
- cco=0;
- if(cco>=nz_size)
- cco=nz_size;
- *ccop=cco;
- }
-}
-
-void mitk::CylindricToCartesianFilter::GenerateOutputInformation()
-{
- mitk::Image::Pointer output = this->GetOutput();
- if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
- return;
-
- mitk::Image::ConstPointer input = this->GetInput();
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-
- unsigned int i, *tmpDimensions=new unsigned int[std::max(3u,input->GetDimension())];
-
- tmpDimensions[0]=m_TargetXSize;
- if(tmpDimensions[0]==0)
- tmpDimensions[0] = input->GetDimension(0);
-
- float scale=((float)tmpDimensions[0])/input->GetDimension(0);
-
- tmpDimensions[1] = tmpDimensions[0];
- tmpDimensions[2] = (unsigned int)(scale*input->GetDimension(1));
-
- for(i=3;i<input->GetDimension();++i)
- tmpDimensions[i]=input->GetDimension(i);
-
- output->Initialize(input->GetPixelType(),
- input->GetDimension(),
- tmpDimensions,
- input->GetNumberOfChannels());
-
- // initialize the spacing of the output
- Vector3D spacing = input->GetSlicedGeometry()->GetSpacing();
- if(input->GetDimension()>=2)
- spacing[2]=spacing[1];
- else
- spacing[2] = 1.0;
- spacing[1] = spacing[0];
- spacing *= 1.0/scale;
- output->GetSlicedGeometry()->SetSpacing(spacing);
-
- mitk::Point3iProperty::Pointer pointProp;
- pointProp = dynamic_cast<mitk::Point3iProperty*>(input->GetProperty("ORIGIN").GetPointer());
- if (pointProp.IsNotNull() )
- {
- itk::Point<int, 3> tp = pointProp->GetValue();
- tp[2] = (int)(tmpDimensions[2]-tp[1] * scale-1);
- tp[0] = tmpDimensions[0]/2;
- tp[1] = tmpDimensions[0]/2;
- mitk::Point3iProperty::Pointer pointProp = mitk::Point3iProperty::New(tp);
- output->SetProperty("ORIGIN", pointProp);
- }
- delete [] tmpDimensions;
-
- //output->GetSlicedGeometry()->SetPlaneGeometry(mitk::Image::BuildStandardPlanePlaneGeometry(output->GetSlicedGeometry(), tmpDimensions).GetPointer(), 0);
- //set the timebounds - after SetPlaneGeometry, so that the already created PlaneGeometry will also receive this timebounds.
- //@fixme!!! will not work for not evenly timed data!
-
- ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
- timeGeometry->Initialize(output->GetSlicedGeometry(), output->GetTimeGeometry()->CountTimeSteps());
- timeGeometry->Initialize(output->GetSlicedGeometry(), output->GetTimeGeometry()->CountTimeSteps());
- timeGeometry->SetFirstTimePoint(input->GetTimeGeometry()->GetMinimumTimePoint());
- TimePointType stepDuration = input->GetTimeGeometry()->GetMaximumTimePoint(0) -input->GetTimeGeometry()->GetMinimumTimePoint(0);
- timeGeometry->SetStepDuration(stepDuration);
- output->SetTimeGeometry(timeGeometry);
-
- output->SetPropertyList(input->GetPropertyList()->Clone());
- m_TimeOfHeaderInitialization.Modified();
-}
-
-void mitk::CylindricToCartesianFilter::GenerateData()
-{
- mitk::Image::ConstPointer input = this->GetInput();
- mitk::Image::Pointer output = this->GetOutput();
-
- mitk::ImageTimeSelector::Pointer timeSelector=mitk::ImageTimeSelector::New();
- timeSelector->SetInput(input);
-
- mitkIpPicDescriptor* pic_transformed=NULL;
- pic_transformed = mitkIpPicNew();
- pic_transformed->dim=3;
- pic_transformed->bpe = output->GetPixelType().GetBpe();
- //pic_transformed->type = output->GetPixelType().GetType();
- pic_transformed->n[0] = output->GetDimension(0);
- pic_transformed->n[1] = output->GetDimension(1);
- pic_transformed->n[2] = output->GetDimension(2);
- pic_transformed->data=malloc(_mitkIpPicSize(pic_transformed));
-
- int nstart, nmax;
- int tstart, tmax;
-
- tstart=output->GetRequestedRegion().GetIndex(3);
- nstart=output->GetRequestedRegion().GetIndex(4);
-
- tmax=tstart+output->GetRequestedRegion().GetSize(3);
- nmax=nstart+output->GetRequestedRegion().GetSize(4);
-
- if(zt==NULL)
- {
- timeSelector->SetChannelNr(nstart);
- timeSelector->SetTimeNr(tstart);
-
- buildTransformShortCuts(input->GetDimension(0),input->GetDimension(1), input->GetDimension(2), output->GetDimension(0), rt_pic, phit_pic, fr_pic, fphi_pic, zt, fz);
-
- // query the line limiting the sector
- a=b=0;
- mitk::FloatProperty::Pointer prop;
-
- prop = dynamic_cast<mitk::FloatProperty*>(input->GetProperty("SECTOR LIMITING LINE SLOPE").GetPointer());
- if (prop.IsNotNull() )
- a = prop->GetValue();
- prop = dynamic_cast<mitk::FloatProperty*>(input->GetProperty("SECTOR LIMITING LINE OFFSET").GetPointer());
- if (prop.IsNotNull() )
- b = prop->GetValue();
-
- buildConeCutOffShortCut(input->GetDimension(0),input->GetDimension(1), rt_pic, fr_pic, a, b, coneCutOff_pic);
- // mitkIpPicPut("C:\\temp\\rt_90.pic",rt_pic);
- //mitkIpPicPut("C:\\temp\\coneCutOff.pic", coneCutOff_pic);
- }
-
- int n,t;
- for(n=nstart;n<nmax;++n)//output->GetNumberOfChannels();++n)
- {
- timeSelector->SetChannelNr(n);
-
- for(t=tstart;t<tmax;++t)
- {
- timeSelector->SetTimeNr(t);
-
- timeSelector->Update();
-
- // Cast to pic descriptor for the timeSelector image
- mitkIpPicDescriptor* timeSelectorPic = mitkIpPicNew();
- mitk::ImageWriteAccessor imageAccess(timeSelector->GetOutput());
- CastToIpPicDescriptor( timeSelector->GetOutput(), &imageAccess, timeSelectorPic );
-
- _mitkIpPicFreeTags(pic_transformed->info->tags_head);
- pic_transformed->info->tags_head = _mitkIpPicCloneTags(timeSelectorPic->info->tags_head);
-
- if(input->GetDimension(2)>1)
- {
- mitkIpPicTypeMultiplex9(_transform, timeSelectorPic , pic_transformed, m_OutsideValue, (float*)fr_pic->data, (float*)fphi_pic->data, fz, (short *)rt_pic->data, (unsigned int *)phit_pic->data, zt, coneCutOff_pic);
- // mitkIpPicPut("1trf.pic",pic_transformed);
- }
- else
- {
- mitkIpPicDescriptor *doubleSlice = mitkIpPicCopyHeader( timeSelectorPic , NULL);
- doubleSlice->dim=3;
- doubleSlice->n[2]=2;
- doubleSlice->data=malloc(_mitkIpPicSize(doubleSlice));
- memcpy(doubleSlice->data, timeSelectorPic->data, _mitkIpPicSize(doubleSlice)/2);
- mitkIpPicTypeMultiplex9(_transform, doubleSlice, pic_transformed, m_OutsideValue, (float*)fr_pic->data, (float*)fphi_pic->data, fz, (short *)rt_pic->data, (unsigned int *)phit_pic->data, zt, coneCutOff_pic);
- mitkIpPicFree(doubleSlice);
- }
- output->SetVolume(pic_transformed->data, t, n);
- }
- }
- //mitkIpPicPut("outzzzzzzzz.pic",pic_transformed);
- mitkIpPicFree(pic_transformed);
-
- m_TimeOfHeaderInitialization.Modified();
-}
-
-mitk::CylindricToCartesianFilter::CylindricToCartesianFilter()
-: m_OutsideValue(0.0), m_TargetXSize(0)
-{
- rt_pic = NULL; phit_pic = NULL; fr_pic = NULL; fphi_pic = NULL; coneCutOff_pic = NULL;
- zt = NULL; fz = NULL;
- a=b=0.0;
-}
-
-mitk::CylindricToCartesianFilter::~CylindricToCartesianFilter()
-{
- if(rt_pic!=NULL) mitkIpPicFree(rt_pic);
- if(phit_pic!=NULL) mitkIpPicFree(phit_pic);
- if(fr_pic!=NULL) mitkIpPicFree(fr_pic);
- if(fphi_pic!=NULL) mitkIpPicFree(fphi_pic);
- if(coneCutOff_pic!=NULL) mitkIpPicFree(coneCutOff_pic);
- if(zt != NULL) free(zt);
- if(fz != NULL) free (fz);
-}
-
-void mitk::CylindricToCartesianFilter::GenerateInputRequestedRegion()
-{
- Superclass::GenerateInputRequestedRegion();
-
- mitk::ImageToImageFilter::InputImagePointer input =
- const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() );
- mitk::Image::Pointer output = this->GetOutput();
-
- Image::RegionType requestedRegion;
- requestedRegion = output->GetRequestedRegion();
- requestedRegion.SetIndex(0, 0);
- requestedRegion.SetIndex(1, 0);
- requestedRegion.SetIndex(2, 0);
- requestedRegion.SetSize(0, input->GetDimension(0));
- requestedRegion.SetSize(1, input->GetDimension(1));
- requestedRegion.SetSize(2, input->GetDimension(2));
-
- input->SetRequestedRegion( & requestedRegion );
-}
diff --git a/Modules/Ext/Algorithms/mitkCylindricToCartesianFilter.h b/Modules/Ext/Algorithms/mitkCylindricToCartesianFilter.h
deleted file mode 100644
index 1de3bbfc7f..0000000000
--- a/Modules/Ext/Algorithms/mitkCylindricToCartesianFilter.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKCYLINDRICTOCARTESIANFILTER_H_HEADER_INCLUDED_C1F48A22
-#define MITKCYLINDRICTOCARTESIANFILTER_H_HEADER_INCLUDED_C1F48A22
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkImageToImageFilter.h"
-#include "mitkIpPic.h"
-
-#ifndef M_PI
- #define M_PI 3.14159265358979323846
-#endif
-
-//#endif
-namespace mitk {
-//##Documentation
-//## @brief Filter to convert a cylindric image into a cartesian image
-//##
-//## @todo position of input image is not yet used to calculate position of the output
-//## @todo tag with transducer position not yet transformed.
-//## @todo the line limiting the sector is assumed to be available as a pic tag. Is this ok?
-//## @ingroup Process
-class MitkExt_EXPORT CylindricToCartesianFilter : public ImageToImageFilter
-{
-public:
- mitkClassMacro(CylindricToCartesianFilter, ImageToImageFilter);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- //##Documentation
- //## @brief Set background grey level
- itkSetMacro(OutsideValue, float);
- //##Documentation
- //## @brief Get background grey level
- itkGetMacro(OutsideValue, float);
-
- //##Documentation
- //## @brief Set the size in x-direction of the converted image.
- //##
- //## A value of 0 (default) means that the filter uses the x-size of the input image.
- itkSetMacro(TargetXSize, unsigned int);
- //##Documentation
- //## @brief Get the size in x-direction of the converted image.
- itkGetMacro(TargetXSize, unsigned int);
-
- //##Documentation
- //## @brief Build some tables to speed up transformation, e.g., to avoid repeated calulations of the same sinus/cosinus.
- //## @todo Free tables if they were already previously allocated
- void buildTransformShortCuts(int orig_xsize, int orig_ysize, int orig_zsize, int new_xsize, mitkIpPicDescriptor * &rt_pic, mitkIpPicDescriptor * &phit_pic, mitkIpPicDescriptor * &fr_pic, mitkIpPicDescriptor * &fphi_pic, unsigned int * &zt, float * &fz);
-
- //##Documentation
- //## @brief Build some tables to speed up transformation of images that only contain data within a sector
- //## @todo Free tables if they were already previously allocated
- void buildConeCutOffShortCut(int orig_xsize, int orig_ysize, mitkIpPicDescriptor *rt_pic, mitkIpPicDescriptor *fr_pic, float a, float b, mitkIpPicDescriptor * &coneCutOff_pic);
-protected:
- mitkIpPicDescriptor * rt_pic, * phit_pic, *fr_pic, * fphi_pic, * coneCutOff_pic;
- float * fz;
- unsigned int * zt;
- //##Description
- //## @brief Cut off line for images that only contain data within a sector
- //##
- //## y=a x+b
- float a;
- //##Description
- //## @brief Cut off line for images that only contain data within a sector
- //##
- //## y=a x+b
- float b;
-
- //##Description
- //## @brief Time when Header was last initialized
- itk::TimeStamp m_TimeOfHeaderInitialization;
-protected:
- virtual void GenerateData();
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateInputRequestedRegion();
-
- CylindricToCartesianFilter();
-
- ~CylindricToCartesianFilter();
-
- float m_OutsideValue;
- unsigned int m_TargetXSize;
-};
-
-} // namespace mitk
-
-#endif /* MITKCYLINDRICTOCARTESIANFILTER_H_HEADER_INCLUDED_C1F48A22 */
-
-
diff --git a/Modules/Ext/Algorithms/mitkGeometryDataSource.cpp b/Modules/Ext/Algorithms/mitkGeometryDataSource.cpp
deleted file mode 100644
index f4fc140e50..0000000000
--- a/Modules/Ext/Algorithms/mitkGeometryDataSource.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkGeometryDataSource.h"
-#include "mitkGeometryData.h"
-
-mitk::GeometryDataSource::GeometryDataSource()
-{
- // Create the output.
- itk::DataObject::Pointer output = this->MakeOutput(0);
- Superclass::SetNumberOfRequiredOutputs(1);
- Superclass::SetNthOutput(0, output);
-}
-
-mitk::GeometryDataSource::~GeometryDataSource()
-{
-}
-
-itk::DataObject::Pointer mitk::GeometryDataSource::MakeOutput ( DataObjectPointerArraySizeType /*idx*/ )
-{
- return OutputType::New().GetPointer();
-}
-
-itk::DataObject::Pointer mitk::GeometryDataSource::MakeOutput( const DataObjectIdentifierType & name )
-{
- itkDebugMacro("MakeOutput(" << name << ")");
- if( this->IsIndexedOutputName(name) )
- {
- return this->MakeOutput( this->MakeIndexFromOutputName(name) );
- }
- return OutputType::New().GetPointer();
-}
-
-mitkBaseDataSourceGetOutputDefinitions(mitk::GeometryDataSource)
diff --git a/Modules/Ext/Algorithms/mitkGeometryDataSource.h b/Modules/Ext/Algorithms/mitkGeometryDataSource.h
deleted file mode 100644
index c67ca5a7af..0000000000
--- a/Modules/Ext/Algorithms/mitkGeometryDataSource.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKGEOMETRYDATASOURCE_H_HEADER_INCLUDED_C10B4740
-#define MITKGEOMETRYDATASOURCE_H_HEADER_INCLUDED_C10B4740
-
-#include "mitkBaseDataSource.h"
-#include "MitkExtExports.h"
-
-namespace mitk {
-
-class GeometryData;
-
-/**
- * @brief Superclass of all classes generating GeometryData (instances of class
- * GeometryData) as output.
- *
- * In itk and vtk the generated result of a ProcessObject is only guaranteed
- * to be up-to-date, when Update() of the ProcessObject or the generated
- * DataObject is called immediately before access of the data stored in the
- * DataObject. This is also true for subclasses of mitk::BaseProcess and thus
- * for mitk::GeometryDataSource.
- * @ingroup Process
- */
-class MitkExt_EXPORT GeometryDataSource : public BaseDataSource
-{
-public:
-
- mitkClassMacro(GeometryDataSource, BaseDataSource)
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- typedef mitk::GeometryData OutputType;
-
- mitkBaseDataSourceGetOutputDeclarations
-
- /**
- * Allocates a new output object and returns it. Currently the
- * index idx is not evaluated.
- * @param idx the index of the output for which an object should be created
- * @returns the new object
- */
- virtual itk::DataObject::Pointer MakeOutput ( DataObjectPointerArraySizeType idx );
-
- /**
- * This is a default implementation to make sure we have something.
- * Once all the subclasses of ProcessObject provide an appopriate
- * MakeOutput(), then ProcessObject::MakeOutput() can be made pure
- * virtual.
- */
- virtual itk::DataObject::Pointer MakeOutput(const DataObjectIdentifierType &name);
-
-protected:
-
- GeometryDataSource();
- virtual ~GeometryDataSource();
-};
-
-} // namespace mitk
-
-
-
-#endif /* MITKGEOMETRYDATASOURCE_H_HEADER_INCLUDED_C10B4740 */
diff --git a/Modules/Ext/Algorithms/mitkImageToItkMultiplexer.h b/Modules/Ext/Algorithms/mitkImageToItkMultiplexer.h
deleted file mode 100644
index 2ce6000a78..0000000000
--- a/Modules/Ext/Algorithms/mitkImageToItkMultiplexer.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKIMAGETOITKMULTIPLEXER_H_HEADER_INCLUDED
-#define MITKIMAGETOITKMULTIPLEXER_H_HEADER_INCLUDED
-
-#include <itkCastImageFilter.h>
-#include <mitkImageToItk.h>
-
-/*!
-* \brief method creates a cast image filter and casts the image of ItkInputImageType
-* to type ItkOutputImageType. The method needs to be called via the
-* mitkImageToItkMultiplexer
-*
-* \code
-* mitk::Image::Pointer inputMitkImage;
-* ... // set inputMitkImage
-* ITKImageType::Pointer resultItkImage = ITKImageType::New();
-* FixedInputDimensionMitkToItkFunctionMultiplexer(resultItkImage, ITKImageType, inputMitkImage, dimension, MakeCastImageFilter);
-*
-* \endcode
-*/
-template < typename ItkInputImageType, typename ItkOutputImageType >
-typename itk::ImageSource < ItkOutputImageType > ::Pointer
-MakeCastImageFilter( ItkInputImageType* inputImage )
-{
- typedef itk::CastImageFilter < ItkInputImageType ,
- ItkOutputImageType > myFilterType;
- typename myFilterType::Pointer myFilter = myFilterType::New();
- myFilter->SetInput( inputImage );
- return myFilter.GetPointer();
-}
-
-#define _calculateItkPipelineFunction(result, mitksource, itkpipelinefunction, type, dimension) \
- if ( typeId == typeid(type) ) \
-{ \
- typedef itk::Image<type, dimension> ImageType; \
- typedef mitk::ImageToItk<ImageType> ImageToItkType; \
- typedef itk::SmartPointer<ImageToItkType> ImageToItkTypePointer; \
- typedef itk::ImageSource<ImageType> ImageFilterType; \
- typedef itk::SmartPointer<ImageFilterType> ImageFilterTypePointer; \
- \
- ImageToItkTypePointer myImageToItkFilter = ImageToItkType::New(); \
- myImageToItkFilter ->SetInput(mitksource); \
- \
- ImageFilterTypePointer itkpipeline = \
- itkpipelinefunction(myImageToItkFilter->GetOutput()).GetPointer(); \
- itkpipeline->Update(); \
- \
- result->InitializeByItk(itkpipeline->GetOutput()); \
- result->SetVolume(itkpipeline->GetOutput()->GetBufferPointer()); \
-}
-// _calculateItkPipelineFunction(result, mitkimage, itkpipeline<type, dimension>::New());
-
-#define ItkFunctionMultiplexer(result, mitkSourceImage, itkfunction) \
-{ \
- const std::type_info& typeId=*mitkSourceImage->GetPixelType().GetTypeId(); \
- switch (mitkSourceImage->GetDimension()) \
-{ \
- case 2: \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, double, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, float, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, long, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned long, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, int, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned int, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, short, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned short, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, char, 2) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned char, 2) \
- break; \
- case 3: \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, double, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, float, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, long, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned long, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, int, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned int, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, short, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned short, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, char, 3) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned char, 3) \
- break; \
- case 4: \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, double, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, float, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, long, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned long, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, int, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned int, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, short, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned short, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, char, 4) else \
- _calculateItkPipelineFunction(result, mitkSourceImage, itkfunction, unsigned char, 4) \
- break; \
- default: break; \
-} \
-}
-///////////////////////////////////////////////
-
-#define _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitksource, itkpipelinefunction, type, dimension) \
- if ( typeId == typeid(type) ) \
-{ \
- typedef itk::Image<type, dimension> ImageType; \
- typedef mitk::ImageToItk<ImageType> ImageToItkType; \
- typedef itk::SmartPointer<ImageToItkType> ImageToItkTypePointer; \
- typedef itk::ImageSource<resultItkImageType> ImageFilterType; \
- typedef itk::SmartPointer<ImageFilterType> ImageFilterTypePointer; \
- \
- ImageToItkTypePointer myImageToItkFilter = ImageToItkType::New(); \
- myImageToItkFilter->SetInput(mitksource); \
- \
- ImageFilterTypePointer itkpipeline = \
- itkpipelinefunction<ImageType,resultItkImageType>(myImageToItkFilter->GetOutput()).GetPointer(); \
- itkpipeline->Update(); \
- \
- resultItkImage = itkpipeline->GetOutput(); \
-}
-
-//##Documentation
-//## @brief multiplexes a mitk image to an itkFilter with inputs of dimensions 2-4 and all data types (the itkFilter must allow to do this!).
-#define AllInputDimensionMitkToItkFunctionMultiplexer(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction) \
-{ \
- const std::type_info& typeId=*mitkSourceImage->GetPixelType().GetTypeId(); \
- switch (mitkSourceImage->GetDimension()) \
-{ \
- case 2: \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, double, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, float, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, long, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned long, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, int, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned int, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, short, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned short, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, char, 2) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned char, 2) \
- break; \
- case 3: \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, double, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, float, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, long, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned long, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, int, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned int, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, short, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned short, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, char, 3) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned char, 3) \
- break; \
- case 4: \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, double, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, float, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, long, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned long, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, int, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned int, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, short, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned short, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, char, 4) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned char, 4) \
- break; \
- default: break; \
-} \
-}
-
-//##Documentation
-//## @brief multiplexes a mitk image to an itkFilter with inputs of fixed dimensions @a inputDimension and all data types (the itkFilter must allow to do this!).
-#define FixedInputDimensionMitkToItkFunctionMultiplexer(resultItkImage, resultItkImageType, mitkSourceImage, inputDimension, itkfunction) \
-{ \
- const std::type_info& typeId=*mitkSourceImage->GetPixelType().GetTypeId(); \
- if (mitkSourceImage->GetDimension() == inputDimension) \
- { \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, double, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, float, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, long, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned long, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, int, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned int, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, short, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned short, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, char, inputDimension) else \
- _calculateMitkToItkPipelineFunction(resultItkImage, resultItkImageType, mitkSourceImage, itkfunction, unsigned char, inputDimension) \
- } \
-}
-
-//for compatibility
-#include "mitkImageCast.h"
-#endif // of MITKIMAGETOITKMULTIPLEXER_H_HEADER_INCLUDED
diff --git a/Modules/Ext/Algorithms/mitkImageToLookupTableFilter.cpp b/Modules/Ext/Algorithms/mitkImageToLookupTableFilter.cpp
deleted file mode 100644
index 5d7fc7a7e5..0000000000
--- a/Modules/Ext/Algorithms/mitkImageToLookupTableFilter.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkImageToLookupTableFilter.h"
-#include "mitkImageToItk.h"
-#include "itkImage.h"
-#include "itkVector.h"
-#include "itkImageRegionIterator.h"
-#include "itkNumericTraits.h"
-#include <algorithm>
-
-mitk::ImageToLookupTableFilter::ImageToLookupTableFilter()
-{
- this->SetNumberOfRequiredInputs(1);
-}
-
-
-
-
-mitk::ImageToLookupTableFilter::~ImageToLookupTableFilter()
-{
-
-}
-
-
-
-
-void mitk::ImageToLookupTableFilter::SetInput( const mitk::ImageToLookupTableFilter::InputImageType *input)
-{
- // Process object is not const-correct so the const_cast is required here
- this->itk::ProcessObject::SetNthInput( 0, const_cast< InputImageType * >( input ) );
-
-}
-
-
-
-
-void mitk::ImageToLookupTableFilter::SetInput( unsigned int index, const mitk::ImageToLookupTableFilter::InputImageType * input)
-{
- if ( index + 1 > this->GetNumberOfInputs() )
- {
- this->SetNumberOfRequiredInputs( index + 1 );
- }
- // Process object is not const-correct so the const_cast is required here
- this->ProcessObject::SetNthInput( index, const_cast< InputImageType *>( input ) );
-}
-
-
-
-
-const mitk::ImageToLookupTableFilter::InputImageType * mitk::ImageToLookupTableFilter::GetInput(void)
-{
- if ( this->GetNumberOfInputs() < 1 )
- {
- return 0;
- }
- return static_cast<const InputImageType * >( this->ProcessObject::GetInput( 0 ) );
-}
-
-
-
-
-const mitk::ImageToLookupTableFilter::InputImageType * mitk::ImageToLookupTableFilter::GetInput(unsigned int idx)
-{
- return static_cast< const InputImageType * >( this->ProcessObject::GetInput( idx ) );
-}
-
-
-
-
-void mitk::ImageToLookupTableFilter::GenerateData()
-{
- this->SetNumberOfIndexedOutputs( this->GetNumberOfInputs() );
- for (unsigned int inputIdx = 0; inputIdx < this->GetNumberOfInputs() ; ++inputIdx)
- {
- InputImagePointer image = const_cast<mitk::Image*>(this->GetInput( inputIdx ));
- OutputTypePointer output = dynamic_cast<OutputType*>(this->MakeOutput( inputIdx ).GetPointer());
-
- this->ProcessObject::SetNthOutput( inputIdx, output.GetPointer() );
- if (image.IsNull())
- {
- itkWarningMacro(<< inputIdx<<"'th input image is null!");
- return;
- }
-
- // the default vtkLookupTable has range=[0,1]; and hsv ranges set
- // up for rainbow color table (from red to blue).
-
- vtkSmartPointer<vtkLookupTable> vtkLut = vtkSmartPointer<vtkLookupTable>::New();
- /*
- if ( ( image->GetPixelType().GetNumberOfComponents() == 3 ) && ( image->GetDimension() == 3 ) )
- {
-
- // some typedefs for conversion to an iterable itk image
- const unsigned int VectorDimension = 3;
- typedef float VectorComponentType;
- typedef itk::Vector< VectorComponentType, VectorDimension > VectorType;
- typedef itk::Image< VectorType, VectorDimension > VectorFieldType;
- typedef itk::ImageRegionIterator< VectorFieldType > VectorFieldIteratorType;
- typedef mitk::ImageToItk<VectorFieldType> ImageConverterType;
-
- // some local variables
- float minValue = itk::NumericTraits<float>::max();
- float maxValue = itk::NumericTraits<float>::NonpositiveMin();
- float norm = 0.0f;
-
- //determine the range of the vector magnitudes in the image
- ImageConverterType::Pointer imageConverter = ImageConverterType::New();
- imageConverter->SetInput(image);
- VectorFieldType::Pointer itkImage = imageConverter->GetOutput();
- VectorFieldIteratorType it( itkImage, itkImage->GetRequestedRegion() );
- it.GoToBegin();
- while ( !it.IsAtEnd() )
- {
- norm = it.Get().GetNorm();
- minValue = std::min(norm, minValue);
- maxValue = std::max(norm, maxValue);
- }
- MITK_INFO << "Range of vector magnitudes: [" << minValue << ", "<< maxValue << "]." << std::endl;
- vtkLut->SetRange(minValue, maxValue);
- }
- else
- {
- itkWarningMacro(<< "Sorry, only 3d vector images are currently supported!");
- }*/
- vtkLut->SetRange(0, 10);
- output->SetVtkLookupTable( vtkLut );
- }
-}
diff --git a/Modules/Ext/Algorithms/mitkImageToLookupTableFilter.h b/Modules/Ext/Algorithms/mitkImageToLookupTableFilter.h
deleted file mode 100644
index ec2c2043b4..0000000000
--- a/Modules/Ext/Algorithms/mitkImageToLookupTableFilter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_IMAGE_TO_LOOKUP_TABLE_FILTER__H_
-#define _MITK_IMAGE_TO_LOOKUP_TABLE_FILTER__H_
-
-#include <mitkLookupTableSource.h>
-#include "MitkExtExports.h"
-#include <mitkImage.h>
-
-namespace mitk
-{
-
-/**
-* Creates a mitk::LookupTable from an image. This may be used to
-* create a default coloring scheme for vector images...
-*/
-class MitkExt_EXPORT ImageToLookupTableFilter : public LookupTableSource
-{
-public:
-
- mitkClassMacro( ImageToLookupTableFilter, LookupTableSource );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- // typedefs for setting an image as input
- typedef mitk::Image InputImageType;
- typedef InputImageType::Pointer InputImagePointer;
- typedef InputImageType::ConstPointer InputImageConstPointer;
-
- virtual void SetInput( const InputImageType *image);
-
- virtual void SetInput( unsigned int, const InputImageType * image);
-
- const InputImageType * GetInput(void);
-
- const InputImageType * GetInput(unsigned int idx);
-
-protected:
-
- virtual void GenerateData();
-
- ImageToLookupTableFilter();
-
- virtual ~ImageToLookupTableFilter();
-
-};
-
-
-} //end of namespace mitk
-
-#endif
diff --git a/Modules/Ext/Algorithms/mitkInterpolateLinesFilter.cpp b/Modules/Ext/Algorithms/mitkInterpolateLinesFilter.cpp
deleted file mode 100644
index 0a124c1776..0000000000
--- a/Modules/Ext/Algorithms/mitkInterpolateLinesFilter.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkInterpolateLinesFilter.h"
-#include "mitkMesh.h"
-#include "mitkSurface.h"
-
-#include <vtkPolyData.h>
-#include <vtkPoints.h>
-#include <vtkCellArray.h>
-#include <vtkCardinalSpline.h>
-
-#include <vector>
-
-
-mitk::InterpolateLinesFilter::InterpolateLinesFilter()
-: m_SplineResolution(10), m_GeometryForInterpolation(NULL), m_Length(0.0)
-{
- m_SpX=vtkCardinalSpline::New();
- m_SpY=vtkCardinalSpline::New();
- m_SpZ=vtkCardinalSpline::New();
-
-}
-
-mitk::InterpolateLinesFilter::~InterpolateLinesFilter()
-{
- m_SpX->Delete();
- m_SpY->Delete();
- m_SpZ->Delete();
-}
-
-void mitk::InterpolateLinesFilter::GenerateOutputInformation()
-{
- mitk::Mesh::ConstPointer input = this->GetInput();
- mitk::Surface::Pointer output = this->GetOutput(0);
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-
- if(input.IsNull()) return;
-
- if(m_GeometryForInterpolation.IsNotNull())
- output->SetGeometry(static_cast<BaseGeometry*>(m_GeometryForInterpolation->Clone().GetPointer()));
- else
- output->SetGeometry(static_cast<BaseGeometry*>(input->GetGeometry()->Clone().GetPointer()));
-}
-
-void mitk::InterpolateLinesFilter::GenerateData()
-{
- mitk::Mesh::ConstPointer input = this->GetInput();
- mitk::Surface::Pointer output = this->GetOutput(0);
-
- vtkPolyData *polyData = vtkPolyData::New();
- vtkPoints *points = vtkPoints::New();
- vtkCellArray *cellarray = vtkCellArray::New();
-
- mitk::Mesh::PointType thisPoint;
-
- m_Length = 0.0;
-
- //iterate through all cells and build tubes
- Mesh::ConstCellIterator cellIt, cellEnd;
- cellEnd = input->GetMesh()->GetCells()->End();
- for( cellIt = input->GetMesh()->GetCells()->Begin(); cellIt != cellEnd; ++cellIt )
- {
- if(((*cellIt->Value()).GetType()==mitk::Mesh::CellType::POLYGON_CELL)
- && ((*cellIt->Value()).GetNumberOfPoints()>=2))
- BuildPointAndVectorList(*cellIt->Value(), points, cellarray);
- }
-
- polyData->SetPoints( points );
- points->Delete();
- polyData->SetLines( cellarray );
- cellarray->Delete();
-
- output->SetVtkPolyData(polyData);
-
- polyData->Delete();
-}
-
-void mitk::InterpolateLinesFilter::BuildPointAndVectorList(mitk::Mesh::CellType& cell, vtkPoints* points, vtkCellArray* cellarray)
-{
- const mitk::Mesh* input = GetInput();
-
- Mesh::PointIdIterator ptIt;
- Mesh::PointIdIterator ptEnd;
-
- ptEnd = cell.PointIdsEnd();
-
- Point3D pt;
-
- int i, size=cell.GetNumberOfPoints();
-
- int closed_loop_pre_load=0;//m_SplineResolution;
- if(m_GeometryForInterpolation.IsNull())
- {
- //when the contour is closed: first point insert behind two last points for smooth crossing
- ptIt = ptEnd; ptIt-=closed_loop_pre_load+1;
- for(i=0;i<closed_loop_pre_load;++i, ++ptIt)
- {
- pt = input->GetPoint(*ptIt);
- m_SpX->AddPoint(i, pt[0]); m_SpY->AddPoint(i, pt[1]); m_SpZ->AddPoint(i, pt[2]);
- }
- //insert points
- for(ptIt = cell.PointIdsBegin();i<size+closed_loop_pre_load;++i, ++ptIt)
- {
- pt = input->GetPoint(*ptIt);
- m_SpX->AddPoint(i, pt[0]); m_SpY->AddPoint(i, pt[1]); m_SpZ->AddPoint(i, pt[2]);
- }
- //when the contour is closed: after the last point insert two first points for smooth crossing
- int j;
- for(j=0,ptIt = cell.PointIdsBegin();j<closed_loop_pre_load;++j,++i, ++ptIt)
- {
- pt = input->GetPoint(*ptIt);
- m_SpX->AddPoint(i, pt[0]); m_SpY->AddPoint(i, pt[1]); m_SpZ->AddPoint(i, pt[2]);
- }
- //bool first = true;
- Point3D lastPt, firstPt;
- Vector3D vec;
- float t, step=1.0f/m_SplineResolution;
- size=(size-1)*m_SplineResolution;
- i=closed_loop_pre_load;
-
- cellarray->InsertNextCell(size);
- for(t=closed_loop_pre_load;i<size+closed_loop_pre_load;++i, t+=step)
- {
- float pt[3];
- FillVector3D(pt, m_SpX->Evaluate(t), m_SpY->Evaluate(t), m_SpZ->Evaluate(t));
- cellarray->InsertCellPoint(points->InsertNextPoint(pt));
- }
- }
- else //m_GeometryForInterpolation!=NULL
- {
- Point2D pt2d;
- //when the contour is closed: before the first point insert two last points for smooth crossing
- ptIt = ptEnd; ptIt-=closed_loop_pre_load+1;
- for(i=0;i<closed_loop_pre_load;++i, ++ptIt)
- {
- m_GeometryForInterpolation->Map(input->GetPoint(*ptIt), pt2d);
- m_SpX->AddPoint(i, pt2d[0]); m_SpY->AddPoint(i, pt2d[1]);
- }
- //insert points
- for(ptIt = cell.PointIdsBegin();i<size+closed_loop_pre_load;++i, ++ptIt)
- {
- m_GeometryForInterpolation->Map(input->GetPoint(*ptIt), pt2d);
- m_SpX->AddPoint(i, pt2d[0]); m_SpY->AddPoint(i, pt2d[1]);
- }
- //when the contour is closed: after the last point insert two first points for smooth crossing
- int j;
- for(j=0,ptIt = cell.PointIdsBegin();j<closed_loop_pre_load;++j,++i, ++ptIt)
- {
- m_GeometryForInterpolation->Map(input->GetPoint(*ptIt), pt2d);
- m_SpX->AddPoint(i, pt2d[0]); m_SpY->AddPoint(i, pt2d[1]);
- }
- bool first = true;
- Point3D lastPt; lastPt.Fill(0);
- Vector3D vec;
- float t, step=1.0f/m_SplineResolution;
- size=(size-1)*m_SplineResolution;
- i=closed_loop_pre_load;
-
- cellarray->InsertNextCell(size);
- for(t=closed_loop_pre_load;i<size+closed_loop_pre_load;++i, t+=step)
- {
- pt2d[0] = m_SpX->Evaluate(t); pt2d[1] = m_SpY->Evaluate(t);
- m_GeometryForInterpolation->Map(pt2d, pt);
-
- if(first==false)
- {
- vec=pt-lastPt;
- m_Length+=vec.GetNorm();
- }
- first=false;
-
- float pvtk[3];
- itk2vtk(pt, pvtk);
- cellarray->InsertCellPoint(points->InsertNextPoint(pvtk));
- lastPt = pt;
- }
- }
-}
-
-const mitk::Mesh *mitk::InterpolateLinesFilter::GetInput(void)
-{
- if (this->GetNumberOfInputs() < 1)
- {
- return 0;
- }
-
- return static_cast<const mitk::Mesh * >
- (this->ProcessObject::GetInput(0) );
-}
-
-void mitk::InterpolateLinesFilter::SetInput(const mitk::Mesh *input)
-{
- // Process object is not const-correct so the const_cast is required here
- this->ProcessObject::SetNthInput(0,
- const_cast< mitk::Mesh * >( input ) );
-}
diff --git a/Modules/Ext/Algorithms/mitkInterpolateLinesFilter.h b/Modules/Ext/Algorithms/mitkInterpolateLinesFilter.h
deleted file mode 100644
index c4936fcc75..0000000000
--- a/Modules/Ext/Algorithms/mitkInterpolateLinesFilter.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKINTERPOLATELINESFILTER_H_HEADER_INCLUDED_C10B22CD
-#define MITKINTERPOLATELINESFILTER_H_HEADER_INCLUDED_C10B22CD
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkSurfaceSource.h"
-#include "mitkMesh.h"
-#include "mitkPlaneGeometry.h"
-
-class vtkPolyData;
-class vtkPoints;
-class vtkCardinalSpline;
-class vtkPoints;
-class vtkCellArray;
-
-
-namespace mitk {
-
-//##Documentation
-//## @brief Interpolate additional points on lines
-//##
-//## If a PlaneGeometry is set (by SetGeometryForInterpolation),
-//## we do an interpolation in the 2D-space of the PlaneGeometry:
-//## Map two neighboring original points on
-//## the PlaneGeometry, resulting in two 2D-points, interpolate
-//## in 2D between them, and map them back via the
-//## PlaneGeometry in the 3D-world.
-//## @ingroup Process
-class MitkExt_EXPORT InterpolateLinesFilter : public SurfaceSource
-{
-public:
- mitkClassMacro(InterpolateLinesFilter, SurfaceSource);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateData();
-
- const mitk::Mesh *GetInput(void);
-
- virtual void SetInput(const mitk::Mesh *image);
-
- //##Documentation
- //## @brief Get spline resolution
- //##
- itkGetMacro(SplineResolution, unsigned int);
- //##Documentation
- //## @brief Set spline resolution
- //##
- itkSetMacro(SplineResolution, unsigned int);
-
- //##Documentation
- //## @brief Get/set geometry for interpolation
- //##
- //## If this is set (not NULL), we do an interpolation in the
- //## 2D-space of the PlaneGeometry: Map two neighboring original
- //## points on the PlaneGeometry, resulting in two 2D-points,
- //## interpolate in 2D between them, and map them back via the
- //## PlaneGeometry in the 3D-world.
- itkGetConstObjectMacro(GeometryForInterpolation, mitk::PlaneGeometry);
- itkSetObjectMacro(GeometryForInterpolation, mitk::PlaneGeometry);
-
- //##Documentation
- //## @brief Get the overall length of the interpolated lines
- //##
- //## @warning valid only after Update()
- itkGetMacro(Length, ScalarType);
-protected:
-
- InterpolateLinesFilter();
- virtual ~InterpolateLinesFilter();
-
- void BuildPointAndVectorList(mitk::Mesh::CellType& cell, vtkPoints* points, vtkCellArray* cellarray);
-
- //##Documentation
- //## @brief Spline resolution of created Surface
- //##
- unsigned int m_SplineResolution;
-
- mitk::PlaneGeometry::Pointer m_GeometryForInterpolation;
- vtkCardinalSpline *m_SpX, *m_SpY, *m_SpZ;
-
- ScalarType m_Length;
-};
-
-} // namespace mitk
-
-#endif /* MITKINTERPOLATELINESFILTER_H_HEADER_INCLUDED_C10B22CD */
diff --git a/Modules/Ext/Algorithms/mitkItkImageToImageFilterAdapter.h b/Modules/Ext/Algorithms/mitkItkImageToImageFilterAdapter.h
deleted file mode 100644
index 685a1fa3fa..0000000000
--- a/Modules/Ext/Algorithms/mitkItkImageToImageFilterAdapter.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef ITKIMAGETOIMAGEFILTERADAPTER_H_HEADER_INCLUDED_C1E5E869
-#define ITKIMAGETOIMAGEFILTERADAPTER_H_HEADER_INCLUDED_C1E5E869
-
-#include "mitkCommon.h"
-#include "mitkImageToImageFilter.h"
-
-#include "itkImage.h"
-#include "itkImageToImageFilter.h"
-
-namespace mitk {
-
-//##Documentation
-//## @brief adapter class, that encapsulates any itk::ImageToImageFilter
-//##
-//## This filter converts a mitk::Image to an itk::Image, executes the
-//## itkFilter and converts the itk::Image back to a mitk::Image as output.
-//## Either call SetSingleFilter() to encapsulate one itk::ImageToImageFilter,
-//## or SetFirstFilter() and SetLastFilter() to encapsulate a whole itk pipeline.
-//## @ingroup Process
-template <typename TPixel>
-class ItkImageToImageFilterAdapter : public ImageToImageFilter
-{
-public:
- typedef TPixel PixelType;
- typedef itk::Image<PixelType, 3> ItkImageType;
- typedef itk::ImageToImageFilter<ItkImageType, ItkImageType> ImageToImageFilterType;
-
- mitkClassMacro(ItkImageToImageFilterAdapter,ImageSource);
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetObjectMacro(FirstFilter, ImageToImageFilterType);
- itkGetObjectMacro(FirstFilter, ImageToImageFilterType);
- itkSetObjectMacro(LastFilter, ImageToImageFilterType);
- itkGetObjectMacro(LastFilter, ImageToImageFilterType);
- void SetSingleFilter(typename ImageToImageFilterType::Pointer filter);
-
- virtual void GenerateOutputInformation();
- virtual void GenerateData();
-
-protected:
- ItkImageToImageFilterAdapter();
- virtual ~ItkImageToImageFilterAdapter();
-
- typename ImageToImageFilterType::Pointer m_FirstFilter; // Start of Filter Pipeline
- typename ImageToImageFilterType::Pointer m_LastFilter; // End of Filter Pipeline
-};
-} // namespace mitk
-
-#include "mitkItkImageToImageFilterAdapter.txx" // because it is a template
-
-#endif /* ITKIMAGETOIMAGEFILTERADAPTER_H_HEADER_INCLUDED_C1E5E869 */
diff --git a/Modules/Ext/Algorithms/mitkItkImageToImageFilterAdapter.txx b/Modules/Ext/Algorithms/mitkItkImageToImageFilterAdapter.txx
deleted file mode 100644
index fb0f1317b0..0000000000
--- a/Modules/Ext/Algorithms/mitkItkImageToImageFilterAdapter.txx
+++ /dev/null
@@ -1,112 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKITKIMAGETOIMAGEFILTERADAPTER_TXX
-#define MITKITKIMAGETOIMAGEFILTERADAPTER_TXX
-
-#include "mitkItkImageToImageFilterAdapter.h"
-#include "mitkImageToItkMultiplexer.h"
-#include "mitkImage.h"
-#include <vtkLinearTransform.h>
-
-namespace mitk
-{
-
-template <typename TPixel>
-ItkImageToImageFilterAdapter< TPixel>::ItkImageToImageFilterAdapter()
-: m_FirstFilter(NULL), m_LastFilter(NULL)
-{
-}
-
-template <typename TPixel>
-ItkImageToImageFilterAdapter< TPixel>::~ItkImageToImageFilterAdapter()
-{
-}
-
-/**
- * \todo check if this is no conflict to the ITK filter writing rules -> ITK SoftwareGuide p.512
- */
-template <typename TPixel>
-void ItkImageToImageFilterAdapter< TPixel>::GenerateOutputInformation()
-{
- itkDebugMacro(<<"GenerateOutputInformation()");
-}
-
-template <typename TPixel>
-void ItkImageToImageFilterAdapter< TPixel>::GenerateData()
-{
- mitk::Image::Pointer outputImage = this->GetOutput();
- typename ImageToImageFilter::InputImageConstPointer inputImage = this->GetInput();
- if(inputImage.IsNull())
- {
- outputImage = NULL;
- return;
- }
- /* Check if there is an input Filter */
- if(m_FirstFilter.IsNull() || m_LastFilter.IsNull())
- {
- outputImage = const_cast<mitk::Image*>(inputImage.GetPointer());
- return;
- }
- /* convert input mitk image to itk image */
- mitk::Image::Pointer inputImageMitk = const_cast<mitk::Image*>(inputImage.GetPointer()); // const away cast, because FixedInput...Multiplexer Macro needs non const Pointer
- typename ItkImageType::Pointer itkImage = ItkImageType::New();
- //FixedInputDimensionMitkToItkFunctionMultiplexer(itkImage, ItkImageType , inputImageMitk, 3, MakeCastImageFilter);
- CastToItkImage(inputImageMitk, itkImage);
- /* check if image conversion failed */
- if (itkImage.IsNull())
- {
- std::cout << " can't convert input image to itk" << std::endl;
- outputImage = const_cast<mitk::Image*>(inputImage.GetPointer());
- return;
- }
- //m_ItkImageToImageFilter->SetInput(itkImage);
- m_FirstFilter->SetInput(itkImage);
- try
- {
- //m_ItkImageToImageFilter->Update();
- m_LastFilter->UpdateLargestPossibleRegion();
- }
- catch( itk::ExceptionObject & excep )
- {
- std::cerr << "mitk::ItkImageToImageFilterAdapter: Exception while executing ITK filter" << std::endl;
- std::cerr << excep << std::endl;
- }
- /* convert the itk image back to an mitk image and set it as output for this filter */
- //outputImage->InitializeByItk(m_LastFilter->GetOutput());
- //outputImage->SetVolume(m_LastFilter->GetOutput()->GetBufferPointer());
- //ItkImageType::Pointer itkOutputImage = m_LastFilter->GetOutput();
- //CastToMitkImage(itkOutputImage, outputImage);
-
-
- typename ItkImageType::Pointer itkOutputImage;
- itkOutputImage = m_LastFilter->GetOutput();
-
-
- CastToMitkImage(itkOutputImage, outputImage);
- /* copy the transform from source to result image */
- outputImage->SetGeometry(static_cast<Geometry3D*>(inputImage->GetGeometry()->Clone().GetPointer()));
-}
-
-
-template <typename TPixel>
-void ItkImageToImageFilterAdapter<TPixel>::SetSingleFilter(typename ImageToImageFilterType::Pointer filter)
-{
- SetFirstFilter(filter);
- SetLastFilter(filter);
-}
-}
-#endif // of MITKITKIMAGETOIMAGEFILTERADAPTER_TXX
diff --git a/Modules/Ext/Algorithms/mitkMeshSource.cpp b/Modules/Ext/Algorithms/mitkMeshSource.cpp
deleted file mode 100644
index 474790fa86..0000000000
--- a/Modules/Ext/Algorithms/mitkMeshSource.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkMeshSource.h"
-
-
-mitk::MeshSource::MeshSource()
-{
- // Create the output.
- OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
- assert (output.IsNotNull());
- this->SetNumberOfRequiredInputs(0);
- this->SetNumberOfIndexedOutputs( 1 );
- this->SetOutput(0, output.GetPointer());
-}
-
-mitk::MeshSource::~MeshSource()
-{
-}
-
-itk::DataObject::Pointer mitk::MeshSource::MakeOutput ( DataObjectPointerArraySizeType /*idx*/ )
-{
- return OutputType::New().GetPointer();
-}
-
-
-itk::DataObject::Pointer mitk::MeshSource::MakeOutput( const DataObjectIdentifierType & name )
-{
- itkDebugMacro("MakeOutput(" << name << ")");
- if( this->IsIndexedOutputName(name) )
- {
- return this->MakeOutput( this->MakeIndexFromOutputName(name) );
- }
- return static_cast<itk::DataObject *>(OutputType::New().GetPointer());
-}
-
-mitk::MeshSource::OutputType* mitk::MeshSource::GetOutput(const itk::ProcessObject::DataObjectIdentifierType &key)
-{
- return static_cast<mitk::MeshSource::OutputType*>(Superclass::GetOutput(key));
-}
-
-const mitk::MeshSource::OutputType* mitk::MeshSource::GetOutput(const itk::ProcessObject::DataObjectIdentifierType &key) const
-{
- return static_cast<const mitk::MeshSource::OutputType*>(Superclass::GetOutput(key));
-}
-
-mitk::MeshSource::OutputType* mitk::MeshSource::GetOutput(itk::ProcessObject::DataObjectPointerArraySizeType idx)
-{
- return static_cast<mitk::MeshSource::OutputType*>(Superclass::GetOutput(idx));
-}
-
-const mitk::MeshSource::OutputType* mitk::MeshSource::GetOutput(itk::ProcessObject::DataObjectPointerArraySizeType idx) const
-{
- return static_cast<const mitk::MeshSource::OutputType*>(Superclass::GetOutput(idx));
-}
diff --git a/Modules/Ext/Algorithms/mitkMeshSource.h b/Modules/Ext/Algorithms/mitkMeshSource.h
deleted file mode 100644
index 76b7fd474c..0000000000
--- a/Modules/Ext/Algorithms/mitkMeshSource.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef _MITKMESHSOURCE_H
-#define _MITKMESHSOURCE_H
-
-#include "itkProcessObject.h"
-#include "MitkExtExports.h"
-#include "mitkMesh.h"
-
-namespace mitk
-{
-/**
- * @brief Superclass of all classes generating point sets (instances of class
- * mitk::Mesh) as output.
- *
- * In itk and vtk the generated result of a ProcessObject is only guaranteed
- * to be up-to-date, when Update() of the ProcessObject or the generated
- * DataObject is called immediately before access of the data stored in the
- * DataObject.
- * @ingroup Process
- */
-class MitkExt_EXPORT MeshSource : public itk::ProcessObject
-{
-public:
- mitkClassMacro( MeshSource, itk::ProcessObject );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- typedef mitk::Mesh OutputType;
-
- typedef OutputType::Pointer OutputTypePointer;
-
- /**
- * Allocates a new output object and returns it. Currently the
- * index idx is not evaluated.
- * @param idx the index of the output for which an object should be created
- * @returns the new object
- */
- virtual itk::DataObject::Pointer MakeOutput ( DataObjectPointerArraySizeType idx );
-
- /**
- * This is a default implementation to make sure we have something.
- * Once all the subclasses of ProcessObject provide an appopriate
- * MakeOutput(), then ProcessObject::MakeOutput() can be made pure
- * virtual.
- */
- virtual itk::DataObject::Pointer MakeOutput(const DataObjectIdentifierType &name);
-
- OutputType* GetOutput(const DataObjectIdentifierType & key);
- const OutputType* GetOutput(const DataObjectIdentifierType & key) const;
- OutputType* GetOutput(DataObjectPointerArraySizeType idx);
- const OutputType* GetOutput(DataObjectPointerArraySizeType idx) const;
-
-protected:
-
- MeshSource();
-
- virtual ~MeshSource();
-
-};
-
-}
-#endif // #define _MITKMESHSOURCE_H
diff --git a/Modules/Ext/Algorithms/mitkPlaneCutFilter.cpp b/Modules/Ext/Algorithms/mitkPlaneCutFilter.cpp
deleted file mode 100644
index 2efbca082f..0000000000
--- a/Modules/Ext/Algorithms/mitkPlaneCutFilter.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPlaneCutFilter.h"
-#include "mitkImageReadAccessor.h"
-#include <mitkImageAccessByItk.h>
-#include <mitkLine.h>
-
-#define roundf(x) ((x - floor(x)) > 0.5f ? ceil(x) : floor(x))
-
-void mitk::PlaneCutFilter::GenerateData()
-{
- if (!this->m_Plane)
- {
- return;
- }
-
- InputImageType *input = const_cast<InputImageType*>(this->GetInput());
-
- if (!input)
- {
- return;
- }
-
- //Allocate output.
- OutputImageType *output = this->GetOutput();
-
- mitk::ImageReadAccessor inputAcc(input);
- output->Initialize(input);
- output->SetImportVolume(const_cast<void*>(inputAcc.GetData()));
-
- //Do the intersection.
- AccessByItk_2(output, _computeIntersection, this->m_Plane, input->GetGeometry());
-}
-
-mitk::PlaneCutFilter::PlaneCutFilter()
- : m_BackgroundLevel(0.0f), m_Plane(0), m_FillMode(FILL)
-{
-}
-
-mitk::PlaneCutFilter::~PlaneCutFilter()
-{
-}
-
-template <typename TPixel, unsigned int VImageDimension>
-void mitk::PlaneCutFilter::_computeIntersection(itk::Image<TPixel, VImageDimension> *image, const PlaneGeometry *plane, const BaseGeometry *geometry)
-{
- typedef itk::Image<TPixel, VImageDimension> ImageType;
-
- const typename ImageType::RegionType &image_region = image->GetLargestPossibleRegion();
- const typename ImageType::SizeValueType
- max_x = image_region.GetSize(0ul),
- max_y = image_region.GetSize(1ul),
- max_z = image_region.GetSize(2ul),
- img_size = max_x * max_y;
- TPixel *data = image->GetBufferPointer();
- Point3D p1, p2;
-
- //TODO: Better solution required!
- TPixel casted_background_level = static_cast<TPixel>(this->m_BackgroundLevel);
-
- p1[0] = 0;
- p2[0] = max_x - 1ul;
-
- if (FILL == this->m_FillMode)
- {
- for (unsigned long z = 0ul; z < max_z; ++z)
- {
- p1[2] = z;
- p2[2] = z;
-
- for (unsigned long y = 0ul; y < max_y; ++y)
- {
- p1[1] = y;
- p2[1] = y;
-
- Point3D p1_t, p2_t;
-
- geometry->IndexToWorld(p1, p1_t);
- geometry->IndexToWorld(p2, p2_t);
-
- if (plane->IsAbove(p1_t))
- {
- if (plane->IsAbove(p2_t))
- {
- if (0.0f == this->m_BackgroundLevel)
- {
- memset(&data[(y * max_x) + (z * img_size)], 0, max_x * sizeof(TPixel));
- }
- else
- {
- TPixel *subdata = &data[(y * max_x) + (z * img_size)];
-
- for (unsigned long x = 0; x < max_x; ++x)
- {
- subdata[x] = casted_background_level;
- }
- }
- }
- else
- {
- Point3D intersection;
- Line3D line;
-
- line.SetPoints(p1_t, p2_t);
- plane->IntersectionPoint(line, intersection);
- geometry->WorldToIndex(intersection, intersection);
-
- if (0.0f == this->m_BackgroundLevel)
- {
- memset(&data[(y * max_x) + (z * img_size)], 0, (static_cast<unsigned long>(roundf(intersection[0])) + 1u) * sizeof(TPixel));
- }
- else
- {
-
- TPixel *subdata = &data[(y * max_x) + (z * img_size)];
- const unsigned long x_size = static_cast<unsigned long>(roundf(intersection[0])) + 1u;
-
- for (unsigned long x = 0; x < x_size; ++x)
- {
- subdata[x] = casted_background_level;
- }
- }
- }
- }
- else if (plane->IsAbove(p2_t))
- {
- Point3D intersection;
- Line3D line;
-
- line.SetPoints(p1_t, p2_t);
- plane->IntersectionPoint(line, intersection);
- geometry->WorldToIndex(intersection, intersection);
-
- if (0.0f == this->m_BackgroundLevel)
- {
- unsigned long x = static_cast<unsigned long>(roundf(intersection[0]));
-
- memset(&data[x + (y * max_x) + (z * img_size)], 0, (max_x - x) * sizeof(TPixel));
- }
- else
- {
- unsigned long x = static_cast<unsigned long>(roundf(intersection[0]));
- TPixel *subdata = &data[x + (y * max_x) + (z * img_size)];
- const unsigned long x_size = max_x - x;
-
- for (x = 0; x < x_size; ++x)
- {
- subdata[x] = casted_background_level;
- }
- }
- }
- }
- }
- }
- else
- {
- for (unsigned long z = 0ul; z < max_z; ++z)
- {
- p1[2] = z;
- p2[2] = z;
-
- for (unsigned long y = 0ul; y < max_y; ++y)
- {
- p1[1] = y;
- p2[1] = y;
-
- Point3D p1_t, p2_t;
-
- geometry->IndexToWorld(p1, p1_t);
- geometry->IndexToWorld(p2, p2_t);
-
- if (!plane->IsAbove(p1_t))
- {
- if (!plane->IsAbove(p2_t))
- {
- if (0.0f == this->m_BackgroundLevel)
- {
- memset(&data[(y * max_x) + (z * img_size)], 0, max_x * sizeof(TPixel));
- }
- else
- {
- TPixel *subdata = &data[(y * max_x) + (z * img_size)];
-
- for (unsigned long x = 0; x < max_x; ++x)
- {
- subdata[x] = casted_background_level;
- }
- }
- }
- else
- {
- Point3D intersection;
- Line3D line;
-
- line.SetPoints(p1_t, p2_t);
- plane->IntersectionPoint(line, intersection);
- geometry->WorldToIndex(intersection, intersection);
-
- if (0.0f == this->m_BackgroundLevel)
- {
- memset(&data[(y * max_x) + (z * img_size)], 0, (static_cast<unsigned long>(roundf(intersection[0])) + 1u) * sizeof(TPixel));
- }
- else
- {
-
- TPixel *subdata = &data[(y * max_x) + (z * img_size)];
- const unsigned long x_size = static_cast<unsigned long>(roundf(intersection[0])) + 1u;
-
- for (unsigned long x = 0; x < x_size; ++x)
- {
- subdata[x] = casted_background_level;
- }
- }
- }
- }
- else if (!plane->IsAbove(p2_t))
- {
- Point3D intersection;
- Line3D line;
-
- line.SetPoints(p1_t, p2_t);
- plane->IntersectionPoint(line, intersection);
- geometry->WorldToIndex(intersection, intersection);
-
- if (0.0f == this->m_BackgroundLevel)
- {
- unsigned long x = static_cast<unsigned long>(roundf(intersection[0]));
-
- memset(&data[x + (y * max_x) + (z * img_size)], 0, (max_x - x) * sizeof(TPixel));
- }
- else
- {
- unsigned long x = static_cast<unsigned long>(roundf(intersection[0]));
- TPixel *subdata = &data[x + (y * max_x) + (z * img_size)];
- const unsigned long x_size = max_x - x;
-
- for (x = 0; x < x_size; ++x)
- {
- subdata[x] = casted_background_level;
- }
- }
- }
- }
- }
- }
-}
diff --git a/Modules/Ext/Algorithms/mitkPlaneCutFilter.h b/Modules/Ext/Algorithms/mitkPlaneCutFilter.h
deleted file mode 100644
index 345b8e75a4..0000000000
--- a/Modules/Ext/Algorithms/mitkPlaneCutFilter.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef PLANECUTFILTER_H_HEADER_INCLUDED_C1F48A22
-#define PLANECUTFILTER_H_HEADER_INCLUDED_C1F48A22
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkImageToImageFilter.h"
-#include "mitkPlaneGeometry.h"
-
-namespace itk
-{
- template <class TPixel, unsigned int VImageDimension> class ITK_EXPORT Image;
-}
-
-namespace mitk {
-
-/**
- \brief Filter to cut an image with a plane.
-
- Everything in the direction of the normal
- of the planes (if fill mode is set to "FILL") will be set to a specified value.
- */
-class MitkExt_EXPORT PlaneCutFilter : public ImageToImageFilter
-{
-public:
- mitkClassMacro(PlaneCutFilter, ImageToImageFilter);
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- typedef enum {FILL, FILL_INVERSE} FillMode;
-
- //##Documentation
- //## @brief Set background grey level
- itkSetMacro(BackgroundLevel, float);
- itkGetMacro(BackgroundLevel, float);
-
- itkSetEnumMacro(FillMode, FillMode);
- itkGetEnumMacro(FillMode, FillMode);
-
- itkSetObjectMacro(Plane, const PlaneGeometry);
- itkGetObjectMacro(Plane, const PlaneGeometry);
-protected:
- float m_BackgroundLevel;
- PlaneGeometry::ConstPointer m_Plane;
- FillMode m_FillMode;
-
- PlaneCutFilter();
- ~PlaneCutFilter();
- virtual void GenerateData();
-
- template <typename TPixel, unsigned int VImageDimension>
- void _computeIntersection(itk::Image<TPixel, VImageDimension> *itkImage, const PlaneGeometry *plane, const BaseGeometry *geometry);
-};
-
-} // namespace mitk
-
-#endif /* PLANECUTFILTER_H_HEADER_INCLUDED_C1F48A22 */
-
-
diff --git a/Modules/Ext/Algorithms/mitkPlaneFit.cpp b/Modules/Ext/Algorithms/mitkPlaneFit.cpp
deleted file mode 100644
index cba794f3e0..0000000000
--- a/Modules/Ext/Algorithms/mitkPlaneFit.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPlaneFit.h"
-
-#include "mitkPlaneGeometry.h"
-#include "mitkGeometryData.h"
-#include <mitkProportionalTimeGeometry.h>
-
-#include <vnl/algo/vnl_svd.h>
-#include <vcl_iostream.h>
-
-
-mitk::PlaneFit::PlaneFit()
-: m_PointSet( NULL )
-{
- m_TimeGeometry = mitk::ProportionalTimeGeometry::New();
-}
-
-mitk::PlaneFit::~PlaneFit()
-{
-}
-
-
-void mitk::PlaneFit::GenerateOutputInformation()
-{
- mitk::PointSet::ConstPointer input = this->GetInput();
- mitk::GeometryData::Pointer output = this->GetOutput();
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-
- if (input.IsNull()) return;
-
- if ( m_PointSet == NULL )
- {
- return;
- }
-
- bool update = false;
- if ( output->GetGeometry() == NULL || output->GetTimeGeometry() == NULL )
- update = true;
- if ( ( ! update ) && ( output->GetTimeGeometry()->CountTimeSteps() != input->GetTimeGeometry()->CountTimeSteps() ) )
- update = true;
- if ( update )
- {
- mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
-
- ProportionalTimeGeometry::Pointer timeGeometry = dynamic_cast<ProportionalTimeGeometry *>(m_TimeGeometry.GetPointer());
- timeGeometry->Initialize(planeGeometry, m_PointSet->GetPointSetSeriesSize());
- //m_TimeGeometry->InitializeEvenlyTimed(
- // planeGeometry, m_PointSet->GetPointSetSeriesSize() );
-
- TimeStepType timeStep;
- for ( timeStep = 0;
- (timeStep < m_PointSet->GetPointSetSeriesSize())
- && (timeStep < m_Planes.size());
- ++timeStep )
- {
- timeGeometry->SetTimeStepGeometry( m_Planes[timeStep], timeStep );
- }
-
- output->SetTimeGeometry( m_TimeGeometry );
- }
-}
-
-void mitk::PlaneFit::GenerateData()
-{
- unsigned int t;
- for ( t = 0; t < m_PointSet->GetPointSetSeriesSize(); ++t )
- {
- // check number of data points - less then 3points isn't enough
- if ( m_PointSet->GetSize( t ) >= 3 )
- {
- this->CalculateCentroid( t );
-
- this->ProcessPointSet( t );
-
- this->InitializePlane( t );
- }
- }
-}
-
-void mitk::PlaneFit::SetInput( const mitk::PointSet* pointSet )
-{
- // Process object is not const-correct so the const_cast is required here
- this->ProcessObject::SetNthInput(0,
- const_cast< mitk::PointSet * >( pointSet ) );
-
- m_PointSet = pointSet;
- unsigned int pointSetSize = pointSet->GetPointSetSeriesSize();
-
- m_Planes.resize( pointSetSize );
- m_Centroids.resize( pointSetSize );
- m_PlaneVectors.resize( pointSetSize );
-
- unsigned int t;
- for ( t = 0; t < pointSetSize; ++t )
- {
- m_Planes[t] = mitk::PlaneGeometry::New();
- }
-}
-
-const mitk::PointSet* mitk::PlaneFit::GetInput()
-{
- if (this->GetNumberOfInputs() < 1)
- {
- return 0;
- }
-
- return static_cast<const mitk::PointSet * > (this->ProcessObject::GetInput(0) );
-}
-
-
-void mitk::PlaneFit::CalculateCentroid( int t )
-{
- if ( m_PointSet == NULL ) return;
-
- int ps_total = m_PointSet->GetSize( t );
-
- m_Centroids[t][0] = m_Centroids[t][1] = m_Centroids[t][2] = 0.0;
-
- for (int i=0; i<ps_total; i++)
- {
- mitk::Point3D p3d = m_PointSet->GetPoint(i,t);
- m_Centroids[t][0] += p3d[0];
- m_Centroids[t][1] += p3d[1];
- m_Centroids[t][2] += p3d[2];
- }
-
- // calculation of centroid
- m_Centroids[t][0] /= ps_total;
- m_Centroids[t][1] /= ps_total;
- m_Centroids[t][2] /= ps_total;
-}
-
-
-void mitk::PlaneFit::ProcessPointSet( int t )
-{
- if (m_PointSet == NULL ) return;
-
- // int matrix with POINTS x (X,Y,Z)
- vnl_matrix<mitk::ScalarType> dataM( m_PointSet->GetSize( t ), 3);
-
- int ps_total = m_PointSet->GetSize( t );
- for (int i=0; i<ps_total; i++)
- {
- mitk::Point3D p3d = m_PointSet->GetPoint(i,t);
- dataM[i][0] = p3d[0] - m_Centroids[t][0];
- dataM[i][1] = p3d[1] - m_Centroids[t][1];
- dataM[i][2] = p3d[2] - m_Centroids[t][2];
- }
- // process the SVD (singular value decomposition) from ITK
- // the vector will be orderd descending
- vnl_svd<mitk::ScalarType> svd(dataM, 0.0);
-
- // calculate the SVD of A
- vnl_vector<mitk::ScalarType> v = svd.nullvector();
-
-
- // Avoid erratic normal sign switching when the plane changes minimally
- // by negating the vector for negative x values.
- if ( v[0] < 0 )
- {
- v = -v;
- }
-
- m_PlaneVectors[t][0] = v[0];
- m_PlaneVectors[t][1] = v[1];
- m_PlaneVectors[t][2] = v[2];
-
-}
-
-mitk::PlaneGeometry::Pointer mitk::PlaneFit::GetPlaneGeometry( int t )
-{
- return m_Planes[t];
-}
-
-const mitk::Vector3D &mitk::PlaneFit::GetPlaneNormal( int t ) const
-{
- return m_PlaneVectors[t];
-}
-
-const mitk::Point3D &mitk::PlaneFit::GetCentroid( int t ) const
-{
- return m_Centroids[t];
-}
-
-void mitk::PlaneFit::InitializePlane( int t )
-{
- m_Planes[t]->InitializePlane( m_Centroids[t], m_PlaneVectors[t] );
-}
-
diff --git a/Modules/Ext/Algorithms/mitkPlaneFit.h b/Modules/Ext/Algorithms/mitkPlaneFit.h
deleted file mode 100644
index 9930a3ce35..0000000000
--- a/Modules/Ext/Algorithms/mitkPlaneFit.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#if !defined(MITK_PLANEFIT_H__INCLUDED_)
-#define MITK_PLANEFIT_H__INCLUDED_
-
-#include "mitkPointSet.h"
-#include "MitkExtExports.h"
-#include "mitkTimeGeometry.h"
-#include "mitkPlaneGeometry.h"
-#include "mitkGeometryDataSource.h"
-
-namespace mitk {
-
- //!
- // kind regards to dr. math!
- // function [x0, a, d, normd] = lsplane(X)
- // ---------------------------------------------------------------------
- // LSPLANE.M Least-squares plane (orthogonal distance
- // regression).
- //
- // Version 1.0
- // Last amended I M Smith 27 May 2002.
- // Created I M Smith 08 Mar 2002
- // ---------------------------------------------------------------------
- // Input
- // X Array [x y z] where x = vector of x-coordinates,
- // y = vector of y-coordinates and z = vector of
- // z-coordinates.
- // Dimension: m x 3.
- //
- // Output
- // x0 Centroid of the data = point on the best-fit plane.
- // Dimension: 3 x 1.
- //
- // a Direction cosines of the normal to the best-fit
- // plane.
- // Dimension: 3 x 1.
- //
- // <Optional...
- // d Residuals.
- // Dimension: m x 1.
- //
- // normd Norm of residual errors.
- // Dimension: 1 x 1.
- // ...>
- //
- // [x0, a <, d, normd >] = lsplane(X)
- // ---------------------------------------------------------------------
-
- class MitkExt_EXPORT PlaneFit : public GeometryDataSource
- {
- public:
-
- mitkClassMacro( PlaneFit, GeometryDataSource);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- typedef mitk::PointSet::PointDataType PointDataType;
- typedef mitk::PointSet::PointDataIterator PointDataIterator;
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateData();
-
- /*!Getter for point set.
- *
- */
- const mitk::PointSet *GetInput();
-
- /*! filter initialisation.
- *
- */
- virtual void SetInput( const mitk::PointSet *ps );
-
- /*! returns the center of gravity of the point set.
- *
- */
- virtual const mitk::Point3D &GetCentroid( int t = 0 ) const;
-
- /*! returns the plane geometry which represents the point set.
- *
- */
- virtual mitk::PlaneGeometry::Pointer GetPlaneGeometry( int t = 0 );
-
- /*! returns the normal of the plane which represents the point set.
- *
- */
- virtual const mitk::Vector3D &GetPlaneNormal( int t = 0 ) const;
-
- protected:
- PlaneFit();
- virtual ~PlaneFit();
-
- /*! Calculates the centroid of the point set.
- * the center of gravity is calculated through the mean value of the whole point set
- */
- void CalculateCentroid( int t = 0 );
-
- /*! working with an SVD algorithm form matrix dataM.
- * ITK suplies the vnl_svd to solve an plan fit eigentvector problem
- * points are processed in the SVD matrix. The normal vector is the
- * singular vector of dataM corresponding to its smalest singular value.
- * The mehtod uses VNL library from ITK and at least the mehtod nullvector()
- * to extract the normalvector.
- */
- void ProcessPointSet( int t = 0 );
-
- /*! Initialize Plane and configuration.
- *
- */
- void InitializePlane( int t = 0 );
-
-
- private:
-
- /*!keeps a copy of the pointset.*/
- const mitk::PointSet* m_PointSet;
-
- /* output object - a time sliced geometry.*/
- mitk::TimeGeometry::Pointer m_TimeGeometry;
-
- std::vector< mitk::PlaneGeometry::Pointer > m_Planes;
-
- /*! the calculatet center point of all points in the point set.*/
- std::vector< mitk::Point3D > m_Centroids;
-
- /* the normal vector to descrie a plane gemoetry.*/
- std::vector< mitk::Vector3D > m_PlaneVectors;
- };
-}//namespace mitk
-#endif //MITK_PLANFIT_INCLUDE_
-
-
diff --git a/Modules/Ext/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp b/Modules/Ext/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp
deleted file mode 100644
index 2f95d42e41..0000000000
--- a/Modules/Ext/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPlanesPerpendicularToLinesFilter.h"
-
-#include <vnl/vnl_cross.h>
-#include <vnl/vnl_quaternion.h>
-#include <vnl/vnl_quaternion.txx>
-
-mitk::PlanesPerpendicularToLinesFilter::PlanesPerpendicularToLinesFilter()
- : m_Plane(NULL), m_UseAllPoints(false), m_CreatedGeometries(NULL), normal(3), targetRight(3)
-{
- m_CreatedGeometries = mitk::SlicedGeometry3D::New();
-}
-
-mitk::PlanesPerpendicularToLinesFilter::~PlanesPerpendicularToLinesFilter()
-{
-}
-
-void mitk::PlanesPerpendicularToLinesFilter::GenerateOutputInformation()
-{
- mitk::Mesh::ConstPointer input = this->GetInput();
- mitk::GeometryData::Pointer output = this->GetOutput();
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-
- if(input.IsNull()) return;
-
- output->SetGeometry(m_CreatedGeometries);
-}
-
-void mitk::PlanesPerpendicularToLinesFilter::CreatePlane(const mitk::Point3D& curr)
-{
- int j;
- for(j=0;j<3;++j)
- normal[j] = last[j]-curr[j]; //@todo globally define normal direction of display xxx
- normal.normalize();
-
- down = vnl_cross_3d(normal, targetRight);
- down.normalize();
- right = vnl_cross_3d(down, normal);
- right.normalize();
-
- itk2vtk(last.GetVnlVector()-right*halfWidthInMM-down*halfHeightInMM, origin);
- right *= targetSpacing[0];
- down *= targetSpacing[1];
- normal *= targetSpacing[2];
-
- mitk::Matrix3D matrix;
- matrix.GetVnlMatrix().set_column(0, right);
- matrix.GetVnlMatrix().set_column(1, down);
- matrix.GetVnlMatrix().set_column(2, normal);
-
- PlaneGeometry::Pointer plane = PlaneGeometry::New();
- plane->GetIndexToWorldTransform()->SetMatrix(matrix);
- plane->SetOrigin(origin);
- plane->SetBounds(bounds);
-
- planes.push_back(plane);
-
- last = curr;
-}
-
-void mitk::PlanesPerpendicularToLinesFilter::GenerateData()
-{
- mitk::Mesh::ConstPointer input = this->GetInput();
- mitk::GeometryData::Pointer output = this->GetOutput();
-
- if(m_Plane.IsNotNull())
- {
- targetRight = m_Plane->GetMatrixColumn(0);
- targetSpacing = m_Plane->GetSpacing();
- bounds = m_Plane->GetBoundingBox()->GetBounds();
- halfWidthInMM = m_Plane->GetExtentInMM(0)*0.5;
- halfHeightInMM = m_Plane->GetExtentInMM(1)*0.5;
- }
- else
- {
- FillVector3D(targetRight, 1.0, 0.0, 0.0);
- targetSpacing.Fill(1.0);
- halfWidthInMM=halfHeightInMM=100.0;
- ScalarType stdBounds[6] = {0.0, 2.0*halfWidthInMM, 0.0, 2.0*halfHeightInMM, 0.0, 0.0};
- bounds = stdBounds;
- }
-
- if(m_UseAllPoints==false)
- {
- int i, size;
- //iterate through all cells and build planes
- Mesh::ConstCellIterator cellIt, cellEnd;
- cellEnd = input->GetMesh()->GetCells()->End();
- for( cellIt = input->GetMesh()->GetCells()->Begin(); cellIt != cellEnd; ++cellIt )
- {
- Mesh::CellType& cell = *cellIt->Value();
-
- Mesh::PointIdIterator ptIt, ptEnd;
- ptEnd = cell.PointIdsEnd();
-
- size=cell.GetNumberOfPoints();
- if(size<=1)
- continue;
-
- ptIt = cell.PointIdsBegin();
- last = input->GetPoint(*ptIt);
- ++ptIt;
- for(i=1;i<size;++i, ++ptIt)
- {
- CreatePlane(input->GetPoint(*ptIt));
- }
- }
- }
- else //m_UseAllPoints==true
- {
- //iterate through all points and build planes
- mitk::PointSet::PointsConstIterator it, pend = input->GetPointSet()->GetPoints()->End();
- it=input->GetPointSet()->GetPoints()->Begin();
- last = it.Value();
- ++it;
- for(;it!=pend;++it)
- {
- CreatePlane(it.Value());
- }
- }
-
- if(planes.size()>0)
- {
- //initialize sliced-geometry for the number of created planes
- m_CreatedGeometries->InitializeSlicedGeometry(planes.size()+1);
-
- //set last plane at last point with same normal as the one before the last
- PlaneGeometry::Pointer plane = static_cast<PlaneGeometry*>((*planes.rbegin())->Clone().GetPointer());
- itk2vtk(last.GetVnlVector()-right*halfWidthInMM-down*halfHeightInMM, origin);
- plane->SetOrigin(origin);
- m_CreatedGeometries->SetPlaneGeometry(plane, planes.size());
-
- //add all planes to sliced-geometry
- int s;
- for(s=0; planes.empty()==false; planes.pop_front(), ++s)
- {
- m_CreatedGeometries->SetPlaneGeometry(planes.front(), s);
- }
-
- m_CreatedGeometries->SetEvenlySpaced(false);
-
- if(m_FrameGeometry.IsNotNull())
- {
- m_CreatedGeometries->SetIndexToWorldTransform(m_FrameGeometry->GetIndexToWorldTransform());
- m_CreatedGeometries->SetBounds(m_FrameGeometry->GetBounds());
- m_CreatedGeometries->SetReferenceGeometry(m_FrameGeometry);
- }
- }
-
- output->SetGeometry(m_CreatedGeometries);
-}
-
-void mitk::PlanesPerpendicularToLinesFilter::SetPlane(const mitk::PlaneGeometry* aPlane)
-{
- if(aPlane!=NULL)
- {
- m_Plane = static_cast<mitk::PlaneGeometry*>(aPlane->Clone().GetPointer());
- }
- else
- {
- if(m_Plane.IsNull())
- return;
- m_Plane=NULL;
- }
- Modified();
-}
-
-const mitk::Mesh *mitk::PlanesPerpendicularToLinesFilter::GetInput(void)
-{
- if (this->GetNumberOfInputs() < 1)
- {
- return 0;
- }
-
- return static_cast<const mitk::Mesh * >
- (this->ProcessObject::GetInput(0) );
-}
-
-void mitk::PlanesPerpendicularToLinesFilter::SetInput(const mitk::Mesh *input)
-{
- // Process object is not const-correct so the const_cast is required here
- this->ProcessObject::SetNthInput(0,
- const_cast< mitk::Mesh * >( input ) );
-}
-
-void mitk::PlanesPerpendicularToLinesFilter::SetFrameGeometry(const mitk::BaseGeometry* frameGeometry)
-{
- if((frameGeometry != NULL) && (frameGeometry->IsValid()))
- {
- m_FrameGeometry = static_cast<mitk::BaseGeometry*>(frameGeometry->Clone().GetPointer());
- }
- else
- {
- m_FrameGeometry = NULL;
- }
-}
diff --git a/Modules/Ext/Algorithms/mitkPlanesPerpendicularToLinesFilter.h b/Modules/Ext/Algorithms/mitkPlanesPerpendicularToLinesFilter.h
deleted file mode 100644
index f213ea24e1..0000000000
--- a/Modules/Ext/Algorithms/mitkPlanesPerpendicularToLinesFilter.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKPLANESPERPENDICULARTOLINES_H_HEADER_INCLUDED_C10B22CD
-#define MITKPLANESPERPENDICULARTOLINES_H_HEADER_INCLUDED_C10B22CD
-
-#include "mitkGeometryDataSource.h"
-#include "MitkExtExports.h"
-#include "mitkMesh.h"
-#include "mitkGeometryData.h"
-#include "mitkPlaneGeometry.h"
-#include "mitkSlicedGeometry3D.h"
-
-namespace mitk {
-
-//##Documentation
-//## @brief Create Planes perpendicular to lines contained in a Mesh. The planes data is generated as one SlicedGeometry3D data.
-//## To create the planes as input a
-//## mitk::mesh (for example a pointSet) and as geometry hint a geometry (for example from the original image) must be given.
-//##
-//## mitk::Mesh::Pointer mesh = mitk::Mesh::New();
-//## mesh->SetMesh(pointSet->GetPointSet());
-//## mitk::Image* currentImage = dynamic_cast<mitk::Image*> (myDataStorage->GetNamedNode(IMAGE)->GetData());
-//## const mitk::Geometry3D* imagegeometry = currentImage->GetUpdatedGeometry();
-//## mitk::PlanesPerpendicularToLinesFilter::Pointer perpendicularPlanes = mitk::PlanesPerpendicularToLinesFilter::New();
-//## perpendicularPlanes->SetInput(mesh);
-//## perpendicularPlanes->SetUseAllPoints(true);
-//## perpendicularPlanes->SetFrameGeometry(imagegeometry);
-//## perpendicularPlanes->Update();
-//##
-//## To get one single plane out of these use SlicedGeometry3D->GetPlaneGeometry(int slicenumber).
-
-
-
-//## @ingroup Process
-class MitkExt_EXPORT PlanesPerpendicularToLinesFilter : public GeometryDataSource
-{
-public:
- mitkClassMacro(PlanesPerpendicularToLinesFilter, GeometryDataSource);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateData();
-
- const mitk::Mesh *GetInput(void);
-
- //## @brief Set the input mesh that is used to create the planes.
- virtual void SetInput(const mitk::Mesh *image);
-
- //##Documentation
- //## @brief Set plane to be used as an example of the planes to move
- //## along the lines in the input mesh.
- //##
- //## The size and spacing are copied from the plane. The in-plane
- //## orientation (right-vector) of the created planes are set as
- //## parallel as possible to the orientation (right-vector) of the
- //## the plane set using this method.
- //## @note The PlaneGeometry is cloned, @em not linked/referenced.
- virtual void SetPlane(const mitk::PlaneGeometry* aPlane);
-
- //##Documentation
- //## @brief Set if all points in the mesh should be interpreted as
- //## one long line.
- //##
- //## Cells are not used in this mode, but all points in the order
- //## of their indices form the line.
- //## Default is @a false.
- itkGetConstMacro(UseAllPoints, bool);
-
- //##Documentation
- //## @brief Set if all points of the mesh shall be used (true) or the cells (false)
- //## Default is @a false.
- itkSetMacro(UseAllPoints, bool);
- itkBooleanMacro(UseAllPoints);
-
- //##Documentation
- //## @brief Set an explicit frame of the created sliced geometry
- //##
- //## Set an explicit framegeometry for the created sliced geometry. This framegeometry is
- //## used as geometry for all created planes.
- //## Uses the IndexToWorldTransform and bounding box of the
- //## provided geometry.
- //## \sa CalculateFrameGeometry
- virtual void SetFrameGeometry(const mitk::BaseGeometry* frameGeometry);
-
-protected:
- PlanesPerpendicularToLinesFilter();
-
- virtual ~PlanesPerpendicularToLinesFilter();
-
- //## @brief Creates the plane at point curr
- //##
- //## Creates the plane at point curr. To create this plane, the last point must
- //## must be renowned.
- //## \sa SetPlane
- void CreatePlane(const Point3D& curr);
-
- //## @brief Plane to be used as an example of the planes to move
- //## along the lines in the input mesh.
- //##
- //## The size and spacing are copied from the m_Plane. The in-plane
- //## orientation (right-vector) of the created planes are set as
- //## parallel as possible to the orientation (right-vector) of m_Plane.
- //## \sa SetPlane
- mitk::PlaneGeometry::Pointer m_Plane;
-
- bool m_UseAllPoints;
-
- //##Documentation
- //## @brief SlicedGeometry3D containing the created planes
- //##
- SlicedGeometry3D::Pointer m_CreatedGeometries;
-
- mitk::BaseGeometry::Pointer m_FrameGeometry;
-
-private:
- std::deque<mitk::PlaneGeometry::Pointer> planes;
- Point3D last;
- VnlVector normal;
- VnlVector right, down;
- VnlVector targetRight;
- Vector3D targetSpacing;
- ScalarType halfWidthInMM, halfHeightInMM;
- mitk::BaseGeometry::BoundsArrayType bounds;
- Point3D origin;
-};
-
-} // namespace mitk
-
-#endif /* MITKPLANESPERPENDICULARTOLINES_H_HEADER_INCLUDED_C10B22CD */
diff --git a/Modules/Ext/Algorithms/mitkPointSetIndexToWorldTransformFilter.cpp b/Modules/Ext/Algorithms/mitkPointSetIndexToWorldTransformFilter.cpp
deleted file mode 100644
index 53625fea75..0000000000
--- a/Modules/Ext/Algorithms/mitkPointSetIndexToWorldTransformFilter.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPointSetIndexToWorldTransformFilter.h"
-
-
-mitk::PointSetIndexToWorldTransformFilter::PointSetIndexToWorldTransformFilter()
-{
-
-}
-
-mitk::PointSetIndexToWorldTransformFilter::~PointSetIndexToWorldTransformFilter()
-{
-
-}
-
-void mitk::PointSetIndexToWorldTransformFilter::GenerateData()
-{
- mitk::PointSet::ConstPointer input = this->GetInput();
- mitk::PointSet::Pointer output = this->GetOutput();
-
- typedef std::vector<mitk::Point3D> PointContainer;
- PointContainer points;
- int pointNo = 0;
-
- while(pointNo!= input->GetSize())
- {
- mitk::Point3D current = input->GetPoint(pointNo);
- points.push_back(current);
- pointNo++;
- }
- output->GetGeometry()->SetIdentity();
- PointContainer::iterator pointsIter = points.begin();
-
- pointNo = 0;
- while(pointsIter != points.end())
- {
- output->SetPoint(pointNo,(*pointsIter));
- pointNo++;
- pointsIter++;
- }
-
-}
diff --git a/Modules/Ext/Algorithms/mitkPointSetIndexToWorldTransformFilter.h b/Modules/Ext/Algorithms/mitkPointSetIndexToWorldTransformFilter.h
deleted file mode 100644
index acfb4cae60..0000000000
--- a/Modules/Ext/Algorithms/mitkPointSetIndexToWorldTransformFilter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITKPOINTSETINDEXTOWORLDTRANSFORMFILTER_H__
-#define _MITKPOINTSETINDEXTOWORLDTRANSFORMFILTER_H__
-
-#include "mitkPointSetToPointSetFilter.h"
-#include "mitkPointSet.h"
-
-#include "MitkExtExports.h"
-
-namespace mitk
-{
- //##Documentation
- //## @brief Transforms a point set object from index to world coordinates.
- //## Transposes the points coordinates with the object's mitk::Geometry3D to display
- //## correct scene coordinates.
- //##
- //## @ingroup Algorithms
-class MitkExt_EXPORT PointSetIndexToWorldTransformFilter : public PointSetToPointSetFilter
-{
-public:
- /**
- * Standard mitk class macro
- */
- mitkClassMacro ( PointSetIndexToWorldTransformFilter, PointSetToPointSetFilter );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
-protected:
-
- /**
- * Protected constructor. Use ::New instead()
- */
- PointSetIndexToWorldTransformFilter();
-
- /**
- * Protected destructor. Instances are destroyed when reference count is zero
- */
- virtual ~PointSetIndexToWorldTransformFilter();
- /**
- * method executed when calling Update();
- */
- virtual void GenerateData();
-
-};
-
-}
-
-#endif
diff --git a/Modules/Ext/Algorithms/mitkPointSetToCurvedGeometryFilter.cpp b/Modules/Ext/Algorithms/mitkPointSetToCurvedGeometryFilter.cpp
deleted file mode 100644
index 77c36f225c..0000000000
--- a/Modules/Ext/Algorithms/mitkPointSetToCurvedGeometryFilter.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPointSetToCurvedGeometryFilter.h"
-#include "mitkThinPlateSplineCurvedGeometry.h"
-#include "mitkPlaneGeometry.h"
-#include "mitkImage.h"
-#include "mitkDataNode.h"
-#include "mitkGeometryData.h"
-#include "mitkPlaneGeometryData.h"
-#include "mitkProperties.h"
-#include "itkMesh.h"
-#include "itkPointSet.h"
-
-mitk::PointSetToCurvedGeometryFilter::PointSetToCurvedGeometryFilter()
-{
- m_ProjectionMode = YZPlane;
- m_PCAPlaneCalculator = mitk::PlaneFit::New();
- m_ImageToBeMapped = NULL;
- m_Sigma = 1000;
- mitk::PlaneGeometryData::Pointer output = static_cast<mitk::PlaneGeometryData*> ( this->MakeOutput ( 0 ).GetPointer() );
- output->Initialize();
- Superclass::SetNumberOfRequiredOutputs ( 1 );
- Superclass::SetNthOutput ( 0, output.GetPointer() );
-}
-
-
-
-mitk::PointSetToCurvedGeometryFilter::~PointSetToCurvedGeometryFilter()
-{}
-
-void mitk::PointSetToCurvedGeometryFilter::GenerateOutputInformation()
-{
- mitk::PointSet::ConstPointer input = this->GetInput();
- mitk::PlaneGeometryData::Pointer output = dynamic_cast<mitk::PlaneGeometryData*> ( this->GetOutput() );
-
- if ( input.IsNull() )
- itkGenericExceptionMacro ( "Input point set is NULL!" );
-
- if ( input->GetTimeGeometry()->CountTimeSteps() != 1 )
- itkWarningMacro ( "More than one time step is not yet supported!" );
-
- if ( output.IsNull() )
- itkGenericExceptionMacro ( "Output is NULL!" );
-
- if ( m_ImageToBeMapped.IsNull() )
- itkGenericExceptionMacro ( "Image to be mapped is NULL!" );
-
- bool update = false;
- if ( output->GetGeometry() == NULL || output->GetPlaneGeometry() == NULL || output->GetTimeGeometry() == NULL )
- update = true;
- if ( ( ! update ) && ( output->GetTimeGeometry()->CountTimeSteps() != input->GetTimeGeometry()->CountTimeSteps() ) )
- update = true;
- if ( update )
- {
- mitk::ThinPlateSplineCurvedGeometry::Pointer curvedGeometry = mitk::ThinPlateSplineCurvedGeometry::New();
- output->SetGeometry(curvedGeometry);
- }
-}
-
-void mitk::PointSetToCurvedGeometryFilter::GenerateData()
-{
- mitk::PointSet::ConstPointer input = this->GetInput();
- mitk::GeometryData::Pointer output = this->GetOutput();
-
- //
- // check preconditions
- //
- if ( input.IsNull() )
- itkGenericExceptionMacro ( "Input point set is NULL!" );
- if ( output.IsNull() )
- itkGenericExceptionMacro ( "output geometry data is NULL!" );
- if ( output->GetTimeGeometry() == NULL )
- itkGenericExceptionMacro ( "Output time sliced geometry is NULL!" );
- if ( output->GetTimeGeometry()->GetGeometryForTimeStep ( 0 ).IsNull() )
- itkGenericExceptionMacro ( "Output geometry3d is NULL!" );
- mitk::ThinPlateSplineCurvedGeometry::Pointer curvedGeometry = dynamic_cast<mitk::ThinPlateSplineCurvedGeometry*> ( output->GetTimeGeometry()->GetGeometryForTimeStep( 0 ).GetPointer() );
- if ( curvedGeometry.IsNull() )
- itkGenericExceptionMacro ( "Output geometry3d is not an instance of mitk::ThinPlateSPlineCurvedGeometry!" );
- if ( m_ImageToBeMapped.IsNull() )
- itkGenericExceptionMacro ( "Image to be mapped is NULL!" );
-
- //
- // initialize members if needed
- //
- if ( m_XYPlane.IsNull() || m_XZPlane.IsNull() || m_YZPlane.IsNull() )
- {
- m_ImageToBeMapped->UpdateOutputInformation();
- const mitk::BaseGeometry* imageGeometry = m_ImageToBeMapped->GetUpdatedGeometry();
- imageGeometry = m_ImageToBeMapped->GetUpdatedGeometry();
- m_XYPlane = mitk::PlaneGeometry::New();
- m_XZPlane = mitk::PlaneGeometry::New();
- m_YZPlane = mitk::PlaneGeometry::New();
- m_XYPlane->InitializeStandardPlane ( imageGeometry, mitk::PlaneGeometry::Axial );
- m_YZPlane->InitializeStandardPlane ( imageGeometry, mitk::PlaneGeometry::Sagittal );
- m_XZPlane->InitializeStandardPlane ( imageGeometry, mitk::PlaneGeometry::Frontal );
- }
- if ( m_PlaneLandmarkProjector.IsNull() )
- {
- m_PlaneLandmarkProjector = mitk::PlaneLandmarkProjector::New();
- m_SphereLandmarkProjector = mitk::SphereLandmarkProjector::New();
- }
-
- //
- // set up geometry according to the current settings
- //
- if ( m_ProjectionMode == Sphere )
- {
- curvedGeometry->SetLandmarkProjector ( m_SphereLandmarkProjector );
- }
- else
- {
- if ( m_ProjectionMode == XYPlane )
- m_PlaneLandmarkProjector->SetProjectionPlane ( m_XYPlane );
- else if ( m_ProjectionMode == XZPlane )
- m_PlaneLandmarkProjector->SetProjectionPlane ( m_XZPlane );
- else if ( m_ProjectionMode == YZPlane )
- m_PlaneLandmarkProjector->SetProjectionPlane ( m_YZPlane );
- else if ( m_ProjectionMode == PCAPlane )
- {
- itkExceptionMacro ( "PCAPlane not yet implemented!" );
- m_PCAPlaneCalculator->SetInput ( input );
- m_PCAPlaneCalculator->Update();
-
- const PlaneGeometry *planarFigureGeometry =
- dynamic_cast< const PlaneGeometry * >( m_PCAPlaneCalculator->GetOutput() );
- const AbstractTransformGeometry *abstrTransfGeometry =
- dynamic_cast< const AbstractTransformGeometry * >( m_PCAPlaneCalculator->GetOutput() );
-
- if ( !planarFigureGeometry || abstrTransfGeometry )
- {
- m_PlaneLandmarkProjector->SetProjectionPlane ( NULL );
- }
- else
- {
- m_PlaneLandmarkProjector->SetProjectionPlane ( planarFigureGeometry );
- }
- }
- else
- itkExceptionMacro ( "Unknown projection mode" );
-
- curvedGeometry->SetLandmarkProjector ( m_PlaneLandmarkProjector );
- }
- //curvedGeometry->SetReferenceGeometry( m_ImageToBeMapped->GetGeometry() );
- curvedGeometry->SetTargetLandmarks ( input->GetPointSet ( 0 )->GetPoints() );
- curvedGeometry->SetSigma ( m_Sigma );
- curvedGeometry->ComputeGeometry();
- curvedGeometry->SetOversampling ( 1.0 );
-
-}
-
-
-void mitk::PointSetToCurvedGeometryFilter::SetDefaultCurvedGeometryProperties ( mitk::DataNode* node )
-{
- if ( node == NULL )
- {
- itkGenericOutputMacro ( "Warning: node is NULL!" );
- return;
- }
- node->SetIntProperty ( "xresolution", 50 );
- node->SetIntProperty ( "yresolution", 50 );
- node->SetProperty ( "name", mitk::StringProperty::New ( "Curved Plane" ) );
- // exclude extent of this plane when calculating DataStorage bounding box
- node->SetProperty ( "includeInBoundingBox", mitk::BoolProperty::New ( false ) );
-}
diff --git a/Modules/Ext/Algorithms/mitkPointSetToCurvedGeometryFilter.h b/Modules/Ext/Algorithms/mitkPointSetToCurvedGeometryFilter.h
deleted file mode 100644
index f91a52d5c7..0000000000
--- a/Modules/Ext/Algorithms/mitkPointSetToCurvedGeometryFilter.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_POINT_SET_TO_CURVED_GEOMETRY_FILTER_H__
-#define _MITK_POINT_SET_TO_CURVED_GEOMETRY_FILTER_H__
-
-#include "mitkPointSetToGeometryDataFilter.h"
-#include "MitkExtExports.h"
-#include <mitkPlaneGeometry.h>
-#include <mitkSphereLandmarkProjector.h>
-#include <mitkPlaneLandmarkProjector.h>
-#include <mitkPlaneFit.h>
-#include <mitkDataNode.h>
-#include <mitkImage.h>
-
-namespace mitk
-{
-
-class MitkExt_EXPORT PointSetToCurvedGeometryFilter : public PointSetToGeometryDataFilter
-{
-public:
- /**
- * Standard mitk class macro
- */
- mitkClassMacro ( PointSetToCurvedGeometryFilter, PointSetToGeometryDataFilter );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /**
- * Defines the geometry, onto which the input landmarks are
- * projected. Currently, Plane and Sphere are supported, whilest plane
- * is differentiated into 4 different planes, the xy, xz, and yz plane,
- * as well a plane which is calculated by a principal component analysis
- * of the input point set.
- */
- enum ProjectionMode {Sphere, XYPlane, XZPlane, YZPlane, PCAPlane};
-
- /**
- * Fills a data tree node with appropriate properties
- * for mapping the output geometry surface
- */
- static void SetDefaultCurvedGeometryProperties( mitk::DataNode* node );
-
- /**
- * Sets / Gets whether the input land marks are projected onto a plane
- * or sphere
- */
- itkSetMacro ( ProjectionMode, ProjectionMode );
-
- /**
- * Sets / Gets whether the input land marks are projected onto a plane
- * or sphere
- */
- itkGetMacro ( ProjectionMode, ProjectionMode );
-
- itkSetObjectMacro( ImageToBeMapped, mitk::Image );
- itkGetObjectMacro( ImageToBeMapped, mitk::Image );
-
- itkSetMacro( Sigma, float);
- itkGetMacro( Sigma, float);
-
-protected:
-
- /**
- * Protected constructor. Use ::New instead()
- */
- PointSetToCurvedGeometryFilter();
-
- /**
- * Protected destructor. Instances are destroyed when reference count is zero
- */
- virtual ~PointSetToCurvedGeometryFilter();
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateData();
-
- ProjectionMode m_ProjectionMode;
-
- mitk::PlaneGeometry::Pointer m_XYPlane;
-
- mitk::PlaneGeometry::Pointer m_XZPlane;
-
- mitk::PlaneGeometry::Pointer m_YZPlane;
-
- mitk::PlaneFit::Pointer m_PCAPlaneCalculator;
-
- mitk::Image::Pointer m_ImageToBeMapped;
-
- mitk::PlaneLandmarkProjector::Pointer m_PlaneLandmarkProjector;
-
- mitk::SphereLandmarkProjector::Pointer m_SphereLandmarkProjector;
-
- float m_Sigma;
-
-};
-
-}
-
-#endif
diff --git a/Modules/Ext/Algorithms/mitkPointSetToGeometryDataFilter.cpp b/Modules/Ext/Algorithms/mitkPointSetToGeometryDataFilter.cpp
deleted file mode 100644
index 609cd7d953..0000000000
--- a/Modules/Ext/Algorithms/mitkPointSetToGeometryDataFilter.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPointSetToGeometryDataFilter.h"
-#include <itkProcessObject.h>
-
-void mitk::PointSetToGeometryDataFilter::SetInput ( const mitk::PointSetToGeometryDataFilter::InputType* input )
-{
- this->SetInput( 0, input );
-}
-
-
-void mitk::PointSetToGeometryDataFilter::SetInput ( const unsigned int& idx, const mitk::PointSetToGeometryDataFilter::InputType* input )
-{
- if ( idx + 1 > this->GetNumberOfInputs() )
- {
- this->SetNumberOfRequiredInputs(idx + 1);
- }
- if ( input != static_cast<InputType*> ( this->ProcessObject::GetInput ( idx ) ) )
- {
- this->ProcessObject::SetNthInput ( idx, const_cast<InputType*> ( input ) );
- this->Modified();
- }
-}
-
-
-mitk::PointSetToGeometryDataFilter::InputType* mitk::PointSetToGeometryDataFilter::GetInput()
-{
- return this->GetInput( 0 );
-}
-
-
-mitk::PointSetToGeometryDataFilter::InputType* mitk::PointSetToGeometryDataFilter::GetInput ( const unsigned int& idx )
-{
- if ( this->GetNumberOfInputs() < 1 )
- return 0;
-
- return static_cast<InputType*> ( this->ProcessObject::GetInput ( idx ) );
-}
-
-
-mitk::PointSetToGeometryDataFilter::PointSetToGeometryDataFilter()
-{}
-
-mitk::PointSetToGeometryDataFilter::~PointSetToGeometryDataFilter()
-{}
-
diff --git a/Modules/Ext/Algorithms/mitkPointSetToGeometryDataFilter.h b/Modules/Ext/Algorithms/mitkPointSetToGeometryDataFilter.h
deleted file mode 100644
index 9145a196eb..0000000000
--- a/Modules/Ext/Algorithms/mitkPointSetToGeometryDataFilter.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _mitk_Point_Set_To_Geometry_Data_Filter__h_
-#define _mitk_Point_Set_To_Geometry_Data_Filter__h_
-
-#include <mitkPointSet.h>
-#include "MitkExtExports.h"
-#include <mitkGeometryDataSource.h>
-
-namespace mitk
-{
-
-/**
- * Common superclass for all algorithms having one or more point
- * sets as input and producing one or more geometry datas as output
- */
-class MitkExt_EXPORT PointSetToGeometryDataFilter : public GeometryDataSource
-{
-public:
- /**
- * Standard mitk class macro
- */
- mitkClassMacro( PointSetToGeometryDataFilter, GeometryDataSource );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /**
- * Common typdedefs for the input type and corresponding pointers
- */
- typedef mitk::PointSet InputType;
- typedef InputType::Pointer InputTypePointer;
- typedef InputType::ConstPointer InputTypeConstPointer;
-
- /**
- * Set and Get input methods.
- */
- virtual void SetInput( const InputType* input );
- virtual void SetInput( const unsigned int& idx, const InputType* input );
- virtual InputType* GetInput();
- virtual InputType* GetInput(const unsigned int& idx);
-
-protected:
-
- /**
- * Protected constructor. Use ::New instead()
- */
- PointSetToGeometryDataFilter();
-
- /**
- * Protected destructor. Instances are destroyed when reference count is zero
- */
- virtual ~PointSetToGeometryDataFilter();
-
-
-};
-
-} //end of namespace mitk
-
-
-#endif
-
-
diff --git a/Modules/Ext/Algorithms/mitkPolygonToRingFilter.cpp b/Modules/Ext/Algorithms/mitkPolygonToRingFilter.cpp
deleted file mode 100644
index 8fc7b9f744..0000000000
--- a/Modules/Ext/Algorithms/mitkPolygonToRingFilter.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPolygonToRingFilter.h"
-#include "mitkMesh.h"
-#include "mitkSurface.h"
-#include "mitkPlaneGeometry.h"
-
-#include <vnl/vnl_cross.h>
-#include <vnl/vnl_quaternion.h>
-#include <vnl/vnl_quaternion.txx>
-
-#include <vtkPolyData.h>
-#include <vtkPoints.h>
-#include <vtkCellArray.h>
-#include <vtkCardinalSpline.h>
-
-#include <vector>
-
-
-mitk::PolygonToRingFilter::PolygonToRingFilter()
-: m_RingRadius(3.5f), m_RingResolution(30), m_SplineResolution(20)
-{
- m_SplineX = vtkCardinalSpline::New();
- m_SplineY = vtkCardinalSpline::New();
- m_SplineZ = vtkCardinalSpline::New();
-}
-
-mitk::PolygonToRingFilter::~PolygonToRingFilter()
-{
- m_SplineX->Delete();
- m_SplineY->Delete();
- m_SplineZ->Delete();
-}
-
-void mitk::PolygonToRingFilter::GenerateOutputInformation()
-{
- mitk::Mesh::ConstPointer input = this->GetInput();
- mitk::Surface::Pointer output = this->GetOutput(0);
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-
- if(input.IsNull()) return;
-
- output->SetGeometry(static_cast<BaseGeometry*>(input->GetGeometry()->Clone().GetPointer()));
-
- output->Expand( input->GetPointSetSeriesSize() );
-}
-
-void mitk::PolygonToRingFilter::GenerateData()
-{
- mitk::Mesh::ConstPointer input = this->GetInput();
- mitk::Surface::Pointer output = this->GetOutput(0);
-
- unsigned int t;
- for ( t = 0; t < input->GetPointSetSeriesSize(); ++t )
- {
-
- vtkPolyData *polyData = vtkPolyData::New();
- vtkPoints *vPoints = vtkPoints::New();
- vtkCellArray *polys = vtkCellArray::New();
-
- mitk::Mesh::PointType thisPoint;
-
- // iterate through all cells and build tubes
- Mesh::ConstCellIterator cellIt, cellEnd;
- cellEnd = input->GetMesh( t )->GetCells()->End();
- for ( cellIt = input->GetMesh( t )->GetCells()->Begin();
- cellIt != cellEnd;
- ++cellIt )
- {
- m_PointList.clear();
- m_VectorList.clear();
-
- this->BuildPointAndVectorList(
- *cellIt->Value(), m_PointList, m_VectorList, t );
- this->BuildVtkTube( vPoints, polys, m_PointList, m_VectorList );
- }
-
- polyData->SetPoints( vPoints );
- vPoints->Delete();
- polyData->SetPolys( polys );
- polys->Delete();
-
- output->SetVtkPolyData( polyData, t );
- polyData->Delete();
-
- }
-
-}
-
-
-//sl: last star
-//sc: current star
-//idmax: Id of the current star ray (sc), which matchs proberly to the first ray of the last star (sl).
-//last_p: center of the last star
-//cur_p: center of the current star
-void mitk::PolygonToRingFilter::DrawCyl(vtkPoints *vPoints, vtkCellArray *polys,
- VectorListType &sl, VectorListType &sc, int idmax, Point3D & last_p, Point3D & cur_p)
-{
- unsigned int i;
- //now we finished:sl0 will be connected with sc->at(idmax)
- VectorListType::iterator slit=sl.begin(), scit=sc.begin(), scend=sc.end();
- scit+=idmax;
- Point3D a,b;
- Point3D a_first,b_first;
- int a_firstID = 0, b_firstID = 0;
-
- vtkIdType front[4];
- for(i=0;i<m_RingResolution;++i)
- {
- VnlVector v0,v1,v2,v3,normal;
- v0=a.GetVnlVector(); v1=b.GetVnlVector();
- a=last_p+*slit*m_RingRadius; b=cur_p+*scit*m_RingRadius;
- v2=b.GetVnlVector(); v3=a.GetVnlVector();
- normal=vnl_cross_3d(v1-v0,v3-v0);
-
- if(i!=0)
- {
- front[3]=vPoints->InsertNextPoint(v0[0],v0[1],v0[2]);
- front[2]=vPoints->InsertNextPoint(v1[0],v1[1],v1[2]);
- front[1]=vPoints->InsertNextPoint(v2[0],v2[1],v2[2]);
- front[0]=vPoints->InsertNextPoint(v3[0],v3[1],v3[2]);
- polys->InsertNextCell( (vtkIdType) 4, front );
- if(i==1)
- {
- a_firstID=front[3]; b_firstID=front[2]; //continue;
- }
- }
-
- ++slit; ++scit; if(scit==scend) scit=sc.begin();
- }
- front[3]=front[0];
- front[2]=front[1];
- front[1]=b_firstID;
- front[0]=a_firstID;
- polys->InsertNextCell( 4, front );
-}
-
-
-void mitk::PolygonToRingFilter::BuildVtkTube(vtkPoints *vPoints, vtkCellArray *polys, PointListType& ptList, VectorListType& vecList)
-{
- PointListType::iterator pit = ptList.begin(), pend = ptList.end();
- VectorListType::iterator vit = vecList.begin();
-
- Vector3D axis, last_v, next_v, s;
- Point3D cur_p,last_p;
-
- //lists for the star
- VectorListType *sl, *sc, *swp, sfirst, buf1, buf2;
- sl=&buf1; sc=&buf2;
-
- Vector3D a,b;
- Matrix3D m;
- //Initialization for the first point
- //alternative1:
- // last_v=*(vl.getLast()); next_v=*vit.current(); axis=last_v+next_v; s.cross(last_v,next_v); s.normalize();
- //alternative2:
- // last_v=*(vl.getLast()); next_v=*vit.current(); s.cross(last_v,next_v); s.normalize();
- // axis=next_v-last_v; axis.normalize(); aa.set(s, M_PI/2.0); m.set(aa); m.transform(&axis);
- //alternative3:
- last_v=vecList.back(); next_v=*vit; s.SetVnlVector( vnl_cross_3d(last_v.GetVnlVector(),next_v.GetVnlVector()) ); s.Normalize();
- a=last_v; b=next_v; a.Normalize(); b.Normalize(); axis=a+b; axis.Normalize();
-
- //build the star at the first point
- m = vnl_quaternion<mitk::ScalarType>(axis.GetVnlVector(),2*vnl_math::pi/(double)m_RingResolution).rotation_matrix_transpose();
- unsigned int i;
- for(i=0;i<m_RingResolution;++i)
- {
- sfirst.push_back(s);
- s=m*s;
- }
- *sl=sfirst;
- last_p=*pit;
- ++pit; ++vit;
-
- //mainloop for all points
- for ( ; pit != pend; ++pit, ++vit )
- {
- // cur_p=*pit.current(); last_v=next_v; next_v=*vit.current(); axis=last_v+next_v; s.cross(last_v,next_v); s.normalize();
- cur_p=*pit; last_v=next_v; next_v=*vit; s.SetVnlVector( vnl_cross_3d(last_v.GetVnlVector(),next_v.GetVnlVector()) ); s.Normalize();
- // axis=next_v-last_v; axis.normalize(); aa.set(s, M_PI/2.0); m.set(aa); m.transform(&axis);
- a=last_v; b=next_v; a.Normalize(); b.Normalize(); axis=a+b; axis.Normalize();
-
- //build new star sc(currentStar) during searching for a start point for the new star
- double max=0; int idmax=0; Vector3D sl0=*(sl->begin());
- m = vnl_quaternion<mitk::ScalarType>(axis.GetVnlVector(),2*vnl_math::pi/(double)m_RingResolution).rotation_matrix_transpose();
- for(i=0;i<m_RingResolution;++i)
- {
- sc->push_back(s);
- double tmp=s*sl0;
- if(tmp>max)
- {
- max=tmp;
- idmax=i;
- }
- s=m*s;
- }
-
- //sl: last star
- //sc: current star
- //idmax: Id of the current star ray (sc), which matchs proberly to the first ray of the last star (sl).
- //last_p: center of the last star
- //cur_p: center of the current star
- DrawCyl(vPoints, polys, *sl, *sc, idmax, last_p, cur_p);
-
- //Crossover to the next
- last_p=cur_p;
- swp=sl; sl=sc; sc=swp; sc->clear();
- }
-
- //calcutate idmax for connection:
- double max=0; int idmax=0; Vector3D sl0=*(sl->begin());
- for(i=0;i<m_RingResolution;++i)
- {
- s=sfirst[i];
- double tmp=s*sl0;
- if(tmp>max)
- {
- max=tmp;
- idmax=i;
- }
- }
- cur_p=*ptList.begin();
- DrawCyl(vPoints, polys, *sl, sfirst, idmax, last_p, cur_p);
-}
-
-void
-mitk::PolygonToRingFilter
-::BuildPointAndVectorList( mitk::Mesh::CellType& cell,
- PointListType& ptList, VectorListType& vecList, int timeStep )
-{
- // This method constructs a spline from the given point list and retrieves
- // a number of interpolated points from it to form a ring-like structure.
- //
- // To make the spline "closed", the end point is connected to the start
- // point. For ensuring smoothness at the start-end-point transition, the
- // (intrinsically non-circular) spline array is extended on both sides
- // by wrapping a number of points from the respective other side.
- //
- // The used VTK filters do principally support this kind of "closed" spline,
- // but it does not produce results as consistent as with the method used
- // here. Also, the spline class of VTK 4.4 has only poor support for
- // arbitrary parametric coordinates (t values in vtkSpline). VTK 5.0 has
- // better support, and also provides a new class vtkParametricSpline for
- // directly calculating 3D splines.
-
-
- // Remove points from previous call of this method
- m_SplineX->RemoveAllPoints();
- m_SplineY->RemoveAllPoints();
- m_SplineZ->RemoveAllPoints();
-
- int numberOfPoints = cell.GetNumberOfPoints();
-
- Mesh::PointType inputPoint;
- double t, tStart(0), tEnd(0);
-
- // Add input points to the spline and assign each the parametric value t
- // derived from the point euclidean distances.
- int i;
- Mesh::PointIdIterator pit = cell.PointIdsEnd() - 3;
- for ( i = -3, t = 0.0; i < numberOfPoints + 3; ++i )
- {
- if ( i == 0 ) { tStart = t; }
- if ( i == numberOfPoints ) { tEnd = t; }
-
- inputPoint = this->GetInput()->GetPoint( *pit, timeStep );
- m_SplineX->AddPoint( t, inputPoint[0] );
- m_SplineY->AddPoint( t, inputPoint[1] );
- m_SplineZ->AddPoint( t, inputPoint[2] );
-
- ++pit;
- if ( pit == cell.PointIdsEnd() )
- {
- pit = cell.PointIdsBegin();
- }
-
- t += inputPoint.EuclideanDistanceTo(
- this->GetInput()->GetPoint( *pit, timeStep ) );
- }
-
- // Evaluate the spline for the desired number of points
- // (number of input points) * (spline resolution)
- Point3D point, firstPoint, lastPoint;
- firstPoint.Fill(0);
- lastPoint.Fill(0);
- int numberOfSegments = numberOfPoints * m_SplineResolution;
- double step = (tEnd - tStart) / numberOfSegments;
- for ( i = 0, t = tStart; i < numberOfSegments; ++i, t += step )
- {
- FillVector3D( point,
- m_SplineX->Evaluate(t), m_SplineY->Evaluate(t), m_SplineZ->Evaluate(t)
- );
-
- ptList.push_back( point );
-
- if ( i == 0 )
- {
- firstPoint = point;
- }
- else
- {
- vecList.push_back( point - lastPoint );
- }
- lastPoint = point;
- }
- vecList.push_back( firstPoint - lastPoint );
-}
-
-
-const mitk::Mesh *mitk::PolygonToRingFilter::GetInput(void)
-{
- if (this->GetNumberOfInputs() < 1)
- {
- return 0;
- }
-
- return static_cast<const mitk::Mesh * >
- (this->ProcessObject::GetInput(0) );
-}
-
-void mitk::PolygonToRingFilter::SetInput(const mitk::Mesh *input)
-{
- // Process object is not const-correct so the const_cast is required here
- this->ProcessObject::SetNthInput(0,
- const_cast< mitk::Mesh * >( input ) );
-}
diff --git a/Modules/Ext/Algorithms/mitkPolygonToRingFilter.h b/Modules/Ext/Algorithms/mitkPolygonToRingFilter.h
deleted file mode 100644
index ad7391425f..0000000000
--- a/Modules/Ext/Algorithms/mitkPolygonToRingFilter.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKPOLYGONTORINGFILTER_H_HEADER_INCLUDED_C10B22CD
-#define MITKPOLYGONTORINGFILTER_H_HEADER_INCLUDED_C10B22CD
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkSurfaceSource.h"
-#include "mitkMesh.h"
-
-class vtkPolyData;
-class vtkPoints;
-class vtkCardinalSpline;
-class vtkPoints;
-class vtkCellArray;
-
-
-namespace mitk {
-
-/**
- * \brief Create ring around polygons contained in a Mesh
- * \ingroup Process
- */
-class MitkExt_EXPORT PolygonToRingFilter : public SurfaceSource
-{
-public:
- mitkClassMacro(PolygonToRingFilter, SurfaceSource);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual void GenerateOutputInformation();
-
- virtual void GenerateData();
-
- const mitk::Mesh *GetInput(void);
-
- virtual void SetInput(const mitk::Mesh *image);
-
- /** \brief Get ring radius */
- itkGetMacro(RingRadius, float);
-
- /* \brief Set ring radius */
- itkSetMacro(RingRadius, float);
-
- /** \brief Get ring resolution of created Surface */
- itkGetMacro(RingResolution, unsigned int);
-
- /** \brief Set ring resolution of created Surface */
- itkSetMacro(RingResolution, unsigned int);
-
- /** \brief Get spline resolution */
- itkGetMacro(SplineResolution, unsigned int);
-
- /** \brief Set spline resolution */
- itkSetMacro(SplineResolution, unsigned int);
-
-protected:
- typedef std::vector<Vector3D> VectorListType;
- typedef std::vector<Point3D> PointListType;
-
- PolygonToRingFilter();
-
- virtual ~PolygonToRingFilter();
-
- void BuildVtkTube( vtkPoints *vPoints, vtkCellArray *polys,
- PointListType& ptList, VectorListType& vecList );
- void BuildPointAndVectorList( mitk::Mesh::CellType& cell,
- PointListType& ptList, VectorListType& vecList, int timeStep = 0 );
- void DrawCyl(vtkPoints *vPoints, vtkCellArray *polys,
- VectorListType &sl, VectorListType &sc, int idmax,
- Point3D & last_p, Point3D & cur_p);
-
- /** \brief Ring radius */
- float m_RingRadius;
-
- /** \brief Ring resolution of created Surface */
- unsigned int m_RingResolution;
-
- /** \brief Spline resolution of created Surface */
- unsigned int m_SplineResolution;
-
- vtkCardinalSpline *m_SplineX, *m_SplineY, *m_SplineZ;
-
- PointListType m_PointList;
- VectorListType m_VectorList;
-};
-
-} // namespace mitk
-
-#endif /* MITKPOLYGONTORINGFILTER_H_HEADER_INCLUDED_C10B22CD */
diff --git a/Modules/Ext/Algorithms/mitkProbeFilter.cpp b/Modules/Ext/Algorithms/mitkProbeFilter.cpp
deleted file mode 100644
index 42a0b6e4a5..0000000000
--- a/Modules/Ext/Algorithms/mitkProbeFilter.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkProbeFilter.h"
-#include "mitkSurface.h"
-#include "mitkImage.h"
-
-#include <vtkProbeFilter.h>
-#include <itkImageRegion.h>
-#include <vtkDataSet.h>
-#include <vtkPolyData.h>
-#include <vtkImageData.h>
-
-mitk::ProbeFilter::ProbeFilter()
-{
-}
-
-mitk::ProbeFilter::~ProbeFilter()
-{
-}
-
-const mitk::Surface *mitk::ProbeFilter::GetInput(void)
-{
- if (this->GetNumberOfInputs() < 1)
- {
- return 0;
- }
- return static_cast< const mitk::Surface * >(this->ProcessObject::GetInput(0) );
-}
-
-const mitk::Image *mitk::ProbeFilter::GetSource(void)
-{
- return static_cast< const mitk::Image * >(this->ProcessObject::GetInput(1));
-}
-
-void mitk::ProbeFilter::SetInput(const mitk::Surface *input)
-{
- this->ProcessObject::SetNthInput( 0, const_cast< mitk::Surface * >( input ) );
-}
-
-void mitk::ProbeFilter::SetSource(const mitk::Image *source)
-{
- this->ProcessObject::SetNthInput( 1, const_cast< mitk::Image * >( source ) );
-}
-
-void mitk::ProbeFilter::GenerateOutputInformation()
-{
- mitk::Surface::ConstPointer input = this->GetInput();
- mitk::Image::ConstPointer source = this->GetSource();
- mitk::Surface::Pointer output = this->GetOutput();
-
- if(input.IsNull()) return;
- if(source.IsNull()) return;
-
- if(input->GetGeometry()==NULL) return;
- if(source->GetGeometry()==NULL) return;
-
- if( (input->GetTimeGeometry()->CountTimeSteps()==1) && (source->GetTimeGeometry()->CountTimeSteps()>1) )
- {
- Geometry3D::Pointer geo3D = Geometry3D::New();
- BaseGeometry::Pointer geometry3D = dynamic_cast<BaseGeometry*>(geo3D.GetPointer());
- geometry3D->Initialize();
- geometry3D->SetBounds(source->GetTimeGeometry()->GetBoundsInWorld());
-
- ProportionalTimeGeometry::Pointer outputTimeGeometry = ProportionalTimeGeometry::New();
- outputTimeGeometry->Initialize(geometry3D, source->GetTimeGeometry()->CountTimeSteps());
- outputTimeGeometry->SetFirstTimePoint(source->GetTimeGeometry()->GetMinimumTimePoint());
- TimePointType stepDuration = source->GetTimeGeometry()->GetMaximumTimePoint(0) - source->GetTimeGeometry()->GetMinimumTimePoint(0);
- outputTimeGeometry->SetStepDuration(stepDuration);
-
- output->Expand(outputTimeGeometry->CountTimeSteps());
- output->SetTimeGeometry( outputTimeGeometry );
- }
- else
- output->SetGeometry( static_cast<BaseGeometry*>(input->GetGeometry()->Clone().GetPointer()) );
-
- itkDebugMacro(<<"GenerateOutputInformation()");
-}
-
-void mitk::ProbeFilter::GenerateData()
-{
- mitk::Surface *input = const_cast< mitk::Surface * >(this->GetInput());
- mitk::Image *source = const_cast< mitk::Image * >(this->GetSource());
- mitk::Surface::Pointer output = this->GetOutput();
-
- itkDebugMacro(<<"Generating Data");
-
- if(output.IsNull())
- {
- itkDebugMacro(<<"Output is NULL.");
- return;
- }
-
- mitk::Surface::RegionType outputRegion = output->GetRequestedRegion();
- const TimeGeometry *outputTimeGeometry = output->GetTimeGeometry();
- const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry();
- const TimeGeometry *sourceTimeGeometry = source->GetTimeGeometry();
- TimePointType timeInMS;
- int timestep=0;
-
- int tstart, tmax;
-
- tstart=outputRegion.GetIndex(3);
- tmax=tstart+outputRegion.GetSize(3);
-
- int t;
- for(t=tstart;t<tmax;++t)
- {
- timeInMS = outputTimeGeometry->TimeStepToTimePoint( t );
-
- vtkProbeFilter* probe = vtkProbeFilter::New();
-
- timestep = inputTimeGeometry->TimePointToTimeStep( timeInMS );
- probe->SetInputData( input->GetVtkPolyData(timestep) );
-
- timestep = sourceTimeGeometry->TimePointToTimeStep( timeInMS );
- probe->SetSourceData( source->GetVtkImageData(timestep) );
-
- output->SetVtkPolyData( probe->GetPolyDataOutput(), t );
-
- probe->Update();
- probe->Delete();
- }
-}
-
-void mitk::ProbeFilter::GenerateInputRequestedRegion()
-{
- Superclass::GenerateInputRequestedRegion();
-
- mitk::Surface *input = const_cast< mitk::Surface * >( this->GetInput() );
- mitk::Image *source = const_cast< mitk::Image * >( this->GetSource() );
-
- if(input==NULL) return;
- if(source==NULL) return;
-
- mitk::Surface::Pointer output = this->GetOutput();
- mitk::Surface::RegionType outputRegion = output->GetRequestedRegion();
- const TimeGeometry *outputTimeGeometry = output->GetTimeGeometry();
-
- mitk::Surface::RegionType inputSurfaceRegion = outputRegion;
- Image::RegionType sourceImageRegion = source->GetLargestPossibleRegion();
-
- if(outputRegion.GetSize(3)<1)
- {
- mitk::Surface::RegionType::SizeType surfacesize;
- surfacesize.Fill(0);
- inputSurfaceRegion.SetSize(surfacesize);
- input->SetRequestedRegion( &inputSurfaceRegion );
- mitk::Image::RegionType::SizeType imagesize;
- imagesize.Fill(0);
- sourceImageRegion.SetSize(imagesize);
- source->SetRequestedRegion( &sourceImageRegion );
- return;
- }
-
- //create and set input requested region for the input surface
- const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry();
-
- ScalarType timeInMS;
- int timestep=0;
-
- // convert the start-index-time of output in start-index-time of input via millisecond-time
- timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3));
- timestep = inputTimeGeometry->TimePointToTimeStep( timeInMS );
- if( ( timeInMS > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() ) && ( inputTimeGeometry->IsValidTimeStep( timestep ) ) )
- inputSurfaceRegion.SetIndex( 3, timestep );
- else
- inputSurfaceRegion.SetIndex( 3, 0 );
- // convert the end-index-time of output in end-index-time of input via millisecond-time
- timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3)+outputRegion.GetSize(3)-1);
- timestep = inputTimeGeometry->TimePointToTimeStep( timeInMS );
- if( ( timeInMS > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() ) && ( outputTimeGeometry->IsValidTimeStep( timestep ) ) )
- inputSurfaceRegion.SetSize( 3, timestep - inputSurfaceRegion.GetIndex(3) + 1 );
- else
- inputSurfaceRegion.SetSize( 3, 1 );
-
- input->SetRequestedRegion( &inputSurfaceRegion );
-
- //create and set input requested region for the source image
- const TimeGeometry *sourceTimeGeometry = source->GetTimeGeometry();
-
- // convert the start-index-time of output in start-index-time of source via millisecond-time
- timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3));
- timestep = sourceTimeGeometry->TimePointToTimeStep( timeInMS );
- if( ( timeInMS > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() ) && ( sourceTimeGeometry->IsValidTimeStep( timestep ) ) )
- sourceImageRegion.SetIndex( 3, timestep );
- else
- sourceImageRegion.SetIndex( 3, 0 );
- // convert the end-index-time of output in end-index-time of source via millisecond-time
- timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3)+outputRegion.GetSize(3)-1);
- timestep = sourceTimeGeometry->TimePointToTimeStep( timeInMS );
- if( ( timeInMS > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() ) && ( outputTimeGeometry->IsValidTimeStep( timestep ) ) )
- sourceImageRegion.SetSize( 3, timestep - sourceImageRegion.GetIndex(3) + 1 );
- else
- sourceImageRegion.SetSize( 3, 1 );
-
- sourceImageRegion.SetIndex( 4, 0 );
- sourceImageRegion.SetSize( 4, 1 );
-
- source->SetRequestedRegion( &sourceImageRegion );
-}
diff --git a/Modules/Ext/Algorithms/mitkProbeFilter.h b/Modules/Ext/Algorithms/mitkProbeFilter.h
deleted file mode 100644
index afc111ffbb..0000000000
--- a/Modules/Ext/Algorithms/mitkProbeFilter.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKPROBEFILTER_H_HEADER_INCLUDED_C10B22CD
-#define MITKPROBEFILTER_H_HEADER_INCLUDED_C10B22CD
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkSurfaceSource.h"
-
-class vtkPlaneSource;
-class vtkTransformPolyDataFilter;
-class vtkDataSetToPolyDataFilter;
-
-namespace mitk {
-
-class Surface;
-class Image;
-
-//##Documentation
-//## @brief Adapter for vtkProbeFilter, making it a 3D+t filter
-//##
-//## @ingroup Process
-class MitkExt_EXPORT ProbeFilter : public SurfaceSource
-{
-public:
- mitkClassMacro(ProbeFilter, SurfaceSource);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual void GenerateOutputInformation();
- virtual void GenerateInputRequestedRegion();
- virtual void GenerateData();
-
- const mitk::Surface *GetInput(void);
- const mitk::Image *GetSource(void);
-
- virtual void SetInput(const mitk::Surface *input);
- virtual void SetSource(const mitk::Image *source);
-
-protected:
- ProbeFilter();
-
- virtual ~ProbeFilter();
-};
-
-} // namespace mitk
-
-#endif /* MITKPROBEFILTER_H_HEADER_INCLUDED_C10B22CD */
diff --git a/Modules/Ext/Algorithms/mitkSurfaceIndexToWorldTransformFilter.cpp b/Modules/Ext/Algorithms/mitkSurfaceIndexToWorldTransformFilter.cpp
deleted file mode 100644
index 28ee053ddc..0000000000
--- a/Modules/Ext/Algorithms/mitkSurfaceIndexToWorldTransformFilter.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkSurfaceIndexToWorldTransformFilter.h"
-
-#include "vtkPoints.h"
-#include "vtkPolyData.h"
-
-mitk::SurfaceIndexToWorldTransformFilter::SurfaceIndexToWorldTransformFilter()
-{
-}
-
-mitk::SurfaceIndexToWorldTransformFilter::~SurfaceIndexToWorldTransformFilter()
-{
-}
-
-void mitk::SurfaceIndexToWorldTransformFilter::GenerateData()
-{
- mitk::Surface* input = const_cast<mitk::Surface*>( this->GetInput());
- mitk::Surface::Pointer output = this->GetOutput();
-
- mitk::Point3D current, transformed;
- vtkPoints* surfacePoints = vtkPoints::New();
- vtkPoints* newSurfacePoints = vtkPoints::New();
- int pointIter = 0;
-
- surfacePoints = input->GetVtkPolyData()->GetPoints();
-
- while(pointIter != surfacePoints->GetNumberOfPoints())
- {
- double* intermed = surfacePoints->GetPoint(pointIter);
- current[0] = intermed[0];
- current[1] = intermed[1];
- current[2] = intermed[2];
-
- input->GetGeometry()->IndexToWorld(current, transformed);
- newSurfacePoints->InsertPoint( pointIter, transformed[0], transformed[1], transformed[2] );
- pointIter++;
- }
-
- output->GetVtkPolyData()->SetPoints(newSurfacePoints);
- output->GetVtkPolyData()->SetPolys(input->GetVtkPolyData()->GetPolys());
- output->GetGeometry()->SetIdentity();
- output->Modified();
- output->Update();
-}
-
-
diff --git a/Modules/Ext/Algorithms/mitkSurfaceIndexToWorldTransformFilter.h b/Modules/Ext/Algorithms/mitkSurfaceIndexToWorldTransformFilter.h
deleted file mode 100644
index 8a3d2c3324..0000000000
--- a/Modules/Ext/Algorithms/mitkSurfaceIndexToWorldTransformFilter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _mitkSurfaceIndexToWorldTransformFilter_h__
-#define _mitkSurfaceIndexToWorldTransformFilter_h__
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkSurfaceToSurfaceFilter.h"
-#include "mitkSurface.h"
-
-namespace mitk {
-
- //##Documentation
- //## @brief Transforms a surface object from index to world coordinates.
- //## Transposes the surface point coordinates with the object's mitk::Geometry3D to display
- //## correct scene coordinates.
- //##
- //## @ingroup Algorithms
-
- class MitkExt_EXPORT SurfaceIndexToWorldTransformFilter : public SurfaceToSurfaceFilter
-{
-public:
-
- /**
- * Standard mitk class macro
- */
- mitkClassMacro(SurfaceIndexToWorldTransformFilter, SurfaceToSurfaceFilter);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
-protected:
-
- /**
- * Protected constructor. Use ::New instead()
- */
- SurfaceIndexToWorldTransformFilter();
-
- /**
- * Protected destructor. Instances are destroyed when reference count is zero
- */
- virtual ~SurfaceIndexToWorldTransformFilter();
-
- /**
- * method executed when calling Update();
- */
- virtual void GenerateData();
-
-};
-
-} // namespace mitk
-
-#endif /* _mitkSurfaceIndexToWorldTransformFilter_h__*/
diff --git a/Modules/Ext/Algorithms/mitkUnstructuredGridHistogram.cpp b/Modules/Ext/Algorithms/mitkUnstructuredGridHistogram.cpp
deleted file mode 100644
index fd1ff53e1b..0000000000
--- a/Modules/Ext/Algorithms/mitkUnstructuredGridHistogram.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include <vtkUnstructuredGrid.h>
-
-#include <vtkPointData.h>
-#include <vtkCellData.h>
-#include <vtkIdList.h>
-
-#include "mitkUnstructuredGridHistogram.h"
-
-
-
-mitk::UnstructuredGridHistogram::~UnstructuredGridHistogram()
-{
-}
-
-void mitk::UnstructuredGridHistogram::Initialize(mitk::UnstructuredGrid* ugrid)
-{
-
- const int numBins = 20;
-
- vtkUnstructuredGrid* vtkUGrid = ugrid->GetVtkUnstructuredGrid();
-
- double* range = vtkUGrid->GetScalarRange();
-
- SizeType size;
- MeasurementVectorType lowerBound;
- MeasurementVectorType upperBound;
-
- size.Fill(numBins);
- lowerBound[0] = range[0];
- upperBound[0] = range[1];
- double length = upperBound[0] - lowerBound[0];
-
- this->Superclass::Initialize(size, lowerBound, upperBound);
-
- vtkDataArray* data;
- if (m_UsePointData) data = vtkUGrid->GetPointData()->GetScalars();
- else data = vtkUGrid->GetCellData()->GetScalars();
-
- if (data == 0) return;
-
- if (m_UsePointData)
- {
- vtkIdList* cellIds = vtkIdList::New();
- for (vtkIdType pointId = 0; pointId < vtkUGrid->GetNumberOfPoints(); pointId++) {
- vtkUGrid->GetPointCells(pointId, cellIds);
- double numIds = (double)cellIds->GetNumberOfIds();
- double scalar = data->GetComponent(pointId, 0);
- //MITK_INFO << "scalar value: " << scalar;
- int bin = numBins - 1;
- if (scalar != upperBound[0])
- bin = (int)(((double)numBins)*(scalar-lowerBound[0])/length);
- //MITK_INFO << " bin: " << bin << std::endl;
- this->IncreaseFrequency(bin, 1.0/(double)numIds);
- cellIds->Reset();
- }
- cellIds->Delete();
- }
- else
- {
- for (vtkIdType cellId = 0; cellId < vtkUGrid->GetNumberOfCells(); cellId++) {
- double scalar = data->GetComponent(cellId, 0);
- //MITK_INFO << "scalar value: " << scalar;
- int bin = numBins - 1;
- if (scalar != upperBound[0])
- bin = (int)(((double)numBins)*(scalar-lowerBound[0])/length);
- //MITK_INFO << " bin: " << bin << std::endl;
- this->IncreaseFrequency(bin, 1.0);
- }
- }
-}
diff --git a/Modules/Ext/Algorithms/mitkUnstructuredGridHistogram.h b/Modules/Ext/Algorithms/mitkUnstructuredGridHistogram.h
deleted file mode 100644
index 276f65e338..0000000000
--- a/Modules/Ext/Algorithms/mitkUnstructuredGridHistogram.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef UNSTRUCTURED_GIRD_HISTOGRAM_H_HEADER_INCLUDED
-#define UNSTRUCTURED_GIRD_HISTOGRAM_H_HEADER_INCLUDED
-
-#include <itkHistogram.h>
-#include "MitkExtExports.h"
-#include "mitkUnstructuredGrid.h"
-
-namespace mitk {
-
-//##Documentation
-//## @brief Subclass of itk::Histogram, specialized for a mitk::UnstructuredGrid
-//##
-class MitkExt_EXPORT UnstructuredGridHistogram : public itk::Statistics::Histogram<double>
-{
-public:
- mitkClassMacro(UnstructuredGridHistogram,itk::Statistics::Histogram<double>)
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- void Initialize(mitk::UnstructuredGrid*);
-
- void SetUsePointData() { m_UsePointData = true; }
- void SetUseCellData() { m_UsePointData = false; }
-
-protected:
- UnstructuredGridHistogram() : m_UsePointData(true) {}
-
- virtual ~UnstructuredGridHistogram();
-
- bool m_UsePointData;
-};
-
-} // namespace mitk
-
-#endif /* UNSTRUCTURED_GIRD_HISTOGRAM_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Algorithms/mitkVolumeVisualizationImagePreprocessor.cpp b/Modules/Ext/Algorithms/mitkVolumeVisualizationImagePreprocessor.cpp
deleted file mode 100644
index 13abc43f1f..0000000000
--- a/Modules/Ext/Algorithms/mitkVolumeVisualizationImagePreprocessor.cpp
+++ /dev/null
@@ -1,652 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkVolumeVisualizationImagePreprocessor.h"
-
-#include <itkOrImageFilter.h>
-#include <itkRegionOfInterestImageFilter.h>
-
-#include <mitkMemoryUtilities.h>
-
-#define VVP_INFO MITK_INFO << "Mem Usage: " << mitk::MemoryUtilities::GetProcessMemoryUsage() << " "
-
-namespace mitk
-{
-
-VolumeVisualizationImagePreprocessor::VolumeVisualizationImagePreprocessor()
-: m_OutOfLiverValue(-512),
- m_surfaceValue(-256),
- m_realSurfaceValue(0),
- m_EstimatedThreshold( 150.0 ),
- m_MinThreshold( 0.0 ),
- m_MaxThreshold( 250.0 )
-{
-}
-
-VolumeVisualizationImagePreprocessor::~VolumeVisualizationImagePreprocessor()
-{
-}
-
-
-
-TransferFunction::Pointer
-VolumeVisualizationImagePreprocessor::GetInitialTransferFunction( )
-{
- int treshold = m_EstimatedThreshold;
-
- double opacity = 0.005;
-
- double maskValue = m_OutOfLiverValue;
- double surfaceValue = m_surfaceValue;
- double realSurfaceValue = m_realSurfaceValue;
-
- //double surfaceSteepness = 0.0;
-
- VVP_INFO << "using threshold of " << treshold << " and opacity of " << opacity;
-
- TransferFunction::Pointer tf = TransferFunction::New();
-
- // grayvalue->opacity
- {
- vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
- f->RemoveAllPoints();
- f->AddPoint(maskValue,0);
- f->AddPoint(maskValue+1,0);
- f->AddPoint(surfaceValue,0.05);
- f->AddPoint(realSurfaceValue,opacity);
- f->AddPoint(treshold-1,opacity);
- f->AddPoint(treshold+4,0.8);
- f->AddPoint(m_MaxThreshold+1,0.8);
- f->ClampingOn();
- f->Modified();
- }
-
- // gradient at grayvalue->opacity
- {
- vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
- f->RemoveAllPoints();
- f->AddPoint( -1000.0, 1.0 );
- f->AddPoint( 1000, 1.0 );
- f->ClampingOn();
- f->Modified();
- }
-
- // grayvalue->color
- {
- vtkColorTransferFunction *ctf=tf->GetColorTransferFunction();
- ctf->RemoveAllPoints();
- ctf->AddRGBPoint( maskValue, 0.5, 0.0, 0.0 );
- ctf->AddRGBPoint( maskValue+1, 0.5, 0.0, 0.0 );
- ctf->AddRGBPoint( surfaceValue, 1.0, 0.0, 0.0 ); //0.5
- ctf->AddRGBPoint( realSurfaceValue, 0.2, 0.0, 0.0 );
-
- ctf->AddRGBPoint( treshold-32, 0.2, 0.0, 0.0 );
- ctf->AddRGBPoint( treshold, 251/255.0, 1.0, 0.0 );
- ctf->AddRGBPoint( m_MaxThreshold+1, 251/255.0, 1.0, 0.0 );
-
- ctf->ClampingOn();
- ctf->Modified();
- }
-
- m_LastUsedTreshold = treshold;
-
- return tf;
-}
-
-
-void VolumeVisualizationImagePreprocessor::UpdateTransferFunction( TransferFunction::Pointer tf, int treshold )
-{
- double opacity = 0.005;
-
- //double maskValue = m_OutOfLiverValue;
- //double surfaceValue = m_surfaceValue;
- //double realSurfaceValue = m_realSurfaceValue;
-
- //double surfaceSteepness = 0.0;
-
- //VVP_INFO << "changing to threshold of " << treshold << " and opacity of " << opacity;
-
- // grayvalue->opacity
- {
- vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
-
- f->RemovePoint( m_LastUsedTreshold-1 );
- f->AddPoint(treshold-1,opacity);
-
- f->RemovePoint( m_LastUsedTreshold+4 );
- f->AddPoint(treshold+4,0.8);
- }
-
- // grayvalue->color
- {
- vtkColorTransferFunction *ctf=tf->GetColorTransferFunction();
-
- ctf->RemovePoint( m_LastUsedTreshold-32 );
- ctf->AddRGBPoint( treshold-32, 0.2, 0.0, 0.0 );
-
- ctf->RemovePoint( m_LastUsedTreshold );
- ctf->AddRGBPoint( treshold, 251/255.0, 1.0, 0.0 );
- }
-
- m_LastUsedTreshold = treshold;
-}
-
-VolumeVisualizationImagePreprocessor::LabelImage::Pointer
-VolumeVisualizationImagePreprocessor::ConnectComponents(BinImage::Pointer src)
-{
- VVP_INFO << "Connect Components...";
-
- LabelImage::Pointer dst = LabelImage::New();
-
- typedef itk::ConnectedComponentImageFilter< BinImage, LabelImage > myFilterType;
-
- myFilterType::Pointer myFilter = myFilterType::New();
-
- myFilter->SetInput(src);
- myFilter->Update();
- dst = myFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-VolumeVisualizationImagePreprocessor::BinImage::Pointer
-VolumeVisualizationImagePreprocessor::Threshold(CTImage::Pointer src, int threshold)
-{
- VVP_INFO << "thresholding...";
-
- BinImage::Pointer dst = BinImage::New();
-
- typedef itk::ThresholdLabelerImageFilter< CTImage, BinImage > myFilterType;
-
- myFilterType::Pointer myFilter = myFilterType::New();
-
- myFilter->SetInput(src);
-
- myFilterType::ThresholdVector tv;
- tv.push_back(threshold);
- myFilter->SetThresholds(tv);
-
- myFilter->Update();
- dst = myFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-VolumeVisualizationImagePreprocessor::LabelImage::Pointer
-VolumeVisualizationImagePreprocessor::RelabelComponents(LabelImage::Pointer src)
-{
- VVP_INFO << "Relabeling Components...";
-
- LabelImage::Pointer dst = LabelImage::New();
-
- typedef itk::RelabelComponentImageFilter< LabelImage, LabelImage > myFilterType;
-
- myFilterType::Pointer myFilter = myFilterType::New();
-
- myFilter->SetInput(src);
- myFilter->Update();
- dst = myFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-VolumeVisualizationImagePreprocessor::BinImage::Pointer
-VolumeVisualizationImagePreprocessor::Dilate(BinImage::Pointer src)
-{
- VVP_INFO << "Dilating...";
-
- BinImage::Pointer dst = BinImage::New();
-
- typedef itk::BinaryDilateImageFilter< BinImage, BinImage,itk::BinaryBallStructuringElement< unsigned char, 3> > BinaryDilateImageType;
- BinaryDilateImageType::KernelType myKernel;
- myKernel.SetRadius(1);
- myKernel.CreateStructuringElement();
- BinaryDilateImageType::Pointer DilateFilter = BinaryDilateImageType::New();
- DilateFilter->SetInput(src);
- DilateFilter->SetKernel(myKernel);
- DilateFilter->SetDilateValue(1); //to be dilated to
- DilateFilter->Update();
- dst = DilateFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-VolumeVisualizationImagePreprocessor::BinImage::Pointer
-VolumeVisualizationImagePreprocessor::Erode(BinImage::Pointer src)
-{
- VVP_INFO << "Eroding...";
-
- BinImage::Pointer dst = BinImage::New();
-
- typedef itk::BinaryErodeImageFilter< BinImage, BinImage,itk::BinaryBallStructuringElement< unsigned char, 3> > BinaryErodeImageType;
- BinaryErodeImageType::KernelType myKernel;
- myKernel.SetRadius(1);
- myKernel.CreateStructuringElement();
- BinaryErodeImageType::Pointer ErodeFilter = BinaryErodeImageType::New();
- ErodeFilter->SetInput(src);
- ErodeFilter->SetKernel(myKernel);
- ErodeFilter->SetErodeValue(0); //to be Eroded to
- ErodeFilter->Update();
- dst = ErodeFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-
-VolumeVisualizationImagePreprocessor::CTImage::Pointer
-VolumeVisualizationImagePreprocessor::Gaussian(CTImage::Pointer src)
-{
- VVP_INFO << "Gaussian...";
-
- typedef itk::DiscreteGaussianImageFilter< CTImage, CTImage> GaussianFilterType;
-
- GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
- gaussianFilter->SetInput( src );
- gaussianFilter->SetVariance( 1 );
- // gaussianFilter->SetMaximumError( 0.1 );
-
- gaussianFilter->SetMaximumKernelWidth ( 8 );
- gaussianFilter->UpdateLargestPossibleRegion();
-
- CTImage::Pointer dst = gaussianFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-
-}
-
-VolumeVisualizationImagePreprocessor::CTImage::Pointer VolumeVisualizationImagePreprocessor::Crop(VolumeVisualizationImagePreprocessor::CTImage::Pointer src )
-{
- VVP_INFO << "Cropping 16bit...";
-
- typedef itk::RegionOfInterestImageFilter<CTImage,CTImage> FilterType;
-
- FilterType::Pointer cropFilter = FilterType::New();
-
- cropFilter->SetInput( src );
-
- CTImage::RegionType region;
- CTImage::SizeType size;
- CTImage::IndexType index;
-
- index.SetElement(0,m_MinX);
- index.SetElement(1,m_MinY);
- index.SetElement(2,m_MinZ);
-
- size.SetElement(0,m_MaxX-m_MinX+1);
- size.SetElement(1,m_MaxY-m_MinY+1);
- size.SetElement(2,m_MaxZ-m_MinZ+1);
-
- region.SetIndex(index);
- region.SetSize(size);
-
- cropFilter->SetRegionOfInterest(region);
- cropFilter->Update();
-
- CTImage::Pointer dst = cropFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-
-
-VolumeVisualizationImagePreprocessor::BinImage::Pointer VolumeVisualizationImagePreprocessor::Crop(VolumeVisualizationImagePreprocessor::BinImage::Pointer src )
-{
- VVP_INFO << "Cropping 8bit...";
-
- typedef itk::RegionOfInterestImageFilter<BinImage,BinImage> FilterType;
-
- FilterType::Pointer cropFilter = FilterType::New();
-
- cropFilter->SetInput( src );
-
- BinImage::RegionType region;
- BinImage::SizeType size;
- BinImage::IndexType index;
-
- index.SetElement(0,m_MinX);
- index.SetElement(1,m_MinY);
- index.SetElement(2,m_MinZ);
-
- size.SetElement(0,m_MaxX-m_MinX+1);
- size.SetElement(1,m_MaxY-m_MinY+1);
- size.SetElement(2,m_MaxZ-m_MinZ+1);
-
- region.SetIndex(index);
- region.SetSize(size);
-
- cropFilter->SetRegionOfInterest(region);
- cropFilter->Update();
-
- BinImage::Pointer dst = cropFilter->GetOutput();
- dst->DisconnectPipeline();
-
- return dst;
-}
-
-
-/*
- CTImage::Pointer CTImageWork = CTImage::New();
-CastToItkImage( imageOrg, CTImageWork );
-
-BinImage::Pointer BinImageMask = BinImage::New();
-CastToItkImage( imageMask, BinImageMask );
-
-BinImage::Pointer BinImageMaskDilate = BinImage::New();
-BinImage::Pointer BinImageMaskErode = BinImage::New();
-*/
-
-int mitk::VolumeVisualizationImagePreprocessor::GetHistogrammValueFromBottom( double part )
-{
- int unteren = total * part;
- for( int r = -32768 ; r <= 32767 ; r++ )
- if( (unteren -= histogramm[32768+(int)r]) <= 0 )
- return r;
- return 0; // will be never reached
-}
-
-
-int mitk::VolumeVisualizationImagePreprocessor::GetHistogrammValueFromTop( double part )
-{
- int oberen = total * part;
- for( int r = 32767 ; r >= -32768 ; r-- )
- if( (oberen -= histogramm[32768+(int)r]) <= 0 )
- return r;
- return 0; // will be never reached
-}
-
-
-void VolumeVisualizationImagePreprocessor::DetermineBoundingBox( BinImage::Pointer mask )
-{
- VVP_INFO << "determining Bounding Box...";
-
- BinIteratorIndexType maskIt( mask, mask->GetRequestedRegion() );
-
- maskIt.GoToBegin();
-
- int totalMinX;
- int totalMinY;
- int totalMinZ;
-
- int totalMaxX;
- int totalMaxY;
- int totalMaxZ;
-
- // Initialize Bounding Box
- {
- m_MinX=m_MinY=m_MinZ = 1000000;
- m_MaxX=m_MaxY=m_MaxZ = -1000000;
-
- totalMinX=totalMinY=totalMinZ = 1000000;
- totalMaxX=totalMaxY=totalMaxZ = -1000000;
- }
-
- while ( ! maskIt.IsAtEnd() )
- {
- BinIteratorIndexType::IndexType idx = maskIt.GetIndex();
- int x=idx.GetElement(0);
- int y=idx.GetElement(1);
- int z=idx.GetElement(2);
-
- if(x<totalMinX) totalMinX=x;
- if(y<totalMinY) totalMinY=y;
- if(z<totalMinZ) totalMinZ=z;
-
- if(x>totalMaxX) totalMaxX=x;
- if(y>totalMaxY) totalMaxY=y;
- if(z>totalMaxZ) totalMaxZ=z;
-
- if(maskIt.Get())
- {
- if(x<m_MinX) m_MinX=x;
- if(y<m_MinY) m_MinY=y;
- if(z<m_MinZ) m_MinZ=z;
-
- if(x>m_MaxX) m_MaxX=x;
- if(y>m_MaxY) m_MaxY=y;
- if(z>m_MaxZ) m_MaxZ=z;
- }
- ++maskIt;
- }
-
- int border = 3;
-
- m_MinX -= border; if(m_MinX < totalMinX ) m_MinX = totalMinX;
- m_MinY -= border; if(m_MinY < totalMinY ) m_MinY = totalMinY;
- m_MinZ -= border; if(m_MinZ < totalMinZ ) m_MinZ = totalMinZ;
-
- m_MaxX += border; if(m_MaxX > totalMaxX ) m_MaxX = totalMaxX;
- m_MaxY += border; if(m_MaxY > totalMaxY ) m_MaxY = totalMaxY;
- m_MaxZ += border; if(m_MaxZ > totalMaxZ ) m_MaxZ = totalMaxZ;
-
- VVP_INFO << "Bounding box" << " m_MinX: " << m_MinX << " m_MaxX: " << m_MaxX
- << "\n m_MinY: " << m_MinY << " m_MaxY: " << m_MaxY
- << "\n m_MinZ: " << m_MinZ << " m_MaxZ: " << m_MaxZ;
-
-
-}
-
-mitk::VolumeVisualizationImagePreprocessor::CTImage::Pointer VolumeVisualizationImagePreprocessor::Composite( CTImage::Pointer work,
- BinImage::Pointer mask,
- BinImage::Pointer dilated,
- BinImage::Pointer eroded)
-{
- VVP_INFO << "Compositing...";
-
- /*
- itk::OrImageFilter<CTImage, CTImage, CTImage>::Pointer nullFilter= itk::OrImageFilter<CTImage, CTImage, CTImage>::New();
- nullFilter->SetInput1( input );
- nullFilter->SetInput2( input );
- nullFilter->UpdateLargestPossibleRegion();
- CTImage::Pointer work = nullFilter->GetOutput();
- */
-
- CTIteratorIndexType workIt( work, work->GetRequestedRegion() );
- BinIteratorType maskIt( mask, mask->GetRequestedRegion() );
- BinIteratorType dilateIt( dilated, dilated->GetRequestedRegion() );
- BinIteratorType erodeIt( eroded, eroded->GetRequestedRegion() );
-
- workIt.GoToBegin();
- maskIt.GoToBegin();
- dilateIt.GoToBegin();
- erodeIt.GoToBegin();
-
- double sum=0;
- int num=0;
-
- double sumIn=0;
- int numIn=0;
-
- int _min=32767,_max=-32768;
-
- total=0;
- memset(histogramm,0,sizeof(int)*65536);
-
- while ( ! ( workIt.IsAtEnd() || maskIt.IsAtEnd() || dilateIt.IsAtEnd() || erodeIt.IsAtEnd() ) )
- {
- int value = workIt.Get();
- unsigned char mask = maskIt.Get();
- unsigned char dilate = dilateIt.Get();
- unsigned char erode = erodeIt.Get();
- //build barchart of internal of the liver
- if(mask != 0)
- {
- sumIn+=value;
- numIn++;
- histogramm[32768+(int)value]++;
- total++;
- }
- //average of the exterior layer
- if(erode != 0 && mask != 0 )
- {
- sum+=value;
- num++;
- if(value>_max) _max=value;
- if(value<_min) _min=value;
- }
-
- //mark the surface of the liver with -1024 and update bounding box
- if(erode == 0 && dilate != 0 )
- {
- value = -1024;
-
- }
- else if( erode != 0 && mask != 0 )//Keep the gray values of internal of the liver
- {
-
- }
- else//mark the exterior with -2048
- {
- value = -2048;
- }
-
- workIt.Set(value);
-
- ++workIt;
- ++maskIt;
- ++dilateIt;
- ++erodeIt;
- }
-
- VVP_INFO << "liver consists of " << total << " samples.";
-
- m_GreatestStructureThreshold = GetHistogrammValueFromTop(0.20);
- m_EstimatedThreshold = GetHistogrammValueFromTop(0.10);
- m_MaxThreshold=GetHistogrammValueFromTop(0.001);
- m_MinThreshold=GetHistogrammValueFromBottom(0.20);
-
- VVP_INFO << "threshold range: (" << m_MinThreshold << ";" << m_MaxThreshold << ") estimated vessel threshold: " << m_EstimatedThreshold ;
- VVP_INFO << "m_GreatestStructureThreshold: " << m_GreatestStructureThreshold;
-
-// BinImage::Pointer binImageThreshold= Threshold(work,m_GreatestStructureThreshold );
-// LabelImage::Pointer LabelImageunsorted=ConnectComponents(binImageThreshold);
-// LabelImage::Pointer LabelImageSorted= RelabelComponents(LabelImageunsorted);
-
-
- if(num>0)
- m_realSurfaceValue=sum/num;
- else
- m_realSurfaceValue=0;
-
- if(numIn>0)
- m_realInLiverValue=sumIn/numIn;
- else
- m_realInLiverValue=0;
-
- m_surfaceValue = _min - 40;
- m_OutOfLiverValue = m_surfaceValue - 40;
-
-// LabelIteratorType labelIt( LabelImageSorted, LabelImageSorted->GetRequestedRegion() );
-
- workIt.GoToBegin();
-// labelIt.GoToBegin();
-
- //int numGesetzt=0;
- //int numGelassen=0;
-
-
- while ( ! workIt.IsAtEnd() )
- {
- int value = workIt.Get();
-// int label = labelIt.Get();
-
- if(value == -1024 )
- {
- value = m_surfaceValue;
- }
- else if( value == -2048 )
- {
- value = m_OutOfLiverValue;
- }
- else
- {//In the space of the liver
- //Label unequal 1 --> set value on minimum
-/*
- if (label != 1){
- numGesetzt++;
- value=m_realInLiverValue;
- }
- else
- {
- //value=m_EstimatedThreshold;
- numGelassen++;
- }
- */
- }
-
- workIt.Set(value);
-
- ++workIt;
-// ++labelIt;
-
- }
-
- //VVP_INFO << "set: " << numGesetzt << " --- unvaried: " << numGelassen;
-
- VVP_INFO << "OutOfLiver value: " << m_OutOfLiverValue;
- VVP_INFO << "surface value: " << m_surfaceValue;
- VVP_INFO << "real surface value: " << m_realSurfaceValue;
- VVP_INFO << "real inLiver value:" << m_realInLiverValue;
-
- work->DisconnectPipeline();
-
- return work;
-}
-
-
-
-Image::Pointer
-VolumeVisualizationImagePreprocessor::Process(
- Image::Pointer m_originalCT, Image::Pointer m_originalLiverMask)
-{
- VVP_INFO << "Processing...";
-
- // converting mitk image -> itk image
- CTImage::Pointer CTImageWork = CTImage::New();
- CastToItkImage( m_originalCT, CTImageWork );
-
- // converting mitk image -> itk image
- BinImage::Pointer BinImageMask = BinImage::New();
- CastToItkImage( m_originalLiverMask, BinImageMask );
-
- DetermineBoundingBox( BinImageMask );
-
- if( m_MaxX < m_MinX
- || m_MaxY < m_MinY
- || m_MaxZ < m_MinZ )
- return 0;
-
- CTImageWork = Gaussian(Crop( CTImageWork ));
- BinImageMask = Crop( BinImageMask );
-
- CTImage::Pointer itkResult =Composite(CTImageWork,BinImageMask,Dilate(BinImageMask),Erode(BinImageMask));
-
- mitk::Image::Pointer mitkResult= mitk::Image::New();
- mitk::CastToMitkImage( itkResult, mitkResult ); //TODO here we can perhaps save memory
-
- VVP_INFO << "Finished...";
-
- return mitkResult;
-}
-
-}
diff --git a/Modules/Ext/Algorithms/mitkVolumeVisualizationImagePreprocessor.h b/Modules/Ext/Algorithms/mitkVolumeVisualizationImagePreprocessor.h
deleted file mode 100644
index a93b3edb53..0000000000
--- a/Modules/Ext/Algorithms/mitkVolumeVisualizationImagePreprocessor.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef mitkVolumeVisualizationImagePreprocessor_h_include
-#define mitkVolumeVisualizationImagePreprocessor_h_include
-
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-
-
-#include "mitkImageCast.h"
-#include "mitkITKImageImport.h"
-#include "mitkTransferFunctionProperty.h"
-
-#include <itkMedianImageFilter.h>
-#include "mitkMaskImageFilter.h"
-#include "mitkAutoCropImageFilter.h"
-#include "mitkSurface.h"
-
-#include <vtkContourFilter.h>
-#include <vtkImageChangeInformation.h>
-#include <vtkMatrix4x4.h>
-#include <vtkLinearTransform.h>
-#include <vtkDataObject.h>
-
-#include <itkDiscreteGaussianImageFilter.h>
-#include <itkConnectedComponentImageFilter.h>
-#include <itkRelabelComponentImageFilter.h>
-#include <itkThresholdLabelerImageFilter.h>
-#include <itkBinaryDilateImageFilter.h>
-#include <itkBinaryErodeImageFilter.h>
-#include <itkBinaryBallStructuringElement.h>
-
-#include <vtkSmoothPolyDataFilter.h>
-
-#include <vtkDecimatePro.h>
-#include <vtkQuadricDecimation.h>
-
-namespace mitk
-{
-
-class MitkExt_EXPORT VolumeVisualizationImagePreprocessor : public itk::Object
-{
-public:
-
- mitkClassMacro(VolumeVisualizationImagePreprocessor, itk::Object);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
-
- mitk::Image::Pointer Process( mitk::Image::Pointer originalCT,
- mitk::Image::Pointer originalLiverMask );
-
-
- double GetEstimatedThreshold() const
- {
- return m_EstimatedThreshold;
- }
-
- double GetMinThreshold() const
- {
- return m_MinThreshold;
- }
-
- double GetMaxThreshold() const
- {
- return m_MaxThreshold;
- }
-
- double GetLastUsedThreshold() const
- {
- return m_LastUsedTreshold;
- }
-
- mitk::TransferFunction::Pointer GetInitialTransferFunction( );
- void UpdateTransferFunction( mitk::TransferFunction::Pointer tf , int treshold );
-
-
-protected:
-
- typedef itk::Image<short, 3> CTImage;
- typedef itk::ImageRegionIterator< CTImage > CTIteratorType;
- typedef itk::ImageRegionIteratorWithIndex< CTImage > CTIteratorIndexType;
-
- typedef itk::Image<unsigned char, 3 > BinImage;
- typedef itk::ImageRegionIterator< BinImage > BinIteratorType;
- typedef itk::ImageRegionIteratorWithIndex< BinImage > BinIteratorIndexType;
-
- typedef itk::Image<unsigned short, 3 > LabelImage;
- typedef itk::ImageRegionIterator< LabelImage > LabelIteratorType;
-
-
- VolumeVisualizationImagePreprocessor();
-
- ~VolumeVisualizationImagePreprocessor();
-
-
- CTImage::Pointer Composite( CTImage::Pointer work,
- BinImage::Pointer mask,
- BinImage::Pointer dilated,
- BinImage::Pointer eroded );
-
-
- void DetermineBoundingBox( BinImage::Pointer mask );
-
- CTImage::Pointer Crop(CTImage::Pointer src );
- BinImage::Pointer Crop(BinImage::Pointer src );
-
-
-
-
- /**the original mask is decrease by 1 Voxel*/
- BinImage::Pointer Dilate(BinImage::Pointer src);
- BinImage::Pointer Erode(BinImage::Pointer src);
- CTImage::Pointer Gaussian(CTImage::Pointer src);
- LabelImage::Pointer ConnectComponents(BinImage::Pointer src);
- LabelImage::Pointer RelabelComponents(LabelImage::Pointer src);
- BinImage::Pointer Threshold(CTImage::Pointer src, int threshold);
-
-
-
-
- // grayvalue of voxel out of liver
- double m_OutOfLiverValue;
-
- // grayvalue liver surface will be set to
- double m_surfaceValue;
-
- // average of all grayvalues located on the liver surface
- double m_realSurfaceValue;
-
- double m_realInLiverValue;
-
- //estimated treshold value
- double m_EstimatedThreshold;
-
- double m_GreatestStructureThreshold;
-
-
- //minimum treshold value
- double m_MinThreshold;
-
- //maximum treshold value
- double m_MaxThreshold;
-
- int m_MinX;
- int m_MinY;
- int m_MinZ;
-
- int m_MaxX;
- int m_MaxY;
- int m_MaxZ;
-
- int m_LastUsedTreshold;
-
- int histogramm[65536];
- int total;
-
-
- int GetHistogrammValueFromTop( double part );
- int GetHistogrammValueFromBottom( double part );
-
-
-};
-
-
-}
-
-#endif // #define mitkVolumeVisualizationImagePreprocessor_h_include
diff --git a/Modules/Ext/Algorithms/mitkvtkImageStencilRaster.h b/Modules/Ext/Algorithms/mitkvtkImageStencilRaster.h
deleted file mode 100644
index 9e6ee0088b..0000000000
--- a/Modules/Ext/Algorithms/mitkvtkImageStencilRaster.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-/*=========================================================================
-
- Program: Visualization Toolkit
- Module: vtkImageStencilData.h
-
- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
- All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
-=========================================================================*/
-// .NAME vtkImageStencilData - efficient description of an image stencil
-// .SECTION Description
-// vtkImageStencilData describes an image stencil in a manner which is
-// efficient both in terms of speed and storage space. The stencil extents
-// are stored for each x-row across the image (multiple extents per row if
-// necessary) and can be retrieved via the GetNextExtent() method.
-// .SECTION see also
-// vtkImageStencilSource vtkImageStencil
-
-#ifndef __vtkImageStencilRaster_h
-#define __vtkImageStencilRaster_h
-
-#include "vtkImageStencilData.h"
-#include "vtkDataObject.h"
-#include "MitkExtExports.h"
-
-
-//BTX
-// Description:
-// This is a helper class for stencil creation. It is a raster with
-// infinite resolution in the X direction (approximately, since it uses
-// double precision). Lines that represent polygon edges can be drawn
-// into this raster, and then filled given a tolerance.
-class MitkExt_EXPORT vtkImageStencilRaster
-{
-public:
- // Description:
- // Create a raster with the specified whole y extent.
- vtkImageStencilRaster(const int wholeExtent[2]);
-
- // Description:
- // Destructor.
- ~vtkImageStencilRaster();
-
- // Description:
- // Reset the raster to its original state, but keep the same whole
- // extent. Pre-allocate the specified 1D allocateExtent, which must be
- // within the whole extent.
- void PrepareForNewData(const int allocateExtent[2] = 0);
-
- // Description:
- // Insert a line into the raster, given the two end points.
- // The "inflect1" and "inflect2" should be set if you want
- // to add a small vertical tolerance to either endpoints.
- void InsertLine(const double p1[2], const double p2[2],
- bool inflect1, bool inflect2);
-
- // Description:
- // Fill the specified extent of a vtkImageStencilData with the raster,
- // after permuting the raster according to xj and yj.
- void FillStencilData(vtkImageStencilData *data, const int extent[6],
- int xj = 0, int yj = 1);
-
- // Description:
- // The tolerance for float-to-int conversions.
- void SetTolerance(double tol) { this->Tolerance = tol; }
- double GetTolerance() { return this->Tolerance; }
-
-protected:
- // Description:
- // Ensure that the raster is initialized for the specified range
- // of y values, which must be within the Extent.
- void PrepareExtent(int ymin, int ymax);
-
- // Description:
- // Insert an x point into the raster. If the y value is larger
- // than the y extent, the extent will grow automatically.
- void InsertPoint(int y, double x);
-
- int Extent[2];
- int UsedExtent[2];
- double **Raster;
- double Tolerance;
-
-private:
- vtkImageStencilRaster(const vtkImageStencilRaster&); // Not implemented.
- void operator=(const vtkImageStencilRaster&); // Not implemented.
-};
-//ETX
-
-#endif
-
-
-
diff --git a/Modules/Ext/Algorithms/mitkvtkLassoStencilSource.h b/Modules/Ext/Algorithms/mitkvtkLassoStencilSource.h
deleted file mode 100644
index 89d70d21a1..0000000000
--- a/Modules/Ext/Algorithms/mitkvtkLassoStencilSource.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-/*=========================================================================
-
- Program: Visualization Toolkit
- Module: vtkLassoStencilSource.h
-
- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
- All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
-=========================================================================*/
-// .NAME vtkLassoStencilSource - Create a stencil from a contour
-// .SECTION Description
-// vtkLassoStencilSource will create an image stencil from a
-// set of points that define a contour. Its output can be
-// used with vtkImageStecil or other vtk classes that apply
-// a stencil to an image.
-// .SECTION See Also
-// vtkROIStencilSource vtkPolyDataToImageStencil
-// .SECTION Thanks
-// Thanks to David Gobbi for contributing this class to VTK.
-
-#ifndef __vtkLassoStencilSource_h
-#define __vtkLassoStencilSource_h
-
-
-#include "vtkImageStencilSource.h"
-#include "MitkExtExports.h"
-
-class vtkPoints;
-class vtkSpline;
-class vtkLSSPointMap;
-
-class MitkExt_EXPORT vtkLassoStencilSource : public vtkImageStencilSource
-{
-public:
- static vtkLassoStencilSource *New();
- vtkTypeMacro(vtkLassoStencilSource, vtkImageStencilSource);
- void PrintSelf(ostream& os, vtkIndent indent);
-
-//BTX
- enum {
- POLYGON = 0,
- SPLINE = 1,
- };
-//ETX
-
- // Description:
- // The shape to use, default is "Polygon". The spline is a
- // cardinal spline. Bezier splines are not yet supported.
- vtkGetMacro(Shape, int);
- vtkSetClampMacro(Shape, int, POLYGON, SPLINE);
- void SetShapeToPolygon() { this->SetShape(POLYGON); };
- void SetShapeToSpline() { this->SetShape(SPLINE); };
- virtual const char *GetShapeAsString();
-
- // Description:
- // The points that make up the lassoo. The loop does not
- // have to be closed, the last point will automatically be
- // connected to the first point by a straight line segment.
- virtual void SetPoints(vtkPoints *points);
- vtkGetObjectMacro(Points, vtkPoints);
-
- // Description:
- // The slice orientation. The default is 2, which is XY.
- // Other values are 0, which is YZ, and 1, which is XZ.
- vtkGetMacro(SliceOrientation, int);
- vtkSetClampMacro(SliceOrientation, int, 0, 2);
-
- // Description:
- // The points for a particular slice. This will override the
- // points that were set by calling SetPoints() for the slice.
- // To clear the setting, call SetSlicePoints(slice, NULL).
- virtual void SetSlicePoints(int i, vtkPoints *points);
- virtual vtkPoints *GetSlicePoints(int i);
-
- // Description:
- // Remove points from all slices.
- virtual void RemoveAllSlicePoints();
-
- // Description:
- // Overload GetMTime() to include the timestamp on the points.
- unsigned long GetMTime();
-
-protected:
- vtkLassoStencilSource();
- ~vtkLassoStencilSource();
-
- virtual int RequestData(vtkInformation *, vtkInformationVector **,
- vtkInformationVector *);
-
- int Shape;
- int SliceOrientation;
- vtkPoints *Points;
- vtkSpline *SplineX;
- vtkSpline *SplineY;
- vtkLSSPointMap *PointMap;
-
-private:
- vtkLassoStencilSource(const vtkLassoStencilSource&); // Not implemented.
- void operator=(const vtkLassoStencilSource&); // Not implemented.
-};
-
-#endif
diff --git a/Modules/Ext/Algorithms/vtkImageStencilRaster.cxx b/Modules/Ext/Algorithms/vtkImageStencilRaster.cxx
deleted file mode 100644
index 43d62a862c..0000000000
--- a/Modules/Ext/Algorithms/vtkImageStencilRaster.cxx
+++ /dev/null
@@ -1,453 +0,0 @@
-/*=========================================================================
-
- Program: Visualization Toolkit
- Module: vtkImageStencilData.cxx
-
- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
- All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
-=========================================================================*/
-
-#include "mitkvtkImageStencilRaster.h"
-
-#include "vtkImageStencilSource.h"
-#include "vtkInformation.h"
-#include "vtkInformationVector.h"
-#include "vtkDemandDrivenPipeline.h"
-#include "vtkDataSetAttributes.h"
-#include "vtkDataArray.h"
-#include "vtkObjectFactory.h"
-#include "vtkMath.h"
-
-#include <math.h>
-#include <vtkstd/algorithm>
-
-//----------------------------------------------------------------------------
-// tolerance for float-to-int conversion in stencil operations
-
-#define VTK_STENCIL_TOL 7.62939453125e-06
-
-//----------------------------------------------------------------------------
-vtkImageStencilRaster::vtkImageStencilRaster(const int extent[2])
-{
- int rsize = extent[1] - extent[0] + 1;
-
- // the "raster" is a sequence of pointer-pairs, where the first pointer
- // points to the first value in the raster line, and the second pointer
- // points to one location past the last vale in the raster line. The
- // difference is the number of x values stored in the raster line.
- this->Raster = new double*[2*static_cast<size_t>(rsize)];
-
- // the extent is the range of y values (one line per y)
- this->Extent[0] = extent[0];
- this->Extent[1] = extent[1];
-
- // tolerance should be larger than expected roundoff errors
- this->Tolerance = VTK_STENCIL_TOL;
-
- // no extent is used initially
- this->UsedExtent[0] = 0;
- this->UsedExtent[1] = -1;
-}
-
-//----------------------------------------------------------------------------
-vtkImageStencilRaster::~vtkImageStencilRaster()
-{
- if (this->UsedExtent[1] >= this->UsedExtent[0])
- {
- size_t i = 2*static_cast<size_t>(this->UsedExtent[0] - this->Extent[0]);
- size_t imax = 2*static_cast<size_t>(this->UsedExtent[1] - this->Extent[0]);
-
- do
- {
- if (this->Raster[i])
- {
- delete [] this->Raster[i];
- }
- i += 2;
- }
- while (i <= imax);
- }
- delete [] this->Raster;
-}
-
-//----------------------------------------------------------------------------
-void vtkImageStencilRaster::PrepareForNewData(const int allocateExtent[2])
-{
- if (this->UsedExtent[1] >= this->UsedExtent[0])
- {
- // reset and re-use the allocated raster lines
- size_t i = 2*static_cast<size_t>(this->UsedExtent[0]-this->Extent[0]);
- size_t imax=2*static_cast<size_t>(this->UsedExtent[1]-this->Extent[0]);
- do
- {
- this->Raster[i+1] = this->Raster[i];
- i += 2;
- }
- while (i <= imax);
- }
-
- if (allocateExtent && allocateExtent[1] >= allocateExtent[1])
- {
- this->PrepareExtent(allocateExtent[0], allocateExtent[1]);
- }
-}
-
-//----------------------------------------------------------------------------
-void vtkImageStencilRaster::PrepareExtent(int ymin, int ymax)
-{
- // this does not do any allocation, it just initializes any
- // raster lines are not already part of the UsedExtent, and
- // then expands the UsedExtent to include [ymin, ymax]
-
- if (this->UsedExtent[1] < this->UsedExtent[0])
- {
- size_t i = 2*static_cast<size_t>(ymin - this->Extent[0]);
- size_t imax = 2*static_cast<size_t>(ymax - this->Extent[0]);
-
- do
- {
- this->Raster[i] = 0;
- }
- while (++i <= imax);
-
- this->UsedExtent[0] = ymin;
- this->UsedExtent[1] = ymax;
-
- return;
- }
-
- if (ymin < this->UsedExtent[0])
- {
- size_t i = 2*static_cast<size_t>(ymin - this->Extent[0]);
- size_t imax = 2*static_cast<size_t>(this->UsedExtent[0]-this->Extent[0]-1);
-
- do
- {
- this->Raster[i] = 0;
- }
- while (++i <= imax);
-
- this->UsedExtent[0] = ymin;
- }
-
- if (ymax > this->UsedExtent[1])
- {
- size_t i = 2*static_cast<size_t>(this->UsedExtent[1]+1 - this->Extent[0]);
- size_t imax = 2*static_cast<size_t>(ymax - this->Extent[0]);
-
- do
- {
- this->Raster[i] = 0;
- }
- while (++i <= imax);
-
- this->UsedExtent[1] = ymax;
- }
-}
-
-//----------------------------------------------------------------------------
-void vtkImageStencilRaster::InsertPoint(int y, double x)
-{
- size_t pos = 2*static_cast<size_t>(y - this->Extent[0]);
- double* &rhead = this->Raster[pos];
- double* &rtail = this->Raster[pos+1];
-
- // current size is the diff between the tail and the head
- size_t n = rtail - rhead;
-
- // no allocation on this raster line yet
- if (rhead == 0)
- {
- rhead = new double[2];
- rtail = rhead;
- }
- // grow whenever size reaches a power of two
- else if (n > 1 && (n & (n-1)) == 0)
- {
- double *ptr = new double[2*n];
- for (size_t i = 0; i < n; i++)
- {
- ptr[i] = rhead[i];
- }
- delete [] rhead;
- rhead = ptr;
- rtail = ptr + n;
- }
-
- // insert the value
- *rtail++ = x;
-}
-
-//----------------------------------------------------------------------------
-void vtkImageStencilRaster::InsertLine(
- const double pt1[2], const double pt2[2],
- bool inflection1, bool inflection2)
-{
- double x1 = pt1[0];
- double x2 = pt2[0];
- double y1 = pt1[1];
- double y2 = pt2[1];
-
- // swap end points if necessary
- if (y1 > y2)
- {
- x1 = pt2[0];
- x2 = pt1[0];
- y1 = pt2[1];
- y2 = pt1[1];
- bool tmp = inflection1;
- inflection1 = inflection2;
- inflection2 = tmp;
- }
-
- // find min and max of x values
- double xmin = x1;
- double xmax = x2;
- if (x1 > x2)
- {
- xmin = x2;
- xmax = x1;
- }
-
- // check for parallel to the x-axis
- if (y1 == y2)
- {
- return;
- }
-
- double ymin = y1;
- double ymax = y2;
-
- // if an end is an inflection point, include a tolerance
- ymin -= inflection1*this->Tolerance;
- ymax += inflection2*this->Tolerance;
-
- // Integer y values for start and end of line
- int iy1, iy2;
- iy1 = this->Extent[0];
- iy2 = this->Extent[1];
-
- // Check for out of bounds
- if (ymax < iy1 || ymin >= iy2)
- {
- return;
- }
-
- // Guard against extentY
- if (ymin >= iy1)
- {
- iy1 = vtkMath::Floor(ymin) + 1;
- }
- if (ymax < iy2)
- {
- iy2 = vtkMath::Floor(ymax);
- }
-
- // Expand allocated extent if necessary
- if (iy1 < this->UsedExtent[0] ||
- iy2 > this->UsedExtent[1])
- {
- this->PrepareExtent(iy1, iy2);
- }
-
- // Precompute values for a Bresenham-like line algorithm
- double grad = (x2 - x1)/(y2 - y1);
- double delta = (iy1 - y1)*grad;
-
- // Go along y and place each x in the proper raster line
- for (int y = iy1; y <= iy2; y++)
- {
- double x = x1 + delta;
- // incrementing delta has less roundoff error than incrementing x,
- // since delta will typically be smaller than x
- delta += grad;
-
- // clamp x (because of tolerance, it might not be in range)
- if (x < xmin)
- {
- x = xmin;
- }
- else if (x > xmax)
- {
- x = xmax;
- }
-
- this->InsertPoint(y, x);
- }
-}
-
-//----------------------------------------------------------------------------
-void vtkImageStencilRaster::FillStencilData(
- vtkImageStencilData *data, const int extent[6], int xj, int yj)
-{
- if (xj != 0)
- {
- // slices are stacked in the x direction
- int xmin = extent[2*xj];
- int xmax = extent[2*xj+1];
- int ymin = this->UsedExtent[0];
- int ymax = this->UsedExtent[1];
- int zmin = extent[0];
- int zmax = extent[1];
-
- for (int idY = ymin; idY <= ymax; idY++)
- {
- size_t pos = 2*static_cast<size_t>(idY - this->Extent[0]);
- double *rline = this->Raster[pos];
- double *rlineEnd = this->Raster[pos+1];
-
- if (rline == 0)
- {
- continue;
- }
-
- vtkstd::sort(rline, rlineEnd);
-
- int xy[2];
- xy[2-xj] = idY;
-
- int lastr = VTK_INT_MIN;
-
- size_t l = rlineEnd - rline;
- l = l - (l & 1); // force l to be an even number
- for (size_t k = 0; k < l; k += 2)
- {
- double x1 = rline[k] - this->Tolerance;
- double x2 = rline[k+1] + this->Tolerance;
-
- // make sure one of the ends is in bounds
- if (x2 < xmin || x1 >= xmax)
- {
- continue;
- }
-
- // clip the line segment with the bounds
- int r1 = xmin;
- int r2 = xmax;
-
- if (x1 >= xmin)
- {
- r1 = vtkMath::Floor(x1) + 1;
- }
- if (x2 < xmax)
- {
- r2 = vtkMath::Floor(x2);
- }
-
- // ensure no overlap occurs with previous
- if (r1 <= lastr)
- {
- r1 = lastr + 1;
- }
- lastr = r2;
-
- for (int idX = r1; idX <= r2; idX++)
- {
- xy[xj-1] = idX;
- data->InsertNextExtent(zmin, zmax, xy[0], xy[1]);
- }
- }
- }
- }
- else
- {
- // slices stacked in the y or z direction
- int zj = 3 - yj;
- int xmin = extent[0];
- int xmax = extent[1];
- int ymin = this->UsedExtent[0];
- int ymax = this->UsedExtent[1];
- int zmin = extent[2*zj];
- int zmax = extent[2*zj+1];
-
- // convert each raster line into extents for the stencil
- for (int idY = ymin; idY <= ymax; idY++)
- {
- size_t pos = 2*static_cast<size_t>(idY - this->Extent[0]);
- double *rline = this->Raster[pos];
- double *rlineEnd = this->Raster[pos+1];
-
- if (rline == 0)
- {
- continue;
- }
-
- vtkstd::sort(rline, rlineEnd);
-
- int lastr = VTK_INT_MIN;
-
- // go through each raster line and fill the stencil
- size_t l = rlineEnd - rline;
- l = l - (l & 1); // force l to be an even number
- for (size_t k = 0; k < l; k += 2)
- {
- int yz[2];
-
- yz[yj-1] = idY;
- yz[2-yj] = zmin;
-
- double x1 = rline[k] - this->Tolerance;
- double x2 = rline[k+1] + this->Tolerance;
-
- if (x2 < xmin || x1 >= xmax)
- {
- continue;
- }
-
- int r1 = xmin;
- int r2 = xmax;
-
- if (x1 >= xmin)
- {
- r1 = vtkMath::Floor(x1) + 1;
- }
- if (x2 < xmax)
- {
- r2 = vtkMath::Floor(x2);
- }
-
- // ensure no overlap occurs between extents
- if (r1 <= lastr)
- {
- r1 = lastr + 1;
- }
- lastr = r2;
-
- if (r2 >= r1)
- {
- data->InsertNextExtent(r1, r2, yz[0], yz[1]);
- }
- }
- }
-
- // copy the result to all other slices
- if (zmin < zmax)
- {
- for (int idY = ymin; idY <= ymax; idY++)
- {
- int r1, r2;
- int yz[2];
-
- yz[yj-1] = idY;
- yz[2-yj] = zmin;
-
- int iter = 0;
- while (data->GetNextExtent(r1, r2, xmin, xmax, yz[0], yz[1], iter))
- {
- for (int idZ = zmin + 1; idZ <= zmax; idZ++)
- {
- yz[2-yj] = idZ;
- data->InsertNextExtent(r1, r2, yz[0], yz[1]);
- }
- yz[2-yj] = zmin;
- }
- }
- }
- }
-}
diff --git a/Modules/Ext/Algorithms/vtkLassoStencilSource.cxx b/Modules/Ext/Algorithms/vtkLassoStencilSource.cxx
deleted file mode 100644
index e86d4ad535..0000000000
--- a/Modules/Ext/Algorithms/vtkLassoStencilSource.cxx
+++ /dev/null
@@ -1,610 +0,0 @@
-/*=========================================================================
-
- Program: Visualization Toolkit
- Module: vtkLassoStencilSource.cxx
-
- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
- All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
-=========================================================================*/
-
-#include "mitkvtkLassoStencilSource.h"
-
-#include "vtkMath.h"
-#include "vtkPoints.h"
-#include "vtkCardinalSpline.h"
-#include "vtkDataArray.h"
-#include "vtkImageData.h"
-#include "vtkImageStencilData.h"
-#include "vtkInformation.h"
-#include "vtkInformationVector.h"
-#include "vtkObjectFactory.h"
-#include "vtkStreamingDemandDrivenPipeline.h"
-#include "vtkSmartPointer.h"
-
-#include "mitkvtkImageStencilRaster.h"
-
-#include <math.h>
-#include <vtkstd/map>
-
-vtkStandardNewMacro(vtkLassoStencilSource);
-vtkCxxSetObjectMacro(vtkLassoStencilSource, Points, vtkPoints);
-
-//----------------------------------------------------------------------------
-class vtkLSSPointMap : public vtkstd::map<int, vtkSmartPointer<vtkPoints> >
-{
-};
-
-//----------------------------------------------------------------------------
-vtkLassoStencilSource::vtkLassoStencilSource()
-{
- this->SetNumberOfInputPorts(0);
-
- this->Shape = vtkLassoStencilSource::POLYGON;
- this->SliceOrientation = 2;
- this->Points = NULL;
- this->SplineX = vtkCardinalSpline::New();
- this->SplineY = vtkCardinalSpline::New();
-
- this->PointMap = new vtkLSSPointMap();
-}
-
-//----------------------------------------------------------------------------
-vtkLassoStencilSource::~vtkLassoStencilSource()
-{
- this->SetPoints(NULL);
- if (this->SplineX)
- {
- this->SplineX->Delete();
- this->SplineX = NULL;
- }
- if (this->SplineY)
- {
- this->SplineY->Delete();
- this->SplineY = NULL;
- }
- if (this->PointMap)
- {
- delete this->PointMap;
- this->PointMap = NULL;
- }
-}
-
-//----------------------------------------------------------------------------
-void vtkLassoStencilSource::PrintSelf(ostream& os, vtkIndent indent)
-{
- this->Superclass::PrintSelf(os,indent);
-
- os << indent << "Shape: " << this->GetShapeAsString() << "\n";
- os << indent << "Points: " << this->Points << "\n";
- os << indent << "SliceOrientation: " << this->GetSliceOrientation() << "\n";
- os << indent << "SlicePoints: " << this->PointMap->size() << "\n";
-}
-
-//----------------------------------------------------------------------------
-const char *vtkLassoStencilSource::GetShapeAsString()
-{
- switch (this->Shape)
- {
- case vtkLassoStencilSource::POLYGON:
- return "Polygon";
- case vtkLassoStencilSource::SPLINE:
- return "Spline";
- }
- return "";
-}
-
-//----------------------------------------------------------------------------
-unsigned long int vtkLassoStencilSource::GetMTime()
-{
- unsigned long mTime = this->vtkImageStencilSource::GetMTime();
-
- if ( this->Points != NULL )
- {
- unsigned long t = this->Points->GetMTime();
- if (t > mTime)
- {
- mTime = t;
- }
- }
-
- if ( !this->PointMap->empty() )
- {
- vtkLSSPointMap::iterator iter = this->PointMap->begin();
- while ( iter != this->PointMap->end() )
- {
- unsigned long t = iter->second->GetMTime();
- if (t > mTime)
- {
- mTime = t;
- }
- iter++;
- }
- }
-
- return mTime;
-}
-
-//----------------------------------------------------------------------------
-void vtkLassoStencilSource::SetSlicePoints(int i, vtkPoints *points)
-{
- vtkLSSPointMap::iterator iter = this->PointMap->find(i);
- if (iter != this->PointMap->end())
- {
- if (iter->second == points)
- {
- return;
- }
- else if (points == 0)
- {
- this->PointMap->erase(iter);
- }
- else
- {
- iter->second = points;
- }
- }
- else
- {
- if (points == NULL)
- {
- return;
- }
- else
- {
- this->PointMap->insert(iter, vtkLSSPointMap::value_type(i, points));
- }
- }
-
- this->Modified();
-}
-
-//----------------------------------------------------------------------------
-void vtkLassoStencilSource::RemoveAllSlicePoints()
-{
- this->PointMap->clear();
-}
-
-//----------------------------------------------------------------------------
-vtkPoints *vtkLassoStencilSource::GetSlicePoints(int i)
-{
- vtkLSSPointMap::iterator iter = this->PointMap->find(i);
- if (iter != this->PointMap->end())
- {
- return iter->second;
- }
- return NULL;
-}
-
-//----------------------------------------------------------------------------
-// tolerance for stencil operations
-
-#define VTK_STENCIL_TOL 7.62939453125e-06
-
-//----------------------------------------------------------------------------
-// Compute a reduced extent based on the bounds of the shape.
-static void vtkLassoStencilSourceSubExtent(
- vtkPoints *points,
- const double origin[3], const double spacing[3],
- const int extent[6], int subextent[6])
-{
- double bounds[6];
- points->GetBounds(bounds);
-
- for (int i = 0; i < 3; i++)
- {
- double emin = (bounds[2*i] - origin[i])/spacing[i] - VTK_STENCIL_TOL;
- double emax = (bounds[2*i+1] - origin[i])/spacing[i] + VTK_STENCIL_TOL;
-
- subextent[2*i] = extent[2*i];
- subextent[2*i+1] = extent[2*i+1];
-
- if (extent[2*i] < emin)
- {
- subextent[2*i] = VTK_INT_MAX;
- if (extent[2*i+1] >= emin)
- {
- subextent[2*i] = vtkMath::Floor(emin) + 1;
- }
- }
-
- if (extent[2*i+1] > emax)
- {
- subextent[2*i+1] = VTK_INT_MIN;
- if (extent[2*i] <= emax)
- {
- subextent[2*i+1] = vtkMath::Floor(emax);
- }
- }
-
- }
-}
-
-//----------------------------------------------------------------------------
-// Rasterize a polygon into the stencil
-static int vtkLassoStencilSourcePolygon(
- vtkPoints *points, vtkImageStencilData *data, vtkImageStencilRaster *raster,
- const int extent[6], const double origin[3], const double spacing[3],
- int xj, int yj)
-{
- // get the bounds of the polygon
- int subextent[6];
- vtkLassoStencilSourceSubExtent(points, origin, spacing, extent, subextent);
-
- // allocate the raster
- raster->PrepareForNewData(&subextent[2*yj]);
-
- // rasterize each line
- vtkIdType n = points->GetNumberOfPoints();
- double p[3];
- double p0[2], p1[2], p2[2], p3[2];
-
- points->GetPoint(n-1, p);
- p0[0] = (p[xj] - origin[xj])/spacing[xj];
- p0[1] = (p[yj] - origin[yj])/spacing[yj];
-
- points->GetPoint(0, p);
- p1[0] = (p[xj] - origin[xj])/spacing[xj];
- p1[1] = (p[yj] - origin[yj])/spacing[yj];
-
- double dx = p1[0] - p0[0];
- double dy = p1[1] - p0[1];
- if (dx*dx + dy*dy <= VTK_STENCIL_TOL*VTK_STENCIL_TOL)
- {
- n -= 1;
- points->GetPoint(n-1, p);
- p0[0] = (p[xj] - origin[xj])/spacing[xj];
- p0[1] = (p[yj] - origin[yj])/spacing[yj];
- }
-
- points->GetPoint(1, p);
- p2[0] = (p[xj] - origin[xj])/spacing[xj];
- p2[1] = (p[yj] - origin[yj])/spacing[yj];
-
- // inflection means the line changes vertical direction
- bool inflection1, inflection2;
- inflection1 = ( (p1[1] - p0[1])*(p2[1] - p1[1]) <= 0 );
-
- for (vtkIdType i = 0; i < n; i++)
- {
- points->GetPoint((i+2)%n, p);
- p3[0] = (p[xj] - origin[xj])/spacing[xj];
- p3[1] = (p[yj] - origin[yj])/spacing[yj];
-
- inflection2 = ( (p2[1] - p1[1])*(p3[1] - p2[1]) <= 0 );
-
- raster->InsertLine(p1, p2, inflection1, inflection2);
-
- p0[0] = p1[0]; p0[1] = p1[1];
- p1[0] = p2[0]; p1[1] = p2[1];
- p2[0] = p3[0]; p2[1] = p3[1];
- inflection1 = inflection2;
- }
-
- raster->FillStencilData(data, extent, xj, yj);
-
- return 1;
-}
-
-
-//----------------------------------------------------------------------------
-// Generate the splines for the given set of points. The splines
-// will be closed if the final point is equal to the first point.
-// The parametric value for the resulting spline will be valid over
-// the range [0, tmax] where the tmax value is returned by reference.
-static void vtkLassoStencilSourceCreateSpline(vtkPoints *points,
- const double origin[3], const double spacing[3],
- int xj, int yj, vtkSpline *xspline, vtkSpline *yspline,
- double &tmax, double &dmax)
-{
- // initialize the spline
- xspline->RemoveAllPoints();
- yspline->RemoveAllPoints();
- xspline->ClosedOff();
- yspline->ClosedOff();
-
- // get the number of points and the first/last point
- vtkIdType n = points->GetNumberOfPoints();
- double p[3];
- double p0[2], p1[2];
-
- points->GetPoint(n-1, p);
- p0[0] = (p[xj] - origin[xj])/spacing[xj];
- p0[1] = (p[yj] - origin[yj])/spacing[yj];
-
- points->GetPoint(0, p);
- p1[0] = (p[xj] - origin[xj])/spacing[xj];
- p1[1] = (p[yj] - origin[yj])/spacing[yj];
-
- // factor between real distance and parametric distance
- double f = 1.0;
- // the length of the implicit segment for closed loops
- double lastd = 0;
-
- // aspect ratio
- double xf = 1.0;
- double yf = 1.0;
- if (spacing[xj] > spacing[yj])
- {
- xf = spacing[xj]/spacing[yj];
- }
- else
- {
- yf = spacing[yj]/spacing[xj];
- }
-
- // if first and last point are same, spline is closed
- double dx = (p1[0] - p0[0])*xf;
- double dy = (p1[1] - p0[1])*yf;
- double d2 = dx*dx + dy*dy;
- while (d2 <= VTK_STENCIL_TOL*VTK_STENCIL_TOL && n > 1)
- {
- n -= 1;
- points->GetPoint(n-1, p);
- p0[0] = (p[xj] - origin[xj])/spacing[xj];
- p0[1] = (p[yj] - origin[yj])/spacing[yj];
-
- xspline->ClosedOn();
- yspline->ClosedOn();
-
- // vtkSpline considers the parametric length of the implicit
- // segment of closed loops to be unity, so set "f" so that
- // multiplying the real length of that segment by "f" gives unity.
- dx = (p1[0] - p0[0])*xf;
- dy = (p1[1] - p0[1])*yf;
- d2 = dx*dx + dy*dy;
- lastd = sqrt(d2);
- if (lastd > 0)
- {
- f = 1.0/lastd;
- }
- }
-
- // Add all the points to the spline.
- double d = 0.0;
- for (vtkIdType i = 0; i < n; i++)
- {
- p0[0] = p1[0]; p0[1] = p1[1];
-
- points->GetPoint(i, p);
- p1[0] = (p[xj] - origin[xj])/spacing[xj];
- p1[1] = (p[yj] - origin[yj])/spacing[yj];
-
- dx = (p1[0] - p0[0])*xf;
- dy = (p1[1] - p0[1])*yf;
-
- d += sqrt(dx*dx + dy*dy);
-
- double t = f*d;
-
- xspline->AddPoint(t, p1[0]);
- yspline->AddPoint(t, p1[1]);
- }
-
- // Do the spline precomputations
- xspline->Compute();
- yspline->Compute();
-
- // The spline is valid over t = [0, tmax]
- d += lastd;
- tmax = f*d;
- dmax = d;
-}
-
-//----------------------------------------------------------------------------
-// Rasterize a spline contour into the stencil
-static int vtkLassoStencilSourceSpline(
- vtkPoints *points, vtkImageStencilData *data, vtkImageStencilRaster *raster,
- const int extent[6], const double origin[3], const double spacing[3],
- int xj, int yj, vtkSpline *xspline, vtkSpline *yspline)
-{
- // create the splines
- double tmax, dmax;
- vtkLassoStencilSourceCreateSpline(
- points, origin, spacing, xj, yj, xspline, yspline, tmax, dmax);
-
- if (dmax <= VTK_STENCIL_TOL)
- {
- return 1;
- }
-
- // get the bounds of the polygon as a first guess of the spline bounds
- int subextent[6];
- vtkLassoStencilSourceSubExtent(points, origin, spacing, extent, subextent);
-
- // allocate the raster
- raster->PrepareForNewData(&subextent[2*yj]);
-
- // go around the spline
- vtkIdType n = vtkMath::Floor(dmax)+1;
- double delta = tmax/n;
-
- double p0[2], p1[2], p2[2], p3[2];
-
- double t = tmax;
- if (xspline->GetClosed())
- {
- t = (n-1)*tmax/n;
- }
- else
- {
- n = n + 1;
- }
-
- p0[0] = xspline->Evaluate(t);
- p0[1] = yspline->Evaluate(t);
-
- t = 0;
- p1[0] = xspline->Evaluate(t);
- p1[1] = yspline->Evaluate(t);
-
- t = delta;
- p2[0] = xspline->Evaluate(t);
- p2[1] = yspline->Evaluate(t);
-
- // inflection means the line changes vertical direction
- bool inflection1, inflection2;
- inflection1 = ( (p1[1] - p0[1])*(p2[1] - p1[1]) <= 0 );
-
- for (vtkIdType i = 0; i < n; i++)
- {
- t += delta;
- if (i == n-2)
- {
- t = 0;
- }
-
- p3[0] = xspline->Evaluate(t);
- p3[1] = yspline->Evaluate(t);
-
- inflection2 = ( (p2[1] - p1[1])*(p3[1] - p2[1]) <= 0 );
-
- raster->InsertLine(p1, p2, inflection1, inflection2);
-
- p0[0] = p1[0]; p0[1] = p1[1];
- p1[0] = p2[0]; p1[1] = p2[1];
- p2[0] = p3[0]; p2[1] = p3[1];
- inflection1 = inflection2;
- }
-
- raster->FillStencilData(data, extent, xj, yj);
-
- return 1;
-}
-
-//----------------------------------------------------------------------------
-static int vtkLassoStencilSourceExecute(
- vtkPoints *points, vtkImageStencilData *data, vtkImageStencilRaster *raster,
- int extent[6], double origin[3], double spacing[3], int shape,
- int xj, int yj, vtkSpline *xspline, vtkSpline *yspline)
-{
- int result = 1;
-
- if (points == 0 || points->GetNumberOfPoints() < 3)
- {
- return 1;
- }
-
- switch (shape)
- {
- case vtkLassoStencilSource::POLYGON:
- result = vtkLassoStencilSourcePolygon(
- points, data, raster, extent, origin, spacing, xj, yj);
- break;
- case vtkLassoStencilSource::SPLINE:
- result = vtkLassoStencilSourceSpline(
- points, data, raster, extent, origin, spacing, xj, yj,
- xspline, yspline);
- break;
- }
-
- return result;
-}
-
-
-//----------------------------------------------------------------------------
-int vtkLassoStencilSource::RequestData(
- vtkInformation *request,
- vtkInformationVector **inputVector,
- vtkInformationVector *outputVector)
-{
- int extent[6];
- double origin[3];
- double spacing[3];
- int result = 1;
-
- this->Superclass::RequestData(request, inputVector, outputVector);
-
- vtkInformation *outInfo = outputVector->GetInformationObject(0);
- vtkImageStencilData *data = vtkImageStencilData::SafeDownCast(
- outInfo->Get(vtkDataObject::DATA_OBJECT()));
-
- outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), extent);
- outInfo->Get(vtkDataObject::ORIGIN(), origin);
- outInfo->Get(vtkDataObject::SPACING(), spacing);
-
- int slabExtent[6];
- slabExtent[0] = extent[0]; slabExtent[1] = extent[1];
- slabExtent[2] = extent[2]; slabExtent[3] = extent[3];
- slabExtent[4] = extent[4]; slabExtent[5] = extent[5];
-
- int xj = 0;
- int yj = 1;
- int zj = 2;
-
- if (this->SliceOrientation == 0)
- {
- xj = 1;
- yj = 2;
- zj = 0;
- }
- else if (this->SliceOrientation == 1)
- {
- xj = 0;
- yj = 2;
- zj = 1;
- }
-
- vtkImageStencilRaster raster(&extent[2*yj]);
- raster.SetTolerance(VTK_STENCIL_TOL);
-
- int zmin = extent[2*zj];
- int zmax = extent[2*zj+1];
-
- vtkLSSPointMap::iterator iter = this->PointMap->lower_bound(zmin);
- vtkLSSPointMap::iterator maxiter = this->PointMap->upper_bound(zmax);
-
- while (iter != maxiter && result != 0)
- {
- this->SetProgress((slabExtent[2*zj] - zmin)*1.0/(zmax - zmin + 1));
-
- int i = iter->first;
- vtkPoints *points = iter->second;
-
- // fill in the slices with no SlicePoints
- if (this->Points && i > slabExtent[2*zj])
- {
- slabExtent[2*zj+1] = i-1;
-
- result = vtkLassoStencilSourceExecute(
- this->Points, data, &raster, slabExtent, origin, spacing,
- this->Shape, xj, yj, this->SplineX, this->SplineY);
- }
-
- // do the slice with its SlicePoints
- if (result)
- {
- slabExtent[2*zj] = i;
- slabExtent[2*zj+1] = i;
-
- result = vtkLassoStencilSourceExecute(
- points, data, &raster, slabExtent, origin, spacing,
- this->Shape, xj, yj, this->SplineX, this->SplineY);
-
- slabExtent[2*zj] = slabExtent[2*zj+1] + 1;
- }
-
- ++iter;
- }
-
- this->SetProgress((slabExtent[2*zj] - zmin)*1.0/(zmax - zmin + 1));
-
- // fill in the rest
- if (result && slabExtent[2*zj] <= zmax)
- {
- slabExtent[2*zj+1] = zmax;
-
- result = vtkLassoStencilSourceExecute(
- this->Points, data, &raster, slabExtent, origin, spacing,
- this->Shape, xj, yj, this->SplineX, this->SplineY);
-
- this->SetProgress(1.0);
- }
-
- return result;
-}
diff --git a/Modules/Ext/Algorithms/vtkPointSetSlicer.cxx b/Modules/Ext/Algorithms/vtkPointSetSlicer.cxx
deleted file mode 100644
index 9b816fc9da..0000000000
--- a/Modules/Ext/Algorithms/vtkPointSetSlicer.cxx
+++ /dev/null
@@ -1,818 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include <vector>
-#include <algorithm>
-
-#include "vtkPointSetSlicer.h"
-
-#include "vtkCellArray.h"
-#include "vtkCellData.h"
-#include "vtkDataSet.h"
-#include "vtkDoubleArray.h"
-#include "vtkFloatArray.h"
-#include "vtkGenericCell.h"
-#include "vtkMergePoints.h"
-#include "vtkObjectFactory.h"
-#include "vtkPointData.h"
-#include "vtkPolyData.h"
-#include "vtkPlane.h"
-#include "vtkCutter.h"
-
-#include "vtkUnstructuredGrid.h"
-
-#include "vtkInformation.h"
-#include "vtkInformationVector.h"
-#include "vtkStreamingDemandDrivenPipeline.h"
-
-vtkStandardNewMacro(vtkPointSetSlicer);
-
-// Construct with user-specified implicit function; initial value of 0.0; and
-// generating cut scalars turned off.
-vtkPointSetSlicer::vtkPointSetSlicer(vtkPlane *cf)
-{
- this->SlicePlane = cf;
- this->GenerateCutScalars = 0;
- this->Locator = 0;
-
- this->Cutter = vtkCutter::New();
- this->Cutter->GenerateValues( 1, 0, 1 );
-
-}
-
-vtkPointSetSlicer::~vtkPointSetSlicer()
-{
- this->SetSlicePlane(0);
- if ( this->Locator )
- {
- this->Locator->UnRegister(this);
- this->Locator = NULL;
- }
-
- this->Cutter->Delete();
-}
-
-void vtkPointSetSlicer::SetSlicePlane(vtkPlane* plane)
-{
- if ( this->SlicePlane == plane )
- {
- return;
- }
- if ( this->SlicePlane )
- {
- this->SlicePlane->UnRegister(this);
- this->SlicePlane = 0;
- }
- if ( plane )
- {
- plane->Register(this);
- this->Cutter->SetCutFunction(plane);
- }
- this->SlicePlane = plane;
- this->Modified();
-}
-
-// Overload standard modified time function. If cut functions is modified,
-// or contour values modified, then this object is modified as well.
-unsigned long vtkPointSetSlicer::GetMTime()
-{
- unsigned long mTime=this->Superclass::GetMTime();
- unsigned long time;
-
- if ( this->SlicePlane != 0 )
- {
- time = this->SlicePlane->GetMTime();
- mTime = ( time > mTime ? time : mTime );
- }
-
- if ( this->Locator != 0 )
- {
- time = this->Locator->GetMTime();
- mTime = ( time > mTime ? time : mTime );
- }
-
- return mTime;
-}
-
-int vtkPointSetSlicer::RequestData(
- vtkInformation * /*request*/,
- vtkInformationVector **inputVector,
- vtkInformationVector *outputVector)
-{
- // get the info objects
- vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
- vtkInformation *outInfo = outputVector->GetInformationObject(0);
-
- // get the input and ouptut
- vtkDataSet *input = vtkDataSet::SafeDownCast(
- inInfo->Get(vtkDataObject::DATA_OBJECT()));
- vtkPolyData *output = vtkPolyData::SafeDownCast(
- outInfo->Get(vtkDataObject::DATA_OBJECT()));
-
- vtkDebugMacro(<< "Executing cutter");
-
- if (!this->SlicePlane)
- {
- vtkErrorMacro("No slice plane specified");
- return 0;
- }
-
- if ( input->GetNumberOfPoints() < 1 )
- {
- return 1;
- }
-
- if (input->GetDataObjectType() == VTK_STRUCTURED_POINTS ||
- input->GetDataObjectType() == VTK_IMAGE_DATA)
- {
- if ( input->GetCell(0) && input->GetCell(0)->GetCellDimension() >= 3 )
- {
- //this->StructuredPointsCutter(input, output, request, inputVector, outputVector);
- return 1;
- }
- }
- if (input->GetDataObjectType() == VTK_STRUCTURED_GRID)
- {
- if (input->GetCell(0))
- {
- int dim = input->GetCell(0)->GetCellDimension();
- // only do 3D structured grids (to be extended in the future)
- if (dim >= 3)
- {
- //this->StructuredGridCutter(input, output);
- return 1;
- }
- }
- }
- if (input->GetDataObjectType() == VTK_RECTILINEAR_GRID)
- {
-
- //this->RectilinearGridCutter(input, output);
- return 1;
-
- }
-
- if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID)
- {
- vtkDebugMacro(<< "Executing Unstructured Grid Cutter");
- this->UnstructuredGridCutter(input, output);
- }
- else
- {
- vtkDebugMacro(<< "Executing DataSet Cutter");
- //this->DataSetCutter(input, output);
- }
-
- return 1;
-}
-int vtkPointSetSlicer::RequestUpdateExtent(
- vtkInformation *,
- vtkInformationVector **inputVector,
- vtkInformationVector *)
-{
- vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
- inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
- return 1;
-}
-int vtkPointSetSlicer::FillInputPortInformation(int, vtkInformation *info)
-{
- info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
- return 1;
-}
-
-void vtkPointSetSlicer::UnstructuredGridCutter(vtkDataSet *input, vtkPolyData *output)
-{
- vtkIdType cellId, i;
- vtkDoubleArray *cellScalars;
- vtkCellArray *newVerts, *newLines, *newPolys;
- vtkPoints *newPoints;
- vtkDoubleArray *cutScalars;
- double s;
- vtkIdType estimatedSize, numCells=input->GetNumberOfCells();
- vtkIdType numPts=input->GetNumberOfPoints();
- vtkIdType cellArrayIt = 0;
- int numCellPts;
- vtkPointData *inPD, *outPD;
- vtkCellData *inCD=input->GetCellData(), *outCD=output->GetCellData();
- vtkIdList *cellIds;
- int abortExecute = 0;
-
- double range[2];
-
- // Create objects to hold output of contour operation
- //
- estimatedSize = (vtkIdType) pow ((double) numCells, .75);
- estimatedSize = estimatedSize / 1024 * 1024; //multiple of 1024
- if (estimatedSize < 1024)
- {
- estimatedSize = 1024;
- }
-
- newPoints = vtkPoints::New();
- newPoints->Allocate(estimatedSize,estimatedSize/2);
- newVerts = vtkCellArray::New();
- newVerts->Allocate(estimatedSize,estimatedSize/2);
- newLines = vtkCellArray::New();
- newLines->Allocate(estimatedSize,estimatedSize/2);
- newPolys = vtkCellArray::New();
- newPolys->Allocate(estimatedSize,estimatedSize/2);
- cutScalars = vtkDoubleArray::New();
- cutScalars->SetNumberOfTuples(numPts);
-
- // Interpolate data along edge. If generating cut scalars, do necessary setup
- if ( this->GenerateCutScalars )
- {
- inPD = vtkPointData::New();
- inPD->ShallowCopy(input->GetPointData());//copies original attributes
- inPD->SetScalars(cutScalars);
- }
- else
- {
- inPD = input->GetPointData();
- }
- outPD = output->GetPointData();
- outPD->InterpolateAllocate(inPD,estimatedSize,estimatedSize/2);
- outCD->CopyAllocate(inCD,estimatedSize,estimatedSize/2);
-
- // locator used to merge potentially duplicate points
- if ( this->Locator == NULL )
- {
- this->CreateDefaultLocator();
- }
- this->Locator->InitPointInsertion (newPoints, input->GetBounds());
-
- // Loop over all points evaluating scalar function at each point
- //
- for ( i=0; i < numPts; i++ )
- {
- s = this->SlicePlane->FunctionValue(input->GetPoint(i));
- cutScalars->SetComponent(i,0,s);
- }
-
- // Compute some information for progress methods
- //
- vtkIdType numCuts = numCells;
- vtkIdType progressInterval = numCuts/20 + 1;
- int cut=0;
-
- vtkUnstructuredGrid *grid = (vtkUnstructuredGrid *)input;
- vtkIdType *cellArrayPtr = grid->GetCells()->GetPointer();
- double *scalarArrayPtr = cutScalars->GetPointer(0);
- double tempScalar;
- cellScalars = cutScalars->NewInstance();
- cellScalars->SetNumberOfComponents(cutScalars->GetNumberOfComponents());
- cellScalars->Allocate(VTK_CELL_SIZE*cutScalars->GetNumberOfComponents());
-
- // Three passes over the cells to process lower dimensional cells first.
- // For poly data output cells need to be added in the order:
- // verts, lines and then polys, or cell data gets mixed up.
- // A better solution is to have an unstructured grid output.
- // I create a table that maps cell type to cell dimensionality,
- // because I need a fast way to get cell dimensionality.
- // This assumes GetCell is slow and GetCellType is fast.
- // I do not like hard coding a list of cell types here,
- // but I do not want to add GetCellDimension(vtkIdType cellId)
- // to the vtkDataSet API. Since I anticipate that the output
- // will change to vtkUnstructuredGrid. This temporary solution
- // is acceptable.
- //
- int cellType;
- unsigned char cellTypeDimensions[VTK_NUMBER_OF_CELL_TYPES];
- vtkCutter::GetCellTypeDimensions(cellTypeDimensions);
- int dimensionality;
- // We skip 0d cells (points), because they cannot be cut (generate no data).
- for (dimensionality = 1; dimensionality <= 3; ++dimensionality)
- {
- // Loop over all cells; get scalar values for all cell points
- // and process each cell.
- //
- cellArrayIt = 0;
- for (cellId=0; cellId < numCells && !abortExecute; cellId++)
- {
- numCellPts = cellArrayPtr[cellArrayIt];
- // I assume that "GetCellType" is fast.
- cellType = input->GetCellType(cellId);
- if (cellType >= VTK_NUMBER_OF_CELL_TYPES)
- { // Protect against new cell types added.
- vtkErrorMacro("Unknown cell type " << cellType);
- cellArrayIt += 1+numCellPts;
- continue;
- }
- if (cellTypeDimensions[cellType] != dimensionality)
- {
- cellArrayIt += 1+numCellPts;
- continue;
- }
- cellArrayIt++;
-
- //find min and max values in scalar data
- range[0] = scalarArrayPtr[cellArrayPtr[cellArrayIt]];
- range[1] = scalarArrayPtr[cellArrayPtr[cellArrayIt]];
- cellArrayIt++;
-
- for (i = 1; i < numCellPts; i++)
- {
- tempScalar = scalarArrayPtr[cellArrayPtr[cellArrayIt]];
- cellArrayIt++;
- if (tempScalar <= range[0])
- {
- range[0] = tempScalar;
- } //if tempScalar <= min range value
- if (tempScalar >= range[1])
- {
- range[1] = tempScalar;
- } //if tempScalar >= max range value
- } // for all points in this cell
-
- int needCell = 0;
- if (0.0 >= range[0] && 0.0 <= range[1])
- {
- needCell = 1;
- }
-
- if (needCell)
- {
- vtkCell *cell = input->GetCell(cellId);
- cellIds = cell->GetPointIds();
- cutScalars->GetTuples(cellIds,cellScalars);
- // Loop over all contour values.
- if (dimensionality == 3 && !(++cut % progressInterval) )
- {
- vtkDebugMacro(<<"Cutting #" << cut);
- this->UpdateProgress (static_cast<double>(cut)/numCuts);
- abortExecute = this->GetAbortExecute();
- }
-
- this->ContourUnstructuredGridCell(cell, cellScalars, this->Locator,
- newVerts, newLines, newPolys, inPD, outPD,
- inCD, cellId, outCD);
- } // if need cell
- } // for all cells
- } // for all dimensions (1,2,3).
-
- // Update ourselves. Because we don't know upfront how many verts, lines,
- // polys we've created, take care to reclaim memory.
- //
- cellScalars->Delete();
- cutScalars->Delete();
-
- if ( this->GenerateCutScalars )
- {
- inPD->Delete();
- }
-
- output->SetPoints(newPoints);
- newPoints->Delete();
-
- if (newVerts->GetNumberOfCells())
- {
- output->SetVerts(newVerts);
- }
- newVerts->Delete();
-
- if (newLines->GetNumberOfCells())
- {
- output->SetLines(newLines);
- }
- newLines->Delete();
-
- if (newPolys->GetNumberOfCells())
- {
- output->SetPolys(newPolys);
- }
- newPolys->Delete();
-
- this->Locator->Initialize();//release any extra memory
- output->Squeeze();
-}
-
-void vtkPointSetSlicer::ContourUnstructuredGridCell(vtkCell* cell,
- vtkDataArray* cellScalars, vtkPointLocator* locator,
- vtkCellArray* verts, vtkCellArray* lines,
- vtkCellArray* polys, vtkPointData* inPd,
- vtkPointData* outPd, vtkCellData* inCd,
- vtkIdType cellId, vtkCellData* outCd)
-{
- if (cell->GetCellType() == VTK_HEXAHEDRON)
- {
- static int CASE_MASK[8] = {1,2,4,8,16,32,64,128};
- POLY_CASES *polyCase;
- EDGE_LIST *edge;
- int i, j, index, *vert;
- volatile int pnum;
- int v1, v2, newCellId;
- double t, x1[3], x2[3], x[3], deltaScalar;
- vtkIdType offset = verts->GetNumberOfCells() + lines->GetNumberOfCells();
-
- // Build the case table
- for ( i=0, index = 0; i < 8; i++)
- {
- if (cellScalars->GetComponent(i,0) >= 0)
- {
- index |= CASE_MASK[i];
- }
- }
-
- polyCase = polyCases + index;
- edge = polyCase->edges;
-
- // get the point number of the polygon
- pnum = 0;
- for (i = 0; i < 8; i++)
- if (edge[i] > -1) pnum++;
- else break;
-
- vtkIdType* pts = new vtkIdType[pnum];
- for (i=0; i<pnum; i++) // insert polygon
- {
- vert = edges[edge[i]];
-
- // calculate a preferred interpolation direction
- deltaScalar = (cellScalars->GetComponent(vert[1],0)
- - cellScalars->GetComponent(vert[0],0));
- if (deltaScalar > 0)
- {
- v1 = vert[0]; v2 = vert[1];
- }
- else
- {
- v1 = vert[1]; v2 = vert[0];
- deltaScalar = -deltaScalar;
- }
-
- // linear interpolation
- t = ( deltaScalar == 0.0 ? 0.0 : (-cellScalars->GetComponent(v1,0)) / deltaScalar );
-
- cell->GetPoints()->GetPoint(v1, x1);
- cell->GetPoints()->GetPoint(v2, x2);
-
- for (j=0; j<3; j++)
- {
- x[j] = x1[j] + t * (x2[j] - x1[j]);
- }
- if ( locator->InsertUniquePoint(x, pts[i]) )
- {
- if ( outPd )
- {
- vtkIdType p1 = cell->GetPointIds()->GetId(v1);
- vtkIdType p2 = cell->GetPointIds()->GetId(v2);
- outPd->InterpolateEdge(inPd,pts[i],p1,p2,t);
- }
- }
- }
-
- // check for degenerate polygon
- std::vector<vtkIdType> pset;
- for (i=0; i<pnum; i++)
- {
- if (std::find(pset.begin(), pset.end(), pts[i]) == pset.end())
- pset.push_back(pts[i]);
- }
-
- if (pset.size() > 2)
- {
- i = 0;
- for (std::vector<vtkIdType>::iterator iter = pset.begin(); iter != pset.end(); iter++)
- {
- pts[i] = *iter;
- i++;
- }
- newCellId = offset + polys->InsertNextCell(pset.size(),pts);
- outCd->CopyData(inCd,cellId,newCellId);
- }
- delete [] pts;
-
- }
- else
- {
- cell->Contour(0, cellScalars, locator, verts, lines, polys,
- inPd, outPd, inCd, cellId, outCd);
- }
-}
-
-// Specify a spatial locator for merging points. By default,
-// an instance of vtkMergePoints is used.
-void vtkPointSetSlicer::SetLocator(vtkPointLocator *locator)
-{
- if ( this->Locator == locator )
- {
- return;
- }
- if ( this->Locator )
- {
- this->Locator->UnRegister(this);
- this->Locator = 0;
- }
- if ( locator )
- {
- locator->Register(this);
- }
- this->Locator = locator;
- this->Modified();
-}
-
-void vtkPointSetSlicer::CreateDefaultLocator()
-{
- if ( this->Locator == 0 )
- {
- this->Locator = vtkMergePoints::New();
- this->Locator->Register(this);
- this->Locator->Delete();
- }
-}
-
-
-void vtkPointSetSlicer::PrintSelf(std::ostream& os, vtkIndent indent)
-{
- this->Superclass::PrintSelf(os,indent);
-
- os << indent << "Slice Plane: " << this->SlicePlane << "\n";
-
- if ( this->Locator )
- {
- os << indent << "Locator: " << this->Locator << "\n";
- }
- else
- {
- os << indent << "Locator: (none)\n";
- }
-
- os << indent << "Generate Cut Scalars: "
- << (this->GenerateCutScalars ? "On\n" : "Off\n");
-}
-
-int vtkPointSetSlicer::edges[12][2] = { {0,1},{1,2},{3,2},{0,3},
- {4,5},{5,6},{7,6},{4,7},
- {0,4},{1,5},{2,6},{3,7} };
-
-vtkPointSetSlicer::POLY_CASES
-vtkPointSetSlicer::polyCases[256] = {
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{0, 3, 8, -1, -1, -1, -1, -1}},
- {{1, 0, 9, -1, -1, -1, -1, -1}},
- {{1, 3, 8, 9, -1, -1, -1, -1}},
- {{2, 1, 10, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{2, 0, 9, 10, -1, -1, -1, -1}},
- {{2, 10, 9, 8, 3, -1, -1, -1}},
- {{3, 2, 11, -1, -1, -1, -1, -1}},
- {{0, 2, 11, 8, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 9, 8, 11, 2, -1, -1, -1}},
- {{3, 1, 10, 11, -1, -1, -1, -1}},
- {{0, 8, 11, 10, 1, -1, -1, -1}},
- {{3, 11, 10, 9, 0, -1, -1, -1}},
- {{8, 9, 10, 11, -1, -1, -1, -1}},
- {{4, 7, 8, -1, -1, -1, -1, -1}},
- {{3, 7, 4, 0, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{9, 1, 3, 7, 4, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{11, 2, 0, 4, 7, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 2, 11, 7, 4, 9, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{4, 7, 11, 10, 9, -1, -1, -1}},
- {{5, 4, 9, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{0, 4, 5, 1, -1, -1, -1, -1}},
- {{8, 3, 1, 5, 4, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{10, 2, 0, 4, 5, -1, -1, -1}},
- {{2, 3, 8, 4, 5, 10, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{5, 4, 8, 11, 10, -1, -1, -1}},
- {{5, 7, 8, 9, -1, -1, -1, -1}},
- {{9, 5, 7, 3, 0, -1, -1, -1}},
- {{8, 7, 5, 1, 0, -1, -1, -1}},
- {{1, 3, 7, 5, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{2, 10, 5, 7, 3, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{2, 11, 7, 5, 1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{5, 7, 11, 10, -1, -1, -1, -1}},
- {{6, 5, 10, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 5, 6, 2, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{9, 0, 2, 6, 5, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{11, 3, 1, 5, 6, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{3, 0, 9, 5, 6, 11, -1, -1}},
- {{6, 5, 9, 8, 11, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{6, 4, 9, 10, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{10, 6, 4, 0, 1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{9, 4, 6, 2, 1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{2, 0, 4, 6, -1, -1, -1, -1}},
- {{3, 8, 4, 6, 2, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{3, 11, 6, 4, 0, -1, -1, -1}},
- {{6, 4, 8, 11, -1, -1, -1, -1}},
- {{6, 10, 9, 8, 7, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{6, 7, 8, 0, 1, 10, -1, -1}},
- {{6, 10, 1, 3, 7, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{7, 8, 0, 2, 6, -1, -1, -1}},
- {{2, 6, 7, 3, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{6, 7, 11, -1, -1, -1, -1, -1}},
- {{7, 6, 11, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{2, 6, 7, 3, -1, -1, -1, -1}},
- {{8, 0, 2, 6, 7, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{10, 1, 3, 7, 6, -1, -1, -1}},
- {{0, 1, 10, 6, 7, 8, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{7, 6, 10, 9, 8, -1, -1, -1}},
- {{4, 6, 11, 8, -1, -1, -1, -1}},
- {{11, 6, 4, 0, 3, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{8, 4, 6, 2, 3, -1, -1, -1}},
- {{0, 2, 6, 4, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 9, 4, 6, 2, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 10, 6, 4, 0, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{4, 6, 10, 9, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{5, 9, 8, 11, 6, -1, -1, -1}},
- {{5, 6, 11, 3, 0, 9, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{6, 11, 3, 1, 5, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{5, 9, 0, 2, 6, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 5, 6, 2, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{5, 6, 10, -1, -1, -1, -1, -1}},
- {{7, 5, 10, 11, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{11, 7, 5, 1, 2, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{10, 5, 7, 3, 2, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{3, 1, 5, 7, -1, -1, -1, -1}},
- {{0, 8, 7, 5, 1, -1, -1, -1}},
- {{0, 9, 5, 7, 3, -1, -1, -1}},
- {{7, 5, 9, 8, -1, -1, -1, -1}},
- {{4, 8, 11, 10, 5, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{4, 5, 10, 2, 3, 8, -1, -1}},
- {{5, 10, 2, 0, 4, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{4, 8, 3, 1, 5, -1, -1, -1}},
- {{0, 4, 5, 1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{4, 5, 9, -1, -1, -1, -1, -1}},
- {{7, 11, 10, 9, 4, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{7, 4, 9, 1, 2, 11, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{7, 11, 2, 0, 4, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{4, 9, 1, 3, 7, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{3, 7, 4, 0, -1, -1, -1, -1}},
- {{7, 4, 8, -1, -1, -1, -1, -1}},
- {{10, 11, 8, 9, -1, -1, -1, -1}},
- {{0, 3, 11, 10, 9, -1, -1, -1}},
- {{1, 0, 8, 11, 10, -1, -1, -1}},
- {{1, 3, 11, 10, -1, -1, -1, -1}},
- {{2, 1, 9, 8, 11, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{2, 0, 8, 11, -1, -1, -1, -1}},
- {{2, 3, 11, -1, -1, -1, -1, -1}},
- {{3, 2, 10, 9, 8, -1, -1, -1}},
- {{0, 2, 10, 9, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}},
- {{1, 2, 10, -1, -1, -1, -1, -1}},
- {{3, 1, 9, 8, -1, -1, -1, -1}},
- {{0, 1, 9, -1, -1, -1, -1, -1}},
- {{3, 0, 8, -1, -1, -1, -1, -1}},
- {{-1, -1, -1, -1, -1, -1, -1, -1}}
-};
diff --git a/Modules/Ext/Algorithms/vtkPointSetSlicer.h b/Modules/Ext/Algorithms/vtkPointSetSlicer.h
deleted file mode 100644
index 26e1cb31f7..0000000000
--- a/Modules/Ext/Algorithms/vtkPointSetSlicer.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _VTKPOINTSETSLICER_H_
-#define _VTKPOINTSETSLICER_H_
-
-#include <iostream>
-#include "MitkExtExports.h"
-
-#include "vtkVersion.h"
-
-class vtkCutter;
-class vtkPlane;
-class vtkPointLocator;
-class vtkCell;
-class vtkDataArray;
-class vtkCellArray;
-class vtkPointData;
-class vtkCellData;
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-
-#include "vtkPolyDataAlgorithm.h"
-
-class MitkExt_EXPORT vtkPointSetSlicer : public vtkPolyDataAlgorithm
-{
-public:
- vtkTypeMacro(vtkPointSetSlicer,vtkPolyDataAlgorithm);
-
- void PrintSelf(std::ostream& os, vtkIndent indent);
-
- // Description:
- // Construct with user-specified implicit function; initial value of 0.0; and
- // generating cut scalars turned off.
- static vtkPointSetSlicer *New();
-
- // Description:
- // Override GetMTime because we delegate to vtkContourValues and refer to
- // vtkImplicitFunction.
- unsigned long GetMTime();
-
- // Description
- // Specify the implicit function to perform the cutting.
- virtual void SetSlicePlane(vtkPlane*);
- vtkGetObjectMacro(SlicePlane,vtkPlane);
-
- // Description:
- // If this flag is enabled, then the output scalar values will be
- // interpolated from the implicit function values, and not the input scalar
- // data.
- vtkSetMacro(GenerateCutScalars,int);
- vtkGetMacro(GenerateCutScalars,int);
- vtkBooleanMacro(GenerateCutScalars,int);
-
- // Description:
- // Specify a spatial locator for merging points. By default,
- // an instance of vtkMergePoints is used.
- void SetLocator(vtkPointLocator *locator);
- vtkGetObjectMacro(Locator,vtkPointLocator);
-
- // Description:
- // Create default locator. Used to create one when none is specified. The
- // locator is used to merge coincident points.
- void CreateDefaultLocator();
-
-protected:
- vtkPointSetSlicer(vtkPlane* cf = 0);
- ~vtkPointSetSlicer();
-
- virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
- virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
- virtual int FillInputPortInformation(int port, vtkInformation *info);
-
- void UnstructuredGridCutter(vtkDataSet *input, vtkPolyData *output);
-
- void ContourUnstructuredGridCell(vtkCell* cell,
- vtkDataArray* cellScalars, vtkPointLocator* locator,
- vtkCellArray* verts, vtkCellArray* lines,
- vtkCellArray* polys, vtkPointData* inPd,
- vtkPointData* outPd, vtkCellData* inCd,
- vtkIdType cellId, vtkCellData* outCd);
-
- vtkPlane *SlicePlane;
- vtkCutter *Cutter;
-
- vtkPointLocator *Locator;
- int GenerateCutScalars;
-
-private:
- vtkPointSetSlicer(const vtkPointSetSlicer&); // Not implemented.
- void operator=(const vtkPointSetSlicer&); // Not implemented.
-
- static int edges[12][2];
-
- typedef int EDGE_LIST;
- typedef struct {
- EDGE_LIST edges[8];
- } POLY_CASES;
-
- static POLY_CASES polyCases[256];
-};
-
-
-#endif /* _VTKPOINTSETSLICER_H_ */
diff --git a/Modules/Ext/CMakeLists.txt b/Modules/Ext/CMakeLists.txt
deleted file mode 100644
index a1c32d30c0..0000000000
--- a/Modules/Ext/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-#if(WIN32)
-# option(MITK_USE_TD_MOUSE "Enable support for 3D Connexion SpaceNavigator" OFF)
-#endif(WIN32)
-
-configure_file(${PROJECT_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in ${PROJECT_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY)
-configure_file(${PROJECT_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in ${PROJECT_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY)
-configure_file(${PROJECT_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in ${PROJECT_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY)
-
-MITK_CREATE_MODULE(
- INCLUDE_DIRS Algorithms Controllers DataManagement Interactions IO Rendering
- DEPENDS MitkDataTypesExt MitkImageExtraction MitkIpPicSupport
- PACKAGE_DEPENDS ANN ITK|ITKConnectedComponents+ITKBinaryMathematicalMorphology
- DEPRECATED_SINCE 2014.03
-)
-
-if(BUILD_TESTING)
- add_subdirectory(Testing)
-endif()
-
diff --git a/Modules/Ext/Controllers/mitkTDMouseVtkCameraController.cpp b/Modules/Ext/Controllers/mitkTDMouseVtkCameraController.cpp
deleted file mode 100644
index 9cdcd2fd2f..0000000000
--- a/Modules/Ext/Controllers/mitkTDMouseVtkCameraController.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkTDMouseVtkCameraController.h"
-#include "mitkVtkPropRenderer.h"
-#include "vtkCamera.h"
-#include "vtkRenderer.h"
-#include "vtkTransform.h"
-#include "mitkNumericTypes.h"
-#include "mitkInteractionConst.h"
-#include "mitkStateEvent.h"
-#include "mitkTDMouseEventThrower.h"
-#include "mitkTDMouseEvent.h"
-#include "mitkGlobalInteraction.h"
-#include "vtkMath.h"
-
-const double TRANSLATIONSENSITIVITY = 2.0;
-const double ROTATIONSENSIVITY = 3.5;
-const double ANGLESENSITIVITY = 3.5;
-
-
-mitk::TDMouseVtkCameraController::TDMouseVtkCameraController()
-: CameraController("TDMouseInteraction")
-{
- //activate and instanciate EventThrower
- mitk::TDMouseEventThrower* thrower = mitk::TDMouseEventThrower::GetInstance();
- //add this to GlobalInteracion to listen to events
- mitk::GlobalInteraction::GetInstance()->AddListener(this);
- //connect method this->OnTDMouseEvent to StateMachineEventMechanism
- CONNECT_ACTION(AcONTDMOUSEINPUT, OnTDMouseEvent);
- CONNECT_ACTION(AcONTDMOUSEKEYDOWN, OnTDMouseKeyDown);
- m_ClippingRangeIsSet = false;
-}
-
-mitk::TDMouseVtkCameraController::~TDMouseVtkCameraController()
-{
-}
-
-bool mitk::TDMouseVtkCameraController::OnTDMouseEvent(mitk::Action* a, const mitk::StateEvent* e)
-{
- //only if 3D rendering
- mitk::BaseRenderer const* br = this->GetRenderer();
- mitk::BaseRenderer::MapperSlotId id = ((mitk::BaseRenderer*)(br))->GetMapperID();
- if (id != mitk::BaseRenderer::Standard3D)
- return true;
-
- //only if focused by the FocusManager
- if (this->GetRenderer() != mitk::GlobalInteraction::GetInstance()->GetFocus())
- return true;
-
- //pre-checking for safety
- vtkRenderer* vtkRenderer = ((mitk::VtkPropRenderer*)this->GetRenderer())->GetVtkRenderer();
- if (vtkRenderer == NULL)
- return false;
-
-
- vtkCamera* vtkCam = (vtkCamera*)vtkRenderer->GetActiveCamera();
-
- if(!m_ClippingRangeIsSet)
- vtkCam->SetClippingRange(0.1, 1000000);
-
- const mitk::TDMouseEvent* tdevent = dynamic_cast<const mitk::TDMouseEvent*>(e->GetEvent());
- if (tdevent == NULL)
- {
- std::cout<<"Wrong event for TDMouseCameraController!"<<std::endl;
- return false;
- }
-
- //get the information from the mouse
- mitk::Vector3D translation = tdevent->GetTranslation();
- mitk::Vector3D rotation = tdevent->GetRotation();
- mitk::ScalarType angle = tdevent->GetAngle();
-
- //output for debug
- //std::cout<<"translation: "<<translation[0]<<" "<<translation[1]<<" "<<translation[2]<<" "<<"\n";
- //std::cout<<"rotation: "<<rotation[0]<<" "<<rotation[1]<<" "<<rotation[2]<<" "<<"\n";
- //std::cout<<"angle: "<<angle<<"\n \n";
-
-
- //empirically gained max and min valued from driver:
- // MAXIMA:
- // translation: 0.83 1.17 1.02
- // rotation: 1.00 1.00 1.00
- // angle: 0.83
- // MINIMA:
- // translation: -1.00 -1.03 -0.88
- // rotation: -1.00 -1.00 -1.00
- // angle: 0.00
-
- //compute current sensitivity according to current BoundingBox of the whole scene!
- double sceneSensivity = 1.0;
-
- mitk::DataStorage* ds = m_Renderer->GetDataStorage();
- mitk::BoundingBox::Pointer bb = ds->ComputeBoundingBox();
- mitk::BoundingBox::AccumulateType length = bb->GetDiagonalLength2();
- if (length > 0.00001)//if length not zero
- sceneSensivity *= 100.0 / (sqrt(length)) ;
-
- //sensivity to adapt to mitk speed
- translation *= sceneSensivity * TRANSLATIONSENSITIVITY;
- rotation *= sceneSensivity * ROTATIONSENSIVITY;
- angle *= sceneSensivity * ANGLESENSITIVITY;
-
- //compute the global space coordinates from the relative mouse coordinate
- //first we need the position of the camera
- mitk::Vector3D camPosition;
- double camPositionTemp[3];
- vtkCam->GetPosition(camPositionTemp);
- camPosition[0] = camPositionTemp[0]; camPosition[1] = camPositionTemp[1]; camPosition[2] = camPositionTemp[2];
-
- //then the upvector of the camera
- mitk::Vector3D upCamVector;
- double upCamTemp[3];
- vtkCam->GetViewUp(upCamTemp);
- upCamVector[0] = upCamTemp[0]; upCamVector[1] = upCamTemp[1]; upCamVector[2] = upCamTemp[2];
- upCamVector.Normalize();
-
- //then the vector to which the camera is heading at (focalpoint)
- mitk::Vector3D focalPoint;
- double focalPointTemp[3];
- vtkCam->GetFocalPoint(focalPointTemp);
- focalPoint[0] = focalPointTemp[0]; focalPoint[1] = focalPointTemp[1]; focalPoint[2] = focalPointTemp[2];
- mitk::Vector3D focalVector;
- focalVector = focalPoint - camPosition;
- focalVector.Normalize();
-
- //orthogonal vector to focalVector and upCamVector
- mitk::Vector3D crossVector;
- crossVector = CrossProduct(upCamVector, focalVector);
- crossVector.Normalize();
-
- //now we have the current orientation so we can adapt it according to the current information, which we got from the TDMouse
-
- //new position of the camera:
- //left/right = camPosition + crossVector * translation[0];
- mitk::Vector3D vectorX = crossVector * -translation[0]; //changes the magnitude, not the direction
- double nextCamPosition[3];
- nextCamPosition[0] = camPosition[0] + vectorX[0];
- nextCamPosition[1] = camPosition[1] + vectorX[1];
- nextCamPosition[2] = camPosition[2] + vectorX[2];
-
- //now the up/down movement
- mitk::Vector3D vectorY = upCamVector * translation[1]; //changes the magnitude, not the direction
- nextCamPosition[0] += vectorY[0];
- nextCamPosition[1] += vectorY[1];
- nextCamPosition[2] += vectorY[2];
-
- //forward/backward movement
- mitk::Vector3D vectorZ = focalVector * -translation[2]; //changes the magnitude, not the direction
- nextCamPosition[0] += vectorZ[0];
- nextCamPosition[1] += vectorZ[1];
- nextCamPosition[2] += vectorZ[2];
-
- //set the next position
- double nextPosition[3];
- nextPosition[0] = nextCamPosition[0]; nextPosition[1] = nextCamPosition[1]; nextPosition[2] = nextCamPosition[2];
- vtkCam->SetPosition(nextPosition);
-
- //adapt the focal point the same way
- double currentFocalPoint[3], nextFocalPoint[3];
- vtkCam->GetFocalPoint(currentFocalPoint);
- nextFocalPoint[0] = currentFocalPoint[0] + vectorX[0] + vectorY[0] + vectorZ[0];
- nextFocalPoint[1] = currentFocalPoint[1] + vectorX[1] + vectorY[1] + vectorZ[1]; ;
- nextFocalPoint[2] = currentFocalPoint[2] + vectorX[2] + vectorY[2] + vectorZ[2];
- vtkCam->SetFocalPoint(nextFocalPoint);
-
-
- //now adapt the rotation of the mouse and adapt the camera according to it
-
- //Pitch:
- //Rotate the focal point about the cross product of the view up vector and the direction of
- //projection, centered at the camera's position.
- vtkCam->Pitch(rotation[0]*angle);
-
- //Yaw:
- //Rotate the focal point about the view up vector centered at the camera's position.
- //Note that the view up vector is not necessarily perpendicular to the direction of projection.
- vtkCam->Yaw(rotation[1]*angle);
-
- //Roll:
- //Rotate the camera about the direction of projection.
- vtkCam->Roll(-rotation[2]*angle * 1.5);//*1.5 to speed up the rotation[2] a little bit
-
- //Recompute the ViewUp vector to force it to be perpendicular to camera->focalpoint vector.
- //Unless you are going to use Yaw or Azimuth on the camera, there is no need to do this.
- vtkCam->OrthogonalizeViewUp();
-
- //no zooming, only translating to the front or back
- // dolly: Move the position of the camera along the direction
- // of projection. Moving towards the focal point (e.g., greater
- // than 1) is a dolly-in, moving away from the focal point
- // (e.g., less than 1) is a dolly-out.
- //double distance = ((tdevent->GetTranslation())[1] / 10.0);//make it less sensitive in comparison to translation and rotatipn
- //vtkCam->Dolly(1.0 + distance );
-
-
- //Reset the camera clipping range based on the bounds of the visible actors.
- //This ensures that no props are cut off
- vtkRenderer->ResetCameraClippingRange();
-
- mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(mitk::GlobalInteraction::GetInstance()->GetFocus()->GetRenderWindow());
-
- return true;
-}
-
-
-bool mitk::TDMouseVtkCameraController::OnTDMouseKeyDown(mitk::Action* a, const mitk::StateEvent* e)
-{
- //reset the camera, so that the objects shown in the scene can be seen.
- const mitk::VtkPropRenderer* glRenderer = dynamic_cast<const mitk::VtkPropRenderer*>(m_Renderer);
- if (glRenderer)
- {
- vtkRenderer* vtkRenderer = glRenderer->GetVtkRenderer();
- mitk::DataStorage* ds = m_Renderer->GetDataStorage();
- if (ds == NULL)
- return false;
-
- mitk::BoundingBox::Pointer bb = ds->ComputeBoundingBox();
-
- mitk::Point3D middle =bb->GetCenter();
- vtkRenderer->GetActiveCamera()->SetFocalPoint(middle[0],middle[1],middle[2]);
-
- vtkRenderer->ResetCamera();
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- return true;
- }
- return false;
-}
diff --git a/Modules/Ext/Controllers/mitkTDMouseVtkCameraController.h b/Modules/Ext/Controllers/mitkTDMouseVtkCameraController.h
deleted file mode 100644
index 6daa75a49e..0000000000
--- a/Modules/Ext/Controllers/mitkTDMouseVtkCameraController.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKTDMOUSEVTKCAMERACONTROLLER_H_HEADER_INCLUDED
-#define MITKTDMOUSEVTKCAMERACONTROLLER_H_HEADER_INCLUDED
-
-#include "mitkCameraController.h"
-
-
-class vtkRenderWindow;
-
-namespace mitk {
-
-//##Documentation
-//## @brief vtk-based camera controller
-//## @ingroup NavigationControl
-class TDMouseVtkCameraController : public CameraController
-{
-public:
- mitkClassMacro(TDMouseVtkCameraController, CameraController);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual bool OnTDMouseEvent(mitk::Action* a, const mitk::StateEvent* e);
- virtual bool OnTDMouseKeyDown(mitk::Action* a, const mitk::StateEvent* e);
-
-protected:
- /**
- * @brief Default Constructor
- **/
- TDMouseVtkCameraController();
-
- /**
- * @brief Default Destructor
- **/
- virtual ~TDMouseVtkCameraController();
-
- bool m_ClippingRangeIsSet;
-
-
-};
-
-} // namespace mitk
-
-#endif /* MITKTDMOUSEVTKCAMERACONTROLLER_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterHierarchyHandling.dia b/Modules/Ext/DataManagement/doc_mitkDataTreeFilterHierarchyHandling.dia
deleted file mode 100644
index 0b1b1710bd..0000000000
Binary files a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterHierarchyHandling.dia and /dev/null differ
diff --git a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterHierarchyHandling.png b/Modules/Ext/DataManagement/doc_mitkDataTreeFilterHierarchyHandling.png
deleted file mode 100644
index d1f9b31add..0000000000
Binary files a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterHierarchyHandling.png and /dev/null differ
diff --git a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterRelatedClasses.dia b/Modules/Ext/DataManagement/doc_mitkDataTreeFilterRelatedClasses.dia
deleted file mode 100644
index fae3939b86..0000000000
Binary files a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterRelatedClasses.dia and /dev/null differ
diff --git a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterRelatedClasses.png b/Modules/Ext/DataManagement/doc_mitkDataTreeFilterRelatedClasses.png
deleted file mode 100644
index ecc84b901d..0000000000
Binary files a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterRelatedClasses.png and /dev/null differ
diff --git a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterTreeViewsGUI.png b/Modules/Ext/DataManagement/doc_mitkDataTreeFilterTreeViewsGUI.png
deleted file mode 100644
index 0c79c1e3e9..0000000000
Binary files a/Modules/Ext/DataManagement/doc_mitkDataTreeFilterTreeViewsGUI.png and /dev/null differ
diff --git a/Modules/Ext/DataManagement/itkAffineGeometryFrame.h.dox b/Modules/Ext/DataManagement/itkAffineGeometryFrame.h.dox
deleted file mode 100644
index 1b563211c3..0000000000
--- a/Modules/Ext/DataManagement/itkAffineGeometryFrame.h.dox
+++ /dev/null
@@ -1,127 +0,0 @@
-// copied here for documentation purposes
-#ifdef DOXYGEN_SKIP
-/*=========================================================================
-
- Program: Insight Segmentation & Registration Toolkit
- Module: $RCSfile: itkAffineGeometryFrame.h,v $
- Language: C++
- Date: $Date$
- Version: $Revision: 1.7 $
-
- Copyright (c) Insight Software Consortium. All rights reserved.
- See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef __itkAffineGeometryFrame_h
-#define __itkAffineGeometryFrame_h
-
-#include "itkObject.h"
-#include "itkMacro.h"
-#include "itkScalableAffineTransform.h"
-#include "itkBoundingBox.h"
-
-namespace itk
-{
-
- /** \class AffineGeometryFrame
- * \brief Describes the geometry of a data object
- */
-template <class TScalarType = double, unsigned int NDimensions = 3>
-class AffineGeometryFrame : public itk::Object
-{
-public:
- typedef AffineGeometryFrame Self;
- typedef itk::Object Superclass;
- typedef SmartPointer<Self> Pointer;
- typedef SmartPointer<const Self> ConstPointer;
-
- typedef ScalableAffineTransform<TScalarType, NDimensions> TransformType;
- typedef BoundingBox<unsigned long, NDimensions, TScalarType> BoundingBoxType;
- typedef typename BoundingBoxType::BoundsArrayType BoundsArrayType;
- typedef typename BoundingBoxType::Pointer BoundingBoxPointer;
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /** \brief Method for creation through the object factory. */
- itkTypeMacro(AffineGeometryFrame, Object);
-
- /** \brief Get the bounding box */
- itkGetConstObjectMacro(BoundingBox, BoundingBoxType);
-
- const BoundsArrayType GetBounds() const
- {
- assert(m_BoundingBox.IsNotNull());
- return m_BoundingBox->GetBounds();
- }
-
- /** \brief Set the bounding box Only possible via the BoundsArray
- * to make clear that a copy of the bounding-box is stored,
- * not a reference to it.*/
- virtual void SetBounds(const BoundsArrayType& bounds);
-
- /** \brief Get the extent of the bounding box */
- TScalarType GetExtent(unsigned int direction) const
- {
- assert(direction<NDimensions);
- assert(m_BoundingBox.IsNotNull());
- BoundsArrayType bounds = m_BoundingBox->GetBounds();
- return bounds[direction*2+1]-bounds[direction*2];
- }
-
- /** \brief Set/Get the IndexToObjectTransform */
- itkGetConstObjectMacro(IndexToObjectTransform, TransformType);
- itkGetObjectMacro(IndexToObjectTransform, TransformType);
- itkSetObjectMacro(IndexToObjectTransform, TransformType);
-
- /** \brief Set/Get the ObjectToNodeTransform */
- itkGetConstObjectMacro(ObjectToNodeTransform, TransformType);
- itkGetObjectMacro(ObjectToNodeTransform, TransformType);
- itkSetObjectMacro(ObjectToNodeTransform, TransformType);
-
- /** \brief Set/Get the IndexToWorldTransform */
- itkGetConstObjectMacro(IndexToWorldTransform, TransformType);
- itkGetObjectMacro(IndexToWorldTransform, TransformType);
- itkSetObjectMacro(IndexToWorldTransform, TransformType);
-
-
- /** \brief Get the IndexToNodeTransform
- * This Transform cannot be set, and is just computed internally */
- itkGetConstObjectMacro(IndexToNodeTransform, TransformType);
-
- /** \brief Initialize the geometry frame */
- virtual void Initialize();
-
-protected:
-
- AffineGeometryFrame();
- virtual ~AffineGeometryFrame();
-
- /** \brief used in clone to initialize the newly created geometry */
- virtual void InitializeGeometry(Self * newGeometry) const;
- void SetBoundsArray(const BoundsArrayType& bounds,
- BoundingBoxPointer& boundingBox);
- mutable BoundingBoxPointer m_BoundingBox;
-
- /** \brief Transform from unit coordinates to object coordinates */
- typename TransformType::Pointer m_IndexToObjectTransform;
- typename TransformType::Pointer m_ObjectToNodeTransform;
- typename TransformType::Pointer m_IndexToNodeTransform;
- typename TransformType::Pointer m_IndexToWorldTransform;
-
-private:
- AffineGeometryFrame(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-} // namespace itk
-
-#endif /* __itkAffineGeometryFrame_h */
-
-#endif
diff --git a/Modules/Ext/DataManagement/itkSmartPointerVectorContainer.h b/Modules/Ext/DataManagement/itkSmartPointerVectorContainer.h
deleted file mode 100644
index 797a8c3ece..0000000000
--- a/Modules/Ext/DataManagement/itkSmartPointerVectorContainer.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef __itkSmartPointerVectorContainer_h
-#define __itkSmartPointerVectorContainer_h
-
-/*
-
- Defines a vector container just like from itkSmartPointerVectorContainer.h.
- The important difference ist, that this vector holds SmartPointers
- to object instead of objects themselves.
-
- Major difference to SmartPointerVectorContainer<SmartPointer<Object>>:
-
- When you ask for a ConstIterator you won't get const SmartPointers,
- but a list of const Object*.
-*/
-
-#include "itkObject.h"
-
-#include <utility>
-#include <vector>
-
-namespace itk
-{
-
-/** \class SmartPointerVectorContainer
- * Define a front-end to the STL "vector" container that conforms to the
- * IndexedContainerInterface. This is a full-fleged Object, so
- * there is modification time, debug, and reference count information.
- *
- * Template parameters for SmartPointerVectorContainer:
- *
- * TElementIdentifier =
- * An INTEGRAL type for use in indexing the vector.
- *
- * TElement =
- * The element type stored in the container.
- *
- * \ingroup DataRepresentation
- */
-template <
- typename TElementIdentifier,
- typename TElement
- >
-class SmartPointerVectorContainer:
- public Object,
- public std::vector<itk::SmartPointer<TElement> > /** difference: we handle smart pointers */
-{
-public:
- /** Standard class typedefs. */
- typedef SmartPointerVectorContainer Self;
- typedef Object Superclass;
- typedef SmartPointer<Self> Pointer;
- typedef SmartPointer<const Self> ConstPointer;
-
- /** Save the template parameters. */
- typedef TElementIdentifier ElementIdentifier;
- typedef TElement Element;
- typedef const TElement ConstElement;
- typedef itk::SmartPointer<Element> ElementPointer;
- typedef const itk::SmartPointer<const Element> ConstElementPointer;
-
-private:
- /** Quick access to the STL vector type that was inherited. */
- typedef std::vector<ElementPointer> VectorType;
- typedef typename VectorType::size_type size_type;
- typedef typename VectorType::iterator VectorIterator;
- typedef typename VectorType::const_iterator VectorConstIterator;
-
-protected:
- /** Provide pass-through constructors corresponding to all the STL
- * vector constructors. These are for internal use only since this is also
- * an Object which must be constructed through the "New()" routine. */
- SmartPointerVectorContainer():
- Object(), VectorType() {}
- SmartPointerVectorContainer(size_type n):
- Object(), VectorType(n) {}
- SmartPointerVectorContainer(size_type n, const Element& x):
- Object(), VectorType(n, x) {}
- SmartPointerVectorContainer(const Self& r):
- Object(), VectorType(r) {}
- template <typename InputIterator>
- SmartPointerVectorContainer(InputIterator first, InputIterator last):
- Object(), VectorType(first, last) {}
-
-public:
-
- /** This type is provided to Adapt this container as an STL container */
- typedef VectorType STLContainerType;
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /** Standard part of every itk Object. */
- itkTypeMacro(SmartPointerVectorContainer, Object);
-
- /** Convenient typedefs for the iterator and const iterator. */
- class Iterator;
- class ConstIterator;
-
- /** Cast the container to a STL container type */
- STLContainerType & CastToSTLContainer() {
- return dynamic_cast<STLContainerType &>(*this); }
-
- /** Cast the container to a const STL container type */
- const STLContainerType & CastToSTLConstContainer() const {
- return dynamic_cast<const STLContainerType &>(*this); }
-
- /** Friends to this class. */
- friend class Iterator;
- friend class ConstIterator;
-
- class Iterator
- {
- public:
- Iterator() {}
- Iterator(size_type d, const VectorType* vec, const VectorIterator& i): m_Pos(d), m_Vector(vec), m_Iter(i) {}
-
- ElementPointer& operator* () { return *m_Iter; }
- Element* operator-> () { return m_Iter == m_Vector->end() ? NULL : m_Iter->GetPointer(); }
- ElementPointer& operator++ () { ++m_Pos; ++m_Iter; return *m_Iter; }
- ElementPointer operator++ (int) { Iterator temp(*this); ++m_Pos; ++m_Iter; return *temp; }
- ElementPointer& operator-- () { --m_Pos; --m_Iter; return *this; }
- ElementPointer operator-- (int) { Iterator temp(*this); --m_Pos; --m_Iter; return *temp; }
-
- bool operator == (const Iterator& r) const { return m_Iter == r.m_Iter; }
- bool operator != (const Iterator& r) const { return m_Iter != r.m_Iter; }
- bool operator == (const ConstIterator& r) const { return m_Iter == r.m_Iter; }
- bool operator != (const ConstIterator& r) const { return m_Iter != r.m_Iter; }
-
- /** Get the index into the SmartPointerVectorContainer associated with this iterator. */
- ElementIdentifier Index(void) const { return static_cast<ElementIdentifier>( m_Pos ); }
-
- /** Get the value at this iterator's location in the SmartPointerVectorContainer. */
- Element* Value(void) const { return m_Iter->GetPointer(); }
-
- private:
- size_type m_Pos;
- const VectorType* m_Vector;
- VectorIterator m_Iter;
- friend class ConstIterator;
- };
-
- class ConstIterator
- {
- public:
- ConstIterator() {}
- ConstIterator(size_type d, const VectorType* vec, const VectorConstIterator& i): m_Pos(d), m_Vector(vec), m_Iter(i) {}
- ConstIterator(const Iterator& r): m_Pos(r.m_Pos), m_Vector(r.m_Vector), m_Iter(r.m_Iter) {}
-
- ConstElementPointer operator* () { return ConstElementPointer(m_Iter == m_Vector->end() ? NULL : m_Iter->GetPointer()); }
- ConstElement* operator-> () { return m_Iter == m_Vector->end() ? NULL : m_Iter->GetPointer(); }
- ConstElementPointer operator++ () { ++m_Pos; ++m_Iter; return ConstElementPointer(m_Iter == m_Vector->end() ? NULL : m_Iter->GetPointer()); }
- ConstElementPointer operator++ (int) { ConstIterator temp(*this); ++m_Pos; ++m_Iter; return *temp; }
- ConstElementPointer operator-- () { --m_Pos; --m_Iter; return ConstElementPointer(m_Iter == m_Vector->end() ? NULL : m_Iter->GetPointer()); }
- ConstElementPointer operator-- (int) { ConstIterator temp(*this); --m_Pos; --m_Iter; return *temp; }
-
- ConstIterator& operator = (const Iterator& r) { m_Pos = r.m_Pos; m_Iter = r.m_Iter; return *this; }
-
- bool operator == (const Iterator& r) const { return m_Iter == r.m_Iter; }
- bool operator != (const Iterator& r) const { return m_Iter != r.m_Iter; }
- bool operator == (const ConstIterator& r) const { return m_Iter == r.m_Iter; }
- bool operator != (const ConstIterator& r) const { return m_Iter != r.m_Iter; }
-
- /** Get the index into the SmartPointerVectorContainer associated with this iterator. */
- ElementIdentifier Index(void) const { return static_cast<ElementIdentifier>( m_Pos ); }
-
- /** Get the value at this iterator's location in the SmartPointerVectorContainer. */
- const Element* Value(void) const { return m_Iter->GetPointer(); }
-
- private:
- size_type m_Pos;
- const VectorType* m_Vector;
- VectorConstIterator m_Iter;
- friend class Iterator;
- };
-
- /** Declare the public interface routines. */
- ElementPointer& ElementAt(ElementIdentifier);
- ConstElementPointer ElementAt(ElementIdentifier) const; // no need to return reference, because assignment not allowed!
- ElementPointer& CreateElementAt(ElementIdentifier);
- ConstElementPointer GetElement(ElementIdentifier) const;
- void SetElement(ElementIdentifier, Element*);
- void InsertElement(ElementIdentifier, Element*);
- bool IndexExists(ElementIdentifier) const;
- bool GetElementIfIndexExists(ElementIdentifier, Element**) const;
- void CreateIndex(ElementIdentifier);
- void DeleteIndex(ElementIdentifier);
- ConstIterator Begin(void) const;
- ConstIterator End(void) const;
- Iterator Begin(void);
- Iterator End(void);
- unsigned long Size(void) const;
- void Reserve(ElementIdentifier);
- void Squeeze(void);
- void Initialize(void);
-
-};
-
-} // end namespace itk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "itkSmartPointerVectorContainer.txx"
-#endif
-
-#endif
-
-
diff --git a/Modules/Ext/DataManagement/itkSmartPointerVectorContainer.txx b/Modules/Ext/DataManagement/itkSmartPointerVectorContainer.txx
deleted file mode 100644
index dc8d9feffd..0000000000
--- a/Modules/Ext/DataManagement/itkSmartPointerVectorContainer.txx
+++ /dev/null
@@ -1,316 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-/*===================================================================
-
-This file is based heavily on a corresponding ITK filter.
-
-===================================================================*/
-#ifndef _itkSmartPointerVectorContainer_txx
-#define _itkSmartPointerVectorContainer_txx
-#include "itkSmartPointerVectorContainer.h"
-
-#include "itkNumericTraits.h"
-
-namespace itk
-{
-
-/**
- * Get a reference to the element at the given index.
- * It is assumed that the index exists, and it will not automatically
- * be created.
- *
- * It is assumed that the value of the element is modified through the
- * reference.
- */
-template <typename TElementIdentifier, typename TElement>
-typename SmartPointerVectorContainer< TElementIdentifier , TElement >::ElementPointer&
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::ElementAt(ElementIdentifier id)
-{
- this->Modified();
- return this->VectorType::operator[](id);
-}
-
-/**
- * Get a reference to the element at the given index.
- * It is assumed that the index exists, and it will not automatically
- * be created.
- *
- */
-template <typename TElementIdentifier, typename TElement>
-const typename SmartPointerVectorContainer< TElementIdentifier , TElement >::ConstElementPointer
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::ElementAt(ElementIdentifier id) const
-{
- return ConstElementPointer(this->VectorType::operator[](id));
-}
-
-
-/**
- * Get a reference to the element at the given index.
- * If the element location does not exist, it will be created with a
- * default element value.
- *
- * It is assumed that the value of the element is modified through the
- * reference.
- */
-template <typename TElementIdentifier, typename TElement>
-typename SmartPointerVectorContainer< TElementIdentifier , TElement >::ElementPointer&
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::CreateElementAt(ElementIdentifier id)
-{
- if(id >= this->VectorType::size())
- {
- this->CreateIndex(id);
- }
- this->Modified();
- return this->VectorType::operator[](id);
-}
-
-
-/**
- * Read the element from the given index.
- * It is assumed that the index exists.
- */
-template <typename TElementIdentifier, typename TElement>
-const typename SmartPointerVectorContainer< TElementIdentifier , TElement >::ConstElementPointer
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::GetElement(ElementIdentifier id) const
-{
- return ConstElementPointer(this->VectorType::operator[](id).GetPointer());
-}
-
-
-/**
- * Set the element value at the given index.
- * It is assumed that the index exists.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::SetElement(ElementIdentifier id, Element* element)
-{
- this->VectorType::operator[](id) = element;
- this->Modified();
-}
-
-
-/**
- * Set the element value at the given index.
- * If the element location does not exist, it will be created with a
- * default element value.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::InsertElement(ElementIdentifier id, Element* element)
-{
- if(id >= static_cast<ElementIdentifier>(this->VectorType::size()))
- {
- this->CreateIndex(id);
- }
- this->VectorType::operator[](id) = element;
- this->Modified();
-}
-
-
-/**
- * Check if the index range of the STL vector is large enough to allow the
- * given index without expansion.
- */
-template <typename TElementIdentifier, typename TElement>
-bool
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::IndexExists(ElementIdentifier id) const
-{
- return (NumericTraits<ElementIdentifier>::IsNonnegative(id)
- && (id < this->VectorType::size()));
-}
-
-
-
-/**
- * Check if the given index is in range of the STL vector. If it is not,
- * return false. Otherwise, set the element through the pointer (if it isn't
- * NULL), and return true.
- */
-template <typename TElementIdentifier, typename TElement>
-bool
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::GetElementIfIndexExists(ElementIdentifier id, Element** element) const
-{
- if (NumericTraits<ElementIdentifier>::IsNonnegative(id)
- && (id < this->VectorType::size()))
- {
- if(element)
- {
- *element = this->VectorType::operator[](id).GetPointer();
- }
- return true;
- }
- return false;
-}
-
-
-/**
- * Make sure that the index range of the STL vector is large enough to allow
- * the given index, expanding it if necessary. The index will contain
- * the default element regardless of whether expansion occured.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::CreateIndex(ElementIdentifier id)
-{
- if(id >= static_cast<ElementIdentifier>(this->VectorType::size()))
- {
- /**
- * The vector must be expanded to fit the
- * new id.
- */
- this->VectorType::resize(id+1);
- this->Modified();
- }
- else if(id > 0)
- {
- /**
- * No expansion was necessary. Just overwrite the index's entry with
- * the default element.
- */
- this->VectorType::operator[](id) = NULL;
- this->Modified();
- }
-}
-
-
-/**
- * It doesn't make sense to delete a vector index.
- * Instead, just overwrite the index with the default element.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::DeleteIndex(ElementIdentifier id)
-{
- this->VectorType::operator[](id) = NULL;
- this->Modified();
-}
-
-
-/**
- * Get a begin const iterator for the vector.
- */
-template <typename TElementIdentifier, typename TElement>
-typename SmartPointerVectorContainer< TElementIdentifier , TElement >::ConstIterator
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::Begin(void) const
-{
- return ConstIterator(0, this, this->VectorType::begin());
-}
-
-
-/**
- * Get an end const iterator for the vector.
- */
-template <typename TElementIdentifier, typename TElement>
-typename SmartPointerVectorContainer< TElementIdentifier , TElement >::ConstIterator
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::End(void) const
-{
- return ConstIterator(this->VectorType::size()-1, this, this->VectorType::end());
-}
-
-
-/**
- * Get a begin iterator for the vector.
- */
-template <typename TElementIdentifier, typename TElement>
-typename SmartPointerVectorContainer< TElementIdentifier , TElement >::Iterator
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::Begin(void)
-{
- return Iterator(0, this, this->VectorType::begin());
-}
-
-
-/**
- * Get an end iterator for the vector.
- */
-template <typename TElementIdentifier, typename TElement>
-typename SmartPointerVectorContainer< TElementIdentifier , TElement >::Iterator
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::End(void)
-{
- return Iterator(this->VectorType::size()-1, this, this->VectorType::end());
-}
-
-
-/**
- * Get the number of elements currently stored in the vector.
- */
-template <typename TElementIdentifier, typename TElement>
-unsigned long
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::Size(void) const
-{
- return static_cast<unsigned long>( this->VectorType::size() );
-}
-
-
-/**
- * Clear the elements. The final size will be zero.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::Initialize(void)
-{
- this->VectorType::clear();
-}
-
-
-
-/**
- * Tell the container to allocate enough memory to allow at least
- * as many elements as the size given to be stored. This is NOT
- * guaranteed to actually allocate any memory, but is useful if the
- * implementation of the container allocates contiguous storage.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::Reserve(ElementIdentifier size)
-{
- this->CreateIndex(size-1);
-}
-
-
-/**
- * Tell the container to try to minimize its memory usage for storage of
- * the current number of elements. This is NOT guaranteed to decrease
- * memory usage.
- */
-template <typename TElementIdentifier, typename TElement>
-void
-SmartPointerVectorContainer< TElementIdentifier , TElement >
-::Squeeze(void)
-{
-}
-
-} // end namespace itk
-
-#endif
diff --git a/Modules/Ext/DataManagement/mitkAffineTransformationOperation.cpp b/Modules/Ext/DataManagement/mitkAffineTransformationOperation.cpp
deleted file mode 100644
index 3e20f7dea5..0000000000
--- a/Modules/Ext/DataManagement/mitkAffineTransformationOperation.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkAffineTransformationOperation.h"
-
-mitk::AffineTransformationOperation::AffineTransformationOperation(OperationType operationType,Point3D point, ScalarType angle, int index)
- : mitk::PointOperation(operationType, point, index), m_Angle(angle)
-{
-}
-
-mitk::AffineTransformationOperation::~AffineTransformationOperation(void)
-{
-}
-
-mitk::ScalarType mitk::AffineTransformationOperation::GetAngle()
-{
- return m_Angle;
-}
-
diff --git a/Modules/Ext/DataManagement/mitkAffineTransformationOperation.h b/Modules/Ext/DataManagement/mitkAffineTransformationOperation.h
deleted file mode 100644
index 95171dd660..0000000000
--- a/Modules/Ext/DataManagement/mitkAffineTransformationOperation.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKAFFINETRANSFORMATIONOPERATION_H_HEADER_INCLUDED
-#define MITKAFFINETRANSFORMATIONOPERATION_H_HEADER_INCLUDED
-
-#include "mitkPointOperation.h"
-#include "MitkExtExports.h"
-#include "mitkNumericTypes.h"
-
-namespace mitk {
-
-//##Documentation
-//## @brief Operation, that holds everything necessary for an affine operation.
-//##
-//## @ingroup Undo
-class MitkExt_EXPORT AffineTransformationOperation : public PointOperation
-{
-public:
- AffineTransformationOperation(OperationType operationType, Point3D point, ScalarType angle, int index);
- virtual ~AffineTransformationOperation(void);
- ScalarType GetAngle();
-protected:
- ScalarType m_Angle;
-};
-
-} // namespace mitk
-
-#endif /* MITKAFFINETRANSFORMATIONOPERATION_H_HEADER_INCLUDED */
-
-
diff --git a/Modules/Ext/DataManagement/mitkColorSequenceHalfTones.cpp b/Modules/Ext/DataManagement/mitkColorSequenceHalfTones.cpp
deleted file mode 100644
index e613c942dc..0000000000
--- a/Modules/Ext/DataManagement/mitkColorSequenceHalfTones.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "mitkColorSequenceHalfTones.h"
-#include <vector>
-namespace mitk
-{
-
-ColorSequenceHalfTones::ColorSequenceHalfTones()
-{
- m_ColorIndex = 0;
- m_Color.SetRed(1.0);
- m_Color.SetGreen(0.67);
- m_Color.SetBlue(0.0);
- InitColorList();
-}//end of constructor
-
-
-ColorSequenceHalfTones::~ColorSequenceHalfTones()
-{
-
-}//end of destructor
-
-Color ColorSequenceHalfTones::GetNextColor()
-{
- m_Color = m_ColorList[m_ColorIndex];
-
- if(m_ColorIndex < m_ColorList.size())
- {
- m_ColorIndex++;
- }
- else
- {
- m_ColorIndex = 0;
- }
- return m_Color;
-}//end of GetNextMitkColor()
-
-void ColorSequenceHalfTones::InitColorList()
-{
-
- Color defaultColor, red, green, blue, yellow, magenta, cyan, orange;
- defaultColor.Set(1.0, 0.67, 0.0);
- red.Set(1.0, 0.6, 0.6);
- green.Set(0.6, 1.0, 0.6);
- blue.Set(0.6, 0.6, 1.0);
- yellow.Set(1.0, 1.0, 0.6);
- magenta.Set(1.0, 0.6, 1.0);
- cyan.Set(0.6, 1.0, 1.0);
- orange.Set(1.0, 0.8, 0.6);
- //m_ColorList.push_back(defaultColor);
- m_ColorList.push_back(red);
- m_ColorList.push_back(yellow);
- m_ColorList.push_back(blue);
- m_ColorList.push_back(green);
- m_ColorList.push_back(magenta);
- m_ColorList.push_back(cyan);
- m_ColorList.push_back(orange);
- m_ColorList.push_back(defaultColor);
-
-
-}// end of ColorList
-
-void ColorSequenceHalfTones::GoToBegin()
-{
- m_ColorIndex = 0;
-}
-
-}//end of namespace
-
diff --git a/Modules/Ext/DataManagement/mitkColorSequenceHalfTones.h b/Modules/Ext/DataManagement/mitkColorSequenceHalfTones.h
deleted file mode 100644
index 59c44d426b..0000000000
--- a/Modules/Ext/DataManagement/mitkColorSequenceHalfTones.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef MITKCOLORSEQUENCEHALFTONES_H_URTESEINDEUTIGEKENNUNG_03
-#define MITKCOLORSEQUENCEHALFTONES_H_URTESEINDEUTIGEKENNUNG_03
-
-#include "mitkColorSequence.h"
-#include "MitkExtExports.h"
-
-namespace mitk
-{
- class MitkExt_EXPORT ColorSequenceHalfTones : public ColorSequence
- {
- public:
- ColorSequenceHalfTones();
- virtual ~ColorSequenceHalfTones();
-
- /*!
- \brief method to return another color
- */
- virtual Color GetNextColor();
-
- /*!
- \brief method to set the color-index to begin again
- */
- virtual void GoToBegin();
-
-
- private:
- /*!
- \brief method that fills the pre-defnied colors
- */
- void InitColorList();
-
- /*!
- \brief global color-object that holds the actual color and changes to the next one
- */
- Color m_Color;
-
- /*!
- \brief color-index to iterate through the colors
- */
- unsigned int m_ColorIndex;
-
- /*!
- \brief vector-List with all pre-defined colors
- */
- std::vector<Color> m_ColorList;
-
- };
-
-}
-
-#endif
-
-
diff --git a/Modules/Ext/DataManagement/mitkDataTreeFilterEvents.h b/Modules/Ext/DataManagement/mitkDataTreeFilterEvents.h
deleted file mode 100644
index 0eb74a6d85..0000000000
--- a/Modules/Ext/DataManagement/mitkDataTreeFilterEvents.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITK_DATATREEFILTEREVENTS_H_INCLUDED
-#define MITK_DATATREEFILTEREVENTS_H_INCLUDED
-
-#pragma GCC visibility push(default)
-#include <itkEventObject.h>
-#pragma GCC visibility pop
-#include "MitkExtExports.h"
-
-namespace mitk {
-
-//------ TreeFilterUpdateAllEvent --------------------------------------------------------
-
-#pragma GCC visibility push(default)
-itkEventMacro( TreeFilterUpdateAllEvent, itk::ModifiedEvent );
-itkEventMacro( TreeFilterRemoveAllEvent, itk::ModifiedEvent );
-#pragma GCC visibility pop
-
-//------ TreeFilterItemEvent -------------------------------------------------------------
- class MitkExt_EXPORT TreeFilterItemEvent : public itk::ModifiedEvent
- {
- public:
- typedef TreeFilterItemEvent Self;
- typedef itk::ModifiedEvent Superclass;
-
- TreeFilterItemEvent()
- : m_ChangedItem( NULL ){}
-
- TreeFilterItemEvent( const mitk::DataTreeFilter::Item* item ) :
- m_ChangedItem(item) {}
-
- virtual ~TreeFilterItemEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterItemEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem );
- }
-
- const mitk::DataTreeFilter::Item* GetChangedItem() const
- {
- return m_ChangedItem;
- }
-
- TreeFilterItemEvent(const Self& s) : itk::ModifiedEvent(s), m_ChangedItem(s.m_ChangedItem) {};
-
- protected:
- const mitk::DataTreeFilter::Item* m_ChangedItem;
-
- private:
- void operator=(const Self&);
-
- };
-
-//------ TreeFilterEvent --------------------------------------------------------
- class MitkExt_EXPORT TreeFilterNewItemEvent : public TreeFilterItemEvent
- {
- public:
- typedef TreeFilterNewItemEvent Self;
- typedef TreeFilterItemEvent Superclass;
-
- TreeFilterNewItemEvent() : TreeFilterItemEvent() {}
- TreeFilterNewItemEvent(const mitk::DataTreeFilter::Item* item) : TreeFilterItemEvent(item) {}
-
- virtual ~TreeFilterNewItemEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterNewItemEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem );
- }
-
- TreeFilterNewItemEvent(const Self& s) : TreeFilterItemEvent(s) {};
-
- private:
- void operator=(const Self&);
-
- };
-
-
-//------ TreeFilterItemAddedEvent --------------------------------------------------------
- class MitkExt_EXPORT TreeFilterItemAddedEvent : public TreeFilterItemEvent
- {
- public:
- typedef TreeFilterItemAddedEvent Self;
- typedef TreeFilterItemEvent Superclass;
-
- TreeFilterItemAddedEvent() : TreeFilterItemEvent() {}
- TreeFilterItemAddedEvent(const mitk::DataTreeFilter::Item* item) : TreeFilterItemEvent(item) {}
-
- virtual ~TreeFilterItemAddedEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterItemAddedEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem );
- }
-
- TreeFilterItemAddedEvent(const Self& s) : TreeFilterItemEvent(s) {};
-
- private:
- void operator=(const Self&);
-
- };
-
-//------ TreeFilterSelectionChangedEvent -------------------------------------------------
- class MitkExt_EXPORT TreeFilterSelectionChangedEvent : public TreeFilterItemEvent
- {
- public:
- typedef TreeFilterSelectionChangedEvent Self;
- typedef TreeFilterItemEvent Superclass;
-
- TreeFilterSelectionChangedEvent() : TreeFilterItemEvent() {}
- TreeFilterSelectionChangedEvent(const mitk::DataTreeFilter::Item* item, bool selected) : TreeFilterItemEvent(item), m_Selected(selected) {}
-
- virtual ~TreeFilterSelectionChangedEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterSelectionChangedEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem, m_Selected );
- }
-
- virtual bool IsSelected() const { return m_Selected; }
-
- TreeFilterSelectionChangedEvent(const Self&s) : TreeFilterItemEvent(s) {};
- private:
- void operator=(const Self&);
-
- bool m_Selected;
-
- };
-
- //------ TreeFilterItemChangedEvent ------------------------------------------------------
- class MitkExt_EXPORT TreeFilterItemChangedEvent : public TreeFilterItemEvent
- {
- public:
- typedef TreeFilterItemChangedEvent Self;
- typedef TreeFilterItemEvent Superclass;
-
- TreeFilterItemChangedEvent() : TreeFilterItemEvent() {}
- TreeFilterItemChangedEvent(const mitk::DataTreeFilter::Item* item) : TreeFilterItemEvent(item) {}
-
- virtual ~TreeFilterItemChangedEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterItemChangedEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem );
- }
-
- TreeFilterItemChangedEvent(const Self&s) : TreeFilterItemEvent(s) {};
-
- private:
- void operator=(const Self&);
-
- };
-
-//------ TreeFilterRemoveItemEvent -------------------------------------------------------
- class MitkExt_EXPORT TreeFilterRemoveItemEvent : public TreeFilterItemEvent
- {
- public:
- typedef TreeFilterRemoveItemEvent Self;
- typedef TreeFilterItemEvent Superclass;
-
- TreeFilterRemoveItemEvent() : TreeFilterItemEvent() {}
- TreeFilterRemoveItemEvent(const mitk::DataTreeFilter::Item* item) : TreeFilterItemEvent(item) {}
-
- virtual ~TreeFilterRemoveItemEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterRemoveItemEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem );
- }
-
- TreeFilterRemoveItemEvent(const Self&s) : TreeFilterItemEvent(s) {};
-
- private:
- void operator=(const Self&);
-
- };
-
-//------ TreeFilterRemoveChildrenEvent -------------------------------------------------------
- class MitkExt_EXPORT TreeFilterRemoveChildrenEvent : public TreeFilterItemEvent
- {
- public:
- typedef TreeFilterRemoveChildrenEvent Self;
- typedef TreeFilterItemEvent Superclass;
-
- TreeFilterRemoveChildrenEvent() : TreeFilterItemEvent() {}
- TreeFilterRemoveChildrenEvent(const mitk::DataTreeFilter::Item* item) : TreeFilterItemEvent(item) {}
-
- virtual ~TreeFilterRemoveChildrenEvent() {}
-
- virtual const char * GetEventName() const
- {
- return "TreeFilterRemoveChildrenEvent";
- }
-
- virtual bool CheckEvent(const ::itk::EventObject* e) const
- {
- return dynamic_cast<const Self*>(e);
- }
-
- virtual ::itk::EventObject* MakeObject() const
- {
- return new Self( m_ChangedItem );
- }
-
- TreeFilterRemoveChildrenEvent(const Self&s) : TreeFilterItemEvent(s) {};
-
- private:
- void operator=(const Self&);
-
- };
-}
-
-#endif
-
-
diff --git a/Modules/Ext/DataManagement/mitkDataTreeFilterFunctions.cpp b/Modules/Ext/DataManagement/mitkDataTreeFilterFunctions.cpp
deleted file mode 100644
index f9cafd5028..0000000000
--- a/Modules/Ext/DataManagement/mitkDataTreeFilterFunctions.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include <mitkDataTreeFilterFunctions.h>
-#include "mitkDataNode.h"
-
-namespace mitk
-{
-
-bool DataTreeFilterFunction::operator()(DataNode* node) const
-{
- return NodeMatches(node);
-}
-
-bool IsDataNode::NodeMatches(DataNode* node) const
-{
- return ( node != NULL );
-}
-
-DataTreeFilterFunction* IsDataNode::Clone() const
-{
- return new IsDataNode();
-}
-
-bool IsGoodDataNode::NodeMatches(DataNode* node) const
-{
- return ( node != NULL && node->GetData() );
-}
-
-DataTreeFilterFunction* IsGoodDataNode::Clone() const
-{
- return new IsGoodDataNode();
-}
-
-bool IsInResultSet::NodeMatches(DataNode* node) const
-{
- if ((node == NULL) || (m_ResultSet.empty()))
- return false;
-
- return (std::find(m_ResultSet.begin(), m_ResultSet.end(), node) != m_ResultSet.end()); // search for node in resultset
-}
-
-DataTreeFilterFunction* IsInResultSet::Clone() const
-{
- return new IsInResultSet(m_ResultSet);
-}
-
-} // namespace
-
diff --git a/Modules/Ext/DataManagement/mitkDataTreeFilterFunctions.h b/Modules/Ext/DataManagement/mitkDataTreeFilterFunctions.h
deleted file mode 100644
index 76bd5d9dae..0000000000
--- a/Modules/Ext/DataManagement/mitkDataTreeFilterFunctions.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITK_DATATREEFILTERFUNCTOINS_H_INCLUDED
-#define MITK_DATATREEFILTERFUNCTOINS_H_INCLUDED
-
-#include <mitkDataNode.h>
-#include "MitkExtExports.h"
-
-#include <mitkProperties.h>
-#include <mitkDataStorage.h>
-
-namespace mitk
-{
- class DataNode;
-
- /*! \brief Base class for all filter function that are accepted by mitk::DataTreeFilter.
-
- Subclasses are required to implement the Clone() method, which should return a copy of
- the object, and the NodeMatches() method. NodeMatches() will receive a
- mitk::DataNode* everytime it is called, and should return true. <b>This pointer can be NULL</b>.
- */
- class MitkExt_EXPORT DataTreeFilterFunction
- {
- public:
- virtual ~DataTreeFilterFunction() {}
- virtual bool operator()(DataNode*) const;
- virtual bool NodeMatches(DataNode*) const = 0;
- virtual DataTreeFilterFunction* Clone() const = 0;
- };
-
- /*! \brief tests the data entry of nodes for a specific type (given here as template parameter).
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataType<mitk::Image>() );
- \endcode
- */
- template <class T>
- class IsBaseDataType : public DataTreeFilterFunction
- {
- public:
- virtual bool NodeMatches(DataNode* node) const
- {
- return ( node != NULL && node->GetData() && dynamic_cast<T*>(node->GetData()) );
- }
-
- virtual DataTreeFilterFunction* Clone() const
- {
- return new IsBaseDataType<T>();
- }
-
- virtual ~IsBaseDataType() {}
- };
-
- /*! \brief Tests the data entry of nodes for a specific type (given here as template parameter) AND having a given property.
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataTypeWithProperty<mitk::Surface>("volume") );
- \endcode
- */
- template <class T>
- class IsBaseDataTypeWithProperty : public DataTreeFilterFunction
- {
- public:
-
- IsBaseDataTypeWithProperty(const char* propertyName)
- :m_PropertyName(propertyName)
- {
- }
-
- virtual bool NodeMatches(DataNode* node) const
- {
- return ( node != NULL && node->GetData() // node is not NULL, and node->GetData is also not NULL
- && dynamic_cast<T*>(node->GetData() ) // data is of a certain type
- && ( node->GetProperty(m_PropertyName.c_str())!= NULL // there is a certain property
- )
- );
- }
-
- virtual DataTreeFilterFunction* Clone() const
- {
- return new IsBaseDataTypeWithProperty<T>(m_PropertyName.c_str());
- }
-
- virtual ~IsBaseDataTypeWithProperty() {}
-
- private:
-
- std::string m_PropertyName;
- };
-
- /*! \brief Tests the data entry of nodes for a specific type (given here as template parameter) AND having a TRUE BoolProperty.
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataTypeWithBoolProperty<mitk::Image>("segmentation") );
- \endcode
- */
- template <class T>
- class IsBaseDataTypeWithBoolProperty : public DataTreeFilterFunction
- {
- public:
-
- IsBaseDataTypeWithBoolProperty(const char* propertyName)
- :m_PropertyName(propertyName)
- {
- }
-
- virtual bool NodeMatches(DataNode* node) const
- {
- bool propVal(false);
- return ( node != NULL && node->GetData() // node is not NULL, and node->GetData is also not NULL
- && dynamic_cast<T*>( node->GetData() ) // data is of a certain type
- && node->GetPropertyValue(m_PropertyName.c_str(), propVal) // there is a certain BoolProperty
- && propVal
- );
- }
-
- virtual DataTreeFilterFunction* Clone() const
- {
- return new IsBaseDataTypeWithBoolProperty<T>(m_PropertyName.c_str());
- }
-
- virtual ~IsBaseDataTypeWithBoolProperty() {}
-
- private:
-
- std::string m_PropertyName;
- };
-
-
- /*! \brief Tests the data entry of nodes for a specific type (given here as template parameter) AND for NOT having a given property (or it being a false bool property).
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataTypeWithoutProperty<mitk::Image>("segmentation") );
- \endcode
- */
- template <class T>
- class IsBaseDataTypeWithoutProperty : public DataTreeFilterFunction
- {
- public:
-
- IsBaseDataTypeWithoutProperty(const char* propertyName)
- :m_PropertyName(propertyName)
- {
- }
-
- virtual bool NodeMatches(DataNode* node) const
- {
- bool propVal(false);
- bool propertyExists(false);
-
- if (node)
- propertyExists = node->GetPropertyValue(m_PropertyName.c_str(), propVal );
-
- return ( node != NULL && node->GetData() // node is not NULL, and node->GetData is also not NULL
- && dynamic_cast<T*>(node->GetData() ) // data is of a certain type
- && ( !propertyExists || !propVal )); // the property does not exist, OR its value is false
- }
-
- virtual DataTreeFilterFunction* Clone() const
- {
- return new IsBaseDataTypeWithoutProperty<T>(m_PropertyName.c_str());
- }
-
- virtual ~IsBaseDataTypeWithoutProperty() {}
-
- private:
-
- std::string m_PropertyName;
- };
-
-
- // some default filters in mitk:: namespace for use by clients of mitk::DataTreeFilter
-
- /*! \brief Accepts all nodes (accepts nodes that are not NULL).
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataTypeWithoutProperty<mitk::Image>("segmentation") );
- \endcode
- */
- class MitkExt_EXPORT IsDataNode : public DataTreeFilterFunction
- {
- public:
- virtual ~IsDataNode() {}
- virtual bool NodeMatches(DataNode*) const;
- virtual DataTreeFilterFunction* Clone() const;
- };
-
- /*! \brief Accepts all data objects (accepts nodes that have associated mitk::BaseData (tested via GetData)).
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataTypeWithoutProperty<mitk::Image>("segmentation") );
- \endcode
- */
- class MitkExt_EXPORT IsGoodDataNode : public DataTreeFilterFunction
- {
- public:
- virtual ~IsGoodDataNode() {}
- virtual bool NodeMatches(DataNode*) const;
- virtual DataTreeFilterFunction* Clone() const;
- };
-
- /*! \brief Accepts all data objects (accepts nodes that have associated mitk::BaseData (tested via GetData)).
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsBaseDataTypeWithoutProperty<mitk::Image>("segmentation") );
- \endcode
- */
- class MitkExt_EXPORT IsInResultSet : public DataTreeFilterFunction
- {
- public:
- IsInResultSet( std::set<const DataNode*> rs )
- :m_ResultSet(rs)
- {
- }
-
- IsInResultSet(const DataStorage::SetOfObjects* rs)
- {
- if (rs)
- {
- for (DataStorage::SetOfObjects::const_iterator iter = rs->begin();
- iter != rs->end();
- ++iter)
- {
- m_ResultSet.insert( iter->GetPointer() );
- }
- }
- }
-
- virtual ~IsInResultSet() {}
- virtual bool NodeMatches(DataNode*) const;
- virtual DataTreeFilterFunction* Clone() const;
- protected:
- //DataStorage::SetOfObjects::ConstPointer m_ResultSet;
- std::set<const DataNode*> m_ResultSet;
- };
-
- /*! \brief Tests if the node contains an image with a specified dimensionality (template parameter)
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::ImageWithDimensionAndProperty<3>("volume") );
- \endcode
- */
- template <unsigned int DIM>
- class IsImageWithDimensionAndWithoutProperty : public DataTreeFilterFunction
- {
- public:
-
- IsImageWithDimensionAndWithoutProperty(const char* propertyName)
- :m_PropertyName(propertyName)
- {
- }
-
- virtual bool NodeMatches(DataNode* node) const
- {
- return ( node != NULL && node->GetData() // node is not NULL, and node->GetData is also not NULL
- && dynamic_cast<mitk::Image*>(node->GetData() ) // data is an image
- && (dynamic_cast<mitk::Image*>(node->GetData() )->GetDimension() == DIM)
- && ( node->GetProperty(m_PropertyName.c_str()) == NULL // there is a certain property
- )
- );
- }
-
- virtual DataTreeFilterFunction* Clone() const
- {
- return new IsImageWithDimensionAndWithoutProperty<DIM>(m_PropertyName.c_str());
- }
-
- virtual ~IsImageWithDimensionAndWithoutProperty() {}
-
- private:
-
- std::string m_PropertyName;
- };
-
- /*! \brief Tests if the node contains an image with a dimensionality greater or equal to the template parameter
-
- To be used with mitk::DataTreeFilter, e.g.
- \code
- treeFilter->SetFilter( mitk::IsImageWithMinimumDimension<3>() );
- \endcode
- */
- template <unsigned int DIM>
- class IsImageWithMinimumDimension : public DataTreeFilterFunction
- {
- public:
-
- virtual bool NodeMatches(DataNode* node) const
- {
- return ( node != NULL && node->GetData() // node is not NULL, and node->GetData is also not NULL
- && dynamic_cast<mitk::Image*>(node->GetData() ) // data is an image
- && (dynamic_cast<mitk::Image*>(node->GetData() )->GetDimension() >= DIM)
- );
- }
-
- virtual DataTreeFilterFunction* Clone() const
- {
- return new IsImageWithMinimumDimension<DIM>();
- }
-
- virtual ~IsImageWithMinimumDimension() {}
- };
-
-} // namespace mitk
-
-#endif
-// vi: textwidth=90
-
-
diff --git a/Modules/Ext/DataManagement/mitkDataTreeHelper.cpp b/Modules/Ext/DataManagement/mitkDataTreeHelper.cpp
deleted file mode 100644
index 76249f7b7a..0000000000
--- a/Modules/Ext/DataManagement/mitkDataTreeHelper.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkDataTreeHelper.h"
-
-mitk::DataTreeIteratorClone mitk::DataTreeHelper::FindIteratorToNode(
- mitk::DataTreeBase* tree,
- const mitk::DataNode* node)
-{
- if(tree == NULL)
- return NULL;
-
- DataTreeIteratorClone pos = DataTreePreOrderIterator(tree);
-
- while ( !pos->IsAtEnd() )
- {
- if ( pos->Get().GetPointer() == node )
- return pos;
- ++pos;
- }
- return pos;
-}
-
-mitk::DataTreeIteratorClone mitk::DataTreeHelper::FindIteratorToNode(
- const mitk::DataTreeIteratorBase* startPosition,
- const mitk::DataNode* node
- )
-{
- DataTreeIteratorClone pos = *startPosition;
-
- while ( !pos->IsAtEnd() )
- {
- if ( pos->Get().GetPointer() == node )
- return pos;
- ++pos;
- }
- return pos;
-}
-
-mitk::DataTreeIteratorClone mitk::DataTreeHelper::GetNamedChild(mitk::DataTreeIteratorBase* iterator, std::string name)
-{
- mitk::DataTreeChildIterator childIterator(*iterator);
- while (! childIterator.IsAtEnd() )
- {
- mitk::DataNode* node = childIterator.Get();
- std::string nodeName;
- if (node && node->GetName(nodeName))
- {
- if (nodeName == name)
- {
- return DataTreeIteratorClone(childIterator);
- }
- }
- ++childIterator;
- }
- return DataTreeIteratorClone(NULL);
-}
diff --git a/Modules/Ext/DataManagement/mitkDelegateManager.cpp b/Modules/Ext/DataManagement/mitkDelegateManager.cpp
deleted file mode 100644
index 0029551f1b..0000000000
--- a/Modules/Ext/DataManagement/mitkDelegateManager.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkDelegateManager.h"
-
-mitk::DelegateManager::DelegateManager()
-{
-}
-mitk::DelegateManager* mitk::DelegateManager::GetInstance()
-{
- static mitk::DelegateManager _DelegateManager;
- return &_DelegateManager;
-}
-
-void mitk::DelegateManager::SetCommand( const std::string& _CommandID, mitk::MessageAbstractDelegate<>* _Command)
-{
- MessageAbstractDelegate<>* _ExistingCommand = this->GetCommand(_CommandID);
- // delete existing MessageAbstractDelegate for id, but only if the existing MessageAbstractDelegate is not the same as the
- // MessageAbstractDelegate parameter
- if(_ExistingCommand && _ExistingCommand != _Command)
- {
- m_CommandMap.erase(_CommandID);
- delete _ExistingCommand;
- _ExistingCommand = 0;
- }
- m_CommandMap[_CommandID] = _Command;
-}
-
-bool mitk::DelegateManager::RemoveCommand( const std::string& _CommandID )
-{
- MessageAbstractDelegate<>* _ExistingCommand = this->GetCommand(_CommandID);
- if(_ExistingCommand)
- {
- m_CommandMap.erase(_CommandID);
- delete _ExistingCommand;
- _ExistingCommand = 0;
- return true;
- }
- return false;
-}
-
-mitk::MessageAbstractDelegate<>* mitk::DelegateManager::GetCommand( const std::string& _CommandID ) const
-{
- std::map<std::string, MessageAbstractDelegate<>*>::const_iterator it = m_CommandMap.find(_CommandID);
- return (it == m_CommandMap.end()) ? 0: it->second;
-}
-
-mitk::DelegateManager::~DelegateManager()
-{
- // delete all commands
- for(std::map<std::string, MessageAbstractDelegate<>*>::iterator it=m_CommandMap.begin(); it!=m_CommandMap.end()
- ; it++)
- {
- delete it->second;
- it->second = 0;
- }
-
- m_CommandMap.clear();
-}
diff --git a/Modules/Ext/DataManagement/mitkDelegateManager.h b/Modules/Ext/DataManagement/mitkDelegateManager.h
deleted file mode 100644
index 5dd7b360b3..0000000000
--- a/Modules/Ext/DataManagement/mitkDelegateManager.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKDelegateManager_H_HEADER_INCLUDED
-#define MITKDelegateManager_H_HEADER_INCLUDED
-
-#include "mitkMessage.h"
-#include "MitkExtExports.h"
-#include "mitkCommon.h"
-
-#include <map>
-
-namespace mitk
-{
-
- ///
- /// \brief Renames the mitk::MessageAbstractDelegate, which is a Functor to a simple function
- /// with no params, to "Command". This should emphasize that it is not used as an event
- /// function but rather as a command.
- ///
- //typedef MessageAbstractDelegate Command;
-
- ///
- /// \class DelegateManager
- /// \brief A class that stores commands (= mitk::Message) via a unique identifier.
- /// One could also say it is an Event Multiplexer.
- ///
- ///
- class MitkExt_EXPORT DelegateManager
- {
- public:
- ///
- /// \brief Singleton pattern.
- ///
- static DelegateManager* GetInstance();
- ///
- /// \brief Adds or overwrites a Command. *Attention*: This is class is the owner of the Command.
- /// Thus whenever a command is overwritten, the old Command is deleted!
- ///
- void SetCommand(const std::string& _CommandID, MessageAbstractDelegate<>*);
- ///
- /// \brief Removes and *deletes* the Command with the given id.
- ///
- bool RemoveCommand(const std::string& _CommandID);
- ///
- /// \brief Returns the Command with the given id or NULL if the _CommandID is unknown.
- ///
- MessageAbstractDelegate<>* GetCommand(const std::string& _CommandID) const;
- ///
- /// \brief Dtor: Deletes all commands and clears m_CommandMap.
- ///
- virtual ~DelegateManager();
- protected:
- ///
- /// \brief Singleton pattern: protected Ctor.
- ///
- DelegateManager();
- ///
- /// \brief Maps IDs to Commands.
- ///
- std::map<std::string, MessageAbstractDelegate<>*> m_CommandMap;
-
- };
-}
-
-
-#endif /* MITKDelegateManager_H_HEADER_INCLUDED */
-
-
diff --git a/Modules/Ext/DataManagement/mitkDrawOperation.cpp b/Modules/Ext/DataManagement/mitkDrawOperation.cpp
deleted file mode 100755
index d40057251f..0000000000
--- a/Modules/Ext/DataManagement/mitkDrawOperation.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include <mitkDrawOperation.h>
-
-
-mitk::DrawOperation::DrawOperation(OperationType operationType, Point3D point, Point3D last_point, int draw_state, int radius)
-: Operation(operationType), m_Point(point), m_LastPoint(last_point), m_DrawState(draw_state), m_Radius(radius)
-{}
-
-
-mitk::DrawOperation::~DrawOperation()
-{
-}
-
-
-mitk::Point3D mitk::DrawOperation::GetPoint()
-{
- return m_Point;
-}
-
-mitk::Point3D mitk::DrawOperation::GetLastPoint()
-{
- return m_LastPoint;
-}
-
-int mitk::DrawOperation::GetDrawState()
-{
- return m_DrawState;
-}
-
-int mitk::DrawOperation::GetRadius()
-{
- return m_Radius;
-}
-
-mitk::SeedsImage::Pointer mitk::DrawOperation::GetSeedsImage()
-{
- return m_SeedsImage;
-}
-
-mitk::SeedsImage::Pointer mitk::DrawOperation::GetLastSeedsImage()
-{
- return m_LastSeedsImage;
-}
diff --git a/Modules/Ext/DataManagement/mitkDrawOperation.h b/Modules/Ext/DataManagement/mitkDrawOperation.h
deleted file mode 100755
index eb7b818f9b..0000000000
--- a/Modules/Ext/DataManagement/mitkDrawOperation.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKDRAWOPERATION_H
-#define MITKDRAWOPERATION_H
-
-#include <mitkCommon.h>
-#include "MitkExtExports.h"
-#include <mitkOperation.h>
-#include <mitkNumericTypes.h>
-#include <mitkImage.h>
-#include <mitkSeedsImage.h>
-
-namespace mitk {
-
-//##Documentation
-//## @brief DrawOperation, that handles all actions on seeds.
-//##
-//## Stores everything for adding and deleting seeds.
-//## @ingroup Undo
-class MitkExt_EXPORT DrawOperation : public Operation
-{
- public:
- //##Documentation
- //##@brief DrawOperation, that handles all actions on seeds.
- //##
- //## @param operationType is the type of that operation (see mitkOperation.h; e.g. move or add; Information for StateMachine::ExecuteOperation());
- //## @param point is the information of the seedpoint to add to the seedsimage
- //## @param last_point is the information of the point added before
- //## @param draw_state represents the seeds type e.g foreground or background seeds
- //## @param radius is the radius of seeds
- DrawOperation(OperationType operationType, Point3D point, Point3D last_point, int draw_state, int radius);
-
- virtual ~DrawOperation();
-
- Point3D GetPoint();
-
- Point3D GetLastPoint();
-
- int GetDrawState();
-
- int GetRadius();
-
- SeedsImage::Pointer GetSeedsImage();
-
- SeedsImage::Pointer GetLastSeedsImage();
-
- private:
- Point3D m_Point;
- Point3D m_LastPoint;
-
- int m_DrawState;
- int m_Radius;
-
- SeedsImage::Pointer m_SeedsImage;
- SeedsImage::Pointer m_LastSeedsImage;
-
-};
-}//namespace mitk
-#endif /* MITKDRAWOPERATION_H*/
-
-
diff --git a/Modules/Ext/DataManagement/mitkExternAbstractTransformGeometry.cpp b/Modules/Ext/DataManagement/mitkExternAbstractTransformGeometry.cpp
deleted file mode 100644
index a0dd3e6949..0000000000
--- a/Modules/Ext/DataManagement/mitkExternAbstractTransformGeometry.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkExternAbstractTransformGeometry.h"
-#include <vtkAbstractTransform.h>
-
-mitk::ExternAbstractTransformGeometry::ExternAbstractTransformGeometry()
-{
-}
-mitk::ExternAbstractTransformGeometry::ExternAbstractTransformGeometry(const ExternAbstractTransformGeometry& other) : Superclass(other)
-{
-}
-
-mitk::ExternAbstractTransformGeometry::~ExternAbstractTransformGeometry()
-{
-}
-
-void mitk::ExternAbstractTransformGeometry::SetVtkAbstractTransform(vtkAbstractTransform* aVtkAbstractTransform)
-{
- Superclass::SetVtkAbstractTransform(aVtkAbstractTransform);
-}
-
-void mitk::ExternAbstractTransformGeometry::SetPlane(const mitk::PlaneGeometry* aPlane)
-{
- Superclass::SetPlane(aPlane);
-}
-
-void mitk::ExternAbstractTransformGeometry::SetParametricBounds(const BoundingBox::BoundsArrayType& bounds)
-{
- Superclass::SetParametricBounds(bounds);
- //@warning affine-transforms and bounding-box should be set by specific sub-classes!
- SetBounds(bounds);
-
- if(m_Plane.IsNotNull())
- {
- m_Plane->SetSizeInUnits(bounds[1]-bounds[0], bounds[3]-bounds[2]);
- m_Plane->SetBounds(bounds);
- }
-}
-
-itk::LightObject::Pointer mitk::ExternAbstractTransformGeometry::InternalClone() const
-{
- Self::Pointer newGeometry = new ExternAbstractTransformGeometry(*this);
- newGeometry->UnRegister();
- return newGeometry.GetPointer();
-}
-
diff --git a/Modules/Ext/DataManagement/mitkExternAbstractTransformGeometry.h b/Modules/Ext/DataManagement/mitkExternAbstractTransformGeometry.h
deleted file mode 100644
index 672729b2ac..0000000000
--- a/Modules/Ext/DataManagement/mitkExternAbstractTransformGeometry.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKEXTERNABSTRACTTRANSFORMPLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
-#define MITKEXTERNABSTRACTTRANSFORMPLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkAbstractTransformGeometry.h"
-
-namespace mitk {
-
-//##Documentation
-//## @brief Identical with AbstractTransformGeometry, except that
-//## it can be externally configured.
-//##
-//## In contrast to its superclass (AbstractTransformGeometry), this class
-//## provides write access to the vtkAbstractTransform and m_Plane.
-//## @note The PlaneGeometry is cloned, @em not linked/referenced.
-//## @note The bounds of the PlaneGeometry are used as the parametric bounds.
-//## @sa AbstractTransformGeometry
-//## @ingroup Geometry
-class MitkExt_EXPORT ExternAbstractTransformGeometry : public AbstractTransformGeometry
-{
-public:
- mitkClassMacro(ExternAbstractTransformGeometry, AbstractTransformGeometry);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- //##Documentation
- //## @brief Set the vtkAbstractTransform (stored in m_VtkAbstractTransform)
- virtual void SetVtkAbstractTransform(vtkAbstractTransform* aVtkAbstractTransform);
-
- //##Documentation
- //## @brief Set the rectangular area that is used for transformation by
- //## m_VtkAbstractTransform and therewith defines the 2D manifold described by
- //## ExternAbstractTransformGeometry
- //##
- //## @note The bounds of the PlaneGeometry are used as the parametric bounds.
- //## @note The PlaneGeometry is cloned, @em not linked/referenced.
- virtual void SetPlane(const mitk::PlaneGeometry* aPlane);
-
- virtual void SetParametricBounds(const BoundingBox::BoundsArrayType& bounds);
-
- virtual itk::LightObject::Pointer InternalClone() const;
-
-protected:
-
- ExternAbstractTransformGeometry();
- ExternAbstractTransformGeometry(const ExternAbstractTransformGeometry& other);
- virtual ~ExternAbstractTransformGeometry();
-
-};
-
-} // namespace mitk
-#endif /* MITKEXTERNABSTRACTTRANSFORMPLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Modules/Ext/DataManagement/mitkFrameOfReferenceUIDManager.cpp b/Modules/Ext/DataManagement/mitkFrameOfReferenceUIDManager.cpp
deleted file mode 100644
index 6e26356055..0000000000
--- a/Modules/Ext/DataManagement/mitkFrameOfReferenceUIDManager.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkFrameOfReferenceUIDManager.h"
-
-std::vector<std::string> mitk::FrameOfReferenceUIDManager::m_FrameOfReferenceUIDs;
-
-mitk::FrameOfReferenceUIDManager::FrameOfReferenceUIDManager()
-{
- if(m_FrameOfReferenceUIDs.size()==0)
- m_FrameOfReferenceUIDs.push_back("");
-}
-
-mitk::FrameOfReferenceUIDManager::~FrameOfReferenceUIDManager()
-{
- m_FrameOfReferenceUIDs.clear();
-}
-
-unsigned int mitk::FrameOfReferenceUIDManager::AddFrameOfReferenceUID(const char* forUID)
-{
- std::string forUIDstring=forUID;
- unsigned int i;
- size_t size;
- size = m_FrameOfReferenceUIDs.size();
- std::vector<std::string>::iterator it;
- for(i=0, it=m_FrameOfReferenceUIDs.begin(); i<size; ++i,++it)
- {
- if(*it==forUIDstring)
- return i;
- }
-//itkGenericOutputMacro(<<"adding uid "<<forUIDstring<< " as id "<<i);
- m_FrameOfReferenceUIDs.push_back(forUIDstring);
- return i;
-}
-
-const char* mitk::FrameOfReferenceUIDManager::GetFrameOfReferenceUID(unsigned int geometryFrameOfReferenceID)
-{
- if(geometryFrameOfReferenceID >= m_FrameOfReferenceUIDs.size())
- return NULL;
- return m_FrameOfReferenceUIDs[geometryFrameOfReferenceID].c_str();
-}
-
-static mitk::FrameOfReferenceUIDManager AddStandardFOR;
diff --git a/Modules/Ext/DataManagement/mitkFrameOfReferenceUIDManager.h b/Modules/Ext/DataManagement/mitkFrameOfReferenceUIDManager.h
deleted file mode 100644
index 10f0d98c19..0000000000
--- a/Modules/Ext/DataManagement/mitkFrameOfReferenceUIDManager.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef FRAMEOFREFERENCEUIDMANAGER_H_HEADER_INCLUDED_C1EBD0AD
-#define FRAMEOFREFERENCEUIDMANAGER_H_HEADER_INCLUDED_C1EBD0AD
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include <vector>
-#include <string>
-
-namespace mitk {
-
-//##Documentation
-//## @brief Manager to map the internal FrameOfReferenceID of
-//## the Geometry3D (Geometry3D::m_FrameOfReferenceID) to a
-//## DICOM FrameOfReferenceUID
-//##
-class MitkExt_EXPORT FrameOfReferenceUIDManager
-{
-public:
- typedef std::string FrameOfReferenceUIDType;
-private:
- static std::vector<FrameOfReferenceUIDType> m_FrameOfReferenceUIDs;
-public:
- static unsigned int AddFrameOfReferenceUID(const char* forUID);
- static const char* GetFrameOfReferenceUID(unsigned int geometryFrameOfReferenceID);
- FrameOfReferenceUIDManager();
- ~FrameOfReferenceUIDManager();
-};
-
-} // namespace mitk
-
-#endif /* GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Modules/Ext/DataManagement/mitkItkBaseDataAdapter.cpp b/Modules/Ext/DataManagement/mitkItkBaseDataAdapter.cpp
deleted file mode 100644
index ba78ad15cd..0000000000
--- a/Modules/Ext/DataManagement/mitkItkBaseDataAdapter.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkItkBaseDataAdapter.h"
-
-namespace mitk {
-
-void ItkBaseDataAdapter::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
- os << indent << "ItkBaseDataAdapter:" << std::endl;
- if(m_ItkDataObject.IsNull())
- {
- os << indent << "No DataObject!" << std::endl;
- }
- else
- {
- m_ItkDataObject->Print(os, indent);
- }
-}
-
-}
diff --git a/Modules/Ext/DataManagement/mitkItkBaseDataAdapter.h b/Modules/Ext/DataManagement/mitkItkBaseDataAdapter.h
deleted file mode 100644
index ebda75e49b..0000000000
--- a/Modules/Ext/DataManagement/mitkItkBaseDataAdapter.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkBaseData.h"
-#include "MitkExtExports.h"
-
-#include <itkDataObject.h>
-
-namespace mitk {
-
-/**
- * \brief Small class to store itk::DataObjects in the mitk::DataStorage.
- *
- * This class can used to store any itk::DataObject in the DataStorage.
- * Please be aware that these objects cannot be visualized via mappers.
- * The user of this class must care himself for type safety.
- **/
-class MitkExt_EXPORT ItkBaseDataAdapter : public BaseData
-{
-public:
- mitkClassMacro(ItkBaseDataAdapter, BaseData);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /** Typedef for the data object */
- typedef itk::DataObject DataType;
-
- /** Returns the data object. **/
- itkGetObjectMacro(ItkDataObject, DataType);
- /** Sets the data object. **/
- itkSetObjectMacro(ItkDataObject, DataType);
-
- virtual void SetRequestedRegionToLargestPossibleRegion() {}
- virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() { return false; }
- virtual bool VerifyRequestedRegion() { return true; }
- virtual void SetRequestedRegion( const itk::DataObject*) {}
-
-protected:
- DataType::Pointer m_ItkDataObject;
-
- virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
-};
-
-}
diff --git a/Modules/Ext/DataManagement/mitkLine.txx b/Modules/Ext/DataManagement/mitkLine.txx
deleted file mode 100644
index adb4d283ac..0000000000
--- a/Modules/Ext/DataManagement/mitkLine.txx
+++ /dev/null
@@ -1,85 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkLine.h"
-#include <itkProcessObject.h>
-#include <itkSmartPointerForwardReference.txx>
-
-
-//##ModelId=3E639CD30201
-mitk::Line::Line()
-{
- m_SlicedGeometry = SlicedGeometry3D::New();
- SetGeometry(m_SlicedGeometry);
- m_SlicedGeometry->Initialize(1);
-}
-
-//##ModelId=3E639CD30233
-mitk::Line::~Line()
-{
-}
-
-//##ModelId=3E6423D2030E
-void mitk::Line::SetGeometry2D(mitk::Geometry2D *geometry2d)
-{
- m_SlicedGeometry->SetGeometry2D(geometry2d, 0);
- m_Geometry2D=geometry2d;
- Modified();
-}
-
-//##ModelId=3E66CC5A0295
-void mitk::Line::UpdateOutputInformation()
-{
- SetPipelineMTime(m_Geometry2D->GetMTime());
- if (this->GetSource())
- {
- this->GetSource()->UpdateOutputInformation();
- }
-}
-
-//##ModelId=3E66CC5A02B4
-void mitk::Line::SetRequestedRegionToLargestPossibleRegion()
-{
-
-}
-
-//##ModelId=3E66CC5A02D2
-bool mitk::Line::RequestedRegionIsOutsideOfTheBufferedRegion()
-{
- if(m_Geometry2D.IsNull()) return true;
-
- return false;
-}
-
-//##ModelId=3E66CC5A02F0
-bool mitk::Line::VerifyRequestedRegion()
-{
- if(m_Geometry2D.IsNull()) return false;
-
- return true;
-}
-
-//##ModelId=3E66CC5A030E
-void mitk::Line::SetRequestedRegion(itk::DataObject *data)
-{
-
-}
-
-//##ModelId=3E67D85E00B7
-void mitk::Line::CopyInformation(const itk::DataObject *data)
-{
-}
-
diff --git a/Modules/Ext/DataManagement/mitkNamedPoint.h b/Modules/Ext/DataManagement/mitkNamedPoint.h
deleted file mode 100644
index fa983c10cf..0000000000
--- a/Modules/Ext/DataManagement/mitkNamedPoint.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITK_NAMED_POINT_H
-#define MITK_NAMED_POINT_H
-
-#include <mitkNumericTypes.h>
-#include <string>
-
-namespace mitk {
-
-class NamedPoint{
-
- std::string m_Name;
- mitk::Point3D m_Point;
-
-public:
-
- /**
- *
- */
- NamedPoint() {
- };
-
- /**
- *
- */
- NamedPoint( const NamedPoint& namedPoint )
- : m_Name( namedPoint.m_Name ), m_Point( namedPoint.m_Point ) {
-
- };
-
- /**
- *
- */
- NamedPoint( const std::string name, const Point3D& point )
- : m_Name( name ), m_Point( point ) {
-
- };
-
-
- /**
- *
- */
- const std::string& GetName() const {
-
- return m_Name;
- };
-
- /**
- *
- */
- void SetName( const std::string& name ) {
-
- m_Name = name;
- };
-
- /**
- *
- */
- const Point3D& GetPoint() const {
-
- return m_Point;
- };
-
- /**
- *
- */
- void SetPoint( const Point3D& point ) {
-
- m_Point = point;
- };
-};
-
-} // mitk
-#endif // MITK_NAMED_POINT_H
diff --git a/Modules/Ext/DataManagement/mitkObjectSet.cpp b/Modules/Ext/DataManagement/mitkObjectSet.cpp
deleted file mode 100644
index f123bc1d48..0000000000
--- a/Modules/Ext/DataManagement/mitkObjectSet.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "mitkObjectSet.h"
diff --git a/Modules/Ext/DataManagement/mitkPropertyManager.cpp b/Modules/Ext/DataManagement/mitkPropertyManager.cpp
deleted file mode 100644
index 8dfb9fd904..0000000000
--- a/Modules/Ext/DataManagement/mitkPropertyManager.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkPropertyManager.h"
-#include "mitkProperties.h"
-#include <limits>
-
-mitk::PropertyManager::PropertyManager()
-{
- m_DefaultPropertyNameSet.insert(std::string("visible"));
- m_PropertyLimits.insert(std::make_pair("opacity",std::make_pair(0.0f,1.0f)));
-}
-mitk::PropertyManager* mitk::PropertyManager::GetInstance()
-{
- static mitk::PropertyManager propManager;
- return &propManager;
-}
-const mitk::PropertyManager::PropertyNameSet& mitk::PropertyManager::GetDefaultPropertyNames()
-{
- return m_DefaultPropertyNameSet;
-};
-mitk::BaseProperty::Pointer mitk::PropertyManager::CreateDefaultProperty(std::string name)
-{
- mitk::BaseProperty::Pointer newProperty(NULL);
- if ( name == "visible" )
- {
- newProperty = mitk::BoolProperty::New(true);
- }
- else
- {
- //MITK_INFO << "Warning: non-existing default property requested: " << name << std::endl;
- }
- return newProperty;
-}
-bool mitk::PropertyManager::GetDefaultLimits(const std::string &name,std::pair<float,float> &minMax)
-{
- PropertyLimitsMap::iterator it = m_PropertyLimits.find(name.c_str());
- if (it != m_PropertyLimits.end())
- {
- minMax = it->second;
- return true;
- }
- else
- {
- minMax = std::make_pair(std::numeric_limits<float>::min(),std::numeric_limits<float>::max());
- return false;
- }
-}
diff --git a/Modules/Ext/DataManagement/mitkPropertyManager.h b/Modules/Ext/DataManagement/mitkPropertyManager.h
deleted file mode 100644
index e2147738e7..0000000000
--- a/Modules/Ext/DataManagement/mitkPropertyManager.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKPROPERTYMANAGER_H_HEADER_INCLUDED
-#define MITKPROPERTYMANAGER_H_HEADER_INCLUDED
-#include "mitkPropertyList.h"
-#include "MitkExtExports.h"
-#include <set>
-#include <map>
-
-namespace mitk {
- class MitkExt_EXPORT PropertyManager {
-
- public:
- typedef std::set<std::string> PropertyNameSet;
-
-// typedef PropertyNameSetterator PropertyNameIterator;
- const PropertyNameSet& GetDefaultPropertyNames();
- BaseProperty::Pointer CreateDefaultProperty(std::string name);
- static PropertyManager* GetInstance();
- bool GetDefaultLimits(const std::string &name,std::pair<float,float> &minMax);
- protected:
- PropertyManager();
- PropertyNameSet m_DefaultPropertyNameSet;
- static void InitDefaultPropertyNames();
- typedef std::map< std::string, std::pair<float,float> > PropertyLimitsMap;
- PropertyLimitsMap m_PropertyLimits;
- } ;
-}
-
-
-#endif /* MITKPROPERTYMANAGER_H_HEADER_INCLUDED */
-
-
diff --git a/Modules/Ext/DataManagement/mitkSTLVectorContainer.h b/Modules/Ext/DataManagement/mitkSTLVectorContainer.h
deleted file mode 100644
index 94bc528c56..0000000000
--- a/Modules/Ext/DataManagement/mitkSTLVectorContainer.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_STL_VECTOR_H_
-#define _MITK_STL_VECTOR_H_
-
-#include <vector>
-#include <itkSimpleDataObjectDecorator.h>
-
-namespace mitk
-{
-
-
-template <typename T>
-class STLVectorContainer : public itk::SimpleDataObjectDecorator< std::vector<T> >
-{
-public:
-
- typedef STLVectorContainer<T> Self;
- typedef itk::SimpleDataObjectDecorator< std::vector<T> > Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
- itkTypeMacro(STLVectorContainer,itk::SimpleDataObjectDecorator)
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- typedef T ValueType;
-
- typedef std::vector<ValueType> STLVectorContainerType;
-
- /**
- * Returns the number of elements contained in the
- * underlying stl-vector
- */
- unsigned int GetSize();
-
- /**
- * Emptys the undelying stl-vector. That means, that
- * after a call to this function, GetSize() returns 0.
- */
- void Clear();
-
- /**
- * Resizes the underlying stl vector to the given size.
- */
- void Resize( unsigned int size );
-
- /**
- * sets the n'th element of the underluing stl vector.
- * if the index is out of range, an assertion is raised
- */
- void SetElement( const unsigned int& index, const ValueType& element );
-
- /**
- * returns the n'th element of the undelying stl vector
- * If the index is out of range, an assertion is raised!
- */
- ValueType& GetElement( const unsigned int& index );
-
-
-};
-
-typedef STLVectorContainer<int> IntVectorContainer;
-typedef STLVectorContainer<unsigned int> UnsignedIntVectorContainer;
-typedef STLVectorContainer<long> LongVectorContainer;
-typedef STLVectorContainer<unsigned long> UnsignedLongVectorContainer;
-typedef STLVectorContainer<short int> ShortIntVectorContainer;
-typedef STLVectorContainer<short unsigned int> ShortUnsignedIntVectorContainer;
-typedef STLVectorContainer<float> FloatVectorContainer;
-typedef STLVectorContainer<double> DoubleVectorContainer;
-
-
-} //end of namespace mitk
-
-#include "mitkSTLVectorContainer.txx"
-
-#endif
diff --git a/Modules/Ext/DataManagement/mitkSTLVectorContainer.txx b/Modules/Ext/DataManagement/mitkSTLVectorContainer.txx
deleted file mode 100644
index b281cfe648..0000000000
--- a/Modules/Ext/DataManagement/mitkSTLVectorContainer.txx
+++ /dev/null
@@ -1,70 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_STL_VECTOR_CONTAINER_TXX_
-#define _MITK_STL_VECTOR_CONTAINER_TXX_
-
-#include "mitkSTLVectorContainer.h"
-
-template<typename T>
-unsigned int mitk::STLVectorContainer<T>::GetSize()
-{
- return this->Get().size();
-}
-
-template<typename T>
-void mitk::STLVectorContainer<T>::Clear()
-{
- return this->Get().clear();
- this->Modified();
-}
-
-/*
- * Resizes the underlying stl vector to the given size.
- */
-template<typename T>
-void mitk::STLVectorContainer<T>::Resize( unsigned int size )
-{
- this->Get().resize( size );
- this->Modified();
-}
-
-/*
- * sets the n'th element of the underluing stl vector.
- * if the index is out of range, an assertion is raised
- */
-template<typename T>
-void mitk::STLVectorContainer<T>::SetElement( const unsigned int& index, const typename mitk::STLVectorContainer<T>::ValueType& element )
-{
- assert( index < this->Get().size() );
- this->Get()[index] = element;
- this->Modified();
-}
-
-/*
- * returns the n'th element of the undelying stl vector
- * If the index is out of range, an assertion is raised!
- */
-template<typename T>
-typename mitk::STLVectorContainer<T>::ValueType& mitk::STLVectorContainer<T>::GetElement( const unsigned int& index )
-{
- assert( index < this->Get().size() );
- return this->Get()[index];
-
-}
-
-
-#endif
diff --git a/Modules/Ext/DataManagement/mitkSTLVectorContainerSource.h b/Modules/Ext/DataManagement/mitkSTLVectorContainerSource.h
deleted file mode 100644
index f5f44d0a68..0000000000
--- a/Modules/Ext/DataManagement/mitkSTLVectorContainerSource.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_STL_VECTOR_CONTAINER_SOURCE_H_
-#define _MITK_STL_VECTOR_CONTAINER_SOURCE_H_
-
-
-#include "mitkSTLVectorContainer.h"
-#include "mitkCommon.h"
-#include "mitkBaseProcess.h"
-
-namespace mitk
-{
-
-template <typename T>
-class STLVectorContainerSource : public BaseProcess
-{
-public:
-
- mitkClassMacro( STLVectorContainerSource, BaseProcess );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- typedef mitk::STLVectorContainer<T> OutputType;
-
- typedef typename OutputType::Pointer OutputTypePointer;
-
- typedef itk::DataObject::Pointer DataObjectPointer;
-
- /**
- * Allocates a new output object and returns it. Currently the
- * index idx is not evaluated.
- * @param idx the index of the output for which an object should be created
- * @returns the new object
- */
- virtual DataObjectPointer MakeOutput ( unsigned int idx );
-
- /**
- * Generates the input requested region simply by calling the equivalent
- * method of the superclass.
- */
- void GenerateInputRequestedRegion();
-
- /**
- * Allows to set the output of the stl vector container source. According to the itk documentation
- * this method is outdated and should not be used. Instead GraftOutput(...)
- * should be used.
- * @param output the intended output of the lookup table source
- */
- void SetOutput( OutputType* output );
-
- /**
- * Replacement of the SetOutput method. I think it is not yet correcly
- * implemented, so you should better not use it.
- * @todo provide a more usefule implementation
- * @param output the intended output of the lookup table source.
- */
- virtual void GraftOutput( OutputType* output );
-
- /**
- * Returns the output with index 0 of the stl vector container source
- * @returns the output
- */
- OutputType* GetOutput();
-
- /**
- * Returns the n'th output of the stl vector container source
- * @param idx the index of the wanted output
- * @returns the output with index idx.
- */
- OutputType* GetOutput ( unsigned int idx );
-
-protected:
- STLVectorContainerSource();
- virtual ~STLVectorContainerSource();
-
-};
-
-typedef STLVectorContainerSource<int> IntVectorContainerSource;
-typedef STLVectorContainerSource<unsigned int> UnsignedIntVectorContainerSource;
-typedef STLVectorContainerSource<long> LongVectorContainerSource;
-typedef STLVectorContainerSource<unsigned long> UnsignedLongVectorContainerSource;
-typedef STLVectorContainerSource<short int> ShortIntVectorContainerSource;
-typedef STLVectorContainerSource<short unsigned int> ShortUnsignedIntVectorContainerSource;
-typedef STLVectorContainerSource<float> FloatVectorContainerSource;
-typedef STLVectorContainerSource<double> DoubleVectorContainerSource;
-
-} // end of namespace mitk
-
-#include "mitkSTLVectorContainerSource.txx"
-
-#endif
diff --git a/Modules/Ext/DataManagement/mitkSTLVectorContainerSource.txx b/Modules/Ext/DataManagement/mitkSTLVectorContainerSource.txx
deleted file mode 100644
index 0c5e6a2a92..0000000000
--- a/Modules/Ext/DataManagement/mitkSTLVectorContainerSource.txx
+++ /dev/null
@@ -1,113 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_STL_VECTOR_CONTAINER_SOURCE_TXX_
-#define _MITK_STL_VECTOR_CONTAINER_SOURCE_TXX_
-
-#include "mitkSTLVectorContainerSource.h"
-
-template <typename T>
-mitk::STLVectorContainerSource<T>::STLVectorContainerSource()
-{
- OutputTypePointer output = static_cast<OutputType*>( this->MakeOutput( 0 ).GetPointer() );
-
- assert( output.GetPointer() != NULL );
-
- this->ProcessObject::SetNumberOfRequiredOutputs( 1 );
- this->ProcessObject::SetNthOutput( 0, output.GetPointer() );
-}
-
-
-template <typename T>
-mitk::STLVectorContainerSource<T>::~STLVectorContainerSource()
-{}
-
-
-
-
-template <typename T>
-typename mitk::STLVectorContainerSource<T>::DataObjectPointer
-mitk::STLVectorContainerSource<T>::MakeOutput ( unsigned int )
-{
- return OutputType::New().GetPointer();
-}
-
-
-
-
-template <typename T>
-void
-mitk::STLVectorContainerSource<T>::SetOutput( OutputType* output )
-{
- itkWarningMacro( << "SetOutput(): This method is slated to be removed from ITK. Please use GraftOutput() in possible combination with DisconnectPipeline() instead." );
- this->SetNthOutput( 0, output );
-}
-
-
-
-
-template <typename T>
-typename mitk::STLVectorContainerSource<T>::OutputType*
-mitk::STLVectorContainerSource<T>::GetOutput()
-{
- if ( this->GetNumberOfOutputs() < 1 )
- {
- return 0;
- }
-
- if ( static_cast<OutputType*> ( this->ProcessObject::GetOutput( 0 ) ) == NULL )
- itkWarningMacro(<< "Output is NULL!" );
- return static_cast<OutputType*> ( this->ProcessObject::GetOutput( 0 ) );
-}
-
-
-
-
-template <typename T>
-typename mitk::STLVectorContainerSource<T>::OutputType*
-mitk::STLVectorContainerSource<T>::GetOutput ( unsigned int idx )
-{
- return static_cast<OutputType*> ( this->ProcessObject::GetOutput( idx ) );
-}
-
-
-
-
-template <typename T>
-void
-mitk::STLVectorContainerSource<T>::GenerateInputRequestedRegion()
-{
- this->ProcessObject::GenerateInputRequestedRegion();
-}
-
-
-
-
-template <typename T>
-void
-mitk::STLVectorContainerSource<T>::GraftOutput( OutputType* graft )
-{
- OutputType * output = this->GetOutput();
-
- if ( output && graft )
- {
- // copy the meta-information
- output->CopyInformation( graft );
- }
-}
-
-
-#endif
diff --git a/Modules/Ext/DataManagement/mitkSeedsImage.cpp b/Modules/Ext/DataManagement/mitkSeedsImage.cpp
deleted file mode 100644
index 4ccc3d39b1..0000000000
--- a/Modules/Ext/DataManagement/mitkSeedsImage.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkSeedsImage.h"
-
-#include "mitkOperation.h"
-#include "mitkOperationActor.h"
-#include "mitkDrawOperation.h"
-#include "mitkImageAccessByItk.h"
-#include "mitkInteractionConst.h"
-#include "mitkRenderingManager.h"
-
-#include <itkNeighborhoodIterator.h>
-#include <itkLineConstIterator.h>
-
-
-mitk::SeedsImage::SeedsImage()
-{
- m_GaussianFunction3D = GaussianFunction3DType::New();
- m_GaussianFunction2D = GaussianFunction2DType::New();
-}
-
-mitk::SeedsImage::~SeedsImage()
-{
-}
-
-void mitk::SeedsImage::Initialize()
-{
- Superclass::Initialize();
- m_Radius = 1;
-}
-
-
-void mitk::SeedsImage::ExecuteOperation(mitk::Operation* operation)
-{
- //mitkCheckOperationTypeMacro(SeedsOperation, operation, seedsOp);
- m_Spacing = this->GetGeometry()->GetSpacing();
- for(unsigned int i=0; i<this->GetDimension(); i++)
- orig_size[i] = this->GetDimension(i);
-
- mitk::DrawOperation * seedsOp =
- dynamic_cast< mitk::DrawOperation * >( operation );
-
- if ( seedsOp != NULL )
- {
- m_DrawState = seedsOp->GetDrawState();
-
- if (m_Radius != seedsOp->GetRadius())
- {
- m_Radius = seedsOp->GetRadius();
- }
-
- switch (operation->GetOperationType())
- {
- case mitk::OpADD:
- {
- m_Point = seedsOp->GetPoint();
- m_LastPoint = m_Point;
- AccessByItk(this, AddSeedPoint);
- break;
- }
- case mitk::OpMOVE:
- {
- m_Point = seedsOp->GetPoint();
- AccessByItk(this, AddSeedPoint);
- AccessByItk(this, PointInterpolation);
- m_LastPoint = m_Point;
- break;
- }
- case mitk::OpUNDOADD:
- {
- m_Point = seedsOp->GetPoint();
- m_LastPoint = m_Point;
- m_DrawState = 0;
-
- // todo - operation is not equal with its inverse operation - possible
- // approximation problems in the function PointInterpolation()
- m_Radius = m_Radius+4;
- AccessByItk(this, AddSeedPoint);
- break;
- }
- case mitk::OpUNDOMOVE:
- {
- m_Point = seedsOp->GetPoint();
- m_DrawState = 0;
-
- // todo - operation is not equal with its inverse operation - possible
- // approximation problems in the function PointInterpolation()
- m_Radius = m_Radius+4;
- AccessByItk(this, AddSeedPoint);
- AccessByItk(this, PointInterpolation);
- m_LastPoint = m_Point;
- break;
- }
- }
-
- //*todo has to be done here, cause of update-pipeline not working yet
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- //mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
-
- this->Modified();
- }
-}
-
-
-template < typename SeedsImageType >
-void mitk::SeedsImage::AddSeedPoint(SeedsImageType* itkImage)
-{
- typedef itk::NeighborhoodIterator< SeedsImageType >
- NeighborhoodIteratorType;
- typedef typename NeighborhoodIteratorType::IndexType IndexType;
-
- NeighborhoodIteratorType& nit = this->GetNit< SeedsImageType >( itkImage );
-
- const unsigned int dimension =
- SeedsImageType::ImageDimension;
-
- mitk::Point3D index;
- this->GetGeometry()->WorldToIndex( m_Point, index );
-
- IndexType itkIndex;
- unsigned int d;
- for ( d = 0; d < dimension; ++d )
- {
- itkIndex[d] = (int)(index[d] + 0.5);
- }
- nit.SetLocation( itkIndex );
-
-
- unsigned int i;
- for ( i = 0; i < nit.Size(); ++i )
- {
- if ( nit[i] != 0 )
- {
- try
- {
- nit.SetPixel( i, m_DrawState );
- }
- catch( itk::RangeError & )
- {
- }
- }
- }
-}
-
-
-template < typename SeedsImageType >
-void mitk::SeedsImage::PointInterpolation(SeedsImageType* itkImage)
-{
- typedef itk::NeighborhoodIterator< SeedsImageType >
- NeighborhoodIteratorType;
- typedef typename NeighborhoodIteratorType::IndexType IndexType;
-
-
- NeighborhoodIteratorType& nit = this->GetNit< SeedsImageType >( itkImage );
-
- const unsigned int dimension =
- SeedsImageType::ImageDimension;
-
- mitk::Point3D indexBegin, indexEnd;
- this->GetGeometry()->WorldToIndex( m_Point, indexBegin );
- this->GetGeometry()->WorldToIndex( m_LastPoint, indexEnd );
-
- IndexType itkIndexBegin, itkIndexEnd;
- unsigned int d;
- for ( d = 0; d < dimension; ++d )
- {
- itkIndexBegin[d] = (int)(indexBegin[d] + 0.5);
- itkIndexEnd[d] = (int)(indexEnd[d] + 0.5);
- }
-
-
- typedef itk::LineConstIterator< SeedsImageType > LineIteratorType;
- LineIteratorType lit( itkImage, itkIndexBegin, itkIndexEnd );
-
- // Disable warnings (which would otherwise be displayed if line leaves the
- // region).
- bool warningDisplay = itk::Object::GetGlobalWarningDisplay();
- itk::Object::GlobalWarningDisplayOff();
- for ( lit.GoToBegin(); !lit.IsAtEnd(); ++lit )
- {
- nit.SetLocation( lit.GetIndex() );
-
- unsigned int i;
- for ( i = 0; i < nit.Size(); ++i )
- {
- if ( nit[i] != 0 )
- {
- try
- {
- nit.SetPixel( i, m_DrawState );
- }
- catch( itk::RangeError & )
- {
- }
- }
- }
- }
- itk::Object::SetGlobalWarningDisplay( warningDisplay );
-}
-
-void mitk::SeedsImage::ClearBuffer()
-{
- AccessByItk(this, ClearBuffer);
-}
-
-template < typename SeedsImageType >
-void mitk::SeedsImage::ClearBuffer(SeedsImageType* itkImage)
-{
- itkImage->FillBuffer(0);
-}
-
-template < typename SeedsImageType >
-itk::NeighborhoodIterator< SeedsImageType >&
-mitk::SeedsImage::GetNit( SeedsImageType* image )
-{
- typedef itk::NeighborhoodIterator< SeedsImageType >
- NeighborhoodIteratorType;
- typedef typename NeighborhoodIteratorType::OffsetType OffsetType;
- typedef typename NeighborhoodIteratorType::SizeType SizeType;
- typedef itk::GaussianSpatialFunction< int, SeedsImageType::ImageDimension >
- GaussianFunctionType;
-
- static SeedsImageType* iteratedImage = 0;
- static NeighborhoodIteratorType nit;
- static typename GaussianFunctionType::Pointer gaussianFunction
- = GaussianFunctionType::New();
-
- if ( iteratedImage != image )
- {
- SizeType radius;
- radius.Fill( m_Radius);
- nit.Initialize( radius, image, image->GetBufferedRegion() );
- iteratedImage = image;
- }
-
- nit.SetRadius( m_Radius );
-
- unsigned int i;
- for ( i = 0; i < nit.GetCenterNeighborhoodIndex()*2+1; ++i )
- {
- OffsetType offset = nit.GetOffset( i );
-
- typename GaussianFunctionType::InputType point;
- double dist = 0;
- unsigned int d;
- for ( d = 0; d < SeedsImageType::ImageDimension; ++d )
- {
- point[d] = offset[d];
- dist += offset[d] * offset[d];
- }
- }
-
- return nit;
-}
-
diff --git a/Modules/Ext/DataManagement/mitkSeedsImage.h b/Modules/Ext/DataManagement/mitkSeedsImage.h
deleted file mode 100644
index 5cc2ffba2e..0000000000
--- a/Modules/Ext/DataManagement/mitkSeedsImage.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSEEDSIMAGE_H_HEADER_INCLUDED_C1C2FCD2
-#define MITKSEEDSIMAGE_H_HEADER_INCLUDED_C1C2FCD2
-
-#include "mitkImage.h"
-#include "MitkExtExports.h"
-
-#include <itkImage.h>
-#include <itkNeighborhood.h>
-#include <itkNeighborhoodIterator.h>
-#include <itkGaussianSpatialFunction.h>
-#include <itkBinaryBallStructuringElement.h>
-
-namespace mitk
-{
-
-//##Documentation
-//## @brief SeedsImage class for storing seeds-images
-//##
-//## Handles operations for drawing seeds.
-//## @ingroup Data
-class MitkExt_EXPORT SeedsImage : public Image
-{
-
-public:
-
- mitkClassMacro(SeedsImage, Image);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkGetMacro(LastPoint, mitk::Point3D);
-
- void Initialize();
-
- /// handles operations
- virtual void ExecuteOperation(Operation* operation);
-
- void ClearBuffer();
-
-
-protected:
- SeedsImage();
- virtual ~SeedsImage();
-
- template< typename SeedsImageType >
- itk::NeighborhoodIterator< SeedsImageType >& GetNit( SeedsImageType* image );
-
- /// sets a sphere of seeds around the point
- template < typename SeedsImageType >
- void AddSeedPoint(SeedsImageType * itkImage);
-
- /// interpolates a tube of seeds between two points
- template < typename SeedsImageType >
- void PointInterpolation(SeedsImageType * itkImage);
-
- /// interpolates a tube of seeds between two points
- template < typename SeedsImageType >
- void ClearBuffer(SeedsImageType * itkImage);
-
-
-protected:
- mitk::Point3D m_Point;
- mitk::Point3D m_LastPoint;
- mitk::Vector3D m_Spacing;
- int orig_size[3];
- int m_DrawState;
- int m_Radius;
- float delta_x, delta_y, delta_z;
- float sphere_distance;
-
- typedef itk::Image<float,3> MaskImageType;
-
- typedef itk::GaussianSpatialFunction< int, 3 > GaussianFunction3DType;
- GaussianFunction3DType::Pointer m_GaussianFunction3D;
- typedef itk::GaussianSpatialFunction< int, 2 > GaussianFunction2DType;
- GaussianFunction2DType::Pointer m_GaussianFunction2D;
-
- typedef itk::BinaryBallStructuringElement< short, 3 > BallStructuringElement3DType;
- BallStructuringElement3DType m_StructuringElement3D;
- typedef itk::BinaryBallStructuringElement< short, 2 > BallStructuringElement2DType;
- BallStructuringElement2DType m_StructuringElement2D;
-
-};
-
-} // namespace mitk
-
-#endif /* MITKSEEDSIMAGE_H_HEADER_INCLUDED_C1C2FCD2 */
diff --git a/Modules/Ext/DataManagement/mitkSeedsImageLookupTableSource.cpp b/Modules/Ext/DataManagement/mitkSeedsImageLookupTableSource.cpp
deleted file mode 100644
index d21a97ca76..0000000000
--- a/Modules/Ext/DataManagement/mitkSeedsImageLookupTableSource.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkSeedsImageLookupTableSource.h"
-#include <vtkLookupTable.h>
-
-
-mitk::SeedsImageLookupTableSource::~SeedsImageLookupTableSource()
-{}
-
-
-mitk::SeedsImageLookupTableSource::SeedsImageLookupTableSource() : mitk::LookupTableSource()
-{
- m_Mode = DefaultLUT;
- m_LookupTable = NULL;
-
- this->Modified();
-}
-
-
-void mitk::SeedsImageLookupTableSource::GenerateData()
-{
- OutputType::Pointer output = this->GetOutput();
-
- vtkLookupTable* vtkLut = this->BuildVtkLookupTable();
- output->SetVtkLookupTable( vtkLut );
- vtkLut->Delete();
-}
-
-vtkLookupTable* mitk::SeedsImageLookupTableSource::BuildSeedsLookupTable()
-{
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
- vtkLookupTable->SetNumberOfTableValues( 256 );
- vtkLookupTable->SetTableRange( 0.0, 255.0 );
-
- // black
- int i;
- for ( i = 0; i < 253; i++ )
- {
- vtkLookupTable->SetTableValue ( i, 0.0, 0.0, 0.0, 0.0 );
- }
-
- // blue
- vtkLookupTable->SetTableValue( 254, 0.0, 0.0, 1.0, 0.7 );
-
- // red
- vtkLookupTable->SetTableValue( 255, 1.0, 0.0, 0.0, 0.7 );
-
- return vtkLookupTable;
-}
-
-vtkLookupTable* mitk::SeedsImageLookupTableSource::BuildForceLookupTable()
-{
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
- vtkLookupTable->SetTableRange( 0.0, 1.0 );
- vtkLookupTable->SetValueRange( 0.0, 1.0 );
- vtkLookupTable->SetNumberOfColors( 256 );
- vtkLookupTable->Build();
-
- int i;
- for ( i = 0; i < 128; i++ )
- {
- vtkLookupTable->SetTableValue ( i,
- 0.0, 0.0, 1.0, 0.2 + fabs(128.0 - i) / 256.0 );
- }
-
- vtkLookupTable->SetTableValue ( 127, 0.0, 0.0, 1.0, 0.0 );
-
- for ( i = 128; i < 256; i++ )
- {
- vtkLookupTable->SetTableValue ( i,
- 1.0, 1.0, 0.0, 0.2 + fabs(i - 128.0) / 256.0 );
- }
-
- return vtkLookupTable;
-}
-
-vtkLookupTable* mitk::SeedsImageLookupTableSource::BuildDefaultLookupTable()
-{
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
- int size = 256;
- vtkLookupTable->SetTableRange(0,255);
- vtkLookupTable->SetNumberOfColors( size );
- vtkLookupTable->Build();
- return( vtkLookupTable );
-}
-
-
-vtkLookupTable* mitk::SeedsImageLookupTableSource::BuildVtkLookupTable()
-{
- if ( m_Mode == Seeds )
- {
- return BuildSeedsLookupTable();
- }
- else if ( m_Mode == Force )
- {
- return BuildForceLookupTable();
- }
-
- else
- {
- return BuildDefaultLookupTable();
- }
-}
diff --git a/Modules/Ext/DataManagement/mitkSeedsImageLookupTableSource.h b/Modules/Ext/DataManagement/mitkSeedsImageLookupTableSource.h
deleted file mode 100644
index 0989a0903f..0000000000
--- a/Modules/Ext/DataManagement/mitkSeedsImageLookupTableSource.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSEEDSIMAGELOOKUPTABLESOURCE_H_HEADER_INCLUDED
-#define MITKSEEDSIMAGELOOKUPTABLESOURCE_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkLookupTableSource.h"
-
-
-namespace mitk
-{
-
-class MitkExt_EXPORT SeedsImageLookupTableSource : public LookupTableSource
-{
-public:
- typedef enum {Seeds, DefaultLUT, Force} LookupTableMode;
-
- mitkClassMacro( SeedsImageLookupTableSource, LookupTableSource );
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /** @brief Some convenient typedefs. */
- typedef mitk::LookupTable OutputType;
-
- void SetUseSeedsLookupTable() {m_Mode = Seeds; this->Modified();};
-
- void SetUseForceLookupTable() {m_Mode = Force; this->Modified();};
-
-protected:
- SeedsImageLookupTableSource();
- virtual ~SeedsImageLookupTableSource();
-
- /**
- * Generates a LookupTable depended on the given mode and stores
- * it in an output object
- */
- virtual void GenerateData();
-
- /**
- * Generates a lookup table, dependend on the given mode
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildVtkLookupTable( );
-
- /**
- * Generates a Seeds lookup table
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildSeedsLookupTable();
-
- /**
- * Generates a force lookup table
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildForceLookupTable();
-
- /**
- * Generates a default lookup table
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildDefaultLookupTable();
-
-private:
- LookupTableMode m_Mode;
- OutputTypePointer m_LookupTable;
-};
-
-} // namespace mitk
-
-#endif /* MITKSEEDSIMAGELOOKUPSOURCE_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/DataManagement/mitkSet.h b/Modules/Ext/DataManagement/mitkSet.h
deleted file mode 100644
index 67727136e1..0000000000
--- a/Modules/Ext/DataManagement/mitkSet.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef mitkSet_H
-#define mitkSet_H
-
-#include <itkDataObject.h>
-#include <itkCommand.h>
-#include <mitkCommon.h>
-#include <vector>
-#include <set>
-
-#include "mitkSetObserver.h"
-
-namespace mitk
-{
-
-///
-/// A class that acts like a weak pointer
-/// but for a list of itk objects
-///
-template <class T>
-class Set: virtual public itk::Object
-{
-public:
- typedef mitk::SetObserver<T> Observer;
- mitkClassMacro(Set<T>, itk::Object);
- itkFactorylessNewMacro(Set<T>);
-
- Set()
- {
- }
-
- ///
- /// clears this set, copies over all elements from otherSet
- ///
- void Copy( mitk::Set<T>* otherSet )
- {
- this->Clear();
- for(unsigned int i=0; i< otherSet->GetSize(); ++i)
- {
- this->Add( otherSet->Get(i) );
- }
- }
-
- bool Add ( const T& obj )
- {
- if(this->Has(obj)) // this is a set! do not add twice
- return false;
-
- // add it now
- m_Objects.push_back(obj); // if index is not valid any more, just add
- // the element
- // subscribe for modified event
- typename itk::MemberCommand<mitk::Set<T> >::Pointer _modifiedCommand =
- itk::MemberCommand<mitk::Set<T> >::New();
- _modifiedCommand->SetCallbackFunction(this
- , &Set<T>::OnObjectModified);
- m_ObjectModifiedTags[obj] =
- obj->AddObserver(itk::ModifiedEvent(), _modifiedCommand);
-
- // subscribe for delete event
- typename itk::MemberCommand<mitk::Set<T> >::Pointer _DeleteCommand =
- itk::MemberCommand<mitk::Set<T> >::New();
- _DeleteCommand->SetCallbackFunction(this
- , &Set<T>::OnObjectModified);
- m_ObjectDeleteTags[obj] =
- obj->AddObserver(itk::DeleteEvent(), _DeleteCommand);
-
- for(typename std::set<SetObserver<T>*>::iterator it = m_SetObserver.begin();
- it != m_SetObserver.end(); ++it)
- (*it)->OnAdded(obj);
-
- this->Modified();
- return true;
- }
-
- bool Remove ( const T& obj )
- {
- return this->Remove(this->IndexOf(obj));
- }
-
- bool Remove ( int index )
- {
- if( !this->IsValid(index) ) // element must exist to be removed
- return false;
-
- typename std::vector<T>::iterator it = m_Objects.begin();
- std::advance(it, index);
-
- T& obj = *it;
-
- for(typename std::set<SetObserver<T>*>::iterator it2
- = m_SetObserver.begin(); it2 != m_SetObserver.end(); ++it2)
- (*it2)->OnRemove(*it);
- // remove it now
- obj->RemoveObserver(m_ObjectModifiedTags[obj]);
- obj->RemoveObserver(m_ObjectDeleteTags[obj]);
- m_ObjectModifiedTags.erase(obj);
- m_ObjectDeleteTags.erase(obj);
- m_Objects.erase(it);
- this->Modified();
- return true;
- }
-
- void Clear ()
- {
- while(m_Objects.size() > 0)
- this->Remove(m_Objects.size()-1);
- }
-
- unsigned int GetSize() const
- {
- return m_Objects.size();
- }
- int IndexOf(const T& obj) const
- {
- int index = -1;
-
- for(unsigned int i=0; i<m_Objects.size(); ++i)
- {
- if(m_Objects.at(i) == obj)
- {
- index = i;
- break;
- }
- }
- return index;
- }
- bool Has(const T& obj) const
- {
- return this->IndexOf(obj) != -1;
- }
- bool IsEmpty() const
- {
- return m_Objects.empty();
- }
- bool IsValid( int index ) const
- {
- if(index >= 0)
- {
- return m_Objects.size() > 0
- && static_cast< unsigned int > (index) < m_Objects.size();
- }
- return false;
- }
- T& Front()
- {
- return m_Objects.front();
- }
- T& Back()
- {
- return m_Objects.back();
- }
- T& Get( unsigned int index )
- {
- return m_Objects.at(index);
- }
- const T& Front() const
- {
- return m_Objects.front();
- }
- const T& Back() const
- {
- return m_Objects.back();
- }
- const T& Get( unsigned int index ) const
- {
- return m_Objects.at(index);
- }
- void AddObserver( SetObserver<T>* observer ) const
- {
- m_SetObserver.insert( observer );
- }
- void RemoveObserver( SetObserver<T>* observer ) const
- {
- m_SetObserver.erase( observer );
- }
- void OnObjectModified(const itk::Object* caller
- , const itk::EventObject &event)
- {
- unsigned int i=0;
- for(; i<m_Objects.size(); ++i)
- if( static_cast<itk::Object*>(m_Objects.at(i)) == caller )
- break;
-
- const itk::DeleteEvent* delEvent
- = dynamic_cast<const itk::DeleteEvent*>(&event);
-
- // inform listeners
- for(typename std::set<SetObserver<T>*>::iterator it = m_SetObserver.begin();
- it != m_SetObserver.end(); ++it)
- delEvent ? (*it)->OnDelete( this->Get(i) )
- : (*it)->OnModified( this->Get(i) );
-
- // remove from list if object was deleted (no dangling pointers)
- if(delEvent)
- {
- this->Remove(i);
- }
- }
-
- Set(const Set<T>& other)
- {
- *this = other;
- }
- Set<T>& operator=
- (const Set<T>& other)
- {
- // do not simply copy -> because of observer objects
- // instead: use add method for each element of the other List
- for(int i=0; i<other.GetSize(); ++i)
- this->Add( other.Get(i) );
-
- return *this;
- }
- virtual ~Set()
- {
- this->Clear();
- }
-protected:
- ///
- /// Holds all objects
- ///
- std::vector<T> m_Objects;
-
- ///
- /// holds the list of observed itk objects (will be updated in setat())
- ///
- mutable std::set<SetObserver<T>*> m_SetObserver;
-
- ///
- /// \brief Holds all tags of Modified Event Listeners.
- ///
- std::map<const T, unsigned long> m_ObjectModifiedTags;
-
- ///
- /// \brief Holds all tags of Modified Event Listeners.
- ///
- std::map<const T, unsigned long> m_ObjectDeleteTags;
-};
-
-} // namespace mitk
-
-#endif // mitkSet_H
diff --git a/Modules/Ext/DataManagement/mitkSetObserver.h b/Modules/Ext/DataManagement/mitkSetObserver.h
deleted file mode 100644
index a27ff5233a..0000000000
--- a/Modules/Ext/DataManagement/mitkSetObserver.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef MITKSETOBSERVER_H
-#define MITKSETOBSERVER_H
-
-namespace mitk
-{
- ///
- /// abstract base class for all objects observing an mitk::Set
- ///
- template <class T>
- struct SetObserver
- {
- virtual void OnAdded( T object ) {}
- virtual void OnModified( T object ) {}
- ///
- /// Will be called before an object gets removed
- ///
- virtual void OnRemove( T object ) {}
- virtual void OnDelete( T object ) {}
- ///
- /// Makes this class abstract
- ///
- virtual ~SetObserver() = 0;
- };
-
- template <class T>
- SetObserver<T>::~SetObserver() {}
-
-}
-
-#endif // MITKSETOBSERVER_H
diff --git a/Modules/Ext/DataManagement/mitkSphereLandmarkProjector.cpp b/Modules/Ext/DataManagement/mitkSphereLandmarkProjector.cpp
deleted file mode 100644
index f9851d51f6..0000000000
--- a/Modules/Ext/DataManagement/mitkSphereLandmarkProjector.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkSphereLandmarkProjector.h"
-#include <vtkThinPlateSplineTransform.h>
-
-#include <vtkTransform.h>
-#include <vtkSphericalTransform.h>
-#include <vtkGeneralTransform.h>
-
-mitk::SphereLandmarkProjector::SphereLandmarkProjector()
-{
- m_SphericalTransform = vtkSphericalTransform::New();
- m_SphereRotation = vtkTransform::New();
- m_SpatialPlacementTransform = vtkTransform::New();
- m_PlaneToSphericalTransform = vtkGeneralTransform::New();
-
- m_SphereRotation->RotateX(90);
-
- //setup parameter-plane of the sphere: x is phi, y is theta; the radius is always 1
- mitk::ScalarType origin[3] = {1, 0, 2*vnl_math::pi}; // (1, 0, 6.28) (1, 0, 0)
- mitk::ScalarType right[3] = {0, 0, -2*vnl_math::pi}; // (0,3.14, 0) (0, 0, 6.28)
- mitk::ScalarType bottom[3] = {0, vnl_math::pi, 0}; // (0, 0,-6.28) (0,3.14, 0)
-
- m_SphereParameterPlane = mitk::PlaneGeometry::New();
- m_SphereParameterPlane->InitializeStandardPlane(right, bottom);
- m_SphereParameterPlane->SetOrigin(origin);
- m_SphereParameterPlane->SetSizeInUnits(100, 50);
-
- m_ParameterPlane = m_SphereParameterPlane;
-}
-
-mitk::SphereLandmarkProjector::~SphereLandmarkProjector()
-{
- m_SphericalTransform->Delete();
- m_SphereRotation->Delete();
- m_SpatialPlacementTransform->Delete();
- m_PlaneToSphericalTransform->Delete();
-}
-
-void mitk::SphereLandmarkProjector::ComputeCompleteAbstractTransform()
-{
- m_PlaneToSphericalTransform->Identity();
- m_PlaneToSphericalTransform->PostMultiply();
- m_PlaneToSphericalTransform->Concatenate(m_SphericalTransform);
- m_PlaneToSphericalTransform->Concatenate(m_SphereRotation);
- m_PlaneToSphericalTransform->Concatenate(m_InterpolatingAbstractTransform);//GetInterpolatingAbstractTransform());
- m_PlaneToSphericalTransform->Concatenate(m_SpatialPlacementTransform);
-
- m_CompleteAbstractTransform = m_PlaneToSphericalTransform;
-}
-
-void mitk::SphereLandmarkProjector::ProjectLandmarks(
- const mitk::PointSet::DataType::PointsContainer* targetLandmarks)
-{
- unsigned int size=targetLandmarks->Size();
- mitk::PointSet::DataType::PointsContainer::ConstIterator pointiterator, start = targetLandmarks->Begin();
- mitk::PointSet::DataType::PointsContainer::ElementIdentifier id;
-
- //Part I: Calculate center of sphere
- mitk::Point3D center;
- center.Fill(0);
- mitk::ScalarType radius;
- mitk::PointSet::PointType point;
- //determine center
- for(id=0, pointiterator=start;id<size;++id, ++pointiterator)
- {
- point = pointiterator->Value();
- center[0]+=point[0];
- center[1]+=point[1];
- center[2]+=point[2];
- }
- center[0]/=(mitk::ScalarType)size;
- center[1]/=(mitk::ScalarType)size;
- center[2]/=(mitk::ScalarType)size;
- //determine radius
- switch(0)
- {
- case 0/*MIN*/:
- radius = itk::NumericTraits<mitk::ScalarType>::max();
- for(id=0, pointiterator=start;id<size;++id, ++pointiterator)
- {
- point = pointiterator->Value();
- mitk::Vector3D v;
- v[0]=point[0]-center[0];
- v[1]=point[1]-center[1];
- v[2]=point[2]-center[2];
- if (v.GetNorm() < radius) radius = v.GetNorm();
- }
- break;
- case 1/*MAX*/:
- radius = 0;
- for(id=0, pointiterator=start;id<size;++id, ++pointiterator)
- {
- point = pointiterator->Value();
- mitk::Vector3D v;
- v[0]=point[0]-center[0];
- v[1]=point[1]-center[1];
- v[2]=point[2]-center[2];
- if (v.GetNorm() > radius) radius = v.GetNorm();
- }
- break;
- case 2/*AVERAGE*/:
- radius = 0;
- for(id=0, pointiterator=start;id<size;++id, ++pointiterator)
- {
- point = pointiterator->Value();
- mitk::Vector3D v;
- v[0]=point[0]-center[0];
- v[1]=point[1]-center[1];
- v[2]=point[2]-center[2];
- radius += v.GetNorm();
- }
- radius*=1.0/size;
- break;
- }
- mitk::Point3D origin = m_SphereParameterPlane->GetOrigin(); origin[0]=radius; m_SphereParameterPlane->SetOrigin(origin);
- m_SpatialPlacementTransform->GetMatrix()->SetElement(0, 3, center[0]);
- m_SpatialPlacementTransform->GetMatrix()->SetElement(1, 3, center[1]);
- m_SpatialPlacementTransform->GetMatrix()->SetElement(2, 3, center[2]);
-
-
- //Part II: Project points on sphere
- mitk::Point3D projectedPoint;
-
- m_WritableFinalTargetLandmarks->Initialize();
- m_ProjectedLandmarks->Initialize();
-
- m_WritableFinalTargetLandmarks->Reserve(size);
- m_ProjectedLandmarks->Reserve(size);
- for(id=0, pointiterator=start;id<size;++id, ++pointiterator)
- {
- point = pointiterator->Value();
-
- mitk::Vector3D v;
- v=point-center;
- mitk::FillVector3D(point, v[0], v[1], v[2]);
- v.Normalize(); v*=radius;
- mitk::FillVector3D(projectedPoint, v[0], v[1], v[2]);
-
- m_WritableFinalTargetLandmarks->InsertElement(id, point);
- m_ProjectedLandmarks->InsertElement(id, projectedPoint);
- }
-}
diff --git a/Modules/Ext/DataManagement/mitkSphereLandmarkProjector.h b/Modules/Ext/DataManagement/mitkSphereLandmarkProjector.h
deleted file mode 100644
index dac94ca8dd..0000000000
--- a/Modules/Ext/DataManagement/mitkSphereLandmarkProjector.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSPHERELANDMARKPROJECTOR_H_HEADER_INCLUDED_C1C68A2C
-#define MITKSPHERELANDMARKPROJECTOR_H_HEADER_INCLUDED_C1C68A2C
-
-#include "mitkLandmarkProjector.h"
-#include "MitkExtExports.h"
-#include "mitkPointSet.h"
-
-class vtkTransform;
-class vtkSphericalTransform;
-class vtkGeneralTransform;
-class vtkTransformPolyDataFilter;
-
-namespace mitk {
-
-//##Documentation
-//## @brief Thin-plate-spline-based landmark-based curved geometry
-//##
-//## @ingroup Geometry
-class MitkExt_EXPORT SphereLandmarkProjector : public LandmarkProjector
-{
-public:
- mitkClassMacro(SphereLandmarkProjector, LandmarkProjector);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual void ProjectLandmarks(const mitk::PointSet::DataType::PointsContainer* targetLandmarks);
-protected:
- SphereLandmarkProjector();
- virtual ~SphereLandmarkProjector();
-
- virtual void ComputeCompleteAbstractTransform();
-
- vtkSphericalTransform* m_SphericalTransform;
- vtkTransform* m_SphereRotation;
- vtkTransform* m_SpatialPlacementTransform;
- vtkGeneralTransform* m_PlaneToSphericalTransform;
-
- mitk::PlaneGeometry::Pointer m_SphereParameterPlane;
-};
-
-} // namespace mitk
-
-#endif /* MITKSPHERELANDMARKPROJECTOR_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Modules/Ext/DataManagement/mitkUSLookupTableSource.cpp b/Modules/Ext/DataManagement/mitkUSLookupTableSource.cpp
deleted file mode 100644
index 1e701ac02e..0000000000
--- a/Modules/Ext/DataManagement/mitkUSLookupTableSource.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkUSLookupTableSource.h"
-#include <mitkIpPic.h>
-#include <vtkLookupTable.h>
-#include <fstream>
-
-
-extern "C"
-{
-#include "uscfunctions/usc.h"
-}
-
-
-mitk::USLookupTableSource::~USLookupTableSource()
-{}
-
-
-mitk::USLookupTableSource::USLookupTableSource() : mitk::LookupTableSource()
-{
-
- std::cout << "creating USLookupTableSource ... " << std::endl;
- m_Mode = DefaultLUT;
- m_LookupTable = NULL;
-
- this->Modified();
- std::cout << "creating USLookupTableSource OK! " << std::endl;
-}
-
-
-void mitk::USLookupTableSource::GenerateData()
-{
- std::cout << "USLookupTableSource::generate data!" << std::endl;
- OutputType::Pointer output = this->GetOutput();
- output->SetVtkLookupTable( this->BuildVtkLookupTable( ) );
-}
-
-vtkLookupTable* mitk::USLookupTableSource::BuildDSRDopplerLookupTable()
-{
-
- std::cout << " creating HP LookupTable ... " << std::endl;
-
- mitkIpPicDescriptor *HPMap;
-
- char MapFilename[ 20 ] = "a.map";
- int failed ;
-
- ifstream infile ( MapFilename, ios::in );
- failed = infile.fail() ;
- infile.close() ;
-
- if ( !failed ) // do we have a HP LUT ?
- {
- std::cout << " reading a.map ... " << std::endl;
- HPMap = usReadMap( "a.map", ".", -1000, -1000 );
-
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
- mitkIpUInt1_t *data = ( ( mitkIpUInt1_t * ) HPMap->data );
-
- vtkLookupTable->SetTableRange(0,255);
-
- int LookupTablesize = 256;
- double rgba[ 4 ];
-
- vtkLookupTable->SetNumberOfColors( LookupTablesize );
- for ( int i = 0; i < LookupTablesize; i++ )
- {
- rgba[ 0 ] = ( ( mitkIpUInt1_t * ) data ) [ 0 + i * 3 * LookupTablesize ] / 255.0f;
- rgba[ 1 ] = ( ( mitkIpUInt1_t * ) data ) [ 1 + i * 3 * LookupTablesize ] / 255.0f ;
- rgba[ 2 ] = ( ( mitkIpUInt1_t * ) data ) [ 2 + i * 3 * LookupTablesize ] / 255.0f ;
- rgba[ 3 ] = 1;
- vtkLookupTable->SetTableValue ( i, rgba );
- }
-
- return ( vtkLookupTable );
-
- } // do we have a HP LUT ?
-
-
- else // no HP lut -> create custom LUT
- {
- std::cout << " no a.map available! creating custom Doppler LookUpTable ... " << std::endl;
-
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
- vtkLookupTable->SetTableRange(0,255);
- // size is the no of different colors in the lut
- int size = 256;
- int lutSize = 256;
- int repeats = lutSize / size;
-
- int factor = 1;
- int i, n;
-
- double rgba[ 4 ];
-
- //int xDim = lutSize;
- //int yDim = 3;
-
- int quartalSize = size / 4;
-
- int index;
-
- for ( i = 1; i <= quartalSize ; i++ )
- {
- for ( n = 0; n < repeats ; n++ )
- {
-
- index = ( i - 1 ) * repeats + n;
- rgba[ 0 ] = 0; // rot
- rgba[ 1 ] = 1 - i / 2.0 / quartalSize; // gruen
- rgba[ 2 ] = 1; // blau
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
- }
-
- // dunkelblau
- for ( i = 1; i <= quartalSize ; i++ )
- {
- for ( n = 0; n < repeats ; n++ )
- {
-
- index = ( i - 1 ) * repeats + repeats * quartalSize + n;
- rgba[ 0 ] = 0;
- rgba[ 1 ] = 0.5 - i / 2.0 / quartalSize;
- rgba[ 2 ] = 1 - i / ( float ) ( 2 * quartalSize );
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
- }
-
-
-
- // dunkelrot
- for ( i = 1; i <= quartalSize ; i++ )
- {
- for ( n = 0; n < repeats ; n++ )
- {
-
- index = ( i - 1 ) * repeats + ( 2 * repeats * quartalSize ) + n;
- rgba[ 0 ] = 0.5 + i / ( float ) ( 2 * quartalSize );
- rgba[ 1 ] = i / 2.0 / quartalSize;
- rgba[ 2 ] = 0;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
- }
-
-
- // hellrot
- for ( i = 1; i <= quartalSize ; i++ )
- {
- for ( n = 0; n < repeats ; n++ )
- {
-
- index = ( i - 1 ) * repeats + ( 3 * repeats * quartalSize ) + n;
- rgba[ 0 ] = 1;
- rgba[ 1 ] = 0.5 + i / 2.0 / quartalSize;
- rgba[ 2 ] = 0;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
- }
-
- // the value 0 is mapped to black
- // so we see the field-out-of-view as black
- index = 0;
- rgba[ 0 ] = 0;
- rgba[ 1 ] = 0;
- rgba[ 2 ] = 0;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue( index, rgba );
-
- int mapZeroVelocityToBlack = 1;
- if ( mapZeroVelocityToBlack == 1 )
- {
- // map the middle value to black, so no velocity (v=0)
- // is displayed as black, otherwise darkred
- rgba[ 0 ] = 0;
- rgba[ 1 ] = 0;
- rgba[ 2 ] = 0;
- rgba[ 3 ] = factor * 1;
- index = lutSize / 2 ;
- vtkLookupTable->SetTableValue( index, rgba );
-// index = lutSize / 2 - 1;
-// vtkLookupTable->SetTableValue( index, rgba );
-// index = lutSize / 2 + 1;
- vtkLookupTable->SetTableValue( index, rgba );
- }
-
- // for (int i=0; i<size; i++)
- // {
- // vtkLookupTable->GetTableValue(i,&rgba[0]);
- // cout << "i=" << i << " r=" << rgba[0] << " g=" << rgba[1]<< " b=" << rgba[2] << endl;
- // }
-
- return( vtkLookupTable );
-
- } // no HP lut -> create custom LUT
-}
-
-
-vtkLookupTable* mitk::USLookupTableSource::BuildStrainRateLookupTable()
-{
- std::cout << " creating StrainRate LookupTable ... " << std::endl;
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
-
- vtkLookupTable->SetTableRange(0,255);
-
- int lutSize = 256;
- vtkLookupTable->SetNumberOfTableValues(lutSize);
-
- // xDim = size;
- // yDim = 3;
- double rgba[ 4 ];
-
- float quartal = lutSize / 8.0f;
-
- float sizeQuartal1 = 3 * quartal; //quartal-1;
-
- float sizeQuartal2 = 0.9375 * quartal;
- float sizeZeroStrain = 0.125 * quartal;
- float sizeQuartal3 = 0.9375 * quartal;
-
- // float sizeQuartal2 = 0.875 * quartal;
- // float sizeZeroStrain = 0.25* quartal;
- // float sizeQuartal3 = 0.875 * quartal;
-
- // float sizeQuartal2 = 0.975 * quartal;
- // float sizeZeroStrain = 0.05* quartal;
- // float sizeQuartal3 = 0.975 * quartal;
-
-
- float sizeQuartal4 = 3 * quartal;
-
- // std::cout << "quartal = " << quartal << std::endl;
- // std::cout << "quartal 1 = " << sizeQuartal1 << std::endl;
- // std::cout << "quartal 2 = " << sizeQuartal2 << std::endl;
- // std::cout << "quartal 3 = " << sizeQuartal3 << std::endl;
- // std::cout << "quartal 4 = " << sizeQuartal4 << std::endl;
- // std::cout << "quartal zero = " << sizeZeroStrain << std::endl;
-
-
- int factor = 1;
- int i;
-
- // dunkelrot
- for ( i = 1; i <= sizeQuartal1; i++ )
- {
- int index = i - 1;
- rgba[ 0 ] = factor * ( 0.5 + i / ( 2 * sizeQuartal1 ) ); // rot
- rgba[ 1 ] = factor * 0; // gruen
- rgba[ 2 ] = factor * 0; // blau
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
-
- // hellrot bis gelb
- for ( i = 1 ; i <= sizeQuartal2 ; i++ )
- {
- int index = ( i - 1 ) + ( int ) sizeQuartal1;
- rgba[ 0 ] = factor * 1;
- rgba[ 1 ] = factor * ( i / sizeQuartal2 );
- rgba[ 2 ] = factor * 0;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
-
-
- //gruen
- for ( i = 1 ; i <= sizeZeroStrain ; i++ )
- {
- int index = ( i - 1 ) + ( int ) ( sizeQuartal1 + sizeQuartal2 );
- rgba[ 0 ] = factor * 0; //1 - i/sizeZeroStrain;
- rgba[ 1 ] = factor * 1;
- rgba[ 2 ] = factor * 0; //i/sizeZeroStrain;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
-
-
- // hellblau
- for ( i = 1 ; i <= sizeQuartal3; i++ )
- {
- int index = ( i - 1 ) + ( int ) ( sizeQuartal1 + sizeQuartal2 + sizeZeroStrain );
- rgba[ 0 ] = factor * 0;
- rgba[ 1 ] = factor * ( 1 - i / sizeQuartal3 );
- rgba[ 2 ] = factor * 1;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- }
-
- // blau
- for ( i = 1 ; i <= sizeQuartal4 ; i++ )
- {
- int index = ( i - 1 ) + ( int ) ( sizeQuartal1 + sizeQuartal2 + sizeQuartal3 + sizeZeroStrain );
- rgba[ 0 ] = factor * 0;
- rgba[ 1 ] = factor * 0;
- rgba[ 2 ] = factor * ( 1 - i / sizeQuartal4 );
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
-
- }
-
- // the value 0 is mapped to black
- // so we see the field-out-of-view as black
- int index = 0;
- rgba[ 0 ] = 0;
- rgba[ 1 ] = 0;
- rgba[ 2 ] = 0;
- rgba[ 3 ] = factor * 1;
- vtkLookupTable->SetTableValue ( index, rgba );
- vtkLookupTable->SetTableValue ( index + 1, rgba );
-
- bool mapZeroStrainRateToBlack = true;
- if ( mapZeroStrainRateToBlack )
- {
- // map the middle value to black, so no velocity (v=0)
- // is displayed as black
- rgba[ 0 ] = 0;
- rgba[ 1 ] = 0;
- rgba[ 2 ] = 0;
- rgba[ 3 ] = factor * 1;
-
-// index = lutSize / 2 -1; // FIXME: this should be lutSize/2 !!!!????
- index = 128 ; // FIXME: this should be lutSize/2 !!!!????
- std::cout << " setting table value " << index << " to zero " << std::endl;
-
- vtkLookupTable->SetTableValue( index, rgba );
- }
-
-
-// for (int i=0; i<lutSize; i++)
-// {
-// vtkLookupTable->GetTableValue(i,&rgba[0]);
-// cout << "i=" << i << " r=" << rgba[0] << " g=" << rgba[1]<< " b=" << rgba[2] << endl;
-// }
-
-// std::cout << " created with " << vtkLookupTable->GetNumberOfColors() << " colors .. " << std::endl;
-// std::cout << " created with " << vtkLookupTable->GetNumberOfTableValues() << " colors .. " << std::endl;
-// float data[2];
-// vtkLookupTable->GetTableRange (data);
-// std::cout << " data0=" << data[0] << " data1=" << data[1] << std::endl;
-// vtkLookupTable->GetTableValue (200, rgba);
-// std::cout << " r=" << rgba[0] << " g=" << rgba[1] << " b=" << rgba[2]<< " a=" << rgba[3]<< std::endl;
-// float rgb[3];
-// vtkLookupTable->GetColor (200, rgb);
-// std::cout << " r=" << rgb[0] << " g=" << rgb[1] << " b=" << rgb[2]<< std::endl;
-// unsigned char *p = vtkLookupTable->GetPointer(200);
-// std::cout << " p0=" << (int)p[0] << " p1=" << (int)p[1] << " p2=" << (int)p[2]<< std::endl;
-// p = vtkLookupTable->GetPointer(128);
-// std::cout << " p0=" << (unsigned int)p[0] << " p1=" <<(unsigned int) p[1] << " p2=" << (unsigned int)p[2]<< std::endl;
-
- return( vtkLookupTable );
-
-}
-
-vtkLookupTable* mitk::USLookupTableSource::BuildDefaultLookupTable(){
-
- std::cout << " creating default LookupTable... " << std::endl;
- vtkLookupTable *vtkLookupTable = vtkLookupTable::New();
- int size = 256;
- vtkLookupTable->SetTableRange(0,255);
- vtkLookupTable->SetNumberOfColors( size );
- vtkLookupTable->Build();
- return( vtkLookupTable );
-
-}
-
-
-vtkLookupTable* mitk::USLookupTableSource::BuildVtkLookupTable()
-{
-
- std::cout << "mitk::USLookupTableSource::BuildVtkLookupTable() ... " << std::endl;
-
- if ( m_Mode == DSRDoppler )
- {
- return BuildDSRDopplerLookupTable();
- }
- else if ( m_Mode == StrainRate )
- {
- return BuildStrainRateLookupTable();
- }
- else
- {
- return BuildDefaultLookupTable();
- }
-
-
-}
-
-
-
diff --git a/Modules/Ext/DataManagement/mitkUSLookupTableSource.h b/Modules/Ext/DataManagement/mitkUSLookupTableSource.h
deleted file mode 100644
index 2d51c837ef..0000000000
--- a/Modules/Ext/DataManagement/mitkUSLookupTableSource.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKUSLookupTableSOURCE_H_HEADER_INCLUDED
-#define MITKUSLookupTableSOURCE_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkLookupTableSource.h"
-
-
-class mitk::LookupTable;
-
-namespace mitk
-{
-
-
-class MitkExt_EXPORT USLookupTableSource : public LookupTableSource
-{
-public:
- typedef enum {DSRDoppler, StrainRate, DefaultLUT} LookupTableMode;
-
- mitkClassMacro( USLookupTableSource, LookupTableSource );
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- /** @brief Some convenient typedefs. */
- typedef mitk::LookupTable OutputType;
-
- void SetUseDSRDopplerLookupTable() {m_Mode = DSRDoppler; this->Modified();};
-
- void SetUseStrainRateLookupTable() {m_Mode = StrainRate; this->Modified();};
-
-protected:
- USLookupTableSource();
- virtual ~USLookupTableSource();
-
- /**
- * Generates a LookupTable depended on the given mode and stores
- * it in an output object
- */
- virtual void GenerateData();
-
- /**
- * Generates a lookup table, dependend on the given mode
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildVtkLookupTable( );
-
- /**
- * Generates a Philips Doppler lookup table
- * if an a.map file is given, then a original LookupTable is genereated
- * else an LookupTable similar to the original one is generated
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildDSRDopplerLookupTable();
-
- /**
- * Generates a Strain Rate lookup table than those that are
- * used e.g. by GE
- *
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildStrainRateLookupTable();
-
- /**
- * Generates a default lookup table
- * @returns a vtkLookupTable
- */
- vtkLookupTable* BuildDefaultLookupTable();
-
-
-
-private:
- LookupTableMode m_Mode;
- OutputTypePointer m_LookupTable;
-
-};
-
-} // namespace mitk
-
-
-
-#endif /* MITKLookupTableSOURCE_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/DataManagement/vtkObjectSet.cpp b/Modules/Ext/DataManagement/vtkObjectSet.cpp
deleted file mode 100644
index bb8941ddaa..0000000000
--- a/Modules/Ext/DataManagement/vtkObjectSet.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "vtkObjectSet.h"
-#include "vtkObjectObserver.h"
-
-#include <vtkCommand.h>
-#include <vtkSmartPointer.h>
-#include <vtkCallbackCommand.h>
-
-vtkObjectSet::vtkObjectSet()
-{
-}
-
-vtkObjectSet::~vtkObjectSet()
-{
-
-}
-
-void vtkObjectSet::AddObserver( vtkObjectObserver* observer )
-{
- m_vtkObjectObservers.insert(observer);
-}
-
-void vtkObjectSet::RemoveObserver( vtkObjectObserver* observer )
-{
- m_vtkObjectObservers.erase(observer);
-}
-
-void vtkObjectSet::AddObject ( vtkObject * obj )
-{
- // if add object, add observer for modified and delete event
- std::pair<std::set<const vtkObject *>::iterator, bool> res = m_Objects.insert(obj);
-
- if(res.second)
- {
- vtkSmartPointer<vtkCallbackCommand> modifiedCallback =
- vtkSmartPointer<vtkCallbackCommand>::New();
- modifiedCallback->SetCallback ( vtkObjectSet::OnObjectModified );
- modifiedCallback->SetClientData(this);
-
- m_ObjectModifiedTags[obj] = obj->AddObserver
- ( vtkCommand::ModifiedEvent, modifiedCallback );
- m_ObjectDeleteTags[obj] = obj->AddObserver
- ( vtkCommand::DeleteEvent, modifiedCallback );
- }
-}
-
-void vtkObjectSet::RemoveObject ( vtkObject * obj )
-{
- // if object removed, remove observer and tags for modified and delete event
- std::set<const vtkObject *>::size_type deletedObjs = m_Objects.erase(obj);
-
- if(deletedObjs > 0)
- {
- obj->RemoveObserver(m_ObjectModifiedTags[obj]);
- obj->RemoveObserver(m_ObjectDeleteTags[obj]);
-
- m_ObjectModifiedTags.erase(obj);
- m_ObjectDeleteTags.erase(obj);
- }
-}
-
-void vtkObjectSet::OnObjectModified(vtkObject* caller, unsigned long eid
- , void* clientdata, void * /*calldata*/)
-{
- // if event == modified event, inform objectobservers
- // else: call RemoveObject() or remove objectobserver and inform objectobservers
-
- vtkObjectSet* instance = static_cast<vtkObjectSet*>( clientdata );
-
- for(std::set<vtkObjectObserver*>::iterator it = instance->m_vtkObjectObservers.begin();
- it != instance->m_vtkObjectObservers.end(); ++it)
- eid == vtkCommand::ModifiedEvent ? (*it)->OnModified( caller ):
- (*it)->OnDeleted( caller );
-
- if(eid != vtkCommand::ModifiedEvent)
- instance->RemoveObject( caller );
-}
diff --git a/Modules/Ext/DataManagement/vtkObjectSet.h b/Modules/Ext/DataManagement/vtkObjectSet.h
deleted file mode 100644
index b994cda7a6..0000000000
--- a/Modules/Ext/DataManagement/vtkObjectSet.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef MITKvtkObjectSet_H
-#define MITKvtkObjectSet_H
-
-#include <vtkObject.h>
-#include <mitkCommon.h>
-#include <MitkExtExports.h>
-#include <set>
-
-class vtkObjectObserver;
-
-///
-/// a class holding
-/// a list of itk objects and/or vtk objects.
-/// the main idea of the class
-/// is that it listens to the modified
-/// and delete events of the objects
-/// and informs associated objectobservers.
-/// This eases the handling of the sometimes complicated
-/// event handling mechanisms.
-///
-class MitkExt_EXPORT vtkObjectSet
-{
-public:
- vtkObjectSet();
- virtual ~vtkObjectSet();
-
- void AddObserver( vtkObjectObserver* observer );
- void RemoveObserver( vtkObjectObserver* observer );
-
- void AddObject ( vtkObject * obj );
- void RemoveObject ( vtkObject * obj );
-
- ///
- /// vtk event function
- ///
- static void OnObjectModified(vtkObject *, unsigned long eid
- , void* clientdata, void * /*calldata*/);
-protected:
- std::set<vtkObjectObserver*> m_vtkObjectObservers;
- std::set<const vtkObject*> m_Objects;
- ///
- /// \brief Holds all tags of Modified Event Listeners.
- ///
- std::map<const vtkObject *, unsigned long> m_ObjectModifiedTags;
- ///
- /// \brief Holds all tags of Modified Event Listeners.
- ///
- std::map<const vtkObject *, unsigned long> m_ObjectDeleteTags;
-};
-
-#endif // MITKvtkObjectSet_H
diff --git a/Modules/Ext/IO/mitkChiliPluginIpPicStub.c b/Modules/Ext/IO/mitkChiliPluginIpPicStub.c
deleted file mode 100644
index d05c50b105..0000000000
--- a/Modules/Ext/IO/mitkChiliPluginIpPicStub.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#undef CHILIPLUGIN
-#include "mitkIpPicGet.c"
diff --git a/Modules/Ext/IO/mitkObjFileIOFactory.cpp b/Modules/Ext/IO/mitkObjFileIOFactory.cpp
deleted file mode 100644
index 24d6eaf34a..0000000000
--- a/Modules/Ext/IO/mitkObjFileIOFactory.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkObjFileIOFactory.h"
-#include "mitkIOAdapter.h"
-#include "mitkObjFileReader.h"
-
-#include "itkVersion.h"
-
-
-namespace mitk
-{
-ObjFileIOFactory::ObjFileIOFactory()
-{
- this->RegisterOverride("mitkIOAdapter",
- "mitkObjFileReader",
- "mitk Obj Surface IO",
- 1,
- itk::CreateObjectFunction<IOAdapter<ObjFileReader> >::New());
-}
-
-ObjFileIOFactory::~ObjFileIOFactory()
-{
-}
-
-const char* ObjFileIOFactory::GetITKSourceVersion() const
-{
- return ITK_SOURCE_VERSION;
-}
-
-const char* ObjFileIOFactory::GetDescription() const
-{
- return "ObjFile IO Factory, allows the loading of Obj files";
-}
-
-} // end namespace mitk
diff --git a/Modules/Ext/IO/mitkObjFileIOFactory.h b/Modules/Ext/IO/mitkObjFileIOFactory.h
deleted file mode 100644
index 1ef13fdcbe..0000000000
--- a/Modules/Ext/IO/mitkObjFileIOFactory.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef __mitkObjFileIOFactory_h
-#define __mitkObjFileIOFactory_h
-
-#ifdef _MSC_VER
-#pragma warning ( disable : 4786 )
-#endif
-
-#include "itkObjectFactoryBase.h"
-#include "MitkExtExports.h"
-#include "mitkBaseData.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Create instances of ObjFileReader objects using an object factory.
-//##
-//## @ingroup IO
-class MitkExt_EXPORT ObjFileIOFactory : public itk::ObjectFactoryBase
-{
-public:
- /** Standard class typedefs. */
- typedef ObjFileIOFactory Self;
- typedef itk::ObjectFactoryBase Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Class methods used to interface with the registered factories. */
- virtual const char* GetITKSourceVersion(void) const;
- virtual const char* GetDescription(void) const;
-
- /** Method for class instantiation. */
- itkFactorylessNewMacro(Self);
- static ObjFileIOFactory* FactoryNew() { return new ObjFileIOFactory;}
- /** Run-time type information (and related methods). */
- itkTypeMacro(ObjFileIOFactory, ObjectFactoryBase);
-
- /**
- * Register one factory of this type
- * \deprecatedSince{2013_09}
- */
- DEPRECATED(static void RegisterOneFactory(void))
- {
- ObjFileIOFactory::Pointer ObjFileIOFactory = ObjFileIOFactory::New();
- ObjectFactoryBase::RegisterFactory(ObjFileIOFactory);
- }
-
-protected:
- ObjFileIOFactory();
- ~ObjFileIOFactory();
-
-private:
- ObjFileIOFactory(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace mitk
-
-#endif
diff --git a/Modules/Ext/IO/mitkObjFileReader.cpp b/Modules/Ext/IO/mitkObjFileReader.cpp
deleted file mode 100644
index f101302f66..0000000000
--- a/Modules/Ext/IO/mitkObjFileReader.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "mitkObjFileReader.h"
-#include <mitkSurface.h>
-#include <vtkOBJReader.h>
-
-
-mitk::ObjFileReader::ObjFileReader()
- : m_FileName("")
-{
-}
-
-mitk::ObjFileReader::~ObjFileReader()
-{
-}
-
-void mitk::ObjFileReader::GenerateData()
-{
- mitk::Surface::Pointer output = this->GetOutput();
-
- if( m_FileName != "")
- {
- MITK_INFO << "Loading " << m_FileName << " as obj..." << std::endl;
-
- vtkOBJReader *reader = vtkOBJReader::New();
- reader->SetFileName( m_FileName.c_str() );
- reader->Update();
-
- if ( reader->GetOutput() != NULL )
- output->SetVtkPolyData( reader->GetOutput() );
-
- reader->Delete();
-
- MITK_INFO << "...finished!" << std::endl;
- }
-}
-
-bool mitk::ObjFileReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
-{
- // First check the extension
- //std::string filename = file;
- if( filename == "" )
- {
- //MITK_INFO<<"No filename specified."<<std::endl;
- return false;
- }
-
- bool extensionFound = false;
- std::string::size_type ObjPos = filename.rfind(".obj");
- if ((ObjPos != std::string::npos)
- && (ObjPos == filename.length() - 4))
- {
- extensionFound = true;
- }
-
- ObjPos = filename.rfind(".OBJ");
- if ((ObjPos != std::string::npos)
- && (ObjPos == filename.length() - 4))
- {
- extensionFound = true;
- }
-
- if( !extensionFound )
- {
- //MITK_INFO<<"The filename extension is not recognized."<<std::endl;
- return false;
- }
-
- return true;
-}
diff --git a/Modules/Ext/IO/mitkObjFileReader.h b/Modules/Ext/IO/mitkObjFileReader.h
deleted file mode 100644
index 49b725deae..0000000000
--- a/Modules/Ext/IO/mitkObjFileReader.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef ObjFileReader_H_HEADER_INCLUDED
-#define ObjFileReader_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkSurfaceSource.h"
-
-namespace mitk {
-//##Documentation
-//## @brief Reader to read files in Obj-format
-//## @ingroup IO
-class MitkExt_EXPORT ObjFileReader : public SurfaceSource
-{
-public:
- mitkClassMacro(ObjFileReader, SurfaceSource);
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetStringMacro(FileName);
- itkGetStringMacro(FileName);
-
- itkSetStringMacro(FilePrefix);
- itkGetStringMacro(FilePrefix);
-
- itkSetStringMacro(FilePattern);
- itkGetStringMacro(FilePattern);
-
- static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
-
-protected:
- virtual void GenerateData();
-
- ObjFileReader();
-
- ~ObjFileReader();
-
- std::string m_FileName, m_FilePrefix, m_FilePattern;
-
-};
-
-} // namespace mitk
-
-#endif /* ObjFileReader_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/IO/mitkPACSPlugin.cpp b/Modules/Ext/IO/mitkPACSPlugin.cpp
deleted file mode 100644
index fdd5df6bc2..0000000000
--- a/Modules/Ext/IO/mitkPACSPlugin.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkPACSPlugin.h"
-
-#include <iostream>
-
-mitk::PACSPlugin* mitk::PACSPlugin::GetInstance(bool destroyInstance)
-{
- static mitk::PACSPlugin::Pointer s_Instance = mitk::PACSPlugin::New();
-
- if( destroyInstance )
- {
- s_Instance = NULL;
- }
-
- return s_Instance;
-}
-
-
-mitk::PACSPlugin::PACSPlugin()
-: m_ReaderType(0)
-{
-}
-
-
-mitk::PACSPlugin::~PACSPlugin()
-{
-}
-
-
-mitk::PACSPlugin::PACSPluginCapability mitk::PACSPlugin::GetPluginCapabilities()
-{
- PACSPluginCapability result;
- result.IsPACSFunctional = false;
- result.HasLoadCapability = false;
- result.HasSaveCapability = false;
- return result;
-}
-
-
-mitk::PACSPlugin::PatientInformationList mitk::PACSPlugin::GetPatientInformationList()
-{
- PatientInformationList emptyResult;
- emptyResult.clear();
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::StudyInformationList mitk::PACSPlugin::GetStudyInformationList( const PatientInformation& /* patient */ )
-{
- StudyInformationList emptyResult;
- emptyResult.clear();
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::SeriesInformationList mitk::PACSPlugin::GetSeriesInformationList( const std::string& /*studyInstanceUID*/ )
-{
- SeriesInformationList emptyResult;
- emptyResult.clear();
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::DocumentInformationList mitk::PACSPlugin::GetDocumentInformationList( const std::string& /*seriesInstanceUID*/ )
-{
- DocumentInformationList emptyResult;
- emptyResult.clear();
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::PatientInformation mitk::PACSPlugin::GetPatientInformation( const std::string& )
-{
- PatientInformation emptyResult;
- emptyResult.PatientsSex = "O";
- emptyResult.PatientComments = "No PACS connectivity implemented or configured. Cannot query patient";
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::StudyInformation mitk::PACSPlugin::GetStudyInformation( const std::string& )
-{
- StudyInformation emptyResult;
- emptyResult.StudyDescription = "No PACS connectivity implemented or configured. Cannot query study";
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::SeriesInformation mitk::PACSPlugin::GetSeriesInformation( const std::string& )
-{
- SeriesInformation emptyResult;
- emptyResult.SeriesDescription = "No PACS connectivity implemented or configured. Cannot query series.";
- return emptyResult;
-}
-
-
-mitk::PACSPlugin::DocumentInformation mitk::PACSPlugin::GetDocumentInformation( const std::string& itkNotUsed(seriesInstanceUID),
- unsigned int itkNotUsed(instanceNumber) )
-{
- DocumentInformation emptyResult;
- return emptyResult;
-}
-
-
-unsigned int mitk::PACSPlugin::GetLightboxCount()
-{
- return 0;
-}
-
-
-unsigned int mitk::PACSPlugin::GetActiveLightbox()
-{
- return (unsigned int)-1; // user should check GetLightboxCount() first, unsensible values might tell him that his request is not sensible
-}
-
-
-void mitk::PACSPlugin::SetReaderType( unsigned int readerType )
-{
- m_ReaderType = readerType;
-}
-
-
-void mitk::PACSPlugin::AbortPACSImport()
-{
-}
-
-
-std::vector<mitk::DataNode::Pointer> mitk::PACSPlugin::LoadImagesFromLightbox( unsigned int itkNotUsed(lightboxIndex) )
-{
- std::vector<DataNode::Pointer> emptyVector;
- emptyVector.clear();
- return emptyVector;
-}
-
-
-std::vector<mitk::DataNode::Pointer> mitk::PACSPlugin::LoadFromSeries( const std::string& seriesInstanceUID )
-{
- std::vector<DataNode::Pointer> resultVector = this->LoadImagesFromSeries( seriesInstanceUID );
- std::vector<DataNode::Pointer> secondResultVector = this->LoadTextsFromSeries( seriesInstanceUID );
- resultVector.insert( resultVector.end(), secondResultVector.begin(), secondResultVector.end() );
- return resultVector;
-}
-
-
-std::vector<mitk::DataNode::Pointer> mitk::PACSPlugin::LoadImagesFromSeries( const std::string& /* seriesInstanceUID */ )
-{
- std::vector<DataNode::Pointer> emptyVector;
- emptyVector.clear();
- return emptyVector;
-}
-
-std::vector<mitk::DataNode::Pointer> mitk::PACSPlugin::LoadImagesFromSeries( std::vector<std::string> /* seriesInstanceUIDs */ )
-{
- std::vector<DataNode::Pointer> emptyVector;
- emptyVector.clear();
- return emptyVector;
-}
-
-
-std::vector<mitk::DataNode::Pointer> mitk::PACSPlugin::LoadTextsFromSeries( const std::string& /* seriesInstanceUID */ )
-{
- std::vector<DataNode::Pointer> emptyVector;
- emptyVector.clear();
- return emptyVector;
-}
-
-
-mitk::DataNode::Pointer mitk::PACSPlugin::LoadSingleText( const std::string& /* seriesInstanceUID */ , unsigned int /* instanceNumber */ )
-{
- return NULL;
-}
-
-
-void mitk::PACSPlugin::SaveAsNewSeries( DataStorage::SetOfObjects::ConstPointer /* inputNodes */,
- const std::string& /* studyInstanceUID */,
- int /* seriesNumber */,
- const std::string& /*seriesDescription */)
-{
-}
-
-
-void mitk::PACSPlugin::SaveToSeries( DataStorage::SetOfObjects::ConstPointer /* inputNodes */,
- const std::string& /* seriesInstanceUID */,
- bool /* overwriteExistingSeries */)
-{
-}
-
-void mitk::PACSPlugin::UploadFileAsNewSeries( const std::string& /* filename */,
- const std::string& /* mimeType */,
- const std::string& /* studyInstanceUID */,
- int /* seriesNumber */,
- const std::string& /* seriesDescription */ )
-{
-}
-
-void mitk::PACSPlugin::UploadFileToSeries( const std::string& /* filename */,
- const std::string& /* filebasename */,
- const std::string& /* mimeType */,
- const std::string& /* seriesInstanceUID */,
- bool /* overwriteExistingSeries */ )
-{
-}
-
-std::string mitk::PACSPlugin::GuessMIMEType( const std::string& filename )
-{
- std::ifstream file( filename.c_str() );
- if (!file)
- {
- // cannot open file
- return std::string("");
- }
-
- const unsigned int maxLength = 8;
- unsigned char line[ maxLength];
- file.getline( reinterpret_cast<char*>(line), maxLength );
- file.close();
-
- std::string firstLine( reinterpret_cast<char*>(line) );
-
- if ( firstLine.substr( 1, 3 ) == "PDF" )
- {
- return std::string("application/pdf");
- }
-
- if ( firstLine.substr( 0, 5 ) == "{\\rtf" )
- {
- return std::string("text/richtext");
- }
-
- if ( firstLine.substr( 0, 2 ) == "PK" )
- {
- return std::string("application/zip");
- }
-
- if ( (line[0] == 0xFF) && (line[1] == 0xD8) )
- {
- return std::string("image/jpeg");
- }
-
- if ( (line[0] == 0x89) &&
- (line[1] == 0x50) &&
- (line[2] == 0x4E) &&
- (line[3] == 0x47) &&
- (line[4] == 0x0D) &&
- (line[5] == 0x0A) &&
- (line[6] == 0x1A) &&
- (line[7] == 0x0A)
- )
- {
- return std::string("image/png");
- }
-
- if ( (line[0] == 0x4D) && (line[1] == 0x5A) )
- {
- //return std::string("application/octet-stream");
- return std::string("Windows EXE");
- }
-
- if ( ( filename.rfind( ".stl" ) == filename.length() - 4 ) ||
- ( filename.rfind( ".STL" ) == filename.length() - 4 ) )
- {
- // this is a guess. don't know a good way to test for STL.
- return std::string("application/sla");
- }
-
- if ( ( filename.rfind( ".txt" ) == filename.length() - 4 ) ||
- ( filename.rfind( ".TXT" ) == filename.length() - 4 ) )
- {
- // this is a guess. don't know a good way to test for STL.
- return std::string("text/plain");
- }
-
- return std::string("");
-}
-
-
-void mitk::PACSPlugin::DownloadSingleFile( const std::string& /*seriesInstanceUID*/,
- unsigned int /*instanceNumber*/,
- const std::string& /*filename*/)
-{
-}
diff --git a/Modules/Ext/IO/mitkPACSPlugin.h b/Modules/Ext/IO/mitkPACSPlugin.h
deleted file mode 100644
index b17d09d086..0000000000
--- a/Modules/Ext/IO/mitkPACSPlugin.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKCHILIPLUGIN_H_HEADER_INCLUDED_C1EBD0AD
-#define MITKCHILIPLUGIN_H_HEADER_INCLUDED_C1EBD0AD
-
-#include "mitkDataStorage.h"
-#include "MitkExtExports.h"
-
-namespace mitk {
-
-/** Documentation
- \brief Interface for minimal PACS communication
- \ingroup IO
- \ingroup Chili
-
- Defines some basic function for communication with a PACS.
- Currently only really implemented for the CHILI Workstation (see CHILIPlugin),
- but should be basic enough to work with differnt systems, too.
-
- \todo The PatientInformation, StudyInformation, SeriesInformation structures should be classes able to contain any kind of tags
-*/
-class MitkExt_EXPORT PACSPlugin : public itk::Object
-{
- public:
-
- /** This struct contain the plugin capabilities. */
- struct MitkExt_EXPORT PACSPluginCapability
- {
- bool IsPACSFunctional; // is there actually a real PACS connectivity implemented, configured and working right now?
- bool HasLoadCapability; // can the current implementation load data from a PACS?
- bool HasSaveCapability; // can the current implementation save data into the PACS?
- };
-
- /** Information about a patient in the PACS. Fields should correspond to DICOM PS 3.4-2008 Annex C.6.1.1.2 **/
- class MitkExt_EXPORT PatientInformation
- {
- public:
- std::string UID; // application specific
- std::string PatientsName; // tag 0010,0010
- std::string PatientID; // tag 0010,0020
- std::string PatientsBirthDate; // tag 0010,0030
- std::string PatientsBirthTime; // tag 0010,0032
- std::string PatientsSex; // tag 0010,0040
- std::string PatientComments; // tag 0010,4000
- };
-
- typedef std::list<PatientInformation> PatientInformationList;
-
- /** Information about a study in the PACS. Fields should correspond to DICOM PS 3.4-2008 Annex C.6.1.1.3 **/
- class MitkExt_EXPORT StudyInformation
- {
- public:
- std::string StudyInstanceUID; // tag 0020,000D
- std::string StudyID; // tag 0020,0010
- std::string StudyDate; // tag 0008,0020
- std::string StudyTime; // tag 0008,0030
- std::string AccessionNumber; // tag 0008,0050
- std::string ModalitiesInStudy; // tag 0008,0061
- std::string ReferringPhysician; // tag 0008,0090
- std::string StudyDescription; // tag 0008,1030
- };
-
- typedef std::list<StudyInformation> StudyInformationList;
-
- /** Information about a study in the PACS. Fields should correspond to DICOM PS 3.4-2008 Annex C.6.1.1.4 **/
- class MitkExt_EXPORT SeriesInformation
- {
- public:
- std::string SeriesInstanceUID; // tag 0020,000E
- int SeriesNumber; // tag 0020,0011
- std::string SeriesDate; // tag 0008,0021
- std::string SeriesTime; // tag 0008,0031
- std::string SeriesDescription; // tag 0008,103E
- std::string BodyPartExamined; // tag 0018,0015
- std::string FrameOfReferenceUID;// tag 0020,0052
- int AcquisitionNumber; // tag 0020,0012 image specific
- std::string ContrastAgent; // tag 0018,0010 image specific
- std::string ScanningSequence; // tag 0018,0020 mr image specific
- int EchoNumber; // tag 0018,0086 mr image specific
- int TemporalPosition; // tag 0020,0100 mr image specific
-
- SeriesInformation()
- : SeriesNumber(-1),
- AcquisitionNumber(-1),
- EchoNumber(-1),
- TemporalPosition(-1)
- {
- }
- };
-
- typedef std::list<SeriesInformation> SeriesInformationList;
-
- /** Information about a document in a series. Very roughly corresponds to DICOM PS 3.3-2008 Annex C.24 */
- class MitkExt_EXPORT DocumentInformation
- {
- public:
- std::string SeriesInstanceUID; // tag 0020,000E
- unsigned int InstanceNumber; // tag 0020,0013
- std::string MimeType; // tag 0042,0012
- std::string ContentDate; // tag 0008,0023
- std::string DocumentTitle; // tag 0042,0010
-
- DocumentInformation()
- :InstanceNumber( (unsigned int)-1 )
- {
- }
- };
-
- /** There can be lots of texts to one series, so we need a list. */
- typedef std::list<DocumentInformation> DocumentInformationList;
-
- mitkClassMacro( PACSPlugin,itk::Object );
-
- /*!
- * \brief Return a singleton mitk::PACSPlugin-Instance
- *
- * \param destroyInstance Tell the specific implementation it should free/delete itself.
- * \warning Application should not use the instance after calling GetInstance(true);
- * \todo check deletion mechanism, should be done by the application, which knows about CHILI (because there is a QcMITK...
- */
- static PACSPlugin* GetInstance( bool destroyInstance = false );
-
- /*!
- * \brief Information about capabilities of the current implementation.
- */
- virtual PACSPluginCapability GetPluginCapabilities();
-
- /*!
- * \brief Get a list of all known patients
- */
- virtual PatientInformationList GetPatientInformationList();
-
- /*!
- * \brief Get a list of all studies for a patient
- */
- virtual StudyInformationList GetStudyInformationList( const PatientInformation& patient );
-
- /*!
- * \brief Get a list of all series for a study instance UID
- */
- virtual SeriesInformationList GetSeriesInformationList( const std::string& studyInstanceUID = "" );
-
- /*!
- * \brief Get a list of all non-image documents for a series instance UID
- */
- virtual DocumentInformationList GetDocumentInformationList( const std::string& seriesInstanceUID = "" );
-
- /*!
- * \brief Patient information for a given series instance UID
- */
- virtual PatientInformation GetPatientInformation( const std::string& seriesInstanceUID = "" );
-
- /*!
- * \brief Study information for a given series instance UID
- */
- virtual StudyInformation GetStudyInformation( const std::string& seriesInstanceUID = "" );
-
- /*!
- * \brief Series information for a given series instance UID
- */
- virtual SeriesInformation GetSeriesInformation( const std::string& seriesInstanceUID = "" );
-
- /*!
- * \brief Document information for a given series instance UID and a document instance number
- */
- virtual DocumentInformation GetDocumentInformation( const std::string& seriesInstanceUID,
- unsigned int instanceNumber );
-
- /*!
- * \brief Number of image preview boxes (lightboxes)
- *
- * If the specific PACS implementation supports a kind of lightbox concept
- * (a preview of all images from a selected series), then this function should
- * return how many of such lightboxes there are.
- */
- virtual unsigned int GetLightboxCount();
-
- /*!
- * \brief Return the index of the active image preview box (lightbox)
- *
- * If the specific PACS implementation supports a kind of lightbox concept
- * (a preview of all images from a selected series), then this function should
- * return the index of the currently active lightbox (starting from 0).
- *
- * If no active lightbox exists (perhaps due to lack of such a concept), it
- * is the calling object's duty to check if the returned index is larger than
- * the number of existing lightboxes reported by GetLightboxCount().
- */
- virtual unsigned int GetActiveLightbox();
-
- /*!
- * Set type of "sorter" that stacks 2D images into 3D or 3D+t volumes
- * \param readerType 0 used for the ImageNumberFilter, 1 for the SingleSpacingFilter and 2 used for SpacingSetFilter.
- * \todo this should take enum values
- */
- virtual void SetReaderType( unsigned int readerType = 0 );
-
- virtual void AbortPACSImport();
-
- /*!
- *
- * \brief Load all images from the given lightbox.
- * \todo rename to LoadLightboxContent and load all images and texts, ignoring the lightbox!! make it use LoadSeriesContent for all series UIDs found in lightbox
- */
- virtual std::vector<DataNode::Pointer> LoadImagesFromLightbox( unsigned int lightboxIndex = 0 );
-
- /*!
- * \brief Load all objects from a given series instance UID
- * \todo rename to LoadSeriesContent, make this take a list of UIDs
- */
- virtual std::vector<DataNode::Pointer> LoadFromSeries( const std::string& seriesInstanceUID );
-
- /*!
- * \brief Load all image objects from a given series instance UID
- * \todo rename to LoadSeriesImageContent, make this take a list of UIDs
- */
- virtual std::vector<DataNode::Pointer> LoadImagesFromSeries( const std::string& seriesInstanceUID );
-
- virtual std::vector<mitk::DataNode::Pointer> LoadImagesFromSeries( std::vector<std::string> seriesInstanceUIDs );
-
- /*!
- * \brief Load all objects from a given series instance UID
- * \todo rename to LoadSeriesDocumentContent, make this take a list of UIDs
- */
- virtual std::vector<DataNode::Pointer> LoadTextsFromSeries( const std::string& seriesInstanceUID );
-
- /*!
- * \brief Load a given document object for a series instance UID and a document instance number
- * \todo rename to LoadDocument make it take a list of parameters
- */
- virtual DataNode::Pointer LoadSingleText( const std::string& seriesInstanceUID, unsigned int instanceNumber );
-
- /*!
- * \brief Load a given document object for a series instance UID and a document instance number
- * In contrast to LoadSingleText this method will just create a new file on the local file system.
- */
- virtual void DownloadSingleFile( const std::string& seriesInstanceUID,
- unsigned int instanceNumber,
- const std::string& filename );
-
- /*!
- * \brief Save given data as a new series
- * \param studyInstanceUID save into this study
- * \param seriesNumber a number identifying the new series
- * \param seriesDescription a string description for the new series
- */
- virtual void SaveAsNewSeries( DataStorage::SetOfObjects::ConstPointer inputNodes,
- const std::string& studyInstanceUID,
- int seriesNumber,
- const std::string& seriesDescription );
-
- /*!
- * \brief Save given data into an existing series
- * \param seriesInstanceUID save into this series
- * \param seriesDescription a string description for the new series
- */
- virtual void SaveToSeries( DataStorage::SetOfObjects::ConstPointer inputNodes,
- const std::string& seriesInstanceUID,
- bool overwriteExistingSeries );
-
- /*!
- * \brief Upload a file as a new series
- * \param studyInstanceUID save into this study
- * \param seriesNumber a number identifying the new series
- * \param seriesDescription a string description for the new series
- */
- virtual void UploadFileAsNewSeries( const std::string& filename,
- const std::string& mimeType,
- const std::string& studyInstanceUID,
- int seriesNumber,
- const std::string& seriesDescription );
-
- /*!
- * \brief Upload file into an existing series
- * \param seriesInstanceUID save into this series
- * \param seriesDescription a string description for the new series
- */
- virtual void UploadFileToSeries( const std::string& filename,
- const std::string& filebasename,
- const std::string& mimeType,
- const std::string& seriesInstanceUID,
- bool overwriteExistingSeries );
-
- virtual std::string GuessMIMEType( const std::string& filename );
-
-
- protected:
-
- // All this is hidden, should be instantiated through the GetInstance() method.
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
- PACSPlugin();
- virtual ~PACSPlugin();
-
- int m_ReaderType;
-};
-
-} // end namespace
-
-#endif
-
diff --git a/Modules/Ext/IO/mitkPACSPluginEvents.h b/Modules/Ext/IO/mitkPACSPluginEvents.h
deleted file mode 100644
index 54130dfae8..0000000000
--- a/Modules/Ext/IO/mitkPACSPluginEvents.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef mitkPACSPluginEventshincluded
-#define mitkPACSPluginEventshincluded
-
-#include <itkObject.h>
-#pragma GCC visibility push(default)
-#include <itkEventObject.h>
-#pragma GCC visibility pop
-
-namespace mitk
-{
- #pragma GCC visibility push(default)
- itkEventMacro( PluginEvent, itk::AnyEvent );
- itkEventMacro( PluginStudySelected, PluginEvent );
- itkEventMacro( PluginLightBoxCountChanged, PluginEvent );
- itkEventMacro( PluginAbortPACSImport, PluginEvent );
- #pragma GCC visibility pop
-}
-
-#endif
-
diff --git a/Modules/Ext/IO/mitkParRecFileIOFactory.cpp b/Modules/Ext/IO/mitkParRecFileIOFactory.cpp
deleted file mode 100644
index 8b2d7d6bf5..0000000000
--- a/Modules/Ext/IO/mitkParRecFileIOFactory.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkParRecFileIOFactory.h"
-#include "mitkIOAdapter.h"
-#include "mitkParRecFileReader.h"
-
-#include "itkVersion.h"
-
-
-namespace mitk
-{
-ParRecFileIOFactory::ParRecFileIOFactory()
-{
- this->RegisterOverride("mitkIOAdapter",
- "mitkParRecFileReader",
- "mitk ParRec Image IO",
- 1,
- itk::CreateObjectFunction<IOAdapter<ParRecFileReader> >::New());
-}
-
-ParRecFileIOFactory::~ParRecFileIOFactory()
-{
-}
-
-const char* ParRecFileIOFactory::GetITKSourceVersion() const
-{
- return ITK_SOURCE_VERSION;
-}
-
-const char* ParRecFileIOFactory::GetDescription() const
-{
- return "ParRecFile IO Factory, allows the loading of ParRec images";
-}
-
-} // end namespace mitk
diff --git a/Modules/Ext/IO/mitkParRecFileIOFactory.h b/Modules/Ext/IO/mitkParRecFileIOFactory.h
deleted file mode 100644
index 334717fcb5..0000000000
--- a/Modules/Ext/IO/mitkParRecFileIOFactory.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef __mitkParRecFileIOFactory_h
-#define __mitkParRecFileIOFactory_h
-
-#ifdef _MSC_VER
-#pragma warning ( disable : 4786 )
-#endif
-
-#include "itkObjectFactoryBase.h"
-#include "MitkExtExports.h"
-#include "mitkBaseData.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Create instances of ParRecFileReader objects using an object factory.
-//##
-//## @ingroup IO
-class MitkExt_EXPORT ParRecFileIOFactory : public itk::ObjectFactoryBase
-{
-public:
- /** Standard class typedefs. */
- typedef ParRecFileIOFactory Self;
- typedef itk::ObjectFactoryBase Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Class methods used to interface with the registered factories. */
- virtual const char* GetITKSourceVersion(void) const;
- virtual const char* GetDescription(void) const;
-
- /** Method for class instantiation. */
- itkFactorylessNewMacro(Self);
- static ParRecFileIOFactory* FactoryNew() { return new ParRecFileIOFactory;}
- /** Run-time type information (and related methods). */
- itkTypeMacro(ParRecFileIOFactory, ObjectFactoryBase);
-
- /**
- * Register one factory of this type
- * \deprecatedSince{2013_09}
- */
- DEPRECATED(static void RegisterOneFactory(void))
- {
- ParRecFileIOFactory::Pointer ParRecFileIOFactory = ParRecFileIOFactory::New();
- ObjectFactoryBase::RegisterFactory(ParRecFileIOFactory);
- }
-
-protected:
- ParRecFileIOFactory();
- ~ParRecFileIOFactory();
-
-private:
- ParRecFileIOFactory(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace mitk
-
-#endif
diff --git a/Modules/Ext/IO/mitkParRecFileReader.cpp b/Modules/Ext/IO/mitkParRecFileReader.cpp
deleted file mode 100644
index 045064e54d..0000000000
--- a/Modules/Ext/IO/mitkParRecFileReader.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkParRecFileReader.h"
-#include <itkImageFileReader.h>
-
-#ifdef __GNUC__
-#define stricmp strcasecmp
-#endif
-
-void mitk::ParRecFileReader::GenerateOutputInformation()
-{
- mitk::Image::Pointer output = this->GetOutput();
-
- if ((output->IsInitialized()) && (this->GetMTime() <= m_ReadHeaderTime.GetMTime()))
- return;
-
- itkDebugMacro(<<"Reading PAR file for GenerateOutputInformation()" << m_FileName);
-
- // Check to see if we can read the file given the name or prefix
- //
- if ( m_FileName == "" && m_FilePrefix == "" )
- {
- throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty");
- }
-
- m_RecFileName = "";
- if( m_FileName != "")
- {
- int extPos=m_FileName.find_last_of(".");
- if(extPos>=-1)
- {
- const char *ext=m_FileName.c_str()+extPos+1;
- if(stricmp(ext,"par")==0)
- m_RecFileName = m_FileName.substr(0,extPos);
- else
- m_RecFileName = m_FileName;
- }
- else
- m_RecFileName = m_FileName;
-
- m_RecFileName.append(".rec");
-
- bool headerRead = false;
-
- bool signedCharType = true;
- unsigned int dimension=0;
- unsigned int dimensions[4]={0,0,1,1};
- float sliceThickness=0.0;
- float sliceGap=0.0;
- float sliceSpacing=0.0;
- mitk::Vector3D thickness; thickness.Fill(1.0);
- mitk::Vector3D gap; gap.Fill(0.0);
- mitk::Vector3D spacing;
-
- FILE *f;
- f=fopen(m_FileName.c_str(), "r");
- if(f!=NULL)
- {
- while(!feof(f))
- {
- char s[300], *p;
- char* ignored = fgets(s,200,f);
- ++ignored;
- if(strstr(s,"Max. number of cardiac phases"))
- {
- p=strchr(s,':')+1;
- dimensions[3]=atoi(p);
- if(dimensions[3]>1)
- dimension=4;
- }
- else
- if(strstr(s,"Max. number of slices/locations"))
- {
- p=strchr(s,':')+1;
- dimensions[2]=atoi(p);
- if(dimension==0)
- {
- if(dimensions[2]>1)
- dimension=3;
- else
- dimension=2;
- }
- }
- else
- if(strstr(s,"Image pixel size"))
- {
- p=strchr(s,':')+1;
- int bpe=atoi(p);
- if(bpe!=8)
- signedCharType = false;
- }
- else
- if(strstr(s,"Recon resolution"))
- {
- p=s+strcspn(s,"0123456789");
- sscanf(p,"%u %u", dimensions, dimensions+1);
- }
- else
- if(strstr(s,"FOV (ap,fh,rl) [mm]"))
- {
- p=s+strcspn(s,"0123456789");
- char *oldLocale = setlocale(LC_ALL, 0);
- sscanf(p,"%f %f %f", &thickness[0], &thickness[1], &thickness[2]);
- setlocale(LC_ALL, oldLocale);
- }
- else
- if(strstr(s,"Slice thickness [mm]"))
- {
- p=s+strcspn(s,"0123456789");
- char *oldLocale = setlocale(LC_ALL, 0);
- sscanf(p,"%f", &sliceThickness);
- setlocale(LC_ALL, oldLocale);
- }
- else
- if(strstr(s,"Slice gap [mm]"))
- {
- p=s+strcspn(s,"-0123456789");
- char *oldLocale = setlocale(LC_ALL, 0);
- sscanf(p,"%f", &sliceGap);
- setlocale(LC_ALL, oldLocale);
- }
- }
- fclose(f);
-
-//C:\home\ivo\data\coronaries\ucsf-wholeheart-2.par
- sliceSpacing = sliceThickness+sliceGap;
- if((dimension>0) && (dimensions[0]>0) && (dimensions[1]>0) && (sliceThickness>0) && (sliceSpacing>0))
- {
- headerRead = true;
- if(fabs(thickness[0]/dimensions[2]-sliceSpacing)<0.0001)
- thickness[0]=thickness[1];
- else
- if(fabs(thickness[1]/dimensions[2]-sliceSpacing)<0.0001)
- thickness[1]=thickness[0];
- thickness[2]=sliceSpacing;
-
- thickness[0]/=dimensions[0];
- thickness[1]/=dimensions[1];
- spacing=thickness+gap;
- }
- }
-
- if( headerRead == false)
- {
- itk::ImageFileReaderException e(__FILE__, __LINE__);
- std::ostringstream msg;
- msg << " Could not read file "
- << m_FileName.c_str();
- e.SetDescription(msg.str().c_str());
- throw e;
- return;
- }
-
- // define types
- mitk::PixelType SCType = mitk::MakeScalarPixelType<signed char>();
- mitk::PixelType SSType = mitk::MakeScalarPixelType<signed short>();
-
- if( signedCharType )
- output->Initialize(SCType, dimension, dimensions);
- else
- output->Initialize(SSType, dimension, dimensions);
-
- output->GetSlicedGeometry()->SetSpacing(spacing);
-
- //output->GetSlicedGeometry()->SetPlaneGeometry(mitk::Image::BuildStandardPlanePlaneGeometry(output->GetSlicedGeometry(), dimensions).GetPointer(), 0);
- output->GetSlicedGeometry()->SetEvenlySpaced();
- }
-
- m_ReadHeaderTime.Modified();
-}
-
-void mitk::ParRecFileReader::GenerateData()
-{
- mitk::Image::Pointer output = this->GetOutput();
-
- // Check to see if we can read the file given the name or prefix
- //
- if ( m_RecFileName == "" )
- {
- throw itk::ImageFileReaderException(__FILE__, __LINE__, "FileName for rec-file empty");
- }
-
- if( m_RecFileName != "")
- {
- FILE *f = fopen(m_RecFileName.c_str(), "r");
- if(f==NULL)
- {
- throw itk::ImageFileReaderException(__FILE__, __LINE__, "Could not open rec-file.");
- }
-
- int zstart, zmax;
- int tstart, tmax;
-
- zstart=output->GetRequestedRegion().GetIndex(2);
- tstart=output->GetRequestedRegion().GetIndex(3);
-
- zmax=zstart+output->GetRequestedRegion().GetSize(2);
- tmax=tstart+output->GetRequestedRegion().GetSize(3);
-
- int sliceSize=output->GetDimension(0)*output->GetDimension(1)*output->GetPixelType().GetBpe()/8;
- void *data = malloc(sliceSize);
-
- bool ignore4Dtopogram=false;
- {
- int slicePlusTimeSize=output->GetDimension(0)*output->GetDimension(1)*output->GetDimension(3)*output->GetPixelType().GetBpe()/8;
- if(output->GetDimension(3)>1)
- ignore4Dtopogram=true;
-
- int z,t;
- for(t=tstart;t<tmax;++t)
- for(z=zstart;z<zmax;++z)
- {
- if(ignore4Dtopogram)
- fseek(f,slicePlusTimeSize*z+(sliceSize+1)*t,SEEK_SET);
- else
- fseek(f,slicePlusTimeSize*z+sliceSize*t,SEEK_SET);
- size_t ignored = fread(data, sliceSize, 1, f);
- ++ignored;
- output->SetSlice(data,z,t,0);
- }
- }
- //else
- //{
- // for(;z<zmax;++z)
- // {
- // fseek(f,sliceSize*z,SEEK_SET);
- // fread(data, sliceSize, 1, f);
- // output->SetSlice(data,z,0,0);
- // }
- //}
- free(data);
-
- fclose(f);
- }
-}
-
-bool mitk::ParRecFileReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
-{
- // First check the extension
- if( filename == "" )
- {
- //MITK_INFO<<"No filename specified."<<std::endl;
- return false;
- }
-
- bool extensionFound = false;
- std::string::size_type PARPos = filename.rfind(".par");
- if ((PARPos != std::string::npos)
- && (PARPos == filename.length() - 4))
- {
- extensionFound = true;
- }
-
- PARPos = filename.rfind(".PAR");
- if ((PARPos != std::string::npos)
- && (PARPos == filename.length() - 4))
- {
- extensionFound = true;
- }
-
- if( !extensionFound )
- {
- //MITK_INFO<<"The filename extension is not recognized."<<std::endl;
- return false;
- }
-
- return true;
-}
-
-mitk::ParRecFileReader::ParRecFileReader()
-: m_FileName(""), m_FilePrefix(""), m_FilePattern("")
-{
-}
-
-mitk::ParRecFileReader::~ParRecFileReader()
-{
-}
diff --git a/Modules/Ext/IO/mitkParRecFileReader.h b/Modules/Ext/IO/mitkParRecFileReader.h
deleted file mode 100644
index 1cf01e5f47..0000000000
--- a/Modules/Ext/IO/mitkParRecFileReader.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef PARRECFILEREADER_H_HEADER_INCLUDED_C1F48A22
-#define PARRECFILEREADER_H_HEADER_INCLUDED_C1F48A22
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkFileReader.h"
-#include "mitkImageSource.h"
-
-namespace mitk {
-//##Documentation
-//## @brief Reader to read files in Philips PAR/REC file format
-//## @ingroup IO
-class MitkExt_EXPORT ParRecFileReader : public ImageSource, public FileReader
-{
-public:
- mitkClassMacro(ParRecFileReader, FileReader);
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetStringMacro(FileName);
- itkGetStringMacro(FileName);
-
- itkSetStringMacro(FilePrefix);
- itkGetStringMacro(FilePrefix);
-
- itkSetStringMacro(FilePattern);
- itkGetStringMacro(FilePattern);
-
- static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
-
-protected:
- virtual void GenerateData();
-
- virtual void GenerateOutputInformation();
-
- ParRecFileReader();
-
- ~ParRecFileReader();
-
- //##Description
- //## @brief Time when Header was last read
- itk::TimeStamp m_ReadHeaderTime;
-
- int m_StartFileIndex;
-protected:
- std::string m_FileName;
- std::string m_RecFileName;
-
- std::string m_FilePrefix;
-
- std::string m_FilePattern;
-};
-
-} // namespace mitk
-
-#endif /* PARRECFILEREADER_H_HEADER_INCLUDED_C1F48A22 */
-
-
diff --git a/Modules/Ext/IO/mitkPropertyListExportToXmlFile.cpp b/Modules/Ext/IO/mitkPropertyListExportToXmlFile.cpp
deleted file mode 100644
index 0e7e807ef3..0000000000
--- a/Modules/Ext/IO/mitkPropertyListExportToXmlFile.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "mitkPropertyListExportToXmlFile.h"
-#include <itkObject.h>
-#include <tinyxml.h>
-#include "mitkProperties.h"
-#include "mitkStringProperty.h"
-#include "mitkEnumerationProperty.h"
-#include <usModuleContext.h>
-#include <usGetModuleContext.h>
-#include <usModule.h>
-#include "usServiceReference.h"
-#include <mitkLogMacros.h>
-#include <string>
-
-namespace mitk
-{
- struct PropertyListExportToXmlFileData
- {
- const std::string* m_FileName;
- const PropertyList* m_PropertyList;
- };
-
- PropertyListExportToXmlFile::PropertyListExportToXmlFile(const std::string* _FileName,
- const PropertyList* _PropertyList)
- : d( new PropertyListExportToXmlFileData )
- {
- d->m_FileName = _FileName;
- d->m_PropertyList = _PropertyList;
- }
-
- PropertyListExportToXmlFile::~PropertyListExportToXmlFile()
- {
- delete d;
- }
-
- void PropertyListExportToXmlFile::Update()
- {
- std::string _FileName = *d->m_FileName;
- PropertyList::Pointer propList = PropertyList::New();
-
- TiXmlDocument doc( _FileName.c_str() );
- TiXmlElement* root = 0;
- TiXmlElement* elem = 0;
-
- std::string className;
- d->m_PropertyList->GetStringProperty("ClassName", className);
- // check if element is already available
- if(doc.LoadFile())
- {
- root = doc.FirstChildElement();
- if(!root)
- {
- MITK_WARN("PropertyListExportToXml") << "No root element found";
- return;
- }
- elem = root->FirstChildElement( className );
- std::string id;
- d->m_PropertyList->GetStringProperty("Id", id);
- if( !id.empty() )
- {
- std::string foundId;
- while(elem)
- {
- elem->QueryStringAttribute("Id", &foundId);
- if( foundId == id )
- break;
- elem = elem->NextSiblingElement( className );
- }
- }
- }
- else
- {
- // document did not exist, create new one with declration
- TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
- doc.LinkEndChild( decl );
- // create root
- root = new TiXmlElement( "data" );
- doc.LinkEndChild( root );
- }
-
- // create elem if not existent
- TiXmlElement* newElem = 0;
- if(!elem)
- {
- elem = new TiXmlElement( className );
- newElem = elem;
- }
-
- const std::map< std::string, BaseProperty::Pointer>* propMap = d->m_PropertyList->GetMap();
- std::map< std::string, BaseProperty::Pointer>::const_iterator propMapIt = propMap->begin();
- while( propMapIt != propMap->end() )
- {
- if( propMapIt->first.find_first_of(".") != std::string::npos )
- {
- MITK_DEBUG << "meta property found. will not write.";
- ++propMapIt;
- continue;
- }
- mitk::IntProperty* intProp = 0;
- mitk::FloatProperty* floatProp = 0;
- mitk::DoubleProperty* doubleProp = 0;
- mitk::BoolProperty* boolProp = 0;
- mitk::StringProperty* stringProp = 0;
- mitk::EnumerationProperty* enumProp = 0;
-
- if( (boolProp = dynamic_cast<BoolProperty*>( propMapIt->second.GetPointer() ) ) )
- {
- elem->SetAttribute( propMapIt->first, boolProp->GetValue() ? 1 : 0 );
- }
- else if( (stringProp = dynamic_cast<StringProperty*>( propMapIt->second.GetPointer() ) ) )
- {
- elem->SetAttribute( propMapIt->first, stringProp->GetValue() );
- }
- else if( (intProp = dynamic_cast<IntProperty*>( propMapIt->second.GetPointer() ) ) )
- {
- elem->SetAttribute( propMapIt->first, intProp->GetValue() );
- }
- else if( (enumProp = dynamic_cast<EnumerationProperty*>( propMapIt->second.GetPointer() ) ) )
- {
- elem->SetAttribute( propMapIt->first, enumProp->GetValueAsId() );
- }
- else if( (doubleProp = dynamic_cast<DoubleProperty*>( propMapIt->second.GetPointer() ) ) )
- {
- elem->SetDoubleAttribute( propMapIt->first, doubleProp->GetValue() );
- }
- else if( (floatProp = dynamic_cast<FloatProperty*>( propMapIt->second.GetPointer() ) ) )
- {
- elem->SetDoubleAttribute( propMapIt->first, static_cast<double>( floatProp->GetValue() ) );
- }
- else
- {
- MITK_DEBUG << "trying to look up serializer for baseproperty in AlgorithmRegistry";
-
- {
- MITK_WARN("PropertyListExportToXmlFile") << "Base property " << propMapIt->first << " is unknown";
- }
- }
- ++propMapIt;
- }
-
- // add the element node as child
- if( newElem )
- root->LinkEndChild(elem);
-
- if( !doc.SaveFile( _FileName ) )
- {
- MITK_DEBUG << "File " << _FileName << " could not be written. Please check permissions.";
- MITK_WARN("PropertyListExportToXmlFile") << "Cannot write file";
- }
- }
-
- void PropertyListExportToXmlFile::SetFileName(const std::string* _FileName)
- {
- d->m_FileName = _FileName;
- }
-
- void PropertyListExportToXmlFile::SetPropertyList(const PropertyList* _PropertyList)
- {
- d->m_PropertyList = _PropertyList;
- }
-} // namespace mitk
diff --git a/Modules/Ext/IO/mitkPropertyListExportToXmlFile.h b/Modules/Ext/IO/mitkPropertyListExportToXmlFile.h
deleted file mode 100644
index 6bc4ef6d87..0000000000
--- a/Modules/Ext/IO/mitkPropertyListExportToXmlFile.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef mitkPropertyListExportToXmlFile_h
-#define mitkPropertyListExportToXmlFile_h
-
-#include "MitkExtExports.h"
-#include <mitkPropertyList.h>
-
-namespace mitk
-{
- ///
- /// d pointer forward declaration
- ///
- struct PropertyListExportToXmlFileData;
- ///
- /// writes a 2d cv point to an xml file
- ///
- class MitkExt_EXPORT PropertyListExportToXmlFile
- {
- public:
- ///
- /// init default values and save references
- ///
- PropertyListExportToXmlFile( const std::string* _FileName = 0,
- const PropertyList* _PropertyList = 0);
- ///
- /// executes the algorithm if inputs changed
- ///
- void Update();
- ///
- /// delete d pointer
- ///
- virtual ~PropertyListExportToXmlFile();
- ///
- /// setter for field FileName
- ///
- void SetFileName(const std::string* _FileName);
- ///
- /// setter for field PropertyList
- ///
- void SetPropertyList(const PropertyList* _PropertyList);
- private:
- ///
- /// d pointer
- ///
- PropertyListExportToXmlFileData* d;
- };
-} // namespace mitk
-
-#endif // mitkPropertyListExportToXmlFile_h
diff --git a/Modules/Ext/IO/mitkPropertyListImportFromXmlFile.cpp b/Modules/Ext/IO/mitkPropertyListImportFromXmlFile.cpp
deleted file mode 100644
index aa70e625e1..0000000000
--- a/Modules/Ext/IO/mitkPropertyListImportFromXmlFile.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "mitkPropertyListImportFromXmlFile.h"
-#include <itkObject.h>
-#include <itksys/SystemTools.hxx>
-#include <tinyxml.h>
-#include "mitkProperties.h"
-#include "mitkStringProperty.h"
-#include "mitkEnumerationProperty.h"
-#include "mitkGenericProperty.h"
-//#include "mitkBasePropertyFromString.h"
-#include <usModuleContext.h>
-#include <usGetModuleContext.h>
-#include <usModule.h>
-#include "usServiceReference.h"
-
-namespace mitk
-{
- struct PropertyListImportFromXmlFileData
- {
- const std::string* m_FileName;
- PropertyList* m_PropertyList;
-
- //private
- long int m_FileModifiedTime;
- };
-
- PropertyListImportFromXmlFile::PropertyListImportFromXmlFile(
- const std::string* _FileName,
- PropertyList* _PropertyList)
- : d( new PropertyListImportFromXmlFileData )
- {
- d->m_FileName = _FileName;
- d->m_PropertyList = _PropertyList;
- d->m_FileModifiedTime = 0;
- }
-
- PropertyListImportFromXmlFile::~PropertyListImportFromXmlFile()
- {
- delete d;
- }
-
- void GetPropertyListFromXMLFile ( const TiXmlElement* elem, const std::string* _FileName, PropertyList* _PropertyList )
- {
- const std::map< std::string, BaseProperty::Pointer>* propMap = _PropertyList->GetMap();
- std::map< std::string, BaseProperty::Pointer>::const_iterator propMapIt = propMap->begin();
- while( propMapIt != propMap->end() )
- {
- std::string key = propMapIt->first;
- mitk::BaseProperty* prop = propMapIt->second.GetPointer();
- mitk::IntProperty* intProp = 0;
- mitk::FloatProperty* floatProp = 0;
- mitk::DoubleProperty* doubleProp = 0;
- mitk::BoolProperty* boolProp = 0;
- mitk::StringProperty* stringProp = 0;
- mitk::EnumerationProperty* enumProp = 0;
- bool found = false;
-
- if( (boolProp = dynamic_cast<BoolProperty*>( prop ) ) )
- {
- int val = false;
- found = elem->QueryIntAttribute(key, &val) == TIXML_SUCCESS;
- if( found )
- boolProp->SetValue( val==0 ? false : true );
- }
- else if( (stringProp = dynamic_cast<StringProperty*>( prop ) ) )
- {
- std::string val = "";
- found = elem->QueryStringAttribute(key.c_str(), &val) == TIXML_SUCCESS;
- if( found )
- stringProp->SetValue( val );
- }
- else if( (intProp = dynamic_cast<IntProperty*>( prop ) ) )
- {
- int val = 0;
- found = elem->QueryIntAttribute(key, &val) == TIXML_SUCCESS;
- if( found )
- intProp->SetValue( val );
- }
- else if( (enumProp = dynamic_cast<EnumerationProperty*>( prop ) ) )
- {
- int val = 0;
- found = elem->QueryIntAttribute(key, &val) == TIXML_SUCCESS;
- if( found && enumProp->IsValidEnumerationValue( val ) )
- enumProp->SetValue( static_cast<unsigned int> ( val ) );
- else
- {
- std::string strval = "";
- found = elem->QueryStringAttribute(key.c_str(), &strval);
- if( found && enumProp->IsValidEnumerationValue( strval ) )
- enumProp->SetValue( strval );
- }
- }
- else if( (doubleProp = dynamic_cast<DoubleProperty*>( prop ) ) )
- {
- double val = 0;
- found = elem->QueryDoubleAttribute(key, &val) == TIXML_SUCCESS;
- doubleProp->SetValue( val );
- }
- else if( (floatProp = dynamic_cast<FloatProperty*>( prop ) ) )
- {
- double val = 0;
- found = elem->QueryDoubleAttribute(key, &val) == TIXML_SUCCESS;
- floatProp->SetValue( static_cast<float>( val ) );
- }
- else
- {
- MITK_WARN("PropertyListImportFromXmlFile") << "Base property " << key << " is unknown";
- }
-
- if(!found)
- {
- MITK_DEBUG << "Attribute " << key << " not found";
- }
-
- ++propMapIt;
- }
- }
-
- void PropertyListImportFromXmlFile::Update()
- {
-
- std::string _FileName = *d->m_FileName;
-
- MITK_DEBUG << "extracting real path (complete path)";
- _FileName = itksys::SystemTools::GetRealPath( _FileName.c_str() );
-
- if( !itksys::SystemTools::FileExists(_FileName.c_str()) )
- {
- MITK_WARN("PropertyListFromXml") << " Cannot open file";
- }
-
- long int _FileModifiedTime = itksys::SystemTools::ModifiedTime( _FileName.c_str() );
- // file has not changed: we know that version... -> do nothing
- if( d->m_FileModifiedTime >= _FileModifiedTime )
- return;
-
- // reread
- TiXmlDocument doc( _FileName );
- doc.LoadFile();
-
- MITK_DEBUG << "searching for element with classname";
- std::string className;
- d->m_PropertyList->GetStringProperty("ClassName", className);
-
- TiXmlHandle docHandle( &doc );
- TiXmlElement* elem = docHandle.FirstChildElement().FirstChildElement( className ).ToElement();
-
- if(!elem)
- {
- MITK_WARN("PropertyListFromXml") << "Cannot find element";
- return;
- }
-
- std::string id;
- d->m_PropertyList->GetStringProperty("Id", id);
- if( !id.empty() )
- {
- std::string foundId;
- while(elem)
- {
- elem->QueryStringAttribute("Id", &foundId);
- if( foundId == id )
- break;
- elem = elem->NextSiblingElement( className );
- }
- if(!elem)
- {
- MITK_WARN("PropertyListFromXml") << "Cannot find element by id";
- return;
- }
- }
-
- MITK_DEBUG << "element found. now reading attributes into propertylist";
- GetPropertyListFromXMLFile( elem, &_FileName, d->m_PropertyList );
-
- MITK_DEBUG << "save that modified time";
- d->m_FileModifiedTime = _FileModifiedTime;
- }
-
- void PropertyListImportFromXmlFile::SetFileName(const std::string* _FileName)
- {
- d->m_FileName = _FileName;
- }
-
- void PropertyListImportFromXmlFile::SetPropertyList(PropertyList* _PropertyList)
- {
- d->m_PropertyList = _PropertyList;
- }
-} // namespace mitk
diff --git a/Modules/Ext/IO/mitkPropertyListImportFromXmlFile.h b/Modules/Ext/IO/mitkPropertyListImportFromXmlFile.h
deleted file mode 100644
index e4e983876e..0000000000
--- a/Modules/Ext/IO/mitkPropertyListImportFromXmlFile.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef mitkPropertyListImportFromXmlFile_h
-#define mitkPropertyListImportFromXmlFile_h
-
-#include <mitkPropertyList.h>
-#include "MitkExtExports.h"
-
-namespace mitk
-{
- ///
- /// d pointer forward declaration
- ///
- struct PropertyListImportFromXmlFileData;
- ///
- /// DOCUMENTATION
- ///
- class MitkExt_EXPORT PropertyListImportFromXmlFile
- {
- public:
- ///
- /// init default values and save references
- ///
- PropertyListImportFromXmlFile( const std::string* _FileName = 0,
- PropertyList* _PropertyList = 0 );
-
- ///
- /// executes the algorithm if inputs changed
- ///
- void Update();
- ///
- /// delete d pointer
- ///
- virtual ~PropertyListImportFromXmlFile();
- ///
- /// setter for field FileName
- ///
- void SetFileName(const std::string* _FileName);
- ///
- /// setter for field PropertyList
- ///
- void SetPropertyList(PropertyList* _PropertyList);
- private:
- ///
- /// d pointer
- ///
- PropertyListImportFromXmlFileData* d;
- };
-} // namespace mitk
-
-#endif // mitkPropertyListImportFromXmlFile_h
diff --git a/Modules/Ext/IO/mitkStlVolumeTimeSeriesIOFactory.cpp b/Modules/Ext/IO/mitkStlVolumeTimeSeriesIOFactory.cpp
deleted file mode 100644
index 12e1582135..0000000000
--- a/Modules/Ext/IO/mitkStlVolumeTimeSeriesIOFactory.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkStlVolumeTimeSeriesIOFactory.h"
-#include "mitkIOAdapter.h"
-#include "mitkStlVolumeTimeSeriesReader.h"
-
-#include "itkVersion.h"
-
-
-namespace mitk
-{
-StlVolumeTimeSeriesIOFactory::StlVolumeTimeSeriesIOFactory()
-{
- this->RegisterOverride("mitkIOAdapter",
- "mitkStlVolumeTimeSeriesReader",
- "mitk Stl Surface IO",
- 1,
- itk::CreateObjectFunction<IOAdapter<StlVolumeTimeSeriesReader> >::New());
-}
-
-StlVolumeTimeSeriesIOFactory::~StlVolumeTimeSeriesIOFactory()
-{
-}
-
-const char* StlVolumeTimeSeriesIOFactory::GetITKSourceVersion() const
-{
- return ITK_SOURCE_VERSION;
-}
-
-const char* StlVolumeTimeSeriesIOFactory::GetDescription() const
-{
- return "StlVolumeTimeSeries IO Factory, allows the loading of Stl surfaces";
-}
-
-} // end namespace mitk
diff --git a/Modules/Ext/IO/mitkStlVolumeTimeSeriesIOFactory.h b/Modules/Ext/IO/mitkStlVolumeTimeSeriesIOFactory.h
deleted file mode 100644
index fce9500ff4..0000000000
--- a/Modules/Ext/IO/mitkStlVolumeTimeSeriesIOFactory.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef __mitkStlVolumeTimeSeriesIOFactory_h
-#define __mitkStlVolumeTimeSeriesIOFactory_h
-
-#ifdef _MSC_VER
-#pragma warning ( disable : 4786 )
-#endif
-
-#include "itkObjectFactoryBase.h"
-#include "MitkExtExports.h"
-#include "mitkBaseData.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Create instances of StlVolumeTimeSeriesReader objects using an object factory.
-//##
-//## @ingroup IO
-class MitkExt_EXPORT StlVolumeTimeSeriesIOFactory : public itk::ObjectFactoryBase
-{
-public:
- /** Standard class typedefs. */
- typedef StlVolumeTimeSeriesIOFactory Self;
- typedef itk::ObjectFactoryBase Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Class methods used to interface with the registered factories. */
- virtual const char* GetITKSourceVersion(void) const;
- virtual const char* GetDescription(void) const;
-
- /** Method for class instantiation. */
- itkFactorylessNewMacro(Self);
- static StlVolumeTimeSeriesIOFactory* FactoryNew() { return new StlVolumeTimeSeriesIOFactory;}
- /** Run-time type information (and related methods). */
- itkTypeMacro(StlVolumeTimeSeriesIOFactory, ObjectFactoryBase);
-
- /**
- * Register one factory of this type
- * \deprecatedSince{2013_09}
- */
- DEPRECATED(static void RegisterOneFactory(void))
- {
- StlVolumeTimeSeriesIOFactory::Pointer StlVolumeTimeSeriesIOFactory = StlVolumeTimeSeriesIOFactory::New();
- ObjectFactoryBase::RegisterFactory(StlVolumeTimeSeriesIOFactory);
- }
-
-protected:
- StlVolumeTimeSeriesIOFactory();
- ~StlVolumeTimeSeriesIOFactory();
-
-private:
- StlVolumeTimeSeriesIOFactory(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace mitk
-
-#endif
diff --git a/Modules/Ext/IO/mitkStlVolumeTimeSeriesReader.cpp b/Modules/Ext/IO/mitkStlVolumeTimeSeriesReader.cpp
deleted file mode 100644
index 0188706f5e..0000000000
--- a/Modules/Ext/IO/mitkStlVolumeTimeSeriesReader.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkStlVolumeTimeSeriesReader.h"
-#include "mitkSTLFileReader.h"
-#include "mitkSurface.h"
-#include "vtkPolyData.h"
-
-void mitk::StlVolumeTimeSeriesReader::GenerateData()
-{
- if ( !this->GenerateFileList() )
- {
- itkWarningMacro( << "Sorry, file list could not be determined..." );
- return ;
- }
-
- mitk::Surface::Pointer surface = this->GetOutput();
- MITK_INFO << "prefix: "<< m_FilePrefix << ", pattern: " <<m_FilePattern << std::endl;
- surface->Expand(m_MatchedFileNames.size());
- for ( unsigned int i = 0 ; i < m_MatchedFileNames.size(); ++i )
- {
- std::string fileName = m_MatchedFileNames[i];
- MITK_INFO << "Loading " << fileName << " as stl..." << std::endl;
-
- STLFileReader::Pointer stlReader = STLFileReader::New();
- stlReader->SetFileName( fileName.c_str() );
- stlReader->Update();
-
- if ( stlReader->GetOutput() != NULL )
- {
- surface->SetVtkPolyData( stlReader->GetOutput()->GetVtkPolyData(), i );
- }
- else
- {
- itkWarningMacro(<< "stlReader returned NULL while reading " << fileName << ". Trying to continue with empty vtkPolyData...");
- surface->SetVtkPolyData( vtkPolyData::New(), i );
- }
- }
-}
-
-bool mitk::StlVolumeTimeSeriesReader::CanReadFile(const std::string /*filename*/, const std::string filePrefix, const std::string filePattern)
-{
- if( filePattern != "" && filePrefix != "" )
- return false;
-
- bool extensionFound = false;
- std::string::size_type STLPos = filePattern.rfind(".stl");
- if ((STLPos != std::string::npos) && (STLPos == filePattern.length() - 4))
- extensionFound = true;
-
- STLPos = filePattern.rfind(".STL");
- if ((STLPos != std::string::npos) && (STLPos == filePattern.length() - 4))
- extensionFound = true;
-
- if( !extensionFound )
- return false;
-
- return true;
-}
-
-mitk::StlVolumeTimeSeriesReader::StlVolumeTimeSeriesReader()
-{}
-
-mitk::StlVolumeTimeSeriesReader::~StlVolumeTimeSeriesReader()
-{}
diff --git a/Modules/Ext/IO/mitkStlVolumeTimeSeriesReader.h b/Modules/Ext/IO/mitkStlVolumeTimeSeriesReader.h
deleted file mode 100644
index 6ea287fe18..0000000000
--- a/Modules/Ext/IO/mitkStlVolumeTimeSeriesReader.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef _Stl_VOLUME_TIME_SERIES_READER__H_
-#define _Stl_VOLUME_TIME_SERIES_READER__H_
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkFileSeriesReader.h"
-#include "mitkSurfaceSource.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Reader to read a series of volume files in stl-format
-//## @ingroup IO
-class MitkExt_EXPORT StlVolumeTimeSeriesReader : public SurfaceSource, public FileSeriesReader
-{
-public:
- mitkClassMacro( StlVolumeTimeSeriesReader, FileReader );
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetStringMacro(FileName);
- itkGetStringMacro(FileName);
-
- itkSetStringMacro(FilePrefix);
- itkGetStringMacro(FilePrefix);
-
- itkSetStringMacro(FilePattern);
- itkGetStringMacro(FilePattern);
-
- static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
-
-protected:
- virtual void GenerateData();
-
- StlVolumeTimeSeriesReader();
-
- ~StlVolumeTimeSeriesReader();
-
- //##Description
- //## @brief Time when Header was last read
- itk::TimeStamp m_ReadHeaderTime;
-
-};
-
-} // namespace mitk
-
-#endif
-
-
diff --git a/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.cpp b/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.cpp
deleted file mode 100644
index c5c68ecccf..0000000000
--- a/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkUnstructuredGridVtkWriter.h"
-#include "mitkUnstructuredGridVtkWriter.txx"
-
-namespace mitk {
-
-template<>
-std::vector<std::string> UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>::GetPossibleFileExtensions()
-{
- std::vector<std::string> possibleFileExtensions;
- possibleFileExtensions.push_back(".vtk");
- return possibleFileExtensions;
-}
-
-template<>
-std::vector<std::string> UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>::GetPossibleFileExtensions()
-{
- std::vector<std::string> possibleFileExtensions;
- possibleFileExtensions.push_back(".vtu");
- return possibleFileExtensions;
-}
-
-template<>
-std::vector<std::string> UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>::GetPossibleFileExtensions()
-{
- std::vector<std::string> possibleFileExtensions;
- possibleFileExtensions.push_back(".pvtu");
- return possibleFileExtensions;
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>::GetDefaultFilename()
-{
- return "vtkUnstructuredGrid.vtk";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>::GetDefaultFilename()
-{
- return "vtkUnstructuredGrid.vtu";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>::GetDefaultFilename()
-{
- return "vtkUnstructuredGrid.pvtu";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>::GetFileDialogPattern()
-{
- return "VTK Legacy Unstructured Grid (*.vtk)";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>::GetFileDialogPattern()
-{
- return "VTK XML Unstructured Grid (*.vtu)";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>::GetFileDialogPattern()
-{
- return "VTK Parallel XML Unstructured Grid (*.pvtu)";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>::GetDefaultExtension()
-{
- return ".vtk";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>::GetDefaultExtension()
-{
- return ".vtu";
-}
-
-template<>
-const char * UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>::GetDefaultExtension()
-{
- return ".pvtu";
-}
-
-
-template class UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>;
-template class UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>;
-template class UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>;
-
-
-}
-
diff --git a/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.h b/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.h
deleted file mode 100644
index ddfc1710a1..0000000000
--- a/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef _MITK_UNSTRUCTURED_GRID_VTK_WRITER__H_
-#define _MITK_UNSTRUCTURED_GRID_VTK_WRITER__H_
-
-
-#include <itkProcessObject.h>
-#include <mitkFileWriterWithInformation.h>
-
-#include <vtkUnstructuredGridWriter.h>
-#include <vtkXMLUnstructuredGridWriter.h>
-#include <vtkXMLPUnstructuredGridWriter.h>
-
-#include "mitkUnstructuredGrid.h"
-
-#include <MitkExtExports.h>
-
-namespace mitk
-{
-
-/**
- * @brief VTK-based writer for mitk::UnstructuredGrid
- *
- * The mitk::UnstructuredGrid is written using the VTK-writer-type provided as the
- * template argument. If the mitk::UnstructuredGrid contains multiple points of
- * time, multiple files are written. The life-span (time-bounds) of each
- * each point of time is included in the filename according to the
- * following scheme:
- * &lt;filename&gt;_S&lt;timebounds[0]&gt;E&lt;timebounds[1]&gt;_T&lt;framenumber&gt;
- * (S=start, E=end, T=time).
- * Writing of multiple files according to a given filename pattern is not
- * yet supported.
- * @ingroup Process
-*/
-template<class VTKWRITER>
-class MitkExt_EXPORT UnstructuredGridVtkWriter : public mitk::FileWriterWithInformation
-{
-public:
-
- mitkClassMacro( UnstructuredGridVtkWriter, mitk::FileWriterWithInformation );
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- mitkWriterMacro;
-
- /**
- * Sets the filename of the file to write.
- * @param _arg the name of the file to write.
- */
- itkSetStringMacro( FileName );
-
- /**
- * @returns the name of the file to be written to disk.
- */
- itkGetStringMacro( FileName );
-
- /**
- * @warning multiple write not (yet) supported
- */
- itkSetStringMacro( FilePrefix );
-
- /**
- * @warning multiple write not (yet) supported
- */
- itkGetStringMacro( FilePrefix );
-
- /**
- * @warning multiple write not (yet) supported
- */
- itkSetStringMacro( FilePattern );
-
- /**
- * @warning multiple write not (yet) supported
- */
- itkGetStringMacro( FilePattern );
-
- using FileWriter::SetInput;
-
- /**
- * Sets the 0'th input object for the filter.
- * @param input the first input for the filter.
- */
- void SetInput( BaseData* input );
-
- /**
- * @returns the 0'th input object of the filter.
- */
- const UnstructuredGrid* GetInput();
-
- /**
- * Returns false if an error happened during writing
- */
- itkGetMacro( Success, bool );
-
- /**
- * @brief Return the possible file extensions for the data type associated with the writer
- */
- virtual std::vector<std::string> GetPossibleFileExtensions();
-
- // FileWriterWithInformation methods
- virtual const char * GetDefaultFilename();
- virtual const char * GetFileDialogPattern();
- virtual const char * GetDefaultExtension();
- virtual bool CanWriteBaseDataType(BaseData::Pointer data);
- virtual void DoWrite(BaseData::Pointer data);
-
-protected:
-
- /**
- * Constructor.
- */
- UnstructuredGridVtkWriter();
-
- /**
- * Virtual destructor.
- */
- virtual ~UnstructuredGridVtkWriter();
-
- void ExecuteWrite(VTKWRITER* vtkWriter);
-
- virtual void GenerateData();
-
- std::string m_FileName;
-
- std::string m_FilePrefix;
-
- std::string m_FilePattern;
-
- bool m_Success;
-};
-
-#ifndef MitkExt_EXPORTS
-extern template class UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>;
-extern template class UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>;
-extern template class UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>;
-#endif
-
-}
-
-
-#endif // _MITK_UNSTRUCTURED_GRID_VTK_WRITER__H_
diff --git a/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.txx b/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.txx
deleted file mode 100644
index 46eb319ee5..0000000000
--- a/Modules/Ext/IO/mitkUnstructuredGridVtkWriter.txx
+++ /dev/null
@@ -1,203 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _MITK_UNSTRUCTURED_GRID_VTKWRITER_TXX_
-#define _MITK_UNSTRUCTURED_GRID_VTKWRITER_TXX_
-
-#include <itkLightObject.h>
-#include <vtkUnstructuredGrid.h>
-#include <vtkLinearTransform.h>
-#include <vtkTransformFilter.h>
-#include <vtkUnstructuredGridWriter.h>
-#include <vtkXMLUnstructuredGridWriter.h>
-#include <vtkXMLPUnstructuredGridWriter.h>
-
-#include <sstream>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <stdio.h>
-
-namespace mitk {
-
-template<class VTKWRITER>
-UnstructuredGridVtkWriter<VTKWRITER>::UnstructuredGridVtkWriter()
- : m_Success(false)
-{
- this->SetNumberOfRequiredInputs(1);
-}
-
-template<class VTKWRITER>
-UnstructuredGridVtkWriter<VTKWRITER>::~UnstructuredGridVtkWriter()
-{
-
-}
-
-template<class VTKWRITER>
-void UnstructuredGridVtkWriter<VTKWRITER>::GenerateData()
-{
- m_Success = false;
- if ( m_FileName == "" )
- {
- itkWarningMacro( << "Sorry, filename has not been set!" );
- return ;
- }
-
- mitk::UnstructuredGrid::Pointer input = const_cast<mitk::UnstructuredGrid*>(this->GetInput());
-
- if (input.IsNull())
- {
- itkWarningMacro( << "Sorry, input to mitk::UnstructuredGridVtkWriter is NULL");
- return;
- }
-
- VTKWRITER* unstructuredGridWriter = VTKWRITER::New();
- vtkTransformFilter* transformPointSet = vtkTransformFilter::New();
- vtkUnstructuredGrid * unstructuredGrid;
- BaseGeometry* geometry;
-
- if(input->GetTimeGeometry()->CountTimeSteps()>1)
- {
-
- int t, timesteps;
-
- timesteps = input->GetTimeGeometry()->CountTimeSteps();
- for(t = 0; t < timesteps; ++t)
- {
- std::ostringstream filename;
- geometry = input->GetGeometry(t);
- if(input->GetTimeGeometry()->IsValidTimeStep(t))
- {
- const mitk::TimeBounds& timebounds = input->GetTimeGeometry()->GetTimeBounds(t);
- filename << m_FileName.c_str() << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << GetDefaultExtension();
- }
- else
- {
- itkWarningMacro(<<"Error on write: TimeGeometry invalid of unstructured grid " << filename.str() << ".");
- filename << m_FileName.c_str() << "_T" << t << GetDefaultExtension();
- }
- transformPointSet->SetInputData(input->GetVtkUnstructuredGrid(t));
- transformPointSet->SetTransform(geometry->GetVtkTransform());
- transformPointSet->UpdateWholeExtent();
- unstructuredGrid = static_cast<vtkUnstructuredGrid*>(transformPointSet->GetOutput());
-
- unstructuredGridWriter->SetFileName(filename.str().c_str());
- unstructuredGridWriter->SetInputData(unstructuredGrid);
-
- ExecuteWrite( unstructuredGridWriter );
- }
- }
- else
- {
- geometry = input->GetGeometry();
- transformPointSet->SetInputData(input->GetVtkUnstructuredGrid());
- transformPointSet->SetTransform(geometry->GetVtkTransform());
- transformPointSet->UpdateWholeExtent();
- unstructuredGrid = static_cast<vtkUnstructuredGrid*>(transformPointSet->GetOutput());
-
- unstructuredGridWriter->SetFileName(m_FileName.c_str());
- unstructuredGridWriter->SetInputData(unstructuredGrid);
-
- ExecuteWrite( unstructuredGridWriter );
- }
- transformPointSet->Delete();
- unstructuredGridWriter->Delete();
-
- m_Success = true;
-}
-
-template<class VTKWRITER>
-void UnstructuredGridVtkWriter<VTKWRITER>::ExecuteWrite( VTKWRITER* vtkWriter )
-{
- struct stat fileStatus;
- time_t timeBefore=0;
- if (!stat(vtkWriter->GetFileName(), &fileStatus))
- {
- timeBefore = fileStatus.st_mtime;
- }
- if (!vtkWriter->Write())
- {
- itkExceptionMacro( << "Error during unstructured grid writing.");
- }
-
- // check if file can be written because vtkWriter doesn't check that
- if (stat(vtkWriter->GetFileName(), &fileStatus) || (timeBefore == fileStatus.st_mtime))
- {
- itkExceptionMacro(<<"Error during unstructured grid writing: file could not be written");
- }
-}
-
-template<class VTKWRITER>
-void UnstructuredGridVtkWriter<VTKWRITER>::SetInput(BaseData *input)
-{
- this->ProcessObject::SetNthInput(0, input);
-}
-
-template<class VTKWRITER>
-const UnstructuredGrid* UnstructuredGridVtkWriter<VTKWRITER>::GetInput()
-{
- if (this->GetNumberOfInputs() < 1)
- {
- return 0;
- }
- else
- {
- return dynamic_cast<UnstructuredGrid*>(this->ProcessObject::GetInput(0));
- }
-}
-
-template<class VTKWRITER>
-bool UnstructuredGridVtkWriter<VTKWRITER>::CanWriteBaseDataType(BaseData::Pointer data)
-{
- return (dynamic_cast<mitk::UnstructuredGrid*>(data.GetPointer()) != 0);
-}
-
-template<class VTKWRITER>
-void UnstructuredGridVtkWriter<VTKWRITER>::DoWrite(BaseData::Pointer data)
-{
- if (CanWriteBaseDataType(data))
- {
- this->SetInput(dynamic_cast<mitk::UnstructuredGrid*>(data.GetPointer()));
- this->Update();
- }
-}
-
-template<class VTKWRITER>
-std::vector<std::string> UnstructuredGridVtkWriter<VTKWRITER>::GetPossibleFileExtensions()
-{
- throw std::exception(); // no specialization available!
-}
-
-template<class VTKWRITER>
-const char* UnstructuredGridVtkWriter<VTKWRITER>::GetDefaultFilename()
-{
- throw std::exception(); // no specialization available!
-}
-
-template<class VTKWRITER>
-const char* UnstructuredGridVtkWriter<VTKWRITER>::GetFileDialogPattern()
-{
- throw std::exception(); // no specialization available!
-}
-
-template<class VTKWRITER>
-const char* UnstructuredGridVtkWriter<VTKWRITER>::GetDefaultExtension()
-{
- throw std::exception(); // no specialization available!
-}
-
-}
-
-#endif
diff --git a/Modules/Ext/IO/mitkUnstructuredGridVtkWriterFactory.cpp b/Modules/Ext/IO/mitkUnstructuredGridVtkWriterFactory.cpp
deleted file mode 100644
index 2f24d71402..0000000000
--- a/Modules/Ext/IO/mitkUnstructuredGridVtkWriterFactory.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkUnstructuredGridVtkWriterFactory.h"
-
-#include "itkCreateObjectFunction.h"
-#include "itkVersion.h"
-
-#include <mitkUnstructuredGridVtkWriter.h>
-
-#include <vtkUnstructuredGridWriter.h>
-#include <vtkXMLUnstructuredGridWriter.h>
-#include <vtkXMLPUnstructuredGridWriter.h>
-
-namespace mitk
-{
-
-template <class T>
-class CreateUnstructuredGridWriter : public itk::CreateObjectFunctionBase
-{
-public:
-
- /** Standard class typedefs. */
- typedef CreateUnstructuredGridWriter Self;
- typedef itk::SmartPointer<Self> Pointer;
-
- /** Methods from itk:LightObject. */
- itkFactorylessNewMacro(Self);
- LightObject::Pointer CreateObject() { typename T::Pointer p = T::New();
- p->Register();
- return p.GetPointer();
- }
-
-protected:
- CreateUnstructuredGridWriter() {}
- ~CreateUnstructuredGridWriter() {}
-
-private:
- CreateUnstructuredGridWriter(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-};
-
-UnstructuredGridVtkWriterFactory::UnstructuredGridVtkWriterFactory()
-{
- this->RegisterOverride("IOWriter",
- "UnstructuredGridVtkWriter<vtkUnstructuredGridWriter>",
- "VTK Legacy Unstructured Grid Writer",
- 1,
- mitk::CreateUnstructuredGridWriter< mitk::UnstructuredGridVtkWriter<vtkUnstructuredGridWriter> >::New());
-
- this->RegisterOverride("IOWriter",
- "UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter>",
- "VTK XML UnstructuredGrid Writer",
- 1,
- mitk::CreateUnstructuredGridWriter< mitk::UnstructuredGridVtkWriter<vtkXMLUnstructuredGridWriter> >::New());
-
- this->RegisterOverride("IOWriter",
- "UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter>",
- "VTK Parallel XML UnstructuredGrid Writer",
- 1,
- mitk::CreateUnstructuredGridWriter< mitk::UnstructuredGridVtkWriter<vtkXMLPUnstructuredGridWriter> >::New());
-}
-
-UnstructuredGridVtkWriterFactory::~UnstructuredGridVtkWriterFactory()
-{
-}
-
-const char* UnstructuredGridVtkWriterFactory::GetITKSourceVersion() const
-{
- return ITK_SOURCE_VERSION;
-}
-
-const char* UnstructuredGridVtkWriterFactory::GetDescription() const
-{
- return "UnstructuredGridVtkWriterFactory";
-}
-
-} // end namespace mitk
diff --git a/Modules/Ext/IO/mitkUnstructuredGridVtkWriterFactory.h b/Modules/Ext/IO/mitkUnstructuredGridVtkWriterFactory.h
deleted file mode 100644
index 1319b7f9d9..0000000000
--- a/Modules/Ext/IO/mitkUnstructuredGridVtkWriterFactory.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef UNSTRUCTURED_GRID_WRITERFACTORY_H_HEADER_INCLUDED
-#define UNSTRUCTURED_GRID_WRITERFACTORY_H_HEADER_INCLUDED
-
-#include "itkObjectFactoryBase.h"
-#include "MitkExtExports.h"
-#include "mitkBaseData.h"
-
-namespace mitk
-{
-
-class MitkExt_EXPORT UnstructuredGridVtkWriterFactory : public itk::ObjectFactoryBase
-{
-public:
-
- mitkClassMacro( mitk::UnstructuredGridVtkWriterFactory, itk::ObjectFactoryBase )
-
- /** Class methods used to interface with the registered factories. */
- virtual const char* GetITKSourceVersion(void) const;
- virtual const char* GetDescription(void) const;
-
- /** Method for class instantiation. */
- itkFactorylessNewMacro(Self);
-
- /**
- * Register one factory of this type
- * \deprecatedSince{2013_09}
- */
- DEPRECATED(static void RegisterOneFactory(void))
- {
- static bool IsRegistered = false;
- if ( !IsRegistered )
- {
- UnstructuredGridVtkWriterFactory::Pointer ugVtkWriterFactory = UnstructuredGridVtkWriterFactory::New();
- ObjectFactoryBase::RegisterFactory( ugVtkWriterFactory );
- IsRegistered = true;
- }
- }
-
-protected:
- UnstructuredGridVtkWriterFactory();
- ~UnstructuredGridVtkWriterFactory();
-
-private:
- UnstructuredGridVtkWriterFactory(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-} // end namespace mitk
-
-#endif // UNSTRUCTURED_GRID_WRITERFACTORY_H_HEADER_INCLUDED
-
-
-
diff --git a/Modules/Ext/IO/mitkVtkUnstructuredGridIOFactory.cpp b/Modules/Ext/IO/mitkVtkUnstructuredGridIOFactory.cpp
deleted file mode 100644
index 89382e368e..0000000000
--- a/Modules/Ext/IO/mitkVtkUnstructuredGridIOFactory.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkVtkUnstructuredGridIOFactory.h"
-#include "mitkIOAdapter.h"
-#include "mitkVtkUnstructuredGridReader.h"
-
-#include "itkVersion.h"
-
-
-namespace mitk
-{
-VtkUnstructuredGridIOFactory::VtkUnstructuredGridIOFactory()
-{
- this->RegisterOverride("mitkIOAdapter",
- "mitkVtkUnstructuredGridReader",
- "mitk Vtk UnstructuredGrid IO",
- 1,
- itk::CreateObjectFunction<IOAdapter<VtkUnstructuredGridReader> >::New());
-}
-
-VtkUnstructuredGridIOFactory::~VtkUnstructuredGridIOFactory()
-{
-}
-
-const char* VtkUnstructuredGridIOFactory::GetITKSourceVersion() const
-{
- return ITK_SOURCE_VERSION;
-}
-
-const char* VtkUnstructuredGridIOFactory::GetDescription() const
-{
- return "VtkUnstructuredGrid IO Factory, allows the loading of Vtk files containing unstructured grid data";
-}
-
-} // end namespace mitk
diff --git a/Modules/Ext/IO/mitkVtkUnstructuredGridIOFactory.h b/Modules/Ext/IO/mitkVtkUnstructuredGridIOFactory.h
deleted file mode 100644
index 92ae0e0cbe..0000000000
--- a/Modules/Ext/IO/mitkVtkUnstructuredGridIOFactory.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef __MITK_VTK_UNSTRUCTURED_GRID_IO_FACTORY_H_HEADER__
-#define __MITK_VTK_UNSTRUCTURED_GRID_IO_FACTORY_H_HEADER__
-
-#ifdef _MSC_VER
-#pragma warning ( disable : 4786 )
-#endif
-
-#include "itkObjectFactoryBase.h"
-#include "MitkExtExports.h"
-#include "mitkBaseData.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Create instances of VtkUnstructuredGridReader objects using an object factory.
-//##
-//## @ingroup IO
-class MitkExt_EXPORT VtkUnstructuredGridIOFactory : public itk::ObjectFactoryBase
-{
-public:
- /** Standard class typedefs. */
- typedef VtkUnstructuredGridIOFactory Self;
- typedef itk::ObjectFactoryBase Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Class methods used to interface with the registered factories. */
- virtual const char* GetITKSourceVersion(void) const;
- virtual const char* GetDescription(void) const;
-
- /** Method for class instantiation. */
- itkFactorylessNewMacro(Self);
- static VtkUnstructuredGridIOFactory* FactoryNew() { return new VtkUnstructuredGridIOFactory;}
- /** Run-time type information (and related methods). */
- itkTypeMacro(VtkUnstructuredGridIOFactory, ObjectFactoryBase);
-
- /**
- * Register one factory of this type
- * \deprecatedSince{2013_09}
- */
- DEPRECATED(static void RegisterOneFactory(void))
- {
- VtkUnstructuredGridIOFactory::Pointer VtkUnstructuredGridIOFactory = VtkUnstructuredGridIOFactory::New();
- ObjectFactoryBase::RegisterFactory(VtkUnstructuredGridIOFactory);
- }
-
-protected:
- VtkUnstructuredGridIOFactory();
- ~VtkUnstructuredGridIOFactory();
-
-private:
- VtkUnstructuredGridIOFactory(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace mitk
-
-#endif // __MITK_VTK_UNSTRUCTURED_GRID_IO_FACTORY_H_HEADER__
diff --git a/Modules/Ext/IO/mitkVtkUnstructuredGridReader.cpp b/Modules/Ext/IO/mitkVtkUnstructuredGridReader.cpp
deleted file mode 100644
index ad44d57d63..0000000000
--- a/Modules/Ext/IO/mitkVtkUnstructuredGridReader.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include "mitkVtkUnstructuredGridReader.h"
-#include <mitkUnstructuredGrid.h>
-#include <vtkDataReader.h>
-#include <vtkUnstructuredGridReader.h>
-#include <vtkXMLUnstructuredGridReader.h>
-
-#include <itksys/SystemTools.hxx>
-
-
-mitk::VtkUnstructuredGridReader::VtkUnstructuredGridReader()
-: m_FileName("")
-{
-}
-
-mitk::VtkUnstructuredGridReader::~VtkUnstructuredGridReader()
-{
-}
-
-void mitk::VtkUnstructuredGridReader::GenerateData()
-{
- if( m_FileName != "")
- {
- bool success = false;
- MITK_INFO << "Loading " << m_FileName << " as vtk unstructured grid" << std::endl;
-
- std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName);
- ext = itksys::SystemTools::LowerCase(ext);
- if (ext == ".vtk")
- {
- ///We create a Generic Reader to test de .vtk/
- vtkDataReader *chooser=vtkDataReader::New();
- chooser->SetFileName(m_FileName.c_str() );
- if( chooser->IsFileUnstructuredGrid())
- {
- ///UnstructuredGrid/
- itkDebugMacro( << "UnstructuredGrid" );
- vtkUnstructuredGridReader *reader = vtkUnstructuredGridReader::New();
- reader->SetFileName( m_FileName.c_str() );
- reader->Update();
-
- if ( reader->GetOutput() != NULL )
- {
- mitk::UnstructuredGrid::Pointer output = this->GetOutput();
- output->SetVtkUnstructuredGrid( reader->GetOutput() );
- success = true;
- }
- reader->Delete();
- }
- }
- else if (ext == ".vtu")
- {
- vtkXMLUnstructuredGridReader *reader=vtkXMLUnstructuredGridReader::New();
- if( reader->CanReadFile(m_FileName.c_str()) )
- {
- ///UnstructuredGrid/
- itkDebugMacro( << "XMLUnstructuredGrid" );
- reader->SetFileName( m_FileName.c_str() );
- reader->Update();
-
- if ( reader->GetOutput() != NULL )
- {
- mitk::UnstructuredGrid::Pointer output = this->GetOutput();
- output->SetVtkUnstructuredGrid( reader->GetOutput() );
- success = true;
- }
- reader->Delete();
- }
- }
- if(!success)
- {
- itkExceptionMacro( << " ... sorry, this .vtk format is not supported yet." );
- }
- }
-}
-
-bool mitk::VtkUnstructuredGridReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
-{
- // First check the extension
- if( filename == "" )
- return false;
-
- std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename);
- ext = itksys::SystemTools::LowerCase(ext);
- if (ext == ".vtk")
- {
- vtkDataReader *chooser=vtkDataReader::New();
- chooser->SetFileName(filename.c_str() );
- if(!chooser->IsFileUnstructuredGrid())
- {
- chooser->Delete();
- return false;
- }
- }
- else if (ext == ".vtu")
- {
- vtkXMLUnstructuredGridReader *chooser=vtkXMLUnstructuredGridReader::New();
- if(!chooser->CanReadFile(filename.c_str()))
- {
- chooser->Delete();
- return false;
- }
- }
- else
- return false;
-
- return true;
-}
diff --git a/Modules/Ext/IO/mitkVtkUnstructuredGridReader.h b/Modules/Ext/IO/mitkVtkUnstructuredGridReader.h
deleted file mode 100644
index 9db5b40c5a..0000000000
--- a/Modules/Ext/IO/mitkVtkUnstructuredGridReader.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef VtkUnstructuredGridReader_H_HEADER_INCLUDED
-#define VtkUnstructuredGridReader_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkUnstructuredGridSource.h"
-
-namespace mitk {
-//##Documentation
-//## @brief Reader to read unstructured grid files in vtk-format
-//## @ingroup IO
-class MitkExt_EXPORT VtkUnstructuredGridReader : public UnstructuredGridSource
-{
-public:
- mitkClassMacro(VtkUnstructuredGridReader, UnstructuredGridSource);
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetStringMacro(FileName);
- itkGetStringMacro(FileName);
-
- itkSetStringMacro(FilePrefix);
- itkGetStringMacro(FilePrefix);
-
- itkSetStringMacro(FilePattern);
- itkGetStringMacro(FilePattern);
-
- static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
-
-protected:
- virtual void GenerateData();
-
- VtkUnstructuredGridReader();
-
- ~VtkUnstructuredGridReader();
-
- std::string m_FileName, m_FilePrefix, m_FilePattern;
-
-};
-
-} // namespace mitk
-
-#endif /* VtkUnstructuredGridReader_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesIOFactory.cpp b/Modules/Ext/IO/mitkVtkVolumeTimeSeriesIOFactory.cpp
deleted file mode 100644
index ca921fc2b9..0000000000
--- a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesIOFactory.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkVtkVolumeTimeSeriesIOFactory.h"
-#include "mitkIOAdapter.h"
-#include "mitkVtkVolumeTimeSeriesReader.h"
-
-#include "itkVersion.h"
-
-
-namespace mitk
-{
-VtkVolumeTimeSeriesIOFactory::VtkVolumeTimeSeriesIOFactory()
-{
- this->RegisterOverride("mitkIOAdapter",
- "mitkVtkVolumeTimeSeriesReader",
- "mitk Vtk Surface IO",
- 1,
- itk::CreateObjectFunction<IOAdapter<VtkVolumeTimeSeriesReader> >::New());
-}
-
-VtkVolumeTimeSeriesIOFactory::~VtkVolumeTimeSeriesIOFactory()
-{
-}
-
-const char* VtkVolumeTimeSeriesIOFactory::GetITKSourceVersion() const
-{
- return ITK_SOURCE_VERSION;
-}
-
-const char* VtkVolumeTimeSeriesIOFactory::GetDescription() const
-{
- return "VtkVolumeTimeSeries IO Factory, allows the loading of Vtk surfaces";
-}
-
-} // end namespace mitk
diff --git a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesIOFactory.h b/Modules/Ext/IO/mitkVtkVolumeTimeSeriesIOFactory.h
deleted file mode 100644
index 49c2b60412..0000000000
--- a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesIOFactory.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#ifndef __mitkVtkVolumeTimeSeriesIOFactory_h
-#define __mitkVtkVolumeTimeSeriesIOFactory_h
-
-#ifdef _MSC_VER
-#pragma warning ( disable : 4786 )
-#endif
-
-#include "itkObjectFactoryBase.h"
-#include "MitkExtExports.h"
-#include "mitkBaseData.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Create instances of VtkVolumeTimeSeriesReader objects using an object factory.
-//##
-//## @ingroup IO
-class MitkExt_EXPORT VtkVolumeTimeSeriesIOFactory : public itk::ObjectFactoryBase
-{
-public:
- /** Standard class typedefs. */
- typedef VtkVolumeTimeSeriesIOFactory Self;
- typedef itk::ObjectFactoryBase Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Class methods used to interface with the registered factories. */
- virtual const char* GetITKSourceVersion(void) const;
- virtual const char* GetDescription(void) const;
-
- /** Method for class instantiation. */
- itkFactorylessNewMacro(Self);
- static VtkVolumeTimeSeriesIOFactory* FactoryNew() { return new VtkVolumeTimeSeriesIOFactory;}
- /** Run-time type information (and related methods). */
- itkTypeMacro(VtkVolumeTimeSeriesIOFactory, ObjectFactoryBase);
-
- /**
- * Register one factory of this type
- * \deprecatedSince{2013_09}
- */
- DEPRECATED(static void RegisterOneFactory(void))
- {
- VtkVolumeTimeSeriesIOFactory::Pointer VtkVolumeTimeSeriesIOFactory = VtkVolumeTimeSeriesIOFactory::New();
- ObjectFactoryBase::RegisterFactory(VtkVolumeTimeSeriesIOFactory);
- }
-
-protected:
- VtkVolumeTimeSeriesIOFactory();
- ~VtkVolumeTimeSeriesIOFactory();
-
-private:
- VtkVolumeTimeSeriesIOFactory(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace mitk
-
-#endif
diff --git a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesReader.cpp b/Modules/Ext/IO/mitkVtkVolumeTimeSeriesReader.cpp
deleted file mode 100644
index 23c386cb4f..0000000000
--- a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesReader.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkVtkVolumeTimeSeriesReader.h"
-#include "mitkVtkSurfaceReader.h"
-#include "mitkSurface.h"
-#include "vtkPolyData.h"
-
-void mitk::VtkVolumeTimeSeriesReader::GenerateData()
-{
- if ( !this->GenerateFileList() )
- {
- itkWarningMacro( << "Sorry, file list could not be determined..." );
- return ;
- }
-
- mitk::Surface::Pointer output = this->GetOutput();
- MITK_INFO << "prefix: "<< m_FilePrefix << ", pattern: " <<m_FilePattern << std::endl;
- output->Expand(m_MatchedFileNames.size());
- for ( unsigned int i = 0 ; i < m_MatchedFileNames.size(); ++i )
- {
- std::string fileName = m_MatchedFileNames[i];
- MITK_INFO << "Loading " << fileName << " as vtk..." << std::endl;
-
- VtkSurfaceReader::Pointer vtkReader = VtkSurfaceReader::New();
- vtkReader->SetFileName( fileName.c_str() );
- vtkReader->Update();
-
- if ( vtkReader->GetOutput() != NULL )
- {
- output->SetVtkPolyData( vtkReader->GetOutput()->GetVtkPolyData(), i );
- }
- else
- {
- itkWarningMacro(<< "vtkPolyDataReader returned NULL while reading " << fileName << ". Trying to continue with empty vtkPolyData...");
- output->SetVtkPolyData( vtkPolyData::New(), i );
- }
- }
-}
-
-bool mitk::VtkVolumeTimeSeriesReader::CanReadFile(const std::string /*filename*/, const std::string filePrefix, const std::string filePattern)
-{
- if( filePattern != "" && filePrefix != "" )
- return false;
-
- bool extensionFound = false;
- std::string::size_type VTKPos = filePattern.rfind(".vtk");
- if ((VTKPos != std::string::npos) && (VTKPos == filePattern.length() - 4))
- extensionFound = true;
-
- VTKPos = filePattern.rfind(".VTK");
- if ((VTKPos != std::string::npos) && (VTKPos == filePattern.length() - 4))
- extensionFound = true;
-
- if( !extensionFound )
- return false;
-
- return true;
-}
-
-mitk::VtkVolumeTimeSeriesReader::VtkVolumeTimeSeriesReader()
-{}
-
-mitk::VtkVolumeTimeSeriesReader::~VtkVolumeTimeSeriesReader()
-{}
diff --git a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesReader.h b/Modules/Ext/IO/mitkVtkVolumeTimeSeriesReader.h
deleted file mode 100644
index 3e1e4b906d..0000000000
--- a/Modules/Ext/IO/mitkVtkVolumeTimeSeriesReader.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef _Vtk_VOLUME_TIME_SERIES_READER__H_
-#define _Vtk_VOLUME_TIME_SERIES_READER__H_
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkFileSeriesReader.h"
-#include "mitkSurfaceSource.h"
-
-namespace mitk
-{
-//##Documentation
-//## @brief Reader to read a series of volume files in Vtk-format
-//## @ingroup IO
-class MitkExt_EXPORT VtkVolumeTimeSeriesReader : public SurfaceSource, public FileSeriesReader
-{
-public:
- mitkClassMacro( VtkVolumeTimeSeriesReader, FileReader );
-
- /** Method for creation through the object factory. */
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- itkSetStringMacro(FileName);
- itkGetStringMacro(FileName);
-
- itkSetStringMacro(FilePrefix);
- itkGetStringMacro(FilePrefix);
-
- itkSetStringMacro(FilePattern);
- itkGetStringMacro(FilePattern);
-
- static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
-
-protected:
- virtual void GenerateData();
-
- VtkVolumeTimeSeriesReader();
-
- ~VtkVolumeTimeSeriesReader();
-
- //##Description
- //## @brief Time when Header was last read
- itk::TimeStamp m_ReadHeaderTime;
-
-};
-
-} // namespace mitk
-
-#endif
-
-
diff --git a/Modules/Ext/Interactions/StateMachines.zip b/Modules/Ext/Interactions/StateMachines.zip
deleted file mode 100644
index b72378a5a9..0000000000
Binary files a/Modules/Ext/Interactions/StateMachines.zip and /dev/null differ
diff --git a/Modules/Ext/Interactions/debug_protocoll.pdf b/Modules/Ext/Interactions/debug_protocoll.pdf
deleted file mode 100644
index 02c5e3aba4..0000000000
Binary files a/Modules/Ext/Interactions/debug_protocoll.pdf and /dev/null differ
diff --git a/Modules/Ext/Interactions/mitkAffineInteractor3D.cpp b/Modules/Ext/Interactions/mitkAffineInteractor3D.cpp
deleted file mode 100644
index 0c0f25130e..0000000000
--- a/Modules/Ext/Interactions/mitkAffineInteractor3D.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkAffineInteractor3D.h"
-#include "mitkPointOperation.h"
-#include "mitkPositionEvent.h"
-#include "mitkStatusBar.h"
-#include "mitkDataNode.h"
-#include "mitkInteractionConst.h"
-#include "mitkAction.h"
-#include "mitkStateEvent.h"
-#include "mitkOperationEvent.h"
-#include "mitkUndoController.h"
-#include "mitkStateMachineFactory.h"
-#include "mitkStateTransitionOperation.h"
-#include "mitkBaseRenderer.h"
-#include "mitkRenderingManager.h"
-#include "mitkRotationOperation.h"
-
-#include <vtkRenderWindow.h>
-#include <vtkRenderWindowInteractor.h>
-#include <vtkInteractorStyle.h>
-#include <vtkRenderer.h>
-#include <vtkCamera.h>
-#include <vtkPoints.h>
-#include <vtkPointData.h>
-#include <vtkDataArray.h>
-
-
-namespace mitk
-{
-
-//how precise must the user pick the point
-//default value
-AffineInteractor3D
-::AffineInteractor3D(const char * type, DataNode* dataNode, int /* n */ )
-: Interactor( type, dataNode ),
- m_Precision( 6.5 ),
- m_InteractionMode( INTERACTION_MODE_TRANSLATION )
-{
- Geometry3D::Pointer geo3D = Geometry3D::New();
- m_OriginalGeometry = dynamic_cast<BaseGeometry*>(geo3D.GetPointer());
-
- // Initialize vector arithmetic
- m_ObjectNormal[0] = 0.0;
- m_ObjectNormal[1] = 0.0;
- m_ObjectNormal[2] = 1.0;
-}
-
-
-AffineInteractor3D::~AffineInteractor3D()
-{
-}
-
-
-void AffineInteractor3D::SetInteractionMode( unsigned int interactionMode )
-{
- m_InteractionMode = interactionMode;
-}
-
-
-void AffineInteractor3D::SetInteractionModeToTranslation()
-{
- m_InteractionMode = INTERACTION_MODE_TRANSLATION;
-}
-
-
-void AffineInteractor3D::SetInteractionModeToRotation()
-{
- m_InteractionMode = INTERACTION_MODE_ROTATION;
-}
-
-
-unsigned int AffineInteractor3D::GetInteractionMode() const
-{
- return m_InteractionMode;
-}
-
-
-void AffineInteractor3D::SetPrecision( ScalarType precision )
-{
- m_Precision = precision;
-}
-
-// Overwritten since this class can handle it better!
-float AffineInteractor3D
-::CanHandleEvent(StateEvent const* stateEvent) const
-{
- float returnValue = 0.5;
-
-
- // If it is a key event that can be handled in the current state,
- // then return 0.5
- DisplayPositionEvent const *disPosEvent =
- dynamic_cast <const DisplayPositionEvent *> (stateEvent->GetEvent());
-
- // Key event handling:
- if (disPosEvent == NULL)
- {
- // Check if the current state has a transition waiting for that key event.
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- return 0.5;
- }
- else
- {
- return 0.0;
- }
- }
-
- //on MouseMove do nothing!
- //if (stateEvent->GetEvent()->GetType() == Type_MouseMove)
- //{
- // return 0.0;
- //}
-
- //if the event can be understood and if there is a transition waiting for that event
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- returnValue = 0.5;//it can be understood
- }
-
- //int timeStep = disPosEvent->GetSender()->GetTimeStep();
-
- //CurveModel *curveModel = dynamic_cast<CurveModel *>(
- // m_DataNode->GetData() );
-
- //if ( curveModel != NULL )
- //{
- // // Get the PlaneGeometry of the window the user interacts with (for 2D point
- // // projection)
- // BaseRenderer *renderer = stateEvent->GetEvent()->GetSender();
- // const PlaneGeometry *projectionPlane = renderer->GetCurrentWorldPlaneGeometry();
-
- // // For reading on the points, Ids etc
- // //CurveModel::PointSetType *pointSet = curveModel->GetPointSet( timeStep );
- // //if ( pointSet == NULL )
- // //{
- // // return 0.0;
- // //}
-
- //}
- return returnValue;
-}
-
-
-bool AffineInteractor3D
-::ExecuteAction( Action *action, StateEvent const *stateEvent )
-{
- bool ok = false;
-
- // Get data object
- BaseData *data = m_DataNode->GetData();
- if ( data == NULL )
- {
- MITK_ERROR << "No data object present!";
- return ok;
- }
-
- // Get Event and extract renderer
- const Event *event = stateEvent->GetEvent();
- BaseRenderer *renderer = NULL;
- vtkRenderWindow *renderWindow = NULL;
- vtkRenderWindowInteractor *renderWindowInteractor = NULL;
- vtkRenderer *currentVtkRenderer = NULL;
- vtkCamera *camera = NULL;
-
- if ( event != NULL )
- {
- renderer = event->GetSender();
- if ( renderer != NULL )
- {
- renderWindow = renderer->GetRenderWindow();
- if ( renderWindow != NULL )
- {
- renderWindowInteractor = renderWindow->GetInteractor();
- if ( renderWindowInteractor != NULL )
- {
- currentVtkRenderer = renderWindowInteractor
- ->GetInteractorStyle()->GetCurrentRenderer();
- if ( currentVtkRenderer != NULL )
- {
- camera = currentVtkRenderer->GetActiveCamera();
- }
- }
- }
- }
- }
-
- // Check if we have a DisplayPositionEvent
- const DisplayPositionEvent *dpe =
- dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
- if ( dpe != NULL )
- {
- m_CurrentPickedPoint = dpe->GetWorldPosition();
- m_CurrentPickedDisplayPoint = dpe->GetDisplayPosition();
- }
-
- // Get the timestep to also support 3D+t
- int timeStep = 0;
- ScalarType timeInMS = 0.0;
- if ( renderer != NULL )
- {
- timeStep = renderer->GetTimeStep( data );
- timeInMS = renderer->GetTime();
- }
-
- // If data is an mitk::Surface, extract it
- Surface *surface = dynamic_cast< Surface * >( data );
- vtkPolyData *polyData = NULL;
- if ( surface != NULL )
- {
- polyData = surface->GetVtkPolyData( timeStep );
-
- // Extract surface normal from surface (if existent, otherwise use default)
- vtkPointData *pointData = polyData->GetPointData();
- if ( pointData != NULL )
- {
- vtkDataArray *normal = polyData->GetPointData()->GetVectors( "planeNormal" );
- if ( normal != NULL )
- {
- m_ObjectNormal[0] = normal->GetComponent( 0, 0 );
- m_ObjectNormal[1] = normal->GetComponent( 0, 1 );
- m_ObjectNormal[2] = normal->GetComponent( 0, 2 );
- }
- }
- }
-
- // Get geometry object
- m_Geometry = data->GetGeometry( timeStep );
-
-
- // Make sure that the data (if time-resolved) has enough entries;
- // if not, create the required extra ones (empty)
- data->Expand( timeStep+1 );
-
-
- switch (action->GetActionId())
- {
- case AcDONOTHING:
- ok = true;
- break;
-
-
- case AcCHECKOBJECT:
- {
- // Re-enable VTK interactor (may have been disabled previously)
- if ( renderWindowInteractor != NULL )
- {
- renderWindowInteractor->Enable();
- }
-
- // Check if we have a DisplayPositionEvent
- const DisplayPositionEvent *dpe =
- dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
- if ( dpe == NULL )
- {
- ok = true;
- break;
- }
-
- // Check if an object is present at the current mouse position
- DataNode *pickedNode = dpe->GetPickedObjectNode();
- StateEvent *newStateEvent;
- if ( pickedNode == m_DataNode )
- {
- // Yes: object will be selected
- newStateEvent = new StateEvent( EIDYES );
- }
- else
- {
- // No: back to start state
- newStateEvent = new StateEvent( EIDNO );
- }
-
- this->HandleEvent( newStateEvent );
-
- ok = true;
- break;
- }
-
- case AcDESELECTOBJECT:
- {
- // Color object white
- m_DataNode->SetColor( 1.0, 1.0, 1.0 );
- RenderingManager::GetInstance()->RequestUpdateAll();
-
- // Colorize surface / wireframe as inactive
- this->ColorizeSurface( polyData,
- m_CurrentPickedPoint, -1.0 );
-
- ok = true;
- break;
- }
-
- case AcSELECTPICKEDOBJECT:
- {
- // Color object red
- m_DataNode->SetColor( 1.0, 0.0, 0.0 );
- RenderingManager::GetInstance()->RequestUpdateAll();
-
- // Colorize surface / wireframe dependend on distance from picked point
- this->ColorizeSurface( polyData,
- m_CurrentPickedPoint, 0.0 );
-
- ok = true;
- break;
- }
-
- case AcINITMOVE:
- {
- // Disable VTK interactor until MITK interaction has been completed
- if ( renderWindowInteractor != NULL )
- {
- renderWindowInteractor->Disable();
- }
-
- // Check if we have a DisplayPositionEvent
- const DisplayPositionEvent *dpe =
- dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
- if ( dpe == NULL )
- {
- ok = true;
- break;
- }
-
- //DataNode *pickedNode = dpe->GetPickedObjectNode();
-
- m_InitialPickedPoint = m_CurrentPickedPoint;
- m_InitialPickedDisplayPoint = m_CurrentPickedDisplayPoint;
-
- if ( currentVtkRenderer != NULL )
- {
- vtkInteractorObserver::ComputeDisplayToWorld(
- currentVtkRenderer,
- m_InitialPickedDisplayPoint[0],
- m_InitialPickedDisplayPoint[1],
- 0.0, //m_InitialInteractionPickedPoint[2],
- m_InitialPickedPointWorld );
- }
-
-
- // Make deep copy of current Geometry3D of the plane
- data->UpdateOutputInformation(); // make sure that the Geometry is up-to-date
- m_OriginalGeometry = static_cast< BaseGeometry * >(
- data->GetGeometry( timeStep )->Clone().GetPointer() );
-
- ok = true;
- break;
- }
-
- case AcMOVE:
- {
- // Check if we have a DisplayPositionEvent
- const DisplayPositionEvent *dpe =
- dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
- if ( dpe == NULL )
- {
- ok = true;
- break;
- }
-
- if ( currentVtkRenderer != NULL )
- {
- vtkInteractorObserver::ComputeDisplayToWorld(
- currentVtkRenderer,
- m_CurrentPickedDisplayPoint[0],
- m_CurrentPickedDisplayPoint[1],
- 0.0, //m_InitialInteractionPickedPoint[2],
- m_CurrentPickedPointWorld );
- }
-
-
- Vector3D interactionMove;
- interactionMove[0] = m_CurrentPickedPointWorld[0] - m_InitialPickedPointWorld[0];
- interactionMove[1] = m_CurrentPickedPointWorld[1] - m_InitialPickedPointWorld[1];
- interactionMove[2] = m_CurrentPickedPointWorld[2] - m_InitialPickedPointWorld[2];
-
- if ( m_InteractionMode == INTERACTION_MODE_TRANSLATION )
- {
- Point3D origin = m_OriginalGeometry->GetOrigin();
-
- Vector3D transformedObjectNormal;
- data->GetGeometry( timeStep )->IndexToWorld(
- m_ObjectNormal, transformedObjectNormal );
-
- data->GetGeometry( timeStep )->SetOrigin(
- origin + transformedObjectNormal * (interactionMove * transformedObjectNormal) );
- }
- else if ( m_InteractionMode == INTERACTION_MODE_ROTATION )
- {
- if ( camera )
- {
- double vpn[3];
- camera->GetViewPlaneNormal( vpn );
-
- Vector3D viewPlaneNormal;
- viewPlaneNormal[0] = vpn[0];
- viewPlaneNormal[1] = vpn[1];
- viewPlaneNormal[2] = vpn[2];
-
- Vector3D rotationAxis =
- itk::CrossProduct( viewPlaneNormal, interactionMove );
- rotationAxis.Normalize();
-
- int *size = currentVtkRenderer->GetSize();
- double l2 =
- (m_CurrentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) *
- (m_CurrentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) +
- (m_CurrentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]) *
- (m_CurrentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]);
-
- double rotationAngle = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
-
- // Use center of data bounding box as center of rotation
- Point3D rotationCenter = m_OriginalGeometry->GetCenter();;
-
- // Reset current Geometry3D to original state (pre-interaction) and
- // apply rotation
- RotationOperation op( OpROTATE, rotationCenter, rotationAxis, rotationAngle );
- BaseGeometry::Pointer newGeometry = static_cast< BaseGeometry * >(
- m_OriginalGeometry->Clone().GetPointer() );
- newGeometry->ExecuteOperation( &op );
- data->SetClonedGeometry(newGeometry, timeStep);
- }
- }
-
- RenderingManager::GetInstance()->RequestUpdateAll();
- ok = true;
- break;
- }
-
-
-
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- }
-
- return ok;
-}
-
-bool AffineInteractor3D::ColorizeSurface( vtkPolyData *polyData,
- const Point3D & /*pickedPoint*/, double scalar )
-{
- if ( polyData == NULL )
- {
- return false;
- }
-
- //vtkPoints *points = polyData->GetPoints();
- vtkPointData *pointData = polyData->GetPointData();
- if ( pointData == NULL )
- {
- return false;
- }
-
- vtkDataArray *scalars = pointData->GetScalars();
- if ( scalars == NULL )
- {
- return false;
- }
-
- for ( unsigned int i = 0; i < pointData->GetNumberOfTuples(); ++i )
- {
- scalars->SetComponent( i, 0, scalar );
- }
-
- polyData->Modified();
- pointData->Update();
-
- return true;
-}
-
-
-} // namespace
diff --git a/Modules/Ext/Interactions/mitkAffineInteractor3D.h b/Modules/Ext/Interactions/mitkAffineInteractor3D.h
deleted file mode 100644
index 58b5b317a6..0000000000
--- a/Modules/Ext/Interactions/mitkAffineInteractor3D.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKAFFINEINTERACTOR3D_H_HEADER_INCLUDED
-#define MITKAFFINEINTERACTOR3D_H_HEADER_INCLUDED
-
-#include "mitkInteractor.h"
-#include "MitkExtExports.h"
-#include "mitkCommon.h"
-#include "mitkSurface.h"
-
-#include <vtkPolyData.h>
-#include <vtkType.h>
-
-namespace mitk
-{
-
-class DataNode;
-
-/**
- * \brief Affine interaction with objects in 3D windows.
- *
- * NOTE: The interaction mechanism is similar to that of vtkPlaneWidget
- *
- * \ingroup Interaction
- * \deprecatedSince{2013_12} mitk::AffineInteractor is deprecated. Use mitk::AffineDataInteractor instead.
-
- */
-class MitkExt_EXPORT AffineInteractor3D : public Interactor
-{
-public:
- enum { INTERACTION_MODE_TRANSLATION, INTERACTION_MODE_ROTATION };
-
- mitkClassMacro(AffineInteractor3D, Interactor);
- mitkNewMacro3Param(Self, const char *, DataNode *, int);
- mitkNewMacro2Param(Self, const char *, DataNode *);
-
-
- void SetInteractionMode( unsigned int interactionMode );
- void SetInteractionModeToTranslation();
- void SetInteractionModeToRotation();
- unsigned int GetInteractionMode() const;
-
- /** \brief Sets the amount of precision */
- void SetPrecision( ScalarType precision );
-
- /**
- * \brief calculates how good the data, this statemachine handles, is hit
- * by the event.
- *
- * overwritten, cause we don't look at the boundingbox, we look at each point
- */
- virtual float CanHandleEvent(StateEvent const *stateEvent) const;
-
-
-protected:
- /**
- * \brief Constructor with Param n for limited Set of Points
- *
- * if no n is set, then the number of points is unlimited*
- */
- DEPRECATED(AffineInteractor3D(const char *type,
- DataNode *dataNode, int n = -1));
-
- /**
- * \brief Default Destructor
- **/
- virtual ~AffineInteractor3D();
-
- virtual bool ExecuteAction( Action* action,
- mitk::StateEvent const* stateEvent );
-
- bool ColorizeSurface( vtkPolyData *polyData, const Point3D &pickedPoint,
- double scalar = 0.0 );
-
-
-private:
-
- /** \brief to store the value of precision to pick a point */
- ScalarType m_Precision;
-
- bool m_InteractionMode;
-
- Point3D m_InitialPickedPoint;
- Point2D m_InitialPickedDisplayPoint;
- double m_InitialPickedPointWorld[4];
-
- Point3D m_CurrentPickedPoint;
- Point2D m_CurrentPickedDisplayPoint;
- double m_CurrentPickedPointWorld[4];
-
- BaseGeometry::Pointer m_Geometry;
-
- BaseGeometry::Pointer m_OriginalGeometry;
-
- Vector3D m_ObjectNormal;
-
-};
-
-
-}
-
-#endif /* MITKAFFINEINTERACTOR3D_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Interactions/mitkConferenceEventMapper.cpp b/Modules/Ext/Interactions/mitkConferenceEventMapper.cpp
deleted file mode 100644
index 184812dec7..0000000000
--- a/Modules/Ext/Interactions/mitkConferenceEventMapper.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include <mitkConferenceEventMapper.h>
-#include <mitkCameraController.h>
-#include <mitkBaseRenderer.h>
-#include <mitkPositionEvent.h>
-#include <mitkRenderingManager.h>
-#include <mitkGlobalInteraction.h>
-
-
-mitk::ConferenceEventMapper::ConferenceEventMapper(){}
-
-mitk::ConferenceEventMapper::~ConferenceEventMapper(){}
-
-//CONFERENCE USE
-bool
-mitk::ConferenceEventMapper::MapEvent(signed int mitkEventID, const char* sender, int Etype, int Estate, int Ebuttonstate, int Ekey, float w1,float w2,float w3,float p1,float p2)
-{
-
- //CONFERENCE EVENT
- mitk::BaseRenderer *br = const_cast<mitk::BaseRenderer*>(mitk::BaseRenderer::GetByName( std::string(sender) ));
-
- mitk::Point3D p3d;
- p3d[0] = (mitk::ScalarType) w1;
- p3d[1] = (mitk::ScalarType) w2;
- p3d[2] = (mitk::ScalarType) w3;
-
- // fit relative values to absolut....
- mitk::Point2D p2d;
- p2d[0] = (mitk::ScalarType) p1 * br->GetSizeX();
- p2d[1] = (mitk::ScalarType) p2 * br->GetSizeX();
-
-
- mitk::PositionEvent *pe = new mitk::PositionEvent(br,Etype,Estate,Ebuttonstate,Ekey,p2d,p3d);
-
- // MOUSE Overlay
- mitk::Point2D p2d_mm, pos_unit;
- //Map world to 2d mm
- if (br->GetDisplayGeometry()->Map( p3d, p2d_mm ) )
- {
- //calculate position of the real inner widget
- br->GetDisplayGeometry()->WorldToDisplay( p2d_mm, pos_unit);
- //MITK_INFO<<p2d_mm[0]<<", "<<p2d_mm[1]<<", U: "<<pos_unit[0]<<", "<<pos_unit[1]<<" p3d ( "<<p3d[0]<<p3d[1]<<p3d[2]<<" ) "<<std::endl;
- br->DrawOverlayMouse(pos_unit); //TEST
- //mitk::RenderingManager::GetInstance()->RequestOverlayUpdateAll();
- }
-
-
- //MITK_INFO<<"mitkEventMapper::MapEvent(): "<<br->GetSizeX()<<" * "<<p1<<" =X (("<<p2d[0]<<")) UND "<<br->GetSizeY()<<" * "<< p2 <<" =Y (("<<p2d[1]<<"))"<<std::endl;
-
- //ONlY 3D Widget
- if( br->GetMapperID() == 2 )
- {
- mitk::CameraController* cc = br->GetCameraController();
-
- //Qt Event IDs
- if (Etype == 6)
- {
- // KeyPress
- //cc->KeyPressEvent( keyevent); */
- ;
- }
- else
- {
- //Umrechnung fuer VTKCameraControler
- p2d[1] = (mitk::ScalarType) (br->GetSizeY() - p2) * br->GetSizeY();
- mitk::PositionEvent *peVTK = new mitk::PositionEvent(br,Etype,Estate,Ebuttonstate,Ekey,p2d,p3d);
- // END
-
- //PRESS
- if(Etype == 2)
- {
- cc->MousePressEvent( peVTK );
- }
- else if (Etype == 3 )
- {
- //RELEASE
- cc->MouseReleaseEvent( peVTK );
- }
- else if (Etype == 5)
- {
- //MOVE
- cc->MouseMoveEvent( peVTK );
- }
- }
- }
-
- bool ok = EventMapper::MapEvent( pe, mitk::GlobalInteraction::GetInstance(), mitkEventID );
-
- return ok;
-}
-
-bool
-mitk::ConferenceEventMapper::MapEvent(const char* sender, float w1, float w2, float w3)
-{
-
- //CONFERENCE EVENT
- mitk::BaseRenderer *br = const_cast<mitk::BaseRenderer*>(mitk::BaseRenderer::GetByName( std::string(sender) ));
-
- mitk::Point3D p3d;
- p3d[0] = (mitk::ScalarType) w1;
- p3d[1] = (mitk::ScalarType) w2;
- p3d[2] = (mitk::ScalarType) w3;
-
- // MOUSE Overlay
- mitk::Point2D p2d_mm, pos_unit;
- //Map world to 2d mm
- if (br->GetDisplayGeometry()->Map( p3d, p2d_mm ) )
- {
- //calculate position of the real inner widget
- br->GetDisplayGeometry()->WorldToDisplay( p2d_mm, pos_unit);
- //MITK_INFO<<p2d_mm[0]<<", "<<p2d_mm[1]<<", U: "<<pos_unit[0]<<", "<<pos_unit[1]<<" p3d ( "<<p3d[0]<<p3d[1]<<p3d[2]<<" ) "<<std::endl;
- br->DrawOverlayMouse(pos_unit); //TEST
- //mitk::RenderingManager::GetInstance()->RequestOverlayUpdateAll();
- }
-
- return true;
-}
-
-
diff --git a/Modules/Ext/Interactions/mitkConferenceEventMapper.h b/Modules/Ext/Interactions/mitkConferenceEventMapper.h
deleted file mode 100644
index 55febd7484..0000000000
--- a/Modules/Ext/Interactions/mitkConferenceEventMapper.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef CONFERENCEVENTMAPPER_H_HEADER_INCLUDE
-#define CONFERENCEVENTMAPPER_H_HEADER_INCLUDE
-
-#include <mitkEventMapper.h>
-#include "MitkExtExports.h"
-
-namespace mitk {
-
- class MitkExt_EXPORT ConferenceEventMapper : public EventMapper
- {
- public:
- ConferenceEventMapper();
-
- ~ConferenceEventMapper();
-
- // First part MITK Event ID and baserendere name
- // Second the normaly not needed integer information from the GUI Event (type, state, button, key)
- // Third the koordinated 3D and the relativ 2D
- static bool MapEvent(signed int id, const char* sender, int Etype, int Estate, int EButtonState, int key, float w1,float w2,float w3,float d0,float d1);
-
- /* EasyEvent for MousMove Interaction.
- * used during conferences
- */
- static bool MapEvent(const char* sender, float w1,float w2,float w3);
- };
-} // namespace mitk
-
-#endif
-
-
diff --git a/Modules/Ext/Interactions/mitkConnectPointsInteractor.cpp b/Modules/Ext/Interactions/mitkConnectPointsInteractor.cpp
deleted file mode 100644
index 325ac4c099..0000000000
--- a/Modules/Ext/Interactions/mitkConnectPointsInteractor.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkConnectPointsInteractor.h"
-#include <mitkLineOperation.h>
-#include <mitkPositionEvent.h>
-#include <mitkState.h>
-#include <mitkStateEvent.h>
-#include <mitkUndoController.h>
-#include <mitkMesh.h>
-#include <mitkDataNode.h>
-#include <mitkInteractionConst.h>
-#include <mitkAction.h>
-#include <vtkLinearTransform.h>
-
-//how precise must the user pick the point
-//default value
-const int PRECISION = 5;
-
-mitk::ConnectPointsInteractor::ConnectPointsInteractor(const char * type, DataNode* dataNode, int n)
-:Interactor(type, dataNode), m_N(n), m_CurrentCellId(0), m_Precision(PRECISION)
-{
- m_LastPoint.Fill(0);
- m_SumVec.Fill(0);
-}
-
-mitk::ConnectPointsInteractor::~ConnectPointsInteractor()
-{
-}
-
-void mitk::ConnectPointsInteractor::SetPrecision(unsigned int precision)
-{
- m_Precision = precision;
-}
-
-//##Documentation
-//## overwritten cause this class can handle it better!
-float mitk::ConnectPointsInteractor::CanHandleEvent(StateEvent const* stateEvent) const
-{
- float returnValue = 0;
-
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- //checking if a keyevent can be handled:
- if (posEvent == NULL)
- {
- //check, if the current state has a transition waiting for that key event.
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- return 0.5;
- }
- else
- {
- return 0;
- }
- }
-
- //Mouse event handling:
- //on MouseMove do nothing! reimplement if needed differently
- if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
- {
- return 0;
- }
-
- //check on the right data-type
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return 0;
-
-
- //since we now have 3D picking in GlobalInteraction and all events send are DisplayEvents with 3D information,
- //we concentrate on 3D coordinates
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
- float p[3];
- itk2vtk(worldPoint, p);
- //transforming the Worldposition to local coordinatesystem
- m_DataNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p);
- vtk2itk(p, worldPoint);
-
- float distance = 5;
- int index = pointSet->SearchPoint(worldPoint, distance);
- if (index>-1)
- //how far away is the line from the point?
- {
- //get the point and calculate the jurisdiction out of it.
- mitk::PointSet::PointType point;
- pointSet->GetPointSet()->GetPoint(index, &point);
- returnValue = point.EuclideanDistanceTo(worldPoint);
-
- //between 1 and 0. 1 if directly hit
- returnValue = 1 - ( returnValue / distance );
- if (returnValue<0 || returnValue>1)
- {
- itkWarningMacro("Difficulties in calculating Jurisdiction. Check PointInteractor");
- return 0;
- }
-
- //and now between 0,5 and 1
- returnValue = 0.5 + (returnValue / 2);
-
- return returnValue;
- }
- else //not found
- {
- return 0;
- }
-}
-
-bool mitk::ConnectPointsInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
-{
- bool ok = false;//for return type bool
-
- //checking corresponding Data; has to be a Mesh or a subclass
- mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataNode->GetData());
- if (mesh == NULL)
- return false;
-
- //for reading on the points, Id's etc
- //mitk::PointSet::DataType *itkpointSet = mesh->GetPointSet();
- //mitk::PointSet::PointsContainer *points = itkpointSet->GetPoints();//Warning Fix: not used!
-
- /*Each case must watch the type of the event!*/
- switch (action->GetActionId())
- {
- case AcDONOTHING:
- ok = true;
- break;
- case AcADDPOINT:
- {
- mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D worldPoint;
- worldPoint = posEvent->GetWorldPosition();
-
- int position = mesh->SearchPoint(worldPoint, m_Precision);
- if (position >= 0)//found a point near enough to the given point
- {
- // if the point is the last in current cell, remove it (this has to be moved in a separate action)
- bool deleteLine=false;
- if(mesh->GetMesh()->GetCells()->Size() > 0)
- {
- Mesh::CellAutoPointer cellAutoPointer;
- ok = mesh->GetMesh()->GetCell(m_CurrentCellId, cellAutoPointer);
- if(ok)
- {
- Mesh::PointIdIterator last = cellAutoPointer->PointIdsEnd();
- --last;
- int foundCell = mesh->SearchFirstCell( (unsigned long) position );
- if (foundCell != -1)//not found
- deleteLine = ((unsigned int)foundCell == m_CurrentCellId) && (*last == (unsigned int)position);
- }
- }
- if(deleteLine)
- {
- LineOperation* doOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position);
- if (m_UndoEnabled)
- {
- LineOperation* undoOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position);
- OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Delete line");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- //execute the Operation
- mesh->ExecuteOperation(doOp );
- }
- else
- {
- // add new cell if necessary
- if(mesh->GetNewCellId() == 0) //allow single line only
- //allow multiple lines: if((mesh->SearchFirstCell(position) >= 0) || ((m_CurrentCellId == 0) && (mesh->GetNewCellId() == 0)))
- {
- //get the next cellId and set m_CurrentCellId
- m_CurrentCellId = mesh->GetNewCellId();
-
- //now reserv a new cell in m_ItkData
- LineOperation* doOp = new mitk::LineOperation(OpNEWCELL, m_CurrentCellId);
- if (m_UndoEnabled)
- {
- LineOperation* undoOp = new mitk::LineOperation(OpDELETECELL, m_CurrentCellId);
- OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Add cell");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- mesh->ExecuteOperation(doOp);
- }
- // add line if point is not yet included in current cell
- if(mesh->SearchFirstCell(position) < 0)
- {
- LineOperation* doOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position);
- if (m_UndoEnabled)
- {
- LineOperation* undoOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position);
- OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Add line");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- //execute the Operation
- mesh->ExecuteOperation(doOp );
- }
- }
- }
- ok = true;
- break;
- }
- case AcREMOVEPOINT:
- {
- //mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- //if (posEvent == NULL)
- // return false;
-
- //mitk::Point3D worldPoint;
- //worldPoint = posEvent->GetWorldPosition();
-
- //int position = mesh->SearchPoint(worldPoint, m_Precision);
- //if (position>=0)//found a point near enough to the given point
- //{
- // // if the point is in the current cell, remove it (this has to be moved in a separate action)
- // if(mesh->SearchFirstCell(position) == m_CurrentCellId)
- // {
- // LineOperation* doOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position);
- // if (m_UndoEnabled)
- // {
- // LineOperation* undoOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position);
- // OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp);
- // m_UndoController->SetOperationEvent(operationEvent);
- // }
- // //execute the Operation
- // mesh->ExecuteOperation(doOp );
- // }
- //}
- ok = true;
- break;
- }
- case AcCHECKELEMENT:
- /*checking if the Point transmitted is close enough to one point. Then generate a new event with the point and let this statemaschine handle the event.*/
- {
- mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (posEvent != NULL)
- {
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- int position = mesh->SearchPoint(worldPoint, m_Precision);
- if (position>=0)//found a point near enough to the given point
- {
- PointSet::PointType pt = mesh->GetPoint(position);//get that point, the one meant by the user!
- mitk::Point2D displPoint;
- displPoint[0] = worldPoint[0]; displPoint[1] = worldPoint[1];
- //new Event with information YES and with the correct point
- mitk::PositionEvent const* newPosEvent = new mitk::PositionEvent(posEvent->GetSender(), Type_None, BS_NoButton, BS_NoButton, Key_none, displPoint, pt);
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, newPosEvent);
- //call HandleEvent to leave the guard-state
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent(newStateEvent );
- ok = true;
- }
- }
- else
- {
- mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (disPosEvent != NULL)
- {//2d Koordinates for 3D Interaction; return false to redo the last statechange
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent(newStateEvent );
- ok = true;
- }
- }
- break;
- }
- case AcCHECKNMINUS1://generate Events if the set will be full after the addition of the point or not.
- {
- if (m_N<0)//number of points not limited->pass on "Amount of points in Set is smaller then N-1"
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- if (mesh->GetSize()<(m_N-1))
- //pointset after addition won't be full
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else //(mesh->GetSize()>=(m_N-1))
- //after the addition of a point, the container will be full
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTLARGERNMINUS1, stateEvent->GetEvent());
- this->HandleEvent(newStateEvent );
- ok = true;
- }//else
- }//else
- }
- break;
- case AcCHECKEQUALS1:
- {
- if (mesh->GetSize()<=1)//the number of points in the list is 1 (or smaler)
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else //more than 1 points in list, so stay in the state!
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
- this->HandleEvent(newStateEvent );
- ok = true;
- }
- }
- break;
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- //mitk::StatusBar::GetInstance()->DisplayText("Message from mitkConnectPointsInteractor: I do not understand the Action!", 10000);
- //ok = false;
- //a false here causes the statemachine to undo its last statechange.
- //otherwise it will end up in a different state, but without done Action.
- //if a transition really has no Action, than call donothing
- }
-
- return ok;
-}
diff --git a/Modules/Ext/Interactions/mitkConnectPointsInteractor.h b/Modules/Ext/Interactions/mitkConnectPointsInteractor.h
deleted file mode 100644
index c78d58396e..0000000000
--- a/Modules/Ext/Interactions/mitkConnectPointsInteractor.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKCONNECTPOINTSINTERACTOR_H_HEADER_INCLUDED_C11202FF
-#define MITKCONNECTPOINTSINTERACTOR_H_HEADER_INCLUDED_C11202FF
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkNumericTypes.h"
-#include <mitkInteractor.h>
-
-namespace mitk
-{
- class DataNode;
- //##Documentation
- //## @brief Interaction for mitk::Mesh: Connect existing points to lines
- //## @ingroup Interaction
- /**
- * \deprecatedSince{2014_03} mitk::ConnectPointsInteractor is deprecated. Needs to be updated to the new interaction-framework.
- * Refer to \see DataInteractionPage for general information about the concept of the new implementation.
- */
- class DEPRECATED() MitkExt_EXPORT ConnectPointsInteractor : public Interactor
- {
- public:
- mitkClassMacro(ConnectPointsInteractor, Interactor);
- mitkNewMacro3Param(Self, const char*, DataNode*, int);
- mitkNewMacro2Param(Self, const char*, DataNode*);
-
- //##Documentation
- //## @brief Sets the amount of precision
- void SetPrecision( unsigned int precision );
-
- //##Documentation
- //## @brief calculates how good the data, this statemachine handles, is hit by the event.
- //##
- //## overwritten, cause we don't look at the boundingbox, we look at each point
- virtual float CanHandleEvent(StateEvent const* stateEvent) const;
-
-
- protected:
- //##Documentation
- //##@brief Constructor with Param n for limited Set of Points
- //##
- //## if no n is set, then the number of points is unlimited*
- ConnectPointsInteractor(const char * type, DataNode* dataNode, int n = -1);
-
- virtual ~ConnectPointsInteractor();
-
- virtual bool ExecuteAction( Action* action, mitk::StateEvent const* stateEvent );
-
- //##Documentation
- //## @brief deselects the Points in the PointSet.
- //## supports Undo if enabled
- void UnselectAll();
-
- //##Documentation
- //## @brief Selects the point.
- //## supports Undo if enabled.
- //## @param position is the index of the point that has to be selected
- void SelectPoint( int position );
-
- private:
-
- //##Documentation
- //## @brief the number of possible points in this object
- //##
- //## if -1, then no limit set
- int m_N;
-
- //##Documentation
- //## @brief stores the current CellId this Statemachine works in
- unsigned int m_CurrentCellId;
-
- //##Documentation
- //## @brief to calculate a direction vector from last point and actual point
- Point3D m_LastPoint;
-
- //##Documentation
- //## @brief summ-vector for Movement
- Vector3D m_SumVec;
-
- //##Documentation
- //## @brief to store the value of precision to pick a point
- unsigned int m_Precision;
- };
-}
-#endif /* MITKCONNECTPOINTSINTERACTOR_H_HEADER_INCLUDED_C11202FF */
diff --git a/Modules/Ext/Interactions/mitkDisplayPointSetInteractor.cpp b/Modules/Ext/Interactions/mitkDisplayPointSetInteractor.cpp
deleted file mode 100644
index 9945b641c9..0000000000
--- a/Modules/Ext/Interactions/mitkDisplayPointSetInteractor.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkDisplayPointSetInteractor.h"
-#include "mitkInteractionConst.h"
-#include "mitkStateEvent.h"
-#include "mitkBaseRenderer.h"
-#include "mitkNumericTypes.h"
-
-
-
-mitk::DisplayPointSetInteractor
-::DisplayPointSetInteractor(const char * type, DataNode* dataNode, int n)
-:PointSetInteractor(type, dataNode, n)
-{
-
-
-}
-
-mitk::DisplayPointSetInteractor::~DisplayPointSetInteractor()
-{
-}
-
-
-bool mitk::DisplayPointSetInteractor
-::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
-{
- bool ok = false;//for return type bool
-
- //get the timestep to also support 3D+T
- //const mitk::Event *theEvent = stateEvent->GetEvent();
-
- /*Each case must watch the type of the event!*/
- /*Each time a Point is added or removed or finished moved, the display-coordinates and the last renderer is stored.*/
- switch (action->GetActionId())
- {
- case AcADDPOINT:
- {
- mitk::DisplayPositionEvent const *posEvent =
- dynamic_cast < const mitk::DisplayPositionEvent * >
- (stateEvent->GetEvent());
- if ( posEvent == NULL )
- {
- return false;
- }
-
- m_LastDisplayCoordinates = posEvent->GetDisplayPosition();
- m_LastRenderer = posEvent->GetSender();
-
-
- ok = Superclass::ExecuteAction( action, stateEvent );
- break;
- }
- case AcREMOVEPOINT://remove the given Point from the list
- {
- mitk::DisplayPositionEvent const *posEvent =
- dynamic_cast < const mitk::DisplayPositionEvent * >
- (stateEvent->GetEvent());
- if ( posEvent == NULL )
- {
- return false;
- }
-
- m_LastDisplayCoordinates = posEvent->GetDisplayPosition();
- m_LastRenderer = posEvent->GetSender();
-
-
- ok = Superclass::ExecuteAction( action, stateEvent );
- break;
- }
- case AcREMOVEALL:
- {
- mitk::DisplayPositionEvent const *posEvent =
- dynamic_cast < const mitk::DisplayPositionEvent * >
- (stateEvent->GetEvent());
- if ( posEvent == NULL )
- {
- return false;
- }
-
- m_LastDisplayCoordinates = posEvent->GetDisplayPosition();
- m_LastRenderer = posEvent->GetSender();
-
-
- ok = Superclass::ExecuteAction( action, stateEvent );
- break;
- }
- case AcFINISHMOVEMENT:
- {
- mitk::DisplayPositionEvent const *posEvent =
- dynamic_cast < const mitk::DisplayPositionEvent * >
- (stateEvent->GetEvent());
- if ( posEvent == NULL )
- {
- return false;
- }
-
- m_LastDisplayCoordinates = posEvent->GetDisplayPosition();
- m_LastRenderer = posEvent->GetSender();
-
-
- ok = Superclass::ExecuteAction( action, stateEvent );
- break;
- }
-
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- }
-
- return ok;
-}
-
-mitk::Point2D mitk::DisplayPointSetInteractor::GetLastDisplayCoordinates()
-{
- return m_LastDisplayCoordinates;
-}
-
-mitk::BaseRenderer* mitk::DisplayPointSetInteractor::GetLastRenderer()
-{
- return m_LastRenderer;
-}
diff --git a/Modules/Ext/Interactions/mitkDisplayPointSetInteractor.h b/Modules/Ext/Interactions/mitkDisplayPointSetInteractor.h
deleted file mode 100644
index 21974293ad..0000000000
--- a/Modules/Ext/Interactions/mitkDisplayPointSetInteractor.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKDISPLAYPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF
-#define MITKDISPLAYPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkNumericTypes.h"
-#include <mitkInteractor.h>
-#include "mitkPointSetInteractor.h"
-#include <mitkBaseRenderer.h>
-
-namespace mitk
-{
- class DataNode;
-
- /**
- * \brief Interaction with a set of points.
- *
- * Points can be added, removed and moved.
- * \ingroup Interaction
- */
-
- /**
- * \deprecatedSince{2014_03} mitk::DisplayPointSetInteractor is deprecated. Needs to be updated to the new interaction-framework.
- * Refer to \see DataInteractionPage for general information about the concept of the new implementation.
- */
-
- class DEPRECATED() MitkExt_EXPORT DisplayPointSetInteractor : public PointSetInteractor
- {
- public:
- mitkClassMacro(DisplayPointSetInteractor, PointSetInteractor);
- mitkNewMacro3Param(Self, const char*, DataNode*, int);
- mitkNewMacro2Param(Self, const char*, DataNode*);
-
- Point2D GetLastDisplayCoordinates();
-
- BaseRenderer* GetLastRenderer();
-
-
- protected:
- /**
- * \brief Constructor with Param n for limited Set of Points
- *
- * if no n is set, then the number of points is unlimited*
- */
- DisplayPointSetInteractor(const char * type,
- DataNode* dataNode, int n = -1);
-
- /**
- * \brief Default Destructor
- **/
- virtual ~DisplayPointSetInteractor();
-
- virtual bool ExecuteAction( Action* action,
- mitk::StateEvent const* stateEvent );
-
- /** \brief last display-coordinates of the point
- *
- */
- Point2D m_LastDisplayCoordinates;
-
-
- mitk::BaseRenderer* m_LastRenderer;
-
-
- };
-}
-#endif /* MITKDisplayPointSetInteractor_H_HEADER_INCLUDED_C11202FF */
diff --git a/Modules/Ext/Interactions/mitkEventAndActionConstants.xml b/Modules/Ext/Interactions/mitkEventAndActionConstants.xml
deleted file mode 100644
index 69c850a546..0000000000
--- a/Modules/Ext/Interactions/mitkEventAndActionConstants.xml
+++ /dev/null
@@ -1,369 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<mitkInteraktionEvents>
- <events>
- <eventCategory NAME="NullEvent">
- <event NAME="EIDNULLEVENT" ID="0" />
- </eventCategory>
- <eventCategory NAME="TDMouseEvents">
- <event NAME="EIDTDMOUSEINPUT" ID="4001" />
- </eventCategory>
- <eventCategory NAME="MouseEvents">
- <event NAME="EIDLEFTMOUSEBTN" ID="1" />
- <event NAME="EIDRIGHTMOUSEBTN" ID="2" />
- <event NAME="EIDLEFTMOUSEBTNANDSHIFT" ID="3" />
- <event NAME="EIDMIDDLEMOUSEBTN" ID="4" />
- <event NAME="EIDLEFTMOUSEBTNANDCTRL" ID="5" />
- <event NAME="EIDMIDDLEMOUSEBTNANDCTRL" ID="6" />
- <event NAME="EIDRIGHTMOUSEBTNANDCTRL" ID="7" />
- <event NAME="EIDLEFTMOUSERELEASE" ID="505" />
- <event NAME="EIDMIDDLEMOUSERELEASE" ID="506" />
- <event NAME="EIDRIGHTMOUSERELEASE" ID="507" />
- <event NAME="EIDLEFTMOUSERELEASEANDSHIFT" ID="508" />
- <event NAME="EIDMOUSEMOVE" ID="520" />
- <event NAME="EIDLEFTMOUSEBTNANDMOUSEMOVE" ID="530" />
- <event NAME="EIDRIGHTMOUSEBTNANDMOUSEMOVE" ID="531" />
- <event NAME="EIDMIDDLEMOUSEBTNANDMOUSEMOVE" ID="533" />
- <event NAME="EIDCTRLANDLEFTMOUSEBTNANDMOUSEMOVE" ID="534" />
- <event NAME="EIDCTRLANDRIGHTMOUSEBTNANDMOUSEMOVE" ID="535" />
- <event NAME="EIDCTRLANDMIDDLEMOUSEBTNANDMOUSEMOVE" ID="536" />
- <event NAME="EIDCTRLANDLEFTMOUSEBTNRELEASE" ID="537" />
- <event NAME="EIDCTRLANDRIGHTMOUSEBTNRELEASE" ID="538" />
- <event NAME="EIDCTRLANDMIDDLEMOUSEBTNRELEASE" ID="539" />
- <event NAME="EIDSHIFTANDCTRLANDMIDDLEMOUSEBTN" ID="540" />
- <event NAME="EIDSHIFTANDLEFTMOUSEBTNANDMOUSEMOVE" ID="541" />
- <event NAME="EIDSHIFTANDCTRLANDMOUSEMOVE" ID="542" />
- <event NAME="EIDSHIFTANDCTRLANDMOUSERELEASE" ID="543" />
- <event NAME="EIDALTANDLEFTMOUSEBTN" ID="600" />
- <event NAME="EIDALTANDLEFTMOUSEBTNANDMOUSEMOVE" ID="610" />
- <event NAME="EIDALTANDLEFTMOUSERELEASE" ID="620" />
- <event NAME="EIDSHIFTANDRIGHTMOUSEPRESS" ID="2000" />
- <event NAME="EIDSHIFTANDRIGHTMOUSEMOVE" ID="2001" />
- <event NAME="EIDSHIFTANDRIGHTMOUSERELEASE" ID="2002" />
- <event NAME="EIDSHIFTANDMIDDLEMOUSEPRESS" ID="2003" />
- <event NAME="EIDSHIFTANDMIDDLEMOUSEMOVE" ID="2004" />
- <event NAME="EIDSHIFTANDMIDDLEMOUSERELEASE" ID="2005" />
- </eventCategory>
- <eventCategory NAME="NoMouseEvents">
- <event NAME="EIDSTRGANDN" ID="10" />
- <event NAME="EIDSTRGANDE" ID="11" />
- <event NAME="EIDDELETE" ID="12" />
- <event NAME="EIDN" ID="13" />
- <event NAME="EIDESCAPE" ID="14" />
- <event NAME="EIDP" ID="15" />
- <event NAME="EIDR" ID="16" />
- <event NAME="EIDT" ID="17" />
- <event NAME="EIDS" ID="18" />
- <event NAME="EIDE" ID="19" />
- <event NAME="EIDSTRGANDALTANDA" ID="20" />
- <event NAME="EIDSTRGANDALTANDB" ID="21" />
- <event NAME="EIDH" ID="22" />
- <event NAME="EIDRETURN" ID="23" />
- <event NAME="EIDENTER" ID="24" />
- <event NAME="EIDSPACE" ID="25" />
- <event NAME="EIDSTRGANDALTANDH" ID="30" />
- <event NAME="EIDSTRGANDALTANDI" ID="31" />
- <event NAME="EIDSTRGANDALTANDS" ID="40" />
- <event NAME="EIDALT" ID="90" />
- <event NAME="EIDSTRGANDB" ID="91" />
- </eventCategory>
- <eventCategory NAME="own thrown events">
- <event NAME="EIDNEW" ID="1000" />
- <event NAME="EIDOLD" ID="1001" />
- <event NAME="EIDFINISHED" ID="1002" />
- <event NAME="EIDNO" ID="1003" />
- <event NAME="EIDYES" ID="1004" />
- <event NAME="EIDSAME" ID="1005" />
- <event NAME="EIDNOANDLASTOBJECT" ID="1006" />
- <event NAME="EIDNOANDNOTLASTOBJECT" ID="1007" />
- <event NAME="EIDLAST" ID="1008" />
- <event NAME="EIDNOTLAST" ID="1009" />
- <event NAME="EIDSTSMALERNMINUS1" ID="1010" />
- <event NAME="EIDSTLARGERNMINUS1" ID="1011" />
- <event NAME="EIDPOSITIONEVENT" ID="1012" />
- <event NAME="EIDEDIT" ID="1013" />
- <event NAME="EIDSMALLERN" ID="1014" />
- <event NAME="EIDEQUALSN" ID="1015" />
- <event NAME="EIDLARGERN" ID="1016" />
- <event NAME="EIDSUBDESELECT" ID="1020" />
- <event NAME="EIDSMTOSELECTED" ID="1030" />
- <event NAME="EIDSMTODESELECTED" ID="1031" />
- <event NAME="EIDTIP" ID="1050" />
- <event NAME="EIDHEAD" ID="1051" />
- <event NAME="EIDBODY" ID="1052" />
- </eventCategory>
- <eventCategory NAME="external thrown events">
- <event NAME="EIDCLEAR" ID="1100" />
- <event NAME="EIDACTIVATETOOL" ID="1300" />
- </eventCategory>
- <eventCategory NAME="Puncture Application">
- <event NAME="EIDPRINT" ID="3001" />
- </eventCategory>
- <eventCategory NAME="AriadneEvents">
- <event NAME="EV_INIT" ID="5551001" />
- <event NAME="EV_PREVIOUS" ID="5551002" />
- <event NAME="EV_PATH_COLLECTION_SELECTED" ID="5551003" />
- <event NAME="EV_NAVIGATION_SELECTED" ID="5551004" />
- <event NAME="EV_LESS_THEN_MIN_COUNT" ID="5551005" />
- <event NAME="EV_READY" ID="5551006" />
- <event NAME="EV_NEXT" ID="5551007" />
- <event NAME="EV_DONE" ID="5551008" />
- <event NAME="EV_NEW_LANDMARK" ID="5551009" />
- <event NAME="EV_REMOVE_LANDMARK" ID="5551010" />
- </eventCategory>
- <eventCategory NAME="FiberBundles">
- <event NAME="EIDFIGUREHOVER" ID="12340" />
- <event NAME="EIDNOFIGUREHOVER" ID="12341" />
- </eventCategory>
- </events>
- <actions>
- <actionCategory NAME="DoNothing">
- <action NAME="AcDONOTHING" ID="0" />
- </actionCategory>
- <actionCategory NAME="Init">
- <action NAME="AcINITNEWOBJECT" ID="5" />
- <action NAME="AcINITEDITOBJECT" ID="6" />
- <action NAME="AcINITEDITGROUP" ID="7" />
- <action NAME="AcINITMOVEMENT" ID="8" />
- <action NAME="AcINITMOVE" ID="9" />
- <action NAME="AcINITFOREGROUND" ID="45">
- <!--used in SeedsInteractor for setting the foreground seeds-->
- </action>
- <action NAME="AcINITBACKGROUND" ID="46">
- <!--used in SeedsInteractor for setting the background seeds-->
- </action>
- <action NAME="AcINITNEUTRAL" ID="47">
- <!--used in SeedsInteractor for setting the neutral seeds (rubber)-->
- </action>
- <action NAME="AcINITUPDATE" ID="1235">
- <!--For shape model deformation-->
- </action>
- </actionCategory>
- <actionCategory NAME="Add">
- <action NAME="AcADDPOINT" ID="10" />
- <action NAME="AcADD" ID="11" />
- <action NAME="AcADDLINE" ID="12" />
- <action NAME="AcADDANDFINISH" ID="13" />
- <action NAME="AcADDSELECTEDTOGROUP" ID="64" />
- </actionCategory>
- <actionCategory NAME="Check">
- <action NAME="AcCHECKPOINT" ID="21" />
- <action NAME="AcCHECKLINE" ID="22" />
- <action NAME="AcCHECKCELL" ID="23" />
- <action NAME="AcCHECKELEMENT" ID="30">
- <!--check if there is a element close enough (picking)-->
- </action>
- <action NAME="AcCHECKOBJECT" ID="31">
- <!--check if an object is hit-->
- </action>
- <action NAME="AcCHECKNMINUS1" ID="32">
- <!--check if the number of elements is equal to N-1-->
- </action>
- <action NAME="AcCHECKEQUALS1" ID="33">
- <!--check if the number of elements in the data is equal to 1-->
- </action>
- <action NAME="AcCHECKNUMBEROFPOINTS" ID="330">
- <!--check the number of elements in the data-->
- </action>
- <action NAME="AcCHECKSELECTED" ID="34">
- <!--check if the given element is selected or not-->
- </action>
- <action NAME="AcCHECKONESELECTED" ID="340">
- <!--check if there is an element that is selected-->
- </action>
- <action NAME="AcCHECKGREATERZERO" ID="35">
- <!--check if the current number of elements is greater than 0-->
- </action>
- <action NAME="AcCHECKGREATERTWO" ID="36">
- <!--check if the current number of elements is greater than two-->
- </action>
- <action NAME="AcCHECKOPERATION" ID="37">
- <!--check if the operation is of one spectial type-->
- </action>
- <action NAME="AcCHECKONESUBINTERACTOR" ID="38" />
- <action NAME="AcCHECKSUBINTERACTORS" ID="39" />
- </actionCategory>
- <actionCategory NAME="Finish">
- <action NAME="AcFINISHOBJECT" ID="40" />
- <action NAME="AcFINISHGROUP" ID="41" />
- <action NAME="AcFINISHMOVEMENT" ID="42" />
- <action NAME="AcFINISHMOVE" ID="43" />
- <action NAME="AcFINISH" ID="44" />
- </actionCategory>
- <actionCategory NAME="Search">
- <action NAME="AcSEARCHOBJECT" ID="50" />
- <action NAME="AcSEARCHGROUP" ID="51" />
- <action NAME="AcSEARCHANOTHEROBJECT" ID="52">
- <!--one object is selected and another object is to be added to selection-->
- </action>
- </actionCategory>
- <actionCategory NAME="Select">
- <action NAME="AcSELECTPICKEDOBJECT" ID="60">
- <!--select the picked object and deselect others-->
- </action>
- <action NAME="AcSELECTANOTHEROBJECT" ID="61" />
- <action NAME="AcSELECTGROUP" ID="62" />
- <action NAME="AcSELECTALL" ID="63" />
- <action NAME="AcSELECT" ID="65" />
- <action NAME="AcSELECTPOINT" ID="66" />
- <action NAME="AcSELECTLINE" ID="68" />
- <action NAME="AcSELECTCELL" ID="67" />
- <action NAME="AcSELECTSUBOBJECT" ID="69">
- <!--used in VesselGraphInteractor-->
- </action>
- </actionCategory>
- <actionCategory NAME="Deselect">
- <action NAME="AcDESELECTOBJECT" ID="70">
- <!--deselect picked from group-->
- </action>
- <action NAME="AcDESELECTALL" ID="72" />
- <action NAME="AcDESELECT" ID="75" />
- <action NAME="AcDESELECTPOINT" ID="76" />
- <action NAME="AcDESELECTLINE" ID="78" />
- <action NAME="AcDESELECTCELL" ID="77" />
- </actionCategory>
- <actionCategory NAME="New">
- <action NAME="AcNEWPOINT" ID="80" />
- <action NAME="AcNEWSUBOBJECT" ID="81" />
- </actionCategory>
- <actionCategory NAME="Move">
- <action NAME="AcMOVEPOINT" ID="90" />
- <action NAME="AcMOVESELECTED" ID="91" />
- <action NAME="AcMOVE" ID="92" />
- </actionCategory>
- <actionCategory NAME="Remove">
- <action NAME="AcREMOVEPOINT" ID="100" />
- <action NAME="AcREMOVE" ID="101" />
- <action NAME="AcREMOVELINE" ID="102" />
- <action NAME="AcREMOVEALL" ID="103" />
- <action NAME="AcREMOVESELECTEDSUBOBJECT" ID="104">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcDELETEPOINT" ID="120" />
- <action NAME="AcCLEAR" ID="130">
- <!--clear all elements from a list-->
- </action>
- </actionCategory>
- <actionCategory NAME="Insert">
- <action NAME="AcINSERTPOINT" ID="110" />
- <action NAME="AcINSERTLINE" ID="111" />
- </actionCategory>
- <actionCategory NAME="AriadneActions">
- <action NAME="AC_SET_NEXT_BUTTON_VISIBLE" ID="5550001" />
- <action NAME="AC_SET_NEXT_BUTTON_INVISIBLE" ID="5550002" />
- <action NAME="AC_SET_PREVIOUS_BUTTON_VISIBLE" ID="5550003" />
- <action NAME="AC_SET_PREVIOUS_BUTTON_INVISIBLE" ID="5550004" />
- <action NAME="AC_SET_ASSISTAND_WIDGET_STECK" ID="5550005" />
- <action NAME="AC_SETMAX_COUNT_REF_POINTS" ID="5550006" />
- <action NAME="AC_SET_NEXT_BUTTON_TEXT" ID="5550007" />
- <action NAME="AC_CHECK_LANDMARK_COUNT" ID="5550008" />
- <action NAME="AC_SET_DONE_FALSE" ID="5550009" />
- <action NAME="AC_INIT" ID="55500010" />
- <action NAME="AC_SET_APPLICATION_SELECTED_FALSE" ID="55500011" />
- <action NAME="AC_SENSOR_ATTACHED" ID="55500012" />
- <action NAME="AC_CLOSE_ASSISTENT" ID="55500013" />
- <action NAME="AC_START_APPLICATION_TEXT" ID="55500014" />
- <action NAME="AC_START_NAVIGATION" ID="55500015" />
- <action NAME="AC_START_PATHCOLLECTION" ID="55500016" />
- <action NAME="AC_LOAD_LANDMARKS" ID="55500017" />
- <action NAME="AC_CALCULATE_LANDMARK_TRANSFORM" ID="55500018" />
- </actionCategory>
- <actionCategory NAME="Misc">
- <action NAME="AcTERMINATE_INTERACTION" ID="666" />
- <action NAME="AcTRANSLATESTART" ID="1000" />
- <action NAME="AcTRANSLATE" ID="1001" />
- <action NAME="AcSCALESTART" ID="1002" />
- <action NAME="AcSCALE" ID="1003" />
- <action NAME="AcROTATESTART" ID="1004" />
- <action NAME="AcROTATE" ID="1005" />
- <action NAME="AcINITAFFINEINTERACTIONS" ID="1006" />
- <action NAME="AcFINISHAFFINEINTERACTIONS" ID="1007" />
- <action NAME="AcTRANSLATEEND" ID="1008" />
- <action NAME="AcSCALEEND" ID="1009" />
- <action NAME="AcROTATEEND" ID="1010" />
- <action NAME="AcINITZOOM" ID="1011" />
- <action NAME="AcZOOM" ID="1012" />
- <action NAME="AcSETSTARTPOINT" ID="1050" />
- <action NAME="AcMODEDESELECT" ID="1100">
- <!--set interactor in not selected mode-->
- </action>
- <action NAME="AcMODESELECT" ID="1101">
- <!--set interactor in selected mode-->
- </action>
- <action NAME="AcMODESUBSELECT" ID="1102">
- <!--set interacor in sub selected mode-->
- </action>
- <action NAME="AcINFORMLISTENERS" ID="1200">
- <!--GlobalInteraction-->
- </action>
- <action NAME="AcASKINTERACTORS" ID="1201">
- <!--GlobalInteraction-->
- </action>
- <action NAME="AcCHECKGREATERONE" ID="1500" />
- <action NAME="AcCHECKBOUNDINGBOX" ID="1510" />
- <action NAME="AcFORCESUBINTERACTORS" ID="1550" />
- <action NAME="AcSENDCOORDINATES" ID="1600" />
- <action NAME="AcTRANSMITEVENT" ID="2000">
- <!--to transmit an event to a lower Interactor/Statemachine-->
- </action>
- <action NAME="AcPERIPHERYSEARCH" ID="3000">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcROOTSEARCH" ID="3001">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcTHICKSTVESSELSEARCH" ID="3002">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcSHORTESTPATHSEARCH" ID="3003">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcSINGLE" ID="3004">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcATTRIBUTATION" ID="3005">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcDEFAULT" ID="3007">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcSETVESSELELEMENT" ID="3008">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcCHECKBARRIERSTATUS" ID="3010">
- <!--used in VesselGraphInteractor-->
- </action>
- <action NAME="AcUPDATEMESH" ID="1234">
- <!--For Shape Model Interaction-->
- </action>
- <action NAME="AcINCREASE" ID="49012" />
- <action NAME="AcDECREASE" ID="49013" />
- <action NAME="AcMODIFY" ID="49014" />
- <action NAME="AcUNDOUPDATE" ID="1236">
- <!--For restoring a mesh after an update-->
- </action>
- <action NAME="AcONTDMOUSEINPUT" ID="4002">
- </action>
- </actionCategory>
- <actionCategory NAME="SegmentationInteractor">
- <action NAME="AcENTEROBJECT" ID="48000" />
- <action NAME="AcLEAVEOBJECT" ID="48001" />
- <action NAME="AcSWITCHOBJECT" ID="48002" />
- <action NAME="AcUPDATELINE" ID="48003" />
- <action NAME="AcINITLINE" ID="48004" />
- <action NAME="AcTERMINATELINE" ID="48005" />
- <action NAME="AcCREATEBOX" ID="48006" />
- <action NAME="AcCREATEOBJECTFROMLINE" ID="48007" />
- <action NAME="AcCANCEL" ID="48008" />
- <action NAME="AcACTIVATETOOL" ID="48009" />
- <action NAME="AcROTATEAROUNDPOINT1" ID="49002" />
- <action NAME="AcROTATEAROUNDPOINT2" ID="49003" />
- <action NAME="AcMOVEPOINT1" ID="49004" />
- <action NAME="AcMOVEPOINT2" ID="49005" />
- <action NAME="AcUPDATEPOINT" ID="49006" />
- <action NAME="AcDISPLAYOPTIONS" ID="49009" />
- <action NAME="AcCYCLE" ID="49010" />
- <action NAME="AcACCEPT" ID="49011" />
- </actionCategory>
- </actions>
-</mitkInteraktionEvents>
-
diff --git a/Modules/Ext/Interactions/mitkEventAndActionConstants.xsl b/Modules/Ext/Interactions/mitkEventAndActionConstants.xsl
deleted file mode 100644
index 1baabec256..0000000000
--- a/Modules/Ext/Interactions/mitkEventAndActionConstants.xsl
+++ /dev/null
@@ -1,516 +0,0 @@
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
- <xsl:output method="text" indent="yes"/>
-<xsl:template match="/">
-<xsl:text disable-output-escaping = "yes">/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKINTERACTCONST_H
-#define MITKINTERACTCONST_H
-
-//##Documentation
-//## @file mitkInteractionConst.h
-//## @brief Constants for most interaction classes, due to the generic StateMachines.
-//##
-//## Changes in Type, ButtonState or Key has to be don in mitkEventMapper.cpp, too.
-//## @ingroup Interaction
-
-/*Prefixes for Constants:
-E = Enumeration
-EID = EventId's
-Op = Operations
-Ac = Action
-Type_ = Type of Event
-BS_ = ButtonStates and Buttons
-Key_ = Keys like in QT
-*/
-namespace mitk{
-
-/*
-//UndoMechanism:
-//constants for UndoMechanism;
-*/
-//different UndoModels:
-typedef enum EUndoModels{LIMITEDLINEARUNDO=10, VERBOSE_LIMITEDLINEARUNDO=11, TREEUNDO=20};
-
-//Constants for EventIds; use the according constant to through an event in the code
-typedef enum EEventIds
-{
-</xsl:text>
-
-<xsl:for-each select="//event">
-<xsl:text> </xsl:text>
-<xsl:value-of select="@NAME"/>
-<xsl:text> = </xsl:text>
-<xsl:value-of select="@ID"/>
-<xsl:if test="position()!=last()">
-<xsl:text>,</xsl:text>
-</xsl:if>
-<xsl:if test="boolean(./comment())">
-<xsl:text> // </xsl:text>
-<xsl:value-of select="./comment()"/>
-</xsl:if>
-<xsl:text disable-output-escaping = "yes">
-</xsl:text>
-</xsl:for-each>
-<xsl:text disable-output-escaping = "yes">
-
-};
-
-//##Constants for Operations
-//## xomments are always examples of the usage
-typedef enum EOperations
-{
- OpNOTHING = 0,
- OpTEST = 1,
- OpNEWCELL = 10, //add a new cell
- OpADD = 100, //add a point or a vessel
- OpUNDOADD = 101,
- OpADDLINE = 1001, //add a line
- OpINSERT = 200, //insert a point at position
- OpINSERTLINE = 201, //insert a line at position
- OpINSERTPOINT = 202,
- OpCLOSECELL = 250, //close a cell (to a polygon)
- OpOPENCELL = 251, //close a cell (to a polygon)
- OpMOVE = 300, //move a point
- OpMOVELINE = 301, //move a line
- OpMOVECELL = 302, //move a line
- OpUNDOMOVE = 303,
- OpREMOVE = 400, //remove a point at position
- OpREMOVELINE = 401, //remove a line at position
- OpREMOVECELL = 402, //remove a cell
- OpREMOVEPOINT = 403,
- OpDELETE = 500, //delete
- OpDELETELINE = 501, //delete the last line in a cell
- OpUNDELETE = 502,
- OpDELETECELL = 505,
- OpSTATECHANGE = 600, //change a state
- OpTERMINATE = 666, //change a state
- OpSELECTPOINT = 700,
- OpSELECTLINE = 701,
- OpSELECTCELL = 702,
- OpSELECTSUBOBJECT = 703, //for VesselGraphInteractor
- //OpSELECTNEWSUBOBJECT = 704, //for VesselGraphInteractor
- OpSELECT = 705,
- OpDESELECTPOINT = 800,
- OpDESELECTLINE = 801,
- OpDESELECTCELL = 802,
- OpDESELECTSUBOBJECT = 803, //for VesselGraphInteractor
- OpDESELECTALL = 804, //for VesselGraphInteractor
- OpDESELECT = 805,
- OpNAVIGATE = 900,
- OpZOOM = 1000,
- OpSCALE = 1100,
- OpROTATE = 1200,
- OpSETPOINTTYPE = 1210,
- OpMODECHANGE = 1500,
- OpSENDCOORDINATES = 1600,
- OpPERIPHERYSEARCH = 2000, //used in VesselGraphInteractor
- OpROOTSEARCH = 2001, //used in VesselGraphInteractor
- OpTHICKSTVESSELSEARCH = 2002, //used in VesselGraphInteractor
- OpSHORTESTPATHSEARCH = 2003, //used in VesselGraphInteractor
- OpATTRIBUTATION = 2004, //used in VesselGraphInteractor
- OpDEFAULT = 2006, //used in VesselGraphInteractor
-};
-
-//##Constants for EventMapping...
-//##connects the statemachine.xml-File with the implemented conditions.
-//##within one statemachine the choice of the actionconstants is freely
-//##
-//## ActionId
-typedef enum EActions
-{
-</xsl:text>
-
-
-<xsl:for-each select="//action">
-<xsl:text> </xsl:text>
-<xsl:value-of select="@NAME"/>
-<xsl:text> = </xsl:text>
-<xsl:value-of select="@ID"/>
-<xsl:if test="position()!=last()">
-<xsl:text>,</xsl:text>
-</xsl:if>
-<xsl:if test="boolean(./comment())">
-<xsl:text> // </xsl:text>
-<xsl:value-of select="./comment()"/>
-</xsl:if>
-<xsl:text disable-output-escaping = "yes">
-</xsl:text>
-</xsl:for-each>
-<xsl:text disable-output-escaping = "yes">
-
-};
-
-
-/*
-//!!!!!!!!!!!!!!!!!!!!!!!!
-//!!!!!!!!!!!!!!!!!!!!!!!!
-//EventMechanism:
-//If you change anything from here on, then change in mitkEventMapper.cpp (Array of constants) as well.
-//!!!!!!!!!!!!!!!!!!!!!!!!
-//!!!!!!!!!!!!!!!!!!!!!!!!
-*/
-
-//Type of an Event;
-typedef enum EEventType
-{
- Type_None = 0, // invalid event
- Type_Timer = 1, // timer event
- Type_MouseButtonPress = 2, // mouse button pressed
- Type_MouseButtonRelease = 3, // mouse button released
- Type_MouseButtonDblClick = 4, // mouse button double click
- Type_MouseMove = 5, // mouse move
- Type_KeyPress = 6, // key pressed
- Type_KeyRelease = 7, // key released
- Type_FocusIn = 8, // keyboard focus received
- Type_FocusOut = 9, // keyboard focus lost
- Type_Enter = 10, // mouse enters widget
- Type_Leave = 11, // mouse leaves widget
- Type_Paint = 12, // paint widget
- Type_Move = 13, // move widget
- Type_Resize = 14, // resize widget
- Type_Create = 15, // after object creation
- Type_Destroy = 16, // during object destruction
- Type_Show = 17, // widget is shown
- Type_Hide = 18, // widget is hidden
- Type_Close = 19, // request to close widget
- Type_Quit = 20, // request to quit application
- Type_Reparent = 21, // widget has been reparented
- Type_ShowMinimized = 22, // widget is shown minimized
- Type_ShowNormal = 23, // widget is shown normal
- Type_WindowActivate = 24, // window was activated
- Type_WindowDeactivate = 25, // window was deactivated
- Type_ShowToParent = 26, // widget is shown to parent
- Type_HideToParent = 27, // widget is hidden to parent
- Type_ShowMaximized = 28, // widget is shown maximized
- Type_ShowFullScreen = 29, // widget is shown full-screen
- Type_Accel = 30, // accelerator event
- Type_Wheel = 31, // wheel event
- Type_AccelAvailable = 32, // accelerator available event
- Type_CaptionChange = 33, // caption changed
- Type_IconChange = 34, // icon changed
- Type_ParentFontChange = 35, // parent font changed
- Type_ApplicationFontChange = 36, // application font changed
- Type_ParentPaletteChange = 37, // parent palette changed
- Type_ApplicationPaletteChange = 38, // application palette changed
- Type_PaletteChange = 39, // widget palette changed
- Type_Clipboard = 40, // internal clipboard event
- Type_Speech = 42, // reserved for speech input
- Type_SockAct = 50, // socket activation
- Type_AccelOverride = 51, // accelerator override event
- Type_DeferredDelete = 52, // deferred delete event
- Type_DragEnter = 60, // drag moves into widget
- Type_DragMove = 61, // drag moves in widget
- Type_DragLeave = 62, // drag leaves or is cancelled
- Type_Drop = 63, // actual drop
- Type_DragResponse = 64, // drag accepted/rejected
- Type_ChildInserted = 70, // new child widget
- Type_ChildRemoved = 71, // deleted child widget
- Type_LayoutHint = 72, // child min/max size changed
- Type_ShowWindowRequest = 73, // widget's window should be mapped
- Type_ActivateControl = 80, // ActiveX activation
- Type_DeactivateControl = 81, // ActiveX deactivation
- Type_ContextMenu = 82, // context popup menu
- Type_IMStart = 83, // input method composition start
- Type_IMCompose = 84, // input method composition
- Type_IMEnd = 85, // input method composition end
- Type_Accessibility = 86, // accessibility information is requested
- Type_TabletMove = 87, // Wacom tablet event
- Type_LocaleChange = 88, // the system locale changed
- Type_LanguageChange = 89, // the application language changed
- Type_LayoutDirectionChange = 90, // the layout direction changed
- Type_Style = 91, // internal style event
- Type_TabletPress = 92, // tablet press
- Type_TabletRelease = 93, // tablet release
- Type_User = 1000, // first user event id
- Type_MaxUser = 65535
-};
-
-
-//##ButtonState
-// mouse/keyboard state values
-//QT combinations if MOUSEBUTTONRelease: left MouseButton + ControlButton: 0x201
-typedef enum EButtonStates
-{
- BS_NoButton = 0x0000,
- BS_LeftButton = 0x0001,
- BS_RightButton = 0x0002,
- BS_MidButton = 0x0004,
- BS_MouseButtonMask = 0x0007,
- BS_ShiftButton = 0x0100,
- BS_ControlButton = 0x0200,
- BS_AltButton = 0x0400,
- BS_MetaButton = 0x0800,
- BS_KeyButtonMask = 0x0f00,
- BS_Keypad = 0x4000
-};
-//##Key
-typedef enum EKeys
-{
- Key_Escape = 0x1000, // misc keys
- Key_Tab = 0x1001,
- Key_Backtab = 0x1002,
- Key_BackTab = 0x1002, //= Key_Backtab
- Key_Backspace = 0x1003,
- Key_BackSpace = 0x1003, //= Key_Backspace
- Key_Return = 0x1004,
- Key_Enter = 0x1005,
- Key_Insert = 0x1006,
- Key_Delete = 0x1007,
- Key_Pause = 0x1008,
- Key_Print = 0x1009,
- Key_SysReq = 0x100a,
- Key_Home = 0x1010, // cursor movement
- Key_End = 0x1011,
- Key_Left = 0x1012,
- Key_Up = 0x1013,
- Key_Right = 0x1014,
- Key_Down = 0x1015,
- Key_Prior = 0x1016,
- Key_PageUp = 0x1016, //=Key_Prior
- Key_Next = 0x1017,
- Key_PageDown = 0x1017, //=Key_Next
- Key_Shift = 0x1020, // modifiers
- Key_Control = 0x1021,
- Key_Meta = 0x1022,
- Key_Alt = 0x1023,
- Key_CapsLock = 0x1024,
- Key_NumLock = 0x1025,
- Key_ScrollLock = 0x1026,
- Key_F1 = 0x1030, // function keys
- Key_F2 = 0x1031,
- Key_F3 = 0x1032,
- Key_F4 = 0x1033,
- Key_F5 = 0x1034,
- Key_F6 = 0x1035,
- Key_F7 = 0x1036,
- Key_F8 = 0x1037,
- Key_F9 = 0x1038,
- Key_F10 = 0x1039,
- Key_F11 = 0x103a,
- Key_F12 = 0x103b,
- Key_F13 = 0x103c,
- Key_F14 = 0x103d,
- Key_F15 = 0x103e,
- Key_F16 = 0x103f,
- Key_F17 = 0x1040,
- Key_F18 = 0x1041,
- Key_F19 = 0x1042,
- Key_F20 = 0x1043,
- Key_F21 = 0x1044,
- Key_F22 = 0x1045,
- Key_F23 = 0x1046,
- Key_F24 = 0x1047,
- Key_F25 = 0x1048, // F25 .. F35 only on X11
- Key_F26 = 0x1049,
- Key_F27 = 0x104a,
- Key_F28 = 0x104b,
- Key_F29 = 0x104c,
- Key_F30 = 0x104d,
- Key_F31 = 0x104e,
- Key_F32 = 0x104f,
- Key_F33 = 0x1050,
- Key_F34 = 0x1051,
- Key_F35 = 0x1052,
- Key_Super_L = 0x1053, // extra keys
- Key_Super_R = 0x1054,
- Key_Menu = 0x1055,
- Key_Hyper_L = 0x1056,
- Key_Hyper_R = 0x1057,
- Key_Help = 0x1058,
- // International input method support (X keycode - = 0xEE00)
- // Only interesting if you are writing your own input method
- Key_Muhenkan = 0x1122, // Cancel Conversion
- Key_Henkan = 0x1123, // Start/Stop Conversion
- Key_Hiragana_Katakana = 0x1127, // Hiragana/Katakana toggle
- Key_Zenkaku_Hankaku = 0x112A, // Zenkaku/Hankaku toggle
- Key_Space = 0x20, // 7 bit printable ASCII
- Key_Any = 0x20, //= Key_Space
- Key_Exclam = 0x21,
- Key_QuoteDbl = 0x22,
- Key_NumberSign = 0x23,
- Key_Dollar = 0x24,
- Key_Percent = 0x25,
- Key_Ampersand = 0x26,
- Key_Apostrophe = 0x27,
- Key_ParenLeft = 0x28,
- Key_ParenRight = 0x29,
- Key_Asterisk = 0x2a,
- Key_Plus = 0x2b,
- Key_Comma = 0x2c,
- Key_Minus = 0x2d,
- Key_Period = 0x2e,
- Key_Slash = 0x2f,
- Key_0 = 0x30,
- Key_1 = 0x31,
- Key_2 = 0x32,
- Key_3 = 0x33,
- Key_4 = 0x34,
- Key_5 = 0x35,
- Key_6 = 0x36,
- Key_7 = 0x37,
- Key_8 = 0x38,
- Key_9 = 0x39,
- Key_Colon = 0x3a,
- Key_Semicolon = 0x3b,
- Key_Less = 0x3c,
- Key_Equal = 0x3d,
- Key_Greater = 0x3e,
- Key_Question = 0x3f,
- Key_At = 0x40,
- Key_A = 0x41,
- Key_B = 0x42,
- Key_C = 0x43,
- Key_D = 0x44,
- Key_E = 0x45,
- Key_F = 0x46,
- Key_G = 0x47,
- Key_H = 0x48,
- Key_I = 0x49,
- Key_J = 0x4a,
- Key_K = 0x4b,
- Key_L = 0x4c,
- Key_M = 0x4d,
- Key_N = 0x4e,
- Key_O = 0x4f,
- Key_P = 0x50,
- Key_Q = 0x51,
- Key_R = 0x52,
- Key_S = 0x53,
- Key_T = 0x54,
- Key_U = 0x55,
- Key_V = 0x56,
- Key_W = 0x57,
- Key_X = 0x58,
- Key_Y = 0x59,
- Key_Z = 0x5a,
- Key_BracketLeft = 0x5b,
- Key_Backslash = 0x5c,
- Key_BracketRight = 0x5d,
- Key_AsciiCircum = 0x5e,
- Key_Underscore = 0x5f,
- Key_QuoteLeft = 0x60,
- Key_BraceLeft = 0x7b,
- Key_Bar = 0x7c,
- Key_BraceRight = 0x7d,
- Key_AsciiTilde = 0x7e,
- Key_nobreakspace = 0x0a0,
- Key_exclamdown = 0x0a1,
- Key_cent = 0x0a2,
- Key_sterling = 0x0a3,
- Key_currency = 0x0a4,
- Key_yen = 0x0a5,
- Key_brokenbar = 0x0a6,
- Key_section = 0x0a7,
- Key_diaeresis = 0x0a8,
- Key_copyright = 0x0a9,
- Key_ordfeminine = 0x0aa,
- Key_guillemotleft = 0x0ab, // left angle quotation mark
- Key_notsign = 0x0ac,
- Key_hyphen = 0x0ad,
- Key_registered = 0x0ae,
- Key_macron = 0x0af,
- Key_degree = 0x0b0,
- Key_plusminus = 0x0b1,
- Key_twosuperior = 0x0b2,
- Key_threesuperior = 0x0b3,
- Key_acute = 0x0b4,
- Key_mu = 0x0b5,
- Key_paragraph = 0x0b6,
- Key_periodcentered = 0x0b7,
- Key_cedilla = 0x0b8,
- Key_onesuperior = 0x0b9,
- Key_masculine = 0x0ba,
- Key_guillemotright = 0x0bb, // right angle quotation mark
- Key_onequarter = 0x0bc,
- Key_onehalf = 0x0bd,
- Key_threequarters = 0x0be,
- Key_questiondown = 0x0bf,
- Key_Agrave = 0x0c0,
- Key_Aacute = 0x0c1,
- Key_Acircumflex = 0x0c2,
- Key_Atilde = 0x0c3,
- Key_Adiaeresis = 0x0c4,
- Key_Aring = 0x0c5,
- Key_AE = 0x0c6,
- Key_Ccedilla = 0x0c7,
- Key_Egrave = 0x0c8,
- Key_Eacute = 0x0c9,
- Key_Ecircumflex = 0x0ca,
- Key_Ediaeresis = 0x0cb,
- Key_Igrave = 0x0cc,
- Key_Iacute = 0x0cd,
- Key_Icircumflex = 0x0ce,
- Key_Idiaeresis = 0x0cf,
- Key_ETH = 0x0d0,
- Key_Ntilde = 0x0d1,
- Key_Ograve = 0x0d2,
- Key_Oacute = 0x0d3,
- Key_Ocircumflex = 0x0d4,
- Key_Otilde = 0x0d5,
- Key_Odiaeresis = 0x0d6,
- Key_multiply = 0x0d7,
- Key_Ooblique = 0x0d8,
- Key_Ugrave = 0x0d9,
- Key_Uacute = 0x0da,
- Key_Ucircumflex = 0x0db,
- Key_Udiaeresis = 0x0dc,
- Key_Yacute = 0x0dd,
- Key_THORN = 0x0de,
- Key_ssharp = 0x0df,
- Key_agrave = 0x0e0,
- Key_aacute = 0x0e1,
- Key_acircumflex = 0x0e2,
- Key_atilde = 0x0e3,
- Key_adiaeresis = 0x0e4,
- Key_aring = 0x0e5,
- Key_ae = 0x0e6,
- Key_ccedilla = 0x0e7,
- Key_egrave = 0x0e8,
- Key_eacute = 0x0e9,
- Key_ecircumflex = 0x0ea,
- Key_ediaeresis = 0x0eb,
- Key_igrave = 0x0ec,
- Key_iacute = 0x0ed,
- Key_icircumflex = 0x0ee,
- Key_idiaeresis = 0x0ef,
- Key_eth = 0x0f0,
- Key_ntilde = 0x0f1,
- Key_ograve = 0x0f2,
- Key_oacute = 0x0f3,
- Key_ocircumflex = 0x0f4,
- Key_otilde = 0x0f5,
- Key_odiaeresis = 0x0f6,
- Key_division = 0x0f7,
- Key_oslash = 0x0f8,
- Key_ugrave = 0x0f9,
- Key_uacute = 0x0fa,
- Key_ucircumflex = 0x0fb,
- Key_udiaeresis = 0x0fc,
- Key_yacute = 0x0fd,
- Key_thorn = 0x0fe,
- Key_ydiaeresis = 0x0ff,
- Key_unknown = 0xffff,
- Key_none = 0xffff//= Key_unknown
-};
-
-}//namespace mitk
-#endif //ifndef MITKINTERACTCONST_H
-
-</xsl:text>
-</xsl:template>
-</xsl:stylesheet>
\ No newline at end of file
diff --git a/Modules/Ext/Interactions/mitkInteractionDebug.cpp b/Modules/Ext/Interactions/mitkInteractionDebug.cpp
deleted file mode 100644
index 127df13a77..0000000000
--- a/Modules/Ext/Interactions/mitkInteractionDebug.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkInteractionDebug.h"
-#include "mitkSocketClient.h"
-#include <string.h>
-
-namespace mitk {
-
- const int InteractionDebug::OPEN_CONNECTION = 1;
- const int InteractionDebug::NEW_STATE_MACHINE = 2;
- const int InteractionDebug::EVENT = 3;
- const int InteractionDebug::TRANSITION = 4;
- const int InteractionDebug::ACTION = 5;
- const int InteractionDebug::DELETE_STATE_MACHINE = 6;
-
- InteractionDebug* InteractionDebug::m_Instance = NULL;;
- char* InteractionDebug::m_FileName = NULL;
-
- /**
- *
- */
- InteractionDebug::InteractionDebug()
- {
- SocketClient::GetInstance()->open( "127.0.0.1", 34768 );
- }
-
-
- /**
- *
- */
- unsigned int InteractionDebug::GetHashValue()
- {
- return 0;
- }
-
- /**
- *
- */
- void InteractionDebug::OpenConection()
- {
- char* wb = m_Buffer;
- *((unsigned long*) wb) = (unsigned long) GetHashValue();
- wb += sizeof(long);
-
- size_t size = strlen( m_FileName );
-
- *((unsigned long*) wb) = (unsigned long) size;
- wb += sizeof(long);
-
- strcpy( wb, m_FileName );
- size += 2*sizeof(long);
-
- sendCounter();
- // MITK_INFO << "Open Connection file name: " << m_FileName << std::endl;
- SocketClient::GetInstance()->send( OPEN_CONNECTION, (unsigned int) size, m_Buffer );
- }
-
- /**
- *
- */
- bool InteractionDebug::NewStateMachine( const char* name, const StateMachine* stateMachine )
- {
- if ( name == NULL )
- return false;
-
- // Instance Address
- char* wb = m_Buffer;
- *((unsigned long*) wb) = (unsigned long) stateMachine;
- wb += sizeof(long);
-
- // Length of the name
- size_t size = strlen(name);
-
- *((unsigned long*) wb) = (unsigned long) size;
- wb += sizeof(long);
-
- // name
- strcpy(wb,name);
-
- size += 2*sizeof(long);
-
- sendCounter();
- // MITK_INFO << "NEW_STATE_MACHINE: instance: " << (unsigned int) stateMachine << " Type: " << name << std::endl;
- return SocketClient::GetInstance()->send( NEW_STATE_MACHINE, (unsigned int) size, m_Buffer );
- }
-
- /**
- *
- */
- bool InteractionDebug::Event( const StateMachine* stateMachine, unsigned int EventId )
- {
- if ( EventId != 520)
- {
- if ( stateMachine == NULL || stateMachine->GetType().empty() )
- return false;
-
- // Instance Address
- char* wb = m_Buffer;
- *((unsigned long*) wb) = (unsigned long) stateMachine;
- wb += sizeof(long);
-
- // eventID
- *((unsigned long*) wb) = EventId;
-
- sendCounter();
- // MITK_INFO << "EVENT: instance: " << (unsigned int) stateMachine << " EventId: " << EventId << std::endl;
- return SocketClient::GetInstance()->send( EVENT, 2*sizeof(long), m_Buffer );
- }
- return true;
- }
-
- /**
- *
- */
- bool InteractionDebug::Transition( const StateMachine* stateMachine, const char* transitionName )
- {
- if ( stateMachine == NULL || stateMachine->GetType().empty() )
- return false;
-
- // Instance Address
- char* wb = m_Buffer;
- *((unsigned long*) wb) = (unsigned long) stateMachine;
- wb += sizeof(long);
-
- // transitionName
- unsigned long size = static_cast<unsigned long>(strlen( transitionName ));
- *((unsigned long*) wb) = size;
-
- wb += sizeof(long);
-
- for ( unsigned long i=0; i<size; i++, wb++ )
- *wb = transitionName[i];
-
- size += 2*sizeof(long);
-
- //sendCounter();
- //MITK_INFO << "TRANSITION: instance: " << (unsigned int) stateMachine << " size: " << size << " transitionName: " << transitionName << std::endl;
- return SocketClient::GetInstance()->send( TRANSITION, size, m_Buffer );
- }
-
- /**
- *
- */
- bool InteractionDebug::Action( const StateMachine* stateMachine, const char* transitionName, unsigned int action )
- {
- if ( stateMachine == NULL || stateMachine->GetType().empty() )
- return false;
-
- // Instance Address
- char* wb = m_Buffer;
- *((unsigned long*) wb) = (unsigned long) stateMachine;
- wb += sizeof(long);
-
- // transitionName
- unsigned long size = static_cast<unsigned long>(strlen( transitionName ));
- *((unsigned long*) wb) = size;
-
- wb += sizeof(long);
-
- for ( unsigned long i=0; i<size; i++, wb++ )
- *wb = transitionName[i];
-
- wb += sizeof(long);
-
- *((unsigned long*) wb) = action;
-
- size += 3*sizeof(long);
-
- sendCounter();
- // MITK_INFO << "ACTION: instance: " << (unsigned int) stateMachine << " size: " << size << "action: " << action << " transitionName " << transitionName << std::endl;
- return SocketClient::GetInstance()->send( ACTION, size, m_Buffer );
- }
-
- /**
- *
- */
- bool InteractionDebug::DeleteStateMachine( const StateMachine* stateMachine )
- {
- if ( stateMachine == NULL || stateMachine->GetType().empty() )
- return false;
-
- // Instance Address
- char* wb = m_Buffer;
- *((unsigned long*) wb) = (unsigned long) stateMachine;
-
- sendCounter();
- // MITK_INFO << "DELETE_STATE_MACHINE: instance: << (unsigned int) stateMachine" << std::endl;
- return SocketClient::GetInstance()->send( DELETE_STATE_MACHINE, sizeof(long), m_Buffer );
- }
-
- /**
- *
- */
- InteractionDebug* InteractionDebug::GetInstance()
- {
- if (m_Instance==NULL)
- m_Instance = new InteractionDebug();
-
- return m_Instance;
- }
-
- /**
- *
- */
- void InteractionDebug::SetXMLFileName( const char* fileName )
- {
- size_t size = strlen(fileName) + 1;
- m_FileName = new char[size];
- strcpy(m_FileName,fileName);
- }
-
- void InteractionDebug::sendCounter()
- {
- static unsigned long m_Counter = 0;
- static char my_Buffer[sizeof(long)];
- m_Counter++;
-
- char* wb = my_Buffer;
- *((unsigned long*) wb) = (unsigned long) m_Counter;
-
- bool success = SocketClient::GetInstance()->send( 7, sizeof(long), wb );
- if (success)
- {
- MITK_INFO << "Counter: " << m_Counter << std::endl;
- }
- }
-
- void InteractionDebug::setMaxConnectionAdvance(int maxConnectionAdvance)
- {
- SocketClient::GetInstance()->setMaxConnectionAdvance(maxConnectionAdvance);
- }
-
-} // mitk
diff --git a/Modules/Ext/Interactions/mitkInteractionDebug.h b/Modules/Ext/Interactions/mitkInteractionDebug.h
deleted file mode 100644
index fc044c0532..0000000000
--- a/Modules/Ext/Interactions/mitkInteractionDebug.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef INTERACTION_DEBUG_H
-#define INTERACTION_DEBUG_H
-#include "mitkStateMachine.h"
-#include "MitkExtExports.h"
-#include "mitkSocketClient.h"
-
-namespace mitk{
-
-class MitkExt_EXPORT InteractionDebug
-{
- static InteractionDebug* m_Instance;
- static char* m_FileName;
-
- char m_Buffer[255];
-
- static const int OPEN_CONNECTION;
- static const int NEW_STATE_MACHINE;
- static const int EVENT;
- static const int TRANSITION;
- static const int ACTION;
- static const int DELETE_STATE_MACHINE;
-
- unsigned int GetHashValue();
- InteractionDebug();
-
-public:
- void OpenConection();
- bool NewStateMachine( const char* name, const StateMachine* stateMachine );
- bool Event( const StateMachine* stateMachine, unsigned int EventId );
- bool Transition( const StateMachine* stateMachine, const char* transitionName );
- bool Action( const StateMachine* stateMachine, const char* transitionName, unsigned int action );
- bool DeleteStateMachine( const StateMachine* stateMachine );
- void setMaxConnectionAdvance(int maxConectionAdvance);
- static InteractionDebug* GetInstance();
- static void SetXMLFileName( const char* fileName );
-
- void sendCounter();
-};
-
-} // mitk
-
-#endif // INTERACTION_DEBUG_H
diff --git a/Modules/Ext/Interactions/mitkInteractionDebugger.cpp b/Modules/Ext/Interactions/mitkInteractionDebugger.cpp
deleted file mode 100644
index 8378d71266..0000000000
--- a/Modules/Ext/Interactions/mitkInteractionDebugger.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkInteractionDebugger.h"
-#include <itkMacro.h>
-
-const char* mitk::InteractionDebugger::m_CurrentSender = "";
-bool mitk::InteractionDebugger::m_Active = false;
-
-mitk::InteractionDebugger::InteractionDebugger()
-{}
-
-void mitk::InteractionDebugger::Activate()
-{
- m_Active = true;
-}
-
-void mitk::InteractionDebugger::Deactivate()
-{
- m_Active = false;
-}
-mitk::InteractionDebugger::~InteractionDebugger()
-{}
-
-void mitk::InteractionDebugger::Set(const char* sender, const char* text)
-{
- if (m_Active)
- {
- std::ostringstream itkmsg;
- if (! itk::Object::GetGlobalWarningDisplay())
- return;
-
- if (sender != m_CurrentSender)
- {
- itkmsg << sender <<" :\n"<<text<<"\n";
- m_CurrentSender = sender;
- }
- else
- itkmsg<<text<<"\n";
-
- itk::OutputWindowDisplayDebugText(itkmsg.str().c_str());
- }
-}
-
diff --git a/Modules/Ext/Interactions/mitkInteractionDebugger.h b/Modules/Ext/Interactions/mitkInteractionDebugger.h
deleted file mode 100644
index 2a54814e4e..0000000000
--- a/Modules/Ext/Interactions/mitkInteractionDebugger.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef MITKINTERACTIONDEBUGGER_H
-#define MITKINTERACTIONDEBUGGER_H
-
-#include <itkObject.h>
-#include "MitkExtExports.h"
-#include "mitkCommon.h"
-
-
-namespace mitk{
-
- /**
- * @brief prints out information for debugging purpose
- *
- * prints out recieved text in a sorted way
- * @ingroup Interaction
- */
- class MitkExt_EXPORT InteractionDebugger : public itk::Object
- {
- public:
- /**
- * set a text for output
- * @param sender: who has sent this text
- */
- static void Set(const char* sender, const char* text);
- static void Activate();
- static void Deactivate();
-
- protected:
- InteractionDebugger();
- ~InteractionDebugger();
-
- private:
- static const char* m_CurrentSender;
- static bool m_Active;
- };
-
-}//namespace mitk
-
-#endif /* MITKINTERACTIONDEBUGGER_H */
-
-
diff --git a/Modules/Ext/Interactions/mitkPointInteractor.cpp b/Modules/Ext/Interactions/mitkPointInteractor.cpp
deleted file mode 100644
index 69befde6b8..0000000000
--- a/Modules/Ext/Interactions/mitkPointInteractor.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkPointInteractor.h"
-#include <mitkPointOperation.h>
-#include <mitkPositionEvent.h>
-#include <mitkOperationEvent.h>
-//#include "mitkStatusBar.h"
-#include <mitkDataNode.h>
-#include <mitkPointSet.h>
-#include <mitkInteractionConst.h>
-#include <mitkAction.h>
-#include <mitkProperties.h>
-#include <vtkLinearTransform.h>
-#include <mitkUndoController.h>
-#include <mitkStateEvent.h>
-#include <mitkState.h>
-
-
-mitk::PointInteractor::PointInteractor(const char * type, DataNode* dataNode)
-: Interactor(type, dataNode), m_LastPosition(0)
-{
- m_LastPoint.Fill(0);
-}
-
-mitk::PointInteractor::~PointInteractor()
-{}
-
-void mitk::PointInteractor::SelectPoint(int position)
-{
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return;
- if (pointSet->GetSize()<=0)//if List is empty, then no select of a point can be done!
- return;
-
- mitk::Point3D noPoint;//dummyPoint... not needed anyway
- noPoint.Fill(0);
- mitk::PointOperation* doOp = new mitk::PointOperation(OpSELECTPOINT, noPoint, position);
- if (m_UndoEnabled)
- {
- mitk::PointOperation* undoOp = new mitk::PointOperation(OpDESELECTPOINT, noPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
- pointSet->ExecuteOperation(doOp);
-}
-
-void mitk::PointInteractor::DeselectAllPoints()
-{
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return;
-
- mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet();
- mitk::PointSet::PointsContainer::Iterator it, end;
- end = itkPointSet->GetPoints()->End();
-
- for (it = itkPointSet->GetPoints()->Begin(); it != end; it++)
- {
- int position = it->Index();
- PointSet::PointDataType pointData = {0, false, PTUNDEFINED};
- itkPointSet->GetPointData(position, &pointData);
- if ( pointData.selected )//then declare an operation which unselects this point; UndoOperation as well!
- {
- mitk::Point3D noPoint;
- noPoint.Fill(0);
-
- mitk::PointOperation* doOp = new mitk::PointOperation(OpDESELECTPOINT, noPoint, position);
- if (m_UndoEnabled)
- {
- mitk::PointOperation* undoOp = new mitk::PointOperation(OpSELECTPOINT, noPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
- pointSet->ExecuteOperation(doOp);
- }
- }
-}
-
-float mitk::PointInteractor::CanHandleEvent(StateEvent const* stateEvent) const
-//go through all points and check, if the given Point lies near a line
-{
- float returnValue = 0;
-
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- //checking if a keyevent can be handled:
- if (posEvent == NULL)
- {
- //check, if the current state has a transition waiting for that key event.
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- return 0.5;
- }
- else
- {
- return 0;
- }
- }
-
- //Mouse event handling:
- //on MouseMove do nothing! reimplement if needed differently
- if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
- {
- return 0;
- }
-
- //if the event can be understood and if there is a transition waiting for that event
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- returnValue = 0.5;//it can be understood
- }
-
- //check on the right data-type
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return 0;
-
-
- //since we now have 3D picking in GlobalInteraction and all events send are DisplayEvents with 3D information,
- //we concentrate on 3D coordinates
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
- float p[3];
- itk2vtk(worldPoint, p);
- //transforming the Worldposition to local coordinatesystem
- m_DataNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p);
- vtk2itk(p, worldPoint);
-
- float distance = 5;
- int index = pointSet->SearchPoint(worldPoint, distance);
- if (index>-1)
- //how far away is the line from the point?
- {
- //get the point and calculate the jurisdiction out of it.
- mitk::PointSet::PointType point;
- pointSet->GetPointSet()->GetPoint(index, &point);
- returnValue = point.EuclideanDistanceTo(worldPoint);
-
- //between 1 and 0. 1 if directly hit
- returnValue = 1 - ( returnValue / distance );
- if (returnValue<0 || returnValue>1)
- {
- itkWarningMacro("Difficulties in calculating Jurisdiction. Check PointInteractor");
- return 0;
- }
-
- //and now between 0,5 and 1
- returnValue = 0.5 + (returnValue / 2);
-
- return returnValue;
- }
- else //not found
- {
- return returnValue;
- }
-
-}
-
-
-bool mitk::PointInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
-{
- bool ok = false;//for return type bool
-
- //checking corresponding Data; has to be a PointSet or a subclass
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return false;
-
- //for reading on the points, Id's etc
- mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet();
- mitk::PointSet::PointsContainer *itkPoints = itkPointSet->GetPoints();
-
- /*Each case must watch the type of the event!*/
- switch (action->GetActionId())
- {
- case AcADDPOINT:
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D itkPoint;
- itkPoint = posEvent->GetWorldPosition();
-
- //find the position, the point is to be added to: first entry with empty index.
- //if the Set is empty, then start with 0. if not empty, then take the first index not occupied
- int lastPosition = 0;
- if (!itkPoints->empty())
- {
- mitk::PointSet::PointsIterator it, end;
- it = itkPoints->Begin();
- end = itkPoints->End();
- while( it != end )
- {
- if (!itkPoints->IndexExists(lastPosition))
- break;
- ++it;
- ++lastPosition;
- }
- }
-
- PointOperation* doOp = new mitk::PointOperation(OpINSERT, itkPoint, lastPosition);
- if (m_UndoEnabled)
- {
- PointOperation* undoOp = new mitk::PointOperation(OpREMOVE, itkPoint, lastPosition);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp, "Add point");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- pointSet->ExecuteOperation(doOp);
- ok = true;
- break;
- }
- case AcDESELECTALL:
- this->DeselectAllPoints();
- ok = true;
- break;
- case AcCHECKELEMENT :
- /*checking if the Point transmitted is close enough to one point. Then generate a new event with the point and let this statemaschine handle the event.*/
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent != NULL)
- {
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- int PRECISION = 4;
- mitk::IntProperty *precision = dynamic_cast<IntProperty*>(action->GetProperty("PRECISION"));
- if (precision != NULL)
- {
- PRECISION = precision->GetValue();
- }
-
- int position = pointSet->SearchPoint(worldPoint, PRECISION);
- if (position>=0)//found a point near enough to the given point
- {
- m_LastPosition = position;//store it to be able to move the point
- worldPoint = pointSet->GetPoint(position);//get that point, the one meant by the user!
- mitk::Point2D displPoint;
- displPoint[0] = worldPoint[0];
- displPoint[1] = worldPoint[1];
-
- //new Event with information YES and with the correct point
- mitk::PositionEvent const* newPosEvent = new mitk::PositionEvent(posEvent->GetSender(), posEvent->GetType(),
- posEvent->GetButton(), posEvent->GetButtonState(), posEvent->GetKey(),
- displPoint, worldPoint);
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, newPosEvent);
- //call HandleEvent to leave the guard-state
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- else //hardly used, due to 3dPicking of globalInteraction
- {
- mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (disPosEvent != NULL)
- {//2d Koordinates for 3D Interaction; return false to redo the last statechange
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- }
- break;
- case AcCHECKSELECTED:
- //check if the point that was hit before is still hit
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent != NULL)
- {
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- int PRECISION = 4;
- mitk::IntProperty *precision = dynamic_cast<IntProperty*>(action->GetProperty("precision"));
- if (precision != NULL)
- {
- PRECISION = precision->GetValue();
- }
-
- int position = pointSet->SearchPoint(worldPoint, PRECISION);
- if (position <0)//no point found at the current mouseposition
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- break;
- }
-
- //point found at the current mouseposition, so check if this point is the same like before
- unsigned int upos = (unsigned int) position;//comparison signed unsigned int
- if (upos == m_LastPosition)//found the same point again
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, posEvent);
- //call HandleEvent to leave the guard-state
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- else //hardly used, due to 3dPicking of globalInteraction
- {
- mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (disPosEvent != NULL)
- {//2d Koordinates for 3D Interaction; return false to redo the last statechange
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- }
- break;
- case AcINITMOVEMENT:
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- //start of the Movement is stored to calculate the undoCoordinate in FinishMovement
- m_LastPoint = posEvent->GetWorldPosition();
-
- ok = true;
- break;
- }
-
- case AcMOVESELECTED://moves the point
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D newPoint;
- newPoint = posEvent->GetWorldPosition();
-
- PointOperation* doOp = new mitk::PointOperation(OpMOVE, newPoint, m_LastPosition);
- //execute the Operation
- //here no undo is stored. only the start and the end is stored for undo.
- m_DataNode->GetData()->ExecuteOperation(doOp);
- ok = true;
- break;
- }
-
- case AcFINISHMOVEMENT:
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- //finish the movement:
- // set undo-information and move it to the last position.
- mitk::Point3D newPoint;
- newPoint = posEvent->GetWorldPosition();
-
- PointOperation* doOp = new mitk::PointOperation(OpMOVE, newPoint, m_LastPosition);
- if ( m_UndoEnabled )
- {
- PointOperation* undoOp = new mitk::PointOperation(OpMOVE, m_LastPoint, m_LastPosition);
- OperationEvent *operationEvent = new OperationEvent( m_DataNode->GetData(), doOp, undoOp, "Move point");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- //execute the Operation
- m_DataNode->GetData()->ExecuteOperation(doOp);
-
- // //increase the GroupEventId, so that the raw-Undo goes to here
- //this->IncCurrGroupEventId();
- ok = true;
- }
- break;
-case AcCHECKGREATERONE:
- //check if after deleteion the set will be empty
- {
- if (pointSet->GetSize()>1)
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- break;
-case AcSELECTANOTHEROBJECT:
- //selects an other Point after one point has been removed
- {
- /*select the point "position-1",
- and if it is the first in list,
- then contine at the last in list*/
- if (pointSet->GetSize()>0)//only then a select of a point is possible!
- {
- if (m_LastPosition > 0)//not the first in list
- {
- this->SelectPoint( m_LastPosition-1 );
- }
- else//it was the first point in list, that was removed, so select the last in list
- {
- m_LastPosition = pointSet->GetSize()-1;//last in list
- SelectPoint( m_LastPosition );
- }//else
- }//if
- ok = true;
- }
- break;
-case AcREMOVEPOINT:
- {
- //store the position of the removed point to be able to use it for selection of a next point
- //even if more than one point is selected, as long as we select the point befor the first selected point we are ok.
- //need to check if empty before select though!
- m_LastPosition = pointSet->SearchSelectedPoint();
-
- Operation* doOp = new mitk::Operation(OpREMOVEPOINT);
- if (m_UndoEnabled)
- {
- Operation* undoOp = new mitk::Operation(OpINSERTPOINT);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp, "Remove point");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- pointSet->ExecuteOperation(doOp);
- ok = true;
- }
- break;
- case AcSELECT:
- //select the point found at the given mouseposition
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- //search the point in the list
- //distance set to 0, cause we already got the exact point from last State checkpoint
- //but we also need the position in the list to move it
- int position = pointSet->SearchPoint(worldPoint, 0);
-
- if (position>=0)//found a point
- {
- PointOperation* doOp = new mitk::PointOperation(OpSELECTPOINT, worldPoint, position);
-
- //Undo
- if (m_UndoEnabled) //write to UndoMechanism
- {
- PointOperation* undoOp = new mitk::PointOperation(OpDESELECTPOINT, worldPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
-
- //execute the Operation
- pointSet->ExecuteOperation(doOp);
- ok = true;
- }
- }
- break;
- case AcDESELECT:
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- //search the point in the list
- //distance set to 0, cause we already got the exact point from last State checkpoint
- //but we also need the position in the list to move it
- int position = pointSet->SearchPoint(worldPoint, 0);
-
- if (position>=0)//found a point
- {
- PointOperation* doOp = new mitk::PointOperation(OpDESELECTPOINT, worldPoint, position);
-
- //Undo
- if (m_UndoEnabled) //write to UndoMechanism
- {
- PointOperation* undoOp = new mitk::PointOperation(OpSELECTPOINT, worldPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
-
- //execute the Operation
- pointSet->ExecuteOperation(doOp);
- ok = true;
- }
- }
- break;
- case AcSETSTARTPOINT:
- {
- //get the selected point and assign it as startpoint
- Point3D point;//dummy
- point.Fill(0);
- int position = pointSet->SearchSelectedPoint();
- if (position >-1)
- {
- PointOperation* doOp = new mitk::PointOperation(OpSETPOINTTYPE, point, position, true, PTSTART);
-
- //Undo
- if (m_UndoEnabled) //write to UndoMechanism
- {
- PointOperation* undoOp = new mitk::PointOperation(OpSETPOINTTYPE, point, position, true, PTUNDEFINED);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
-
- //execute the Operation
- pointSet->ExecuteOperation(doOp);
- ok = true;
- }
- }
- break;
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- }
-
- return ok;
-
-}
-
diff --git a/Modules/Ext/Interactions/mitkPointInteractor.h b/Modules/Ext/Interactions/mitkPointInteractor.h
deleted file mode 100644
index 2b4ae96e34..0000000000
--- a/Modules/Ext/Interactions/mitkPointInteractor.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKPOINTINTERACTOR_H_HEADER_INCLUDED
-#define MITKPOINTINTERACTOR_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include <mitkInteractor.h>
-#include <mitkNumericTypes.h>
-
-namespace mitk
-{
- class DataNode;
-
- //##Documentation
- //## @brief Interaction with a point
- //##
- //## Interact with a point: set point, select point, move point and remove point
- //## All Set-operations are done through the method "ExecuteAction".
- //## the identificationnumber of this point is set by this points and evalued from an empty place in the DataStructure
- //## @ingroup Interaction
- class MitkExt_EXPORT PointInteractor : public Interactor
- {
- public:
- mitkClassMacro(PointInteractor, Interactor);
- mitkNewMacro2Param(Self, const char*, DataNode*);
-
- //##Documentation
- //## @brief Sets the amount of precision
- void SetPrecision(unsigned int precision);
-
- //##Documentation
- //## @brief derived from mitk::Interactor; calculates Jurisdiction according to points
- //##
- //## standard method can not be used, since it doesn't calculate in points, only in BoundingBox of Points
- virtual float CanHandleEvent(StateEvent const* stateEvent) const;
-
-
- protected:
- //##Documentation
- //##@brief Constructor
- PointInteractor(const char * type, DataNode* dataNode);
-
- //##Documentation
- //##@brief Destructor
- virtual ~PointInteractor();
-
- //##Documentation
- //## @brief select the point on the given position
- virtual void SelectPoint(int position);
-
- //##Documentation
- //## @brief unselect all points that exist in mesh
- virtual void DeselectAllPoints();
-
- //##Documentation
- //## @brief Executes Actions
- virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
-
-
- private:
-
- //##Documentation
- //## @brief to calculate a direction vector from last point and actual point
- Point3D m_LastPoint;
-
- //##Documentation
- //## @brief to store a position
- unsigned int m_LastPosition;
-
- };
-}
-#endif /* MITKPOINTINTERACTOR_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Interactions/mitkPointSelectorInteractor.cpp b/Modules/Ext/Interactions/mitkPointSelectorInteractor.cpp
deleted file mode 100644
index 6fa966a4c8..0000000000
--- a/Modules/Ext/Interactions/mitkPointSelectorInteractor.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkPointSelectorInteractor.h"
-#include <mitkPointOperation.h>
-#include <mitkPositionEvent.h>
-#include <mitkOperationEvent.h>
-//#include "mitkStatusBar.h"
-#include <mitkDataNode.h>
-#include <mitkPointSet.h>
-#include <mitkInteractionConst.h>
-#include <mitkAction.h>
-#include <mitkProperties.h>
-#include <vtkLinearTransform.h>
-#include <mitkUndoController.h>
-#include <mitkStateEvent.h>
-#include <mitkState.h>
-
-
-mitk::PointSelectorInteractor::PointSelectorInteractor(const char * type, DataNode* dataNode)
-: Interactor(type, dataNode), m_LastPosition(0)
-{
- m_LastPoint.Fill(0);
-}
-
-mitk::PointSelectorInteractor::~PointSelectorInteractor()
-{}
-
-void mitk::PointSelectorInteractor::SelectPoint(int position)
-{
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return;
- if (pointSet->GetSize()<=0)//if List is empty, then no select of a point can be done!
- return;
-
- mitk::Point3D noPoint;//dummyPoint... not needed anyway
- noPoint.Fill(0);
- mitk::PointOperation* doOp = new mitk::PointOperation(OpSELECTPOINT, noPoint, position);
- if (m_UndoEnabled)
- {
- mitk::PointOperation* undoOp = new mitk::PointOperation(OpDESELECTPOINT, noPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
- pointSet->ExecuteOperation(doOp);
-}
-
-void mitk::PointSelectorInteractor::DeselectAllPoints()
-{
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return;
-
- mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet();
- mitk::PointSet::PointsContainer::Iterator it, end;
- end = itkPointSet->GetPoints()->End();
-
- for (it = itkPointSet->GetPoints()->Begin(); it != end; it++)
- {
- int position = it->Index();
- PointSet::PointDataType pointData = {0, false, PTUNDEFINED};
- itkPointSet->GetPointData(position, &pointData);
- if ( pointData.selected )//then declare an operation which unselects this point; UndoOperation as well!
- {
- mitk::Point3D noPoint;
- noPoint.Fill(0);
-
- mitk::PointOperation* doOp = new mitk::PointOperation(OpDESELECTPOINT, noPoint, position);
- if (m_UndoEnabled)
- {
- mitk::PointOperation* undoOp = new mitk::PointOperation(OpSELECTPOINT, noPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
- pointSet->ExecuteOperation(doOp);
- }
- }
-}
-
-float mitk::PointSelectorInteractor::CanHandleEvent(StateEvent const* stateEvent) const
-//go through all points and check, if the given Point lies near a line
-{
- float returnValue = 0;
-
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- //checking if a keyevent can be handled:
- if (posEvent == NULL)
- {
- //check, if the current state has a transition waiting for that key event.
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- return 0.5;
- }
- else
- {
- return 0;
- }
- }
-
- //Mouse event handling:
- //on MouseMove do nothing! reimplement if needed differently
- if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
- {
- return 0;
- }
-
- //if the event can be understood and if there is a transition waiting for that event
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- returnValue = 0.5;//it can be understood
- }
-
- //check on the right data-type
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return 0;
-
-
- //since we now have 3D picking in GlobalInteraction and all events send are DisplayEvents with 3D information,
- //we concentrate on 3D coordinates
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
- float p[3];
- itk2vtk(worldPoint, p);
- //transforming the Worldposition to local coordinatesystem
- m_DataNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p);
- vtk2itk(p, worldPoint);
-
- float distance = 5;
- int index = pointSet->SearchPoint(worldPoint, distance);
- if (index>-1)
- //how far away is the line from the point?
- {
- //get the point and calculate the jurisdiction out of it.
- mitk::PointSet::PointType point;
- pointSet->GetPointSet()->GetPoint(index, &point);
- returnValue = point.EuclideanDistanceTo(worldPoint);
-
- //between 1 and 0. 1 if directly hit
- returnValue = 1 - ( returnValue / distance );
- if (returnValue<0 || returnValue>1)
- {
- itkWarningMacro("Difficulties in calculating Jurisdiction. Check PointSelectorInteractor");
- return 0;
- }
-
- //and now between 0,5 and 1
- returnValue = 0.5 + (returnValue / 2);
-
- return returnValue;
- }
- else //not found
- {
- return returnValue;
- }
-
-}
-
-
-bool mitk::PointSelectorInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
-{
- bool ok = false;//for return type bool
-
- //checking corresponding Data; has to be a PointSet or a subclass
- mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
- if (pointSet == NULL)
- return false;
-
- //for reading on the points, Id's etc
- //mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet();
- //mitk::PointSet::PointsContainer *itkPoints = itkPointSet->GetPoints();
-
- /*Each case must watch the type of the event!*/
- switch (action->GetActionId())
- {
- case AcADDPOINT:
- break;
- case AcDESELECTALL:
- this->DeselectAllPoints();
- ok = true;
- break;
- case AcCHECKELEMENT :
- /*checking if the Point transmitted is close enough to one point. Then generate a new event with the point and let this statemaschine handle the event.*/
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent != NULL)
- {
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- int PRECISION = 4;
- mitk::IntProperty *precision = dynamic_cast<IntProperty*>(action->GetProperty("PRECISION"));
- if (precision != NULL)
- {
- PRECISION = precision->GetValue();
- }
-
- int position = pointSet->SearchPoint(worldPoint, PRECISION);
- if (position>=0)//found a point near enough to the given point
- {
- m_LastPosition = position;//store it to be able to move the point
- worldPoint = pointSet->GetPoint(position);//get that point, the one meant by the user!
- mitk::Point2D displPoint;
- displPoint[0] = worldPoint[0];
- displPoint[1] = worldPoint[1];
-
- //new Event with information YES and with the correct point
- mitk::PositionEvent const* newPosEvent = new mitk::PositionEvent(posEvent->GetSender(), posEvent->GetType(),
- posEvent->GetButton(), posEvent->GetButtonState(), posEvent->GetKey(),
- displPoint, worldPoint);
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, newPosEvent);
- //call HandleEvent to leave the guard-state
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- else //hardly used, due to 3dPicking of globalInteraction
- {
- mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (disPosEvent != NULL)
- {//2d Koordinates for 3D Interaction; return false to redo the last statechange
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- }
- break;
- case AcCHECKSELECTED:
- //check if the point that was hit before is still hit
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent != NULL)
- {
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- int PRECISION = 4;
- mitk::IntProperty *precision = dynamic_cast<IntProperty*>(action->GetProperty("precision"));
- if (precision != NULL)
- {
- PRECISION = precision->GetValue();
- }
-
- int position = pointSet->SearchPoint(worldPoint, PRECISION);
- if (position <0)//no point found at the current mouseposition
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- break;
- }
-
- //point found at the current mouseposition, so check if this point is the same like before
- unsigned int upos = (unsigned int) position;//comparison signed unsigned int
- if (upos == m_LastPosition)//found the same point again
- {
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, posEvent);
- //call HandleEvent to leave the guard-state
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- else
- {
- //new Event with information NO
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- else //hardly used, due to 3dPicking of globalInteraction
- {
- mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- if (disPosEvent != NULL)
- {//2d Koordinates for 3D Interaction; return false to redo the last statechange
- mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
- this->HandleEvent( newStateEvent );
- ok = true;
- }
- }
- }
- break;
- case AcINITMOVEMENT:
- break;
- case AcMOVESELECTED://moves the point
- break;
- case AcFINISHMOVEMENT:
- break;
- case AcCHECKGREATERONE:
- break;
- case AcSELECTANOTHEROBJECT:
- //selects an other Point after one point has been removed
- {
- /*select the point "position-1",
- and if it is the first in list,
- then contine at the last in list*/
- if (pointSet->GetSize()>0)//only then a select of a point is possible!
- {
- if (m_LastPosition > 0)//not the first in list
- {
- this->SelectPoint( m_LastPosition-1 );
- }
- else//it was the first point in list, that was removed, so select the last in list
- {
- m_LastPosition = pointSet->GetSize()-1;//last in list
- SelectPoint( m_LastPosition );
- }//else
- }//if
- ok = true;
- }
- break;
- case AcREMOVEPOINT:
- break;
- case AcSELECT:
- //select the point found at the given mouseposition
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- //search the point in the list
- //distance set to 0, cause we already got the exact point from last State checkpoint
- //but we also need the position in the list to move it
- int position = pointSet->SearchPoint(worldPoint, 0);
-
- if (position>=0)//found a point
- {
- PointOperation* doOp = new mitk::PointOperation(OpSELECTPOINT, worldPoint, position);
-
- //Undo
- if (m_UndoEnabled) //write to UndoMechanism
- {
- PointOperation* undoOp = new mitk::PointOperation(OpDESELECTPOINT, worldPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
-
- //execute the Operation
- pointSet->ExecuteOperation(doOp);
- ok = true;
- }
- }
- break;
- case AcDESELECT:
- {
- mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- mitk::Point3D worldPoint = posEvent->GetWorldPosition();
-
- //search the point in the list
- //distance set to 0, cause we already got the exact point from last State checkpoint
- //but we also need the position in the list to move it
- int position = pointSet->SearchPoint(worldPoint, 0);
-
- if (position>=0)//found a point
- {
- PointOperation* doOp = new mitk::PointOperation(OpDESELECTPOINT, worldPoint, position);
-
- //Undo
- if (m_UndoEnabled) //write to UndoMechanism
- {
- PointOperation* undoOp = new mitk::PointOperation(OpSELECTPOINT, worldPoint, position);
- OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
- m_UndoController->SetOperationEvent(operationEvent);
- }
-
- //execute the Operation
- pointSet->ExecuteOperation(doOp);
- ok = true;
- }
- }
- break;
- case AcSETSTARTPOINT:
- break;
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- }
-
- return ok;
-
-}
-
-
diff --git a/Modules/Ext/Interactions/mitkPointSelectorInteractor.h b/Modules/Ext/Interactions/mitkPointSelectorInteractor.h
deleted file mode 100644
index 05adfa433e..0000000000
--- a/Modules/Ext/Interactions/mitkPointSelectorInteractor.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKPOINTSELECTORINTERACTOR_H_HEADER_INCLUDED
-#define MITKPOINTSELECTORINTERACTOR_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include <mitkInteractor.h>
-#include <mitkNumericTypes.h>
-
-namespace mitk
-{
- class DataNode;
-
- //##Documentation
- //## @brief Just select a point, that's the only way to interact with the point
- //##
- //## Interact with a point: Select the point without moving to get parameters that does not change
- //## All Set-operations would be done through the method "ExecuteAction", if there would be anyone.
- //## the identificationnumber of this point is set by this points and evalued from an empty place in the DataStructure
- //## @ingroup Interaction
- class MitkExt_EXPORT PointSelectorInteractor : public Interactor
- {
- public:
- mitkClassMacro(PointSelectorInteractor, Interactor);
- mitkNewMacro2Param(Self, const char*, DataNode*);
-
- //##Documentation
- //## @brief Sets the amount of precision
- void SetPrecision(unsigned int precision);
-
- //##Documentation
- //## @brief derived from mitk::Interactor; calculates Jurisdiction according to points
- //##
- //## standard method can not be used, since it doesn't calculate in points, only in BoundingBox of Points
- virtual float CanHandleEvent(StateEvent const* stateEvent) const;
-
-
- protected:
- //##Documentation
- //##@brief Constructor
- PointSelectorInteractor(const char * type, DataNode* dataNode);
-
- //##Documentation
- //##@brief Destructor
- virtual ~PointSelectorInteractor();
-
- //##Documentation
- //## @brief select the point on the given position
- virtual void SelectPoint(int position);
-
- //##Documentation
- //## @brief unselect all points that exist in mesh
- virtual void DeselectAllPoints();
-
- //##Documentation
- //## @brief Executes Actions
- virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
-
-
- private:
-
- //##Documentation
- //## @brief to calculate a direction vector from last point and actual point
- Point3D m_LastPoint;
-
- //##Documentation
- //## @brief to store a position
- unsigned int m_LastPosition;
-
- };
-}
-#endif /* MITKPointSelectorInteractor_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Interactions/mitkSeedsInteractor.cpp b/Modules/Ext/Interactions/mitkSeedsInteractor.cpp
deleted file mode 100644
index 09636e81ac..0000000000
--- a/Modules/Ext/Interactions/mitkSeedsInteractor.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkSeedsInteractor.h"
-
-#include "mitkProperties.h"
-#include "mitkStringProperty.h"
-#include "mitkAction.h"
-#include "mitkDisplayPositionEvent.h"
-#include "mitkOperationEvent.h"
-#include "mitkInteractionConst.h"
-#include "mitkUndoController.h"
-#include "mitkDataNode.h"
-#include "mitkStateEvent.h"
-#include "mitkState.h"
-#include "mitkDrawOperation.h"
-
-
-mitk::SeedsInteractor::SeedsInteractor(const char * type, mitk::DataNode* dataNode)
- : mitk::Interactor(type, dataNode)
-{
- m_Radius = 1;
- m_Config = 0; // default config 254, 255 are added for fore- and backgrund seeds
- m_CurrentDrawState = 255;
-}
-
-mitk::SeedsInteractor::~SeedsInteractor()
-{
-}
-
-
-bool mitk::SeedsInteractor::ExecuteAction(mitk::Action* action, mitk::StateEvent const* stateEvent)
-{
- const mitk::DisplayPositionEvent* posEvent = dynamic_cast<const mitk::DisplayPositionEvent*>(stateEvent->GetEvent());
- if (posEvent == NULL)
- return false;
-
- event_point = posEvent->GetWorldPosition();
-
- m_DataNode->SetVisibility(true);
- m_SeedsImage = dynamic_cast<mitk::SeedsImage*>(m_DataNode->GetData());
-
-
- bool ok = false;
- switch (action->GetActionId())
- {
- case mitk::AcINITFOREGROUND:
- {
- if (m_Config == 0) m_DrawState = m_CurrentDrawState;
- else m_DrawState = 1;
- ok = true;
- break;
- }
- case mitk::AcINITBACKGROUND:
- {
- if (m_Config == 0) m_DrawState = 254;
- else m_DrawState = -1;
- ok = true;
- break;
- }
- case mitk::AcINITNEUTRAL:
- {
- m_DrawState = 0;
- ok = true;
- break;
- }
- case mitk::AcADD:
- {
- last_point = event_point;
- mitk::DrawOperation* doOp = new mitk::DrawOperation(OpADD, event_point, last_point, m_DrawState, m_Radius);
- if (m_UndoEnabled){ //write to UndoMechanism/ Can probably be removed!
- mitk::DrawOperation* undoOp = new mitk::DrawOperation(OpUNDOADD, event_point, last_point, m_DrawState, m_Radius);
- mitk::OperationEvent *operationEvent = new mitk::OperationEvent(m_SeedsImage, doOp, undoOp, "Add seed point");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- //execute the Operation
- m_SeedsImage->ExecuteOperation(doOp);
- ok = true;
- break;
- }
- case mitk::AcMOVE:
- {
- last_point = event_point;
- mitk::DrawOperation* doOp = new mitk::DrawOperation(OpMOVE, event_point, last_point, m_DrawState, m_Radius);
- if (m_UndoEnabled){ //write to UndoMechanism/ Can probably be removed!
- mitk::DrawOperation* undoOp = new mitk::DrawOperation(OpUNDOMOVE, event_point, last_point, m_DrawState, m_Radius);
- mitk::OperationEvent *operationEvent = new mitk::OperationEvent(m_SeedsImage, doOp, undoOp, "Move seed point");
- m_UndoController->SetOperationEvent(operationEvent);
- }
- //execute the Operation
- m_SeedsImage->ExecuteOperation(doOp);
- ok = true;
- //this->Modified();
- break;
- }
- case mitk::AcFINISH:
- {
- last_point = event_point;
- ok = true;
- this->Modified();
-
- this->InvokeEvent( itk::EndEvent() );
-
- break;
- }
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- }
- return ok;
-}
diff --git a/Modules/Ext/Interactions/mitkSeedsInteractor.h b/Modules/Ext/Interactions/mitkSeedsInteractor.h
deleted file mode 100644
index cb9011f359..0000000000
--- a/Modules/Ext/Interactions/mitkSeedsInteractor.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef __SeedsInteractor_H
-#define __SeedsInteractor_H
-
-#include <mitkCommon.h>
-#include "MitkExtExports.h"
-#include <mitkInteractor.h>
-#include <mitkNumericTypes.h>
-#include <mitkImageAccessByItk.h>//needed by QmitkSimplexMeshes (SMDeformation.cpp and LungSegmentation.cpp)
-#include <mitkDataNode.h>
-#include <mitkSeedsImage.h>
-
-
-namespace mitk {
-
- //##Documentation
- //## @brief SeedsInteractor handles all actions on the seedsimage
- //## @ingroup Interaction
-
- /**
- * \deprecatedSince{2014_03} mitk::ConnectPointsInteractor is deprecated. Needs to be updated to the new interaction-framework.
- * Refer to \see DataInteractionPage for general information about the concept of the new implementation.
- */
-
- class DEPRECATED() MitkExt_EXPORT SeedsInteractor : public Interactor
- {
- public:
- mitkClassMacro(SeedsInteractor, Interactor);
- mitkNewMacro2Param(Self, const char*, DataNode*);
-
- /// sets the radius of the seeds.
- void SetRadius(int val){m_Radius=val;};
- void SetCurrentDrawState(int val){m_CurrentDrawState = val;};
-
- itkSetMacro(Config, unsigned int);
- itkGetMacro(Config, unsigned int);
-
- protected:
- /**
- * @brief Default Constructor
- **/
- SeedsInteractor(const char * type, DataNode* dataNode);
- /**
- * @brief Default Destructor
- **/
- virtual ~SeedsInteractor();
-
- virtual bool ExecuteAction(Action* action, StateEvent const* stateEvent);
-
- protected:
- SeedsImage::Pointer m_SeedsImage;
- SeedsImage::Pointer m_LastSeedsImage;
- Point3D event_point;
- Point3D last_point;
-
- int m_Radius;
- int m_DrawState;
- int m_CurrentDrawState;
- unsigned int m_Config; // determine whether 254,255 or smoothed float values are used.
- };
-
-}
-#endif //__SeedsInteractor_H
diff --git a/Modules/Ext/Interactions/mitkSocketClient.cpp b/Modules/Ext/Interactions/mitkSocketClient.cpp
deleted file mode 100644
index 5ddbb43322..0000000000
--- a/Modules/Ext/Interactions/mitkSocketClient.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkSocketClient.h"
-#include <itkObjectFactory.h>
-#include <itkOutputWindow.h>
-#include <itkCommand.h>
-
-namespace mitk
-{
-
- SocketClientImplementation* SocketClient::m_Implementation = NULL;
- SocketClient* SocketClient::m_Instance = NULL;
-
- void SocketClient::open( const char* ipAdress, unsigned short port )
- {
- if (m_Implementation)
- {
- m_Implementation->open( ipAdress, port );
- }
- }
-
- void SocketClient::setMaxConnectionAdvance( int maxConnectionAdvance )
- {
- if (m_Implementation)
- {
- m_Implementation->setMaxConnectionAdvance( maxConnectionAdvance );
- }
- }
-
- bool SocketClient::send( unsigned int messagetype, unsigned int bodySize, char* body )
- {
- if (m_Implementation)
- {
- return m_Implementation->send( messagetype, bodySize, body);
- }
- else
- {
- return false;
- }
- }
-
- void SocketClient::SetImplementationInstance(SocketClientImplementation* implementation)
- {
- if ( m_Implementation == implementation )
- {
- return;
- }
- m_Implementation = implementation;
- }
-
- SocketClient* SocketClient::GetInstance()
- {
- if (m_Instance == NULL)
- {
- m_Instance = new SocketClient();
- }
-
- return m_Instance;
- }
-
- SocketClient::SocketClient()
- {
- }
-
- SocketClient::~SocketClient()
- {
- }
-}//end namespace mitk
diff --git a/Modules/Ext/Interactions/mitkSocketClient.h b/Modules/Ext/Interactions/mitkSocketClient.h
deleted file mode 100644
index 8b6fdf1e04..0000000000
--- a/Modules/Ext/Interactions/mitkSocketClient.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSOCKETCLIENT_H
-#define MITKSOCKETCLIENT_H
-#include <itkObject.h>
-#include "MitkExtExports.h"
-#include "mitkCommon.h"
-
-#include "mitkSocketClientImplementation.h"
-
-
-namespace mitk
-{
-
- //##Documentation
- //## @brief Sending a message to the applications ProgressBar
- //##
- //## Holds a GUI dependent ProgressBarImplementation and sends the progress further.
- //## All mitk-classes use this class to display progress on GUI-ProgressBar.
- //## The mainapplication has to set the internal held ProgressBarImplementation with SetImplementationInstance(..).
- //## @ingroup Interaction
- class MitkExt_EXPORT SocketClient : public itk::Object
- {
-
- public:
-
- itkTypeMacro(ProgressBar, itk::Object);
-
- static SocketClient* GetInstance();
-
- static void SetImplementationInstance(SocketClientImplementation* implementation);
-
- void open( const char* ipAdress, unsigned short port );
-
- void setMaxConnectionAdvance( int maxConnectionAdvance );
-
- bool send( unsigned int messagetype, unsigned int bodySize = 0, char* body = NULL );
-
- protected:
- SocketClient();
- virtual ~SocketClient();
- static SocketClientImplementation* m_Implementation;
- static SocketClient* m_Instance;
- };
-
-}// end namespace mitk
-
-#endif /* define MITKSOCKETCLIENT_H */
diff --git a/Modules/Ext/Interactions/mitkSocketClientImplementation.h b/Modules/Ext/Interactions/mitkSocketClientImplementation.h
deleted file mode 100644
index f52ab15bce..0000000000
--- a/Modules/Ext/Interactions/mitkSocketClientImplementation.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSOCKETCLIENTIMPLEMENTATION_H
-#define MITKSOCKETCLIENTIMPLEMENTATION_H
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-
-namespace mitk
-{
-
- //##Documentation
- //## @brief GUI indepentent Interface for all Gui depentent implementations of a ProgressBar.
- class MitkExt_EXPORT SocketClientImplementation
- {
-
- public:
-
- //##Documentation
- //## @brief Constructor
- SocketClientImplementation(){};
-
- //##Documentation
- //## @brief Destructor
- virtual ~SocketClientImplementation(){};
-
- virtual void open( const char* ipAdress, unsigned short port )=0;
-
- virtual void setMaxConnectionAdvance( int maxConnectionAdvance )=0;
-
- virtual bool send( unsigned int messagetype, unsigned int bodySize = 0, char* body = NULL )=0;
- };
-
-}// end namespace mitk
-
-#endif /* define MITKSOCKETCLIENTIMPLEMENTATION_H */
diff --git a/Modules/Ext/Interactions/mitkSpaceNavigatorDriver.cpp b/Modules/Ext/Interactions/mitkSpaceNavigatorDriver.cpp
deleted file mode 100644
index ab8dfc11dd..0000000000
--- a/Modules/Ext/Interactions/mitkSpaceNavigatorDriver.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#define SPACE_NAVIGATOR_MAIN_SOURCE
-
-#include "mitkSpaceNavigatorDriver.h"
-#include "mitkTDMouseEventThrower.h"
-
-SpaceNavigatorDriver* SpaceNavigatorDriver::GetInstance()
-{
- //create the singleton instance of the driver, so it can listen for events
- static SpaceNavigatorDriver instance;
- return &instance;
-}
-
-SpaceNavigatorDriver::SpaceNavigatorDriver()
-{
- LRESULT result=0;
-
- HRESULT hr=::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED );
- if (!SUCCEEDED(hr))
- {
- cout << "Fehler" << endl;
-
- // stop creation of window
- result = -1;
- }
- else
- {
- HRESULT hr = InitializeCOM();
- if (!SUCCEEDED(hr))
- {
- // stop creation of window
- result = -1;
- }
- }
-}
-
-SpaceNavigatorDriver::~SpaceNavigatorDriver()
-{
- UninitializeCOM();
-}
-
-inline HRESULT SpaceNavigatorDriver::HookEvent1(CComPtr<ISimpleDevice> device)
-{
- // Get the interfaces to the sensor and the keyboard;
- return device->get_Sensor(&m_pISensor);
-}
-
-inline HRESULT SpaceNavigatorDriver::HookEvent2()
-{
- return __hook(&_ISensorEvents::SensorInput, m_pISensor,
- &SpaceNavigatorDriver::OnSensorInput);
-}
-
-inline HRESULT SpaceNavigatorDriver::HookEvent3(CComPtr<ISimpleDevice> device)
-{
- return device->get_Keyboard(&m_pIKeyboard);
-}
-
-inline HRESULT SpaceNavigatorDriver::HookEvent4()
-{
- return __hook(&_IKeyboardEvents::KeyDown, m_pIKeyboard,
- &SpaceNavigatorDriver::OnKeyDown);
-}
-
-inline HRESULT SpaceNavigatorDriver::HookEvent5()
-{
- return __hook(&_IKeyboardEvents::KeyUp, m_pIKeyboard,
- &SpaceNavigatorDriver::OnKeyUp);
-}
-
-
-
-HRESULT SpaceNavigatorDriver::InitializeCOM()
-{
- HRESULT hr;
- CComPtr<IUnknown> _3DxDevice;
-
- // Create the device object
- hr = _3DxDevice.CoCreateInstance(__uuidof(Device));
- if (SUCCEEDED(hr))
- {
-
- CComPtr<ISimpleDevice> _3DxSimpleDevice;
-
- hr = _3DxDevice.QueryInterface(&_3DxSimpleDevice);
- if (SUCCEEDED(hr))
- {
- hr = __hook(&_ISimpleDeviceEvents::DeviceChange, _3DxSimpleDevice,
- &SpaceNavigatorDriver::OnDeviceChange);
-
- //workaround for .net 2003 Bug Nr. 829749
- hr = this->HookEvent1(_3DxSimpleDevice);
- hr = this->HookEvent2();
- hr = this->HookEvent3(_3DxSimpleDevice);
- hr = this->HookEvent4();
- hr = this->HookEvent5();
-
- // Connect to the driver
- _3DxSimpleDevice->Connect();
-
- cout << "Connected to COM-object for space navigation..." << endl;
- }
- }
- else
- cout << "CoCreateInstance failed";
-
- return hr;
-}
-
-HRESULT SpaceNavigatorDriver::OnDeviceChange(long reserved )
-{
- HRESULT result = S_OK;
- //cout << "SpaceNavigatorDriver::OnDeviceChange(reserved =0" << reserved << endl;
-
- HRESULT hr;
- ISimpleDevicePtr _p3DxDevice;
- hr = m_pIKeyboard->get_Device((IDispatch**)&_p3DxDevice);
- if (SUCCEEDED(hr))
- {
- long device;
- _p3DxDevice->get_Type(&device);
- //cout << "Attached device=" << device;
- _p3DxDevice.Release();
-
- long keys, programmableKeys;
- m_pIKeyboard->get_Keys(&keys);
- m_pIKeyboard->get_ProgrammableKeys(&programmableKeys);
- //cout << "Number of Keys=%d\tProgrammable keys=%d\n" << keys << " / " << programmableKeys;
-
- for (long i=1; i<=keys; i++)
- {
- BSTR bstrLabel;
- BSTR bstrName;
- m_pIKeyboard->GetKeyLabel(i, &bstrLabel);
- m_pIKeyboard->GetKeyName(i, &bstrName);
- CString strLabel(bstrLabel);
- CString strName(bstrName);
-
- //cout << "Key Label=%s\tKey Name=%s\n" <<
- //(const TCHAR *)strLabel << " / " << (const TCHAR *)strName;
-
- }
- mitk::TDMouseEventThrower::GetInstance()->DeviceChange (device, keys, programmableKeys);
- }
- return result;
-}
-
-HRESULT SpaceNavigatorDriver::OnKeyDown(int keyCode )
-{
- HRESULT result = S_OK;
- mitk::TDMouseEventThrower::GetInstance()->KeyDown (keyCode);
- return result;
-}
-
-HRESULT SpaceNavigatorDriver::OnKeyUp(int keyCode )
-{
- HRESULT result = S_OK;
- mitk::TDMouseEventThrower::GetInstance()->KeyUp (keyCode);
- return result;
-}
-
-#define ScaleRotation 1024.0
-#define ScaleTranslation 512.0
-#define Sensitivity 1.0
-
-HRESULT SpaceNavigatorDriver::OnSensorInput(void)
-{
- HRESULT result = S_OK;
- static DWORD s_dwLastDraw = 0;
-
- //cout << "CCubeWindow::OnSensorInput()";
- try {
- CComPtr<IAngleAxis> pRotation;
- HRESULT hr = m_pISensor->get_Rotation(&pRotation);
-
- double angle;
- pRotation->get_Angle(&angle);
-
- CComPtr<IVector3D> pTranslation;
- hr = m_pISensor->get_Translation(&pTranslation);
-
- double length;
- pTranslation->get_Length(&length);
-
- if (angle > 0. || length > 0.)
- {
- mitk::Vector3D translation;
- mitk::Vector3D rotation;
- double val;
-
- double timeFactor = 1.;
-
- DWORD dwNow = ::GetTickCount();
- if (s_dwLastDraw)
- {
- double period;
- m_pISensor->get_Period(&period);
- timeFactor = (double)(dwNow-s_dwLastDraw)/period;
- }
- s_dwLastDraw = dwNow;
-
- length *= timeFactor;
- length /= ScaleTranslation*Sensitivity;
-
- pTranslation->put_Length(length);
-
- pTranslation->get_X(&val);
- translation[0] = (float)val;
- pTranslation->get_Y(&val);
- translation[1] = (float)val;
- pTranslation->get_Z(&val);
- translation[2] = (float)val;
-
- pRotation->get_X(&val);
- rotation[0] = (float)val;
- pRotation->get_Y(&val);
- rotation[1] = (float)val;
- pRotation->get_Z(&val);
- rotation[2] = (float)val;
-
- angle *= timeFactor;
- angle /= ScaleRotation*Sensitivity;
-
- mitk::TDMouseEventThrower::GetInstance()->SensorInput( translation, rotation, angle);
- //cout << translation[0] << "\t" << translation[1] << "\t" << translation[2] << endl;
- }
- else
- s_dwLastDraw = 0;
-
- pRotation.Release();
- pTranslation.Release();
- }
- catch (...)
- {
- cout << "Some sort of exception handling" << endl;
- }
-
- return result;
-}
-
-HRESULT SpaceNavigatorDriver::UninitializeCOM()
-{
- HRESULT hr;
- CComPtr<IUnknown> _3DxDevice;
-
- // Create the device object
- hr = _3DxDevice.CoCreateInstance(__uuidof(Device));
- if (SUCCEEDED(hr))
- {
- CComPtr<ISimpleDevice> _3DxSimpleDevice;
- _3DxDevice.QueryInterface(&_3DxSimpleDevice);
- _3DxSimpleDevice->Disconnect();
- }
-
-
- if (m_pISensor)
- {
- // unhook (unadvise) the sensor event sink
- __unhook(&_ISensorEvents::SensorInput, m_pISensor,
- &SpaceNavigatorDriver::OnSensorInput);
-
- m_pISensor.Release();
- }
-
- if (m_pIKeyboard)
- {
- __unhook(&_IKeyboardEvents::KeyDown, m_pIKeyboard,
- &SpaceNavigatorDriver::OnKeyDown);
-
- m_pIKeyboard.Release();
- }
-
- return hr;
-}
diff --git a/Modules/Ext/Interactions/mitkSurfaceDeformationInteractor3D.cpp b/Modules/Ext/Interactions/mitkSurfaceDeformationInteractor3D.cpp
deleted file mode 100644
index f385279407..0000000000
--- a/Modules/Ext/Interactions/mitkSurfaceDeformationInteractor3D.cpp
+++ /dev/null
@@ -1,498 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkSurfaceDeformationInteractor3D.h"
-#include "mitkPointOperation.h"
-#include "mitkDisplayPositionEvent.h"
-#include "mitkWheelEvent.h"
-#include "mitkStatusBar.h"
-#include "mitkDataNode.h"
-#include "mitkInteractionConst.h"
-#include "mitkAction.h"
-#include "mitkStateEvent.h"
-#include "mitkOperationEvent.h"
-#include "mitkUndoController.h"
-#include "mitkStateMachineFactory.h"
-#include "mitkStateTransitionOperation.h"
-#include "mitkBaseRenderer.h"
-#include "mitkRenderingManager.h"
-#include "mitkSurface.h"
-
-
-#include <vtkRenderWindow.h>
-#include <vtkRenderWindowInteractor.h>
-#include <vtkInteractorStyle.h>
-#include <vtkPolyData.h>
-#include <vtkPointData.h>
-#include <vtkDataArray.h>
-#include <vtkPointData.h>
-#include <vtkDataArray.h>
-
-
-//how precise must the user pick the point
-//default value
-mitk::SurfaceDeformationInteractor3D
-::SurfaceDeformationInteractor3D(const char * type, DataNode* dataNode, int /* n */ )
-: Interactor( type, dataNode ),
- m_Precision( 6.5 ),
- m_PickedSurfaceNode( NULL ),
- m_PickedSurface( NULL ),
- m_GaussSigma( 30.0 )
-{
- m_OriginalPolyData = vtkPolyData::New();
-
- // Initialize vector arithmetic
- m_ObjectNormal[0] = 0.0;
- m_ObjectNormal[1] = 0.0;
- m_ObjectNormal[2] = 1.0;
-}
-
-mitk::SurfaceDeformationInteractor3D::~SurfaceDeformationInteractor3D()
-{
- m_OriginalPolyData->Delete();
-}
-
-void mitk::SurfaceDeformationInteractor3D::SetPrecision( mitk::ScalarType precision )
-{
- m_Precision = precision;
-}
-
-// Overwritten since this class can handle it better!
-float mitk::SurfaceDeformationInteractor3D
-::CanHandleEvent(StateEvent const* stateEvent) const
-{
- float returnValue = 0.5;
-
-
- // If it is a key event that can be handled in the current state,
- // then return 0.5
- mitk::DisplayPositionEvent const *disPosEvent =
- dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
-
- // Key event handling:
- if (disPosEvent == NULL)
- {
- // Check if the current state has a transition waiting for that key event.
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- return 0.5;
- }
- else
- {
- return 0.0;
- }
- }
-
- //on MouseMove do nothing!
- //if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
- //{
- // return 0.0;
- //}
-
- //if the event can be understood and if there is a transition waiting for that event
- if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
- {
- returnValue = 0.5;//it can be understood
- }
-
- //int timeStep = disPosEvent->GetSender()->GetTimeStep();
-
- //mitk::CurveModel *curveModel = dynamic_cast<mitk::CurveModel *>(
- // m_DataNode->GetData() );
-
- //if ( curveModel != NULL )
- //{
- // // Get the PlaneGeometry of the window the user interacts with (for 2D point
- // // projection)
- // mitk::BaseRenderer *renderer = stateEvent->GetEvent()->GetSender();
- // const PlaneGeometry *projectionPlane = renderer->GetCurrentWorldPlaneGeometry();
-
- // // For reading on the points, Ids etc
- // //mitk::CurveModel::PointSetType *pointSet = curveModel->GetPointSet( timeStep );
- // //if ( pointSet == NULL )
- // //{
- // // return 0.0;
- // //}
-
- //}
- return returnValue;
-}
-
-
-bool mitk::SurfaceDeformationInteractor3D
-::ExecuteAction( Action *action, mitk::StateEvent const *stateEvent )
-{
- bool ok = false;
-
- // Get data object
- mitk::BaseData *data = m_DataNode->GetData();
- if ( data == NULL )
- {
- MITK_ERROR << "No data object present!";
- return ok;
- }
-
- // Get mitk::Event and extract renderer
- const mitk::Event *event = stateEvent->GetEvent();
- mitk::BaseRenderer *renderer = NULL;
- vtkRenderWindow *renderWindow = NULL;
- vtkRenderWindowInteractor *renderWindowInteractor = NULL;
-
- if ( event != NULL )
- {
- renderer = event->GetSender();
- if ( renderer != NULL )
- {
- renderWindow = renderer->GetRenderWindow();
- if ( renderWindow != NULL )
- {
- renderWindowInteractor = renderWindow->GetInteractor();
- }
- }
- }
-
- // Check if we have a DisplayPositionEvent
- const mitk::DisplayPositionEvent *dpe =
- dynamic_cast< const mitk::DisplayPositionEvent * >( stateEvent->GetEvent() );
- if ( dpe != NULL )
- {
- m_PickedSurfaceNode = dpe->GetPickedObjectNode();
- m_CurrentPickedPoint = dpe->GetWorldPosition();
- m_CurrentPickedDisplayPoint = dpe->GetDisplayPosition();
- }
-
-
- // Get the timestep to also support 3D+t
- int timeStep = 0;
- mitk::ScalarType timeInMS = 0.0;
- if ( renderer != NULL )
- {
- timeStep = renderer->GetTimeStep( data );
- timeInMS = renderer->GetTime();
- }
-
- // Extract surface
- m_Surface = dynamic_cast< Surface * >( data );
- if ( m_Surface != NULL )
- {
- m_PolyData = m_Surface->GetVtkPolyData( timeStep );
- }
- else
- {
- m_PolyData = NULL;
- }
-
- // Extract surface normal from surface (if existent, otherwise use default)
- vtkPointData *pointData = m_PolyData->GetPointData();
- if ( pointData != NULL )
- {
- vtkDataArray *normal = m_PolyData->GetPointData()->GetVectors( "planeNormal" );
- if ( normal != NULL )
- {
- m_ObjectNormal[0] = normal->GetComponent( 0, 0 );
- m_ObjectNormal[1] = normal->GetComponent( 0, 1 );
- m_ObjectNormal[2] = normal->GetComponent( 0, 2 );
- }
- }
-
- // Get geometry object
- m_Geometry = data->GetGeometry( timeStep );
-
-
- // Make sure that the data (if time-resolved) has enough entries;
- // if not, create the required extra ones (empty)
- data->Expand( timeStep+1 );
-
-
- switch (action->GetActionId())
- {
- case AcDONOTHING:
- ok = true;
- break;
-
-
- case AcCHECKOBJECT:
- {
- // Check if an object is present at the current mouse position
- m_PickedSurface = NULL;
- m_PickedPolyData = NULL;
-
- if ( m_PickedSurfaceNode != NULL )
- {
- m_PickedSurface = dynamic_cast< mitk::Surface * >( m_PickedSurfaceNode->GetData() );
- if ( m_PickedSurface != NULL )
- {
- m_PickedPolyData = m_PickedSurface->GetVtkPolyData( timeStep );
- }
- }
-
- mitk::StateEvent *newStateEvent;
- if ( (m_PickedSurfaceNode == m_DataNode) && (m_PickedSurface != NULL) )
- {
- // Yes: object will be selected
- newStateEvent = new mitk::StateEvent( EIDYES );
-
- // Disable VTK interactor until MITK interaction has been completed
- if ( renderWindowInteractor != NULL )
- {
- renderWindowInteractor->Disable();
- }
- }
- else
- {
- // No: back to start state
- newStateEvent = new mitk::StateEvent( EIDNO );
-
- // Re-enable VTK interactor (may have been disabled previously)
- if ( renderWindowInteractor != NULL )
- {
- renderWindowInteractor->Enable();
- }
- }
-
- this->HandleEvent( newStateEvent );
-
- // Colorized surface at current picked position
- m_SurfaceColorizationCenter = m_CurrentPickedPoint;
-
- ok = true;
- break;
- }
-
- case AcDESELECTOBJECT:
- {
- // Color object white
- m_DataNode->SetColor( 1.0, 1.0, 1.0 );
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
-
- // Colorize surface / wireframe as inactive
- this->ColorizeSurface( m_PolyData,
- m_SurfaceColorizationCenter, COLORIZATION_CONSTANT, -1.0 );
-
- ok = true;
- break;
- }
-
- case AcSELECTPICKEDOBJECT:
- {
- // Color object red
- m_DataNode->SetColor( 1.0, 0.0, 0.0 );
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
-
- // Colorize surface / wireframe dependend on distance from picked point
- this->ColorizeSurface( m_PolyData,
- m_SurfaceColorizationCenter, COLORIZATION_GAUSS );
-
- ok = true;
- break;
- }
-
- case AcINITMOVE:
- {
- // Store current picked point
- m_InitialPickedPoint = m_CurrentPickedPoint;
- m_InitialPickedDisplayPoint = m_CurrentPickedDisplayPoint;
-
- if ( renderWindowInteractor != NULL )
- {
- vtkInteractorObserver::ComputeDisplayToWorld(
- renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(),
- m_InitialPickedDisplayPoint[0],
- m_InitialPickedDisplayPoint[1],
- 0.0, //m_InitialInteractionPickedPoint[2],
- m_InitialPickedPointWorld );
- }
-
-
- // Make deep copy of vtkPolyData interacted on
- m_OriginalPolyData->DeepCopy( m_PolyData );
-
- ok = true;
- break;
- }
-
- case AcMOVE:
- {
- if ( renderWindowInteractor != NULL )
- {
- vtkInteractorObserver::ComputeDisplayToWorld(
- renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(),
- m_CurrentPickedDisplayPoint[0],
- m_CurrentPickedDisplayPoint[1],
- 0.0, //m_InitialInteractionPickedPoint[2],
- m_CurrentPickedPointWorld );
- }
-
-
- // Calculate mouse move in 3D space
- mitk::Vector3D interactionMove;
- interactionMove[0] = m_CurrentPickedPointWorld[0] - m_InitialPickedPointWorld[0];
- interactionMove[1] = m_CurrentPickedPointWorld[1] - m_InitialPickedPointWorld[1];
- interactionMove[2] = m_CurrentPickedPointWorld[2] - m_InitialPickedPointWorld[2];
-
- // Transform mouse move into geometry space
- data->UpdateOutputInformation(); // make sure that the Geometry is up-to-date
- mitk::Point3D origin; origin.Fill( 0.0 );
- mitk::Vector3D interactionMoveIndex;
- m_Geometry->WorldToIndex( interactionMove, interactionMoveIndex );
-
-
- // Get picked point and transform into local coordinates
- mitk::Point3D pickedPoint;
- m_Geometry->WorldToIndex( m_InitialPickedPoint, pickedPoint );
- mitk::Vector3D v1 = pickedPoint.GetVectorFromOrigin();
-
- mitk::Vector3D v2 = m_ObjectNormal * (interactionMoveIndex * m_ObjectNormal);
-
-
- vtkPoints *originalPoints = m_OriginalPolyData->GetPoints();
- vtkPoints *deformedPoints = m_PolyData->GetPoints();
-
- double denom = m_GaussSigma * m_GaussSigma * 2;
- double point[3];
- for ( unsigned int i = 0; i < deformedPoints->GetNumberOfPoints(); ++i )
- {
- // Get original point
- double *originalPoint = originalPoints->GetPoint( i );
- mitk::Vector3D v0;
- v0[0] = originalPoint[0];
- v0[1] = originalPoint[1];
- v0[2] = originalPoint[2];
-
-
- // Calculate distance of this point from line through picked point
- double d = itk::CrossProduct( m_ObjectNormal, (v1 - v0) ).GetNorm();
-
- mitk::Vector3D t = v2 * exp( - d * d / denom );
-
- point[0] = originalPoint[0] + t[0];
- point[1] = originalPoint[1] + t[1];
- point[2] = originalPoint[2] + t[2];
- deformedPoints->SetPoint( i, point );
- }
-
- // Make sure that surface is colorized at initial picked position
- // as long as we are in deformation state
- m_SurfaceColorizationCenter = m_InitialPickedPoint;
-
- m_PolyData->Modified();
- m_Surface->Modified();
-
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- ok = false;
- break;
- }
-
- case AcMODIFY:
- {
- // Check if we have an mitk::WheelEvent
- const mitk::WheelEvent *we =
- dynamic_cast< const mitk::WheelEvent * >( stateEvent->GetEvent() );
- if ( we == NULL )
- {
- ok = true;
- break;
- }
-
- m_GaussSigma += (double) (we->GetDelta()) / 20;;
- if ( m_GaussSigma < 10.0 )
- {
- m_GaussSigma = 10.0;
- }
- else if ( m_GaussSigma > 128.0 )
- {
- m_GaussSigma = 128.0;
- }
-
- // Colorize surface / wireframe dependend on sigma and distance from picked point
- this->ColorizeSurface( m_PolyData,
- m_SurfaceColorizationCenter, COLORIZATION_GAUSS );
-
-
- mitk::RenderingManager::GetInstance()->RequestUpdateAll(
- mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS );
- ok = true;
- break;
- }
-
-
- default:
- return Superclass::ExecuteAction( action, stateEvent );
- }
-
- return ok;
-}
-
-
-bool mitk::SurfaceDeformationInteractor3D::ColorizeSurface( vtkPolyData *polyData,
- const Point3D &pickedPoint, int mode, double scalar )
-{
- if ( polyData == NULL )
- {
- return false;
- }
-
- vtkPoints *points = polyData->GetPoints();
- vtkPointData *pointData = polyData->GetPointData();
- if ( pointData == NULL )
- {
- return false;
- }
-
- vtkDataArray *scalars = pointData->GetScalars();
- if ( scalars == NULL )
- {
- return false;
- }
-
- if ( mode == COLORIZATION_GAUSS )
- {
- // Get picked point and transform into local coordinates
- mitk::Point3D localPickedPoint;
- m_Geometry->WorldToIndex( pickedPoint, localPickedPoint );
- mitk::Vector3D v1 = localPickedPoint.GetVectorFromOrigin();
-
- double denom = m_GaussSigma * m_GaussSigma * 2;
- for ( unsigned int i = 0; i < points->GetNumberOfPoints(); ++i )
- {
- // Get original point
- double *point = points->GetPoint( i );
- mitk::Vector3D v0;
- v0[0] = point[0];
- v0[1] = point[1];
- v0[2] = point[2];
-
- // Calculate distance of this point from line through picked point
- double d = itk::CrossProduct( m_ObjectNormal, (v1 - v0) ).GetNorm();
- double t = exp( - d * d / denom );
-
- scalars->SetComponent( i, 0, t );
- }
- }
- else if ( mode == COLORIZATION_CONSTANT )
- {
- for ( unsigned int i = 0; i < pointData->GetNumberOfTuples(); ++i )
- {
- scalars->SetComponent( i, 0, scalar );
- }
- }
-
- polyData->Modified();
- pointData->Update();
-
- return true;
-}
diff --git a/Modules/Ext/Interactions/mitkSurfaceDeformationInteractor3D.h b/Modules/Ext/Interactions/mitkSurfaceDeformationInteractor3D.h
deleted file mode 100644
index b61be85aeb..0000000000
--- a/Modules/Ext/Interactions/mitkSurfaceDeformationInteractor3D.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSURFACEDEFORMATIONINTERACTOR3D_H_HEADER_INCLUDED
-#define MITKSURFACEDEFORMATIONINTERACTOR3D_H_HEADER_INCLUDED
-
-#include "mitkInteractor.h"
-#include "MitkExtExports.h"
-#include "mitkCommon.h"
-
-#include <vtkType.h>
-
-class vtkPolyData;
-
-namespace mitk
-{
-
-class DataNode;
-class Surface;
-
-/**
- * \brief Affine interaction with objects in 3D windows.
- *
- * NOTE: The interaction mechanism is similar to that of vtkPlaneWidget
- *
- * \ingroup Interaction
- */
-class MitkExt_EXPORT SurfaceDeformationInteractor3D : public Interactor
-{
-public:
- mitkClassMacro(SurfaceDeformationInteractor3D, Interactor);
- mitkNewMacro3Param(Self, const char *, DataNode *, int);
- mitkNewMacro2Param(Self, const char *, DataNode *);
-
- /** \brief Sets the amount of precision */
- void SetPrecision( ScalarType precision );
-
- /**
- * \brief calculates how good the data, this statemachine handles, is hit
- * by the event.
- *
- * overwritten, cause we don't look at the boundingbox, we look at each point
- */
- virtual float CanHandleEvent(StateEvent const *stateEvent) const;
-
-
-protected:
- /**
- * \brief Constructor with Param n for limited Set of Points
- *
- * if no n is set, then the number of points is unlimited*
- */
- SurfaceDeformationInteractor3D(const char *type,
- DataNode *dataNode, int n = -1);
-
- /**
- * \brief Default Destructor
- **/
- virtual ~SurfaceDeformationInteractor3D();
-
- virtual bool ExecuteAction( Action* action,
- mitk::StateEvent const* stateEvent );
-
- enum
- {
- COLORIZATION_GAUSS,
- COLORIZATION_CONSTANT
- };
-
- bool ColorizeSurface( vtkPolyData *polyData, const Point3D &pickedPoint,
- int mode, double scalar = 0.0 );
-
-
-private:
-
- /** \brief to store the value of precision to pick a point */
- ScalarType m_Precision;
-
- Point3D m_InitialPickedPoint;
- Point2D m_InitialPickedDisplayPoint;
- double m_InitialPickedPointWorld[4];
-
- Point3D m_CurrentPickedPoint;
- Point2D m_CurrentPickedDisplayPoint;
- double m_CurrentPickedPointWorld[4];
-
- Point3D m_SurfaceColorizationCenter;
-
- Vector3D m_ObjectNormal;
-
- BaseGeometry::Pointer m_Geometry;
-
- Surface *m_Surface;
- vtkPolyData *m_PolyData;
-
- DataNode *m_PickedSurfaceNode;
- Surface *m_PickedSurface;
- vtkPolyData *m_PickedPolyData;
-
- vtkPolyData *m_OriginalPolyData;
-
- double m_GaussSigma;
-
-};
-
-}
-
-#endif /* MITKSURFACEDEFORMATIONINTERACTOR3D_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Interactions/mitkSurfaceInteractor.cpp b/Modules/Ext/Interactions/mitkSurfaceInteractor.cpp
deleted file mode 100644
index dcf25b7f09..0000000000
--- a/Modules/Ext/Interactions/mitkSurfaceInteractor.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkSurfaceInteractor.h"
-#include "mitkPointLocator.h"
-#include "mitkSurface.h"
-
-#include "mitkStateEvent.h"
-#include "mitkInteractionConst.h"
-#include "mitkBaseRenderer.h"
-
-#include <vtkPolyData.h>
-
-mitk::SurfaceInteractor::SurfaceInteractor(const char * type, DataNode* dataNode)
-: AffineInteractor(type, dataNode)
-{
- m_PtLoc = PLocType::New();
-}
-
-
-float mitk::SurfaceInteractor::CanHandleEvent( StateEvent const* stateEvent ) const
-{
- float jd = 0.0f;
-
- if( ! ( stateEvent->GetEvent()->GetButtonState() == mitk::BS_ControlButton && stateEvent->GetEvent()->GetType() == mitk::Type_MouseButtonPress ))
- return jd;
-
- if ( stateEvent->GetEvent()->GetSender()->GetMapperID() == mitk::BaseRenderer::Standard3D )
- return jd;
-
- mitk::Surface* surf = dynamic_cast<mitk::Surface*>(this->GetData());
- if (surf)
- {
- mitk::DisplayPositionEvent const *event = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
- mitk::PointSet::PointType pt = event->GetWorldPosition();
-
- // Use ANN to get the point of the polydata closest to the world event
- if( surf->GetVtkPolyData(m_TimeStep) == NULL ) itkExceptionMacro(<< "No polydata at this time step!");
- m_PtLoc->SetPoints(dynamic_cast<vtkPointSet*>(surf->GetVtkPolyData(m_TimeStep)));
- mitk::PointLocator::DistanceType dst = m_PtLoc->GetMinimalDistance(pt);
-
- mitk::BaseRenderer* ren = stateEvent->GetEvent()->GetSender();
-
- // Get the diameter of the render window bounding box
- mitk::DataStorage* storage = ren->GetDataStorage();
- mitk::BoundingBox::Pointer bb = storage->ComputeBoundingBox();
- mitk::BoundingBox::AccumulateType dia = std::sqrt(bb->GetDiagonalLength2());
-
- if (dia > 0.00001) //if diameter not zero
- {
- float verh = dst/dia;
- if (verh>1) verh = 1; //if dst is bigger than dia, then set to 1
- //now inverse (0 = bad and 1 = good) and set between 0.5 and 1
- jd = ((1-verh)/2)+0.5f;
- }
- }
- return jd;
-}
diff --git a/Modules/Ext/Interactions/mitkSurfaceInteractor.h b/Modules/Ext/Interactions/mitkSurfaceInteractor.h
deleted file mode 100644
index 5d4f59bb00..0000000000
--- a/Modules/Ext/Interactions/mitkSurfaceInteractor.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKSURFACEINTERACTOR_H_HEADER_INCLUDED
-#define MITKSURFACEINTERACTOR_H_HEADER_INCLUDED
-
-#include "mitkAffineInteractor.h"
-#include "MitkExtExports.h"
-#include "mitkPointLocator.h"
-
-namespace mitk {
-
- //##Documentation
- //## @brief Interactor for Affine transformations on one or multiple surfaces
- //##
- //## A surface interacted by this class can translate, rotate and scale
- //## by modifying its geometry. The surface closest to the picking point is
- //## chosen for interaction automatically by CanHandleEvent
- //## @ingroup Interaction
- class MitkExt_EXPORT SurfaceInteractor : public AffineInteractor
- {
- public:
- mitkClassMacro(SurfaceInteractor,AffineInteractor);
- // itkFactorylessNewMacro(Self)
- // itkCloneMacro(Self)
- mitkNewMacro2Param(Self, const char*, DataNode*);
-
- protected:
-
- //##Documentation
- //## @brief Constructor
- //##
- //## @param dataNode is the node, this Interactor is connected to
- //## @param type is the type of StateMachine like declared in the XML-Configure-File
- SurfaceInteractor(const char * type, DataNode* dataNode);
-
- //##Documentation
- //## @brief Destructor
- ~SurfaceInteractor(){};
-
- //##Documentation
- //## @brief calculates how good the data this state machine handles is hit by the event.
- //##
- //## Returns a value between 0 and 1.
- //## (Used by GlobalInteraction to decide which DESELECTED state machine to send the event to.)
- //##
- //## \WARNING This is interactor currently does not work for interaction in 3D. Try using mitkAffineInteractor3D instead.
- virtual float CanHandleEvent(StateEvent const* stateEvent) const;
-
- private:
-
- typedef PointLocator PLocType;
- typedef PLocType::Pointer PLPointer;
-
- PLPointer m_PtLoc;
-
- };
-
-} // namespace mitk
-
-#endif /* MITKSURFACEINTERACTOR_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Interactions/mitkTDMouseEvent.cpp b/Modules/Ext/Interactions/mitkTDMouseEvent.cpp
deleted file mode 100644
index 13e62055d0..0000000000
--- a/Modules/Ext/Interactions/mitkTDMouseEvent.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkTDMouseEvent.h"
-#include "mitkInteractionConst.h"
-#include "mitkNumericTypes.h"
-
-mitk::TDMouseEvent::TDMouseEvent(int buttonState, const Vector3D& translation, const Vector3D& rotation, const ScalarType& angle)
-: Event(NULL, Type_TDMouseInput, BS_NoButton, buttonState, Key_none), m_Translation(translation), m_Rotation(rotation), m_Angle(angle)
-{
-}
diff --git a/Modules/Ext/Interactions/mitkTDMouseEvent.h b/Modules/Ext/Interactions/mitkTDMouseEvent.h
deleted file mode 100644
index 9e69d43eb3..0000000000
--- a/Modules/Ext/Interactions/mitkTDMouseEvent.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef TDMOUSEEVENT_H_HEADER_INCLUDED
-#define TDMOUSEEVENT_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "mitkEvent.h"
-#include "mitkNumericTypes.h"
-
-
-namespace mitk {
-
-//##Documentation
-//## @brief Event on 3D Mouse input
-//##
-//## Seven coordinates exposed by the 3D Mouse:
-//## 3-dimensional translation vector
-//## 3-dimensional rotation achsis (length allways 1.0)
-//## scalar rotation angle
-//## @ingroup Interaction
-class TDMouseEvent : public Event
-{
- public:
- //##Documentation
- //## @brief Constructor with all necessary arguments.
- //##
- //## buttonState: information from the Event
- TDMouseEvent(int buttonState, const Vector3D& translation, const Vector3D& rotation, const ScalarType& angle);
-
- const Vector3D& GetTranslation() const
- {
- return m_Translation;
- }
-
- void SetTranslation(const Vector3D& translation) { m_Translation = translation; }
-
- const Vector3D& GetRotation() const
- {
- return m_Rotation;
- }
-
- void SetRotation(const Vector3D& rotation) { m_Rotation = rotation; }
-
- const ScalarType& GetAngle() const
- {
- return m_Angle;
- }
-
- void SetAngle(const ScalarType& angle) { m_Angle = angle; }
-
-
- protected:
- Vector3D m_Translation;
- Vector3D m_Rotation;
- ScalarType m_Angle;
-
-};
-
-} // namespace mitk
-
-#endif /* TDMOUSEEVENT_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Interactions/mitkTDMouseEventThrower.cpp b/Modules/Ext/Interactions/mitkTDMouseEventThrower.cpp
deleted file mode 100644
index b419761930..0000000000
--- a/Modules/Ext/Interactions/mitkTDMouseEventThrower.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkTDMouseEventThrower.h"
-#include "mitkTDMouseEvent.h"
-#include "mitkInteractionConst.h"
-#include "mitkNumericTypes.h"
-#include "mitkGlobalInteraction.h"
-#include "mitkStateEvent.h"
-#include "mitkSpaceNavigatorDriver.h"
-
-
-mitk::TDMouseEventThrower * mitk::TDMouseEventThrower::GetInstance()
-{
- //instance will not be initialize and return 0
- static TDMouseEventThrower instance;
- return &instance;
-}
-
-mitk::TDMouseEventThrower::TDMouseEventThrower()
-{
- //init the driver
- SpaceNavigatorDriver* spaceNavigatorDriver = SpaceNavigatorDriver::GetInstance();
-}
-
-mitk::TDMouseEventThrower::~TDMouseEventThrower()
-{
-}
-
-void mitk::TDMouseEventThrower::DeviceChange (long device, long keys, long programmableKeys)
-{
-}
-
-void mitk::TDMouseEventThrower::KeyDown (int keyCode)
-{
- //send the informations to GlobalInteraction
- mitk::Event* e = new mitk::Event(NULL, mitk::Type_TDMouseKeyDown, mitk::BS_LeftButton, keyCode, mitk::Key_none);
- mitk::StateEvent* se = new mitk::StateEvent(mitk::EIDTDMOUSEKEYDOWN, e);
- mitk::GlobalInteraction::GetInstance()->HandleEvent(se);
-}
-
-void mitk::TDMouseEventThrower::KeyUp (int keyCode)
-{
-}
-
-void mitk::TDMouseEventThrower::SensorInput( mitk::Vector3D translation, mitk::Vector3D rotation, mitk::ScalarType angle)
-{
- mitk::TDMouseEvent* e = new mitk::TDMouseEvent(mitk::BS_NoButton, translation, rotation, angle);
- mitk::StateEvent* se = new mitk::StateEvent(mitk::EIDTDMOUSEINPUT, e);
- mitk::GlobalInteraction::GetInstance()->HandleEvent(se);
-}
diff --git a/Modules/Ext/Interactions/mitkTDMouseEventThrower.h b/Modules/Ext/Interactions/mitkTDMouseEventThrower.h
deleted file mode 100644
index 9f86a61f32..0000000000
--- a/Modules/Ext/Interactions/mitkTDMouseEventThrower.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef TDMouseEventThrower__h__
-#define TDMouseEventThrower__h__
-
-#include <mitkNumericTypes.h>
-#include <iostream>
-
-namespace mitk {
-
- class TDMouseEventThrower
- {
- public:
-
- static TDMouseEventThrower* GetInstance();
-
- void DeviceChange (long device, long keys, long programmableKeys);
- void KeyDown (int keyCode);
- void KeyUp (int keyCode);
- void SensorInput( mitk::Vector3D translation, mitk::Vector3D rotation, mitk::ScalarType angle);
-
- protected:
- TDMouseEventThrower();
- ~TDMouseEventThrower();
- };
-
-}//namespace
-
-#endif // TDMouseEventThrower__h__
diff --git a/Modules/Ext/Rendering/mitkGLUT.h b/Modules/Ext/Rendering/mitkGLUT.h
deleted file mode 100644
index c273feff62..0000000000
--- a/Modules/Ext/Rendering/mitkGLUT.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKGLUT_H_HEADER_INCLUDED
-#define MITKGLUT_H_HEADER_INCLUDED
-
-// Since 7.8.07 MITK is not using/requiring GLUT anymore.
-
-#ifdef __APPLE__
-//#include <glut.h>
-#else
-//#include <GL/glut.h>
-#endif
-
-#endif /* MITKGLUT_H_HEADER_INCLUDED */
-
diff --git a/Modules/Ext/Rendering/mitkImageBackground2D.cpp b/Modules/Ext/Rendering/mitkImageBackground2D.cpp
deleted file mode 100644
index 77df492c68..0000000000
--- a/Modules/Ext/Rendering/mitkImageBackground2D.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkImageBackground2D.h"
-// MITK includes
-#include "mitkVtkLayerController.h"
-
-// VTK includes
-#include "vtkSystemIncludes.h"
-#include "vtkRenderer.h"
-#include "vtkMapper.h"
-#include "vtkObjectFactory.h"
-#include "vtkImageActor.h"
-#include "vtkRenderWindow.h"
-#include "vtkImageImport.h"
-#include "vtkCommand.h"
-#include "vtkCamera.h"
-
-#include <iostream>
-
-// VTK CALLBACK for automatic resize of the video
-class vtkVideoSizeCallback : public vtkCommand
-{
-public:
- static vtkVideoSizeCallback *New(){ return new vtkVideoSizeCallback; }
-
- vtkRenderer * m_ImageRenderer;
- int m_ImageWidth, m_ImageHeight;
-
- void SetVtkVideoRenderer(vtkRenderer* r)
- {
- m_ImageRenderer = r;
- }
- void SetVideoDimensions(int x, int y)
- {
- m_ImageWidth = x; m_ImageHeight = y;
- }
-
- virtual void Execute(vtkObject* /*caller*/, unsigned long, void*)
- {
- //vtkRenderWindow * RenderWindow = reinterpret_cast<vtkRenderWindow*>(caller);
- //m_ImageRenderer->ResetCameraClippingRange();
- }
-};
-
-mitk::ImageBackground2D::ImageBackground2D()
-{
- m_ImageWidth = 0;
- m_ImageHeight = 0;
- m_ImageScalarComponents = 3;
- m_ParallelScale = 0;
- m_RenderWindow = NULL;
-
- m_Actor = vtkImageActor::New();
- m_ImageRenderer = vtkRenderer::New();
- m_VtkImageImport = vtkImageImport::New();
-
- m_ImageData = NULL;
-}
-
-void mitk::ImageBackground2D::InitVtkImageImport()
-{
- /*m_VtkImageImport->Delete();
- m_VtkImageImport = vtkImageImport::New();*/
- m_VtkImageImport->SetDataScalarTypeToUnsignedChar();
- m_VtkImageImport->SetNumberOfScalarComponents(m_ImageScalarComponents);
- m_VtkImageImport->SetWholeExtent(0,m_ImageWidth-1,0,m_ImageHeight-1,0,1-1);
- m_VtkImageImport->SetDataExtentToWholeExtent();
-}
-
-mitk::ImageBackground2D::~ImageBackground2D()
-{
- if ( m_RenderWindow != NULL )
- if ( this->IsEnabled() )
- this->Disable();
- if ( m_Actor!=NULL )
- m_Actor->Delete();
- if ( m_ImageRenderer != NULL )
- m_ImageRenderer->Delete();
- if ( m_VtkImageImport != NULL)
- m_VtkImageImport->Delete();
-}
-/**
- * Sets the renderwindow, in which the Video background
- * will be shown. Make sure, you have called this function
- * before calling Enable()
- */
-void mitk::ImageBackground2D::SetRenderWindow(vtkRenderWindow* renderWindow )
-{
- m_RenderWindow = renderWindow;
-
- /*m_SizeCallback = vtkVideoSizeCallback::New();
- m_RenderWindow->GetVtkRenderWindow()->AddObserver(vtkCommand::ModifiedEvent,m_SizeCallback);*/
-
-}
-
-void mitk::ImageBackground2D::SetParallelScale(int scale)
-{
- m_ParallelScale = scale;
- m_ImageRenderer->GetActiveCamera()->SetParallelScale(m_ParallelScale);
-}
-int mitk::ImageBackground2D::GetParallelScale()
-{
- // TODO someone who knows this, check if double->int could cause problems
- return static_cast<int>(m_ImageRenderer->GetActiveCamera()->GetParallelScale());
-}
-/**
- * Enables drawing of the color Video background.
- * If you want to disable it, call the Disable() function.
- */
-void mitk::ImageBackground2D::Enable()
-{
- m_ImageRenderer = vtkRenderer::New();
-
- mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertBackgroundRenderer(m_ImageRenderer,true);
-
- char * c = 0;
- Update(c);
- m_Actor->SetInputData(m_VtkImageImport->GetOutput());
-
- m_ImageRenderer->AddActor2D(m_Actor);
- m_ImageRenderer->ResetCamera();
- m_ImageRenderer->InteractiveOff();
- m_ImageRenderer->GetActiveCamera()->ParallelProjectionOn();
- if(m_ParallelScale == 0)
- m_ImageRenderer->GetActiveCamera()->SetParallelScale(m_ImageHeight/2);
-
- //m_SizeCallback->SetVtkVideoRenderer(m_ImageRenderer);
- //m_SizeCallback->SetVideoDimensions(m_ImageWidth, m_ImageHeight);
-
-}
-
-/**
- * Disables drawing of the color Video background.
- * If you want to enable it, call the Enable() function.
- */
-void mitk::ImageBackground2D::Disable()
-{
- if ( this->IsEnabled() )
- mitk::VtkLayerController::GetInstance(m_RenderWindow)->RemoveRenderer(m_ImageRenderer);
-}
-/**
- * Checks, if the Video background is currently
- * enabled (visible)
- */
-bool mitk::ImageBackground2D::IsEnabled()
-{
- if ( mitk::VtkLayerController::GetInstance(m_RenderWindow)->IsRendererInserted(m_ImageRenderer))
- return true;
- else
- return false;
-}
-
-void mitk::ImageBackground2D::Update(char * dataPointer)
-{
- if(!IsEnabled())
- return;
-
- // VTK import image data must be allocated before import (with correct parameters)
- if(m_ImageData == NULL)
- m_ImageData = new unsigned char[m_ImageHeight*m_ImageWidth*m_ImageScalarComponents];
-
- if(!dataPointer)
- {// no valid image pointer provided -> initialize black image
- unsigned char* b = m_ImageData;
- for ( int textCounter = 0; textCounter < (m_ImageHeight*m_ImageWidth*m_ImageScalarComponents); textCounter++ )
- *b++ = 0;
- }
-
- m_VtkImageImport->SetImportVoidPointer(m_ImageData);
- m_VtkImageImport->Modified();
- m_VtkImageImport->Update();
- m_RenderWindow->Render();
-
-}
-
-void mitk::ImageBackground2D::Update(char * dataPointer, int width, int height, int imageScalarComponents)
-{
- // no image-backround layer is rendered
- if(!IsEnabled())
- return;
-
- // image contains no data, OR image scalar components missmatch (no RGB, no greyscale)
- if(!dataPointer || (imageScalarComponents != 1 && imageScalarComponents != 3))
- {
- // no valid image pointer provided -> we initialize black image
- if(m_ImageData == NULL)
- m_ImageData = new unsigned char[m_ImageHeight*m_ImageWidth*m_ImageScalarComponents];
-
- unsigned char* b = m_ImageData;
- for ( int textCounter = 0; textCounter < (m_ImageHeight*m_ImageWidth*m_ImageScalarComponents); textCounter++ )
- *b++ = 0;
- }
- else
- {
- if(m_ImageWidth == 0)
- { // VTK Image Import has to be initialized properly
- m_ImageHeight = height;
- m_ImageWidth = width;
- m_ImageScalarComponents = imageScalarComponents;
- InitVtkImageImport();
- }
-
-
- // VTK import image data must be allocated before import (with correct parameters)
- if(m_ImageData == NULL)
- m_ImageData = new unsigned char[m_ImageHeight*m_ImageWidth*m_ImageScalarComponents];
-
- int column, row;
- unsigned char* tex = m_ImageData;
- char* data = dataPointer;
-
- // PREPARE image Data for VTKImageImport Filter //
-
-
- if(imageScalarComponents == 1)
- {
- m_VtkImageImport->SetNumberOfScalarComponents(m_ImageScalarComponents);
-
- unsigned char g;
- for (column = 0; column < m_ImageHeight; column++)
- for (row = 0; row < m_ImageWidth; row++)
- {
- g = *data++;
- *tex++ = g;
- }
- }
- else if(imageScalarComponents == 3)
- {
- // flip image, change color channels
- unsigned char r, g, b;
- for (column = 0; column < m_ImageHeight; column++)
- for (row = 0; row < m_ImageWidth; row++)
- { //change r with b
- b = *data++;
- g = *data++;
- r = *data++;
- *tex++ = r;
- *tex++ = g;
- *tex++ = b;
- }
- } // else if(imageScalarComponents == 3)
-
- } // end else image data present
-
-
- // Initialize VTK-ImageImport Filter //
- m_VtkImageImport->SetImportVoidPointer(m_ImageData);
- m_VtkImageImport->Modified();
- m_VtkImageImport->Update();
- m_RenderWindow->Render();
-
-}
-
-
diff --git a/Modules/Ext/Rendering/mitkImageBackground2D.h b/Modules/Ext/Rendering/mitkImageBackground2D.h
deleted file mode 100644
index 5d5ec8c856..0000000000
--- a/Modules/Ext/Rendering/mitkImageBackground2D.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef _mitk_Image_Background2D_h_
-#define _mitk_Image_Background2D_h_
-
-#include "mitkVideoSource.h"
-#include "MitkExtExports.h"
-
-#include "mitkConfig.h"
-
-class vtkRenderer;
-class vtkRenderWindow;
-class vtkImageActor;
-class vtkImageImport;
-class vtkVideoSizeCallback;
-
-namespace mitk
-{
-
- class RenderWindow;
-
- /**
- * Displays a 2D image (currently unsigned char) in the background
- * of a vtkRenderWindow.
- * Caution: As the data is not being copied, a user is responsible for a valid
- * pointer to the image. Also the image dimensions needs to be set correctly before enabling the
- * background.
- */
- class MitkExt_EXPORT ImageBackground2D : public itk::Object
- {
- public:
- mitkClassMacro( ImageBackground2D, itk::Object );
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- ////##Documentation
- ////## @brief returns the mitkRenderWindow in which the video is displayed.
- vtkRenderWindow* GetRenderWindow();
- ////##Documentation
- ////## @brief sets the mitkRenderWindow in which the video is displayed.
- ////## must be initialized before enabling the background.
- void SetRenderWindow(vtkRenderWindow* renderWindow);
- ////##Documentation
- ////## @brief sets the width,height and number of scalar components of the image.
- ////## must be correctly initialized before enabling the background.
- void SetImageDimensions(int x, int y, int nrOfScalarComponents)
- {
- m_ImageWidth = x;
- m_ImageHeight = y;
- m_ImageScalarComponents = nrOfScalarComponents;
- InitVtkImageImport();
- }
-
- void SetParallelScale(int scale);
- int GetParallelScale();
-
- void Update(char * dataPointer);
- void Update(char * dataPointer, int width, int height, int imageScalarComponents);
-
- ////##Documentation
- ////## @brief visualizes the video. Requires image dimensions and an active mitkvideosource to be set.
- void Enable();
- ////##Documentation
- ////## @brief disables visualization of the video.
- void Disable();
- ////##Documentation
- ////## @brief Checks, if the Video background is currently enabled (visible).
- bool IsEnabled();
-
- protected:
- ImageBackground2D();
- ~ImageBackground2D();
-
- void InitVtkImageImport();
-
- vtkRenderWindow* m_RenderWindow;
- vtkRenderer* m_ImageRenderer;
- vtkImageActor* m_Actor;
- vtkImageImport* m_VtkImageImport;
-
- // Adjust Image Size
- vtkVideoSizeCallback * m_SizeCallback;
-
- unsigned char * m_ImageData;
-
- int m_ImageWidth, m_ImageHeight, m_ImageScalarComponents, m_ParallelScale;
- };
-} // namespace mitk
-
-#endif
-
-
diff --git a/Modules/Ext/Rendering/mitkLineMapper2D.cpp b/Modules/Ext/Rendering/mitkLineMapper2D.cpp
deleted file mode 100644
index 19560e23ca..0000000000
--- a/Modules/Ext/Rendering/mitkLineMapper2D.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkLineMapper2D.h"
-#include "mitkPointSet.h"
-#include "mitkBaseRenderer.h"
-#include "mitkPlaneGeometry.h"
-#include "mitkColorProperty.h"
-#include "mitkProperties.h"
-#include <vtkLinearTransform.h>
-#include "mitkPointSet.h"
-#include "mitkGL.h"
-
-mitk::LineMapper2D::LineMapper2D()
-: mitk::PointSetGLMapper2D()
-{
-
-}
-
-mitk::LineMapper2D::~LineMapper2D()
-{
-}
-
-const mitk::PointSet *mitk::LineMapper2D::GetInput(void)
-{
- return static_cast<const mitk::PointSet * > ( GetDataNode()->GetData() );
-}
-
-void mitk::LineMapper2D::Paint(mitk::BaseRenderer * renderer)
-{
-
- bool visible = true;
- GetDataNode()->GetVisibility(visible, renderer, "visible");
- if(!visible) return;
-
- bool updateNeccesary = true;//!!!! @TODO !??!!
-
- if (updateNeccesary)
- {
- mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>(this->GetInput());
- mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
- assert(displayGeometry.IsNotNull());
-
- //apply color and opacity read from the PropertyList
- ApplyColorAndOpacityProperties(renderer);
-
- vtkLinearTransform* transform = GetDataNode()->GetVtkTransform();
-
- //List of the Points
- PointSet::DataType::PointsContainerConstIterator it, end;
- it = input->GetPointSet()->GetPoints()->Begin();
- end = input->GetPointSet()->GetPoints()->End();//the last before end, because lines from n to n+1
- if (end!=it) // otherwise PointSet is empty
- end--;
-
- //bool list for the selection of the points
- PointSet::DataType::PointDataContainerIterator selIt, selItNext;
- selIt=input->GetPointSet()->GetPointData()->Begin();
-
- int j=0;
- while(it!=end)
- {
- mitk::Point3D p, q, projected_p, projected_q;
- float vtkp[3];
- itk2vtk(it->Value(), vtkp);
- transform->TransformPoint(vtkp, vtkp);
- vtk2itk(vtkp,p);
-
- //next point n+1
- it++;
- itk2vtk(it->Value(), vtkp);
- transform->TransformPoint(vtkp, vtkp);
- vtk2itk(vtkp,q);
- it--;
-
- displayGeometry->Project(p, projected_p);
- displayGeometry->Project(q, projected_q);
-
- Vector3D diffp=p-projected_p, diffq=q-projected_q;
- if((diffp.GetSquaredNorm()<4.0) &&
- (diffq.GetSquaredNorm()<4.0))
- {
- Point2D p2d, q2d, tmp;
-
- displayGeometry->Map(projected_p, p2d);
- displayGeometry->WorldToDisplay(p2d, p2d);
- displayGeometry->Map(projected_q, q2d);
- displayGeometry->WorldToDisplay(q2d, q2d);
-
- //outlined, cause iterators behave strange and multiple points can't be selected anyway by now!
- //selItNext = selIt++;//Iterator to the next Element, cause only when the two points ar selected, then the Line is Selected
- //if (selIt->Value() && selItNext->Value())//selected
- //{
- // float colorSel[]={1.0,0.0,0.6}; //for selected!
-
- // //current color for changing to a diferent color if selected
- // float currCol[4];
- // glGetFloatv(GL_CURRENT_COLOR,currCol);
-
- // glColor3f(colorSel[0],colorSel[1],colorSel[2]);//red
-
-
- // glBegin (GL_LINES);
- // glVertex2f(p2d[0], p2d[1]);
- // glVertex2f(q2d[0], q2d[1]);
- // glEnd ();
-
- // glColor3f(currCol[0],currCol[1],currCol[2]);//the color before changing to select!
-
- //}
- //else
- //{
- glBegin (GL_LINES);
- glVertex2f(p2d[0], p2d[1]);
- glVertex2f(q2d[0], q2d[1]);
- glEnd ();
- //}
- }
- ++it;
- ++selIt;
- j++;
- }
- //drawing the points
- PointSetGLMapper2D::Paint(renderer);
- }
-}
diff --git a/Modules/Ext/Rendering/mitkLineMapper2D.h b/Modules/Ext/Rendering/mitkLineMapper2D.h
deleted file mode 100644
index 9ad9444abd..0000000000
--- a/Modules/Ext/Rendering/mitkLineMapper2D.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKLINEMAPPER2D_H_HEADER_INCLUDED
-#define MITKLINEMAPPER2D_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkPointSetGLMapper2D.h"
-
-namespace mitk {
-
-class BaseRenderer;
-class PointSet;
-
-//##Documentation
-//## @brief OpenGL-based mapper to display Lines
-//##
-//## uses the information from the PointSet to build up the lines.
-//## Only lines in 2D in one Slice are drawn, not between slices!
-//## @ingroup Mapper
-
-/** \deprecatedSince{2013_06} This mapper is deprecated. */
-class DEPRECATED() MitkExt_EXPORT LineMapper2D : public PointSetGLMapper2D
-{
-public:
- mitkClassMacro(LineMapper2D, PointSetGLMapper2D);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- //##Documentation
- //## @brief Get the PointDataList to map
- const PointSet * GetInput(void);
-
- virtual void Paint(mitk::BaseRenderer * renderer);
-
-protected:
- LineMapper2D();
-
- virtual ~LineMapper2D();
-};
-
-} // namespace mitk
-
-#endif /* MITKLINEMAPPER2D_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Rendering/mitkLineVtkMapper3D.cpp b/Modules/Ext/Rendering/mitkLineVtkMapper3D.cpp
deleted file mode 100644
index e5feb688b2..0000000000
--- a/Modules/Ext/Rendering/mitkLineVtkMapper3D.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkLineVtkMapper3D.h"
-
-#include <vtkPolyDataMapper.h>
-#include <vtkActor.h>
-#include <vtkProp3DCollection.h>
-#include <mitkProperties.h>
-#include "mitkStringProperty.h"
-#include <vtkProperty.h>
-
-mitk::LineVtkMapper3D::LineVtkMapper3D()
-: PointSetVtkMapper3D()//constructor of superclass
-{
-}
-
-mitk::LineVtkMapper3D::~LineVtkMapper3D()
-{
-}
-
-void mitk::LineVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer)
-{//from PointListVTKMapper3D and a little re-layouted!
- if(IsVisible(renderer)==false)
- {
- m_Actor->VisibilityOff();
- return;
- }
-
- m_Actor->VisibilityOn();
-
- m_vtkPointList->Delete();
- m_vtkTextList->Delete();
- m_contour->Delete();
- m_tubefilter->Delete();
-
- m_vtkPointList = vtkAppendPolyData::New();
- m_vtkTextList = vtkAppendPolyData::New();
- m_contour = vtkPolyData::New();
- m_tubefilter = vtkTubeFilter::New();
-
-
- mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>(this->GetInput());
- mitk::PointSet::PointSetType::Pointer pointList;
-
- pointList = input->GetPointList();
-
- mitk::PointSet::PointsContainer::Iterator i;
-
- int j;
- bool makeContour;
- if (dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetProperty("show contour").GetPointer()) == NULL)
- makeContour = false;
- else
- makeContour = dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetProperty("show contour").GetPointer())->GetValue();
-
- vtkPoints *points = vtkPoints::New();
- vtkCellArray *polys = vtkCellArray::New();
-
- for (j=0, i=pointList->GetPoints()->Begin(); i!=pointList->GetPoints()->End() ; i++,j++)
- {
- int cell[2] = {j-1,j};
- points->InsertPoint(j,i.Value()[0],i.Value()[1],i.Value()[2]);
- if (j>0)
- polys->InsertNextCell(2,cell);
- }
-
- bool close;
- if (dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetProperty("close contour").GetPointer()) == NULL)
- close = false;
- else
- close = dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetProperty("close contour").GetPointer())->GetValue();
-
- if (close)
- {
- int cell[2] = {j-1,0};
- polys->InsertNextCell(2,cell);
- }
-
- m_contour->SetPoints(points);
- points->Delete();
- m_contour->SetLines(polys);
- polys->Delete();
- m_contour->Update();
-
- m_tubefilter->SetInput(m_contour);
- m_tubefilter->SetRadius(1);
- m_tubefilter->Update();;
-
- m_vtkPointList->AddInput(m_tubefilter->GetOutput());
-
-
- // check for color prop and use it for rendering if it exists
- float rgba[4]={1.0f,1.0f,1.0f,1.0f};
- GetColor(rgba, renderer);
-
- for (j=0, i=pointList->GetPoints()->Begin(); i!=pointList->GetPoints()->End() ; i++,j++)
- {
- vtkSphereSource *sphere = vtkSphereSource::New();
-
- sphere->SetRadius(2);
- sphere->SetCenter(i.Value()[0],i.Value()[1],i.Value()[2]);
-
- m_vtkPointList->AddInput(sphere->GetOutput());
-
- if (dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetProperty("label").GetPointer()) == NULL)
- {
- }
- else
- {
- const char * pointLabel =dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetProperty("label").GetPointer())->GetValue();
- char buffer[20];
- std::string l = pointLabel;
- if (input->GetSize()>1)
- {
- sprintf(buffer,"%d",j+1);
- l.append(buffer);
- }
-
- // Define the text for the label
- vtkVectorText *label = vtkVectorText::New();
- label->SetText(l.c_str());
-
- // Set up a transform to move the label to a new position.
- vtkTransform *aLabelTransform =vtkTransform::New();
- aLabelTransform->Identity();
- aLabelTransform->Translate(i.Value()[0]+2,i.Value()[1]+2,i.Value()[2]);
- aLabelTransform->Scale(5.7,5.7,5.7);
-
- // Move the label to a new position.
- vtkTransformPolyDataFilter *labelTransform = vtkTransformPolyDataFilter::New();
- labelTransform->SetTransform(aLabelTransform);
- labelTransform->SetInput(label->GetOutput());
-
- m_vtkPointList->AddInput(labelTransform->GetOutput());
- }
-
-
- }
-
-
- m_VtkPolyDataMapper->SetInput(m_vtkPointList->GetOutput());
- m_Actor->GetProperty()->SetColor(rgba);
-}
-
diff --git a/Modules/Ext/Rendering/mitkLineVtkMapper3D.h b/Modules/Ext/Rendering/mitkLineVtkMapper3D.h
deleted file mode 100644
index ccca95cfe2..0000000000
--- a/Modules/Ext/Rendering/mitkLineVtkMapper3D.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKLINEVTKMAPPER3D_H_HEADER_INCLUDED
-#define MITKLINEVTKMAPPER3D_H_HEADER_INCLUDED
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "mitkPointSetVtkMapper3D.h"
-#include "mitkPointSet.h"
-#include "mitkBaseRenderer.h"
-
-#include <vtkSphereSource.h>
-#include <vtkAppendPolyData.h>
-#include <vtkPolyData.h>
-#include <vtkPoints.h>
-#include <vtkPointData.h>
-#include <vtkCellArray.h>
-#include <vtkFloatArray.h>
-#include <vtkTubeFilter.h>
-#include <vtkVectorText.h>
-#include <vtkTextSource.h>
-#include <vtkTransform.h>
-#include <vtkTransformPolyDataFilter.h>
-
-
-class vtkActor;
-class vtkAssembly;
-class vtkFollower;
-class vtkPolyDataMapper;
-
-namespace mitk {
-
-//##Documentation
-//## @brief Vtk-based mapper to draw Lines from PointSet
-//##
-//## @ingroup Mapper
-class MitkExt_EXPORT LineVtkMapper3D : public PointSetVtkMapper3D
-{
- public:
-
- mitkClassMacro(LineVtkMapper3D, PointSetVtkMapper3D);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
-
- protected:
- LineVtkMapper3D();
- virtual ~LineVtkMapper3D();
-
- virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer);
-};
-
-} // namespace mitk
-
-#endif /* MITKLINEVTKMAPPER3D_H_HEADER_INCLUDED */
diff --git a/Modules/Ext/Rendering/mitkNativeRenderWindowInteractor.cpp b/Modules/Ext/Rendering/mitkNativeRenderWindowInteractor.cpp
deleted file mode 100644
index 309ce8fd46..0000000000
--- a/Modules/Ext/Rendering/mitkNativeRenderWindowInteractor.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkNativeRenderWindowInteractor.h"
-
-#include <vtkRenderWindow.h>
-#include <vtkRenderWindowInteractor.h>
-
-mitk::NativeRenderWindowInteractor::NativeRenderWindowInteractor() : m_MitkRenderWindow(NULL), m_NativeVtkRenderWindowInteractor(NULL)
-{
- m_NativeVtkRenderWindowInteractor = vtkRenderWindowInteractor::New();
-}
-
-mitk::NativeRenderWindowInteractor::~NativeRenderWindowInteractor()
-{
- m_NativeVtkRenderWindowInteractor->Delete();
-}
-
-void mitk::NativeRenderWindowInteractor::SetMitkRenderWindow(vtkRenderWindow* renderwindow)
-{
- m_MitkRenderWindow = renderwindow;
- if(m_MitkRenderWindow != NULL)
- m_NativeVtkRenderWindowInteractor->SetRenderWindow(m_MitkRenderWindow);
-}
-
-void mitk::NativeRenderWindowInteractor::Start()
-{
- if(m_MitkRenderWindow != NULL)
- m_NativeVtkRenderWindowInteractor->Start();
-}
diff --git a/Modules/Ext/Rendering/mitkNativeRenderWindowInteractor.h b/Modules/Ext/Rendering/mitkNativeRenderWindowInteractor.h
deleted file mode 100644
index 446ba16e60..0000000000
--- a/Modules/Ext/Rendering/mitkNativeRenderWindowInteractor.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#ifndef MITKNATIVERENDERWINDOWINTERACTOR_H_HEADER_INCLUDED_C1C53722
-#define MITKNATIVERENDERWINDOWINTERACTOR_H_HEADER_INCLUDED_C1C53722
-
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-#include "itkObject.h"
-#include "itkObjectFactory.h"
-
-class vtkRenderWindow;
-class vtkRenderWindowInteractor;
-
-namespace mitk
-{
-
-class MitkExt_EXPORT NativeRenderWindowInteractor : public itk::Object
-{
-public:
- mitkClassMacro(NativeRenderWindowInteractor, itk::Object);
-
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-
- virtual void Start();
-
- void SetMitkRenderWindow(vtkRenderWindow * renderwindow);
- itkGetMacro(MitkRenderWindow, vtkRenderWindow*);
-
-protected:
- NativeRenderWindowInteractor();
- virtual ~NativeRenderWindowInteractor();
-
- vtkRenderWindow* m_MitkRenderWindow;
-
- vtkRenderWindowInteractor* m_NativeVtkRenderWindowInteractor;
-};
-
-}
-#endif /* MITKNATIVERENDERWINDOWINTERACTOR_H_HEADER_INCLUDED_C1C53722 */
-
-
diff --git a/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapper.cpp b/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapper.cpp
deleted file mode 100644
index 1b731f69f8..0000000000
--- a/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapper.cpp
+++ /dev/null
@@ -1,7493 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-/*=========================================================================
-
- Program: Visualization Toolkit
- Module: $RCSfile: vtkMitkOpenGLGPUVolumeRayCastMapper.cxx,v $
-
- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
- All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
-=========================================================================*/
-
-#include "vtkMitkOpenGLGPUVolumeRayCastMapper.h"
-
-// Only with VTK 5.6 or above
-#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
-
-#include "vtkObjectFactory.h"
-#include "vtkVolume.h"
-#include "vtkRenderer.h"
-#include "vtkRenderWindow.h"
-#include "vtkCamera.h"
-#include "vtkMatrix4x4.h"
-#include "vtkImageData.h"
-
-#include "vtkTimerLog.h"
-
-#include "vtkVolumeProperty.h"
-#include "vtkColorTransferFunction.h"
-#include "vtkPiecewiseFunction.h"
-
-#include "vtkOpenGLExtensionManager.h"
-#include "vtkgl.h"
-
-#ifndef VTK_IMPLEMENT_MESA_CXX
-# include "vtkOpenGL.h"
-#endif
-
-#include <math.h>
-
-#include <vtkstd/string>
-#include <vtkstd/map>
-#include <vtkstd/vector>
-#include <assert.h>
-
-#include "vtkClipDataSet.h"
-#include "vtkCellArray.h"
-#include "vtkDoubleArray.h"
-#include "vtkFloatArray.h"
-#include "vtkGeometryFilter.h"
-#include "vtkMath.h"
-#include "vtkPlane.h"
-#include "vtkPlaneCollection.h"
-#include "vtkPlanes.h"
-#include "vtkPolyData.h"
-#include "vtkPointData.h"
-#include "vtkCellData.h"
-#include "vtkPoints.h"
-#include "vtkUnsignedCharArray.h"
-#include "vtkUnsignedShortArray.h"
-#include "vtkUnsignedIntArray.h"
-#include "vtkUnstructuredGrid.h"
-#include "vtkVoxel.h"
-
-#include "vtkClipConvexPolyData.h"
-#include "vtkClipPolyData.h"
-#include "vtkDensifyPolyData.h"
-
-#include "vtkImageResample.h"
-
-#include <sstream>
-#include <stdlib.h> // qsort()
-
-#include "vtkDataSetTriangleFilter.h"
-
-#include "vtkAbstractArray.h" // required if compiled against VTK 5.0
-
-#include "vtkTessellatedBoxSource.h"
-#include "vtkCleanPolyData.h"
-
-#include "vtkCommand.h" // for VolumeMapperRender{Start|End|Progress}Event
-#include "vtkPerlinNoise.h"
-
-#include <vtksys/ios/sstream>
-#include "vtkStdString.h"
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class vtkUnsupportedRequiredExtensionsStringStream
-{
-public:
- vtkstd::ostringstream Stream;
- vtkUnsupportedRequiredExtensionsStringStream()
- {
- }
-private:
- // undefined copy constructor.
- vtkUnsupportedRequiredExtensionsStringStream(const vtkUnsupportedRequiredExtensionsStringStream &other);
- // undefined assignment operator.
- vtkUnsupportedRequiredExtensionsStringStream &operator=(const vtkUnsupportedRequiredExtensionsStringStream &other);
-};
-
-class vtkMapDataArrayTextureId
-{
-public:
- vtkstd::map<vtkImageData *,vtkKWScalarField *> Map;
- vtkMapDataArrayTextureId()
- {
- }
-private:
- // undefined copy constructor.
- vtkMapDataArrayTextureId(const vtkMapDataArrayTextureId &other);
- // undefined assignment operator.
- vtkMapDataArrayTextureId &operator=(const vtkMapDataArrayTextureId &other);
-};
-
-class vtkMapMaskTextureId
-{
-public:
- vtkstd::map<vtkImageData *,vtkKWMask *> Map;
- vtkMapMaskTextureId()
- {
- }
-private:
- // undefined copy constructor.
- vtkMapMaskTextureId(const vtkMapMaskTextureId &other);
- // undefined assignment operator.
- vtkMapMaskTextureId &operator=(const vtkMapMaskTextureId &other);
-};
-
-//-----------------------------------------------------------------------------
-extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_HeaderFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_NoShadeFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_ShadeFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_OneComponentFS;
-extern const char *vtkMitkGPUVolumeRayCastMapper_FourComponentsFS;
-
-enum
-{
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized=-1, // not init
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionPerspective=0, // false
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionParallel=1 // true
-};
-
-enum
-{
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized,
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP,
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent,
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite,
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP,
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent,
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask
-};
-
-// component implementation
-enum
-{
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized=-1, // not init
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne=0, // false
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentFour=1, // true
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed=2 // when not composite
-};
-
-// Shade implementation
-enum
-{
- vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized=-1, // not init
- vtkMitkOpenGLGPUVolumeRayCastMapperShadeNo=0, // false
- vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes=1, // true
- vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed=2 // when not composite
-};
-
-
-// Cropping implementation
-enum
-{
- vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized,
- vtkMitkOpenGLGPUVolumeRayCastMapperCompositeCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperCompositeNoCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMIPCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMIPNoCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentNoCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMinIPCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMinIPNoCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentCropping,
- vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentNoCropping
-};
-
-enum
-{
- vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap=0, // 2d texture
- vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront // 2d texture
-};
-
-const int vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects=vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+2;
-
-const int vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize=1024; //power of two
-
-#ifndef VTK_IMPLEMENT_MESA_CXX
-vtkStandardNewMacro(vtkMitkOpenGLGPUVolumeRayCastMapper);
-#endif
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class vtkOpacityTable
-{
-public:
- vtkOpacityTable()
- {
- this->TextureId=0;
- this->LastBlendMode=vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND;
- this->LastSampleDistance=1.0;
- this->Table=0;
- this->Loaded=false;
- this->LastLinearInterpolation=false;
- }
-
- ~vtkOpacityTable()
- {
- if(this->TextureId!=0)
- {
- glDeleteTextures(1,&this->TextureId);
- this->TextureId=0;
- }
- if(this->Table!=0)
- {
- delete[] this->Table;
- this->Table=0;
- }
- }
-
- bool IsLoaded()
- {
- return this->Loaded;
- }
-
- void Bind()
- {
- assert("pre: uptodate" && this->Loaded);
- glBindTexture(GL_TEXTURE_1D,this->TextureId);
- }
-
- // \pre the active texture is set to TEXTURE2
- void Update(vtkPiecewiseFunction *scalarOpacity,
- int blendMode,
- double sampleDistance,
- double range[2],
- double unitDistance,
- bool linearInterpolation)
- {
- assert("pre: scalarOpacity_exists" && scalarOpacity!=0);
- bool needUpdate=false;
- if(this->TextureId==0)
- {
- glGenTextures(1,&this->TextureId);
- needUpdate=true;
- }
- glBindTexture(GL_TEXTURE_1D,this->TextureId);
- if(needUpdate)
- {
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,
- vtkgl::CLAMP_TO_EDGE);
- }
- if(scalarOpacity->GetMTime() > this->BuildTime ||
- (this->LastBlendMode!=blendMode)
- || (blendMode==vtkVolumeMapper::COMPOSITE_BLEND &&
- this->LastSampleDistance!=sampleDistance)
- || needUpdate || !this->Loaded)
- {
- this->Loaded=false;
- if(this->Table==0)
- {
- this->Table=
- new float[vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize];
- }
-
- scalarOpacity->GetTable(range[0],range[1],
- vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,
- this->Table);
-
- this->LastBlendMode=blendMode;
-
- // Correct the opacity array for the spacing between the planes if we
- // are using a composite blending operation
- if(blendMode==vtkVolumeMapper::COMPOSITE_BLEND)
- {
- float *ptr=this->Table;
- double factor=sampleDistance/unitDistance;
- int i=0;
- while(i<vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize)
- {
- if(*ptr>0.0001f)
- {
- *ptr=static_cast<float>(1.0-pow(1.0-static_cast<double>(*ptr),
- factor));
- }
- ++ptr;
- ++i;
- }
- this->LastSampleDistance=sampleDistance;
- }
- glTexImage1D(GL_TEXTURE_1D,0,GL_ALPHA16,
- vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,0,
- GL_ALPHA,GL_FLOAT,this->Table);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("1d opacity texture is too large");
- this->Loaded=true;
- this->BuildTime.Modified();
- }
-
- needUpdate=needUpdate ||
- this->LastLinearInterpolation!=linearInterpolation;
- if(needUpdate)
- {
- this->LastLinearInterpolation=linearInterpolation;
- GLint value;
- if(linearInterpolation)
- {
- value=GL_LINEAR;
- }
- else
- {
- value=GL_NEAREST;
- }
- glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,value);
- glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,value);
- }
- }
-protected:
- GLuint TextureId;
- int LastBlendMode;
- double LastSampleDistance;
- vtkTimeStamp BuildTime;
- float *Table;
- bool Loaded;
- bool LastLinearInterpolation;
-};
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class vtkOpacityTables
-{
-public:
- vtkstd::vector<vtkOpacityTable> Vector;
- vtkOpacityTables(size_t numberOfLevels)
- : Vector(numberOfLevels)
- {
- }
-private:
- // undefined copy constructor.
- vtkOpacityTables(const vtkOpacityTables &other);
- // undefined assignment operator.
- vtkOpacityTables &operator=(const vtkOpacityTables &other);
-};
-
-//-----------------------------------------------------------------------------
-class vtkRGBTable
-{
-public:
- vtkRGBTable()
- {
- this->TextureId=0;
- this->Table=0;
- this->Loaded=false;
- this->LastLinearInterpolation=false;
- }
-
- ~vtkRGBTable()
- {
- if(this->TextureId!=0)
- {
- glDeleteTextures(1,&this->TextureId);
- this->TextureId=0;
- }
- if(this->Table!=0)
- {
- delete[] this->Table;
- this->Table=0;
- }
- }
-
- bool IsLoaded()
- {
- return this->Loaded;
- }
-
- void Bind()
- {
- assert("pre: uptodate" && this->Loaded);
- glBindTexture(GL_TEXTURE_1D,this->TextureId);
- }
-
- // \pre the active texture is set properly. (default color,
- // mask1, mask2,..)
- void Update(vtkColorTransferFunction *scalarRGB,
- double range[2],
- bool linearInterpolation)
- {
- assert("pre: scalarRGB_exists" && scalarRGB!=0);
- bool needUpdate=false;
- if(this->TextureId==0)
- {
- glGenTextures(1,&this->TextureId);
- needUpdate=true;
- }
- glBindTexture(GL_TEXTURE_1D,this->TextureId);
- if(needUpdate)
- {
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,
- vtkgl::CLAMP_TO_EDGE);
- }
- if(scalarRGB->GetMTime() > this->BuildTime
- || needUpdate || !this->Loaded)
- {
- this->Loaded=false;
- if(this->Table==0)
- {
- this->Table=
- new float[vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize*3];
- }
-
- scalarRGB->GetTable(range[0],range[1],
- vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,
- this->Table);
-
- glTexImage1D(GL_TEXTURE_1D,0,GL_RGB16,
- vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,0,
- GL_RGB,GL_FLOAT,this->Table);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("1d RGB texture is too large");
- this->Loaded=true;
- this->BuildTime.Modified();
- }
-
- needUpdate=needUpdate ||
- this->LastLinearInterpolation!=linearInterpolation;
- if(needUpdate)
- {
- this->LastLinearInterpolation=linearInterpolation;
- GLint value;
- if(linearInterpolation)
- {
- value=GL_LINEAR;
- }
- else
- {
- value=GL_NEAREST;
- }
- glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,value);
- glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,value);
- }
- }
-protected:
- GLuint TextureId;
- vtkTimeStamp BuildTime;
- float *Table;
- bool Loaded;
- bool LastLinearInterpolation;
-};
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class vtkKWScalarField
-{
-public:
- vtkKWScalarField()
- {
- this->TextureId=0;
- this->Loaded=false;
- this->Supports_GL_ARB_texture_float=false;
- this->LoadedTableRange[0]=0.0;
- this->LoadedTableRange[1]=1.0;
- this->LoadedExtent[0]=VTK_INT_MAX;
- this->LoadedExtent[1]=VTK_INT_MIN;
- this->LoadedExtent[2]=VTK_INT_MAX;
- this->LoadedExtent[3]=VTK_INT_MIN;
- this->LoadedExtent[4]=VTK_INT_MAX;
- this->LoadedExtent[5]=VTK_INT_MIN;
- }
- ~vtkKWScalarField()
- {
- if(this->TextureId!=0)
- {
- glDeleteTextures(1,&this->TextureId);
- this->TextureId=0;
- }
- }
-
- vtkTimeStamp GetBuildTime()
- {
- return this->BuildTime;
- }
-
- void Bind()
- {
- assert("pre: uptodate" && this->Loaded);
- glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
- }
-
- void Update(vtkImageData *input,
- int cellFlag,
- int textureExtent[6],
- int scalarMode,
- int arrayAccessMode,
- int arrayId,
- const char *arrayName,
- bool linearInterpolation,
- double tableRange[2],
- int maxMemoryInBytes)
- {
- bool needUpdate=false;
- bool modified=false;
- if(this->TextureId==0)
- {
- glGenTextures(1,&this->TextureId);
- needUpdate=true;
- }
- glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
-
- int obsolete=needUpdate || !this->Loaded || input->GetMTime()>this->BuildTime;
- if(!obsolete)
- {
- obsolete=cellFlag!=this->LoadedCellFlag;
- int i=0;
- while(!obsolete && i<6)
- {
- obsolete=obsolete || this->LoadedExtent[i]>textureExtent[i];
- ++i;
- obsolete=obsolete || this->LoadedExtent[i]<textureExtent[i];
- ++i;
- }
- }
-
- if(!obsolete)
- {
- obsolete=this->LoadedTableRange[0]!=tableRange[0] ||
- this->LoadedTableRange[1]!=tableRange[1];
- }
-
- if(obsolete)
- {
- this->Loaded=false;
- int dim[3];
- input->GetDimensions(dim);
-
- GLint internalFormat=0;
- GLenum format=0;
- GLenum type=0;
- // shift then scale: y:=(x+shift)*scale
- double shift=0.0;
- double scale=1.0;
- int needTypeConversion=0;
- vtkDataArray *sliceArray=0;
-
- vtkDataArray *scalars=
- vtkAbstractMapper::GetScalars(input,scalarMode,arrayAccessMode,
- arrayId,arrayName,
- this->LoadedCellFlag);
-
- // DONT USE GetScalarType() or GetNumberOfScalarComponents() on
- // ImageData as it deals only with point data...
-
- int scalarType=scalars->GetDataType();
- if(scalars->GetNumberOfComponents()==4)
- {
- // this is RGBA, unsigned char only
- internalFormat=GL_RGBA16;
- format=GL_RGBA;
- type=GL_UNSIGNED_BYTE;
- }
- else
- {
- // input->GetNumberOfScalarComponents()==1
- switch(scalarType)
- {
- case VTK_FLOAT:
- if(this->Supports_GL_ARB_texture_float)
- {
- internalFormat=vtkgl::INTENSITY16F_ARB;
- }
- else
- {
- internalFormat=GL_INTENSITY16;
- }
- format=GL_RED;
- type=GL_FLOAT;
- shift=-tableRange[0];
- scale=1/(tableRange[1]-tableRange[0]);
- break;
- case VTK_UNSIGNED_CHAR:
- internalFormat=GL_INTENSITY8;
- format=GL_RED;
- type=GL_UNSIGNED_BYTE;
- shift=-tableRange[0]/VTK_UNSIGNED_CHAR_MAX;
- scale=
- VTK_UNSIGNED_CHAR_MAX/(tableRange[1]-tableRange[0]);
- break;
- case VTK_SIGNED_CHAR:
- internalFormat=GL_INTENSITY8;
- format=GL_RED;
- type=GL_BYTE;
- shift=-(2*tableRange[0]+1)/VTK_UNSIGNED_CHAR_MAX;
- scale=VTK_SIGNED_CHAR_MAX/(tableRange[1]-tableRange[0]);
- break;
- case VTK_CHAR:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_BIT:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_ID_TYPE:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_INT:
- internalFormat=GL_INTENSITY16;
- format=GL_RED;
- type=GL_INT;
-
- shift=-(2*tableRange[0]+1)/VTK_UNSIGNED_INT_MAX;
- scale=VTK_INT_MAX/(tableRange[1]-tableRange[0]);
- break;
- case VTK_DOUBLE:
- case VTK___INT64:
- case VTK_LONG:
- case VTK_LONG_LONG:
- case VTK_UNSIGNED___INT64:
- case VTK_UNSIGNED_LONG:
- case VTK_UNSIGNED_LONG_LONG:
- needTypeConversion=1; // to float
- if(this->Supports_GL_ARB_texture_float)
- {
- internalFormat=vtkgl::INTENSITY16F_ARB;
- }
- else
- {
- internalFormat=GL_INTENSITY16;
- }
- format=GL_RED;
- type=GL_FLOAT;
- shift=-tableRange[0];
- scale=1/(tableRange[1]-tableRange[0]);
- sliceArray=vtkFloatArray::New();
- break;
- case VTK_SHORT:
- internalFormat=GL_INTENSITY16;
- format=GL_RED;
- type=GL_SHORT;
-
- shift=-(2*tableRange[0]+1)/VTK_UNSIGNED_SHORT_MAX;
- scale=VTK_SHORT_MAX/(tableRange[1]-tableRange[0]);
- break;
- case VTK_STRING:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_UNSIGNED_SHORT:
- internalFormat=GL_INTENSITY16;
- format=GL_RED;
- type=GL_UNSIGNED_SHORT;
-
- shift=-tableRange[0]/VTK_UNSIGNED_SHORT_MAX;
- scale=
- VTK_UNSIGNED_SHORT_MAX/(tableRange[1]-tableRange[0]);
- break;
- case VTK_UNSIGNED_INT:
- internalFormat=GL_INTENSITY16;
- format=GL_RED;
- type=GL_UNSIGNED_INT;
-
- shift=-tableRange[0]/VTK_UNSIGNED_INT_MAX;
- scale=VTK_UNSIGNED_INT_MAX/(tableRange[1]-tableRange[0]);
- break;
- default:
- assert("check: impossible case" && 0);
- break;
- }
- }
-
- // Enough memory?
- int textureSize[3];
- int i=0;
- while(i<3)
- {
- textureSize[i]=textureExtent[2*i+1]-textureExtent[2*i]+1;
- ++i;
- }
-
- GLint width;
- glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&width);
- this->Loaded=textureSize[0]<=width && textureSize[1]<=width
- && textureSize[2]<=width;
- if(this->Loaded)
- {
- // so far, so good. the texture size is theorically small enough
- // for OpenGL
-
- vtkgl::TexImage3D(vtkgl::PROXY_TEXTURE_3D,0,internalFormat,
- textureSize[0],textureSize[1],textureSize[2],0,
- format,type,0);
- glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_3D,0,GL_TEXTURE_WIDTH,
- &width);
-
- this->Loaded=width!=0;
- if(this->Loaded)
- {
- // so far, so good but some cards always succeed with a proxy texture
- // let's try to actually allocate..
-
- vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,internalFormat,textureSize[0],
- textureSize[1],textureSize[2],0,format,type,0);
- GLenum errorCode=glGetError();
- this->Loaded=errorCode!=GL_OUT_OF_MEMORY;
- if(this->Loaded)
- {
- // so far, so good, actual allocation succeeded.
- if(errorCode!=GL_NO_ERROR)
- {
- cout<<"after try to load the texture";
- cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
- cout<<vtkMitkOpenGLGPUVolumeRayCastMapper::OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
- cout<<endl;
- }
- // so far, so good but some cards don't report allocation error
- this->Loaded=textureSize[0]*textureSize[1]*
- textureSize[2]*vtkAbstractArray::GetDataTypeSize(scalarType)*
- scalars->GetNumberOfComponents()<=maxMemoryInBytes;
- if(this->Loaded)
- {
- // OK, we consider the allocation above succeeded...
- // If it actually didn't the only to fix it for the user
- // is to decrease the value of this->MaxMemoryInBytes.
-
- // enough memory! We can load the scalars!
-
- double bias=shift*scale;
-
- // we don't clamp to edge because for the computation of the
- // gradient on the border we need some external value.
- glTexParameterf(vtkgl::TEXTURE_3D,vtkgl::TEXTURE_WRAP_R,vtkgl::CLAMP_TO_EDGE);
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_S,vtkgl::CLAMP_TO_EDGE);
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_T,vtkgl::CLAMP_TO_EDGE);
-
- GLfloat borderColor[4]={0.0,0.0,0.0,0.0};
-
- glTexParameterfv(vtkgl::TEXTURE_3D,GL_TEXTURE_BORDER_COLOR, borderColor);
-
- if(needTypeConversion)
- {
- // Convert and send to the GPU, z-slice by z-slice.
- // Allocate memory on the GPU (NULL data pointer with the right
- // dimensions)
- // Here we are assuming that GL_ARB_texture_non_power_of_two is
- // available
- glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
-
- // memory allocation is already done.
-
- // Send the slices:
- // allocate CPU memory for a slice.
- sliceArray->SetNumberOfComponents(1); // FB TODO CHECK THAT
- sliceArray->SetNumberOfTuples(textureSize[0]*textureSize[1]);
-
- void *slicePtr=sliceArray->GetVoidPointer(0);
- int k=0;
- int kInc=(dim[0]-cellFlag)*(dim[1]-cellFlag);
- int kOffset=(textureExtent[4]*(dim[1]-cellFlag)
- +textureExtent[2])*(dim[0]-cellFlag)
- +textureExtent[0];
- while(k<textureSize[2])
- {
- int j=0;
- int jOffset=0;
- int jDestOffset=0;
- while(j<textureSize[1])
- {
- i=0;
- while(i<textureSize[0])
- {
- sliceArray->SetTuple1(jDestOffset+i,
- (scalars->GetTuple1(kOffset+jOffset
- +i)
- +shift)*scale);
- ++i;
- }
- ++j;
- jOffset+=dim[0]-cellFlag;
- jDestOffset+=textureSize[0];
- }
-
- // Here we are assuming that GL_ARB_texture_non_power_of_two is
- // available
- vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D, 0,
- 0,0,k,
- textureSize[0],textureSize[1],
- 1, // depth is 1, not 0!
- format,type, slicePtr);
- ++k;
- kOffset+=kInc;
- }
- sliceArray->Delete();
- }
- else
- {
- // One chunk of data to the GPU.
- // It works for the whole volume or for a subvolume.
- // Here we are assuming that GL_ARB_texture_non_power_of_two is
- // available
-
- // make sure any previous OpenGL call is executed and will not
- // be disturbed by our PixelTransfer value
- glFinish();
- glPixelTransferf(GL_RED_SCALE,static_cast<GLfloat>(scale));
- glPixelTransferf(GL_RED_BIAS,static_cast<GLfloat>(bias));
- glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
-
- if(!(textureExtent[1]-textureExtent[0]+cellFlag==dim[0]))
- {
- glPixelStorei(GL_UNPACK_ROW_LENGTH,dim[0]-cellFlag);
- }
- if(!(textureExtent[3]-textureExtent[2]+cellFlag==dim[1]))
- {
- glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,
- dim[1]-cellFlag);
- }
- void *dataPtr=scalars->GetVoidPointer(
- ((textureExtent[4]*(dim[1]-cellFlag)+textureExtent[2])
- *(dim[0]-cellFlag)+textureExtent[0])
- *scalars->GetNumberOfComponents());
-
- if(1) // !this->SupportsPixelBufferObjects)
- {
- vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, internalFormat,
- textureSize[0],textureSize[1],textureSize[2],
- 0,format,type,dataPtr);
- }
- else
- {
- GLuint pbo=0;
- vtkgl::GenBuffers(1,&pbo);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("genbuffer");
- vtkgl::BindBuffer(vtkgl::PIXEL_UNPACK_BUFFER,pbo);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("binbuffer");
- vtkgl::GLsizeiptr texSize=
- textureSize[0]*textureSize[1]*textureSize[2]*
- vtkAbstractArray::GetDataTypeSize(scalarType)*
- scalars->GetNumberOfComponents();
- vtkgl::BufferData(vtkgl::PIXEL_UNPACK_BUFFER,texSize,dataPtr,
- vtkgl::STREAM_DRAW);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("bufferdata");
- vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, internalFormat,
- textureSize[0],textureSize[1],textureSize[2],
- 0,format,type,0);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("teximage3d");
- vtkgl::BindBuffer(vtkgl::PIXEL_UNPACK_BUFFER,0);
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("bindbuffer to 0");
- vtkgl::DeleteBuffers(1,&pbo);
- }
- vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("3d texture is too large2");
- // make sure TexImage3D is executed with our PixelTransfer mode
- glFinish();
- // Restore the default values.
- glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
- glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,0);
- glPixelTransferf(GL_RED_SCALE,1.0);
- glPixelTransferf(GL_RED_BIAS,0.0);
- }
- this->LoadedCellFlag=cellFlag;
- i=0;
- while(i<6)
- {
- this->LoadedExtent[i]=textureExtent[i];
- ++i;
- }
-
- double spacing[3];
- double origin[3];
- input->GetSpacing(spacing);
- input->GetOrigin(origin);
- int swapBounds[3];
- swapBounds[0]=(spacing[0]<0);
- swapBounds[1]=(spacing[1]<0);
- swapBounds[2]=(spacing[2]<0);
-
- if(!this->LoadedCellFlag) // loaded extents represent points
- {
- // slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
- // in general, x=o+i*spacing.
- // if spacing is positive min extent match the min of the
- // bounding box
- // and the max extent match the max of the bounding box
- // if spacing is negative min extent match the max of the
- // bounding box
- // and the max extent match the min of the bounding box
-
- // if spacing is negative, we may have to rethink the equation
- // between real point and texture coordinate...
- this->LoadedBounds[0]=origin[0]+
- static_cast<double>(this->LoadedExtent[0+swapBounds[0]])*spacing[0];
- this->LoadedBounds[2]=origin[1]+
- static_cast<double>(this->LoadedExtent[2+swapBounds[1]])*spacing[1];
- this->LoadedBounds[4]=origin[2]+
- static_cast<double>(this->LoadedExtent[4+swapBounds[2]])*spacing[2];
- this->LoadedBounds[1]=origin[0]+
- static_cast<double>(this->LoadedExtent[1-swapBounds[0]])*spacing[0];
- this->LoadedBounds[3]=origin[1]+
- static_cast<double>(this->LoadedExtent[3-swapBounds[1]])*spacing[1];
- this->LoadedBounds[5]=origin[2]+
- static_cast<double>(this->LoadedExtent[5-swapBounds[2]])*spacing[2];
-
- }
- else // loaded extents represent cells
- {
- int wholeTextureExtent[6];
- input->GetExtent(wholeTextureExtent);
- i=1;
- while(i<6)
- {
- wholeTextureExtent[i]--;
- i+=2;
- }
-
- i=0;
- while(i<3)
- {
- if(this->LoadedExtent[2*i]==wholeTextureExtent[2*i])
- {
- this->LoadedBounds[2*i+swapBounds[i]]=origin[i];
- }
- else
- {
- this->LoadedBounds[2*i+swapBounds[i]]=origin[i]+
- (static_cast<double>(this->LoadedExtent[2*i])+0.5)*spacing[i];
- }
-
- if(this->LoadedExtent[2*i+1]==wholeTextureExtent[2*i+1])
- {
- this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
- (static_cast<double>(this->LoadedExtent[2*i+1])+1.0)*spacing[i];
- }
- else
- {
- this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
- (static_cast<double>(this->LoadedExtent[2*i+1])+0.5)*spacing[i];
- }
- ++i;
- }
- }
- this->LoadedTableRange[0]=tableRange[0];
- this->LoadedTableRange[1]=tableRange[1];
- modified=true;
- } // if enough memory
- else
- {
- }
- } //load fail with out of memory
- else
- {
- }
- } // proxy ok
- else
- { // proxy failed
- }
- }
- else
- {
- // out of therical limitationa
- }
- } // if obsolete
-
- if(this->Loaded &&
- (needUpdate || modified ||
- linearInterpolation!=this->LinearInterpolation))
- {
- this->LinearInterpolation=linearInterpolation;
- if(this->LinearInterpolation)
- {
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MIN_FILTER,
- GL_LINEAR);
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MAG_FILTER,
- GL_LINEAR);
- }
- else
- {
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MIN_FILTER,
- GL_NEAREST );
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MAG_FILTER,
- GL_NEAREST );
- }
- modified=true;
- }
- if(modified)
- {
- this->BuildTime.Modified();
- }
- }
-
- double *GetLoadedBounds()
- {
- assert("pre: loaded" && this->Loaded);
- return this->LoadedBounds;
- }
-
- vtkIdType *GetLoadedExtent()
- {
- assert("pre: loaded" && this->Loaded);
- return this->LoadedExtent;
- }
-
- int GetLoadedCellFlag()
- {
- assert("pre: loaded" && this->Loaded);
- return this->LoadedCellFlag;
- }
-
- bool IsLoaded()
- {
- return this->Loaded;
- }
-
- bool GetSupports_GL_ARB_texture_float()
- {
- return this->Supports_GL_ARB_texture_float;
- }
-
- void SetSupports_GL_ARB_texture_float(bool value)
- {
- this->Supports_GL_ARB_texture_float=value;
- }
-
-protected:
- GLuint TextureId;
- vtkTimeStamp BuildTime;
- double LoadedBounds[6];
- vtkIdType LoadedExtent[6];
- int LoadedCellFlag;
- bool Loaded;
- bool LinearInterpolation;
- bool Supports_GL_ARB_texture_float;
- double LoadedTableRange[2];
-};
-
-
-//-----------------------------------------------------------------------------
-class vtkKWMask
-{
-public:
- vtkKWMask()
- {
- this->TextureId=0;
- this->Loaded=false;
- this->LoadedExtent[0]=VTK_INT_MAX;
- this->LoadedExtent[1]=VTK_INT_MIN;
- this->LoadedExtent[2]=VTK_INT_MAX;
- this->LoadedExtent[3]=VTK_INT_MIN;
- this->LoadedExtent[4]=VTK_INT_MAX;
- this->LoadedExtent[5]=VTK_INT_MIN;
- }
- ~vtkKWMask()
- {
- if(this->TextureId!=0)
- {
- glDeleteTextures(1,&this->TextureId);
- this->TextureId=0;
- }
- }
-
- vtkTimeStamp GetBuildTime()
- {
- return this->BuildTime;
- }
-
- // \pre vtkgl::ActiveTexture(vtkgl::TEXTURE7) has to be called first.
- void Bind()
- {
- assert("pre: uptodate" && this->Loaded);
- glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
- }
-
- // \pre vtkgl::ActiveTexture(vtkgl::TEXTURE7) has to be called first.
- void Update(vtkImageData *input,
- int cellFlag,
- int textureExtent[6],
- int scalarMode,
- int arrayAccessMode,
- int arrayId,
- const char *arrayName,
- int maxMemoryInBytes)
- {
- bool needUpdate=false;
- bool modified=false;
- if(this->TextureId==0)
- {
- glGenTextures(1,&this->TextureId);
- needUpdate=true;
- }
- glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
-
- int obsolete=needUpdate || !this->Loaded
- || input->GetMTime()>this->BuildTime;
- if(!obsolete)
- {
- obsolete=cellFlag!=this->LoadedCellFlag;
- int i=0;
- while(!obsolete && i<6)
- {
- obsolete=obsolete || this->LoadedExtent[i]>textureExtent[i];
- ++i;
- obsolete=obsolete || this->LoadedExtent[i]<textureExtent[i];
- ++i;
- }
- }
-
- if(obsolete)
- {
- this->Loaded=false;
- int dim[3];
- input->GetDimensions(dim);
-
- vtkDataArray *scalars=
- vtkAbstractMapper::GetScalars(input,scalarMode,arrayAccessMode,
- arrayId,arrayName,
- this->LoadedCellFlag);
-
- // DONT USE GetScalarType() or GetNumberOfScalarComponents() on
- // ImageData as it deals only with point data...
-
- int scalarType=scalars->GetDataType();
- if(scalarType!=VTK_UNSIGNED_CHAR)
- {
- cout <<"mask should be VTK_UNSIGNED_CHAR." << endl;
- }
- if(scalars->GetNumberOfComponents()!=1)
- {
- cout <<"mask should be a one-component scalar field." << endl;
- }
-
- GLint internalFormat=GL_ALPHA8;
- GLenum format=GL_ALPHA;
- GLenum type=GL_UNSIGNED_BYTE;
-
- // Enough memory?
- int textureSize[3];
- int i=0;
- while(i<3)
- {
- textureSize[i]=textureExtent[2*i+1]-textureExtent[2*i]+1;
- ++i;
- }
-
- GLint width;
- glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&width);
- this->Loaded=textureSize[0]<=width && textureSize[1]<=width
- && textureSize[2]<=width;
- if(this->Loaded)
- {
- // so far, so good. the texture size is theorically small enough
- // for OpenGL
-
- vtkgl::TexImage3D(vtkgl::PROXY_TEXTURE_3D,0,internalFormat,
- textureSize[0],textureSize[1],textureSize[2],0,
- format,type,0);
- glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_3D,0,GL_TEXTURE_WIDTH,
- &width);
-
- this->Loaded=width!=0;
- if(this->Loaded)
- {
- // so far, so good but some cards always succeed with a proxy texture
- // let's try to actually allocate..
-
- vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,internalFormat,textureSize[0],
- textureSize[1],textureSize[2],0,format,type,0);
- GLenum errorCode=glGetError();
- this->Loaded=errorCode!=GL_OUT_OF_MEMORY;
- if(this->Loaded)
- {
- // so far, so good, actual allocation succeeded.
- if(errorCode!=GL_NO_ERROR)
- {
- cout<<"after try to load the texture";
- cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
- cout<<vtkMitkOpenGLGPUVolumeRayCastMapper::OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
- cout<<endl;
- }
- // so far, so good but some cards don't report allocation error
- this->Loaded=textureSize[0]*textureSize[1]*
- textureSize[2]*vtkAbstractArray::GetDataTypeSize(scalarType)*
- scalars->GetNumberOfComponents()<=maxMemoryInBytes;
- if(this->Loaded)
- {
- // OK, we consider the allocation above succeeded...
- // If it actually didn't the only to fix it for the user
- // is to decrease the value of this->MaxMemoryInBytes.
-
- // enough memory! We can load the scalars!
-
- // we don't clamp to edge because for the computation of the
- // gradient on the border we need some external value.
- glTexParameterf(vtkgl::TEXTURE_3D,vtkgl::TEXTURE_WRAP_R,vtkgl::CLAMP_TO_EDGE);
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_S,vtkgl::CLAMP_TO_EDGE);
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_T,vtkgl::CLAMP_TO_EDGE);
-
- GLfloat borderColor[4]={0.0,0.0,0.0,0.0};
-
- glTexParameterfv(vtkgl::TEXTURE_3D,GL_TEXTURE_BORDER_COLOR, borderColor);
-
- glPixelTransferf(GL_ALPHA_SCALE,1.0);
- glPixelTransferf(GL_ALPHA_BIAS,0.0);
- glPixelStorei(GL_UNPACK_ALIGNMENT,1);
-
- if(!(textureExtent[1]-textureExtent[0]+cellFlag==dim[0]))
- {
- glPixelStorei(GL_UNPACK_ROW_LENGTH,dim[0]-cellFlag);
- }
- if(!(textureExtent[3]-textureExtent[2]+cellFlag==dim[1]))
- {
- glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,
- dim[1]-cellFlag);
- }
- void *dataPtr=scalars->GetVoidPointer(
- ((textureExtent[4]*(dim[1]-cellFlag)+textureExtent[2])
- *(dim[0]-cellFlag)+textureExtent[0])
- *scalars->GetNumberOfComponents());
-
- vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, internalFormat,
- textureSize[0],textureSize[1],textureSize[2],
- 0,format,type,dataPtr);
-
- // Restore the default values.
- glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
- glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,0);
- glPixelTransferf(GL_ALPHA_SCALE,1.0);
- glPixelTransferf(GL_ALPHA_BIAS,0.0);
-
- this->LoadedCellFlag=cellFlag;
- i=0;
- while(i<6)
- {
- this->LoadedExtent[i]=textureExtent[i];
- ++i;
- }
-
- double spacing[3];
- double origin[3];
- input->GetSpacing(spacing);
- input->GetOrigin(origin);
- int swapBounds[3];
- swapBounds[0]=(spacing[0]<0);
- swapBounds[1]=(spacing[1]<0);
- swapBounds[2]=(spacing[2]<0);
-
- if(!this->LoadedCellFlag) // loaded extents represent points
- {
- // slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
- // in general, x=o+i*spacing.
- // if spacing is positive min extent match the min of the
- // bounding box
- // and the max extent match the max of the bounding box
- // if spacing is negative min extent match the max of the
- // bounding box
- // and the max extent match the min of the bounding box
-
- // if spacing is negative, we may have to rethink the equation
- // between real point and texture coordinate...
- this->LoadedBounds[0]=origin[0]+
- static_cast<double>(this->LoadedExtent[0+swapBounds[0]])*spacing[0];
- this->LoadedBounds[2]=origin[1]+
- static_cast<double>(this->LoadedExtent[2+swapBounds[1]])*spacing[1];
- this->LoadedBounds[4]=origin[2]+
- static_cast<double>(this->LoadedExtent[4+swapBounds[2]])*spacing[2];
- this->LoadedBounds[1]=origin[0]+
- static_cast<double>(this->LoadedExtent[1-swapBounds[0]])*spacing[0];
- this->LoadedBounds[3]=origin[1]+
- static_cast<double>(this->LoadedExtent[3-swapBounds[1]])*spacing[1];
- this->LoadedBounds[5]=origin[2]+
- static_cast<double>(this->LoadedExtent[5-swapBounds[2]])*spacing[2];
-
- }
- else // loaded extents represent cells
- {
- int wholeTextureExtent[6];
- input->GetExtent(wholeTextureExtent);
- i=1;
- while(i<6)
- {
- wholeTextureExtent[i]--;
- i+=2;
- }
-
- i=0;
- while(i<3)
- {
- if(this->LoadedExtent[2*i]==wholeTextureExtent[2*i])
- {
- this->LoadedBounds[2*i+swapBounds[i]]=origin[i];
- }
- else
- {
- this->LoadedBounds[2*i+swapBounds[i]]=origin[i]+
- (static_cast<double>(this->LoadedExtent[2*i])+0.5)*spacing[i];
- }
-
- if(this->LoadedExtent[2*i+1]==wholeTextureExtent[2*i+1])
- {
- this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
- (static_cast<double>(this->LoadedExtent[2*i+1])+1.0)*spacing[i];
- }
- else
- {
- this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
- (static_cast<double>(this->LoadedExtent[2*i+1])+0.5)*spacing[i];
- }
- ++i;
- }
- }
- modified=true;
- } // if enough memory
- else
- {
- }
- } //load fail with out of memory
- else
- {
- }
- } // proxy ok
- else
- { // proxy failed
- }
- }
- else
- {
- // out of therical limitationa
- }
- } // if obsolete
-
- if(this->Loaded && (needUpdate || modified))
- {
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MIN_FILTER,
- GL_NEAREST );
- glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MAG_FILTER,
- GL_NEAREST );
- modified=true;
- }
- if(modified)
- {
- this->BuildTime.Modified();
- }
- }
-
- double *GetLoadedBounds()
- {
- assert("pre: loaded" && this->Loaded);
- return this->LoadedBounds;
- }
-
- vtkIdType *GetLoadedExtent()
- {
- assert("pre: loaded" && this->Loaded);
- return this->LoadedExtent;
- }
-
- int GetLoadedCellFlag()
- {
- assert("pre: loaded" && this->Loaded);
- return this->LoadedCellFlag;
- }
-
- bool IsLoaded()
- {
- return this->Loaded;
- }
-
-protected:
- GLuint TextureId;
- vtkTimeStamp BuildTime;
- double LoadedBounds[6];
- vtkIdType LoadedExtent[6];
- int LoadedCellFlag;
- bool Loaded;
-};
-
-
-//-----------------------------------------------------------------------------
-// Display the status of the current framebuffer on the standard output.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::CheckFrameBufferStatus()
-{
- GLenum status;
- status = vtkgl::CheckFramebufferStatusEXT(vtkgl::FRAMEBUFFER_EXT);
- switch(status)
- {
- case 0:
- cout << "call to vtkgl::CheckFramebufferStatusEXT generates an error."
- << endl;
- break;
- case vtkgl::FRAMEBUFFER_COMPLETE_EXT:
- break;
- case vtkgl::FRAMEBUFFER_UNSUPPORTED_EXT:
- cout << "framebuffer is unsupported" << endl;
- break;
- case vtkgl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
- cout << "framebuffer has an attachment error"<<endl;
- break;
- case vtkgl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
- cout << "framebuffer has a missing attachment"<<endl;
- break;
- case vtkgl::FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
- cout << "framebuffer has bad dimensions"<<endl;
- break;
- case vtkgl::FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
- cout << "framebuffer has bad formats"<<endl;
- break;
- case vtkgl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
- cout << "framebuffer has bad draw buffer"<<endl;
- break;
- case vtkgl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
- cout << "framebuffer has bad read buffer"<<endl;
- break;
- default:
- cout << "Unknown framebuffer status=0x" << hex<< status << dec << endl;
- }
- // DO NOT REMOVE THE FOLLOWING COMMENTED LINE. FOR DEBUGGING PURPOSE.
-// this->DisplayFrameBufferAttachments();
-// this->DisplayReadAndDrawBuffers();
-}
-
-//-----------------------------------------------------------------------------
-vtkStdString vtkMitkOpenGLGPUVolumeRayCastMapper::BufferToString(int buffer)
-{
- vtkStdString result;
- vtksys_ios::ostringstream ost;
-
- GLint size;
-
- GLint b=static_cast<GLint>(buffer);
- switch(b)
- {
- case GL_NONE:
- ost << "GL_NONE";
- break;
- case GL_FRONT_LEFT:
- ost << "GL_FRONT_LEFT";
- break;
- case GL_FRONT_RIGHT:
- ost << "GL_FRONT_RIGHT";
- break;
- case GL_BACK_LEFT:
- ost << "GL_BACK_LEFT";
- break;
- case GL_BACK_RIGHT:
- ost << "GL_BACK_RIGHT";
- break;
- case GL_FRONT:
- ost << "GL_FRONT";
- break;
- case GL_BACK:
- ost << "GL_BACK";
- break;
- case GL_LEFT:
- ost << "GL_LEFT";
- break;
- case GL_RIGHT:
- ost << "GL_RIGHT";
- break;
- case GL_FRONT_AND_BACK:
- ost << "GL_FRONT_AND_BACK";
- break;
- default:
- glGetIntegerv(GL_AUX_BUFFERS,&size);
- if(buffer>=GL_AUX0 && buffer<(GL_AUX0+size))
- {
- ost << "GL_AUX" << (buffer-GL_AUX0);
- }
- else
- {
- glGetIntegerv(vtkgl::MAX_COLOR_ATTACHMENTS_EXT,&size);
- if(static_cast<GLuint>(buffer)>=vtkgl::COLOR_ATTACHMENT0_EXT &&
- static_cast<GLuint>(buffer)<
- (vtkgl::COLOR_ATTACHMENT0_EXT+static_cast<GLuint>(size)))
- {
- ost << "GL_COLOR_ATTACHMENT"
- << (static_cast<GLuint>(buffer)-vtkgl::COLOR_ATTACHMENT0_EXT)
- << "_EXT";
- }
- else
- {
- ost << "unknown color buffer type=0x"<<hex<<buffer<<dec;
- }
- }
- break;
- }
-
- result=ost.str();
- return result;
-}
-
-// ----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::DisplayReadAndDrawBuffers()
-{
- GLint value;
- glGetIntegerv(vtkgl::MAX_DRAW_BUFFERS,&value);
- GLenum max=static_cast<GLenum>(value);
-
- vtkStdString s;
- GLenum i=0;
- while(i<max)
- {
- glGetIntegerv(vtkgl::DRAW_BUFFER0+i,&value);
- s=this->BufferToString(static_cast<int>(value));
- cout << "draw buffer " << i << "=" << s << endl;
- ++i;
- }
-
- glGetIntegerv(GL_READ_BUFFER,&value);
- s=this->BufferToString(static_cast<int>(value));
- cout << "read buffer=" << s << endl;
-}
-
-// ----------------------------------------------------------------------------
-// Description:
-// Display all the attachments of the current framebuffer object.
-// ----------------------------------------------------------------------------
-//
-// ----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::DisplayFrameBufferAttachments()
-{
- GLint framebufferBinding;
- glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&framebufferBinding);
- this->PrintError("after getting FRAMEBUFFER_BINDING_EXT");
- if(framebufferBinding==0)
- {
- cout<<"Current framebuffer is bind to the system one"<<endl;
- }
- else
- {
- cout<<"Current framebuffer is bind to framebuffer object "
- <<framebufferBinding<<endl;
-
- GLint value;
- glGetIntegerv(vtkgl::MAX_COLOR_ATTACHMENTS_EXT,&value);
- GLenum maxColorAttachments=static_cast<GLenum>(value);
- this->PrintError("after getting MAX_COLOR_ATTACHMENTS_EXT");
- GLenum i=0;
- while(i<maxColorAttachments)
- {
- cout<<"color attachement "<<i<<":"<<endl;
- this->DisplayFrameBufferAttachment(vtkgl::COLOR_ATTACHMENT0_EXT+i);
- ++i;
- }
- cout<<"depth attachement :"<<endl;
- this->DisplayFrameBufferAttachment(vtkgl::DEPTH_ATTACHMENT_EXT);
- cout<<"stencil attachement :"<<endl;
- this->DisplayFrameBufferAttachment(vtkgl::STENCIL_ATTACHMENT_EXT);
- }
-}
-
-// ----------------------------------------------------------------------------
-// Description:
-// Display a given attachment for the current framebuffer object.
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::DisplayFrameBufferAttachment(
- unsigned int uattachment)
-{
- GLenum attachment=static_cast<GLenum>(uattachment);
-
- GLint params;
- vtkgl::GetFramebufferAttachmentParameterivEXT(
- vtkgl::FRAMEBUFFER_EXT,attachment,
- vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,&params);
-
- this->PrintError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT");
- switch(params)
- {
- case GL_NONE:
- cout<<" this attachment is empty"<<endl;
- break;
- case GL_TEXTURE:
- vtkgl::GetFramebufferAttachmentParameterivEXT(
- vtkgl::FRAMEBUFFER_EXT,attachment,
- vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,&params);
- this->PrintError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT");
- cout<<" this attachment is a texture with name: "<<params<<endl;
- vtkgl::GetFramebufferAttachmentParameterivEXT(
- vtkgl::FRAMEBUFFER_EXT,attachment,
- vtkgl::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,&params);
- this->PrintError(
- "after getting FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT");
- cout<<" its mipmap level is: "<<params<<endl;
- vtkgl::GetFramebufferAttachmentParameterivEXT(
- vtkgl::FRAMEBUFFER_EXT,attachment,
- vtkgl::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,&params);
- this->PrintError(
- "after getting FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT");
- if(params==0)
- {
- cout<<" this is not a cube map texture."<<endl;
- }
- else
- {
- cout<<" this is a cube map texture and the image is contained in face "
- <<params<<endl;
- }
- vtkgl::GetFramebufferAttachmentParameterivEXT(
- vtkgl::FRAMEBUFFER_EXT,attachment,
- vtkgl::FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,&params);
- this->PrintError(
- "after getting FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT");
- if(params==0)
- {
- cout<<" this is not 3D texture."<<endl;
- }
- else
- {
- cout<<" this is a 3D texture and the zoffset of the attached image is "
- <<params<<endl;
- }
- break;
- case vtkgl::RENDERBUFFER_EXT:
- cout<<" this attachment is a renderbuffer"<<endl;
- vtkgl::GetFramebufferAttachmentParameterivEXT(
- vtkgl::FRAMEBUFFER_EXT,attachment,
- vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,&params);
- this->PrintError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT");
- cout<<" this attachment is a renderbuffer with name: "<<params<<endl;
-
- vtkgl::BindRenderbufferEXT(vtkgl::RENDERBUFFER_EXT,
- static_cast<GLuint>(params));
- this->PrintError(
- "after getting binding the current RENDERBUFFER_EXT to params");
-
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_WIDTH_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_WIDTH_EXT");
- cout<<" renderbuffer width="<<params<<endl;
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_HEIGHT_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_HEIGHT_EXT");
- cout<<" renderbuffer height="<<params<<endl;
- vtkgl::GetRenderbufferParameterivEXT(
- vtkgl::RENDERBUFFER_EXT,vtkgl::RENDERBUFFER_INTERNAL_FORMAT_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_INTERNAL_FORMAT_EXT");
-
- cout<<" renderbuffer internal format=0x"<< hex<<params<<dec<<endl;
-
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_RED_SIZE_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_RED_SIZE_EXT");
- cout<<" renderbuffer actual resolution for the red component="<<params
- <<endl;
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_GREEN_SIZE_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_GREEN_SIZE_EXT");
- cout<<" renderbuffer actual resolution for the green component="<<params
- <<endl;
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_BLUE_SIZE_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_BLUE_SIZE_EXT");
- cout<<" renderbuffer actual resolution for the blue component="<<params
- <<endl;
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_ALPHA_SIZE_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_ALPHA_SIZE_EXT");
- cout<<" renderbuffer actual resolution for the alpha component="<<params
- <<endl;
- vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::RENDERBUFFER_DEPTH_SIZE_EXT,
- &params);
- this->PrintError("after getting RENDERBUFFER_DEPTH_SIZE_EXT");
- cout<<" renderbuffer actual resolution for the depth component="<<params
- <<endl;
- vtkgl::GetRenderbufferParameterivEXT(
- vtkgl::RENDERBUFFER_EXT,vtkgl::RENDERBUFFER_STENCIL_SIZE_EXT,&params);
- this->PrintError("after getting RENDERBUFFER_STENCIL_SIZE_EXT");
- cout<<" renderbuffer actual resolution for the stencil component="
- <<params<<endl;
- break;
- default:
- cout<<" unexcepted value."<<endl;
- break;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Return a string matching the OpenGL errorCode. The returned string will
-// not be null.
-//-----------------------------------------------------------------------------
-const char *vtkMitkOpenGLGPUVolumeRayCastMapper::OpenGLErrorMessage(
- unsigned int errorCode)
-{
- const char *result;
- switch(static_cast<GLenum>(errorCode))
- {
- case GL_NO_ERROR:
- result="No error";
- break;
- case GL_INVALID_ENUM:
- result="Invalid enum";
- break;
- case GL_INVALID_VALUE:
- result="Invalid value";
- break;
- case GL_INVALID_OPERATION:
- result="Invalid operation";
- break;
- case GL_STACK_OVERFLOW:
- result="stack overflow";
- break;
- case GL_STACK_UNDERFLOW:
- result="stack underflow";
- break;
- case GL_OUT_OF_MEMORY:
- result="out of memory";
- break;
- case vtkgl::TABLE_TOO_LARGE:
- // GL_ARB_imaging
- result="Table too large";
- break;
- case vtkgl::INVALID_FRAMEBUFFER_OPERATION_EXT:
- // GL_EXT_framebuffer_object, 310
- result="invalid framebuffer operation ext";
- break;
- case vtkgl::TEXTURE_TOO_LARGE_EXT:
- // GL_EXT_texture
- result="Texture too large";
- break;
- default:
- result="unknown error";
- }
- assert("post: result_exists" && result!=0);
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Display headerMessage on the standard output and the last OpenGL error
-// message if any.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError(const char *headerMessage)
-{
- GLenum errorCode=glGetError();
- if(errorCode!=GL_NO_ERROR)
- {
- if ( headerMessage )
- {
- cout<<headerMessage;
- }
- cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
- cout<<OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
- cout<<endl;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Construct a new vtkMitkOpenGLGPUVolumeRayCastMapper with default values
-//-----------------------------------------------------------------------------
-vtkMitkOpenGLGPUVolumeRayCastMapper::vtkMitkOpenGLGPUVolumeRayCastMapper()
-{
- this->UnsupportedRequiredExtensions=0;
- this->OpenGLObjectsCreated=0;
- this->LoadExtensionsSucceeded=0;
- this->NumberOfFrameBuffers=0;
-
- this->m_BindMax = false;
-
- // up to 2 frame buffer 2D textures (left/right)
- // 1 dataset 3D texture
- // 1 colormap 1D texture
- // 1 opacitymap 1d texture
- // 1 grabbed depth buffer 2d texture
- int i=0;
- while(i<vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects)
- {
- this->TextureObjects[i]=0;
- ++i;
- }
-
- this->DepthRenderBufferObject=0;
- this->FrameBufferObject=0;
-
- for ( int j = 0; j < 8; j++ )
- {
- for (i = 0; i < 3; i++ )
- {
- this->BoundingBox[j][i] = 0.0;
- }
- }
-
- this->LastSize[0]=0;
- this->LastSize[1]=0;
-
- this->ReductionFactor = 1.0;
-
- this->Supports_GL_ARB_texture_float=0;
- this->SupportsPixelBufferObjects=0;
-
- i=0;
- while(i<3)
- {
- this->TempMatrix[i]=vtkMatrix4x4::New();
- ++i;
- }
-
- this->ErrorLine=0;
- this->ErrorColumn=0;
- this->ErrorString=0;
-
- this->LastParallelProjection=
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
- this->LastRayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
- this->LastCroppingMode=
- vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
- this->LastComponent=
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
- this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
-
- this->ClippedBoundingBox = NULL;
-
- this->SmallInput = NULL;
-
- this->MaxValueFrameBuffer=0;
- this->MaxValueFrameBuffer2=0;
- this->ReducedSize[0]=0;
- this->ReducedSize[1]=0;
-
- this->NumberOfCroppingRegions=0;
-
- this->PolyDataBoundingBox=0;
- this->Planes=0;
- this->NearPlane=0;
- this->Clip=0;
- this->Densify=0;
- this->InvVolumeMatrix=vtkMatrix4x4::New();
-
- this->ScaleBiasProgramShader=0;
- this->UFrameBufferTexture=-1;
- this->UScale=-1;
- this->UBias=-1;
-
- this->SavedFrameBuffer=0;
-
- this->BoxSource=0;
-
- this->NoiseTexture=0;
- this->NoiseTextureSize=0;
- this->NoiseTextureId=0;
-
- this->IgnoreSampleDistancePerPixel=true;
-
- this->ScalarsTextures=new vtkMapDataArrayTextureId;
- this->MaskTextures=new vtkMapMaskTextureId;
-
- this->RGBTable=0;
- this->Mask1RGBTable=0;
- this->Mask2RGBTable=0;
- this->OpacityTables=0;
-
- this->CurrentScalar=0;
- this->CurrentMask=0;
-
- this->ActualSampleDistance=1.0;
- this->LastProgressEventTime=0.0; // date in seconds
-
- this->PreserveOrientation=true;
-}
-
-//-----------------------------------------------------------------------------
-// Destruct a vtkMitkOpenGLGPUVolumeRayCastMapper - clean up any memory used
-//-----------------------------------------------------------------------------
-vtkMitkOpenGLGPUVolumeRayCastMapper::~vtkMitkOpenGLGPUVolumeRayCastMapper()
-{
- if(this->UnsupportedRequiredExtensions!=0)
- {
- delete this->UnsupportedRequiredExtensions;
- this->UnsupportedRequiredExtensions=0;
- }
- int i=0;
- while(i<3)
- {
- this->TempMatrix[i]->Delete();
- this->TempMatrix[i]=0;
- ++i;
- }
-
- if(this->ErrorString!=0)
- {
- delete[] this->ErrorString;
- this->ErrorString=0;
- }
-
- if ( this->SmallInput )
- {
- this->SmallInput->UnRegister(this);
- }
-
- if(this->PolyDataBoundingBox!=0)
- {
- this->PolyDataBoundingBox->UnRegister(this);
- this->PolyDataBoundingBox=0;
- }
- if(this->Planes!=0)
- {
- this->Planes->UnRegister(this);
- this->Planes=0;
- }
- if(this->NearPlane!=0)
- {
- this->NearPlane->UnRegister(this);
- this->NearPlane=0;
- }
- if(this->Clip!=0)
- {
- this->Clip->UnRegister(this);
- this->Clip=0;
- }
- if(this->Densify!=0)
- {
- this->Densify->UnRegister(this);
- this->Densify=0;
- }
-
- if(this->BoxSource!=0)
- {
- this->BoxSource->UnRegister(this);
- this->BoxSource=0;
- }
- this->InvVolumeMatrix->UnRegister(this);
- this->InvVolumeMatrix=0;
-
- if(this->NoiseTexture!=0)
- {
- delete[] this->NoiseTexture;
- this->NoiseTexture=0;
- this->NoiseTextureSize=0;
- }
-
- if(this->ScalarsTextures!=0)
- {
- delete this->ScalarsTextures;
- this->ScalarsTextures=0;
- }
-
- if(this->MaskTextures!=0)
- {
- delete this->MaskTextures;
- this->MaskTextures=0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Based on hardware and properties, we may or may not be able to
-// render using 3D texture mapping. This indicates if 3D texture
-// mapping is supported by the hardware, and if the other extensions
-// necessary to support the specific properties are available.
-//
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::IsRenderSupported(
- vtkRenderWindow *window,
- vtkVolumeProperty *vtkNotUsed(property))
-{
- window->MakeCurrent();
- if(!this->LoadExtensionsSucceeded)
- {
- this->LoadExtensions(window);
- }
- if(!this->LoadExtensionsSucceeded)
- {
- vtkDebugMacro(
- "The following OpenGL extensions are required but not supported: "
- << (this->UnsupportedRequiredExtensions->Stream.str()).c_str());
- return 0;
- }
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Return if the required OpenGL extension `extensionName' is supported.
-// If not, its name is added to the string of unsupported but required
-// extensions.
-// \pre extensions_exist: extensions!=0
-// \pre extensionName_exists: extensionName!=0
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::TestRequiredExtension(
- vtkOpenGLExtensionManager *extensions,
- const char *extensionName)
-{
- assert("pre: extensions_exist" && extensions!=0);
- assert("pre: extensionName_exists" && extensionName!=0);
- int result=extensions->ExtensionSupported(extensionName);
-
- if(!result)
- {
- if(this->LoadExtensionsSucceeded)
- {
- this->UnsupportedRequiredExtensions->Stream<<extensionName;
- this->LoadExtensionsSucceeded=0;
- }
- else
- {
- this->UnsupportedRequiredExtensions->Stream<<", "<<extensionName;
- }
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Attempt to load required and optional OpenGL extensions for the current
-// context window. Variable LoadExtensionsSucceeded is set if all required
-// extensions has been loaded. In addition, variable
-// Supports_GL_ARB_texture_float is set if this extension has been loaded.
-//
-// Pre-conditions:
-// - window != NULL
-//
-// Post-conditions:
-// - this->LoadExtensionsSucceeded will be set to 0 or 1
-// - this->UnsupportedRequiredExtensions will have a message indicating
-// any failure codes
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::LoadExtensions(
- vtkRenderWindow *window)
-{
- // We may already have a string stream for the unsupported extensions
- // from the last time this method was called. If so, delete it.
- if(this->UnsupportedRequiredExtensions!=0)
- {
- delete this->UnsupportedRequiredExtensions;
- }
-
- // Create a string stream to hold the unsupported extensions so we can
- // report something meaningful back
- this->UnsupportedRequiredExtensions =
- new vtkUnsupportedRequiredExtensionsStringStream;
-
- // It does not work on Apple OS X Snow Leopard with nVidia.
- // There is a bug in the OpenGL driver with an error in the
- // Cg compiler about an infinite loop.
-#ifdef __APPLE__
- this->LoadExtensionsSucceeded=0;
- return;
-#endif
-
- // Assume success
- this->LoadExtensionsSucceeded=1;
-
- const char *gl_vendor=reinterpret_cast<const char *>(glGetString(GL_VENDOR));
- /* if(strstr(gl_vendor,"ATI")!=0)
- {
- this->LoadExtensionsSucceeded=0;
- return;
- }*/
- const char *gl_version=reinterpret_cast<const char *>(glGetString(GL_VERSION));
- if(strstr(gl_version,"Mesa")!=0)
- {
- // - GL_VENDOR cannot be used because it can be "Brian Paul" or
- // "Mesa project"
- // - GL_RENDERER cannot be used because it can be "Software Rasterizer" or
- // "Mesa X11"
- // - GL_VERSION is more robust. It has things like "2.0 Mesa 7.0.4" or
- // "2.1 Mesa 7.2" or "2.1 Mesa 7.3-devel"
- // Mesa does not work with multiple draw buffers:
- // "framebuffer has bad draw buffer"
- // "render clipped 1 ERROR (x506) invalid framebuffer operation ext"
- this->LoadExtensionsSucceeded=0;
- return;
- }
-
- // Create an extension manager
- vtkOpenGLExtensionManager *extensions=vtkOpenGLExtensionManager::New();
- extensions->SetRenderWindow(window);
-
- // GL_ARB_draw_buffers requires OpenGL 1.3, so we must have OpenGL 1.3
- // We don't need to check for some extensions that become part of OpenGL
- // core after 1.3. Among them:
- // - texture_3d is in core OpenGL since 1.2
- // - texture_edge_clamp is in core OpenGL since 1.2
- // (GL_SGIS_texture_edge_clamp or GL_EXT_texture_edge_clamp (nVidia) )
- // - multitexture is in core OpenGL since 1.3
-
- int supports_GL_1_3=extensions->ExtensionSupported("GL_VERSION_1_3");
- int supports_GL_2_0=0;
-
- // No 1.3 support - give up
- if(!supports_GL_1_3)
- {
- this->LoadExtensionsSucceeded=0;
- this->UnsupportedRequiredExtensions->Stream<<
- " OpenGL 1.3 is required but not supported";
- extensions->Delete();
- return;
- }
-
- // Check for 2.0 support
- supports_GL_2_0=extensions->ExtensionSupported("GL_VERSION_2_0");
-
- // Some extensions that are supported in 2.0, but if we don't
- // have 2.0 we'll need to check further
- int supports_shading_language_100 = 1;
- int supports_shader_objects = 1;
- int supports_fragment_shader = 1;
- int supports_texture_non_power_of_two = 1;
- int supports_draw_buffers = 1;
- if(!supports_GL_2_0)
- {
- supports_shading_language_100=
- extensions->ExtensionSupported("GL_ARB_shading_language_100");
- supports_shader_objects=
- extensions->ExtensionSupported("GL_ARB_shader_objects");
- supports_fragment_shader=
- extensions->ExtensionSupported("GL_ARB_fragment_shader");
- supports_texture_non_power_of_two=
- extensions->ExtensionSupported("GL_ARB_texture_non_power_of_two");
- supports_draw_buffers=
- extensions->ExtensionSupported("GL_ARB_draw_buffers");
- }
-
- // We have to check for framebuffer objects
- int supports_GL_EXT_framebuffer_object=
- extensions->ExtensionSupported("GL_EXT_framebuffer_object" );
-
- // Find out if we have OpenGL 1.4 support
- int supports_GL_1_4=extensions->ExtensionSupported("GL_VERSION_1_4");
-
- // Find out if we have the depth texture ARB extension
- int supports_GL_ARB_depth_texture=
- extensions->ExtensionSupported("GL_ARB_depth_texture");
-
- // Depth textures are support if we either have OpenGL 1.4
- // or if the depth texture ARB extension is supported
- int supports_depth_texture =
- supports_GL_1_4 || supports_GL_ARB_depth_texture;
-
- // Now start adding messages to the UnsupportedRequiredExtensions string
- // Log message if shading language 100 is not supported
- if(!supports_shading_language_100)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " shading_language_100 (or OpenGL 2.0) is required but not supported";
- this->LoadExtensionsSucceeded=0;
- }
- else
- {
- // We can query the GLSL version, we need >=1.20
- const char *glsl_version=
- reinterpret_cast<const char *>(glGetString(vtkgl::SHADING_LANGUAGE_VERSION));
- int glslMajor, glslMinor;
- vtksys_ios::istringstream ist(glsl_version);
- ist >> glslMajor;
- char c;
- ist.get(c); // '.'
- ist >> glslMinor;
-//sscanf(version, "%d.%d", &glslMajor, &glslMinor);
- if(glslMajor<1 || (glslMajor==1 && glslMinor<20))
- {
- this->LoadExtensionsSucceeded=0;
- }
- }
-
- // Log message if shader objects are not supported
- if(!supports_shader_objects)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " shader_objects (or OpenGL 2.0) is required but not supported";
- this->LoadExtensionsSucceeded=0;
- }
-
- // Log message if fragment shaders are not supported
- if(!supports_fragment_shader)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " fragment_shader (or OpenGL 2.0) is required but not supported";
- this->LoadExtensionsSucceeded=0;
- }
-
- // Log message if non power of two textures are not supported
- if(!supports_texture_non_power_of_two)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " texture_non_power_of_two (or OpenGL 2.0) is required but not "
- << "supported";
- this->LoadExtensionsSucceeded=0;
- }
-
- // Log message if draw buffers are not supported
- if(!supports_draw_buffers)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " draw_buffers (or OpenGL 2.0) is required but not supported";
- this->LoadExtensionsSucceeded=0;
- }
-
- // Log message if depth textures are not supported
- if(!supports_depth_texture)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " depth_texture (or OpenGL 1.4) is required but not supported";
- this->LoadExtensionsSucceeded=0;
- }
-
- // Log message if framebuffer objects are not supported
- if(!supports_GL_EXT_framebuffer_object)
- {
- this->UnsupportedRequiredExtensions->Stream<<
- " framebuffer_object is required but not supported";
- this->LoadExtensionsSucceeded=0;
- }
-
- // Have we succeeded so far? If not, just return.
- if(!this->LoadExtensionsSucceeded)
- {
- extensions->Delete();
- return;
- }
-
- // Now start loading the extensions
- // First load all 1.2 and 1.3 extensions (we know we
- // support at least up to 1.3)
- extensions->LoadExtension("GL_VERSION_1_2");
- extensions->LoadExtension("GL_VERSION_1_3");
-
- // Load the 2.0 extensions if supported
- if(supports_GL_2_0)
- {
- extensions->LoadExtension("GL_VERSION_2_0");
- }
- // Otherwise, we'll need to specifically load the
- // shader objects, fragment shader, and draw buffers
- // extensions
- else
- {
- extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
- extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
- extensions->LoadCorePromotedExtension("GL_ARB_draw_buffers");
- }
-
- // Load the framebuffer object extension
- extensions->LoadExtension("GL_EXT_framebuffer_object");
-
- // Optional extension (does not fail if not present)
- // Load it if supported which will allow us to store
- // textures as floats
- this->Supports_GL_ARB_texture_float=
- extensions->ExtensionSupported("GL_ARB_texture_float" );
- if(this->Supports_GL_ARB_texture_float)
- {
- extensions->LoadExtension( "GL_ARB_texture_float" );
- }
-
- // Optional extension (does not fail if not present)
- // Used to minimize memory footprint when loading large 3D textures
- // of scalars.
- // VBO or 1.5 is required by PBO or 2.1
- int supports_GL_1_5=extensions->ExtensionSupported("GL_VERSION_1_5");
- int supports_vertex_buffer_object=supports_GL_1_5 ||
- extensions->ExtensionSupported("GL_ARB_vertex_buffer_object");
- int supports_GL_2_1=extensions->ExtensionSupported("GL_VERSION_2_1");
- this->SupportsPixelBufferObjects=supports_vertex_buffer_object &&
- (supports_GL_2_1 ||
- extensions->ExtensionSupported("GL_ARB_pixel_buffer_object"));
-
- if(this->SupportsPixelBufferObjects)
- {
- if(supports_GL_1_5)
- {
- extensions->LoadExtension("GL_VERSION_1_5");
- }
- else
- {
- extensions->LoadCorePromotedExtension("GL_ARB_vertex_buffer_object");
- }
- if(supports_GL_2_1)
- {
- extensions->LoadExtension("GL_VERSION_2_1");
- }
- else
- {
- extensions->LoadCorePromotedExtension("GL_ARB_pixel_buffer_object");
- }
- }
-
- // Ultimate test. Some old cards support OpenGL 2.0 but not while
- // statements in a fragment shader (example: nVidia GeForce FX 5200)
- // It does not fail when compiling each shader source but at linking
- // stage because the parser underneath only check for syntax during
- // compilation and the actual native code generation happens during
- // the linking stage.
- this->CreateGLSLObjects();
- this->NumberOfCroppingRegions=1;
- this->BuildProgram(1,vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite,
- vtkMitkOpenGLGPUVolumeRayCastMapperShadeNo,
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne);
-
- GLint params;
- vtkgl::GetProgramiv(static_cast<GLuint>(this->ProgramShader),
- vtkgl::LINK_STATUS,&params);
- if(params==GL_FALSE)
- {
- this->LoadExtensionsSucceeded=0;
- this->UnsupportedRequiredExtensions->Stream<<
- " this card does not support while statements in fragment shaders.";
- }
-
- // FB debug
- this->CheckLinkage(this->ProgramShader);
-
- // Release GLSL Objects.
- GLuint programShader=static_cast<GLuint>(this->ProgramShader);
- vtkgl::DeleteProgram(programShader);
-
- this->LastParallelProjection=
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
- this->LastRayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
- this->LastCroppingMode=
- vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
- this->LastComponent=
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
- this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
-
- extensions->Delete();
-}
-
-//-----------------------------------------------------------------------------
-// Create GLSL OpenGL objects such fragment program Ids.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::CreateGLSLObjects()
-{
- GLuint programShader;
- GLuint fragmentMainShader;
-
- programShader=vtkgl::CreateProgram();
- fragmentMainShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
- vtkgl::AttachShader(programShader,fragmentMainShader);
- vtkgl::DeleteShader(fragmentMainShader); // reference counting
-
- vtkgl::ShaderSource(
- fragmentMainShader,1,
- const_cast<const char **>(&vtkMitkGPUVolumeRayCastMapper_HeaderFS),0);
- vtkgl::CompileShader(fragmentMainShader);
-
- this->CheckCompilation(static_cast<unsigned int>(fragmentMainShader));
-
- GLuint fragmentProjectionShader;
- GLuint fragmentTraceShader;
- GLuint fragmentCroppingShader;
- GLuint fragmentComponentShader;
- GLuint fragmentShadeShader;
-
- fragmentProjectionShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
- vtkgl::AttachShader(programShader,fragmentProjectionShader);
- vtkgl::DeleteShader(fragmentProjectionShader); // reference counting
-
- fragmentTraceShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
- vtkgl::AttachShader(programShader,fragmentTraceShader);
- vtkgl::DeleteShader(fragmentTraceShader); // reference counting
- fragmentCroppingShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
- vtkgl::AttachShader(programShader,fragmentCroppingShader);
- vtkgl::DeleteShader(fragmentCroppingShader); // reference counting
-
- fragmentComponentShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
-
- // don't delete it, it is optionally attached.
- fragmentShadeShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
-
- // Save GL objects by static casting to standard C types. GL* types
- // are not allowed in VTK header files.
- this->ProgramShader=static_cast<unsigned int>(programShader);
-
- this->FragmentMainShader=static_cast<unsigned int>(fragmentMainShader);
- this->FragmentProjectionShader=
- static_cast<unsigned int>(fragmentProjectionShader);
- this->FragmentTraceShader=static_cast<unsigned int>(fragmentTraceShader);
- this->FragmentCroppingShader=
- static_cast<unsigned int>(fragmentCroppingShader);
- this->FragmentComponentShader=
- static_cast<unsigned int>(fragmentComponentShader);
- this->FragmentShadeShader=
- static_cast<unsigned int>(fragmentShadeShader);
-
-}
-
-void vtkMitkOpenGLGPUVolumeRayCastMapper::BindFramebuffer()
-{
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,
- this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront],
- 0);
- GLenum err = glGetError();
-
- if(m_BindMax)
- {
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT+1,
- GL_TEXTURE_2D,this->MaxValueFrameBuffer,0);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Create OpenGL objects such as textures, buffers and fragment program Ids.
-// It only registers Ids, there is no actual initialization of textures or
-// fragment program.
-//
-// Pre-conditions:
-// This method assumes that this->LoadedExtensionsSucceeded is 1.
-//
-// Post-conditions:
-// When this method completes successfully, this->OpenGLObjectsCreated
-// will be 1.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::CreateOpenGLObjects()
-{
- // Do nothing if the OpenGL objects have already been created
- if ( this->OpenGLObjectsCreated )
- {
- return;
- }
-
- // We need only two color buffers (ping-pong)
- this->NumberOfFrameBuffers=2;
-
- // TODO: clean this up!
- // 2*Frame buffers(2d textures)+colorMap (1d texture) +dataset (3d texture)
- // + opacitymap (1d texture) + grabbed depthMap (2d texture)
-
- // Frame buffers(2d textures)+colorMap (1d texture) +dataset (3d texture)
- // + opacity (1d texture)+grabbed depth buffer (2d texture)
-
- GLuint frameBufferObject;
- GLuint depthRenderBufferObject;
- GLuint textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects];
-
- // Create the various objects we will need - one frame buffer
- // which will contain a render buffer for depth and a texture
- // for color.
- vtkgl::GenFramebuffersEXT(1, &frameBufferObject); // color
- vtkgl::GenRenderbuffersEXT(1, &depthRenderBufferObject); // depth
- glGenTextures(vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects,textureObjects);
-
- // Color buffers
- GLint value;
- glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&value);
- GLuint savedFrameBuffer=static_cast<GLuint>(value);
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,frameBufferObject);
-
-
- // Depth buffer
- vtkgl::BindRenderbufferEXT(vtkgl::RENDERBUFFER_EXT,
- depthRenderBufferObject);
-
- vtkgl::FramebufferRenderbufferEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::DEPTH_ATTACHMENT_EXT,
- vtkgl::RENDERBUFFER_EXT,
- depthRenderBufferObject);
-
- // Restore default frame buffer.
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,savedFrameBuffer);
-
-
- this->CreateGLSLObjects();
-
- // Save GL objects by static casting to standard C types. GL* types
- // are not allowed in VTK header files.
- this->FrameBufferObject=static_cast<unsigned int>(frameBufferObject);
- this->DepthRenderBufferObject=static_cast<unsigned int>(depthRenderBufferObject);
- int i=0;
- while(i<vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects)
- {
- this->TextureObjects[i]=static_cast<unsigned int>(textureObjects[i]);
- ++i;
- }
-
-
- this->OpenGLObjectsCreated=1;
-}
-
-
-//-----------------------------------------------------------------------------
-// Check the compilation status of some fragment shader source.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::CheckCompilation(
- unsigned int fragmentShader)
-{
- GLuint fs=static_cast<GLuint>(fragmentShader);
- GLint params;
- vtkgl::GetShaderiv(fs,vtkgl::COMPILE_STATUS,&params);
-
- if(params==GL_TRUE)
- {
- vtkDebugMacro(<<"shader source compiled successfully");
- }
- else
- {
- vtkErrorMacro(<<"shader source compile error");
- // include null terminator
- vtkgl::GetShaderiv(fs,vtkgl::INFO_LOG_LENGTH,&params);
- if(params>0)
- {
- char *buffer=new char[params];
- vtkgl::GetShaderInfoLog(fs,params,0,buffer);
- vtkErrorMacro(<<"log: "<<buffer);
- delete[] buffer;
- }
- else
- {
- vtkErrorMacro(<<"no log");
- }
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Print the list of uniform variables. This is a debugging method used only
-// internally to this class.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::PrintUniformVariables(unsigned int programShader)
-{
- GLint params;
- GLuint prog=static_cast<GLuint>(programShader);
-
- // info about the list of active uniform variables
- vtkgl::GetProgramiv(prog,vtkgl::ACTIVE_UNIFORMS,&params);
- cout<<"There are "<<params<<" active uniform variables"<<endl;
- GLuint i=0;
- GLuint c=static_cast<GLuint>(params);
- vtkgl::GetProgramiv(prog,vtkgl::OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB,
- &params);
-
- GLint buffSize=params;
- char *name=new char[buffSize+1];
- GLint size;
- GLenum type;
- while(i<c)
- {
- vtkgl::GetActiveUniform(prog,i,buffSize,0,&size,&type,name);
- cout<<i<<" ";
- switch(type)
- {
- case GL_FLOAT:
- cout<<"float";
- break;
- case vtkgl::FLOAT_VEC2_ARB:
- cout<<"vec2";
- break;
- case vtkgl::FLOAT_VEC3_ARB:
- cout<<"vec3";
- break;
- case vtkgl::FLOAT_VEC4_ARB:
- cout<<"vec4";
- break;
- case GL_INT:
- cout<<"int";
- break;
- case vtkgl::INT_VEC2_ARB:
- cout<<"ivec2";
- break;
- case vtkgl::INT_VEC3_ARB:
- cout<<"ivec3";
- break;
- case vtkgl::INT_VEC4_ARB:
- cout<<"ivec4";
- break;
- case vtkgl::BOOL_ARB:
- cout<<"bool";
- break;
- case vtkgl::BOOL_VEC2_ARB:
- cout<<"bvec2";
- break;
- case vtkgl::BOOL_VEC3_ARB:
- cout<<"bvec3";
- break;
- case vtkgl::BOOL_VEC4_ARB:
- cout<<"bvec4";
- break;
- case vtkgl::FLOAT_MAT2_ARB:
- cout<<"mat2";
- break;
- case vtkgl::FLOAT_MAT3_ARB:
- cout<<"mat3";
- break;
- case vtkgl::FLOAT_MAT4_ARB:
- cout<<"mat4";
- break;
- case vtkgl::SAMPLER_1D_ARB:
- cout<<"sampler1D";
- break;
- case vtkgl::SAMPLER_2D_ARB:
- cout<<"sampler2D";
- break;
- case vtkgl::SAMPLER_3D_ARB:
- cout<<"sampler3D";
- break;
- case vtkgl::SAMPLER_CUBE_ARB:
- cout<<"samplerCube";
- break;
- case vtkgl::SAMPLER_1D_SHADOW_ARB:
- cout<<"sampler1Dshadow";
- break;
- case vtkgl::SAMPLER_2D_SHADOW_ARB:
- cout<<"sampler2Dshadow";
- break;
- }
- cout<<" "<<name<<endl;
- ++i;
- }
- delete[] name;
-}
-
-
-//-----------------------------------------------------------------------------
-// Check the linkage status of the fragment program. This is an internal
-// debugging method only. Returns 1 if link status is TRUE, 0 otherwise.
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::CheckLinkage(unsigned int programShader)
-{
- GLint params;
- GLuint prog=static_cast<GLuint>(programShader);
- vtkgl::GetProgramiv(prog,vtkgl::LINK_STATUS,&params);
- int status = 0;
- if(params==GL_TRUE)
- {
- status = 1;
- vtkDebugMacro(<<"program linked successfully");
- }
- else
- {
- vtkErrorMacro(<<"program link error");
- vtkgl::GetProgramiv(prog,vtkgl::INFO_LOG_LENGTH,&params);
- if(params>0)
- {
- char *buffer=new char[params];
- vtkgl::GetProgramInfoLog(prog,params,0,buffer);
- vtkErrorMacro(<<"log: "<<buffer);
- delete[] buffer;
- }
- else
- {
- vtkErrorMacro(<<"no log: ");
- }
- }
-
- return status;
-}
-
-//-----------------------------------------------------------------------------
-// Delete OpenGL objects.
-// \post done: this->OpenGLObjectsCreated==0
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::ReleaseGraphicsResources(
- vtkWindow *window)
-{
- if(this->OpenGLObjectsCreated)
- {
- window->MakeCurrent();
- this->LastSize[0]=0;
- this->LastSize[1]=0;
- GLuint frameBufferObject=static_cast<GLuint>(this->FrameBufferObject);
- vtkgl::DeleteFramebuffersEXT(1,&frameBufferObject);
- GLuint depthRenderBufferObject=
- static_cast<GLuint>(this->DepthRenderBufferObject);
- vtkgl::DeleteRenderbuffersEXT(1,&depthRenderBufferObject);
- GLuint textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects];
- int i=0;
- while(i<(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers))
- {
- textureObjects[i]=static_cast<GLuint>(this->TextureObjects[i]);
- ++i;
- }
- glDeleteTextures(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers,textureObjects);
-
- if(this->MaxValueFrameBuffer!=0)
- {
- GLuint maxValueFrameBuffer=
- static_cast<GLuint>(this->MaxValueFrameBuffer);
- glDeleteTextures(1,&maxValueFrameBuffer);
- this->MaxValueFrameBuffer=0;
- }
- if(this->MaxValueFrameBuffer2!=0)
- {
- GLuint maxValueFrameBuffer2=
- static_cast<GLuint>(this->MaxValueFrameBuffer2);
- glDeleteTextures(1,&maxValueFrameBuffer2);
- this->MaxValueFrameBuffer2=0;
- }
-
- GLuint programShader=static_cast<GLuint>(this->ProgramShader);
- vtkgl::DeleteProgram(programShader);
- this->ProgramShader=0;
- GLuint fragmentComponentShader=
- static_cast<GLuint>(this->FragmentComponentShader);
- vtkgl::DeleteShader(fragmentComponentShader);
- GLuint fragmentShadeShader=
- static_cast<GLuint>(this->FragmentShadeShader);
- vtkgl::DeleteShader(fragmentShadeShader);
-
- GLuint scaleBiasProgramShader=
- static_cast<GLuint>(this->ScaleBiasProgramShader);
- if(scaleBiasProgramShader!=0)
- {
- vtkgl::DeleteProgram(scaleBiasProgramShader);
- this->ScaleBiasProgramShader=0;
- }
- this->LastParallelProjection=
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
- this->LastRayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
- this->LastCroppingMode=
- vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
- this->LastComponent=
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
- this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
- this->OpenGLObjectsCreated=0;
- }
-
- if(this->NoiseTextureId!=0)
- {
- window->MakeCurrent();
- GLuint noiseTextureObjects=static_cast<GLuint>(this->NoiseTextureId);
- glDeleteTextures(1,&noiseTextureObjects);
- this->NoiseTextureId=0;
- }
-
- if(this->ScalarsTextures!=0)
- {
- if(!this->ScalarsTextures->Map.empty())
- {
- vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=this->ScalarsTextures->Map.begin();
- while(it!=this->ScalarsTextures->Map.end())
- {
- vtkKWScalarField *texture=(*it).second;
- delete texture;
- ++it;
- }
- this->ScalarsTextures->Map.clear();
- }
- }
-
- if(this->MaskTextures!=0)
- {
- if(!this->MaskTextures->Map.empty())
- {
- vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it=this->MaskTextures->Map.begin();
- while(it!=this->MaskTextures->Map.end())
- {
- vtkKWMask *texture=(*it).second;
- delete texture;
- ++it;
- }
- this->MaskTextures->Map.clear();
- }
- }
-
- if(this->RGBTable!=0)
- {
- delete this->RGBTable;
- this->RGBTable=0;
- }
-
- if(this->Mask1RGBTable!=0)
- {
- delete this->Mask1RGBTable;
- this->Mask1RGBTable=0;
- }
-
- if(this->Mask2RGBTable!=0)
- {
- delete this->Mask2RGBTable;
- this->Mask2RGBTable=0;
- }
-
- if(this->OpacityTables!=0)
- {
- delete this->OpacityTables;
- this->OpacityTables=0;
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Delete OpenGL objects.
-// \post done: this->OpenGLObjectsCreated==0
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::ReleaseGraphicsResources(
- mitk::BaseRenderer * renderer)
-{
- if(this->OpenGLObjectsCreated)
- {
- vtkWindow * window = renderer->GetVtkRenderer()->GetRenderWindow();
- window->MakeCurrent();
- this->LastSize[0]=0;
- this->LastSize[1]=0;
- GLuint frameBufferObject=static_cast<GLuint>(this->FrameBufferObject);
- vtkgl::DeleteFramebuffersEXT(1,&frameBufferObject);
- GLuint depthRenderBufferObject=
- static_cast<GLuint>(this->DepthRenderBufferObject);
- vtkgl::DeleteRenderbuffersEXT(1,&depthRenderBufferObject);
- GLuint textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects];
- int i=0;
- while(i<(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers))
- {
- textureObjects[i]=static_cast<GLuint>(this->TextureObjects[i]);
- ++i;
- }
- glDeleteTextures(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers,textureObjects);
-
- if(this->MaxValueFrameBuffer!=0)
- {
- GLuint maxValueFrameBuffer=
- static_cast<GLuint>(this->MaxValueFrameBuffer);
- glDeleteTextures(1,&maxValueFrameBuffer);
- this->MaxValueFrameBuffer=0;
- }
- if(this->MaxValueFrameBuffer2!=0)
- {
- GLuint maxValueFrameBuffer2=
- static_cast<GLuint>(this->MaxValueFrameBuffer2);
- glDeleteTextures(1,&maxValueFrameBuffer2);
- this->MaxValueFrameBuffer2=0;
- }
-
- GLuint programShader=static_cast<GLuint>(this->ProgramShader);
- vtkgl::DeleteProgram(programShader);
- this->ProgramShader=0;
- GLuint fragmentComponentShader=
- static_cast<GLuint>(this->FragmentComponentShader);
- vtkgl::DeleteShader(fragmentComponentShader);
- GLuint fragmentShadeShader=
- static_cast<GLuint>(this->FragmentShadeShader);
- vtkgl::DeleteShader(fragmentShadeShader);
-
- GLuint scaleBiasProgramShader=
- static_cast<GLuint>(this->ScaleBiasProgramShader);
- if(scaleBiasProgramShader!=0)
- {
- vtkgl::DeleteProgram(scaleBiasProgramShader);
- this->ScaleBiasProgramShader=0;
- }
- this->LastParallelProjection=
- vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
- this->LastRayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
- this->LastCroppingMode=
- vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
- this->LastComponent=
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
- this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
- this->OpenGLObjectsCreated=0;
- }
-
- if(this->NoiseTextureId!=0)
- {
- window->MakeCurrent();
- GLuint noiseTextureObjects=static_cast<GLuint>(this->NoiseTextureId);
- glDeleteTextures(1,&noiseTextureObjects);
- this->NoiseTextureId=0;
- }
-
- if(this->ScalarsTextures!=0)
- {
- if(!this->ScalarsTextures->Map.empty())
- {
- vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=this->ScalarsTextures->Map.begin();
- while(it!=this->ScalarsTextures->Map.end())
- {
- vtkKWScalarField *texture=(*it).second;
- delete texture;
- ++it;
- }
- this->ScalarsTextures->Map.clear();
- }
- }
-
- if(this->MaskTextures!=0)
- {
- if(!this->MaskTextures->Map.empty())
- {
- vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it=this->MaskTextures->Map.begin();
- while(it!=this->MaskTextures->Map.end())
- {
- vtkKWMask *texture=(*it).second;
- delete texture;
- ++it;
- }
- this->MaskTextures->Map.clear();
- }
- }
-
- if(this->RGBTable!=0)
- {
- delete this->RGBTable;
- this->RGBTable=0;
- }
-
- if(this->Mask1RGBTable!=0)
- {
- delete this->Mask1RGBTable;
- this->Mask1RGBTable=0;
- }
-
- if(this->Mask2RGBTable!=0)
- {
- delete this->Mask2RGBTable;
- this->Mask2RGBTable=0;
- }
-
- if(this->OpacityTables!=0)
- {
- delete this->OpacityTables;
- this->OpacityTables=0;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Allocate memory on the GPU for the framebuffers according to the size of
-// the window or reallocate if the size has changed. Return true if
-// allocation succeeded.
-// \pre ren_exists: ren!=0
-// \pre opengl_objects_created: this->OpenGLObjectsCreated
-// \post right_size: LastSize[]=window size.
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::AllocateFrameBuffers(vtkRenderer *ren)
-{
- assert("pre: ren_exists" && ren!=0);
- assert("pre: opengl_objects_created" && this->OpenGLObjectsCreated);
-
- int result=1;
- int size[2];
- ren->GetTiledSize(&size[0],&size[1]);
-
- int sizeChanged=this->LastSize[0]!=size[0] || this->LastSize[1]!=size[1];
-
- GLenum errorCode=glGetError();
-
- // Need allocation?
- if(sizeChanged)
- {
- int i=0;
- GLenum errorCode=glGetError();
-
- while(i <this->NumberOfFrameBuffers && errorCode==GL_NO_ERROR)
- {
- glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+i]));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- // Here we are assuming that GL_ARB_texture_non_power_of_two is available
- if(this->Supports_GL_ARB_texture_float)
- {
- glTexImage2D(GL_TEXTURE_2D,0,vtkgl::RGBA16F_ARB,size[0],size[1],
- 0, GL_RGBA, GL_FLOAT, NULL );
- }
- else
- {
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,size[0],size[1],
- 0, GL_RGBA, GL_FLOAT, NULL );
- }
- errorCode=glGetError();
-
- ++i;
- }
- if(errorCode==GL_NO_ERROR)
- {
- // grabbed depth buffer
- glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap]));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri(GL_TEXTURE_2D, vtkgl::DEPTH_TEXTURE_MODE, GL_LUMINANCE);
- glTexImage2D(GL_TEXTURE_2D, 0, vtkgl::DEPTH_COMPONENT32, size[0],size[1],
- 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL );
-
- // Set up the depth render buffer
-
- GLint savedFrameBuffer;
- glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
- static_cast<GLuint>(this->FrameBufferObject));
-
- this->BindFramebuffer();
-
- vtkgl::BindRenderbufferEXT(
- vtkgl::RENDERBUFFER_EXT,
- static_cast<GLuint>(this->DepthRenderBufferObject));
- vtkgl::RenderbufferStorageEXT(vtkgl::RENDERBUFFER_EXT,
- vtkgl::DEPTH_COMPONENT24,size[0],size[1]);
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
- static_cast<GLuint>(savedFrameBuffer));
- errorCode=glGetError();
-
- if(errorCode==GL_NO_ERROR)
- {
- this->LastSize[0]=size[0];
- this->LastSize[1]=size[1];
- }
- }
- result=errorCode==GL_NO_ERROR;
- }
-
- int needNewMaxValueBuffer=this->MaxValueFrameBuffer==0 &&
- (this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND ||
- this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND);
-
- if(needNewMaxValueBuffer)
- {
-
- // blend mode changed and need max value buffer.
-
- // create and bind second color buffer (we use only the red component
- // to store the max scalar). We cant use a one component color buffer
- // because all color buffer have to have the same format.
-
- // max scalar frame buffer
- GLuint maxValueFrameBuffer;
- glGenTextures(1,&maxValueFrameBuffer);
- this->MaxValueFrameBuffer=
- static_cast<unsigned int>(maxValueFrameBuffer);
-
- // Color buffers
-
- this->m_BindMax = true;
-
- // max scalar frame buffer2
- GLuint maxValueFrameBuffer2;
-
- glGenTextures(1,&maxValueFrameBuffer2);
-
- glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer2);
- this->MaxValueFrameBuffer2=
- static_cast<unsigned int>(maxValueFrameBuffer2);
-
- }
- else
- {
- if(this->MaxValueFrameBuffer!=0 &&
- (this->BlendMode!=vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
- &&
- this->BlendMode!=vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND))
- {
- // blend mode changed and does not need max value buffer anymore.
-
- GLint savedFrameBuffer;
- glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
-
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
- static_cast<GLuint>(this->FrameBufferObject));
-
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT+1,
- GL_TEXTURE_2D,0,0); // not scalar buffer
-
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
- static_cast<GLuint>(savedFrameBuffer));
-
- GLuint maxValueFrameBuffer=
- static_cast<GLuint>(this->MaxValueFrameBuffer);
- glDeleteTextures(1,&maxValueFrameBuffer);
- this->MaxValueFrameBuffer=0;
-
- m_BindMax = false;
-
- GLuint maxValueFrameBuffer2=
- static_cast<GLuint>(this->MaxValueFrameBuffer2);
- glDeleteTextures(1,&maxValueFrameBuffer2);
- this->MaxValueFrameBuffer2=0;
- }
- }
-
- if((this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
- || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND) && (sizeChanged || needNewMaxValueBuffer))
- {
-
- // max scalar frame buffer
- GLuint maxValueFrameBuffer=static_cast<GLuint>(this->MaxValueFrameBuffer);
- glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- // Here we are assuming that GL_ARB_texture_non_power_of_two is available
-
- if(this->Supports_GL_ARB_texture_float)
- {
- glTexImage2D(GL_TEXTURE_2D,0,vtkgl::RGBA16F_ARB,size[0],size[1],
- 0, GL_RGBA, GL_FLOAT, NULL );
- }
- else
- {
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,size[0],size[1],
- 0, GL_RGBA, GL_FLOAT, NULL );
- }
-
- // max scalar frame buffer 2
- GLuint maxValueFrameBuffer2=static_cast<GLuint>(this->MaxValueFrameBuffer2);
- glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer2);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- // Here we are assuming that GL_ARB_texture_non_power_of_two is available
- if(this->Supports_GL_ARB_texture_float)
- {
- glTexImage2D(GL_TEXTURE_2D,0,vtkgl::RGBA16F_ARB,size[0],size[1],
- 0, GL_RGBA, GL_FLOAT, NULL );
- }
- else
- {
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,size[0],size[1],
- 0, GL_RGBA, GL_FLOAT, NULL );
- }
-
- }
-
- PrintError("AllocateFrameBuffers");
- return result;
-}
-
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::GetTextureFormat(
- vtkImageData *input,
- unsigned int *internalFormat,
- unsigned int *format,
- unsigned int *type,
- int *componentSize)
-{
- *internalFormat=0;
- *format=0;
- *type=0;
- *componentSize=0;
-
- vtkDataArray *scalars=this->GetScalars(input,this->ScalarMode,
- this->ArrayAccessMode,
- this->ArrayId,
- this->ArrayName,
- this->CellFlag);
-
- int scalarType=scalars->GetDataType();
- int components=scalars->GetNumberOfComponents();
- *componentSize=vtkAbstractArray::GetDataTypeSize(scalarType)*components;
-
- if(components==4)
- {
- // this is RGBA, unsigned char only
- *internalFormat=GL_RGBA16;
- *format=GL_RGBA;
- *type=GL_UNSIGNED_BYTE;
- }
- else
- {
- // components==1
- switch(scalarType)
- {
- case VTK_FLOAT:
- if(this->Supports_GL_ARB_texture_float)
- {
- *internalFormat=vtkgl::INTENSITY16F_ARB;
- }
- else
- {
- *internalFormat=GL_INTENSITY16;
- }
- *format=GL_RED;
- *type=GL_FLOAT;
- break;
- case VTK_UNSIGNED_CHAR:
- *internalFormat=GL_INTENSITY8;
- *format=GL_RED;
- *type=GL_UNSIGNED_BYTE;
- break;
- case VTK_SIGNED_CHAR:
- *internalFormat=GL_INTENSITY8;
- *format=GL_RED;
- *type=GL_BYTE;
- break;
- case VTK_CHAR:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_BIT:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_ID_TYPE:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_INT:
- *internalFormat=GL_INTENSITY16;
- *format=GL_RED;
- *type=GL_INT;
- break;
- case VTK_DOUBLE:
- case VTK___INT64:
- case VTK_LONG:
- case VTK_LONG_LONG:
- case VTK_UNSIGNED___INT64:
- case VTK_UNSIGNED_LONG:
- case VTK_UNSIGNED_LONG_LONG:
- if(this->Supports_GL_ARB_texture_float)
- {
- *internalFormat=vtkgl::INTENSITY16F_ARB;
- }
- else
- {
- *internalFormat=GL_INTENSITY16;
- }
- *format=GL_RED;
- *type=GL_FLOAT;
- break;
- case VTK_SHORT:
- *internalFormat=GL_INTENSITY16;
- *format=GL_RED;
- *type=GL_SHORT;
- break;
- case VTK_STRING:
- // not supported
- assert("check: impossible case" && 0);
- break;
- case VTK_UNSIGNED_SHORT:
- *internalFormat=GL_INTENSITY16;
- *format=GL_RED;
- *type=GL_UNSIGNED_SHORT;
- break;
- case VTK_UNSIGNED_INT:
- *internalFormat=GL_INTENSITY16;
- *format=GL_RED;
- *type=GL_UNSIGNED_INT;
- break;
- default:
- assert("check: impossible case" && 0);
- break;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Assuming the textureSize[3] is less of equal to the maximum size of an
-// OpenGL 3D texture, try to see if the texture can fit on the card.
-//-----------------------------------------------------------------------------
-bool vtkMitkOpenGLGPUVolumeRayCastMapper::TestLoadingScalar(
- unsigned int internalFormat,
- unsigned int format,
- unsigned int type,
- int textureSize[3],
- int componentSize)
-{
- // componentSize=vtkAbstractArray::GetDataTypeSize(scalarType)*input->GetNumberOfScalarComponents()
-
- bool result;
-
- vtkgl::TexImage3D(vtkgl::PROXY_TEXTURE_3D,0,
- static_cast<GLint>(internalFormat),
- textureSize[0],textureSize[1],textureSize[2],0,
- format,
- type,0);
- GLint width;
- glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_3D,0,GL_TEXTURE_WIDTH,
- &width);
-
- result=width!=0;
- if(result)
- {
- // so far, so good but some cards always succeed with a proxy texture
- // let's try to actually allocate..
- vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,static_cast<GLint>(internalFormat),
- textureSize[0],
- textureSize[1],textureSize[2],0,
- format,
- type,0);
- GLenum errorCode=glGetError();
-
- result=errorCode!=GL_OUT_OF_MEMORY;
- if(result)
- {
- if(errorCode!=GL_NO_ERROR)
- {
- cout<<"after try to load the texture";
- cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
- cout<<OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
- cout<<endl;
- }
- // so far, so good but some cards don't report allocation error
- result=textureSize[0]*textureSize[1]*textureSize[2]*componentSize
- <=static_cast<float>(this->MaxMemoryInBytes)*this->MaxMemoryFraction;
- }
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Load the scalar field (one or four component scalar field), cell or point
-// based for a given subextent of the whole extent (can be the whole extent)
-// as a 3D texture on the GPU.
-// Extents are expressed in point if the cell flag is false or in cells of
-// the cell flag is true.
-// It returns true if it succeeded, false if there is not enough memory on
-// the GPU.
-// If succeeded, it updates the LoadedExtent, LoadedBounds, LoadedCellFlag
-// and LoadedTime. It also succeed if the scalar field is already loaded
-// (ie since last load, input has not changed and cell flag has not changed
-// and requested texture extents are enclosed in the loaded extent).
-// \pre input_exists: input!=0
-// \pre valid_point_extent: (this->CellFlag ||
-// (textureExtent[0]<textureExtent[1] &&
-// textureExtent[2]<textureExtent[3] &&
-// textureExtent[4]<textureExtent[5])))
-// \pre valid_cell_extent: (!this->CellFlag ||
-// (textureExtent[0]<=textureExtent[1] &&
-// textureExtent[2]<=textureExtent[3] &&
-// textureExtent[4]<=textureExtent[5])))
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::LoadScalarField(vtkImageData *input,
- vtkImageData *maskInput,
- int textureExtent[6],
- vtkVolume *volume)
-{
- assert("pre: input_exists" && input!=0);
- assert("pre: valid_point_extent" && (this->CellFlag ||
- (textureExtent[0]<textureExtent[1] &&
- textureExtent[2]<textureExtent[3] &&
- textureExtent[4]<textureExtent[5])));
- assert("pre: valid_cell_extent" && (!this->CellFlag ||
- (textureExtent[0]<=textureExtent[1] &&
- textureExtent[2]<=textureExtent[3] &&
- textureExtent[4]<=textureExtent[5])));
-
- int result=1; // succeeded
-
- // make sure we rebind our texture object to texture0 even if we don't have
- // to load the data themselves because the binding might be changed by
- // another mapper between two rendering calls.
-
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
-
- // Find the texture.
- vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=
- this->ScalarsTextures->Map.find(input);
-
-
- vtkKWScalarField *texture;
- if(it==this->ScalarsTextures->Map.end())
- {
- texture=new vtkKWScalarField;
- this->ScalarsTextures->Map[input]=texture;
- texture->SetSupports_GL_ARB_texture_float(this->Supports_GL_ARB_texture_float==1);
- }
- else
- {
- texture=(*it).second;
- }
-
- texture->Update(input,this->CellFlag,textureExtent,this->ScalarMode,
- this->ArrayAccessMode,
- this->ArrayId,
- this->ArrayName,
- volume->GetProperty()->GetInterpolationType()
- ==VTK_LINEAR_INTERPOLATION,
- this->TableRange,
- static_cast<int>(static_cast<float>(this->MaxMemoryInBytes)*this->MaxMemoryFraction));
-
- result=texture->IsLoaded();
- this->CurrentScalar=texture;
-
-
- // Mask
- if(maskInput!=0)
- {
- vtkgl::ActiveTexture(vtkgl::TEXTURE7);
-
- // Find the texture.
- vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it2=
- this->MaskTextures->Map.find(maskInput);
-
-
- vtkKWMask *mask;
- if(it2==this->MaskTextures->Map.end())
- {
- mask=new vtkKWMask;
- this->MaskTextures->Map[maskInput]=mask;
- }
- else
- {
- mask=(*it2).second;
- }
-
- mask->Update(maskInput,this->CellFlag,textureExtent,this->ScalarMode,
- this->ArrayAccessMode,
- this->ArrayId,
- this->ArrayName,
- static_cast<int>(static_cast<float>(this->MaxMemoryInBytes)*this->MaxMemoryFraction));
-
- result=result && mask->IsLoaded();
- this->CurrentMask=mask;
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
- }
-
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Allocate memory and load color table on the GPU or
-// reload it if the transfer function changed.
-// \pre vol_exists: vol!=0
-// \pre valid_numberOfScalarComponents: numberOfScalarComponents==1 || numberOfScalarComponents==4
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::UpdateColorTransferFunction(
- vtkVolume *vol,
- int numberOfScalarComponents)
-{
- assert("pre: vol_exists" && vol!=0);
- assert("pre: valid_numberOfScalarComponents" &&
- (numberOfScalarComponents==1 || numberOfScalarComponents==4));
-
- // Build the colormap in a 1D texture.
-
- // 1D RGB-texture=mapping from scalar values to color values
- // build the table
-
- if(numberOfScalarComponents==1)
- {
- vtkVolumeProperty *volumeProperty=vol->GetProperty();
- vtkColorTransferFunction *colorTransferFunction=volumeProperty->GetRGBTransferFunction(0);
-
- vtkgl::ActiveTexture(vtkgl::TEXTURE1);
-
- this->RGBTable->Update(
- colorTransferFunction,this->TableRange,
- volumeProperty->GetInterpolationType()==VTK_LINEAR_INTERPOLATION);
- // Restore default
- vtkgl::ActiveTexture( vtkgl::TEXTURE0);
- }
-
- if(this->MaskInput!=0)
- {
- vtkVolumeProperty *volumeProperty=vol->GetProperty();
- vtkColorTransferFunction *c=volumeProperty->GetRGBTransferFunction(1);
-
- vtkgl::ActiveTexture(vtkgl::TEXTURE8);
- this->Mask1RGBTable->Update(c,this->TableRange,false);
-
- c=volumeProperty->GetRGBTransferFunction(2);
- vtkgl::ActiveTexture(vtkgl::TEXTURE9);
- this->Mask2RGBTable->Update(c,this->TableRange,false);
-
- // Restore default
- vtkgl::ActiveTexture( vtkgl::TEXTURE0);
- }
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Allocate memory and load opacity table on the GPU or
-// reload it if the transfert function changed.
-// \pre vol_exists: vol!=0
-// \pre valid_numberOfScalarComponents: numberOfScalarComponents==1 || numberOfScalarComponents==4
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::UpdateOpacityTransferFunction(
- vtkVolume *vol,
- int numberOfScalarComponents,
- unsigned int level)
-{
- assert("pre: vol_exists" && vol!=0);
- assert("pre: valid_numberOfScalarComponents" &&
- (numberOfScalarComponents==1 || numberOfScalarComponents==4));
-
- (void)numberOfScalarComponents; // remove warning in release mode.
-
- vtkVolumeProperty *volumeProperty=vol->GetProperty();
- vtkPiecewiseFunction *scalarOpacity=volumeProperty->GetScalarOpacity();
-
- vtkgl::ActiveTexture( vtkgl::TEXTURE2); //stay here
- this->OpacityTables->Vector[level].Update(
- scalarOpacity,this->BlendMode,
- this->ActualSampleDistance,
- this->TableRange,
- volumeProperty->GetScalarOpacityUnitDistance(0),
- volumeProperty->GetInterpolationType()==VTK_LINEAR_INTERPOLATION);
- // Restore default active texture
- vtkgl::ActiveTexture( vtkgl::TEXTURE0);
-
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Prepare rendering in the offscreen framebuffer.
-// \pre ren_exists: ren!=0
-// \pre vol_exists: vol!=0
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::SetupRender(vtkRenderer *ren,
- vtkVolume *vol)
-{
- assert("pre: ren_exists" && ren!=0);
- assert("pre: vol_exists" && vol!=0);
-
- double aspect[2];
- int lowerLeft[2];
- int usize, vsize;
-
- ren->GetTiledSizeAndOrigin(&usize,&vsize,lowerLeft,lowerLeft+1);
-
- usize = static_cast<int>(usize*this->ReductionFactor);
- vsize = static_cast<int>(vsize*this->ReductionFactor);
-
- this->ReducedSize[0]=usize;
- this->ReducedSize[1]=vsize;
-
- // the FBO has the size of the renderer (not the renderwindow),
- // we always starts at 0,0.
- glViewport(0,0, usize, vsize);
- glEnable( GL_SCISSOR_TEST ); // scissor on the FBO, on the reduced part.
- glScissor(0,0, usize, vsize);
- glClearColor(0.0, 0.0, 0.0, 0.0); // maxvalue is 1
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- ren->ComputeAspect();
- ren->GetAspect(aspect);
- double aspect2[2];
- ren->vtkViewport::ComputeAspect();
- ren->vtkViewport::GetAspect(aspect2);
- double aspectModification = aspect[0]*aspect2[1]/(aspect[1]*aspect2[0]);
-
- vtkCamera *cam = ren->GetActiveCamera();
-
- glMatrixMode( GL_PROJECTION);
- if(usize && vsize)
- {
- this->TempMatrix[0]->DeepCopy(cam->GetProjectionTransformMatrix(
- aspectModification*usize/vsize, -1,1));
- this->TempMatrix[0]->Transpose();
- glLoadMatrixd(this->TempMatrix[0]->Element[0]);
- }
- else
- {
- glLoadIdentity();
-
- }
-
- // push the model view matrix onto the stack, make sure we
- // adjust the mode first
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- this->TempMatrix[0]->DeepCopy(vol->GetMatrix());
- this->TempMatrix[0]->Transpose();
-
- // insert camera view transformation
- glMultMatrixd(this->TempMatrix[0]->Element[0]);
- glShadeModel(GL_SMOOTH);
- glDisable( GL_LIGHTING);
- glEnable (GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND); // very important, otherwise the first image looks dark.
- this->PrintError("SetupRender");
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::DebugDisplayBox(vtkPolyData *box)
-{
- vtkPoints *points=box->GetPoints();
- vtkCellArray *polys=box->GetPolys();
- cout<<"npts="<<points->GetNumberOfPoints()<<endl;
- int pointId=0;
- while(pointId<points->GetNumberOfPoints())
- {
- double coords[3];
- points->GetPoint(pointId,coords);
- cout<<"pointId="<<pointId<<endl;
- int i=0;
- while(i<3)
- {
- cout<<" "<<coords[i];
- ++i;
- }
- cout<<endl;
- ++pointId;
- }
- vtkIdType npts=0;
- vtkIdType *pts=0;
- cout<<"ncells="<<polys->GetNumberOfCells()<<endl;
- int cellId=0;
- polys->InitTraversal();
- while(cellId<polys->GetNumberOfCells())
- {
- polys->GetNextCell(npts,pts);
- cout<<"cellId="<<cellId<<" npts="<<npts<<endl;
- vtkIdType i=0;
- while(i<npts)
- {
- cout<<pts[i]<<" ";
- ++i;
- }
- cout<<endl;
- ++cellId;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Clip the bounding box with the clipping planes and near and
-// far planes. Grab the output polydata for later rendering.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::ClipBoundingBox(vtkRenderer *ren,
- double worldBounds[6],
- vtkVolume *vol)
-{
- // Pass camera through inverse volume matrix
- // so that we are in the same coordinate system
- vol->GetMatrix( this->InvVolumeMatrix );
- this->InvVolumeMatrix->Invert();
-
- if(this->BoxSource==0)
- {
- this->BoxSource=vtkTessellatedBoxSource::New();
- }
- this->BoxSource->SetBounds(worldBounds);
- this->BoxSource->SetLevel(0);
- this->BoxSource->QuadsOn();
-
- if(this->Planes==0)
- {
- this->Planes=vtkPlaneCollection::New();
- }
- this->Planes->RemoveAllItems();
-
- vtkCamera *cam = ren->GetActiveCamera();
- double camWorldRange[2];
- double camWorldPos[4];
- double camFocalWorldPoint[4];
- double camWorldDirection[3];
- double range[2];
- double camPos[4];
- double focalPoint[4];
- double direction[3];
-
- cam->GetPosition(camWorldPos);
- camWorldPos[3] = 1.0;
- this->InvVolumeMatrix->MultiplyPoint( camWorldPos, camPos );
- if ( camPos[3] )
- {
- camPos[0] /= camPos[3];
- camPos[1] /= camPos[3];
- camPos[2] /= camPos[3];
- }
-
- cam->GetFocalPoint(camFocalWorldPoint);
- camFocalWorldPoint[3]=1.0;
- this->InvVolumeMatrix->MultiplyPoint( camFocalWorldPoint,focalPoint );
- if ( focalPoint[3] )
- {
- focalPoint[0] /= focalPoint[3];
- focalPoint[1] /= focalPoint[3];
- focalPoint[2] /= focalPoint[3];
- }
-
- // Compute the normalized view direction
- direction[0] = focalPoint[0] - camPos[0];
- direction[1] = focalPoint[1] - camPos[1];
- direction[2] = focalPoint[2] - camPos[2];
-
- vtkMath::Normalize(direction);
-
- // The range (near/far) must also be transformed
- // into the local coordinate system.
- camWorldDirection[0] = camFocalWorldPoint[0] - camWorldPos[0];
- camWorldDirection[1] = camFocalWorldPoint[1] - camWorldPos[1];
- camWorldDirection[2] = camFocalWorldPoint[2] - camWorldPos[2];
- vtkMath::Normalize(camWorldDirection);
-
- double camNearWorldPoint[4];
- double camFarWorldPoint[4];
- double camNearPoint[4];
- double camFarPoint[4];
- cam->GetClippingRange(camWorldRange);
- camNearWorldPoint[0] = camWorldPos[0] + camWorldRange[0]*camWorldDirection[0];
- camNearWorldPoint[1] = camWorldPos[1] + camWorldRange[0]*camWorldDirection[1];
- camNearWorldPoint[2] = camWorldPos[2] + camWorldRange[0]*camWorldDirection[2];
- camNearWorldPoint[3] = 1.;
-
- camFarWorldPoint[0] = camWorldPos[0] + camWorldRange[1]*camWorldDirection[0];
- camFarWorldPoint[1] = camWorldPos[1] + camWorldRange[1]*camWorldDirection[1];
- camFarWorldPoint[2] = camWorldPos[2] + camWorldRange[1]*camWorldDirection[2];
- camFarWorldPoint[3] = 1.;
-
- this->InvVolumeMatrix->MultiplyPoint( camNearWorldPoint, camNearPoint );
- if (camNearPoint[3])
- {
- camNearPoint[0] /= camNearPoint[3];
- camNearPoint[1] /= camNearPoint[3];
- camNearPoint[2] /= camNearPoint[3];
- }
- this->InvVolumeMatrix->MultiplyPoint( camFarWorldPoint, camFarPoint );
- if (camFarPoint[3])
- {
- camFarPoint[0] /= camFarPoint[3];
- camFarPoint[1] /= camFarPoint[3];
- camFarPoint[2] /= camFarPoint[3];
- }
- range[0] = sqrt(vtkMath::Distance2BetweenPoints(camNearPoint, camPos));
- range[1] = sqrt(vtkMath::Distance2BetweenPoints(camFarPoint, camPos));
-
- //double nearPoint[3], farPoint[3];
-
- double dist = range[1] - range[0];
- range[0] += dist / (2<<16);
- range[1] -= dist / (2<<16);
-
- if(this->NearPlane==0)
- {
- this->NearPlane= vtkPlane::New();
- }
- //this->NearPlane->SetOrigin( nearPoint );
- this->NearPlane->SetOrigin( camNearPoint );
- this->NearPlane->SetNormal( direction );
- this->Planes->AddItem(this->NearPlane);
-
- if ( this->ClippingPlanes )
- {
- this->ClippingPlanes->InitTraversal();
- vtkPlane *plane;
- while ( (plane = this->ClippingPlanes->GetNextItem()) )
- {
- // Planes are in world coordinates, we need to
- // convert them in local coordinates
- double planeOrigin[4], planeNormal[4], planeP1[4];
- plane->GetOrigin(planeOrigin);
- planeOrigin[3] = 1.;
- plane->GetNormal(planeNormal);
- planeP1[0] = planeOrigin[0] + planeNormal[0];
- planeP1[1] = planeOrigin[1] + planeNormal[1];
- planeP1[2] = planeOrigin[2] + planeNormal[2];
- planeP1[3] = 1.;
- this->InvVolumeMatrix->MultiplyPoint(planeOrigin, planeOrigin);
- this->InvVolumeMatrix->MultiplyPoint(planeP1, planeP1);
- if( planeOrigin[3])
- {
- planeOrigin[0] /= planeOrigin[3];
- planeOrigin[1] /= planeOrigin[3];
- planeOrigin[2] /= planeOrigin[3];
- }
- if( planeP1[3])
- {
- planeP1[0] /= planeP1[3];
- planeP1[1] /= planeP1[3];
- planeP1[2] /= planeP1[3];
- }
- planeNormal[0] = planeP1[0] - planeOrigin[0];
- planeNormal[1] = planeP1[1] - planeOrigin[1];
- planeNormal[2] = planeP1[2] - planeOrigin[2];
- vtkMath::Normalize(planeNormal);
- vtkPlane* localPlane = vtkPlane::New();
- localPlane->SetOrigin(planeOrigin);
- localPlane->SetNormal(planeNormal);
- this->Planes->AddItem(localPlane);
- localPlane->Delete();
- }
- }
-
- if(this->Clip==0)
- {
- this->Clip=vtkClipConvexPolyData::New();
- this->Clip->SetInputConnection(this->BoxSource->GetOutputPort());
- this->Clip->SetPlanes( this->Planes );
- }
-
- this->Clip->Update();
-
- if(this->Densify==0)
- {
- this->Densify=vtkDensifyPolyData::New();
- this->Densify->SetInputConnection(this->Clip->GetOutputPort());
- this->Densify->SetNumberOfSubdivisions(2);
- }
- this->Densify->Update();
- this->ClippedBoundingBox = this->Densify->GetOutput();
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::RenderClippedBoundingBox(
- int tcoordFlag,
- size_t currentBlock,
- size_t numberOfBlocks,
- vtkRenderWindow *renWin )
-{
- assert("pre: valid_currentBlock" && currentBlock<numberOfBlocks);
-
- vtkPoints *points = this->ClippedBoundingBox->GetPoints();
- vtkCellArray *polys = this->ClippedBoundingBox->GetPolys();
-
- vtkIdType npts;
- vtkIdType *pts;
-
- vtkIdType i, j;
-
- double center[3] = {0,0,0};
- double min[3] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX};
- double max[3] = {VTK_DOUBLE_MIN, VTK_DOUBLE_MIN, VTK_DOUBLE_MIN};
-
- // First compute center point
- npts = points->GetNumberOfPoints();
- for ( i = 0; i < npts; i++ )
- {
- double pt[3];
- points->GetPoint( i, pt );
- for ( j = 0; j < 3; j++ )
- {
- min[j] = (pt[j]<min[j])?(pt[j]):(min[j]);
- max[j] = (pt[j]>max[j])?(pt[j]):(max[j]);
- }
- }
-
- center[0] = 0.5*(min[0]+max[0]);
- center[1] = 0.5*(min[1]+max[1]);
- center[2] = 0.5*(min[2]+max[2]);
-
- double *loadedBounds=0;
- vtkIdType *loadedExtent=0;
-
- if ( tcoordFlag )
- {
- loadedBounds=this->CurrentScalar->GetLoadedBounds();
- loadedExtent=this->CurrentScalar->GetLoadedExtent();
- }
-
- double *spacing=this->GetInput()->GetSpacing();
- double spacingSign[3];
- i=0;
- while(i<3)
- {
- if(spacing[i]<0)
- {
- spacingSign[i]=-1.0;
- }
- else
- {
- spacingSign[i]=1.0;
- }
- ++i;
- }
-
- // make it double for the ratio of the progress.
- int polyId=0;
- double polyCount=static_cast<double>(polys->GetNumberOfCells());
- polys->InitTraversal();
- int abort=0;
- while ( !abort && polys->GetNextCell(npts, pts) )
- {
- vtkIdType start, end, inc;
-
- // Need to have at least a triangle
- if ( npts > 2 )
- {
- // Check the cross product of the first two
- // vectors dotted with the vector from the
- // center to the second point. Is it positive or
- // negative?
-
- double p1[3], p2[3], p3[3];
- double v1[3], v2[3], v3[3], v4[3];
-
- points->GetPoint(pts[0], p1 );
- points->GetPoint(pts[1], p2 );
- points->GetPoint(pts[2], p3 );
-
- v1[0] = p2[0] - p1[0];
- v1[1] = p2[1] - p1[1];
- v1[2] = p2[2] - p1[2];
-
- v2[0] = p2[0] - p3[0];
- v2[1] = p2[1] - p3[1];
- v2[2] = p2[2] - p3[2];
-
- vtkMath::Cross( v1, v2, v3 );
- vtkMath::Normalize(v3);
-
- v4[0] = p2[0] - center[0];
- v4[1] = p2[1] - center[1];
- v4[2] = p2[2] - center[2];
- vtkMath::Normalize(v4);
-
- double dot = vtkMath::Dot( v3, v4 );
-
- if (( dot < 0) && this->PreserveOrientation)
- {
- start = 0;
- end = npts;
- inc = 1;
- }
- else
- {
- start = npts-1;
- end = -1;
- inc = -1;
- }
-
- glBegin( GL_TRIANGLE_FAN ); // GL_POLYGON -> GL_TRIANGLE_FAN
-
- double vert[3];
- double tcoord[3];
- for ( i = start; i != end; i += inc )
- {
- points->GetPoint(pts[i], vert);
- if ( tcoordFlag )
- {
- for ( j = 0; j < 3; j++ )
- {
- // loaded bounds take both cell data and point date cases into
- // account
- if(this->CellFlag) // texcoords between 0 and 1. More complex
- // depends on the loaded texture
- {
- tcoord[j] = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /
- (loadedBounds[j*2+1] - loadedBounds[j*2]);
- }
- else // texcoords between 1/2N and 1-1/2N.
- {
- double tmp; // between 0 and 1
- tmp = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /
- (loadedBounds[j*2+1] - loadedBounds[j*2]);
- double delta=static_cast<double>(
- loadedExtent[j*2+1]-loadedExtent[j*2]+1);
- tcoord[j]=(tmp*(delta-1)+0.5)/delta;
- }
- }
- vtkgl::MultiTexCoord3dv(vtkgl::TEXTURE0, tcoord);
- }
- glVertex3dv(vert);
- }
- glEnd();
-
- }
- if(tcoordFlag)
- {
- // otherwise, we are rendering back face to initialize the zbuffer.
- if (!this->GeneratingCanonicalView && this->ReportProgress)
- {
- glFinish();
- // Only invoke an event at most one every second.
- double currentTime=vtkTimerLog::GetUniversalTime();
- if(currentTime - this->LastProgressEventTime > 1.0)
- {
- double progress=(static_cast<double>(currentBlock)+polyId/polyCount)/
- static_cast<double>(numberOfBlocks);
- this->InvokeEvent(vtkCommand::VolumeMapperRenderProgressEvent,
- &progress);
- renWin->MakeCurrent();
- this->LastProgressEventTime = currentTime;
- }
- }
- abort=renWin->CheckAbortStatus();
- }
- ++polyId;
- }
- return abort;
-}
-
-void vtkMitkOpenGLGPUVolumeRayCastMapper::CopyFBOToTexture()
-{
- // in OpenGL copy texture to texture does not exist but
- // framebuffer to texture exists (and our FB is an FBO).
- // we have to copy and not just to switch color textures because the
- // colorbuffer has to accumulate color or values step after step.
- // Switching would not work because two different steps can draw different
- // polygons that don't overlap
- vtkgl::ActiveTexture(vtkgl::TEXTURE4);
- glBindTexture(
- GL_TEXTURE_2D,
- this->TextureObjects[
- vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+1]);
-
- glReadBuffer(vtkgl::COLOR_ATTACHMENT0_EXT);
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,this->ReducedSize[0],
- this->ReducedSize[1]);
- if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
- || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
- {
- vtkgl::ActiveTexture(vtkgl::TEXTURE5);
- glBindTexture(GL_TEXTURE_2D,this->MaxValueFrameBuffer2);
- glReadBuffer(vtkgl::COLOR_ATTACHMENT0_EXT+1);
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,this->ReducedSize[0],
- this->ReducedSize[1]);
- }
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
-}
-
-//-----------------------------------------------------------------------------
-// Restore OpenGL state after rendering of the dataset.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::CleanupRender()
-{
- glPopMatrix();
- glDisable(GL_CULL_FACE);
-}
-
-//-----------------------------------------------------------------------------
-// Build the fragment shader program that scale and bias a texture
-// for window/level purpose.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::BuildScaleBiasProgram()
-{
- if(this->ScaleBiasProgramShader==0)
- {
- GLuint programShader;
- GLuint fragmentShader;
-
- programShader=vtkgl::CreateProgram();
- fragmentShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
- vtkgl::AttachShader(programShader,fragmentShader);
- vtkgl::DeleteShader(fragmentShader); // reference counting
-
- vtkgl::ShaderSource(
- fragmentShader,1,
- const_cast<const char **>(&vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS),0);
- vtkgl::CompileShader(fragmentShader);
-
- this->CheckCompilation(static_cast<unsigned int>(fragmentShader));
- vtkgl::LinkProgram(programShader);
- this->CheckLinkage(static_cast<unsigned int>(programShader));
-
- this->ScaleBiasProgramShader=static_cast<unsigned int>(programShader);
- this->UFrameBufferTexture=
- static_cast<int>(vtkgl::GetUniformLocation(programShader,
- "frameBufferTexture"));
- this->UScale=static_cast<int>(vtkgl::GetUniformLocation(programShader,
- "scale"));
- this->UBias=static_cast<int>(vtkgl::GetUniformLocation(programShader,
- "bias"));
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// Render the offscreen buffer to the screen.
-// \pre ren_exists: ren!=0
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderTextureToScreen(vtkRenderer *ren)
-{
- assert("pre: ren_exists" && ren!=0);
-
- if ( this->GeneratingCanonicalView )
- {
- // We just need to copy of the data, not render it
- glBindTexture(GL_TEXTURE_2D,
- this->TextureObjects[
- vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront]);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
- glPixelStorei( GL_PACK_ALIGNMENT, 1 );
-
- unsigned char *outPtr = static_cast<unsigned char *>(this->CanonicalViewImageData->GetScalarPointer());
- glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, outPtr );
- return;
- }
-
- int lowerLeft[2];
- int usize, vsize;
- ren->GetTiledSizeAndOrigin(&usize,&vsize,lowerLeft,lowerLeft+1);
- glViewport(lowerLeft[0],lowerLeft[1], usize, vsize);
- glEnable( GL_SCISSOR_TEST );
- glScissor(lowerLeft[0],lowerLeft[1], usize, vsize);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(0.0, usize, 0.0, vsize, -1.0, 1.0 );
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glBindTexture(GL_TEXTURE_2D,
- this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront]);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glEnable(GL_BLEND);
- glBlendFunc( GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
-
- // As we use replace mode, we don't need to set the color value.
-
- glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
-
- glDisable(GL_DEPTH_TEST);
-
- double xOffset = 1.0 / usize;
- double yOffset = 1.0 / vsize;
-
- glDepthMask(GL_FALSE);
-
- double scale=1.0/this->FinalColorWindow;
- double bias=0.5-this->FinalColorLevel/this->FinalColorWindow;
-
- if(scale!=1.0 || bias!=0.0)
- {
- this->BuildScaleBiasProgram();
- vtkgl::UseProgram(this->ScaleBiasProgramShader);
- if(this->UFrameBufferTexture!=-1)
- {
- vtkgl::Uniform1i(this->UFrameBufferTexture,0);
- }
- else
- {
- vtkErrorMacro(<<"uFrameBufferTexture is not a uniform variable.");
- }
- if(this->UScale!=-1)
- {
- vtkgl::Uniform1f(this->UScale,static_cast<GLfloat>(scale));
- }
- else
- {
- vtkErrorMacro(<<"uScale is not a uniform variable.");
- }
- if(this->UBias!=-1)
- {
- vtkgl::Uniform1f(this->UBias,static_cast<GLfloat>(bias));
- }
- else
- {
- vtkErrorMacro(<<"uBias is not a uniform variable.");
- }
- }
- else
- {
- glEnable(GL_TEXTURE_2D); // fixed pipeline
- }
-
- glBegin(GL_QUADS);
- glTexCoord2f(static_cast<GLfloat>(xOffset),static_cast<GLfloat>(yOffset));
- glVertex2f(0.0,0.0);
- glTexCoord2f(static_cast<GLfloat>(this->ReductionFactor-xOffset),
- static_cast<GLfloat>(yOffset));
- glVertex2f(static_cast<GLfloat>(usize),0.0);
- glTexCoord2f(static_cast<GLfloat>(this->ReductionFactor-xOffset),
- static_cast<GLfloat>(this->ReductionFactor-yOffset));
- glVertex2f(static_cast<GLfloat>(usize),static_cast<GLfloat>(vsize));
- glTexCoord2f(static_cast<GLfloat>(xOffset),
- static_cast<GLfloat>(this->ReductionFactor-yOffset));
- glVertex2f(0.0,static_cast<GLfloat>(vsize));
- glEnd();
-
- // Restore the default mode. Used in overlay.
- glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
-
- if(scale!=1.0 || bias!=0.0)
- {
- vtkgl::UseProgram(0);
- }
- else
- {
- glDisable(GL_TEXTURE_2D);
- }
-
- glDepthMask(GL_TRUE);
-
- glDisable(GL_BLEND);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-}
-
-//-----------------------------------------------------------------------------
-// Update the reduction factor of the render viewport (this->ReductionFactor)
-// according to the time spent in seconds to render the previous frame
-// (this->TimeToDraw) and a time in seconds allocated to render the next
-// frame (allocatedTime).
-// \pre valid_current_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
-// \pre positive_TimeToDraw: this->TimeToDraw>=0.0
-// \pre positive_time: allocatedTime>0.0
-// \post valid_new_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::ComputeReductionFactor(
- double allocatedTime)
-{
- assert("pre: valid_current_reduction_range" && this->ReductionFactor>0.0
- && this->ReductionFactor<=1.0);
- assert("pre: positive_TimeToDraw" && this->TimeToDraw>=0.0);
- assert("pre: positive_time" && allocatedTime>0.0);
-
- if ( this->GeneratingCanonicalView )
- {
- this->ReductionFactor = 1.0;
- return;
- }
-
- if ( !this->AutoAdjustSampleDistances )
- {
- this->ReductionFactor = 1.0 / this->ImageSampleDistance;
- return;
- }
-
- if ( this->TimeToDraw )
- {
- double oldFactor = this->ReductionFactor;
-
- double timeToDraw;
- if (allocatedTime < 1.0)
- {
- timeToDraw = this->SmallTimeToDraw;
- if ( timeToDraw == 0.0 )
- {
- timeToDraw = this->BigTimeToDraw/3.0;
- }
- }
- else
- {
- timeToDraw = this->BigTimeToDraw;
- }
-
- if ( timeToDraw == 0.0 )
- {
- timeToDraw = 10.0;
- }
-
- double fullTime = timeToDraw / this->ReductionFactor;
- double newFactor = allocatedTime / fullTime;
-
- if ( oldFactor == 1.0 ||
- newFactor / oldFactor > 1.3 ||
- newFactor / oldFactor < .95 )
- {
-
- this->ReductionFactor = (newFactor+oldFactor)/2.0;
-
- this->ReductionFactor = (this->ReductionFactor > 5.0)?(1.00):(this->ReductionFactor);
- this->ReductionFactor = (this->ReductionFactor > 1.0)?(0.99):(this->ReductionFactor);
- this->ReductionFactor = (this->ReductionFactor < 0.1)?(0.10):(this->ReductionFactor);
-
- if ( 1.0/this->ReductionFactor > this->MaximumImageSampleDistance )
- {
- this->ReductionFactor = 1.0 / this->MaximumImageSampleDistance;
- }
- if ( 1.0/this->ReductionFactor < this->MinimumImageSampleDistance )
- {
- this->ReductionFactor = 1.0 / this->MinimumImageSampleDistance;
- }
- }
- }
- else
- {
- this->ReductionFactor = 1.0;
- }
-
- assert("post: valid_new_reduction_range" && this->ReductionFactor>0.0
- && this->ReductionFactor<=1.0);
-}
-
-//-----------------------------------------------------------------------------
-// Rendering initialization including making the context current, loading
-// necessary extensions, allocating frame buffers, updating transfer function,
-// computing clipping regions, and building the fragment shader.
-//
-// Pre-conditions:
-// - ren != NULL
-// - vol != NULL
-// - ren->GetRenderWindow() != NULL
-// - 1 <= numberOfScalarComponents <= 4
-// - numberOfLevels >= 1
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::PreRender(vtkRenderer *ren,
- vtkVolume *vol,
- double datasetBounds[6],
- double scalarRange[2],
- int numberOfScalarComponents,
- unsigned int numberOfLevels)
-{
- // make sure our window is the current OpenGL context.
- ren->GetRenderWindow()->MakeCurrent();
-
- // If we haven't already succeeded in loading the extensions,
- // try to load them
- if(!this->LoadExtensionsSucceeded)
- {
- this->LoadExtensions(ren->GetRenderWindow());
- }
-
- // If we can't load the necessary extensions, provide
- // feedback on why it failed.
- if(!this->LoadExtensionsSucceeded)
- {
- vtkErrorMacro(
- "Rendering failed because the following OpenGL extensions "
- "are required but not supported: " <<
- (this->UnsupportedRequiredExtensions->Stream.str()).c_str());
- return;
- }
-
- // Create the OpenGL object that we need
- this->CreateOpenGLObjects();
-
- // Compute the reduction factor that may be necessary to get
- // the interactive rendering rate that we want
- this->ComputeReductionFactor(vol->GetAllocatedRenderTime());
-
- // Allocate the frame buffers
- if(!this->AllocateFrameBuffers(ren))
- {
- vtkErrorMacro("Not enough GPU memory to create a framebuffer.");
- return;
- }
-
- // Save the scalar range - this is what we will use for the range
- // of the transfer functions
- this->TableRange[0]=scalarRange[0];
- this->TableRange[1]=scalarRange[1];
-
-
- if(this->RGBTable==0)
- {
- this->RGBTable=new vtkRGBTable;
- }
-
- if(this->MaskInput!=0)
- {
- if(this->Mask1RGBTable==0)
- {
- this->Mask1RGBTable=new vtkRGBTable;
- }
- if(this->Mask2RGBTable==0)
- {
- this->Mask2RGBTable=new vtkRGBTable;
- }
- }
-
- // Update the color transfer function
- this->UpdateColorTransferFunction(vol,numberOfScalarComponents);
-
- // Update the noise texture that will be used to jitter rays to
- // reduce alliasing artifacts
- this->UpdateNoiseTexture();
-
- // We are going to change the blending mode and blending function -
- // so lets push here so we can pop later
- glPushAttrib(GL_COLOR_BUFFER_BIT);
-
- // If this is the canonical view - we don't want to intermix so we'll just
- // start by clearing the z buffer.
- if ( this->GeneratingCanonicalView )
- {
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
-
- // See if the volume transform is orientation-preserving
- vtkMatrix4x4 *m=vol->GetMatrix();
- double det=vtkMath::Determinant3x3(
- m->GetElement(0,0),m->GetElement(0,1),m->GetElement(0,2),
- m->GetElement(1,0),m->GetElement(1,1),m->GetElement(1,2),
- m->GetElement(2,0),m->GetElement(2,1),m->GetElement(2,2));
-
- this->PreserveOrientation=det>0;
-
- // If we have clipping planes, render the back faces of the clipped
- // bounding box of the whole dataset to set the zbuffer.
- if(this->ClippingPlanes && this->ClippingPlanes->GetNumberOfItems()!=0)
- {
- // push the model view matrix onto the stack, make sure we
- // adjust the mode first
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- this->TempMatrix[0]->DeepCopy(vol->GetMatrix());
- this->TempMatrix[0]->Transpose();
- glMultMatrixd(this->TempMatrix[0]->Element[0]);
- this->ClipBoundingBox(ren,datasetBounds,vol);
- glEnable (GL_CULL_FACE);
- glCullFace (GL_FRONT);
- glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
- this->RenderClippedBoundingBox(0,0,1,ren->GetRenderWindow());
- glDisable (GL_CULL_FACE);
- glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
- //glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
- // Check if everything is OK
- this->CheckFrameBufferStatus();
-
- // Intermixed geometry: Grab the depth buffer into a texture
-
- int size[2];
- int lowerLeft[2];
- ren->GetTiledSizeAndOrigin(size,size+1,lowerLeft,lowerLeft+1);
-
- vtkgl::ActiveTexture( vtkgl::TEXTURE3 );
- glBindTexture(GL_TEXTURE_2D,
- static_cast<GLuint>(
- this->TextureObjects[
- vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap]));
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,lowerLeft[0],lowerLeft[1],size[0],
- size[1]);
-
-
- vtkgl::ActiveTexture( vtkgl::TEXTURE0 );
-
- int parallelProjection=ren->GetActiveCamera()->GetParallelProjection();
-
- // initialize variables to prevent compiler warnings.
- int rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP;
- int shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed;
- int componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed;
-
- switch(this->BlendMode)
- {
- case vtkVolumeMapper::COMPOSITE_BLEND:
- switch(numberOfScalarComponents)
- {
- case 1:
- componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne;
- break;
- case 4:
- componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentFour;
- break;
- default:
- assert("check: impossible case" && false);
- break;
- }
- if(this->MaskInput!=0)
- {
- rayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask;
- }
- else
- {
- //cout<<"program is composite+shade"<<endl;
- rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite;
- }
- if ( vol->GetProperty()->GetShade() )
- {
- shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes;
- assert("check: only_1_component_todo" && numberOfScalarComponents==1);
- }
- else
- {
- shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNo;
- //cout<<"program is composite"<<endl;
- }
- break;
- case vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND:
- shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed;
- componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed;
- switch(numberOfScalarComponents)
- {
- case 1:
- rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP;
- break;
- case 4:
- rayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent;
- break;
- default:
- assert("check: impossible case" && false);
- break;
- }
- break;
- case vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND:
- shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed;
- componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed;
- switch(numberOfScalarComponents)
- {
- case 1:
- rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP;
- break;
- case 4:
- rayCastMethod=
- vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent;
- break;
- default:
- assert("check: impossible case" && false);
- break;
- }
- break;
- default:
- assert("check: impossible case" && 0);
- rayCastMethod=0;
- break;
- }
-
- this->ComputeNumberOfCroppingRegions(); // TODO AMR vs single block
- if(this->AMRMode)
- {
- NumberOfCroppingRegions=2; // >1, means use do compositing between blocks
- }
- this->BuildProgram(parallelProjection,rayCastMethod,shadeMethod,
- componentMethod);
- this->CheckLinkage(this->ProgramShader);
-
- vtkgl::UseProgram(this->ProgramShader);
-
- // for active texture 0, dataset
-
- if(numberOfScalarComponents==1)
- {
- // colortable
- vtkgl::ActiveTexture(vtkgl::TEXTURE1);
- this->RGBTable->Bind();
-
- if(this->MaskInput!=0)
- {
- vtkgl::ActiveTexture(vtkgl::TEXTURE8);
- this->Mask1RGBTable->Bind();
- vtkgl::ActiveTexture(vtkgl::TEXTURE9);
- this->Mask2RGBTable->Bind();
- }
- }
-
- GLint uDataSetTexture;
-
- uDataSetTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"dataSetTexture");
-
- if(uDataSetTexture!=-1)
- {
- vtkgl::Uniform1i(uDataSetTexture,0);
- }
- else
- {
- vtkErrorMacro(<<"dataSetTexture is not a uniform variable.");
- }
-
- if ( this->MaskInput)
- {
- // Make the mask texture available on texture unit 7
- GLint uMaskTexture;
-
- uMaskTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"maskTexture");
-
- if(uMaskTexture!=-1)
- {
- vtkgl::Uniform1i(uMaskTexture,7);
- }
- else
- {
- vtkErrorMacro(<<"maskTexture is not a uniform variable.");
- }
- }
-
- if(numberOfScalarComponents==1)
- {
- GLint uColorTexture;
- uColorTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"colorTexture");
-
- if(uColorTexture!=-1)
- {
- vtkgl::Uniform1i(uColorTexture,1);
- }
- else
- {
- vtkErrorMacro(<<"colorTexture is not a uniform variable.");
- }
-
- if(this->MaskInput!=0)
- {
- GLint uMask1ColorTexture;
- uMask1ColorTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"mask1ColorTexture");
-
- if(uMask1ColorTexture!=-1)
- {
- vtkgl::Uniform1i(uMask1ColorTexture,8);
- }
- else
- {
- vtkErrorMacro(<<"mask1ColorTexture is not a uniform variable.");
- }
-
- GLint uMask2ColorTexture;
- uMask2ColorTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"mask2ColorTexture");
-
- if(uMask2ColorTexture!=-1)
- {
- vtkgl::Uniform1i(uMask2ColorTexture,9);
- }
- else
- {
- vtkErrorMacro(<<"mask2ColorTexture is not a uniform variable.");
- }
-
- GLint uMaskBlendFactor;
- uMaskBlendFactor=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"maskBlendFactor");
- if(uMaskBlendFactor!=-1)
- {
- vtkgl::Uniform1f(uMaskBlendFactor,this->MaskBlendFactor);
- }
- else
- {
- vtkErrorMacro(<<"maskBlendFactor is not a uniform variable.");
- }
- }
-
- }
-
- GLint uOpacityTexture;
-
- uOpacityTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"opacityTexture");
-
- if(uOpacityTexture!=-1)
- {
- vtkgl::Uniform1i(uOpacityTexture,2);
- }
- else
- {
- vtkErrorMacro(<<"opacityTexture is not a uniform variable.");
- }
-
- // depthtexture
- vtkgl::ActiveTexture( vtkgl::TEXTURE3 );
- glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap]));
-
- GLint uDepthTexture;
-
- uDepthTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"depthTexture");
-
- if(uDepthTexture!=-1)
- {
- vtkgl::Uniform1i(uDepthTexture,3);
- }
- else
- {
- vtkErrorMacro(<<"depthTexture is not a uniform variable.");
- }
-
- // noise texture
- vtkgl::ActiveTexture( vtkgl::TEXTURE6 );
- glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->NoiseTextureId));
-
-
- GLint uNoiseTexture;
-
- uNoiseTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"noiseTexture");
-
- if(uNoiseTexture!=-1)
- {
- vtkgl::Uniform1i(uNoiseTexture,6);
- }
- else
- {
- vtkErrorMacro(<<"noiseTexture is not a uniform variable.");
- }
-
- this->CheckFrameBufferStatus();
-
- if(this->NumberOfCroppingRegions>1)
- {
- // framebuffer texture
- if(rayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP && rayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP)
- {
- vtkgl::ActiveTexture( vtkgl::TEXTURE4 );
- glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront]));
-
- GLint uFrameBufferTexture;
-
- uFrameBufferTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"frameBufferTexture");
-
- this->PrintError("framebuffertexture 1");
- if(uFrameBufferTexture!=-1)
- {
- vtkgl::Uniform1i(uFrameBufferTexture,4);
- }
- else
- {
- vtkErrorMacro(<<"frameBufferTexture is not a uniform variable.");
- }
- this->PrintError("framebuffertexture 2");
- }
-
- this->CheckFrameBufferStatus();
- // max scalar value framebuffer texture
- if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
- || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
- {
- vtkgl::ActiveTexture( vtkgl::TEXTURE5 );
- glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->MaxValueFrameBuffer2));
-
- GLint uScalarBufferTexture;
-
- uScalarBufferTexture=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"scalarBufferTexture");
-
- this->PrintError("scalarbuffertexture 1");
- if(uScalarBufferTexture!=-1)
- {
- vtkgl::Uniform1i(uScalarBufferTexture,5);
- }
- else
- {
- vtkErrorMacro(<<"scalarBufferTexture is not a uniform variable.");
- }
- this->PrintError("scalarbuffertexture 2");
- }
- }
- this->CheckFrameBufferStatus();
-
- GLint uWindowLowerLeftCorner;
-
- uWindowLowerLeftCorner=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"windowLowerLeftCorner");
-
- if(uWindowLowerLeftCorner!=-1)
- {
- vtkgl::Uniform2f(uWindowLowerLeftCorner,static_cast<GLfloat>(lowerLeft[0]),
- static_cast<GLfloat>(lowerLeft[1]));
- }
- else
- {
- vtkErrorMacro(<<"windowLowerLeftCorner is not a uniform variable.");
- }
- GLint uInvOriginalWindowSize;
-
- uInvOriginalWindowSize=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"invOriginalWindowSize");
-
- if(uInvOriginalWindowSize!=-1)
- {
- vtkgl::Uniform2f(uInvOriginalWindowSize,
- static_cast<GLfloat>(1.0/size[0]),
- static_cast<GLfloat>(1.0/size[1]));
- }
- else
- {
- // yes it is not error. It is only actually used when there is some
- // complex cropping (this->NumberOfCroppingRegions>1). Some GLSL compilers
- // may remove the uniform variable for optimization when it is not used.
- vtkDebugMacro(
- <<"invOriginalWindowSize is not an active uniform variable.");
- }
-
- size[0] = static_cast<int>(size[0]*this->ReductionFactor);
- size[1] = static_cast<int>(size[1]*this->ReductionFactor);
-
- GLint uInvWindowSize;
-
- uInvWindowSize=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"invWindowSize");
-
- if(uInvWindowSize!=-1)
- {
- vtkgl::Uniform2f(uInvWindowSize,static_cast<GLfloat>(1.0/size[0]),
- static_cast<GLfloat>(1.0/size[1]));
- }
- else
- {
- vtkErrorMacro(<<"invWindowSize is not a uniform variable.");
- }
-
-
- this->PrintError("after uniforms for textures");
-
-
- this->CheckFrameBufferStatus();
-
- GLint savedFrameBuffer;
- glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
- this->SavedFrameBuffer=static_cast<unsigned int>(savedFrameBuffer);
-
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
- static_cast<GLuint>(this->FrameBufferObject));
-
- this->BindFramebuffer();
-
- GLenum buffer[4];
- buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
- if(this->NumberOfCroppingRegions>1 &&
- this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND)
- {
- // max scalar frame buffer
- buffer[1] = vtkgl::COLOR_ATTACHMENT1_EXT;
- }
- else
- {
- buffer[1] = GL_NONE;
- }
-
- vtkgl::DrawBuffers(2,buffer);
-
- this->CheckFrameBufferStatus();
-
- // Use by the composite+shade program
- double shininess=vol->GetProperty()->GetSpecularPower();
- if(shininess>128.0)
- {
- shininess=128.0; // upper limit for the OpenGL shininess.
- }
- glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,static_cast<GLfloat>(shininess));
-
- glDisable(GL_COLOR_MATERIAL); // other mapper may have enable that.
-
- GLfloat values[4];
- values[3]=1.0;
-
- values[0]=0.0;
- values[1]=values[0];
- values[2]=values[0];
- glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,values);
-
- values[0]=static_cast<float>(vol->GetProperty()->GetAmbient());
- values[1]=values[0];
- values[2]=values[0];
- glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,values);
-
- values[0]=static_cast<float>(vol->GetProperty()->GetDiffuse());
- values[1]=values[0];
- values[2]=values[0];
- glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,values);
- values[0]=static_cast<float>(vol->GetProperty()->GetSpecular());
- values[1]=values[0];
- values[2]=values[0];
- glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,values);
-
-// cout << "pingpong=" << this->PingPongFlag << endl;
-
- // To initialize the second color buffer
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D,
- this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront],
- 0);
-
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT+1,
- GL_TEXTURE_2D,
- this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+1],
- 0);
- buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
- buffer[1] = vtkgl::COLOR_ATTACHMENT1_EXT;
- vtkgl::DrawBuffers(2,buffer);
-
-// cout << "check before setup" << endl;
- this->CheckFrameBufferStatus();
- this->SetupRender(ren,vol);
-
- // restore in case of composite with no cropping or streaming.
- buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
- buffer[1] = GL_NONE;
- vtkgl::DrawBuffers(2,buffer);
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT+1,
- GL_TEXTURE_2D,0,0);
-// cout << "check after color init" << endl;
- this->CheckFrameBufferStatus();
-
- if(this->NumberOfCroppingRegions>1 &&
- (this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND
- || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MAXIMUM_INTENSITY_BLEND))
- {
-// cout << "this->MaxValueFrameBuffer="<< this->MaxValueFrameBuffer <<endl;
-// cout << "this->MaxValueFrameBuffer2="<< this->MaxValueFrameBuffer2 <<endl;
-
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D,
- this->MaxValueFrameBuffer,0);
-
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT+1,
- GL_TEXTURE_2D,
- this->MaxValueFrameBuffer2,0);
-
- buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
- buffer[1] = vtkgl::COLOR_ATTACHMENT1_EXT;
- vtkgl::DrawBuffers(2,buffer);
-
- if(this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
- {
- glClearColor(1.0, 0.0, 0.0, 0.0);
- }
- else
- {
- glClearColor(0.0, 0.0, 0.0, 0.0); // for MAXIMUM_INTENSITY_BLEND
- }
-// cout << "check before clear on max" << endl;
- this->CheckFrameBufferStatus();
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- if(this->NumberOfCroppingRegions>1)
- {
- // color buffer target in the color attachement 0
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D,
- this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront],
- 0);
-
- // color buffer input is on texture unit 4.
- vtkgl::ActiveTexture(vtkgl::TEXTURE4);
- glBindTexture(GL_TEXTURE_2D,this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+1]);
-
- if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
- || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
- {
- // max buffer target in the color attachment 1
- vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
- vtkgl::COLOR_ATTACHMENT0_EXT+1,
- GL_TEXTURE_2D,
- this->MaxValueFrameBuffer,0);
-
- // max buffer input is on texture unit 5.
- vtkgl::ActiveTexture(vtkgl::TEXTURE5);
- glBindTexture(GL_TEXTURE_2D,this->MaxValueFrameBuffer2);
- }
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
- }
-
- this->CheckFrameBufferStatus();
-
- if(this->OpacityTables!=0 &&
- this->OpacityTables->Vector.size()!=numberOfLevels)
- {
- delete this->OpacityTables;
- this->OpacityTables=0;
- }
- if(this->OpacityTables==0)
- {
- this->OpacityTables=new vtkOpacityTables(numberOfLevels);
- }
-
- // debug code
- // DO NOT REMOVE the following commented line
-// this->ValidateProgram();
-
- glCullFace (GL_BACK);
- // otherwise, we are rendering back face to initialize the zbuffer.
-
-
- if(!this->GeneratingCanonicalView && this->ReportProgress)
- {
- // initialize the time to avoid a progress event at the beginning.
- this->LastProgressEventTime=vtkTimerLog::GetUniversalTime();
- }
-
- this->PrintError("PreRender end");
-}
-
-//-----------------------------------------------------------------------------
-// Compute how each axis of a cell is projected on the viewport in pixel.
-// This requires to have information about the camera and about the volume.
-// It set the value of IgnoreSampleDistancePerPixel to true in case of
-// degenerated case (axes aligned with the view).
-//-----------------------------------------------------------------------------
-double vtkMitkOpenGLGPUVolumeRayCastMapper::ComputeMinimalSampleDistancePerPixel(
- vtkRenderer *renderer,
- vtkVolume *volume)
-{
- // For each of the 3 directions of a cell, compute the step in z
- // (world coordinate, not eye/camera coordinate)
- // to go to the next pixel in x.
- // Same for the next pixel in y.
- // Keep the minimum of both zstep
- // Then keep the minimum for the 3 directions.
-
- // in case of either the numerator or the denominator of each ratio is 0.
- this->IgnoreSampleDistancePerPixel=true;
- double result=0.0;
-
- vtkMatrix4x4 *worldToDataset=volume->GetMatrix();
- vtkCamera *camera=renderer->GetActiveCamera();
- vtkMatrix4x4 *eyeToWorld=camera->GetViewTransformMatrix();
- vtkMatrix4x4 *eyeToDataset=vtkMatrix4x4::New();
- vtkMatrix4x4::Multiply4x4(eyeToWorld,worldToDataset,eyeToDataset);
-
- int usize;
- int vsize;
- renderer->GetTiledSize(&usize,&vsize);
- vtkMatrix4x4 *viewportToEye=camera->GetProjectionTransformMatrix(
- usize/static_cast<double>(vsize),0.0,1.0);
-
- double volBounds[6];
- this->GetInput()->GetBounds(volBounds);
- int dims[3];
- this->GetInput()->GetDimensions(dims);
-
- double v0[4];
- v0[0]=volBounds[0];
- v0[1]=volBounds[2];
- v0[2]=volBounds[4];
- v0[3]=1.0;
-
- double w0[4];
- eyeToDataset->MultiplyPoint(v0,w0);
-
- double z0;
-
- if(w0[3]!=0.0)
- {
- z0=w0[2]/w0[3];
- }
- else
- {
- z0=0.0;
- vtkGenericWarningMacro( "eyeToWorld transformation has some projective component." );
- }
-
- double p0[4];
- viewportToEye->MultiplyPoint(w0,p0);
- p0[0]/=p0[3];
- p0[1]/=p0[3];
- p0[2]/=p0[3];
-
- bool inFrustum=p0[0]>=-1.0 && p0[0]<=1.0 && p0[1]>=-1.0 && p0[1]<=1.0 && p0[2]>=-1.0 && p0[2]<=1.0;
-
- if(inFrustum)
- {
- int dim=0;
- while(dim<3)
- {
- double v1[4];
- int coord=0;
- while(coord<3)
- {
- if(coord==dim)
- {
- v1[coord]=volBounds[2*coord+1];
- }
- else
- {
- v1[coord]=volBounds[2*coord]; // same as v0[coord];
- }
- ++coord;
- }
- v1[3]=1.0;
-
- double w1[4];
- eyeToDataset->MultiplyPoint(v1,w1);
- double z1;
-
- if(w1[3]!=0.0)
- {
- z1=w1[2]/w1[3];
- }
- else
- {
- z1=0.0;
- vtkGenericWarningMacro( "eyeToWorld transformation has some projective component." );
- }
-
-
- double p1[4];
- viewportToEye->MultiplyPoint(w1,p1);
- p1[0]/=p1[3];
- p1[1]/=p1[3];
- p1[2]/=p1[3];
-
- inFrustum=p1[0]>=-1.0 && p1[0]<=1.0 && p1[1]>=-1.0 && p1[1]<=1.0 && p1[2]>=-1.0 && p1[2]<=1.0;
-
- if(inFrustum)
- {
- double dx=fabs(p1[0]-p0[0]);
- double dy=fabs(p1[1]-p0[1]);
- double dz=fabs(z1-z0);
- dz=dz/(dims[dim]-1);
- dx=dx/(dims[dim]-1)*usize;
- dy=dy/(dims[dim]-1)*vsize;
-
- if(dz!=0.0)
- {
- if(dx!=0.0)
- {
- double d=dz/dx;
- if(!this->IgnoreSampleDistancePerPixel)
- {
- if(result>d)
- {
- result=d;
- }
- }
- else
- {
- this->IgnoreSampleDistancePerPixel=false;
- result=d;
- }
- }
-
- if(dy!=0.0)
- {
- double d=dz/dy;
- if(!this->IgnoreSampleDistancePerPixel)
- {
- if(result>d)
- {
- result=d;
- }
- }
- else
- {
- this->IgnoreSampleDistancePerPixel=false;
- result=d;
- }
- }
-
- }
- }
- ++dim;
- }
- }
-
- eyeToDataset->Delete();
-
- if(this->IgnoreSampleDistancePerPixel)
- {
- // cout<<"ignore SampleDistancePerPixel"<<endl;
- }
- else
- {
- //cout<<"SampleDistancePerPixel="<<result<<endl;
- }
-
- return result;
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderBlock(vtkRenderer *ren,
- vtkVolume *vol,
- unsigned int level)
-{
- vtkImageData *input = this->GetInput();
-
- if(!this->AutoAdjustSampleDistances)
- {
- this->ActualSampleDistance=this->SampleDistance;
- }
- else
- {
- double datasetSpacing[3]; // from input. same for each block in streaming.
- // different for each block in AMR. Given in dataset space.
-
- input->GetSpacing(datasetSpacing);
-
- vtkMatrix4x4 *worldToDataset=vol->GetMatrix();
- // Assuming spacing is positive.
- double minWorldSpacing=VTK_DOUBLE_MAX;
- int i=0;
- while(i<3)
- {
- double tmp=worldToDataset->GetElement(0,i);
- double tmp2=tmp*tmp;
- tmp=worldToDataset->GetElement(1,i);
- tmp2+=tmp*tmp;
- tmp=worldToDataset->GetElement(2,i);
- double worldSpacing=datasetSpacing[i]*sqrt(tmp2+tmp*tmp);
- if(worldSpacing<minWorldSpacing)
- {
- minWorldSpacing=worldSpacing;
- }
- ++i;
- }
- // minWorldSpacing is the optimal sample distance in world space.
- // To go faster (reduceFactor<1.0), we multiply this distance
- // by 1/reduceFactor.
-
- this->ActualSampleDistance=static_cast<float>(minWorldSpacing);
-
- if ( this->ReductionFactor < 1.0 )
- {
- this->ActualSampleDistance /= static_cast<GLfloat>(this->ReductionFactor*0.5);
- }
- }
-
- // As the opacity table table depend on the samplingdistance per block,
- // it has to be recomputed if the sample distance changed between blocks
- // of different size/level.
-
- vtkDataArray *scalars=this->GetScalars(input,this->ScalarMode,
- this->ArrayAccessMode,
- this->ArrayId,
- this->ArrayName,
- this->CellFlag);
-
- this->UpdateOpacityTransferFunction(vol,
- scalars->GetNumberOfComponents(),
- level);
-
- // opacitytable
- vtkgl::ActiveTexture(vtkgl::TEXTURE2);
- this->OpacityTables->Vector[level].Bind();
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
-
- this->PrintError("after uniforms for projection and shade");
-
- // debug code
- // DO NOT REMOVE the following commented line
-// this->ValidateProgram();
-
- this->PrintError("before render");
- if(!this->Cropping)
- {
- this->RenderWholeVolume(ren,vol);
- }
- else
- {
- this->ClipCroppingRegionPlanes();
- this->RenderRegions(ren,vol);
- }
- this->PrintError("after render");
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::PostRender(
- vtkRenderer *ren,
- int numberOfScalarComponents)
-{
- this->PrintError("PostRender1");
- if(this->NumberOfCroppingRegions>1)
- {
- if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
- || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
- {
- vtkgl::ActiveTexture( vtkgl::TEXTURE5 );
- glBindTexture(GL_TEXTURE_2D,0);
- }
-
- if(this->LastRayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP
- && this->LastRayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP)
- {
- vtkgl::ActiveTexture( vtkgl::TEXTURE4 );
- glBindTexture(GL_TEXTURE_2D,0);
- }
- }
-
- // noisetexture
- vtkgl::ActiveTexture(vtkgl::TEXTURE6);
- glBindTexture(GL_TEXTURE_2D,0);
-
- // depthtexture
- vtkgl::ActiveTexture(vtkgl::TEXTURE3);
- glBindTexture(GL_TEXTURE_2D,0);
-
- // opacity
- vtkgl::ActiveTexture(vtkgl::TEXTURE2);
- glBindTexture(GL_TEXTURE_1D,0);
-
- if(numberOfScalarComponents==1)
- {
- vtkgl::ActiveTexture(vtkgl::TEXTURE1);
- glBindTexture(GL_TEXTURE_1D,0);
- }
-
-
- // mask, if any
- if(this->MaskInput!=0)
- {
- vtkgl::ActiveTexture(vtkgl::TEXTURE7);
- glBindTexture(vtkgl::TEXTURE_3D_EXT,0);
- }
-
- // back to active texture 0.
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
- glBindTexture(vtkgl::TEXTURE_3D_EXT,0);
-
- vtkgl::UseProgram(0);
-
- this->PrintError("after UseProgram(0)");
-
- this->CleanupRender();
- this->PrintError("after CleanupRender");
-
- vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
- static_cast<GLuint>(this->SavedFrameBuffer));
- this->SavedFrameBuffer=0;
-
- // Undo the viewport change we made to reduce resolution
- int size[2];
- int lowerLeft[2];
- ren->GetTiledSizeAndOrigin(size,size+1,lowerLeft,lowerLeft+1);
- glViewport(lowerLeft[0],lowerLeft[1], size[0], size[1]);
- glEnable( GL_SCISSOR_TEST );
- glScissor(lowerLeft[0],lowerLeft[1], size[0], size[1]);
-
- // Render the texture to the screen - this copies the offscreen buffer
- // onto the screen as a texture mapped polygon
- this->RenderTextureToScreen(ren);
- this->PrintError("after RenderTextureToScreen");
-
- glEnable(GL_DEPTH_TEST);
-
- glPopAttrib(); // restore the blending mode and function
-
- glFinish();
-
- this->PrintError("PostRender2");
-}
-
-//-----------------------------------------------------------------------------
-// The main render method called from the superclass
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer *ren,
- vtkVolume *vol)
-{
- // We've already checked that we have input
- vtkImageData *input = this->GetTransformedInput();
-
- // Get the bounds of this data
- double bounds[6];
- this->GetBounds(bounds);
-
- // Get the scalar range. First we have to get the scalars.
- double range[2];
- vtkDataArray *scalars=this->GetScalars(input,this->ScalarMode,
- this->ArrayAccessMode,
- this->ArrayId,this->ArrayName,
- this->CellFlag);
-
- // How many components are there?
- int numberOfScalarComponents=scalars->GetNumberOfComponents();
-
- // If it is just one, then get the range from the scalars
- if(numberOfScalarComponents==1)
- {
- // Warning: here, we ignore the blank cells.
- scalars->GetRange(range);
- }
- // If it is 3, then use the 4th component's range since that is
- // the component that will be passed through the scalar opacity
- // transfer function to look up opacity
- else
- {
- // Note that we've already checked data type and we know this is
- // unsigned char
- scalars->GetRange(range,3);
- }
-
- // The rendering work has been broken into 3 stages to support AMR
- // volume rendering in blocks. Here we are simply rendering the
- // whole volume as one block. Note that if the volume is too big
- // to fix into texture memory, it will be streamed through in the
- // RenderBlock method.
-
- this->PreRender(ren,vol,bounds,range,numberOfScalarComponents,1);
-
- if(!this->OpacityTables)
- this->PreRender(ren,vol,bounds,range,numberOfScalarComponents,1);
-
- if(this->LoadExtensionsSucceeded)
- {
- this->RenderBlock(ren,vol,0);
- this->PostRender(ren,numberOfScalarComponents);
- }
-
- // Let's just make sure no OpenGL errors occurred during this render
- this->PrintError("End GPU Render");
-
- // If this isn't a canonical view render, then update the progress to
- // 1 because we are done.
- if (!this->GeneratingCanonicalView )
- {
- double progress=1.0;
- this->InvokeEvent(vtkCommand::VolumeMapperRenderProgressEvent,&progress);
- ren->GetRenderWindow()->MakeCurrent();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Render a the whole volume.
-// \pre this->ProgramShader!=0 and is linked.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderWholeVolume(vtkRenderer *ren,
- vtkVolume *vol)
-{
- double volBounds[6];
- this->GetTransformedInput()->GetBounds(volBounds);
- this->RenderSubVolume(ren,volBounds,vol);
-}
-
-
-//-----------------------------------------------------------------------------
-// Sort regions from front to back.
-//-----------------------------------------------------------------------------
-class vtkRegionDistance2
-{
-public:
- size_t Id; // 0<=Id<27
- // square distance between camera center to region center: >=0
- double Distance2;
-};
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-extern "C" int vtkRegionComparisonFunction(const void *x,
- const void *y)
-{
- double dx=static_cast<const vtkRegionDistance2 *>(x)->Distance2;
- double dy=static_cast<const vtkRegionDistance2 *>(y)->Distance2;
-
- int result;
- if(dx<dy)
- {
- result=-1;
- }
- else
- {
- if(dx>dy)
- {
- result=1;
- }
- else
- {
- result=0;
- }
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Render a subvolume.
-// \pre this->ProgramShader!=0 and is linked.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderRegions(vtkRenderer *ren,
- vtkVolume *vol)
-{
- double bounds[27][6];
- double distance2[27];
-
- double camPos[4];
- ren->GetActiveCamera()->GetPosition(camPos);
-
- double volBounds[6];
- this->GetInput()->GetBounds(volBounds);
-
-
- // Pass camera through inverse volume matrix
- // so that we are in the same coordinate system
- vol->GetMatrix( this->InvVolumeMatrix );
- camPos[3] = 1.0;
- this->InvVolumeMatrix->Invert();
- this->InvVolumeMatrix->MultiplyPoint( camPos, camPos );
- if ( camPos[3] )
- {
- camPos[0] /= camPos[3];
- camPos[1] /= camPos[3];
- camPos[2] /= camPos[3];
- }
-
- // These are the region limits for x (first four), y (next four) and
- // z (last four). The first region limit is the lower bound for
- // that axis, the next two are the region planes along that axis, and
- // the final one in the upper bound for that axis.
- double limit[12];
- size_t i;
- for ( i = 0; i < 3; i++ )
- {
- limit[i*4 ] = volBounds[i*2];
- limit[i*4+1] = this->ClippedCroppingRegionPlanes[i*2];
- limit[i*4+2] = this->ClippedCroppingRegionPlanes[i*2+1];
- limit[i*4+3] = volBounds[i*2+1];
- }
-
- // For each of the 27 possible regions, find out if it is enabled,
- // and if so, compute the bounds and the distance from the camera
- // to the center of the region.
- size_t numRegions = 0;
- size_t region;
- for ( region = 0; region < 27; region++ )
- {
- int regionFlag = 1<<region;
-
- if ( this->CroppingRegionFlags & regionFlag )
- {
- // what is the coordinate in the 3x3x3 grid
- size_t loc[3];
- loc[0] = region%3;
- loc[1] = (region/3)%3;
- loc[2] = (region/9)%3;
-
- // make sure the cropping region is not empty NEW
- // otherwise, we skip the region.
- if((limit[loc[0]]!=limit[loc[0]+1])
- && (limit[loc[1]+4]!=limit[loc[1]+5])
- && (limit[loc[2]+8]!=limit[loc[2]+9]))
- {
- // compute the bounds and center
- double center[3];
- for ( i = 0; i < 3; i++ )
- {
- bounds[numRegions][i*2 ] = limit[4*i+loc[i]];
- bounds[numRegions][i*2+1] = limit[4*i+loc[i]+1];
- center[i]=(bounds[numRegions][i*2]+bounds[numRegions][i*2+1])*0.5;
- }
-
- // compute the distance squared to the center
- distance2[numRegions] =
- (camPos[0]-center[0])*(camPos[0]-center[0]) +
- (camPos[1]-center[1])*(camPos[1]-center[1]) +
- (camPos[2]-center[2])*(camPos[2]-center[2]);
-
- // we've added one region
- numRegions++;
- }
- }
- }
- vtkRegionDistance2 regions[27];
-
- i=0;
- while(i<numRegions)
- {
- regions[i].Id=i;
- regions[i].Distance2=distance2[i];
- ++i;
- }
- qsort(regions,numRegions,sizeof(vtkRegionDistance2),
- vtkRegionComparisonFunction);
-
- // loop over all regions we need to render
- int abort=0;
- i=0;
- while(!abort && i < numRegions)
- {
-// cout<<"i="<<i<<" regions[i].Id="<<regions[i].Id<<endl;
- abort=this->RenderSubVolume(ren,bounds[regions[i].Id],vol);
- ++i;
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// Computethe number of cropping regions. (0 is no cropping).
-// \post positive_NumberOfCroppingRegions: this->NumberOfCroppingRegions>=0
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::ComputeNumberOfCroppingRegions()
-{
- this->NumberOfCroppingRegions=0;
- if(this->Cropping)
- {
- // For each of the 27 possible regions, find out if it is enabled;
- for ( int region = 0; region < 27; region++ )
- {
- int regionFlag = 1<<region;
-
- if ( this->CroppingRegionFlags & regionFlag )
- {
- // we've added one region
- ++this->NumberOfCroppingRegions;
- }
- }
- }
- this->NumberOfCroppingRegions=2; // FB: DEBUG
- assert("post: positive_NumberOfCroppingRegions" &&
- this->NumberOfCroppingRegions>=0);
-}
-
-//-----------------------------------------------------------------------------
-// slabsDataSet are position of the slabs in dataset coordinates.
-// slabsPoints are position of the slabs in points coordinates.
-// For instance, slabsDataSet[0] is the position of the plane bounding the slab
-// on the left of x axis of the dataset. slabsPoints[0]=0.3 means that
-// this plane lies between point 0 and point 1 along the x-axis.
-// There is no clamping/clipping according to the dataset bounds so,
-// slabsPoints can be negative or excess the number of points along the
-// corresponding axis.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::SlabsFromDatasetToIndex(
- double slabsDataSet[6],
- double slabsPoints[6])
-{
- double *spacing=this->GetInput()->GetSpacing();
- double origin[3];
-
- // take spacing sign into account
- double *bds = this->GetInput()->GetBounds();
- origin[0] = bds[0];
- origin[1] = bds[2];
- origin[2] = bds[4];
-
- int i=0;
- while(i<6)
- {
- slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
- ++i;
- }
-}
-
-//-----------------------------------------------------------------------------
-// slabsDataSet are position of the slabs in dataset coordinates.
-// slabsPoints are position of the slabs in points coordinates.
-// For instance, slabsDataSet[0] is the position of the plane bounding the slab
-// on the left of x axis of the dataset. slabsPoints[0]=0.3 means that
-// this plane lies between point 0 and point 1 along the x-axis.
-// There is no clamping/clipping according to the dataset bounds so,
-// slabsPoints can be negative or excess the number of points along the
-// corresponding axis.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::SlabsFromIndexToDataset(
- double slabsPoints[6],
- double slabsDataSet[6])
-{
- double *spacing=this->GetInput()->GetSpacing();
- double origin[3];
-
- // take spacing sign into account
- double *bds = this->GetInput()->GetBounds();
- origin[0] = bds[0];
- origin[1] = bds[2];
- origin[2] = bds[4];
-
- int i=0;
- while(i<6)
- {
- slabsDataSet[i]=slabsPoints[i]*spacing[i/2]+origin[i/2];
- ++i;
- }
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class vtkStreamBlock
-{
-public:
- double Bounds[6];
- double Extent[6];
-};
-
-//-----------------------------------------------------------------------------
-// Render a subvolume. bounds are in world coordinates.
-// \pre this->ProgramShader!=0 and is linked.
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::RenderSubVolume(vtkRenderer *ren,
- double bounds[6],
- vtkVolume *volume)
-{
- // Time to load scalar field
- size_t i;
- int wholeTextureExtent[6];
- this->GetTransformedInput()->GetExtent(wholeTextureExtent);
- if(this->CellFlag)
- {
- i=1;
- while(i<6)
- {
- wholeTextureExtent[i]--;
- i+=2;
- }
- }
-
- // 1. Found out the extent of the subvolume
- double realExtent[6];
- int subvolumeTextureExtent[6];
-
- this->SlabsFromDatasetToIndex(bounds,realExtent);
-
- if(this->CellFlag) // 3D texture are celldata
- {
- // texture extents are expressed in cells in this case
- i=0;
- while(i<6)
- {
- subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i]-0.5);
- ++i;
- subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i]-0.5)+1;
- ++i;
- }
- }
- else
- {
- // texture extents are expressed in points in this case
- i=0;
- while(i<6)
- {
- subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i]);
- ++i;
- subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i])+1; // used to not have +1
- ++i;
- }
- }
-
- i=0;
- while(i<6)
- {
- assert("check: wholeTextureExtent" && wholeTextureExtent[i]==0);
- if(subvolumeTextureExtent[i]<wholeTextureExtent[i])
- {
- subvolumeTextureExtent[i]=wholeTextureExtent[i];
- }
- ++i;
- if(subvolumeTextureExtent[i]>wholeTextureExtent[i])
- {
- subvolumeTextureExtent[i]=wholeTextureExtent[i];
- }
- ++i;
- }
-
- assert("check: subvolume_inside_wholevolume" &&
- subvolumeTextureExtent[0]>=wholeTextureExtent[0]
- && subvolumeTextureExtent[1]<=wholeTextureExtent[1]
- && subvolumeTextureExtent[2]>=wholeTextureExtent[2]
- && subvolumeTextureExtent[3]<=wholeTextureExtent[3]
- && subvolumeTextureExtent[4]>=wholeTextureExtent[4]
- && subvolumeTextureExtent[5]<=wholeTextureExtent[5]);
-
- // 2. Is this subvolume already on the GPU?
- // ie are the extent of the subvolume inside the loaded extent?
-
-
- // Find the texture (and mask).
- vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=
- this->ScalarsTextures->Map.find(this->GetTransformedInput());
- vtkKWScalarField *texture;
- if(it==this->ScalarsTextures->Map.end())
- {
- texture=0;
- }
- else
- {
- texture=(*it).second;
- }
-
- vtkKWMask *mask=0;
- if(this->MaskInput!=0)
- {
- vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it2=
- this->MaskTextures->Map.find(this->MaskInput);
- if(it2==this->MaskTextures->Map.end())
- {
- mask=0;
- }
- else
- {
- mask=(*it2).second;
- }
- }
-
- int loaded =
- texture!=0 &&
- texture->IsLoaded() &&
- this->GetTransformedInput()->GetMTime()<=texture->GetBuildTime() &&
- (this->GetMaskInput() ? this->GetMaskInput()->GetMTime() <= texture->GetBuildTime() : true) &&
- texture->GetLoadedCellFlag()==this->CellFlag;
-
-
- vtkIdType *loadedExtent;
-
- if(loaded)
- {
- loadedExtent=texture->GetLoadedExtent();
- i=0;
- while(loaded && i<6)
- {
- loaded=loaded && loadedExtent[i]<=subvolumeTextureExtent[i];
- ++i;
- loaded=loaded && loadedExtent[i]>=subvolumeTextureExtent[i];
- ++i;
- }
- }
-
- if(loaded)
- {
- this->CurrentScalar=texture;
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
- this->CurrentScalar->Bind();
-
- vtkgl::ActiveTexture(vtkgl::TEXTURE7);
- this->CurrentMask=mask;
- if(this->CurrentMask!=0)
- {
- this->CurrentMask->Bind();
- }
- }
-
- if(!loaded)
- {
- // 3. Not loaded: try to load the whole dataset
- if(!this->LoadScalarField(this->GetTransformedInput(),this->MaskInput,wholeTextureExtent,volume))
- {
- // 4. loading the whole dataset failed: try to load the subvolume
- if(!this->LoadScalarField(this->GetTransformedInput(),this->MaskInput, subvolumeTextureExtent,
- volume))
- {
- // 5. loading the subvolume failed: stream the subvolume
- // 5.1 do zslabs first, if too large then cut with x or y with the
- // largest dimension. order of zlabs depends on sign of spacing[2]
- int streamTextureExtent[6];
- i=0;
- while(i<6)
- {
- streamTextureExtent[i]=subvolumeTextureExtent[i];
- ++i;
- }
-
- unsigned int internalFormat;
- unsigned int format;
- unsigned int type;
- int componentSize;
- this->GetTextureFormat(this->GetInput(),&internalFormat,&format,&type,
- &componentSize);
-
- // Enough memory?
- int originalTextureSize[3];
- int textureSize[3];
- i=0;
- while(i<3)
- {
- textureSize[i]=subvolumeTextureExtent[2*i+1]-subvolumeTextureExtent[2*i]+1;
- originalTextureSize[i]=textureSize[i];
- ++i;
- }
-
- // Make sure loading did not fail because of theorical limits
-
- GLint width;
- glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&width);
-
- int clippedXY=0;
- int clippedZ=0;
-
- if(textureSize[0]>width)
- {
- textureSize[0]=width;
- clippedXY=1;
- }
- if(textureSize[1]>width)
- {
- textureSize[1]=width;
- clippedXY=1;
- }
- if(textureSize[2]>width)
- {
- textureSize[2]=width;
- clippedZ=1;
- }
-
- int minSize;
- if(this->CellFlag)
- {
- minSize=1;
- }
- else
- {
- minSize=2;
- }
-
- if(clippedXY)
- {
- // We cannot expect to first divide as z-slabs because it is already
- // clipped in another dimension. From now, just divide in the largest
- // dimension.
- bool foundSize=false;
- while(!foundSize && textureSize[0]>=minSize
- && textureSize[1]>=minSize)
- {
- foundSize=this->TestLoadingScalar(internalFormat,format,type,
- textureSize,componentSize);
- if(!foundSize)
- {
- int maxDim=0;
- if(textureSize[1]>textureSize[0])
- {
- maxDim=1;
- }
- if(textureSize[2]>textureSize[maxDim])
- {
- maxDim=2;
- }
- textureSize[maxDim]>>=1; // /=2
- }
- }
- }
- else
- {
- // we are in cropping mode, it will be slow anyway. the case we want
- // to optimize is stream the all scalar field. With that in mine,
- // it is better to first try to send z-slabs. If even a minimal
- // z-slab is too big, we have to divide by x or y dimensions. In
- // this case, it will be slow and we can choose to keep blocks as
- // square as possible by dividing by the largest dimension at each
- // iteration.
-
- if(!clippedZ)
- {
- // we start by subdividing only if we did not already clipped
- // the z dimension according to the theorical limits.
- textureSize[2]>>=1; // /=2
- }
-
- bool foundSize=false;
- while(!foundSize && textureSize[2]>=minSize)
- {
- foundSize=this->TestLoadingScalar(internalFormat,format,type,
- textureSize,componentSize);
- if(!foundSize)
- {
- textureSize[2]>>=1; // /=2
- }
- }
- if(!foundSize)
- {
- textureSize[2]=minSize;
- if(textureSize[0]>textureSize[1])
- {
- textureSize[0]>>=1; // /=2
- }
- else
- {
- textureSize[1]>>=1; // /=2
- }
- while(!foundSize && textureSize[0]>=minSize
- && textureSize[1]>=minSize)
- {
- foundSize=this->TestLoadingScalar(internalFormat,format,type,
- textureSize,componentSize);
- if(!foundSize)
- {
- if(textureSize[0]>textureSize[1])
- {
- textureSize[0]>>=1; // /=2
- }
- else
- {
- textureSize[1]>>=1; // /=2
- }
- }
- }
- }
- if(!foundSize)
- {
- vtkErrorMacro(
- <<"No memory left on the GPU even for a minimal block.");
- return 1; // abort
- }
- }
-
- // except for the last bound.
- // front to back ordering
-
- // Pass camera through inverse volume matrix
- // so that we are in the same coordinate system
- double camPos[4];
- vtkCamera *cam = ren->GetActiveCamera();
- cam->GetPosition(camPos);
- volume->GetMatrix( this->InvVolumeMatrix );
- camPos[3] = 1.0;
- this->InvVolumeMatrix->Invert();
- this->InvVolumeMatrix->MultiplyPoint( camPos, camPos );
- if ( camPos[3] )
- {
- camPos[0] /= camPos[3];
- camPos[1] /= camPos[3];
- camPos[2] /= camPos[3];
- }
-
-
- // 5.2 iterate of each stream of the subvolume and render it:
-
- // point scalar: on the first block, the first point is not shared
-
- // blockExtent is always expressed in point, not in texture
- // extent.
- size_t remainder[3];
- i=0;
- while(i<3)
- {
- remainder[i]=static_cast<size_t>(
- (originalTextureSize[i]-textureSize[i])%(textureSize[i]-1));
- if(remainder[i]>0)
- {
- remainder[i]=1;
- }
- ++i;
- }
-
- size_t counts[3];
-
- counts[0]=static_cast<size_t>((originalTextureSize[0]-textureSize[0])
- /(textureSize[0]-1));
- counts[0]+=remainder[0]+1;
- counts[1]=static_cast<size_t>((originalTextureSize[1]-textureSize[1])
- /(textureSize[1]-1));
- counts[1]+=remainder[1]+1;
- counts[2]=static_cast<size_t>((originalTextureSize[2]-textureSize[2])
- /(textureSize[2]-1));
- counts[2]+=remainder[2]+1;
-
- size_t count=counts[0]*counts[1]*counts[2];
-
- double blockExtent[6];
- vtkStreamBlock *blocks=new vtkStreamBlock[count];
- vtkRegionDistance2 *sortedBlocks=new vtkRegionDistance2[count];
-
- // iterate over z,y,x
- size_t blockId=0;
-
- size_t zIndex=0;
- blockExtent[4]=realExtent[4];
- blockExtent[5]=vtkMath::Floor(blockExtent[4])+textureSize[2];
- if(!this->CellFlag)
- {
- blockExtent[5]--;
- }
- if(blockExtent[5]>realExtent[5])
- {
- blockExtent[5]=realExtent[5];
- }
- while(zIndex<counts[2])
- {
-
- blockExtent[2]=realExtent[2];
- blockExtent[3]=vtkMath::Floor(blockExtent[2])+textureSize[1];
- if(!this->CellFlag)
- {
- blockExtent[3]--;
- }
- if(blockExtent[3]>realExtent[3])
- {
- blockExtent[3]=realExtent[3];
- }
- size_t yIndex=0;
- while(yIndex<counts[1])
- {
-
- blockExtent[0]=realExtent[0];
- blockExtent[1]=vtkMath::Floor(blockExtent[0])+textureSize[0];
- if(!this->CellFlag)
- {
- blockExtent[1]--;
- }
- if(blockExtent[1]>realExtent[1])
- {
- blockExtent[1]=realExtent[1];
- }
- size_t xIndex=0;
- while(xIndex<counts[0])
- {
- assert("check: valid_blockId" && blockId<count);
- // save blockExtent to the list of blocks
- double blockBounds[6];
- this->SlabsFromIndexToDataset(blockExtent,blockBounds);
-
- // compute the bounds and center
- double center[3];
- i=0;
- while(i<3)
- {
- center[i]=(blockBounds[i*2]+blockBounds[i*2+1])*0.5;
- ++i;
- }
-
- // compute the distance squared to the center
- double distance2=(camPos[0]-center[0])*(camPos[0]-center[0])+
- (camPos[1]-center[1])*(camPos[1]-center[1]) +
- (camPos[2]-center[2])*(camPos[2]-center[2]);
-
- i=0;
- while(i<6)
- {
- blocks[blockId].Bounds[i]=blockBounds[i];
- blocks[blockId].Extent[i]=blockExtent[i];
- ++i;
- }
-
- sortedBlocks[blockId].Id=blockId;
- sortedBlocks[blockId].Distance2=distance2;
-
- ++blockId;
-
- blockExtent[0]=blockExtent[1];
- blockExtent[1]=blockExtent[0]+textureSize[0];
- if(!this->CellFlag)
- {
- blockExtent[1]--;
- }
- if(blockExtent[1]>realExtent[1])
- {
- blockExtent[1]=realExtent[1];
- }
- ++xIndex;
- } // while x
-
- blockExtent[2]=blockExtent[3];
- blockExtent[3]=blockExtent[2]+textureSize[1];
- if(!this->CellFlag)
- {
- blockExtent[3]--;
- }
- if(blockExtent[3]>realExtent[3])
- {
- blockExtent[3]=realExtent[3];
- }
- ++yIndex;
- } // while y
-
-
- blockExtent[4]=blockExtent[5];
- blockExtent[5]=blockExtent[4]+textureSize[2];
- if(!this->CellFlag)
- {
- blockExtent[5]--;
- }
- if(blockExtent[5]>realExtent[5])
- {
- blockExtent[5]=realExtent[5];
- }
- ++zIndex;
- } // while z
-
- assert("check: valid_number_of_blocks" && blockId==count);
-
- qsort(sortedBlocks,static_cast<size_t>(count),
- sizeof(vtkRegionDistance2),
- vtkRegionComparisonFunction);
-
- // loop over all blocks we need to render
- i=0;
- int abort=0;
- while(!abort && i < count) // 1) //count)
- {
- size_t k=sortedBlocks[i].Id;
-
- int blockTextureExtent[6];
- int j;
- if(this->CellFlag) // 3D texture are celldata
- {
- // texture extents are expressed in cells in this case
- j=0;
- while(j<6)
- {
- blockTextureExtent[j]=vtkMath::Floor(blocks[k].Extent[j]);
- ++j;
- }
- }
- else
- {
- // texture extents are expressed in points in this case
- j=0;
- while(j<6)
- {
- blockTextureExtent[j]=vtkMath::Floor(blocks[k].Extent[j]);
- ++j;
- blockTextureExtent[j]=vtkMath::Floor(blocks[k].Extent[j]);
- if(blockTextureExtent[j]<blocks[k].Extent[j])
- {
- ++blockTextureExtent[j];
- }
- ++j;
- }
- }
-
- // Load the block
- if(!this->LoadScalarField(this->GetInput(),this->MaskInput, blockTextureExtent,
- volume))
- {
- cout<<"Loading the streamed block FAILED!!!!!"<<endl;
- }
-
- loadedExtent=this->CurrentScalar->GetLoadedExtent();
-
- float lowBounds[3];
- float highBounds[3];
- if(!this->CurrentScalar->GetLoadedCellFlag()) // points
- {
- j=0;
- while(j<3)
- {
- double delta=
- static_cast<double>(loadedExtent[j*2+1]-loadedExtent[j*2]);
- lowBounds[j]=static_cast<float>((blocks[k].Extent[j*2]-static_cast<double>(loadedExtent[j*2]))/delta);
- highBounds[j]=static_cast<float>((blocks[k].Extent[j*2+1]-static_cast<double>(loadedExtent[j*2]))/delta);
- ++j;
- }
- }
- else // cells
- {
- j=0;
- while(j<3)
- {
- double delta=
- static_cast<double>(loadedExtent[j*2+1]-loadedExtent[j*2]);
- lowBounds[j]=static_cast<float>((blocks[k].Extent[j*2]-0.5-static_cast<double>(loadedExtent[j*2]))/delta);
- highBounds[j]=static_cast<float>((blocks[k].Extent[j*2+1]-0.5-static_cast<double>(loadedExtent[j*2]))/delta);
- ++j;
- }
- }
-
-
-
-
- // bounds have to be normalized. There are used in the shader
- // as bounds to a value used to sample a texture.
-
- assert("check: positive_low_bounds0" && lowBounds[0]>=0.0);
- assert("check: positive_low_bounds1" && lowBounds[1]>=0.0);
- assert("check: positive_low_bounds2" && lowBounds[2]>=0.0);
-
- assert("check: increasing_bounds0" && lowBounds[0]<=highBounds[0]);
- assert("check: increasing_bounds1" && lowBounds[1]<=highBounds[1]);
- assert("check: increasing_bounds2" && lowBounds[2]<=highBounds[2]);
- assert("check: high_bounds0_less_than1" && highBounds[0]<=1.0);
- assert("check: high_bounds1_less_than1" && highBounds[1]<=1.0);
- assert("check: high_bounds2_less_than1" && highBounds[2]<=1.0);
-
- GLint lb;
- lb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
- "lowBounds");
-
- this->PrintError("get uniform low bounds");
- if(lb!=-1)
- {
- vtkgl::Uniform3f(lb, lowBounds[0],lowBounds[1],lowBounds[2]);
- this->PrintError("set uniform low bounds");
- }
- else
- {
- vtkErrorMacro(<<" lowBounds is not a uniform variable.");
- }
- GLint hb;
- hb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
- "highBounds");
- this->PrintError("get uniform high bounds");
- if(hb!=-1)
- {
- vtkgl::Uniform3f(hb, highBounds[0],highBounds[1],highBounds[2]);
- this->PrintError("set uniform high bounds");
- }
- else
- {
- vtkErrorMacro(<<" highBounds is not a uniform variable.");
- }
-
- this->PrintError("uniform low/high bounds block");
- // other sub-volume rendering code
- this->LoadProjectionParameters(ren,volume);
- this->ClipBoundingBox(ren,blocks[k].Bounds,volume);
- abort=this->RenderClippedBoundingBox(1,i,count,ren->GetRenderWindow());
- if (!abort)
- {
- this->CopyFBOToTexture();
- }
- this->PrintError("render clipped block 1");
-
-
-
- ++i;
- }
-
- delete[] blocks;
- delete[] sortedBlocks;
- return abort;
- }
- }
- }
-
- loadedExtent=this->CurrentScalar->GetLoadedExtent();
-
- // low bounds and high bounds are in texture coordinates.
- float lowBounds[3];
- float highBounds[3];
- if(!this->CurrentScalar->GetLoadedCellFlag()) // points
- {
- i=0;
- while(i<3)
- {
- double delta=
- static_cast<double>(loadedExtent[i*2+1]-loadedExtent[i*2]+1);
- lowBounds[i]=static_cast<float>((realExtent[i*2]+0.5-static_cast<double>(loadedExtent[i*2]))/delta);
- highBounds[i]=static_cast<float>((realExtent[i*2+1]+0.5-static_cast<double>(loadedExtent[i*2]))/delta);
- ++i;
- }
- }
- else // cells
- {
- i=0;
- while(i<3)
- {
- double delta=
- static_cast<double>(loadedExtent[i*2+1]-loadedExtent[i*2]+1);
-
- // this->LoadedExtent[i*2]==0, texcoord starts at 0, if realExtent==0
- // otherwise, texcoord start at 1/2N
- // this->LoadedExtent[i*2]==wholeTextureExtent[i*2+1], texcoord stops at 1, if realExtent==wholeTextureExtent[i*2+1]+1
- // otherwise it stop at 1-1/2N
- // N is the number of texels in the loadedtexture not the number of
- // texels in the whole texture.
-
- lowBounds[i]=static_cast<float>((realExtent[i*2]-static_cast<double>(loadedExtent[i*2]))/delta);
- highBounds[i]=static_cast<float>((realExtent[i*2+1]-static_cast<double>(loadedExtent[i*2]))/delta);
- ++i;
- }
- }
-
- assert("check: positive_low_bounds0" && lowBounds[0]>=0.0);
- assert("check: positive_low_bounds1" && lowBounds[1]>=0.0);
- assert("check: positive_low_bounds2" && lowBounds[2]>=0.0);
-
- assert("check: increasing_bounds0" && lowBounds[0]<=highBounds[0]);
- assert("check: increasing_bounds1" && lowBounds[1]<=highBounds[1]);
- assert("check: increasing_bounds2" && lowBounds[2]<=highBounds[2]);
- assert("check: high_bounds0_less_than1" && highBounds[0]<=1.0);
- assert("check: high_bounds1_less_than1" && highBounds[1]<=1.0);
- assert("check: high_bounds2_less_than1" && highBounds[2]<=1.0);
-
- GLint lb;
- lb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
- "lowBounds");
-
- this->PrintError("get uniform low bounds");
- if(lb!=-1)
- {
- vtkgl::Uniform3f(lb, lowBounds[0],lowBounds[1],lowBounds[2]);
- this->PrintError("set uniform low bounds");
- }
- else
- {
- vtkErrorMacro(<<" lowBounds is not a uniform variable.");
- }
- GLint hb;
- hb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
- "highBounds");
- this->PrintError("get uniform high bounds");
- if(hb!=-1)
- {
- vtkgl::Uniform3f(hb, highBounds[0],highBounds[1],highBounds[2]);
- this->PrintError("set uniform high bounds");
- }
- else
- {
- vtkErrorMacro(<<" highBounds is not a uniform variable.");
- }
-
- this->PrintError("uniform low/high bounds");
- // other sub-volume rendering code
- this->LoadProjectionParameters(ren,volume);
- this->ClipBoundingBox(ren,bounds,volume);
- int abort=this->RenderClippedBoundingBox(1,0,1,ren->GetRenderWindow());
- if (!abort)
- {
- this->CopyFBOToTexture();
- }
- this->PrintError("render clipped 1");
- return abort;
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::LoadProjectionParameters(
- vtkRenderer *ren,
- vtkVolume *vol)
-{
- vtkMatrix4x4 *worldToDataset=vol->GetMatrix();
- vtkMatrix4x4 *datasetToWorld=this->TempMatrix[0];
- vtkMatrix4x4::Invert(worldToDataset,datasetToWorld);
-
- double *bounds=this->CurrentScalar->GetLoadedBounds();
-
- double dx=bounds[1]-bounds[0];
- double dy=bounds[3]-bounds[2];
- double dz=bounds[5]-bounds[4];
-
- // worldToTexture matrix is needed
-
- // Compute change-of-coordinate matrix from world space to texture space.
- vtkMatrix4x4 *worldToTexture=this->TempMatrix[2];
- vtkMatrix4x4 *datasetToTexture=this->TempMatrix[1];
-
- // Set the matrix
- datasetToTexture->Zero();
- datasetToTexture->SetElement(0,0,dx);
- datasetToTexture->SetElement(1,1,dy);
- datasetToTexture->SetElement(2,2,dz);
- datasetToTexture->SetElement(3,3,1.0);
- datasetToTexture->SetElement(0,3,bounds[0]);
- datasetToTexture->SetElement(1,3,bounds[2]);
- datasetToTexture->SetElement(2,3,bounds[4]);
-
- // worldToTexture=worldToDataSet*dataSetToTexture
- vtkMatrix4x4::Multiply4x4(worldToDataset,datasetToTexture,worldToTexture);
-
- // NEW
- int parallelProjection=ren->GetActiveCamera()->GetParallelProjection();
-
-// cout << "actualSampleDistance=" << this->ActualSampleDistance << endl;
-
- if(parallelProjection)
- {
- // Unit vector of the direction of projection in world space.
- double dirWorld[4];
- double dir[4];
- ren->GetActiveCamera()->GetDirectionOfProjection(dirWorld);
- dirWorld[3]=0.0;
-
- // direction in dataset space.
- datasetToWorld->MultiplyPoint(dirWorld,dir);
-
- // incremental vector:
- // direction in texture space times sample distance in world space.
- dir[0]=dir[0]*this->ActualSampleDistance/dx;
- dir[1]=dir[1]*this->ActualSampleDistance/dy;
- dir[2]=dir[2]*this->ActualSampleDistance/dz;
-
- GLint rayDir;
- rayDir=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"parallelRayDirection");
- if(rayDir!=-1)
- {
- vtkgl::Uniform3f(rayDir,static_cast<GLfloat>(dir[0]),
- static_cast<GLfloat>(dir[1]),
- static_cast<GLfloat>(dir[2]));
- }
- else
- {
- vtkErrorMacro(<<"parallelRayDirection is not a uniform variable.");
- }
- //cout<<"rayDir="<<dir[0]<<","<<dir[1]<<","<<dir[2]<<endl;
- }
- else
- {
- // Perspective projection
-
- // Compute camera position in texture coordinates
- // Position of the center of the camera in world frame
- double cameraPosWorld[4];
- // Position of the center of the camera in the dataset frame
- // (the transform of the volume is taken into account)
- double cameraPosDataset[4];
- // Position of the center of the camera in the texture frame
- // the coordinates are translated and rescaled
- double cameraPosTexture[4];
-
- ren->GetActiveCamera()->GetPosition(cameraPosWorld);
- cameraPosWorld[3]=1.0; // we use homogeneous coordinates.
-
- datasetToWorld->MultiplyPoint(cameraPosWorld,cameraPosDataset);
-
- // From homogeneous to cartesian coordinates.
- if(cameraPosDataset[3]!=1.0)
- {
- double ratio=1/cameraPosDataset[3];
- cameraPosDataset[0]*=ratio;
- cameraPosDataset[1]*=ratio;
- cameraPosDataset[2]*=ratio;
- }
-
- cameraPosTexture[0] = (cameraPosDataset[0]-bounds[0])/dx;
- cameraPosTexture[1] = (cameraPosDataset[1]-bounds[2])/dy;
- cameraPosTexture[2] = (cameraPosDataset[2]-bounds[4])/dz;
-
- // Only make sense for the vectorial part of the homogeneous matrix.
- // coefMatrix=transposeWorldToTexture*worldToTexture
- // we re-cycle the datasetToWorld pointer with a different name
- vtkMatrix4x4 *transposeWorldToTexture=this->TempMatrix[1];
- // transposeWorldToTexture={^t}worldToTexture
- vtkMatrix4x4::Transpose(worldToTexture,transposeWorldToTexture);
-
- vtkMatrix4x4 *coefMatrix=this->TempMatrix[1];
- vtkMatrix4x4::Multiply4x4(transposeWorldToTexture,worldToTexture,
- coefMatrix);
- GLint uCameraPosition;
-
- uCameraPosition=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"cameraPosition");
-
- if(uCameraPosition!=-1)
- {
- vtkgl::Uniform3f(uCameraPosition,
- static_cast<GLfloat>(cameraPosTexture[0]),
- static_cast<GLfloat>(cameraPosTexture[1]),
- static_cast<GLfloat>(cameraPosTexture[2]));
- }
- else
- {
- vtkErrorMacro(<<"cameraPosition is not a uniform variable.");
- }
- GLint uSampleDistance;
- uSampleDistance=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"sampleDistance");
-
- if(uSampleDistance!=-1)
- {
- vtkgl::Uniform1f(uSampleDistance,this->ActualSampleDistance);
- }
- else
- {
- vtkErrorMacro(<<"sampleDistance is not a uniform variable.");
- }
-
- GLint uMatrix1;
-
- uMatrix1=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"matrix1");
-
- if(uMatrix1!=-1)
- {
- vtkgl::Uniform3f(uMatrix1,
- static_cast<GLfloat>(coefMatrix->GetElement(0,0)),
- static_cast<GLfloat>(coefMatrix->GetElement(1,1)),
- static_cast<GLfloat>(coefMatrix->GetElement(2,2)));
- }
- else
- {
- vtkErrorMacro(<<"matrix1 is not a uniform variable.");
- }
- GLint uMatrix2;
- uMatrix2=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"matrix2");
-
- if(uMatrix2!=-1)
- {
- vtkgl::Uniform3f(uMatrix2,
- static_cast<GLfloat>(2*coefMatrix->GetElement(0,1)),
- static_cast<GLfloat>(2*coefMatrix->GetElement(1,2)),
- static_cast<GLfloat>(2*coefMatrix->GetElement(0,2)));
- }
- else
- {
- vtkErrorMacro(<<"matrix2 is not a uniform variable.");
- }
- }
- this->PrintError("after uniforms for projection");
-
- // Change-of-coordinate matrix from Eye space to texture space.
- vtkMatrix4x4 *eyeToTexture=this->TempMatrix[1];
- vtkMatrix4x4 *eyeToWorld=ren->GetActiveCamera()->GetViewTransformMatrix();
-
- vtkMatrix4x4::Multiply4x4(eyeToWorld,worldToTexture,eyeToTexture);
-
- GLfloat matrix[16];// used sometimes as 3x3, sometimes as 4x4.
- double *raw=eyeToTexture->Element[0];
- int index;
- int column;
- int row;
-
- int shadeMethod=this->LastShade;
-
- if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes)
- {
- index=0;
- column=0;
- while(column<3)
- {
- row=0;
- while(row<3)
- {
-// cout << "index=" << index << " row*4+column=" << row*4+column << endl;
- matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
- ++index;
- ++row;
- }
- ++column;
- }
- GLint uEyeToTexture3;
-
- uEyeToTexture3=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"eyeToTexture3");
-
- this->PrintError("after getUniform eyeToTexture3");
-
- if(uEyeToTexture3!=-1)
- {
- vtkgl::UniformMatrix3fv(uEyeToTexture3,1,GL_FALSE,matrix);
- }
- else
- {
- vtkErrorMacro(<<"eyeToTexture3 is not a uniform variable.");
- }
- this->PrintError("after Uniform eyeToTexture3");
-
- index=0;
- column=0;
- while(column<4)
- {
- row=0;
- while(row<4)
- {
-// cout << "index=" << index << " row*4+column=" << row*4+column << endl;
- matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
- ++index;
- ++row;
- }
- ++column;
- }
- GLint uEyeToTexture4;
-
- uEyeToTexture4=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"eyeToTexture4");
-
- if(uEyeToTexture4!=-1)
- {
- vtkgl::UniformMatrix4fv(uEyeToTexture4,1,GL_FALSE,matrix);
- }
- else
- {
- vtkErrorMacro(<<"eyeToTexture4 is not a uniform variable.");
- }
- }
-
- eyeToTexture->Invert();
-
- index=0;
- column=0;
- while(column<4)
- {
- row=0;
- while(row<4)
- {
-// cout << "index=" << index << " row*4+column=" << row*4+column << endl;
- matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
- ++index;
- ++row;
- }
- ++column;
- }
-
- this->PrintError("before GetUniformLocation TextureToEye");
- GLint uTextureToEye;
-
- uTextureToEye=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"textureToEye");
-
- this->PrintError("after GetUniformLocation TextureToEye");
- if(uTextureToEye!=-1)
- {
- vtkgl::UniformMatrix4fv(uTextureToEye,1,GL_FALSE,matrix);
- }
- else
- {
- vtkErrorMacro(<<"textureToEye is not a uniform variable.");
- }
- this->PrintError("after UniformMatrxix TextureToEye");
-
- if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes)
- {
- eyeToTexture->Transpose();
-
- index=0;
- column=0;
- while(column<3)
- {
- row=0;
- while(row<3)
- {
-// cout << "index=" << index << " row*4+column=" << row*4+column << endl;
- matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
- ++index;
- ++row;
- }
- ++column;
- }
- GLint uTranposeTextureToEye;
- uTranposeTextureToEye=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"transposeTextureToEye");
-
- if(uTranposeTextureToEye!=-1)
- {
- vtkgl::UniformMatrix3fv(uTranposeTextureToEye,1,GL_FALSE,matrix);
- }
- else
- {
- vtkErrorMacro(<<"transposeTextureToEye is not a uniform variable.");
- }
-
- float cellScale[3]; // 1/(2*Step)
- float cellStep[3]; // Step
-
- vtkIdType *loadedExtent=this->CurrentScalar->GetLoadedExtent();
- cellScale[0]=static_cast<float>(static_cast<double>(
- loadedExtent[1]-loadedExtent[0])*0.5);
- cellScale[1]=static_cast<float>(static_cast<double>(
- loadedExtent[3]-loadedExtent[2])*0.5);
- cellScale[2]=static_cast<float>(static_cast<double>(
- loadedExtent[5]-loadedExtent[4])*0.5);
- cellStep[0]=static_cast<float>(1.0/static_cast<double>(
- loadedExtent[1]-loadedExtent[0]));
- cellStep[1]=static_cast<float>(1.0/static_cast<double>(
- loadedExtent[3]-loadedExtent[2]));
- cellStep[2]=static_cast<float>(1.0/static_cast<double>(
- loadedExtent[5]-loadedExtent[4]));
-
- GLint uCellScale;
- uCellScale=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"cellScale");
- if(uCellScale!=-1)
- {
- vtkgl::Uniform3f(uCellScale,cellScale[0],cellScale[1],cellScale[2]);
- }
- else
- {
- vtkErrorMacro(<<"error: cellScale is not a uniform variable.");
- }
- GLint uCellStep;
-
- uCellStep=vtkgl::GetUniformLocation(
- static_cast<GLuint>(this->ProgramShader),"cellStep");
-
- if(uCellStep!=-1)
- {
- vtkgl::Uniform3f(uCellStep,cellStep[0],cellStep[1],cellStep[2]);
- }
- else
- {
- vtkErrorMacro(<<"error: cellStep is not a uniform variable.");
- }
- }
-
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Concatenate the header string, projection type code and method to the
-// final fragment code in this->FragmentCode.
-// \pre valid_raycastMethod: raycastMethod>=
-// vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP &&
-// raycastMethod<=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::BuildProgram(int parallelProjection,
- int raycastMethod,
- int shadeMethod,
- int componentMethod)
-{
-
- assert("pre: valid_raycastMethod" &&
- raycastMethod>= vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP
- && raycastMethod<=vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask);
- GLuint fs;
-
-// cout<<"projection="<<parallelProjection<<endl;
-// cout<<"method="<<raycastMethod<<endl;
- if(parallelProjection!=this->LastParallelProjection)
- {
- // update projection
- const char *projectionCode;
- if(parallelProjection)
- {
- projectionCode=vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS;
- }
- else
- {
- projectionCode=vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS;
- }
-
- fs=static_cast<GLuint>(this->FragmentProjectionShader);
- vtkgl::ShaderSource(fs,1,const_cast<const char **>(&projectionCode),0);
- vtkgl::CompileShader(fs);
- this->CheckCompilation(this->FragmentProjectionShader);
- }
-
- if(raycastMethod!=this->LastRayCastMethod)
- {
- // update tracing method
- const char *methodCode;
- switch(raycastMethod)
- {
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP:
- methodCode=vtkMitkGPUVolumeRayCastMapper_MIPFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent:
- methodCode=vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite:
- methodCode=vtkMitkGPUVolumeRayCastMapper_CompositeFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask:
- methodCode=vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP:
- methodCode=vtkMitkGPUVolumeRayCastMapper_MinIPFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent:
- methodCode=vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS;
- break;
- }
- fs=static_cast<GLuint>(this->FragmentTraceShader);
- vtkgl::ShaderSource(fs,1,const_cast<const char **>(&methodCode),0);
- vtkgl::CompileShader(fs);
- this->CheckCompilation(this->FragmentTraceShader);
- }
-
- // update cropping method
- int croppingMode;
- switch(raycastMethod)
- {
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP:
- if(this->NumberOfCroppingRegions>1)
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMIPCropping;
- }
- else
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMIPNoCropping;
- }
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent:
- if(this->NumberOfCroppingRegions>1)
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentCropping;
- }
- else
- {
- croppingMode=
- vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentNoCropping;
- }
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP:
- if(this->NumberOfCroppingRegions>1)
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMinIPCropping;
- }
- else
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMinIPNoCropping;
- }
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent:
- if(this->NumberOfCroppingRegions>1)
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentCropping;
- }
- else
- {
- croppingMode=
- vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentNoCropping;
- }
- break;
- default:
- if(this->NumberOfCroppingRegions>1)
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperCompositeCropping;
- }
- else
- {
- croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperCompositeNoCropping;
- }
- break;
- }
-
-// cout<<"croppingMode="<<croppingMode<<endl;
- if(croppingMode!=this->LastCroppingMode)
- {
- const char *croppingCode;
- switch(croppingMode)
- {
- case vtkMitkOpenGLGPUVolumeRayCastMapperMIPCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMIPNoCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentNoCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperCompositeCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperCompositeNoCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPNoCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS;
- break;
- case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentNoCropping:
- croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS;
- break;
- }
-
- fs=static_cast<GLuint>(this->FragmentCroppingShader);
- vtkgl::ShaderSource(fs,1,const_cast<const char **>(&croppingCode),0);
- vtkgl::CompileShader(fs);
-
- this->CheckCompilation(this->FragmentCroppingShader);
- }
-
- if(componentMethod!=this->LastComponent)
- {
- fs=static_cast<GLuint>(this->FragmentComponentShader);
- GLuint programShader=static_cast<GLuint>(this->ProgramShader);
- if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed)
- {
- if(this->LastComponent!=
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized)
- {
- vtkgl::DetachShader(programShader,fs);
- }
- }
- else
- {
- if(this->LastComponent==
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized ||
- this->LastComponent==
- vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed)
- {
- vtkgl::AttachShader(programShader,fs);
- }
- const char *componentCode;
- if(componentMethod==vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne)
- {
- componentCode=vtkMitkGPUVolumeRayCastMapper_OneComponentFS;
- }
- else
- {
- componentCode=vtkMitkGPUVolumeRayCastMapper_FourComponentsFS;
- }
- vtkgl::ShaderSource(fs,1,const_cast<const char **>(&componentCode),0);
- vtkgl::CompileShader(fs);
- this->CheckCompilation(this->FragmentComponentShader);
- }
- }
-
- if(shadeMethod!=this->LastShade)
- {
- fs=static_cast<GLuint>(this->FragmentShadeShader);
- GLuint programShader=static_cast<GLuint>(this->ProgramShader);
- if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed)
- {
- if(this->LastShade!=
- vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized)
- {
- vtkgl::DetachShader(programShader,fs);
- }
- }
- else
- {
- if(this->LastShade==vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized
- || this->LastShade==vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed)
- {
- vtkgl::AttachShader(programShader,fs);
- }
- const char *shadeCode;
- if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes)
- {
- shadeCode=vtkMitkGPUVolumeRayCastMapper_ShadeFS;
- }
- else
- {
- shadeCode=vtkMitkGPUVolumeRayCastMapper_NoShadeFS;
- }
- vtkgl::ShaderSource(fs,1,const_cast<const char **>(&shadeCode),0);
- vtkgl::CompileShader(fs);
- this->CheckCompilation(this->FragmentShadeShader);
- }
- }
-
- if(parallelProjection!=this->LastParallelProjection ||
- raycastMethod!=this->LastRayCastMethod ||
- croppingMode!=this->LastCroppingMode ||
- componentMethod!=this->LastComponent ||
- shadeMethod!=this->LastShade)
- {
- // need to re-link the program
- this->LastParallelProjection=parallelProjection;
- this->LastRayCastMethod=raycastMethod;
- this->LastCroppingMode=croppingMode;
- this->LastComponent=componentMethod;
- this->LastShade=shadeMethod;
-
- vtkgl::LinkProgram(static_cast<GLuint>(this->ProgramShader));
- }
-}
-
-// ----------------------------------------------------------------------------
-// Description:
-// Is the program shader valid in the current OpenGL state?
-// Debugging purpose only.
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::ValidateProgram()
-{
- vtkgl::ValidateProgram(this->ProgramShader);
-
- GLint params;
- vtkgl::GetProgramiv(this->ProgramShader,
- vtkgl::VALIDATE_STATUS,&params);
- if(params==GL_TRUE)
- {
- cout<<"In the current state the fragment program will succeed."<<endl;
- }
- else
- {
- cout<<"In the current state the fragment program will fail."<<endl;
- }
- vtkgl::GetProgramiv(this->ProgramShader,
- vtkgl::INFO_LOG_LENGTH,&params);
-
- if(params>0)
- {
- char *buffer=new char[params];
- vtkgl::GetProgramInfoLog(this->ProgramShader,params,0,buffer);
- cout<<"validation log: "<<buffer<<endl;
- cout<<"end of validation log"<<endl;
- delete[] buffer;
- }
- else
- {
- cout<<"no validation log"<<endl;
- }
-
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-const char *vtkMitkOpenGLGPUVolumeRayCastMapper::GetEnabledString(
- unsigned char value)
-{
- if(value)
- {
- return "enabled";
- }
- else
- {
- return "disabled";
- }
-}
-
-//-----------------------------------------------------------------------------
-// Display current OpenGL state
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::GetOpenGLState()
-{
- cout<<"lighting:"<<this->GetEnabledString(glIsEnabled(GL_LIGHTING))<<endl;
- cout<<"lighting:"<<this->GetEnabledString(glIsEnabled(GL_LIGHTING))<<endl;
-
- // save current active texture.
- GLint value;
- glGetIntegerv(vtkgl::ACTIVE_TEXTURE,&value);
- GLenum activeTexture=static_cast<GLenum>(value);
- cout<<"active texture is "<<(activeTexture-vtkgl::TEXTURE0)<<endl;
-
- // iterative over all textures.
-
- GLenum texture=vtkgl::TEXTURE0;
- while(texture<vtkgl::TEXTURE6)
- {
- vtkgl::ActiveTexture(texture);
- cout<<"texture"<<texture-vtkgl::TEXTURE0<<endl;
- cout<<"1d:"<<GetEnabledString(glIsEnabled(GL_TEXTURE_1D))<<endl;
- cout<<"2d:"<<GetEnabledString(glIsEnabled(GL_TEXTURE_2D))<<endl;
- cout<<"3d:"<<GetEnabledString(glIsEnabled(vtkgl::TEXTURE_3D_EXT))<<endl;
- glGetIntegerv(GL_TEXTURE_BINDING_1D,&value);
- cout<<"binding 1d:"<<value<<endl;
- glGetIntegerv(GL_TEXTURE_BINDING_2D,&value);
- cout<<"binding 2d:"<<value<<endl;
- glGetIntegerv(vtkgl::TEXTURE_BINDING_3D,&value);
- cout<<"binding 3d:"<<value<<endl;
- ++texture;
- }
-
- // restore current active texture
- vtkgl::ActiveTexture(activeTexture);
-}
-
-//-----------------------------------------------------------------------------
-// Return the current OpenGL state about lighting.
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::GetLightingStatus()
-{
- //cout<<"lighting: ";
- GLboolean flag=glIsEnabled(GL_LIGHTING);
- if(flag)
- {
- cout<<"enabled"<<endl;
- }
- else
- {
- cout<<"disabled"<<endl;
- }
- GLint value;
- glGetIntegerv(GL_MAX_LIGHTS,&value);
- cout<<"number of lights supported by this GPU:"<<value<<endl;
-
- float values[4];
- glGetFloatv(GL_LIGHT_MODEL_AMBIENT,values);
-
- cout<<"light model ambient="<<values[0]<<","<<values[1]<<","<<values[2]
- <<","<<values[3]<<endl;
-
- unsigned int i=0;
- unsigned int c=static_cast<unsigned int>(value);
-
- cout<<"light\t| status\t| ambient\t| diffuse\t| specular\t| position\t| spot direction\t| spot exponent\t| spot cutoff\t| k0\t| k1\t| k2"<<endl;
-
- while(i<c)
- {
- cout<<i<<"\t| ";
- glIsEnabled(GL_LIGHT0+i);
- if(flag)
- {
- cout<<"enabled";
- }
- else
- {
- cout<<"disabled";
- }
-
- glGetLightfv(GL_LIGHT0+i,GL_AMBIENT,values);
- cout<<"\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
- glGetLightfv(GL_LIGHT0+i,GL_DIFFUSE,values);
- cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
- glGetLightfv(GL_LIGHT0+i,GL_SPECULAR,values);
- cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
- glGetLightfv(GL_LIGHT0+i,GL_POSITION,values);
- cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
- glGetLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,values);
- cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2];
- glGetLightfv(GL_LIGHT0+i,GL_SPOT_EXPONENT,values);
- cout<<")\t| "<<values[0];
- glGetLightfv(GL_LIGHT0+i,GL_SPOT_CUTOFF,values);
- cout<<"\t| "<<values[0];
- glGetLightfv(GL_LIGHT0+i,GL_CONSTANT_ATTENUATION,values);
- cout<<"\t| "<<values[0];
- glGetLightfv(GL_LIGHT0+i,GL_LINEAR_ATTENUATION,values);
- cout<<"\t| "<<values[0];
- glGetLightfv(GL_LIGHT0+i,GL_QUADRATIC_ATTENUATION,values);
- cout<<"\t| "<<values[0]<<endl;
- ++i;
- }
-
- cout<<"color material=";
- flag=glIsEnabled(GL_COLOR_MATERIAL);
- if(flag)
- {
- cout<<"enabled"<<endl;
- }
- else
- {
- cout<<"disabled"<<endl;
- }
-
- cout<<"color material face=";
- GLint ivalue[4];
- glGetIntegerv(GL_COLOR_MATERIAL_FACE,ivalue); // 2.14.3
- switch(ivalue[0])
- {
- case GL_FRONT_AND_BACK:
- cout<<"GL_FRONT_AND_BACK";
- break;
- case GL_FRONT:
- cout<<"GL_FRONT";
- break;
- case GL_BACK:
- cout<<"GL_BACK";
- break;
- default:
- cout<<"unknown value="<<ivalue[0]<<endl;
- break;
- }
-
- cout<<"color material parameter=";
- glGetIntegerv(GL_COLOR_MATERIAL_PARAMETER,ivalue); // 2.14.3
- switch(ivalue[0])
- {
- case GL_AMBIENT_AND_DIFFUSE:
- cout<<"GL_AMBIENT_AND_DIFFUSE";
- break;
- case GL_AMBIENT:
- cout<<"GL_AMBIENT";
- break;
- case GL_DIFFUSE:
- cout<<"GL_DIFFUSE";
- break;
- case GL_EMISSION:
- cout<<"GL_EMISSION";
- break;
- case GL_SPECULAR:
- cout<<"GL_SPECULAR";
- break;
- default:
- cout<<"unknown value="<<ivalue[0]<<endl;
- break;
- }
-
- GLfloat fcolor[4];
- glGetMaterialfv(GL_FRONT,GL_EMISSION,fcolor);
- cout<<"front emission="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
- glGetMaterialfv(GL_FRONT,GL_AMBIENT,fcolor);
- cout<<"front ambient="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
- glGetMaterialfv(GL_FRONT,GL_DIFFUSE,fcolor);
- cout<<"front diffuse="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
- glGetMaterialfv(GL_FRONT,GL_SPECULAR,fcolor);
- cout<<"front specular="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
-}
-
-
-//-----------------------------------------------------------------------------
-// Compute y=2^n such that x<=y.
-// \pre positive_x: x>=0
-// \post valid_result: result>=x
-//-----------------------------------------------------------------------------
-int vtkMitkOpenGLGPUVolumeRayCastMapper::PowerOfTwoGreaterOrEqual(int x)
-{
- assert("pre: positive_x" && x>=0);
-
- int result=1;
- while(result<x)
- {
- result<<=1; // *2
- }
- assert("post: valid_result" && result>=x);
- return result;
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::UpdateNoiseTexture()
-{
- if(this->NoiseTextureId==0)
- {
- GLuint noiseTextureObject;
- glGenTextures(1,&noiseTextureObject);
- this->NoiseTextureId=static_cast<unsigned int>(noiseTextureObject);
- vtkgl::ActiveTexture(vtkgl::TEXTURE6);
- glBindTexture(GL_TEXTURE_2D,noiseTextureObject);
-
- GLsizei size=128; // 1024; // Power of two value
- GLint maxSize;
- const float factor=0.1f;
-// const float factor=1.0f;
- const float amplitude=0.5f*factor; // something positive.
- // amplitude=0.5. noise between -0.5 +0.5. add some +0.5 shift.
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSize);
- if(size>maxSize)
- {
- size=maxSize;
- }
- if(this->NoiseTexture!=0 && this->NoiseTextureSize!=size)
- {
- delete[] this->NoiseTexture;
- this->NoiseTexture=0;
- }
- if(this->NoiseTexture==0)
- {
- this->NoiseTexture=new float[size*size];
- this->NoiseTextureSize=size;
- vtkPerlinNoise *noiseGenerator=vtkPerlinNoise::New();
- noiseGenerator->SetFrequency(size,1.0,1.0);
- noiseGenerator->SetPhase(0.0,0.0,0.0);
- noiseGenerator->SetAmplitude(amplitude);
- int j=0;
- while(j<size)
- {
- int i=0;
- while(i<size)
- {
- this->NoiseTexture[j*size+i]=0.0; //amplitude+static_cast<float>(noiseGenerator->EvaluateFunction(i,j,0.0));
- ++i;
- }
- ++j;
- }
- noiseGenerator->Delete();
- }
- glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,size,size,0,GL_RED,GL_FLOAT,
- this->NoiseTexture);
-
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
- GLfloat borderColor[4]={0.0,0.0,0.0,0.0};
- glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,borderColor);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- vtkgl::ActiveTexture(vtkgl::TEXTURE0);
- }
-}
-
-// ----------------------------------------------------------------------------
-// Description:
-// Return how much the dataset has to be reduced in each dimension to
-// fit on the GPU. If the value is 1.0, there is no need to reduce the
-// dataset.
-// \pre the calling thread has a current OpenGL context.
-// \pre mapper_supported: IsRenderSupported(renderer->GetRenderWindow(),0)
-// The computation is based on hardware limits (3D texture indexable size)
-// and MaxMemoryInBytes.
-// \post valid_i_ratio: ratio[0]>0 && ratio[0]<=1.0
-// \post valid_j_ratio: ratio[1]>0 && ratio[1]<=1.0
-// \post valid_k_ratio: ratio[2]>0 && ratio[2]<=1.0
-void vtkMitkOpenGLGPUVolumeRayCastMapper::GetReductionRatio(double ratio[3])
-{
- // Compute texture size
- int i;
- int wholeTextureExtent[6];
- this->GetInput()->GetExtent(wholeTextureExtent);
- if(this->CellFlag) // if we deal with cell data
- {
- i=1;
- while(i<6)
- {
- wholeTextureExtent[i]--;
- i+=2;
- }
- }
-
- // Indexable hardware limits
- GLint maxSize;
- glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&maxSize);
-
- vtkIdType rTextureSize[3];
- double dMaxSize=static_cast<double>(maxSize);
- i=0;
- while(i<3)
- {
- double textureSize=wholeTextureExtent[2*i+1]-wholeTextureExtent[2*i]+1;
- if(textureSize>maxSize)
- {
- ratio[i]=dMaxSize/textureSize;
- }
- else
- {
- ratio[i]=1.0; // no reduction
- }
- rTextureSize[i]=static_cast<vtkIdType>(floor(textureSize*ratio[i]));
- ++i;
- }
-
- // Data memory limits.
-
- vtkDataArray *scalars=this->GetScalars(this->GetInput(),this->ScalarMode,
- this->ArrayAccessMode,
- this->ArrayId,
- this->ArrayName,
- this->CellFlag);
- int scalarType=scalars->GetDataType();
-
- vtkIdType size=rTextureSize[0]*rTextureSize[1]*rTextureSize[2]
- *vtkAbstractArray::GetDataTypeSize(scalarType)
- *scalars->GetNumberOfComponents();
-
- if(size>static_cast<double>(this->MaxMemoryInBytes)
- *static_cast<double>(this->MaxMemoryFraction))
- {
- double r=static_cast<double>(this->MaxMemoryInBytes)
- *static_cast<double>(this->MaxMemoryFraction)/static_cast<double>(size);
- double r3=pow(r,1.0/3.0);
- // try the keep reduction ratio uniform to avoid artifacts.
- bool reduced[3];
- i=0;
- int count=0;
- while(i<3)
- {
- vtkIdType newSize=static_cast<vtkIdType>(
- floor(static_cast<double>(rTextureSize[i])*r3));
- reduced[i]=newSize>=1;
- if(reduced[i])
- {
- ++count;
- }
- ++i;
- }
-
- if(count<3) // some axis cannot be reduced
- {
- double r2=sqrt(r);
- count=0;
- i=0;
- while(i<3)
- {
- if(reduced[i])
- {
- vtkIdType newSize=static_cast<vtkIdType>(
- floor(static_cast<double>(rTextureSize[i])*r2));
- reduced[i]=newSize>=1;
- if(reduced[i])
- {
- ++count;
- }
- }
- ++i;
- }
- if(count<2) // we can only reduce one axis
- {
- i=0;
- while(i<3)
- {
- if(reduced[i])
- {
- ratio[i]*=r;
- }
- ++i;
- }
- }
- else // we can reduce two axes
- {
- i=0;
- while(i<3)
- {
- if(reduced[i])
- {
- ratio[i]*=r2;
- }
- ++i;
- }
- }
- }
- else // we can reduce all three axes
- {
- i=0;
- while(i<3)
- {
- ratio[i]*=r3;
- ++i;
- }
- }
- }
-
- assert("post: valid_i_ratio" && ratio[0]>0 && ratio[0]<=1.0);
- assert("post: valid_j_ratio" && ratio[1]>0 && ratio[1]<=1.0);
- assert("post: valid_k_ratio" && ratio[2]>0 && ratio[2]<=1.0);
-}
-
-//-----------------------------------------------------------------------------
-// Standard print method
-//-----------------------------------------------------------------------------
-void vtkMitkOpenGLGPUVolumeRayCastMapper::PrintSelf(ostream& os,
- vtkIndent indent)
-{
- this->Superclass::PrintSelf(os,indent);
-}
-
-#endif
diff --git a/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapper.h b/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapper.h
deleted file mode 100644
index 3853505924..0000000000
--- a/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapper.h
+++ /dev/null
@@ -1,526 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-/*=========================================================================
-
- Program: Visualization Toolkit
- Module: $RCSfile: vtkMitkOpenGLGPUVolumeRayCastMapper.h,v $
-
- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
- All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
-=========================================================================*/
-// .NAME vtkMitkOpenGLGPUVolumeRayCastMapper - OpenGL subclass that draws the
-// image to the screen
-// .SECTION Description
-// This is the concrete implementation of a ray cast image display helper -
-// a helper class responsible for drawing the image to the screen.
-
-// .SECTION see also
-// vtkGPUVolumeRayCastMapper
-
-#ifndef __vtkMitkOpenGLGPUVolumeRayCastMapper_h
-#define __vtkMitkOpenGLGPUVolumeRayCastMapper_h
-
-#include "vtkMitkGPUVolumeRayCastMapper.h"
-#include "mitkCommon.h"
-#include "MitkExtExports.h"
-
-// Only with VTK 5.6 or above
-#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
-
-class vtkVolume;
-class vtkRenderer;
-class vtkOpenGLExtensionManager;
-class vtkMatrix4x4;
-class vtkUnsupportedRequiredExtensionsStringStream; // Pimpl
-class vtkMapDataArrayTextureId; // Pimpl
-class vtkMapMaskTextureId; // Pimpl
-class vtkPolyData;
-class vtkClipConvexPolyData;
-class vtkClipPolyData;
-class vtkTessellatedBoxSource;
-
-class vtkOpacityTable; // internal class.
-class vtkRGBTable; // internal class.
-class vtkKWScalarField; // internal class.
-class vtkKWMask; // internal class.
-
-class vtkOpacityTables; // Pimpl
-class vtkDensifyPolyData;
-class vtkStdString;
-
-class MitkExt_EXPORT vtkMitkOpenGLGPUVolumeRayCastMapper : public vtkMitkGPUVolumeRayCastMapper
-{
-public:
- static vtkMitkOpenGLGPUVolumeRayCastMapper *New();
- vtkTypeMacro(vtkMitkOpenGLGPUVolumeRayCastMapper,vtkMitkGPUVolumeRayCastMapper);
- virtual void PrintSelf(ostream& os, vtkIndent indent);
-
- // Description:
- // Based on hardware and properties, we may or may not be able to
- // render using 3D texture mapping. This indicates if 3D texture
- // mapping is supported by the hardware, and if the other extensions
- // necessary to support the specific properties are available.
- virtual int IsRenderSupported(vtkRenderWindow *window,
- vtkVolumeProperty *property);
-
- // Description:
- // Return a string matching the OpenGL errorCode.
- // \post result_exists: result!=0
- static const char *OpenGLErrorMessage(unsigned int errorCode);
-
- // Description:
- // Display headerMessage on the standard output and the last OpenGL error
- // message if any.
- // \pre headerMessage_exists: headerMessage!=0
- static void PrintError(const char *headerMessage);
-
-
-
-protected:
- vtkMitkOpenGLGPUVolumeRayCastMapper();
- ~vtkMitkOpenGLGPUVolumeRayCastMapper();
-
- // The render method called by the superclass
- virtual void GPURender(vtkRenderer *ren,
- vtkVolume *vol);
-
- // Methods called by the AMR Volume Mapper.
- virtual void PreRender(vtkRenderer *ren,
- vtkVolume *vol,
- double datasetBounds[6],
- double scalarRange[2],
- int numberOfScalarComponents,
- unsigned int numberOfLevels);
-
- // \pre input is up-to-date
- virtual void RenderBlock(vtkRenderer *ren,
- vtkVolume *vol,
- unsigned int level);
-
- virtual void PostRender(vtkRenderer *ren,
- int numberOfScalarComponents);
-
- // Description:
- // Return if the required OpenGL extension `extensionName' is supported.
- // If not, its name is added to the string of unsupported but required
- // extensions.
- // \pre extensions_exist: extensions!=0
- // \pre extensionName_exists: extensionName!=0
- int TestRequiredExtension(vtkOpenGLExtensionManager *extensions,
- const char *extensionName);
-
- // Description:
- // Attempt to load required and optional OpenGL extensions for the current
- // context window. Variable LoadExtensionsSucceeded is set if all required
- // extensions has been loaded. In addition, variable
- // Supports_GL_ARB_texture_float is set if this extension has been loaded.
- // \pre: window_exists: window!=0
- void LoadExtensions(vtkRenderWindow *window);
-
- // Description:
- // Create GLSL OpenGL objects such fragment program Ids.
- void CreateGLSLObjects();
-
- // Description:
- // Allows late binding textures to framebuffers, because ATI openGL requires
- // the texture to initialized before
- void BindFramebuffer();
-
- // Description:
- // Create OpenGL objects such as textures, buffers and fragment program Ids.
- // It only registers Ids, there is no actual initialization of textures or
- // fragment program.
- // \pre extensions_loaded: this->LoadExtensionsSucceeded
- // \post done: this->OpenGLObjectsCreated==1
-
- void CreateOpenGLObjects();
-
- // Description:
- // Delete OpenGL objects.
- // \post done: this->OpenGLObjectsCreated==0
- // \deprecatedSince{2013_12} Use ReleaseGraphicsResources(mitk::BaseRenderer* renderer) instead
- //
- DEPRECATED(void ReleaseGraphicsResources(vtkWindow *window));
-
- // Description:
- // Delete OpenGL objects.
- // \post done: this->OpenGLObjectsCreated==0
- //
- void ReleaseGraphicsResources(mitk::BaseRenderer* renderer);
-
- // Description:
- // Allocate memory on the GPU for the framebuffers according to the size of
- // the window or reallocate if the size has changed. Return true if
- // allocation succeeded.
- // \pre ren_exists: ren!=0
- // \pre opengl_objects_created: this->OpenGLObjectsCreated
- // \post right_size: LastSize[]=window size.
- int AllocateFrameBuffers(vtkRenderer *ren);
-
- // Description
- // Load the scalar field (one or four component scalar field), cell or point
- // based for a given subextent of the whole extent (can be the whole extent)
- // as a 3D texture on the GPU.
- // Extents are expressed in point if the cell flag is false or in cells of
- // the cell flag is true.
- // It returns true if it succeeded, false if there is not enough memory on
- // the GPU.
- // If succeeded, it updates the LoadedExtent, LoadedBounds, LoadedCellFlag
- // and LoadedTime. It also succeed if the scalar field is already loaded
- // (ie since last load, input has not changed and cell flag has not changed
- // and requested texture extents are enclosed in the loaded extent).
- // \pre input_exists: input!=0
- // \pre valid_point_extent: (this->CellFlag ||
- // (textureExtent[0]<textureExtent[1] &&
- // textureExtent[2]<textureExtent[3] &&
- // textureExtent[4]<textureExtent[5])))
- // \pre valid_cell_extent: (!this->CellFlag ||
- // (textureExtent[0]<=textureExtent[1] &&
- // textureExtent[2]<=textureExtent[3] &&
- // textureExtent[4]<=textureExtent[5])))
- int LoadScalarField(vtkImageData *input,
- vtkImageData *maskInput,
- int textureExtent[6],
- vtkVolume *volume);
-
- // Description:
- // Allocate memory and load color table on the GPU or
- // reload it if the transfer function changed.
- // \pre vol_exists: vol!=0
- // \pre valid_numberOfScalarComponents: numberOfScalarComponents==1 || numberOfScalarComponents==4
- int UpdateColorTransferFunction(vtkVolume *vol,
- int numberOfScalarComponents);
- // Description:
- // Allocate memory and load opacity table on the GPU or
- // reload it if the transfer functions changed.
- // \pre vol_exists: vol!=0
- // \pre valid_numberOfScalarComponents: numberOfScalarComponents==1 || numberOfScalarComponents==4
- int UpdateOpacityTransferFunction(vtkVolume *vol,
- int numberOfScalarComponents,
- unsigned int level);
-
- // Description:
- // Prepare rendering in the offscreen framebuffer.
- // \pre ren_exists: ren!=0
- // \pre vol_exists: vol!=0
- void SetupRender(vtkRenderer *ren, vtkVolume *vol);
-
- // Description:
- // Clip the bounding box with all clipping planes
- // and the near and far plane
- void ClipBoundingBox(vtkRenderer *ren,
- double worldBounds[6],
- vtkVolume *vol);
-
- // Description:
- // Render the bounding box. The flag indicates whether
- // or not tcoords are rendered too. Return abort status (true==abort).
- // \pre valid_currentBlock: currentBlock>=0 && currentBlock<numberOfBlocks
- int RenderClippedBoundingBox(int tcoordFlag,
- size_t currentBlock,
- size_t numberOfBlocks,
- vtkRenderWindow *renWin);
-
- // Description:
- // Method used to copy the state of the color buffer (which is in
- // a frame buffer object) to a texture.
- void CopyFBOToTexture();
-
- // Description:
- // Restore OpenGL state after rendering of the dataset.
- void CleanupRender();
-
- // Description:
- // Render the offscreen buffer to the screen.
- // \pre ren_exists: ren!=0
- void RenderTextureToScreen(vtkRenderer *ren);
-
- // Description:
- // Compute y=2^n such that x<=y.
- // \pre positive_x: x>=0
- // \post valid_result: result>=x
- int PowerOfTwoGreaterOrEqual(int x);
-
- // Description:
- // Display the status of the current framebuffer on the standard output.
- void CheckFrameBufferStatus();
-
- // Description:
- // Create a string from a buffer id. The result has to be free by the caller.
- vtkStdString BufferToString(int buffer);
-
- // Description:
- // Display the buffers assigned for drawing and reading operations.
- void DisplayReadAndDrawBuffers();
-
- // Description:
- // Display all the attachments of the current framebuffer object.
- void DisplayFrameBufferAttachments();
-
- // Description:
- // Display a given attachment for the current framebuffer object.
- void DisplayFrameBufferAttachment(unsigned int uattachment);
-
- // Description:
- // Concatenate the header string, projection type code and method to the
- // final fragment code in this->FragmentCode.
- // \pre valid_raycastMethod: raycastMethod>= vtkMitkOpenGLGPUVolumeRayCastMapperMethodMaximumIntensityProjection && raycastMethod<=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent
- void BuildProgram(int parallelProjection,
- int raycastMethod,
- int shadeMethod,
- int componentMethod);
-
- // Description:
- // Return the current OpenGL state about lighting.
- void GetLightingStatus();
-
- // Description:
- // Check the compilation status of some fragment shader source.
- void CheckCompilation(unsigned int fragmentShader);
-
- // Description:
- // Check the linkage status of the fragment program.
- int CheckLinkage(unsigned int programShader);
-
- // Description:
- // Print all active uniform variables
- void PrintUniformVariables(unsigned int programShader);
-
- // Description:
- // Is the program shader valid in the current OpenGL state?
- // Debugging purpose only.
- void ValidateProgram();
-
- // Description:
- // Update the reduction factor of the render viewport (this->ReductionFactor)
- // according to the time spent in seconds to render the previous frame
- // (this->TimeToDraw) and a time in seconds allocated to render the next
- // frame (allocatedTime).
- // \pre valid_current_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
- // \pre positive_TimeToDraw: this->TimeToDraw>=0.0
- // \pre positive_time: allocatedTime>0
- // \post valid_new_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
- void ComputeReductionFactor(double allocatedTime);
-
- // Description:
- // Render a subvolume.
- // \pre this->ProgramShader!=0 and is linked.
- void RenderWholeVolume(vtkRenderer *ren,
- vtkVolume *vol);
-
- // Description:
- // Render a subvolume.
- // \pre this->ProgramShader!=0 and is linked.
- void RenderRegions(vtkRenderer *ren,
- vtkVolume *vol);
-
- // Return abort status (true==abort)
- int RenderSubVolume(vtkRenderer *ren,
- double bounds[6],
- vtkVolume *vol);
-
- void LoadProjectionParameters(vtkRenderer *ren,
- vtkVolume *vol);
-
- // Description:
- // Compute and return the number of cropping regions
- void ComputeNumberOfCroppingRegions();
-
- void GetTextureFormat(vtkImageData *input,
- unsigned int *internalFormat,
- unsigned int *format,
- unsigned int *type,
- int *componentSize);
-
- bool TestLoadingScalar(unsigned int internalFormat,
- unsigned int format,
- unsigned int type,
- int textureSize[3],
- int componentSize);
-
- void SlabsFromDatasetToIndex(double slabsDataSet[6],
- double slabsPoints[6]);
-
- void SlabsFromIndexToDataset(double slabsPoints[6],
- double slabsDataSet[6]);
-
- const char *GetEnabledString(unsigned char value);
- void GetOpenGLState();
-
- void DebugDisplayBox(vtkPolyData *box);
-
- void UpdateNoiseTexture();
-
- // Description:
- // Compute how each axis of a cell is projected on the viewport in pixel.
- // This requires to have information about the camera and about the volume.
- // It set the value of IgnoreSampleDistancePerPixel to true in case of
- // degenerated case (axes aligned with the view).
- double ComputeMinimalSampleDistancePerPixel(vtkRenderer *renderer,
- vtkVolume *volume);
-
- // Description:
- // Return how much the dataset has to be reduced in each dimension to
- // fit on the GPU. If the value is 1.0, there is no need to reduce the
- // dataset.
- // \pre the calling thread has a current OpenGL context.
- // \pre mapper_supported: IsRenderSupported(renderer->GetRenderWindow(),0)
- // The computation is based on hardware limits (3D texture indexable size)
- // and MaxMemoryInBytes.
- // \post valid_i_ratio: ratio[0]>0 && ratio[0]<=1.0
- // \post valid_j_ratio: ratio[1]>0 && ratio[1]<=1.0
- // \post valid_k_ratio: ratio[2]>0 && ratio[2]<=1.0
- virtual void GetReductionRatio(double ratio[3]);
-
- bool m_BindMax;
-
- int NumberOfCroppingRegions;
-
- // World coordinates of each corner of the dataset.
- double BoundingBox[8][3];
-
- // Used during the clipping process.
- vtkPolyData *PolyDataBoundingBox;
- vtkPlaneCollection *Planes;
- vtkPlane *NearPlane;
-
- vtkClipConvexPolyData *Clip;
- vtkMatrix4x4 *InvVolumeMatrix;
-
- vtkDensifyPolyData *Densify;
-
- int OpenGLObjectsCreated;
- int NumberOfFrameBuffers;
-
- unsigned int FrameBufferObject;
- unsigned int DepthRenderBufferObject;
-
- // 3D scalar texture +1D color+1D opacity+2D grabbed depth buffer
- // +1 2D colorbuffer.
- unsigned int TextureObjects[5];
- unsigned int FragmentMainShader;
- unsigned int FragmentProjectionShader;
- unsigned int FragmentTraceShader;
- unsigned int FragmentCroppingShader;
- unsigned int FragmentComponentShader;
- unsigned int FragmentShadeShader;
- unsigned int ProgramShader;
- // used in MIP Mode (2 needed for ping-pong technique)
- unsigned int MaxValueFrameBuffer;
- unsigned int MaxValueFrameBuffer2;
- int ReducedSize[2];
-
- vtkPolyData *ClippedBoundingBox;
-
- int LastSize[2];
-
- double ReductionFactor;
-
- // Supported extensions
- // List of unsupported required extensions. Pimpl.
- vtkUnsupportedRequiredExtensionsStringStream *UnsupportedRequiredExtensions;
- int LoadExtensionsSucceeded;
-
- int Supports_GL_ARB_texture_float;
- int SupportsPixelBufferObjects;
-
- vtkTimeStamp DataBufferTime;
-
- // Matrices used in internal computation. As a member variable,
- // only one memory allocation is performed.
- vtkMatrix4x4 *TempMatrix[3];
-
- double TableRange[2];
-
- // Final string to send to the GPU as the fragment program source code.
-// char *FragmentCode;
-// int FragmentCodeCapacity;
-
-
- int ErrorLine;
- int ErrorColumn;
- char *ErrorString;
-
- // Store the last projection an raycast method in order to not rebuild
- // the fragment code at every call.
- int LastParallelProjection;
- int LastRayCastMethod;
- int LastCroppingMode;
- int LastComponent;
- int LastShade;
-
- vtkImageData *SmallInput;
- vtkTimeStamp SmallInputBuildTime;
-
- // Description:
- // Build the fragment shader program that scale and bias a texture
- // for window/level purpose.
- void BuildScaleBiasProgram();
-
- unsigned int ScaleBiasProgramShader; // GLuint
- int UFrameBufferTexture; // GLint
- int UScale; // GLint
- int UBias; // GLint
-
-#if 0
- vtkIdType LoadedExtent[6];
- double LoadedBounds[6];
- vtkTimeStamp LoadedScalarTime;
- int LoadedCellFlag; // point data or cell data (or field data, not handled) ?
-#endif
-
- unsigned int SavedFrameBuffer; // some offscreen mode use a framebuffer too.
-
- vtkTessellatedBoxSource *BoxSource;
-
- float *NoiseTexture;
- int NoiseTextureSize; // size of one dimension.
- unsigned int NoiseTextureId; // GLuint
-
- bool IgnoreSampleDistancePerPixel;
-
- vtkMapDataArrayTextureId *ScalarsTextures; // need a list for AMR mode.
- vtkMapMaskTextureId *MaskTextures; // need a list for AMR mode.
-
- vtkRGBTable *RGBTable;
- vtkRGBTable *Mask1RGBTable;
- vtkRGBTable *Mask2RGBTable;
-
- vtkOpacityTables *OpacityTables;
-
- vtkKWScalarField *CurrentScalar;
- vtkKWMask *CurrentMask;
-
- float ActualSampleDistance;
-
- double LastProgressEventTime; // initial value is 0.0. Expressed in seconds.
-
- bool PreserveOrientation;
-
-private:
- vtkMitkOpenGLGPUVolumeRayCastMapper(const vtkMitkOpenGLGPUVolumeRayCastMapper&); // Not implemented.
- void operator=(const vtkMitkOpenGLGPUVolumeRayCastMapper&); // Not implemented.
-};
-
-#endif
-
-#endif
diff --git a/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapperShaders.cpp b/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapperShaders.cpp
deleted file mode 100644
index 74887c425d..0000000000
--- a/Modules/Ext/Rendering/vtkMitkOpenGLGPUVolumeRayCastMapperShaders.cpp
+++ /dev/null
@@ -1,1814 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include <vtkObject.h>
-
-// Only with VTK 5.6 or above
-#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
- /* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some function used by the composite method when cropping\n"
-"// is on.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// color buffer as an input\n"
-"uniform sampler2D frameBufferTexture;\n"
-"// 2D Texture fragment coordinates [0,1] from fragment coordinates\n"
-"// the frame buffer texture has the size of the plain buffer but\n"
-"// we use a fraction of it. The texture coordinates is less than 1 if\n"
-"// the reduction factor is less than 1.\n"
-"vec2 fragTexCoord;\n"
-"\n"
-"vec4 initialColor()\n"
-"{\n"
-" return texture2D(frameBufferTexture,fragTexCoord);\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_CompositeFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_CompositeFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_CompositeFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_CompositeFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment program part with ray cast and composite method.\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform sampler3D dataSetTexture;\n"
-"uniform sampler1D opacityTexture;\n"
-"\n"
-"uniform vec3 lowBounds;\n"
-"uniform vec3 highBounds;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"float tMax;\n"
-"\n"
-"// from cropping vs no cropping\n"
-"vec4 initialColor();\n"
-"\n"
-"// from 1 vs 4 component shader.\n"
-"float scalarFromValue(vec4 value);\n"
-"vec4 colorFromValue(vec4 value);\n"
-"\n"
-"// from noshade vs shade.\n"
-"void initShade();\n"
-"vec4 shade(vec4 value);\n"
-"\n"
-"void trace(void)\n"
-"{\n"
-" vec4 destColor=initialColor();\n"
-" float remainOpacity=1.0-destColor.a;\n"
-"\n"
-" bool inside=true;\n"
-" \n"
-" vec4 color;\n"
-" vec4 opacity;\n"
-"\n"
-" initShade();\n"
-" \n"
-" float t=0.0;\n"
-" \n"
-" // We NEED two nested while loops. It is trick to work around hardware\n"
-" // limitation about the maximum number of loops.\n"
-"\n"
-" while(inside)\n"
-" { \n"
-" while(inside)\n"
-" {\n"
-" vec4 value=texture3D(dataSetTexture,pos);\n"
-" float scalar=scalarFromValue(value);\n"
-" // opacity is the sampled texture value in the 1D opacity texture at\n"
-" // scalarValue\n"
-" opacity=texture1D(opacityTexture,scalar);\n"
-" if(opacity.a>0.0)\n"
-" {\n"
-" color=shade(value);\n"
-" color=color*opacity.a;\n"
-" destColor=destColor+color*remainOpacity;\n"
-" remainOpacity=remainOpacity*(1.0-opacity.a);\n"
-" }\n"
-" pos=pos+rayDir;\n"
-" t+=1.0;\n"
-" inside=t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" && all(lessThanEqual(pos,highBounds))\n"
-" && (remainOpacity>=0.0039); // 1/255=0.0039\n"
-" }\n"
-" }\n"
-" gl_FragColor = destColor;\n"
-" gl_FragColor.a = 1.0-remainOpacity;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment program part with ray cast and composite method with masks.\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform sampler3D dataSetTexture;\n"
-"uniform sampler3D maskTexture;\n"
-"uniform sampler1D mask1ColorTexture;\n"
-"uniform sampler1D mask2ColorTexture;\n"
-"uniform sampler1D opacityTexture;\n"
-"\n"
-"uniform vec3 lowBounds;\n"
-"uniform vec3 highBounds;\n"
-"\n"
-"uniform float maskBlendFactor;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"float tMax;\n"
-"\n"
-"// from cropping vs no cropping\n"
-"vec4 initialColor();\n"
-"\n"
-"// from 1 vs 4 component shader.\n"
-"float scalarFromValue(vec4 value);\n"
-"vec4 colorFromValue(vec4 value);\n"
-"\n"
-"// from noshade vs shade.\n"
-"void initShade();\n"
-"vec4 shade(vec4 value);\n"
-"\n"
-"void trace(void)\n"
-"{\n"
-" vec4 destColor=initialColor();\n"
-" float remainOpacity=1.0-destColor.a;\n"
-"\n"
-" bool inside=true;\n"
-" \n"
-" vec4 maskValue;\n"
-" vec4 color;\n"
-" vec4 opacity;\n"
-"\n"
-" initShade();\n"
-" \n"
-" float t=0.0;\n"
-" \n"
-" // We NEED two nested while loops. It is trick to work around hardware\n"
-" // limitation about the maximum number of loops.\n"
-"\n"
-" while(inside)\n"
-" { \n"
-" while(inside)\n"
-" {\n"
-" vec4 value=texture3D(dataSetTexture,pos);\n"
-" float scalar=scalarFromValue(value);\n"
-" opacity=texture1D(opacityTexture,scalar);\n"
-" \n"
-" if(maskBlendFactor==0.0)\n"
-" {\n"
-" color=shade(value);\n"
-" }\n"
-" else\n"
-" {\n"
-" // get the mask value at this same location\n"
-" maskValue=texture3D(maskTexture,pos);\n"
-" if(maskValue.a==0.0)\n"
-" {\n"
-" color=shade(value);\n"
-" }\n"
-" else\n"
-" {\n"
-" if(maskValue.a==1.0/255.0)\n"
-" {\n"
-" color=texture1D(mask1ColorTexture,scalar);\n"
-" }\n"
-" else\n"
-" {\n"
-" // maskValue.a == 2.0/255.0\n"
-" color=texture1D(mask2ColorTexture,scalar);\n"
-" }\n"
-" color.a=1.0;\n"
-" if(maskBlendFactor<1.0)\n"
-" {\n"
-" color=(1.0-maskBlendFactor)*shade(value)+maskBlendFactor*color;\n"
-" }\n"
-"// color.r = 1;\n"
-"// color.g = 0;\n"
-"// color.b = 0;\n"
-"// color.a = 1;\n"
-" }\n"
-" }\n"
-" \n"
-" color=color*opacity.a;\n"
-" destColor=destColor+color*remainOpacity;\n"
-" remainOpacity=remainOpacity*(1.0-opacity.a);\n"
-" \n"
-" pos=pos+rayDir;\n"
-" t+=1.0;\n"
-" inside=t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" && all(lessThanEqual(pos,highBounds))\n"
-" && (remainOpacity>=0.0039); // 1/255=0.0039\n"
-" }\n"
-" }\n"
-" gl_FragColor = destColor;\n"
-" gl_FragColor.a = 1.0-remainOpacity;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some function used by the composite method when cropping\n"
-"// is off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// Max intensity is the lowest value.\n"
-"vec4 initialColor()\n"
-"{\n"
-" return vec4(0.0,0.0,0.0,0.0);\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the Minimum Intensity Projection\n"
-"// (MinIP) method when cropping is on.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// GLSL Spec 1.10 rev 59 30-April-2004 defines gl_FragData[] but implementation\n"
-"// older than the spec only has it as an extension\n"
-"// (nVidia Linux driver 100.14.13, OpenGL version 2.1.1,\n"
-"// on Quadro FX 3500/PCI/SSE2)\n"
-"#extension GL_ARB_draw_buffers : enable\n"
-"\n"
-"// max scalar buffer as an input\n"
-"uniform sampler2D scalarBufferTexture;\n"
-"// 2D Texture fragment coordinates [0,1] from fragment coordinates\n"
-"// the scalar frame buffer texture has the size of the plain buffer but\n"
-"// we use a fraction of it. The texture coordinates is less than 1 if\n"
-"// the reduction factor is less than 1.\n"
-"vec2 fragTexCoord;\n"
-"\n"
-"float initialMinValue()\n"
-"{\n"
-" return texture2D(scalarBufferTexture,fragTexCoord).r;\n"
-"}\n"
-"\n"
-"void writeColorAndMinScalar(vec4 sample,\n"
-" vec4 opacity,\n"
-" float minValue)\n"
-"{\n"
-" // color framebuffer\n"
-" gl_FragData[0].r =sample.r * opacity.a;\n"
-" gl_FragData[0].g =sample.g * opacity.a;\n"
-" gl_FragData[0].b =sample.b * opacity.a;\n"
-" gl_FragData[0].a=opacity.a;\n"
-" \n"
-" // min scalar framebuffer\n"
-" gl_FragData[1].r=minValue;\n"
-" gl_FragData[1].g=0.0;\n"
-" gl_FragData[1].b=0.0;\n"
-" gl_FragData[1].a=0.0;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the 4-component Minimum Intensity\n"
-"// Projection (MinIP) method when cropping is on.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// GLSL Spec 1.10 rev 59 30-April-2004 defines gl_FragData[] but implementation\n"
-"// older than the spec only has it as an extension\n"
-"// (nVidia Linux driver 100.14.13, OpenGL version 2.1.1,\n"
-"// on Quadro FX 3500/PCI/SSE2)\n"
-"#extension GL_ARB_draw_buffers : enable\n"
-"\n"
-"// max scalar buffer as an input\n"
-"uniform sampler2D scalarBufferTexture;\n"
-"\n"
-"// color buffer as an input\n"
-"uniform sampler2D frameBufferTexture;\n"
-"\n"
-"// 2D Texture fragment coordinates [0,1] from fragment coordinates\n"
-"// the scalar frame buffer texture has the size of the plain buffer but\n"
-"// we use a fraction of it. The texture coordinates is less than 1 if\n"
-"// the reduction factor is less than 1.\n"
-"vec2 fragTexCoord;\n"
-"\n"
-"float initialMinValue()\n"
-"{\n"
-" return texture2D(scalarBufferTexture,fragTexCoord).r;\n"
-"}\n"
-"\n"
-"vec4 initialColor()\n"
-"{\n"
-" return texture2D(frameBufferTexture,fragTexCoord);\n"
-"}\n"
-"\n"
-"void writeColorAndMinScalar(vec4 color,\n"
-" vec4 opacity,\n"
-" float minValue)\n"
-"{\n"
-" // color framebuffer\n"
-" gl_FragData[0].r = color.r*opacity.a;\n"
-" gl_FragData[0].g = color.g*opacity.a;\n"
-" gl_FragData[0].b = color.b*opacity.a;\n"
-" gl_FragData[0].a=opacity.a;\n"
-" \n"
-" // min scalar framebuffer\n"
-" gl_FragData[1].r=minValue;\n"
-" gl_FragData[1].g=0.0;\n"
-" gl_FragData[1].b=0.0;\n"
-" gl_FragData[1].a=0.0;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment program with ray cast and 4-dependent-component Minimum Intensity\n"
-"// Projection (MinIP) method.\n"
-"// Compilation: header part and the projection part are inserted first.\n"
-"// pos is defined and initialized in header\n"
-"// rayDir is defined in header and initialized in the projection part\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform sampler3D dataSetTexture;\n"
-"uniform sampler1D opacityTexture;\n"
-"\n"
-"uniform vec3 lowBounds;\n"
-"uniform vec3 highBounds;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"float tMax;\n"
-"\n"
-"// Sub-functions, depending on cropping mode\n"
-"float initialMinValue();\n"
-"vec4 initialColor();\n"
-"void writeColorAndMinScalar(vec4 color,\n"
-" vec4 opacity,\n"
-" float minValue);\n"
-"\n"
-"void trace(void)\n"
-"{\n"
-" // Max intensity is the lowest value.\n"
-" float minValue=initialMinValue();\n"
-" vec4 color=initialColor();\n"
-" bool inside=true;\n"
-" float t=0.0;\n"
-" vec4 sample;\n"
-" bool changed=false;\n"
-" \n"
-" // We NEED two nested while loops. It is a trick to work around hardware\n"
-" // limitation about the maximum number of loops.\n"
-" while(inside)\n"
-" {\n"
-" while(inside)\n"
-" {\n"
-" sample=texture3D(dataSetTexture,pos);\n"
-" if(sample.w<minValue)\n"
-" {\n"
-" changed=true;\n"
-" minValue=sample.w;\n"
-" color=sample;\n"
-" }\n"
-" pos=pos+rayDir;\n"
-" t+=1.0;\n"
-" \n"
-" // yes, t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" // && all(lessThanEqual(pos,highBounds));\n"
-" // looks better but the latest nVidia 177.80 has a bug...\n"
-" inside=t<tMax && pos.x>=lowBounds.x && pos.y>=lowBounds.y\n"
-" && pos.z>=lowBounds.z && pos.x<=highBounds.x && pos.y<=highBounds.y\n"
-" && pos.z<=highBounds.z;\n"
-" }\n"
-" }\n"
-" \n"
-" if(changed)\n"
-" {\n"
-" vec4 opacity=texture1D(opacityTexture,minValue);\n"
-" writeColorAndMinScalar(color,opacity,minValue);\n"
-" }\n"
-" else\n"
-" {\n"
-" discard;\n"
-" }\n"
-"}\n"
-"\n";
-
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the 4-component Minimum Intensity\n"
-"// Projection (MinIP) method when cropping is off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"float initialMinValue()\n"
-"{\n"
-" return 1.0;\n"
-"}\n"
-"\n"
-"vec4 initialColor()\n"
-"{\n"
-" return vec4(0.0,0.0,0.0,0.0);\n"
-"}\n"
-"\n"
-"void writeColorAndMinScalar(vec4 color,\n"
-" vec4 opacity,\n"
-" float minValue)\n"
-"{\n"
-" // minValue is not used\n"
-" \n"
-" // color framebuffer\n"
-" gl_FragColor.r = color.r*opacity.a;\n"
-" gl_FragColor.g = color.g*opacity.a;\n"
-" gl_FragColor.b = color.b*opacity.a;\n"
-" gl_FragColor.a=opacity.a;\n"
-"}\n"
-"\n";
-
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MinIPFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MinIPFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MinIPFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MinIPFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment program with ray cast and Minimum Intensity Projection (MinIP)\n"
-"// method.\n"
-"// Compilation: header part and the projection part are inserted first.\n"
-"// pos is defined and initialized in header\n"
-"// rayDir is defined in header and initialized in the projection part\n"
-"// initMinValue() and writeColorAndMinScalar are defined in some specific\n"
-"// file depending on cropping flag being on or off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform sampler3D dataSetTexture;\n"
-"uniform sampler1D colorTexture;\n"
-"uniform sampler1D opacityTexture;\n"
-"\n"
-"uniform vec3 lowBounds;\n"
-"uniform vec3 highBounds;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"float tMax;\n"
-"\n"
-"// Sub-functions, depending on cropping mode\n"
-"float initialMinValue();\n"
-"void writeColorAndMinScalar(vec4 sample,\n"
-" vec4 opacity,\n"
-" float minValue);\n"
-"\n"
-"void trace(void)\n"
-"{\n"
-" // Max intensity is the lowest value.\n"
-" float minValue=initialMinValue();\n"
-" bool inside=true;\n"
-" vec4 sample;\n"
-" \n"
-" float t=0.0;\n"
-" // We NEED two nested while loops. It is trick to work around hardware\n"
-" // limitation about the maximum number of loops.\n"
-" while(inside)\n"
-" {\n"
-" while(inside)\n"
-" {\n"
-" sample=texture3D(dataSetTexture,pos);\n"
-" minValue=min(minValue,sample.r);\n"
-" pos=pos+rayDir;\n"
-" t+=1.0;\n"
-" inside=t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" && all(lessThanEqual(pos,highBounds));\n"
-" \n"
-" // yes, t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" // && all(lessThanEqual(pos,highBounds));\n"
-" // looks better but the latest nVidia 177.80 has a bug...\n"
-" inside=t<tMax && pos.x>=lowBounds.x && pos.y>=lowBounds.y\n"
-" && pos.z>=lowBounds.z && pos.x<=highBounds.x && pos.y<=highBounds.y\n"
-" && pos.z<=highBounds.z;\n"
-" \n"
-" \n"
-" }\n"
-" }\n"
-"\n"
-" sample=texture1D(colorTexture,minValue);\n"
-" vec4 opacity=texture1D(opacityTexture,minValue);\n"
-" \n"
-" writeColorAndMinScalar(sample,opacity,minValue);\n"
-"}\n"
-"\n";
-
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the Minimum Intensity projection\n"
-"// (MinIP) method when cropping is off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"float initialMinValue()\n"
-"{\n"
-" return 1.0;\n"
-"}\n"
-"\n"
-"void writeColorAndMinScalar(vec4 sample,\n"
-" vec4 opacity,\n"
-" float minValue)\n"
-"{\n"
-" // we don't need to write minValue to a buffer when there is no cropping.\n"
-" // color framebuffer\n"
-" gl_FragColor.r =sample.r * opacity.a;\n"
-" gl_FragColor.g =sample.g * opacity.a;\n"
-" gl_FragColor.b =sample.b * opacity.a;\n"
-" gl_FragColor.a=opacity.a;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the Maximum Intensity Projection\n"
-"// (MIP) method when cropping is on.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// GLSL Spec 1.10 rev 59 30-April-2004 defines gl_FragData[] but implementation\n"
-"// older than the spec only has it as an extension\n"
-"// (nVidia Linux driver 100.14.13, OpenGL version 2.1.1,\n"
-"// on Quadro FX 3500/PCI/SSE2)\n"
-"#extension GL_ARB_draw_buffers : enable\n"
-"\n"
-"// max scalar buffer as an input\n"
-"uniform sampler2D scalarBufferTexture;\n"
-"// 2D Texture fragment coordinates [0,1] from fragment coordinates\n"
-"// the scalar frame buffer texture has the size of the plain buffer but\n"
-"// we use a fraction of it. The texture coordinates is less than 1 if\n"
-"// the reduction factor is less than 1.\n"
-"vec2 fragTexCoord;\n"
-"\n"
-"float initialMaxValue()\n"
-"{\n"
-" return texture2D(scalarBufferTexture,fragTexCoord).r;\n"
-"}\n"
-"\n"
-"void writeColorAndMaxScalar(vec4 sample,\n"
-" vec4 opacity,\n"
-" float maxValue)\n"
-"{\n"
-" // color framebuffer\n"
-" gl_FragData[0].r =sample.r * opacity.a;\n"
-" gl_FragData[0].g =sample.g * opacity.a;\n"
-" gl_FragData[0].b =sample.b * opacity.a;\n"
-" gl_FragData[0].a=opacity.a;\n"
-" \n"
-" // max scalar framebuffer\n"
-" gl_FragData[1].r=maxValue;\n"
-" gl_FragData[1].g=0.0;\n"
-" gl_FragData[1].b=0.0;\n"
-" gl_FragData[1].a=0.0;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the 4-component Maximum Intensity\n"
-"// Projection (MIP) method when cropping is on.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// GLSL Spec 1.10 rev 59 30-April-2004 defines gl_FragData[] but implementation\n"
-"// older than the spec only has it as an extension\n"
-"// (nVidia Linux driver 100.14.13, OpenGL version 2.1.1,\n"
-"// on Quadro FX 3500/PCI/SSE2)\n"
-"#extension GL_ARB_draw_buffers : enable\n"
-"\n"
-"// max scalar buffer as an input\n"
-"uniform sampler2D scalarBufferTexture;\n"
-"\n"
-"// color buffer as an input\n"
-"uniform sampler2D frameBufferTexture;\n"
-"\n"
-"// 2D Texture fragment coordinates [0,1] from fragment coordinates\n"
-"// the scalar frame buffer texture has the size of the plain buffer but\n"
-"// we use a fraction of it. The texture coordinates is less than 1 if\n"
-"// the reduction factor is less than 1.\n"
-"vec2 fragTexCoord;\n"
-"\n"
-"float initialMaxValue()\n"
-"{\n"
-" return texture2D(scalarBufferTexture,fragTexCoord).r;\n"
-"}\n"
-"\n"
-"vec4 initialColor()\n"
-"{\n"
-" return texture2D(frameBufferTexture,fragTexCoord);\n"
-"}\n"
-"\n"
-"void writeColorAndMaxScalar(vec4 color,\n"
-" vec4 opacity,\n"
-" float maxValue)\n"
-"{\n"
-" // color framebuffer\n"
-" gl_FragData[0].r = color.r*opacity.a;\n"
-" gl_FragData[0].g = color.g*opacity.a;\n"
-" gl_FragData[0].b = color.b*opacity.a;\n"
-" gl_FragData[0].a=opacity.a;\n"
-" \n"
-" // max scalar framebuffer\n"
-" gl_FragData[1].r=maxValue;\n"
-" gl_FragData[1].g=0.0;\n"
-" gl_FragData[1].b=0.0;\n"
-" gl_FragData[1].a=0.0;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment program with ray cast and 4-dependent-component Maximum Intensity\n"
-"// Projection (MIP) method.\n"
-"// Compilation: header part and the projection part are inserted first.\n"
-"// pos is defined and initialized in header\n"
-"// rayDir is defined in header and initialized in the projection part\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform sampler3D dataSetTexture;\n"
-"uniform sampler1D opacityTexture;\n"
-"\n"
-"uniform vec3 lowBounds;\n"
-"uniform vec3 highBounds;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"float tMax;\n"
-"\n"
-"// Sub-functions, depending on cropping mode\n"
-"float initialMaxValue();\n"
-"vec4 initialColor();\n"
-"void writeColorAndMaxScalar(vec4 color,\n"
-" vec4 opacity,\n"
-" float maxValue);\n"
-"\n"
-"void trace(void)\n"
-"{\n"
-" // Max intensity is the lowest value.\n"
-" float maxValue=initialMaxValue();\n"
-" vec4 color=initialColor();\n"
-" bool inside=true;\n"
-" float t=0.0;\n"
-" vec4 sample;\n"
-" bool changed=false;\n"
-" \n"
-" // We NEED two nested while loops. It is a trick to work around hardware\n"
-" // limitation about the maximum number of loops.\n"
-" while(inside)\n"
-" {\n"
-" while(inside)\n"
-" {\n"
-" sample=texture3D(dataSetTexture,pos);\n"
-" if(sample.w>maxValue)\n"
-" {\n"
-" changed=true;\n"
-" maxValue=sample.w;\n"
-" color=sample;\n"
-" }\n"
-" pos=pos+rayDir;\n"
-" t+=1.0;\n"
-" \n"
-" // yes, t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" // && all(lessThanEqual(pos,highBounds));\n"
-" // looks better but the latest nVidia 177.80 has a bug...\n"
-" inside=t<tMax && pos.x>=lowBounds.x && pos.y>=lowBounds.y\n"
-" && pos.z>=lowBounds.z && pos.x<=highBounds.x && pos.y<=highBounds.y\n"
-" && pos.z<=highBounds.z;\n"
-" }\n"
-" }\n"
-" \n"
-" if(changed)\n"
-" {\n"
-" vec4 opacity=texture1D(opacityTexture,maxValue);\n"
-" writeColorAndMaxScalar(color,opacity,maxValue);\n"
-" }\n"
-" else\n"
-" {\n"
-" discard;\n"
-" }\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the 4-component Maximum Intensity\n"
-"// Projection (MIP) method when cropping is off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"float initialMaxValue()\n"
-"{\n"
-" return 0.0;\n"
-"}\n"
-"\n"
-"vec4 initialColor()\n"
-"{\n"
-" return vec4(0.0,0.0,0.0,0.0);\n"
-"}\n"
-"\n"
-"void writeColorAndMaxScalar(vec4 color,\n"
-" vec4 opacity,\n"
-" float maxValue)\n"
-"{\n"
-" // maxValue is not used\n"
-" \n"
-" // color framebuffer\n"
-" gl_FragColor.r = color.r*opacity.a;\n"
-" gl_FragColor.g = color.g*opacity.a;\n"
-" gl_FragColor.b = color.b*opacity.a;\n"
-" gl_FragColor.a=opacity.a;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MIPFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MIPFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MIPFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MIPFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment program with ray cast and Maximum Intensity Projection (MIP)\n"
-"// method.\n"
-"// Compilation: header part and the projection part are inserted first.\n"
-"// pos is defined and initialized in header\n"
-"// rayDir is defined in header and initialized in the projection part\n"
-"// initMaxValue() and writeColorAndMaxScalar are defined in some specific\n"
-"// file depending on cropping flag being on or off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform sampler3D dataSetTexture;\n"
-"uniform sampler1D colorTexture;\n"
-"uniform sampler1D opacityTexture;\n"
-"\n"
-"uniform vec3 lowBounds;\n"
-"uniform vec3 highBounds;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"float tMax;\n"
-"\n"
-"// Sub-functions, depending on cropping mode\n"
-"float initialMaxValue();\n"
-"void writeColorAndMaxScalar(vec4 sample,\n"
-" vec4 opacity,\n"
-" float maxValue);\n"
-"\n"
-"void trace(void)\n"
-"{\n"
-" // Max intensity is the lowest value.\n"
-" float maxValue=initialMaxValue();\n"
-" bool inside=true;\n"
-" vec4 sample;\n"
-" \n"
-" float t=0.0;\n"
-" // We NEED two nested while loops. It is trick to work around hardware\n"
-" // limitation about the maximum number of loops.\n"
-" while(inside)\n"
-" {\n"
-" while(inside)\n"
-" {\n"
-" sample=texture3D(dataSetTexture,pos);\n"
-" maxValue=max(maxValue,sample.r);\n"
-" pos=pos+rayDir;\n"
-" t+=1.0;\n"
-" \n"
-" // yes, t<tMax && all(greaterThanEqual(pos,lowBounds))\n"
-" // && all(lessThanEqual(pos,highBounds));\n"
-" // looks better but the latest nVidia 177.80 has a bug...\n"
-" inside=t<tMax && pos.x>=lowBounds.x && pos.y>=lowBounds.y\n"
-" && pos.z>=lowBounds.z && pos.x<=highBounds.x && pos.y<=highBounds.y\n"
-" && pos.z<=highBounds.z;\n"
-" }\n"
-" }\n"
-"\n"
-" sample=texture1D(colorTexture,maxValue);\n"
-" vec4 opacity=texture1D(opacityTexture,maxValue);\n"
-" \n"
-" writeColorAndMaxScalar(sample,opacity,maxValue);\n"
-"}\n"
-"\n";
-
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Implementation of some functions used by the Maximum Intensity projection\n"
-"// (MIP) method when cropping is off.\n"
-"\n"
-"#version 110\n"
-"\n"
-"float initialMaxValue()\n"
-"{\n"
-" return 0.0;\n"
-"}\n"
-"\n"
-"void writeColorAndMaxScalar(vec4 sample,\n"
-" vec4 opacity,\n"
-" float maxValue)\n"
-"{\n"
-" // we don't need to write maxValue to a buffer when there is no cropping.\n"
-" // color framebuffer\n"
-" gl_FragColor.r =sample.r * opacity.a;\n"
-" gl_FragColor.g =sample.g * opacity.a;\n"
-" gl_FragColor.b =sample.b * opacity.a;\n"
-" gl_FragColor.a=opacity.a;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_OneComponentFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_OneComponentFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_OneComponentFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_OneComponentFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment shader that implements scalarFromValue() and colorFromValue() in\n"
-"// the case of a one-component dataset.\n"
-"// The functions are used in composite mode.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// \"value\" is a sample of the dataset.\n"
-"// Think of \"value\" as an object.\n"
-"\n"
-"uniform sampler1D colorTexture;\n"
-"\n"
-"float scalarFromValue(vec4 value)\n"
-"{\n"
-" return value.x;\n"
-"}\n"
-"\n"
-"vec4 colorFromValue(vec4 value)\n"
-"{\n"
-" return texture1D(colorTexture,value.x);\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Parallel projection.\n"
-"\n"
-"#version 110\n"
-"\n"
-"uniform vec3 parallelRayDirection;\n"
-"\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"// Defined in the right projection method.\n"
-"void incrementalRayDirection()\n"
-"{\n"
-" rayDir=parallelRayDirection;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Perspective projection.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"// Camera position in texture space\n"
-"uniform vec3 cameraPosition;\n"
-"// Sample distance in world space\n"
-"uniform float sampleDistance;\n"
-"// Matrix coefficients: diagonal (a11,a22,a33)\n"
-"uniform vec3 matrix1;\n"
-"// Matrix coefficients: others (2a12,2a23,2a13)\n"
-"uniform vec3 matrix2;\n"
-"\n"
-"// Defined in the right projection method.\n"
-"void incrementalRayDirection()\n"
-"{\n"
-" // Direction of the ray in texture space, not normalized.\n"
-" rayDir=pos-cameraPosition;\n"
-" \n"
-" // x^2, y^2, z^2\n"
-" vec3 normDir=rayDir*rayDir;\n"
-" normDir.x=dot(normDir,matrix1);\n"
-" \n"
-" // xy,yz,zx\n"
-" vec3 coefs=rayDir*rayDir.yxz;\n"
-" coefs.x=dot(coefs,matrix2);\n"
-"\n"
-" // n^2\n"
-" normDir.x=normDir.x+coefs.x;\n"
-" \n"
-" // 1/n\n"
-" // normDir=1/sqrt(normDir)\n"
-" normDir.x=inversesqrt(normDir.x);\n"
-" \n"
-" // Final scale factor for the ray direction in texture space\n"
-" // normDir=normDir*sampleDistance\n"
-" normDir.x=normDir.x*sampleDistance;\n"
-" // Now, rayDir is the incremental direction in texture space\n"
-" rayDir=rayDir*normDir.x;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// This fragment shader scales and biases a framebuffer passed as a texture.\n"
-"// Incoming color from the texture is pre-multiplied by alpha.\n"
-"// It does not affect the alpha component.\n"
-"// Passing the framebuffer as a texture allows the use of a reduction factor\n"
-"// compared to the size of the final image.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// Framebuffer to scale.\n"
-"uniform sampler2D frameBufferTexture;\n"
-"uniform float scale;\n"
-"uniform float bias;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec4 color=texture2D(frameBufferTexture,gl_TexCoord[0].xy);\n"
-" if(color.a==0.0)\n"
-" {\n"
-" discard;\n"
-" }\n"
-" // As incoming color is pre-multiplied by alpha, the bias has to be\n"
-" // multiplied by alpha before adding it.\n"
-" gl_FragColor.r=color.r*scale+bias*color.a;\n"
-" gl_FragColor.g=color.g*scale+bias*color.a;\n"
-" gl_FragColor.b=color.b*scale+bias*color.a;\n"
-" gl_FragColor.a=color.a;\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_ShadeFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_ShadeFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_ShadeFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_ShadeFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"// Fragment shader that implements initShade() and shade() in the case of\n"
-"// shading.\n"
-"// The functions are used in composite mode.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// \"value\" is a sample of the dataset.\n"
-"// Think of \"value\" as an object.\n"
-"\n"
-"// from 1- vs 4-component shader.\n"
-"vec4 colorFromValue(vec4 value);\n"
-"\n"
-"uniform sampler3D dataSetTexture; // need neighbors for gradient\n"
-"\n"
-"// Change-of-coordinate matrix from eye space to texture space\n"
-"uniform mat3 eyeToTexture3;\n"
-"uniform mat4 eyeToTexture4;\n"
-"\n"
-"// Tranpose of Change-of-coordinate matrix from texture space to eye space\n"
-"uniform mat3 transposeTextureToEye;\n"
-"\n"
-"// Used to compute the gradient.\n"
-"uniform vec3 cellStep;\n"
-"uniform vec3 cellScale;\n"
-"\n"
-"\n"
-"// Entry position (global scope), updated in the loop\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"\n"
-"// local to the implementation, shared between initShade() and shade()\n"
-"const vec3 minusOne=vec3(-1.0,-1.0,-1.0);\n"
-"const vec4 clampMin=vec4(0.0,0.0,0.0,0.0);\n"
-"const vec4 clampMax=vec4(1.0,1.0,1.0,1.0);\n"
-"\n"
-"vec3 xvec;\n"
-"vec3 yvec;\n"
-"vec3 zvec;\n"
-"vec3 wReverseRayDir;\n"
-"vec3 lightPos;\n"
-"vec3 ldir;\n"
-"vec3 h;\n"
-"vec4 hPos; // homogeneous position\n"
-"\n"
-"// ----------------------------------------------------------------------------\n"
-"void initShade()\n"
-"{\n"
-" xvec=vec3(cellStep.x,0.0,0.0); // 0.01\n"
-" yvec=vec3(0.0,cellStep.y,0.0);\n"
-" zvec=vec3(0.0,0.0,cellStep.z);\n"
-" \n"
-" // Reverse ray direction in eye space\n"
-" wReverseRayDir=eyeToTexture3*rayDir;\n"
-" wReverseRayDir=wReverseRayDir*minusOne;\n"
-" wReverseRayDir=normalize(wReverseRayDir);\n"
-" \n"
-" // Directonal light: w==0\n"
-" if(gl_LightSource[0].position.w==0.0)\n"
-" {\n"
-" ldir=gl_LightSource[0].position.xyz;\n"
-" ldir=normalize(ldir);\n"
-" h=normalize(ldir+wReverseRayDir);\n"
-" }\n"
-" else\n"
-" {\n"
-" lightPos=gl_LightSource[0].position.xyz/gl_LightSource[0].position.w;\n"
-" hPos.w=1.0; // used later\n"
-" }\n"
-"}\n"
-"\n"
-"// ----------------------------------------------------------------------------\n"
-"vec4 shade(vec4 value)\n"
-"{\n"
-" vec3 g1;\n"
-" vec3 g2;\n"
-" vec4 tmp;\n"
-" float att;\n"
-" float spot;\n"
-" \n"
-" g1.x=texture3D(dataSetTexture,pos+xvec).x;\n"
-" g1.y=texture3D(dataSetTexture,pos+yvec).x;\n"
-" g1.z=texture3D(dataSetTexture,pos+zvec).x;\n"
-" g2.x=texture3D(dataSetTexture,pos-xvec).x;\n"
-" g2.y=texture3D(dataSetTexture,pos-yvec).x;\n"
-" g2.z=texture3D(dataSetTexture,pos-zvec).x;\n"
-" // g1-g2 is the gradient in texture coordinates\n"
-" // the result is the normalized gradient in eye coordinates.\n"
-" \n"
-" g2=g1-g2;\n"
-" g2=g2*cellScale;\n"
-" \n"
-" float normalLength=length(g2);\n"
-" if(normalLength>0.0)\n"
-" {\n"
-" g2=normalize(transposeTextureToEye*g2);\n"
-" }\n"
-" else\n"
-" {\n"
-" g2=vec3(0.0,0.0,0.0);\n"
-" }\n"
-" \n"
-" vec4 color=colorFromValue(value);\n"
-" \n"
-" // initialize color to 0.0\n"
-" vec4 finalColor=vec4(0.0,0.0,0.0,0.0); \n"
-" \n"
-" if(gl_LightSource[0].position.w!=0.0)\n"
-" {\n"
-" // We need to know the eye position only if light is positional\n"
-" // ldir= vertex position in eye coordinates\n"
-" hPos.xyz=pos;\n"
-" tmp=eyeToTexture4*hPos;\n"
-" ldir=tmp.xyz/tmp.w;\n"
-" // ldir=light direction\n"
-" ldir=lightPos-ldir;\n"
-" float sqrDistance=dot(ldir,ldir);\n"
-" ldir=normalize(ldir);\n"
-" h=normalize(ldir+wReverseRayDir);\n"
-" att=1.0/(gl_LightSource[0].constantAttenuation+gl_LightSource[0].linearAttenuation*sqrt(sqrDistance)+gl_LightSource[0].quadraticAttenuation*sqrDistance);\n"
-" }\n"
-" else\n"
-" {\n"
-" att=1.0;\n"
-" }\n"
-" \n"
-" if(att>0.0)\n"
-" {\n"
-" if(gl_LightSource[0].spotCutoff==180.0)\n"
-" {\n"
-" spot=1.0;\n"
-" }\n"
-" else\n"
-" {\n"
-" float coef=-dot(ldir,gl_LightSource[0].spotDirection);\n"
-" if(coef>=gl_LightSource[0].spotCosCutoff)\n"
-" {\n"
-" spot=pow(coef,gl_LightSource[0].spotExponent);\n"
-" }\n"
-" else\n"
-" {\n"
-" spot=0.0;\n"
-" }\n"
-" }\n"
-" if(spot>0.0)\n"
-" {\n"
-" // LIT operation...\n"
-" float nDotL=dot(g2,ldir);\n"
-" float nDotH=dot(g2,h);\n"
-" \n"
-" // separate nDotL and nDotH for two-sided shading, otherwise we\n"
-" // get black spots.\n"
-" \n"
-" if(nDotL<0.0) // two-sided shading\n"
-" {\n"
-" nDotL=-nDotL;\n"
-" }\n"
-" \n"
-" if(nDotH<0.0) // two-sided shading\n"
-" {\n"
-" nDotH=-nDotH;\n"
-" }\n"
-" // ambient term for this light\n"
-" finalColor+=gl_FrontLightProduct[0].ambient;\n"
-" \n"
-" // diffuse term for this light\n"
-" if(nDotL>0.0)\n"
-" {\n"
-// WORKAROUND FIX: gl_FrontLightProduct[0].diffuse seems to be not transferred to ATI cards
-//" finalColor+=(gl_FrontLightProduct[0].diffuse*nDotL)*color;\n"
-// just using a white light now
-" finalColor+=(0.8*nDotL)*color;\n"
-" }\n"
-" \n"
-" // specular term for this light\n"
-" float shininessFactor=pow(nDotH,gl_FrontMaterial.shininess);\n"
-" finalColor+=gl_FrontLightProduct[0].specular*shininessFactor;\n"
-" finalColor*=att*spot;\n"
-" }\n"
-" }\n"
-" \n"
-" // scene ambient term\n"
-// WORKAROUND FIX: gl_FrontLightModelProduct.sceneColor seems to be not transferred to ATI cards
-//" finalColor+=gl_FrontLightModelProduct.sceneColor*color;\n"
-// just using a dim ambient light
-" finalColor+=0.3*color;\n"
-" \n"
-" // clamp. otherwise we get black spots\n"
-" finalColor=clamp(finalColor,clampMin,clampMax);\n"
-" \n"
-" return finalColor;\n"
-"}\n"
-"\n";
-
-
-
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_NoShadeFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_NoShadeFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_NoShadeFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_NoShadeFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment shader that implements initShade() and shade() in the case of no\n"
-"// shading.\n"
-"// The functions are used in composite mode.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// \"value\" is a sample of the dataset.\n"
-"// Think of \"value\" as an object.\n"
-"\n"
-"// from 1- vs 4-component shader.\n"
-"vec4 colorFromValue(vec4 value);\n"
-"\n"
-"// ----------------------------------------------------------------------------\n"
-"void initShade()\n"
-"{\n"
-" // empty, nothing to do.\n"
-"}\n"
-"\n"
-"// ----------------------------------------------------------------------------\n"
-"vec4 shade(vec4 value)\n"
-"{\n"
-" return colorFromValue(value);\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_HeaderFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_HeaderFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_HeaderFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_HeaderFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"#version 110\n"
-"\n"
-"// Depth map of the polygonal geometry\n"
-"uniform sampler2D depthTexture;\n"
-"\n"
-"// 2D noise texture to jitter the starting point of the ray in order to\n"
-"// remove patterns when the opacity transfer function make the data on the\n"
-"// border of the dataset to be visible.\n"
-"uniform sampler2D noiseTexture;\n"
-"\n"
-"uniform vec2 windowLowerLeftCorner;\n"
-"uniform vec2 invOriginalWindowSize;\n"
-"uniform vec2 invWindowSize;\n"
-"\n"
-"// Change-of-coordinate matrix from eye space to texture space\n"
-"uniform mat4 textureToEye;\n"
-"\n"
-"// Entry position (global scope)\n"
-"vec3 pos;\n"
-"// Incremental vector in texture space (global scope)\n"
-"vec3 rayDir;\n"
-"\n"
-"// Abscissa along the ray of the point on the depth map\n"
-"// tracing stops when t>=tMax\n"
-"float tMax;\n"
-"\n"
-"// 2D Texture fragment coordinates [0,1] from fragment coordinates\n"
-"// the frame buffer texture has the size of the plain buffer but\n"
-"// we use a fraction of it. The texture coordinates is less than 1 if\n"
-"// the reduction factor is less than 1.\n"
-"vec2 fragTexCoord;\n"
-"\n"
-"// Defined in the right projection method.\n"
-"// May use pos in global scope as input.\n"
-"// Use rayDir in global scope as output.\n"
-"void incrementalRayDirection();\n"
-"void trace();\n"
-"\n"
-"void main()\n"
-"{\n"
-"\n"
-" // device coordinates are between -1 and 1\n"
-" // we need texture coordinates between 0 and 1\n"
-" // the depth buffer has the original size buffer.\n"
-" fragTexCoord=(gl_FragCoord.xy-windowLowerLeftCorner)*invWindowSize;\n"
-" vec4 depth=texture2D(depthTexture,fragTexCoord);\n"
-" if(gl_FragCoord.z>=depth.x) // depth test\n"
-" {\n"
-" discard;\n"
-" }\n"
-" \n"
-" // color buffer or max scalar buffer have a reduced size.\n"
-" fragTexCoord=(gl_FragCoord.xy-windowLowerLeftCorner)*invOriginalWindowSize;\n"
-" // Abscissa of the point on the depth buffer along the ray.\n"
-" // point in texture coordinates\n"
-" vec4 maxPoint;\n"
-" \n"
-" // from window coordinates to normalized device coordinates\n"
-" maxPoint.x=(gl_FragCoord.x-windowLowerLeftCorner.x)*2.0*invWindowSize.x-1.0;\n"
-" maxPoint.y=(gl_FragCoord.y-windowLowerLeftCorner.y)*2.0*invWindowSize.y-1.0;\n"
-" maxPoint.z=(2.0*depth.x-(gl_DepthRange.near+gl_DepthRange.far))/gl_DepthRange.diff;\n"
-" maxPoint.w=1.0;\n"
-" \n"
-" // from normalized device coordinates to eye coordinates\n"
-" maxPoint=gl_ProjectionMatrixInverse*maxPoint;\n"
-" \n"
-" // from eye coordinates to texture coordinates\n"
-" maxPoint=textureToEye*maxPoint;\n"
-" // homogeneous to cartesian coordinates\n"
-" maxPoint/=maxPoint.w;\n"
-" \n"
-" // Entry position. divide by q.\n"
-" // pos=gl_TexCoord[0].xyz/gl_TexCoord[0].w;\n"
-" \n"
-" pos.x=gl_TexCoord[0].x/gl_TexCoord[0].w;\n"
-" pos.y=gl_TexCoord[0].y/gl_TexCoord[0].w;\n"
-" pos.z=gl_TexCoord[0].z/gl_TexCoord[0].w;\n"
-" \n"
-" // Incremental vector in texture space. Computation depends on the\n"
-" // type of projection (parallel or perspective)\n"
-" incrementalRayDirection();\n"
-" \n"
-" vec4 noiseValue=texture2D(noiseTexture,pos.xy*100.0); // with repeat/tiling mode on the noise texture.\n"
-" \n"
-" pos+=(noiseValue.x)*rayDir;\n"
-"\n"
-" tMax=length(maxPoint.xyz-pos.xyz) /length(rayDir);\n"
-"\n"
-"\n"
-" // Tracing method. Set the final fragment color.\n"
-" trace();\n"
-"}\n"
-"\n";
-
-/* DO NOT EDIT.
- * Generated by ..\bin\Release\vtkEncodeString.exe
- *
- * Define the vtkMitkGPUVolumeRayCastMapper_FourComponentsFS string.
- *
- * Generated from file: V:/windows/source/VTK560/VolumeRendering/vtkMitkGPUVolumeRayCastMapper_FourComponentsFS.glsl
- */
-const char *vtkMitkGPUVolumeRayCastMapper_FourComponentsFS =
-"/*=========================================================================\n"
-"\n"
-" Program: Visualization Toolkit\n"
-" Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper_FourComponentsFS.glsl,v $\n"
-"\n"
-" Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n"
-" All rights reserved.\n"
-" See Copyright.txt or http://www.kitware.com/Copyright.htm for details.\n"
-"\n"
-" This software is distributed WITHOUT ANY WARRANTY; without even\n"
-" the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n"
-" PURPOSE. See the above copyright notice for more information.\n"
-"\n"
-"=========================================================================*/\n"
-"\n"
-"// Fragment shader that implements scalarFromValue() and colorFromValue() in\n"
-"// the case of a one-component dataset.\n"
-"// The functions are used in composite mode.\n"
-"\n"
-"#version 110\n"
-"\n"
-"// \"value\" is a sample of the dataset.\n"
-"// Think of \"value\" as an object.\n"
-"\n"
-"float scalarFromValue(vec4 value)\n"
-"{\n"
-" return value.w;\n"
-"}\n"
-"\n"
-"vec4 colorFromValue(vec4 value)\n"
-"{\n"
-" return vec4(value.xyz,1.0);\n"
-"}\n"
-"\n";
-
-#endif
diff --git a/Modules/Ext/Resources/Interactions/AffineDeformationConfig.xml b/Modules/Ext/Resources/Interactions/AffineDeformationConfig.xml
deleted file mode 100644
index 207435e14d..0000000000
--- a/Modules/Ext/Resources/Interactions/AffineDeformationConfig.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<config>
- <event_variant name="MovePointer" class="MouseMoveEvent" >
- </event_variant>
- <event_variant name="InitDeformation" class="MousePressEvent">
- <attribute name="EventButton" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="ObjectDeformation" class="MouseMoveEvent">
- <attribute name="ButtonState" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="EndDeformation" class="MouseReleaseEvent">
- <attribute name="EventButton" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="ScaleRadius" class="MouseWheelEvent">
- </event_variant>
-</config>
diff --git a/Modules/Ext/Resources/Interactions/AffineInteraction3D.xml b/Modules/Ext/Resources/Interactions/AffineInteraction3D.xml
deleted file mode 100644
index 36d4e14d15..0000000000
--- a/Modules/Ext/Resources/Interactions/AffineInteraction3D.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<statemachine NAME="Affine">
- <state name="start" startstate="true" >
- <transition event_class="InteractionPositionEvent" event_variant="MovePointer" target="select">
- <condition name="isOverObject"/>
- <action name="selectObject"/>
- </transition>
- </state>
- <state name="select" >
- <transition event_class="InteractionPositionEvent" event_variant="MovePointer" target="start">
- <condition name="isOverObject" inverted="true" />
- <action name="deselectObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="MovePointer" target="select">
- <condition name="isOverObject"/>
- <action name="selectObject"/>
- </transition>
- <transition event_class="InternalEvent" event_variant="LeaveRenderWindow" target="start">
- <action name="deselectObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="ScaleRadius" target="select">
- <action name="scaleRadius"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="InitTranslation" target="translate">
- <action name="initTranslate"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="InitRotation" target="rotate">
- <action name="initRotate"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="InitDeformation" target="deform">
- <action name="initDeformation"/>
- </transition>
- </state>
- <state name="translate" >
- <transition event_class="InteractionPositionEvent" event_variant="ObjectTranslation" target="translate">
- <action name="translateObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="EndTranslation" target="start">
- <condition name="isOverObject" inverted="true"/>
- <action name="deselectObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="EndTranslation" target="select">
- <condition name="isOverObject"/>
- <action name="selectObject"/>
- </transition>
- </state>
- <state name="rotate" >
- <transition event_class="InteractionPositionEvent" event_variant="ObjectRotation" target="rotate">
- <action name="rotateObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="EndRotation" target="start">
- <condition name="isOverObject" inverted="true"/>
- <action name="deselectObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="EndRotation" target="select">
- <condition name="isOverObject" />
- <action name="selectObject"/>
- </transition>
- </state>
- <state name="deform" >
- <transition event_class="InteractionPositionEvent" event_variant="ObjectDeformation" target="deform">
- <action name="deformObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="EndDeformation" target="start">
- <condition name="isOverObject" inverted="true"/>
- <action name="deselectObject"/>
- </transition>
- <transition event_class="InteractionPositionEvent" event_variant="EndDeformation" target="select">
- <condition name="isOverObject"/>
- <action name="selectObject"/>
- </transition>
- </state>
-</statemachine>
diff --git a/Modules/Ext/Resources/Interactions/AffineRotationConfig.xml b/Modules/Ext/Resources/Interactions/AffineRotationConfig.xml
deleted file mode 100644
index fb9c6fe6d1..0000000000
--- a/Modules/Ext/Resources/Interactions/AffineRotationConfig.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<config>
- <event_variant name="MovePointer" class="MouseMoveEvent">
- </event_variant>
- <event_variant name="InitRotation" class="MousePressEvent">
- <attribute name="EventButton" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="ObjectRotation" class="MouseMoveEvent" >
- <attribute name="ButtonState" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="EndRotation" class="MouseReleaseEvent">
- <attribute name="EventButton" value="LeftMouseButton"/>
- </event_variant>
-</config>
diff --git a/Modules/Ext/Resources/Interactions/AffineTranslationConfig.xml b/Modules/Ext/Resources/Interactions/AffineTranslationConfig.xml
deleted file mode 100644
index 4bbbe5c8be..0000000000
--- a/Modules/Ext/Resources/Interactions/AffineTranslationConfig.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<config>
- <event_variant name="MovePointer" class="MouseMoveEvent" >
- </event_variant>
- <event_variant name="InitTranslation" class="MousePressEvent">
- <attribute name="EventButton" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="ObjectTranslation" class="MouseMoveEvent">
- <attribute name="ButtonState" value="LeftMouseButton"/>
- </event_variant>
- <event_variant name="EndTranslation" class="MouseReleaseEvent">
- <attribute name="EventButton" value="LeftMouseButton"/>
- </event_variant>
-</config>
diff --git a/Modules/Ext/Testing/files.cmake b/Modules/Ext/Testing/files.cmake
deleted file mode 100644
index fab0398af5..0000000000
--- a/Modules/Ext/Testing/files.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-set(MODULE_TESTS
- mitkDataNodeExtTest.cpp
- mitkExternalToolsTest.cpp
- # mitkPipelineSmartPointerCorrectnessTest.cpp
- mitkPlaneFitTest.cpp
- mitkPointLocatorTest.cpp
-)
-set(MODULE_IMAGE_TESTS
- mitkCylindricToCartesianFilterTest.cpp #only runs on images
-)
-
-set(MODULE_TESTIMAGES
- US4DCyl.nrrd
- Pic3D.nrrd
- Pic2DplusT.nrrd
- BallBinary30x30x30.nrrd
- Png2D-bw.png
-)
-set(MODULE_TESTSURFACES
- binary.stl
- ball.stl
-)
diff --git a/Modules/Ext/Testing/mitkCylindricToCartesianFilterTest.cpp b/Modules/Ext/Testing/mitkCylindricToCartesianFilterTest.cpp
deleted file mode 100644
index 989e7c7fca..0000000000
--- a/Modules/Ext/Testing/mitkCylindricToCartesianFilterTest.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkImage.h"
-#include "mitkDataNodeFactory.h"
-#include "mitkCylindricToCartesianFilter.h"
-#include "mitkImageSliceSelector.h"
-
-#include <fstream>
-int mitkCylindricToCartesianFilterTest(int argc, char* argv[])
-{
- std::cout << "Loading file: ";
- if(argc==0)
- {
- std::cout<<"no file specified [FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- mitk::Image::Pointer image = NULL;
- mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
- try
- {
- factory->SetFileName( argv[1] );
- factory->Update();
-
- if(factory->GetNumberOfOutputs()<1)
- {
- std::cout<<"file could not be loaded [FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- mitk::DataNode::Pointer node = factory->GetOutput( 0 );
- image = dynamic_cast<mitk::Image*>(node->GetData());
- if(image.IsNull())
- {
- std::cout<<"file not an image - test will not be applied [PASSED]"<<std::endl;
- std::cout<<"[TEST DONE]"<<std::endl;
- return EXIT_SUCCESS;
- }
- }
- catch ( itk::ExceptionObject & ex )
- {
- std::cout << "Exception: " << ex << "[FAILED]" << std::endl;
- return EXIT_FAILURE;
- }
-
- //Use CylindricToCartesianFilter
- mitk::CylindricToCartesianFilter::Pointer cyl2cart = mitk::CylindricToCartesianFilter::New();
- cyl2cart->SetInput(image);
- cyl2cart->SetTargetXSize( 64 );
-
- //Take a slice
- mitk::ImageSliceSelector::Pointer slice = mitk::ImageSliceSelector::New();
- slice->SetInput(cyl2cart->GetOutput());
- slice->SetSliceNr(1);
- slice->Update();
-
- std::cout << "Testing IsInitialized(): ";
- if(slice->GetOutput()->IsInitialized()==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing IsSliceSet(): ";
- if(slice->GetOutput()->IsSliceSet(0)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- if(image->GetDimension(3) > 1)
- {
- int time=image->GetDimension(3)-1;
-
- std::cout << "Testing 3D+t: Setting time to " << time << ": ";
- slice->SetTimeNr(time);
- if(slice->GetTimeNr()!=time)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing 3D+t: Updating slice: ";
- slice->Update();
- if(slice->GetOutput()->IsInitialized()==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing 3D+t: IsSliceSet(): ";
- if(slice->GetOutput()->IsSliceSet(0)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing 3D+t: First slice in reader available: ";
- if(image->IsSliceSet(0, time)==false)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- std::cout<<"[PASSED]"<<std::endl;
- }
-
- std::cout<<"[TEST DONE]"<<std::endl;
- return EXIT_SUCCESS;
-}
diff --git a/Modules/Ext/Testing/mitkDataNodeExtTest.cpp b/Modules/Ext/Testing/mitkDataNodeExtTest.cpp
deleted file mode 100644
index cd3a544394..0000000000
--- a/Modules/Ext/Testing/mitkDataNodeExtTest.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkDataNode.h"
-
-#include <vtkWindow.h>
-#include "mitkVtkPropRenderer.h"
-
-#include "mitkTestingMacros.h"
-#include "mitkGlobalInteraction.h"
-
-#include <iostream>
-
-//Basedata Test
-#include <mitkItkBaseDataAdapter.h>
-#include <mitkMesh.h>
-#include <mitkSeedsImage.h>
-#include <mitkBoundingObject.h>
-#include <mitkUnstructuredGrid.h>
-
-//Mapper Test
-#include <mitkMapper.h>
-#include <mitkVtkMapper.h>
-#include <mitkGLMapper.h>
-#include <mitkLineMapper2D.h>
-
-#include <mitkLineVtkMapper3D.h>
-
-//Interactors
-#include <mitkConnectPointsInteractor.h>
-#include <mitkPointInteractor.h>
-#include <mitkPointSelectorInteractor.h>
-#include <mitkSeedsInteractor.h>
-#include <mitkDisplayPointSetInteractor.h>
-
-//Propertylist Test
-#include <mitkAnnotationProperty.h>
-#include <mitkClippingProperty.h>
-#include <mitkColorProperty.h>
-#include <mitkEnumerationProperty.h>
-#include <mitkGridRepresentationProperty.h>
-#include <mitkGridVolumeMapperProperty.h>
-#include <mitkOrganTypeProperty.h>
-#include <mitkVtkInterpolationProperty.h>
-#include <mitkVtkRepresentationProperty.h>
-#include <mitkVtkResliceInterpolationProperty.h>
-#include <mitkVtkScalarModeProperty.h>
-
-
-/**
- * Extended test for mitk::DataNode. A number of tests from the core test
- * mitkDataNodeTest are assumed to pass!
- */
-class mitkDataNodeExtTestClass { public:
-
-static void TestDataSetting(mitk::DataNode::Pointer dataNode)
-{
-
- mitk::BaseData::Pointer baseData;
-
- //NULL pointer Test
- dataNode->SetData(baseData);
- MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" )
-
- baseData = mitk::ItkBaseDataAdapter::New();
- dataNode->SetData(baseData);
- MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ItkBaseDataAdapter object was set correctly" )
-
- baseData = mitk::Mesh::New();
- dataNode->SetData(baseData);
- MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Mesh object was set correctly" )
-
- baseData = mitk::SeedsImage::New();
- dataNode->SetData(baseData);
- MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a SeedsImage object was set correctly" )
-
- baseData = mitk::BoundingObject::New();
- dataNode->SetData(baseData);
- MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a BoundingObject object was set correctly" )
-
- baseData = mitk::UnstructuredGrid::New();
- dataNode->SetData(baseData);
- MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a UnstructuredGrid object was set correctly" )
-}
-
-static void TestMapperSetting(mitk::DataNode::Pointer dataNode)
-{
- //tests the SetMapper() method
- //in dataNode is a mapper vector which can be accessed by index
- //in this test method we use only slot 0 (filled with null) and slot 1
- //so we also test the destructor of the mapper classes
- mitk::Mapper::Pointer mapper;
-
- dataNode->SetMapper(0,mapper);
- MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" )
-
- mapper = mitk::LineMapper2D::New();
- dataNode->SetMapper(1,mapper);
- MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineMapper2D was set correctly" )
- MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
-
- //linker error
- //mapper = mitk::LineVtkMapper3D::New();
- //dataNode->SetMapper(1,mapper);
- //MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineVtkMapper3D was set correctly" )
- //MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
-}
-
-static void TestInteractorSetting(mitk::DataNode::Pointer dataNode)
-{
-
- //this method tests the SetInteractor() and GetInteractor methods
- //the Interactor base class calls the DataNode->SetInteractor method
-
- mitk::Interactor::Pointer interactor;
-
- MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a NULL pointer was set correctly (Interactor)" )
-
- interactor = mitk::ConnectPointsInteractor::New("AffineInteractions click to select", dataNode);
- MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a ConnectPointsInteractor was set correctly" )
-
- interactor = mitk::PointInteractor::New("AffineInteractions click to select", dataNode);
- MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointInteractor was set correctly" )
-
- interactor = mitk::PointSelectorInteractor::New("AffineInteractions click to select", dataNode);
- MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointSelectorInteractor was set correctly" )
-
- interactor = mitk::SeedsInteractor::New("AffineInteractions click to select", dataNode);
- MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a SeedsInteractor was set correctly" )
-
- interactor = mitk::DisplayPointSetInteractor::New("AffineInteractions click to select", dataNode);
- MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a DisplayPointSetInteractor was set correctly" )
-}
-
-};
-
-int mitkDataNodeExtTest(int /* argc */, char* /*argv*/[])
-{
- // always start with this!
- MITK_TEST_BEGIN("DataNodeExt")
-
- // Global interaction must(!) be initialized
- mitk::GlobalInteraction::GetInstance()->Initialize("global");
-
- // let's create an object of our class
- mitk::DataNode::Pointer myDataNode = mitk::DataNode::New();
-
- // first test: did this work?
- // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
- // it makes no sense to continue without an object.
- MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation")
-
- //test setData() Method
- mitkDataNodeExtTestClass::TestDataSetting(myDataNode);
- mitkDataNodeExtTestClass::TestMapperSetting(myDataNode);
-
- //note, that no data is set to the dataNode
- mitkDataNodeExtTestClass::TestInteractorSetting(myDataNode);
-
- // write your own tests here and use the macros from mitkTestingMacros.h !!!
- // do not write to std::cout and do not return from this function yourself!
-
- // always end with this!
- MITK_TEST_END()
-}
diff --git a/Modules/Ext/Testing/mitkExternalToolsTest.cpp b/Modules/Ext/Testing/mitkExternalToolsTest.cpp
deleted file mode 100644
index 995c65e0d8..0000000000
--- a/Modules/Ext/Testing/mitkExternalToolsTest.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include <iostream>
-#include <string>
-
-#include <stdlib.h> // for system() call
-
-#include <itksys/SystemTools.hxx> // for chdir et al.
-
-int mitkExternalToolsTest(int argc, char* argv[])
-{
- return EXIT_SUCCESS; // we'll go back to a CMake solution...
-
-
- std::cout << "Got " << argc << " parameters" << std::endl;
- if ( argc == 5 )
- {
- // "parse" commandline
- // quote spaces in commandline parameters (all paths/files)
- //std::string cmakeBinary = itksys::SystemTools::EscapeChars( argv[1], " " );
- std::string cmakeBinary = argv[1];
- std::string cmakeGenerator = argv[2];
- std::string mitkBinaryDirectory = argv[3];
- std::string sourceDirectory = argv[4];
-
- // try to configure MITK external project
- std::cout << "Calling CMake as '" << cmakeBinary << "'" << std::endl;
- std::cout << "Calling CMake for generator '" << cmakeGenerator << "'" << std::endl;
- std::cout << "MITK was compiled in '" << mitkBinaryDirectory << "'" << std::endl;
- std::cout << "Configuring project in '" << sourceDirectory << "'" << std::endl;
-
- if( itksys::SystemTools::ChangeDirectory(mitkBinaryDirectory.c_str()) != 0 )
- {
- std::cerr << "Couldn't change to MITK build dir. See output above." << std::endl;
- return EXIT_FAILURE;
- }
-
- std::string oneCommandlineQuote("\"");
-
- std::string commandline( oneCommandlineQuote );
- commandline += cmakeBinary;
- commandline += oneCommandlineQuote;
-
- commandline += " -G ";
- commandline += oneCommandlineQuote;
- commandline += cmakeGenerator;
- commandline += oneCommandlineQuote;
-
- commandline += " -DMITK_DIR:PATH=";
-
- commandline += oneCommandlineQuote;
- commandline += mitkBinaryDirectory;
- commandline += oneCommandlineQuote;
- commandline += " ";
- commandline += oneCommandlineQuote;
- commandline += sourceDirectory;
- commandline += oneCommandlineQuote;
-
- std::cout << "Calling system() with '"
- << commandline
- << "'"
- << std::endl;
-
- int returnCode = system(commandline.c_str());
-
- std::cout << "system() returned " << returnCode << std::endl;
-
- if (returnCode != 0)
- {
- std::cerr << "Configure FAILED. See output above." << std::endl;
- return EXIT_FAILURE;
- }
-
- // try to build MITK external project
-
-#ifdef WIN32
-#else
- commandline = "make";
- // commented out because mbits configures with Qt4. Have to check this monday.
- //returnCode = system(commandline.c_str());
-
- if (returnCode != 0) // make should return 0
- {
- std::cout << "make returned " << returnCode << std::endl;
- std::cerr << "Building the project FAILED. See output above." << std::endl;
- return EXIT_FAILURE;
- }
-
-#endif
- //
- // TODO extend test here to support windows...
- //
- return returnCode;
- }
- else
- {
- std::cout << "Invoke this test with three parameters:" << std::endl;
- std::cout << " 1. CMake binary including necessary path" << std::endl;
- std::cout << " 2. CMake generator name" << std::endl;
- std::cout << " 3. MITK binary path (top-level directory)" << std::endl;
- std::cout << " 4. Source directory containing CMakeLists.txt" << std::endl;
- return EXIT_FAILURE;
- }
-}
-
diff --git a/Modules/Ext/Testing/mitkImageStatisticsCalculatorTest.cpp b/Modules/Ext/Testing/mitkImageStatisticsCalculatorTest.cpp
deleted file mode 100644
index c9e4202fa9..0000000000
--- a/Modules/Ext/Testing/mitkImageStatisticsCalculatorTest.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkStandardFileLocations.h"
-#include "mitkDicomSeriesReader.h"
-#include "mitkTestingMacros.h"
-#include "mitkImageStatisticsCalculator.h"
-#include "mitkPlanarPolygon.h"
-
-#include "mitkDicomSeriesReader.h"
-#include <itkGDCMSeriesFileNames.h>
-
-#include "vtkStreamingDemandDrivenPipeline.h"
-
-
-//#include <QtCore>
-
-/**
- * \brief Test class for mitkImageStatisticsCalculator
- *
- * This test covers:
- * - instantiation of an ImageStatisticsCalculator class
- * - correctness of statistics when using PlanarFigures for masking
- */
-class mitkImageStatisticsCalculatorTestClass
-{
-
-public:
-
- struct testCase
- {
- int id;
- mitk::PlanarFigure::Pointer figure;
- double mean;
- double sd;
- };
-
-
-// calculate statistics for the given image and planarpolygon
-static const mitk::ImageStatisticsCalculator::Statistics TestStatistics( mitk::Image::Pointer image, mitk::PlanarFigure::Pointer polygon )
-{
- mitk::ImageStatisticsCalculator::Pointer statisticsCalculator = mitk::ImageStatisticsCalculator::New();
- statisticsCalculator->SetImage( image );
- statisticsCalculator->SetMaskingModeToPlanarFigure();
- statisticsCalculator->SetPlanarFigure( polygon );
-
- statisticsCalculator->ComputeStatistics();
-
- return statisticsCalculator->GetStatistics();
-}
-
-
-// returns a vector of defined test-cases
-static std::vector<testCase> InitializeTestCases( mitk::Geometry2D::Pointer geom )
-{
- std::vector<testCase> testCases;
-
- {
- /*****************************
- * one whole white pixel
- * -> mean of 255 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 10.5 ; pnt1[1] = 3.5;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5;
- figure1->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 10.5; pnt4[1] = 4.5;
- figure1->SetControlPoint( 3, pnt4, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 255.0;
- test.sd = 0.0;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * half pixel in x-direction (white)
- * -> mean of 255 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 10.0 ; pnt1[1] = 3.5;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5;
- figure1->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 10.0; pnt4[1] = 4.5;
- figure1->SetControlPoint( 3, pnt4, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 255.0;
- test.sd = 0.0;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * half pixel in diagonal-direction (white)
- * -> mean of 255 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 10.5 ; pnt1[1] = 3.5;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5;
- figure1->SetControlPoint( 2, pnt3, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 255.0;
- test.sd = 0.0;
-
- testCases.push_back( test );
- }
-
-
- {
- /*****************************
- * one pixel (white) + 2 half pixels (white) + 1 half pixel (black)
- * -> mean of 191.25 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 1.1; pnt1[1] = 1.1;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 2.0; pnt2[1] = 2.0;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 3.0; pnt3[1] = 1.0;
- figure1->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 2.0; pnt4[1] = 0.0;
- figure1->SetControlPoint( 3, pnt4, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 191.25;
- test.sd = 127.5;
-
- testCases.push_back( test );
- }
-
-
- {
- /*****************************
- * whole pixel (white) + half pixel (gray) in x-direction
- * -> mean of 191.5 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 11.0; pnt1[1] = 3.5;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5;
- figure1->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 11.0; pnt4[1] = 4.5;
- figure1->SetControlPoint( 3, pnt4, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 191.50;
- test.sd = 89.80;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * quarter pixel (black) + whole pixel (white) + half pixel (gray) in x-direction
- * -> mean of 191.5 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 11.0; pnt1[1] = 3.5;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.25; pnt2[1] = 3.5;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 9.25; pnt3[1] = 4.5;
- figure1->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 11.0; pnt4[1] = 4.5;
- figure1->SetControlPoint( 3, pnt4, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 191.5;
- test.sd = 89.80;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * half pixel (black) + whole pixel (white) + half pixel (gray) in x-direction
- * -> mean of 127.66 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New();
- figure1->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 11.0; pnt1[1] = 3.5;
- figure1->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.0; pnt2[1] = 3.5;
- figure1->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 9.0; pnt3[1] = 4.0;
- figure1->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 11.0; pnt4[1] = 4.0;
- figure1->SetControlPoint( 3, pnt4, true );
- figure1->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure1;
- test.mean = 127.66;
- test.sd = 127.5;
-
- testCases.push_back( test );
- }
-
-
- {
- /*****************************
- * whole pixel (gray)
- * -> mean of 128 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New();
- figure2->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 11.5; pnt1[1] = 10.5;
- figure2->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 11.5; pnt2[1] = 11.5;
- figure2->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 12.5; pnt3[1] = 11.5;
- figure2->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 12.5; pnt4[1] = 10.5;
- figure2->SetControlPoint( 3, pnt4, true );
- figure2->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure2;
- test.mean = 128.0;
- test.sd = 0.0;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * whole pixel (gray) + half pixel (white) in y-direction
- * -> mean of 191.5 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New();
- figure2->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 11.5; pnt1[1] = 10.5;
- figure2->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 11.5; pnt2[1] = 12.0;
- figure2->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 12.5; pnt3[1] = 12.0;
- figure2->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 12.5; pnt4[1] = 10.5;
- figure2->SetControlPoint( 3, pnt4, true );
- figure2->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure2;
- test.mean = 191.5;
- test.sd = 89.80;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * 2 whole pixel (white) + 2 whole pixel (black) in y-direction
- * -> mean of 127.66 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New();
- figure2->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 11.5; pnt1[1] = 10.5;
- figure2->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 11.5; pnt2[1] = 13.5;
- figure2->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 12.5; pnt3[1] = 13.5;
- figure2->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 12.5; pnt4[1] = 10.5;
- figure2->SetControlPoint( 3, pnt4, true );
- figure2->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure2;
- test.mean = 127.66;
- test.sd = 127.5;
-
- testCases.push_back( test );
- }
-
-
- {
- /*****************************
- * 9 whole pixels (white) + 3 half pixels (white)
- * + 3 whole pixel (black) [ + 3 slightly less than half pixels (black)]
- * -> mean of 204.0 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New();
- figure2->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 0.5; pnt1[1] = 0.5;
- figure2->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 3.5; pnt2[1] = 3.5;
- figure2->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 8.4999; pnt3[1] = 3.5;
- figure2->SetControlPoint( 2, pnt3, true );
- mitk::Point2D pnt4; pnt4[0] = 5.4999; pnt4[1] = 0.5;
- figure2->SetControlPoint( 3, pnt4, true );
- figure2->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure2;
- test.mean = 204.0;
- test.sd = 105.58;
-
- testCases.push_back( test );
- }
-
- {
- /*****************************
- * half pixel (white) + whole pixel (white) + half pixel (black)
- * -> mean of 212.66 expected
- ******************************/
- mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New();
- figure2->SetGeometry2D( geom );
- mitk::Point2D pnt1; pnt1[0] = 9.5; pnt1[1] = 0.5;
- figure2->PlaceFigure( pnt1 );
-
- mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 2.5;
- figure2->SetControlPoint( 1, pnt2, true );
- mitk::Point2D pnt3; pnt3[0] = 11.5; pnt3[1] = 2.5;
- figure2->SetControlPoint( 2, pnt3, true );
- figure2->GetPolyLine(0);
-
- testCase test;
- test.id = testCases.size();
- test.figure = figure2;
- test.mean = 212.66;
- test.sd = 73.32;
-
- testCases.push_back( test );
- }
-
-
-
- return testCases;
-}
-
-// loads the test image
-static mitk::Image::Pointer GetTestImage()
-{
- mitk::StandardFileLocations::Pointer locator = mitk::StandardFileLocations::GetInstance();
-
- const std::string filename = locator->FindFile("testimage.dcm", "Modules/MitkExt/Testing/Data");
- if (filename.empty())
- {
- MITK_ERROR << "Could not find test file";
- return NULL;
- }
- else
- {
- MITK_INFO << "Found testimage.dcm";
- }
-
-
- itk::FilenamesContainer file;
- file.push_back( filename );
-
- mitk::DicomSeriesReader* reader = new mitk::DicomSeriesReader;
-
- mitk::DataNode::Pointer node = reader->LoadDicomSeries( file, false, false );
- mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
-
- return image;
-}
-
-};
-
-int mitkImageStatisticsCalculatorTest(int argc, char* argv[])
-{
- // always start with this!
- MITK_TEST_BEGIN("mitkImageStatisticsCalculatorTest")
-
- //QCoreApplication app(argc, argv);
-
- mitk::Image::Pointer image = mitkImageStatisticsCalculatorTestClass::GetTestImage();
- MITK_TEST_CONDITION_REQUIRED( image.IsNotNull(), "Loading test image" );
-
- mitk::Geometry2D::Pointer geom = image->GetSlicedGeometry()->GetGeometry2D(0);
-
- std::vector<mitkImageStatisticsCalculatorTestClass::testCase> allTestCases =
- mitkImageStatisticsCalculatorTestClass::InitializeTestCases( geom );
-
-
- for ( int i=0; i<allTestCases.size(); i++ )
- {
- mitkImageStatisticsCalculatorTestClass::testCase test = allTestCases[i];
-
- const mitk::ImageStatisticsCalculator::Statistics stats =
- mitkImageStatisticsCalculatorTestClass::TestStatistics( image, test.figure );
-
- int tmpMean = stats.Mean * 100;
- double calculatedMean = tmpMean / 100.0;
- MITK_TEST_CONDITION( calculatedMean == test.mean,
- "Calculated mean grayvalue '"<< calculatedMean <<"' is equal to the desired value '"
- << test.mean <<"' for testcase #" << test.id );
-
- int tmpSD = stats.Sigma * 100;
- double calculatedSD = tmpSD / 100.0;
- MITK_TEST_CONDITION( calculatedSD == test.sd,
- "Calculated grayvalue sd '"<< calculatedSD <<"' is equal to the desired value '"
- << test.sd <<"' for testcase #" << test.id );
- }
-
-
- MITK_TEST_END()
-}
-
diff --git a/Modules/Ext/Testing/mitkPipelineSmartPointerCorrectnessTest.cpp b/Modules/Ext/Testing/mitkPipelineSmartPointerCorrectnessTest.cpp
deleted file mode 100644
index 20e05d3bb2..0000000000
--- a/Modules/Ext/Testing/mitkPipelineSmartPointerCorrectnessTest.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include "mitkSurfaceToImageFilter.h"
-#include "mitkGeometryClipImageFilter.h"
-#include "mitkImageSliceSelector.h"
-
-#include <fstream>
-
-#include "mitkReferenceCountWatcher.h"
-
-class TwoOutputsFilter : public mitk::SurfaceToImageFilter
-{
-public:
- mitkClassMacro(TwoOutputsFilter, SurfaceToImageFilter);
- itkFactorylessNewMacro(Self)
- itkCloneMacro(Self)
-protected:
- TwoOutputsFilter()
- {
- mitk::Image::Pointer output
- = static_cast<mitk::Image*>(this->MakeOutput(0).GetPointer());
- Superclass::SetNumberOfRequiredOutputs(2);
- Superclass::SetNthOutput(1, output.GetPointer());
- }
-
- virtual ~TwoOutputsFilter()
- {
- }
-};
-
-template <class FilterType, class InputType>
-int runPipelineSmartPointerCorrectnessTestForFilterType(typename InputType::Pointer input)
-{
- typename FilterType::Pointer filter;
- std::cout << "Testing " << typeid(FilterType).name() << "::New(): ";
- filter = FilterType::New();
- if (filter.IsNull())
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- {
- std::cout<<"[PASSED]"<<std::endl;
- }
-
- std::cout << "Testing SetInput(" << typeid(FilterType).name() << "): ";
- filter->SetInput(input);
- std::cout<<"[PASSED]"<<std::endl;
- //std::cout << "Testing mitk::SurfaceToImageFilter::*TESTED_METHOD_DESCRIPTION: ";
- //// METHOD_TEST_CODE
- //if (filter.IsNull()) {
- // std::cout<<"[FAILED]"<<std::endl;
- // // return EXIT_FAILURE;
- //}
- //else {
- //std::cout<<"[PASSED]"<<std::endl;
- //}
-
-//#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
- //MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED test
- std::cout << "Initializing mitk::ReferenceCountWatcher: ";
- mitk::ReferenceCountWatcher::Pointer filterWatcher, filterOutputWatcher;
- filterWatcher = new mitk::ReferenceCountWatcher(filter, "filter1");
- filterOutputWatcher = new mitk::ReferenceCountWatcher(filter->GetOutput(), "filter1Output");
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED part1: "<<std::endl;
- try
- {
- mitk::Image::Pointer output = filter->GetOutput();
- std::cout << "Testing to set filter to NULL, keeping reference to output:";
- filter = NULL;
- std::cout<<"[PASSED]"<<std::endl;
- std::cout << "Testing reference count of output: ";
- if(output->GetReferenceCount()!=2)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- std::cout << "Testing external reference count of output: ";
- if(output->GetExternalReferenceCount()!=1)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing to set output to NULL:";
- //output->GetSource()->DebugOn();
- //output->DebugOn();
- output = NULL;
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter:";
- if(filterWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter output:";
- if(filterOutputWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- }
- catch(...)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
- std::cout << "Testing MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED part2: "<<std::endl;
- filter = FilterType::New();
- filterWatcher = new mitk::ReferenceCountWatcher(filter, "filter2");
- filterOutputWatcher = new mitk::ReferenceCountWatcher(filter->GetOutput(), "filter2Output");
- try
- {
- std::cout << "Testing to set filter to NULL, keeping NO reference to output:";
- filter = NULL;
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter:";
- if(filterWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter output:";
- if(filterOutputWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- }
- catch(...)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
- std::cout << "Testing MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED part3: "<<std::endl;
- try
- {
- mitk::Image::Pointer output;
- {
- typename FilterType::Pointer localFilter = FilterType::New();
- filterWatcher = new mitk::ReferenceCountWatcher(localFilter, "filter3");
- filterOutputWatcher = new mitk::ReferenceCountWatcher(localFilter->GetOutput(), "filter3Output");
- output = localFilter->GetOutput();
- std::cout << "Testing running out of scope of filter, keeping reference to output:";
- }
- std::cout<<"[PASSED]"<<std::endl;
- std::cout << "Testing reference count of output: ";
- if(output->GetReferenceCount()!=2)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- std::cout << "Testing external reference count of output: ";
- if(output->GetExternalReferenceCount()!=1)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing to set output to NULL:";
- output = NULL;
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter:";
- if(filterWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter output:";
- if(filterOutputWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- }
- catch(...)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
- std::cout << "Testing MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED part4: "<<std::endl;
- try
- {
- mitk::Image::Pointer output;
- {
- typename FilterType::Pointer localFilter = FilterType::New();
- filterWatcher = new mitk::ReferenceCountWatcher(localFilter, "filter4");
- filterOutputWatcher = new mitk::ReferenceCountWatcher(localFilter->GetOutput(), "filter4Output");
- output = localFilter->GetOutput();
- std::cout << "Testing running out of scope of filter, keeping reference to output (as in part 3):";
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing output->DisconnectPipeline(): ";
- output->DisconnectPipeline();
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of output: ";
- if(output->GetReferenceCount()!=1)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- std::cout << "Testing external reference count of output: ";
- if(output->GetExternalReferenceCount()!=1)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter:";
- if(filterWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing to set output to NULL:";
- output = NULL;
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter output:";
- if(filterOutputWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- }
- catch(...)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
- std::cout << "Testing MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED part5: "<<std::endl;
- try
- {
- {
- typename FilterType::Pointer localFilter = FilterType::New();
- filterWatcher = new mitk::ReferenceCountWatcher(localFilter, "filter5");
- filterOutputWatcher = new mitk::ReferenceCountWatcher(localFilter->GetOutput(), "filter5Output");
- std::cout << "Testing running out of scope of filter, keeping NO reference to output:";
- }
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter:";
- if(filterWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
-
- std::cout << "Testing reference count of filter output:";
- if(filterOutputWatcher->GetReferenceCount()!=0)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- else
- std::cout<<"[PASSED]"<<std::endl;
- }
- catch(...)
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-//#endif
-}
-
-int mitkPipelineSmartPointerCorrectnessTest(int /*argc*/, char* /*argv*/[])
-{
- int result;
- result = runPipelineSmartPointerCorrectnessTestForFilterType<mitk::SurfaceToImageFilter, mitk::Surface>(mitk::Surface::New());
- if( result != EXIT_SUCCESS )
- return result;
- std::cout << std::endl;
-
- result = runPipelineSmartPointerCorrectnessTestForFilterType<mitk::GeometryClipImageFilter, mitk::Image>(mitk::Image::New());
- if( result != EXIT_SUCCESS )
- return result;
- std::cout << std::endl;
-
- result = runPipelineSmartPointerCorrectnessTestForFilterType<TwoOutputsFilter, mitk::Surface>(mitk::Surface::New());
- if( result != EXIT_SUCCESS )
- return result;
-
- result = runPipelineSmartPointerCorrectnessTestForFilterType<mitk::ImageSliceSelector, mitk::Image>(mitk::Image::New());
- if( result != EXIT_SUCCESS )
- return result;
-
- std::cout<<"[TEST DONE]"<<std::endl;
- return EXIT_SUCCESS;
-}
diff --git a/Modules/Ext/Testing/mitkPlaneFitTest.cpp b/Modules/Ext/Testing/mitkPlaneFitTest.cpp
deleted file mode 100644
index 43a2a1ef27..0000000000
--- a/Modules/Ext/Testing/mitkPlaneFitTest.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include <mitkPlaneFit.h>
-#include <mitkPointSet.h>
-#include <mitkPlaneGeometry.h>
-#include <mitkNumericTypes.h>
-#include <mitkGeometryData.h>
-#include <fstream>
-
-int mitkPlaneFitTest(int, char*[] )
-{
- //float bounds[]={0.0f,10.0f,0.0f,10.0f,0.0f,5.0f};
-
- mitk::PlaneFit::Pointer PlaneFit = mitk::PlaneFit::New();
- mitk::PointSet::Pointer PointSet = mitk::PointSet::New();
- mitk::PlaneGeometry::Pointer planeGeo= mitk::PlaneGeometry::New();
- mitk::BaseGeometry::Pointer BaseGeometry = dynamic_cast<mitk::PlaneGeometry*>(planeGeo.GetPointer());
-
- mitk::Point3D Point;
-
- //first without any point, then incrementally add points within thre points there will be a plane geometry
- std::cout <<"Start PlaneFitTest "<<std::endl;
- for(int position=0; position<6; position++)
- {
- //add a point directly
- mitk::FillVector3D(Point, (float) position , (float) position * 1.5 , 2.5);
- PointSet->GetPointSet()->GetPoints()->InsertElement(position, Point);
- }
-
- //Set Input
- PlaneFit->SetInput(PointSet);
-
- const mitk::PointSet* testPointSet = PlaneFit->GetInput();
- std::cout<<" Size test of Input Method: ";
- if( testPointSet->GetSize() == PointSet->GetSize() )
- {
- std::cout<<"[PASSED]"<<std::endl;
- }
- else
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
-
- //Test Centroid
- std::cout << " Testing centroid calculaation: ";
- PlaneFit->Update();
- const mitk::Point3D &centroid = PlaneFit->GetCentroid();
- mitk::Point3D expectedCentroid;
- expectedCentroid[0]=2.5;
- expectedCentroid[1]=3.75;
- expectedCentroid[2]=2.5;
-
- if ( centroid == expectedCentroid )
- {
- std::cout<<"[PASSED]"<<std::endl;
- }
- else
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
-
-
-
- //Test PlaneGeometry
- std::cout << " Test PlaneGeometry: ";
- mitk::PlaneGeometry* PlaneGeometry = dynamic_cast<mitk::PlaneGeometry*>( PlaneFit->GetOutput()->GetGeometry());
- if( PlaneGeometry )
- {
- std::cout<<"[PASSED]"<<std::endl;
- }
- else
- {
- std::cout<<"[FAILED]"<<std::endl;
- return EXIT_FAILURE;
- }
-
- std::cout<<"[TEST DONE]"<<std::endl;
- return EXIT_SUCCESS;
-}
-
diff --git a/Modules/Ext/Testing/mitkPointLocatorTest.cpp b/Modules/Ext/Testing/mitkPointLocatorTest.cpp
deleted file mode 100644
index 3dbff18e17..0000000000
--- a/Modules/Ext/Testing/mitkPointLocatorTest.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-
-#include <mitkPointSet.h>
-#include <mitkTestingMacros.h>
-#include <vtkPolyData.h>
-#include <vtkPoints.h>
-#include <mitkPointLocator.h>
-#include <vtkPointLocator.h>
-#include <cstdlib>
-
-double GenerateRandomNumber( const double& min = 0.0, const double& max = 100.0 )
-{
- return ( ( ( double ) ( std::rand( ) ) ) / ( ( double ) ( RAND_MAX ) ) ) * ( max - min) + min;
-}
-
-void GenerateRandomPoint( double& x, double& y, double& z, const double& min = 0.0, const double& max = 100.0 )
-{
- x = GenerateRandomNumber(min, max);
- y = GenerateRandomNumber(min, max);
- z = GenerateRandomNumber(min, max);
-}
-
-int mitkPointLocatorTest(int /*argc*/, char* /*argv*/[])
-{
- MITK_TEST_BEGIN("mitkPointLocator");
- std::srand( 1 );
- unsigned int num_points = 10000;
-
- // Create PointSet with randomly defined point
- MITK_TEST_OUTPUT(<< "Creating random point set of 10000 points ");
- vtkPoints* points = vtkPoints::New();
- for (unsigned int i = 0; i < num_points ; ++i )
- {
- points->InsertPoint(i, GenerateRandomNumber(), GenerateRandomNumber(), GenerateRandomNumber());
- }
- vtkPolyData* pointSet = vtkPolyData::New();
- pointSet->SetPoints( points );
- points->Delete();
-
- MITK_TEST_CONDITION_REQUIRED((unsigned) pointSet->GetNumberOfPoints()== num_points,"Test number of points in vtkPointSet");
-
- // feed the point set into a vtk point locator
- MITK_TEST_OUTPUT(<< "Building vtkPointLocator ");
- vtkPointLocator* vtkPointLoc = vtkPointLocator::New();
- vtkPointLoc->SetDataSet( pointSet );
- vtkPointLoc->BuildLocator();
- MITK_TEST_OUTPUT(<< "[PASSED]");
-
- // feed the point set into the mitk point locator
- MITK_TEST_OUTPUT(<< "Building mitkPointLocator ");
- mitk::PointLocator::Pointer mitkPointLocatorInitializedByVtkPointSet = mitk::PointLocator::New();
- mitk::PointLocator::Pointer mitkPointLocatorInitializedByMITKPointSet = mitk::PointLocator::New();
- mitk::PointLocator::Pointer mitkPointLocatorInitializedByITKPointSet = mitk::PointLocator::New();
- MITK_TEST_CONDITION_REQUIRED(mitkPointLocatorInitializedByVtkPointSet.IsNotNull(), "Test whether mitkPointLocator is not null");
-
- mitk::PointSet::Pointer mitkPointSet = mitk::PointSet::New();
- mitk::PointLocator::ITKPointSet::Pointer itkPointSet = mitk::PointLocator::ITKPointSet::New();
- for ( int i=0; i<pointSet->GetNumberOfPoints();i++ )
- {
- mitk::Point3D pnt;
- pnt[0] = pointSet->GetPoint( i )[0];
- pnt[1] = pointSet->GetPoint( i )[1];
- pnt[2] = pointSet->GetPoint( i )[2];
- mitkPointSet->InsertPoint(i, pnt );
- mitk::PointLocator::ITKPointSet::PointType itkPoint;
- itkPoint[0] = pointSet->GetPoint( i )[0];
- itkPoint[1] = pointSet->GetPoint( i )[1];
- itkPoint[2] = pointSet->GetPoint( i )[2];
- itkPointSet->SetPoint(i,itkPoint);
- }
-
- MITK_TEST_OUTPUT(<< "Setting random point set ");
- mitkPointLocatorInitializedByVtkPointSet->SetPoints( pointSet );
- mitkPointLocatorInitializedByMITKPointSet->SetPoints( mitkPointSet );
- mitkPointLocatorInitializedByITKPointSet->SetPoints( itkPointSet );
- MITK_TEST_OUTPUT(<< "[PASSED]");
-
- MITK_TEST_OUTPUT(<< "Testing 1000 random points ");
- // generate N random points and calculate the closest
- // points with both the vtk and mitk pointlocator.
- // verify, that the point ids are the same.
- double p[3], x, y, z;
- mitk::PointSet::PointType pointType;
- for ( unsigned int i = 0 ; i < 100 ; ++i )
- {
- GenerateRandomPoint( x, y, z );
- p[0] = x;
- p[1] = y;
- p[2] = z;
- pointType[0] = p[0];
- pointType[1] = p[1];
- pointType[2] = p[2];
- int closestPointReference = vtkPointLoc->FindClosestPoint(p); // ground truth vtkPointLocator
- int closestPointVTK1 = mitkPointLocatorInitializedByVtkPointSet->FindClosestPoint(p);
- int closestPointVTK2 = mitkPointLocatorInitializedByVtkPointSet->FindClosestPoint(x, y, z);
- int closestPointVTK3 = mitkPointLocatorInitializedByVtkPointSet->FindClosestPoint(pointType);
- int closestPointMITK1 = mitkPointLocatorInitializedByMITKPointSet->FindClosestPoint(p);
- int closestPointMITK2 = mitkPointLocatorInitializedByMITKPointSet->FindClosestPoint(x, y, z);
- int closestPointMITK3 = mitkPointLocatorInitializedByMITKPointSet->FindClosestPoint(pointType);
- int closestPointITK1 = mitkPointLocatorInitializedByITKPointSet->FindClosestPoint(p);
- int closestPointITK2 = mitkPointLocatorInitializedByITKPointSet->FindClosestPoint(x, y, z);
- int closestPointITK3 = mitkPointLocatorInitializedByITKPointSet->FindClosestPoint(pointType);
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointVTK1,"Test FindClosestPoint() using a point array with a PointLocator initialized with a vtkPointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointVTK2,"Test FindClosestPoint() using single coordinates with a PointLocator initialized with a vtkPointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointVTK3,"Test FindClosestPoint() using an mitk::PointSet with a PointLocator initialized with a vtkPointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointMITK1,"Test FindClosestPoint() using a point array with a PointLocator initialized with a mitk::PointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointMITK2,"Test FindClosestPoint() using single coordinates with a PointLocator initialized with a mitk::PointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointMITK3,"Test FindClosestPoint() using an mitk::PointSet with a PointLocator initialized with a mitk::PointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointITK1,"Test FindClosestPoint() using a point array with a PointLocator initialized with a itk::PointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointITK2,"Test FindClosestPoint() using single coordinates with a PointLocator initialized with a itk::PointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointITK3,"Test FindClosestPoint() using an mitk::PointSet with a PointLocator initialized with a itk::PointSet");
- //Test GetMinimalDistance
- // Get closest point
- //double* closestPoint = vtkPointLoc->GetPoints()->GetPoint(closestPointReference);
- double* closestPoint = pointSet->GetPoint(closestPointReference);
- mitk::PointSet::PointType cP;
- cP[0] = closestPoint[0];
- cP[1] = closestPoint[1];
- cP[2] = closestPoint[2];
- mitk::PointLocator::DistanceType minimalDistanceReference = cP.SquaredEuclideanDistanceTo(pointType);
-
- //mitk::PointLocator::DistanceType minimalDistanceReference =
- // (x-closestPoint[0])*(x-closestPoint[0])+(y-closestPoint[1])*(y-closestPoint[1])+(z-closestPoint[2])*(z-closestPoint[2]);
- mitk::PointLocator::DistanceType minimalDistanceVtk = mitkPointLocatorInitializedByVtkPointSet->GetMinimalDistance(pointType);
- mitk::PointLocator::DistanceType minimalDistanceItk = mitkPointLocatorInitializedByITKPointSet->GetMinimalDistance(pointType);
- mitk::PointLocator::DistanceType minimalDistanceMITK = mitkPointLocatorInitializedByMITKPointSet->GetMinimalDistance(pointType);
- MITK_TEST_CONDITION_REQUIRED(mitk::Equal(minimalDistanceReference,minimalDistanceVtk), "Test GetMinimalDistance() using a PointLocator initialized with a vtkPointSet" );
- MITK_TEST_CONDITION_REQUIRED(mitk::Equal(minimalDistanceReference,minimalDistanceItk), "Test GetMinimalDistance() using a PointLocator initialized with a itkPointSet" );
- MITK_TEST_CONDITION_REQUIRED(mitk::Equal(minimalDistanceReference,minimalDistanceMITK), "Test GetMinimalDistance() using a PointLocator initialized with a MITKPointSet" );
-
- int closestPointCombinedVtk;
- mitk::PointLocator::DistanceType minimalDistanceCombinedVtk;
- mitkPointLocatorInitializedByVtkPointSet->FindClosestPointAndDistance(pointType,&closestPointCombinedVtk,&minimalDistanceCombinedVtk);
- int closestPointCombinedITK;
- mitk::PointLocator::DistanceType minimalDistanceCombinedITK;
- mitkPointLocatorInitializedByITKPointSet->FindClosestPointAndDistance(pointType,&closestPointCombinedITK,&minimalDistanceCombinedITK);
- int closestPointCombinedMITK;
- mitk::PointLocator::DistanceType minimalDistanceCombinedMITK;
- mitkPointLocatorInitializedByMITKPointSet->FindClosestPointAndDistance(pointType,&closestPointCombinedMITK,&minimalDistanceCombinedMITK);
- MITK_TEST_CONDITION_REQUIRED(mitk::Equal(minimalDistanceReference,minimalDistanceCombinedVtk), "Test distance returned by FindClosestPointAndDistance() using a PointLocator initialized with a vtkPointSet" );
- MITK_TEST_CONDITION_REQUIRED(mitk::Equal(minimalDistanceReference,minimalDistanceCombinedITK), "Test distance returned by FindClosestPointAndDistance() using a PointLocator initialized with a itkPointSet" );
- MITK_TEST_CONDITION_REQUIRED(mitk::Equal(minimalDistanceReference,minimalDistanceCombinedMITK), "Test distance returned by FindClosestPointAndDistance() using a PointLocator initialized with a MITKPointSet" );
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointCombinedVtk,"Test closest point returned by FindClosestPointAndDistance() using a point array with a PointLocator initialized with a vtkPointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointCombinedITK,"Test closest point returned by FindClosestPointAndDistance() using a point array with a PointLocator initialized with a itkPointSet");
- MITK_TEST_CONDITION_REQUIRED(closestPointReference==closestPointCombinedMITK,"Test closest point returned by FindClosestPointAndDistance() using a point array with a PointLocator initialized with a MITKPointSet");
- }
-
- vtkPointLoc->Delete();
- pointSet->Delete();
-
- MITK_TEST_END();
-}
diff --git a/Modules/Ext/files.cmake b/Modules/Ext/files.cmake
deleted file mode 100644
index a65eb78547..0000000000
--- a/Modules/Ext/files.cmake
+++ /dev/null
@@ -1,81 +0,0 @@
-set(CPP_FILES
- Algorithms/vtkPointSetSlicer.cxx
- Algorithms/mitkAngleCorrectByPointFilter.cpp
- Algorithms/mitkCylindricToCartesianFilter.cpp
- Algorithms/mitkGeometryDataSource.cpp
- Algorithms/mitkImageToLookupTableFilter.cpp
- Algorithms/mitkInterpolateLinesFilter.cpp
- Algorithms/mitkMeshSource.cpp
- Algorithms/mitkPlaneCutFilter.cpp
- Algorithms/mitkPlaneFit.cpp
- Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp
- Algorithms/mitkPointSetToCurvedGeometryFilter.cpp
- Algorithms/mitkPointSetToGeometryDataFilter.cpp
- Algorithms/mitkPointSetIndexToWorldTransformFilter.cpp
- Algorithms/mitkSurfaceIndexToWorldTransformFilter.cpp
- Algorithms/mitkPolygonToRingFilter.cpp
- Algorithms/mitkProbeFilter.cpp
- Algorithms/mitkUnstructuredGridHistogram.cpp
- Algorithms/mitkVolumeVisualizationImagePreprocessor.cpp
-
- DataManagement/mitkAffineTransformationOperation.cpp
- DataManagement/mitkColorSequenceHalfTones.cpp
- DataManagement/mitkDelegateManager.cpp
- DataManagement/mitkDrawOperation.cpp
- DataManagement/mitkExternAbstractTransformGeometry.cpp
- DataManagement/mitkFrameOfReferenceUIDManager.cpp
- DataManagement/mitkItkBaseDataAdapter.cpp
- DataManagement/mitkObjectSet.cpp
- DataManagement/mitkPropertyManager.cpp
- DataManagement/mitkSeedsImage.cpp
- DataManagement/mitkSeedsImageLookupTableSource.cpp
- DataManagement/mitkSphereLandmarkProjector.cpp
-# DataManagement/mitkUSLookupTableSource.cpp
- DataManagement/vtkObjectSet.cpp
- IO/mitkObjFileIOFactory.cpp
- IO/mitkObjFileReader.cpp
- IO/mitkPACSPlugin.cpp
- IO/mitkParRecFileIOFactory.cpp
- IO/mitkParRecFileReader.cpp
- IO/mitkPropertyListExportToXmlFile.cpp
- IO/mitkPropertyListImportFromXmlFile.cpp
- IO/mitkStlVolumeTimeSeriesIOFactory.cpp
- IO/mitkStlVolumeTimeSeriesReader.cpp
- IO/mitkUnstructuredGridVtkWriter.cpp
- IO/mitkUnstructuredGridVtkWriterFactory.cpp
- IO/mitkVtkUnstructuredGridIOFactory.cpp
- IO/mitkVtkUnstructuredGridReader.cpp
- IO/mitkVtkVolumeTimeSeriesIOFactory.cpp
- IO/mitkVtkVolumeTimeSeriesReader.cpp
- Interactions/mitkConferenceEventMapper.cpp
- Interactions/mitkConnectPointsInteractor.cpp
- #Interactions/mitkCoordinateSupplier.cpp
- #Interactions/mitkDisplayCoordinateOperation.cpp
- #Interactions/mitkDisplayInteractor.cpp
- Interactions/mitkAffineInteractor3D.cpp
- Interactions/mitkDisplayPointSetInteractor.cpp
- #Interactions/mitkDisplayVectorInteractor.cpp
- Interactions/mitkInteractionDebug.cpp
- Interactions/mitkInteractionDebugger.cpp
- Interactions/mitkPointInteractor.cpp
- Interactions/mitkPointSelectorInteractor.cpp
- #Interactions/mitkPositionTracker.cpp
- Interactions/mitkSeedsInteractor.cpp
- Interactions/mitkSocketClient.cpp
- Interactions/mitkSurfaceDeformationInteractor3D.cpp
- Interactions/mitkSurfaceInteractor.cpp
-# Interactions/mitkCreateSurfaceTool.cpp
- Rendering/mitkImageBackground2D.cpp
- Rendering/mitkLineMapper2D.cpp
-# Rendering/mitkLineVtkMapper3D.cpp
- Rendering/mitkNativeRenderWindowInteractor.cpp
-)
-
-
-set(RESOURCE_FILES
-Interactions/AffineInteraction3D.xml
-Interactions/AffineTranslationConfig.xml
-Interactions/AffineRotationConfig.xml
-Interactions/AffineDeformationConfig.xml
-)
-
diff --git a/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp b/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp
index 4ab901d78a..036f4b98ec 100644
--- a/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp
+++ b/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp
@@ -1,150 +1,153 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTrackingVolumeGenerator.h"
#include "mitkSTLFileReader.h"
#include "mitkStandardFileLocations.h"
#include "mitkConfig.h"
#include <vtkCubeSource.h>
#include <mitkTrackingTypes.h>
#include <mitkTrackingDevice.h>
#include <mitkVirtualTrackingDevice.h>
#include <vtkSmartPointer.h>
#include <mitkSurface.h>
#include <usModuleContext.h>
#include <usGetModuleContext.h>
#include <usModule.h>
#include <usModuleResource.h>
#include <usModuleResourceStream.h>
#include <mitkIOUtil.h>
mitk::TrackingVolumeGenerator::TrackingVolumeGenerator()
{
m_Data = mitk::DeviceDataUnspecified;
}
void mitk::TrackingVolumeGenerator::SetTrackingDevice (mitk::TrackingDevice::Pointer tracker)
{
this->m_Data = mitk::GetFirstCompatibleDeviceDataForLine(tracker->GetType());
}
void mitk::TrackingVolumeGenerator::GenerateData()
{
mitk::Surface::Pointer output = this->GetOutput(); //the surface wich represents the tracking volume
std::string filepath = ""; // Full path to file (wil be resolved later)
std::string filename = this->m_Data.VolumeModelLocation; // Name of the file or possibly a magic String, e.g. "cube"
MITK_INFO << "volume: " << filename;
// See if filename matches a magic string.
if (filename.compare("cube") == 0){
vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();
double bounds[6];
bounds[0] = bounds[2] = bounds[4] = -400.0; // initialize bounds to -400 ... +400 cube. This is the default value of the
bounds[1] = bounds[3] = bounds[5] = 400.0; // virtual tracking device, but it can be changed. In that case,
// the tracking volume polydata has to be updated manually
cubeSource->SetBounds(bounds);
cubeSource->Update();
output->SetVtkPolyData(cubeSource->GetOutput()); //set the vtkCubeSource as polyData of the surface
return;
}
if (filename.compare("") == 0) // empty String means no model, return empty output
{
- output->SetVtkPolyData(vtkPolyData::New()); //initialize with empty poly data (otherwise old surfaces may be returned) => so an empty surface is returned
+ // initialize with empty poly data (otherwise old surfaces may be returned) => so an empty surface is returned
+ vtkPolyData *emptyPolyData = vtkPolyData::New();
+ output->SetVtkPolyData(emptyPolyData);
+ emptyPolyData->Delete();
return;
}
// from here on, we assume that filename contains an actual filename and not a magic string
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource moduleResource = module->GetResource(filename);
bool isCompressed = moduleResource.IsCompressed();
// Create ResourceStream from Resource
us::ModuleResourceStream resStream(moduleResource,std::ios_base::binary);
ofstream tmpOutputStream;
std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpOutputStream);
if (!isCompressed)
{
tmpOutputStream << resStream.rdbuf();
}
else
{
resStream.seekg(0, std::ios::end);
std::ios::pos_type length = resStream.tellg();
resStream.seekg(0, std::ios::beg);
char* data = new char[length];
resStream.read(data, length);
tmpOutputStream.close();
tmpOutputStream.open(tmpFilePath.c_str(), std::ios_base::binary | std::ios_base::out);
tmpOutputStream.write(data, length);
tmpOutputStream.flush();
delete[] data;
}
tmpOutputStream.close();
//filepath = mitk::StandardFileLocations::GetInstance()->FindFile(filename.c_str());
if (tmpFilePath.empty())
{
MITK_ERROR << ("Volume Generator could not find the specified file " + filename);
return;
}
mitk::STLFileReader::Pointer stlReader = mitk::STLFileReader::New();
stlReader->SetFileName( tmpFilePath.c_str() );
stlReader->Update();
std::remove(tmpFilePath.c_str());
if ( stlReader->GetOutput() == NULL)
{
MITK_ERROR << "Error while reading file";
return ;
}
output->SetVtkPolyData( stlReader->GetOutput()->GetVtkPolyData());//set the visible trackingvolume
}
void mitk::TrackingVolumeGenerator::SetTrackingDeviceType(mitk::TrackingDeviceType deviceType)
{
m_Data = mitk::GetFirstCompatibleDeviceDataForLine(deviceType);
}
mitk::TrackingDeviceType mitk::TrackingVolumeGenerator::GetTrackingDeviceType() const
{
return m_Data.Line;
}
void mitk::TrackingVolumeGenerator::SetTrackingDeviceData(mitk::TrackingDeviceData deviceData)
{
m_Data= deviceData;
}
mitk::TrackingDeviceData mitk::TrackingVolumeGenerator::GetTrackingDeviceData() const
{
return m_Data;
}
diff --git a/Modules/ImageExtraction/Testing/Data/img.nrrd b/Modules/ImageExtraction/Testing/Data/img.nrrd
deleted file mode 100644
index 04a51b53cb..0000000000
--- a/Modules/ImageExtraction/Testing/Data/img.nrrd
+++ /dev/null
@@ -1,17 +0,0 @@
-NRRD0004
-# Complete NRRD file format specification at:
-# http://teem.sourceforge.net/nrrd/format.html
-content: SomeIDNumber42
-type: short
-dimension: 3
-space: right-anterior-superior
-sizes: 3 3 1
-thicknesses: 1 1 1
-space directions: (1,0,0) (0,1,0) (0,0,1)
-centerings: cell cell cell
-kinds: space space space
-encoding: ASCII
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-
-1 2 3 4 5 6 7 8 9
diff --git a/Modules/ImageExtraction/Testing/Data/lungs.vtk b/Modules/ImageExtraction/Testing/Data/lungs.vtk
deleted file mode 100644
index 5b0f7f17ac..0000000000
--- a/Modules/ImageExtraction/Testing/Data/lungs.vtk
+++ /dev/null
@@ -1,18985 +0,0 @@
-# vtk DataFile Version 3.0
-vtk output
-ASCII
-DATASET POLYDATA
-POINTS 7860 float
-59 174 77.8 95 170 80.2059 55 171 80.2222
-56 171 79.2353 56 172 78.5806 57 172 78.1765
-58 173 78.2 59 173 78.6923 61 173 79.6452
-87 173 80.4194 88 173 79.8 89 173 79.4571
-91 173 80.4706 58 174 78.5172 60 174 78.1765
-89 174 80.4706 91 174 80.8235 59 175 78.5172
-60 175 78.0909 63 175 79.4571 88 175 80.5588
-64 176 80.1429 63 177 80.2059 65 177 80.2059
-67 177 80.1429 81 177 80.4706 82 177 79.8
-84 177 79.8 62 177.087 81 64 177.5 81
-68 178 80.2059 80 178 80.2059 82 178 80.2059
-69 179 79.8529 77 179 80.2059 79 179 79.8
-80 179 80.2059 81 179 80.8235 70 180 80.5455
-74 180 80.4706 114 150 83.4706 113 151 83.4706
-112.739 151 84 114 152 82.8529 39 155 83.8
-38.6667 155 84 113 155 82.8 114 155 82.8
-39 156 83.1429 38.3333 156 84 40 156 83.4706
-114 156 83.1429 40 157 83.1429 40 158 83.8
-40.6667 158 84 42 158.833 84 41.3333 159 84
-109 159 83.4706 112 159 81.1765 113 159 81.4545
-43 160 83.2059 108 160 83.4706 109 160 82.8
-111 160 81.5294 112 160 81.1765 113 160 82.3
-110 161 82.2 111 161 81.5143 112 161 81.8182
-44 162 82.8 45 162 82.8 107 162 83.0323
-109 162 83.0323 110 162 82.2 111 162 82.2
-112 162 83.4828 46 163 83.4194 110 163 83.2059
-46.25 164 84 47 164 83.4194 106 164 82.2
-109 164 83.4706 104 165 83.4 105 165 82.4545
-106 165 82.2 108 165 83.4706 49 166 82.8
-50 166 82.8 51.1667 166 84 103 166 83.9
-51.4 167 84 99 167 83.2174 101 167 81.9
-96 168 83.4828 97 168 82.7 98 168 82.8182
-101 168 81.8824 95 169 81.8824 96 169 81.9677
-97 169 82.5556 93 170 82.3636 93 169.333 84
-96 170 81.2222 54 171 82.6552 93 171 81.6667
-94 171 81.1936 91 172 81.6207 92 172 81.9677
-93 172 81.6 94 172 81.8824 95 172 81.5294
-97 172 83.8846 68 173 83.3333 76 173 83.4706
-85 173 83.6842 86 173 81.7826 93 173 82.2
-71 174 82.6452 76 174 82.4571 84 174 83.6842
-85 174 83.8333 92 174 81.5294 57 174.727 84
-75 175 82.6452 80 175 82.4571 82 175 82.0714
-86 175 81.6 69 176 82.6452 71 176 82.8529
-72 176 83.8064 74 176 83.4194 80 176 82.2
-87 176 81.4545 60.2609 177 84 75 177 82.4571
-87 177 81.5294 89 177 82.8529 81 181.25 84
-115 146.357 87 36 149 86.4194 114 149 84.1765
-36 150 86.4194 37 150 86.8 36.0909 151 87
-37 151 86.0323 37 152 85.5556 37 153 86.0526
-38 153 86.6842 111 153 86.9091 37 154 86.1667
-38 154 84.7826 39 154 85.8261 38 155 84.6667
-38 156 85.0714 37.6538 156 87 41 157 84.6818
-41 158 84.1364 40 159 85.8571 41 159 84.1364
-44 158.278 87 108 159 84.5294 41 160 85.2273
-45.5 160 87 41.2 161 87 47 163 84.2727
-46 164 84.2308 52 165 85.3548 100 165 86.5455
-102 165 84.5294 53 166 86.0323 52 167 84.2647
-106 167 84.5294 51 168 84.9677 53 168 84.4545
-95 167.63 87 53 169 84.2647 92 168.75 87
-105 169 86.2059 67 169.75 87 89 170 84.8824
-98 170 85.56 98 171 85.7727 72 172 85
-74 172 85.5556 82 172 84.5294 84 172 84.6923
-98 172 85.3043 99 172 85.2 73 173 85.8261
-74 173 85.8261 84 173 84.8333 73 174 85.1538
-99 174 86.8235 73 175 85 74 175 84.5172
-184.833 178 87 186 178 85.8462 186 179 85
-188 179 84.9677 189 179 85.3 191 179 85.1818
-193 179 84.375 195 179 85.6552 196 179 86.069
-198 179 85.4545 198 178.261 87 201 179 86.4706
-202 179 86.2059 186 180 86.8235 189 180 85.3548
-190 180 84.6 191 180 84.6 193 180 84.4286
-196 180 86.1 198 180 85.5 200 180 86.2059
-201 179.75 87 193 181 86.8966 68 181.706 87
-82 182 84.5294 84 183.087 87 117 143 89.8
-118 143 89.4706 118 142.25 90 117 144 88.5
-118 144 89.4706 115 145 89.2174 116 145 87.9677
-117 145 88.2 34 146 89.6087 115 146 87.6818
-116 146 87.5769 117 146 89 35 147 87.9677
-116 147 87.2308 35 148 87.5769 36 148 87.4545
-35 149 87.5455 35.7727 152 90 39 153 89.7273
-151 155 88.8 42.6429 157 90 152 157 88.8
-153 157 89.1429 43 157.278 90 44 157.105 90
-45.4545 158 90 152 158 89.8 153 158 89.8
-45.8947 159 90 153 159 89.9 47.2857 161 90
-52 162 89.55 48 162.286 90 55 164 88.3043
-56 164 89.2174 98 164 88.8529 55 165 87.6923
-56 165 89.2174 96 165 89.2059 95.1818 165 90
-99 165 87.9677 45 165.346 90 56 166 88
-63 167 87.375 64.6 167 90 92.7692 167 90
-95 167 89.3182 94.375 167 90 64.3 168 90
-68.3333 168 90 93 167.75 90 93 168 89.5714
-94 168 89 94 167.75 90 72 168.474 90
-73 168.333 90 66 169.4 90 50 170.105 90
-174 175 89.4 175 175 88.8 176 175 89.4194
-176 176 89.0323 177 176 88.6452 178.6 176 90
-181 176 89.4231 181 177 89.3077 181 178 89.04
-182 178 88.7586 183 178 89.3182 184 178 89
-202 178 87.5172 204 178 88.5 182 179 89.4194
-183 179 89.7391 184 179 88.875 204 179 88.1538
-181 180 89.8235 183 180 89.4194 202 180 88
-119 140 92.7778 120 140 91.6452 118 141 91.9615
-119 141 90.8571 120 141 91.2 118 142 90.2
-119 142 90.1765 120 142 91.5 120.654 142 93
-119 143 90.5294 150 145 92.8 149.714 145 93
-150 146 91.8 150 147 91.5 151 147 91.8529
-117.895 148 93 150 148 91.8529 151 148 91.5
-151 149 90.5294 151 150 90.1765 36.5909 153 93
-39 154.5 93 39.1053 155 93 39.1667 156 93
-40 156.526 93 154 157 90.5294 156.105 159 93
-46 159.563 93 50.75 160 93 153 160 91.1471
-155 160 91.7 45.3333 161 93 51 161 91.0714
-52 161 91.2273 154 161 90.6 45.8667 162 93
-51 162 90.5 50.6875 162 93 154 162 91.7
-156 161.455 93 155 163 92.7391 155.25 163 93
-47 164 92.3077 46.25 164 93 159 164 91.5
-47 164.857 93 63 165 90.6667 92 165 90.8824
-159 165 90.8824 45 165.591 93 46.5455 166 93
-64 166 90.2609 66 166 92.6842 67 166 92.8636
-92 166 90.2 93 166 91.0385 158 166 91.5
-160 166 90.5806 161 166 92.3077 46.6 167 93
-65 166.684 93 69 166.4 93 70 166.227 93
-71 167 91.5556 72 167 92 75 167 90.6
-93 167 92.25 94 167 92.25 161 167 92.7391
-161.5 167 93 68.3333 168 93 72 168 91.5
-94 168 90.2143 160 168 92.4444 161 168 92.25
-162 168 91.5556 48.4 169 93 67 169 90.2727
-162 170 91.2353 51.2857 171 93 66 170.208 93
-167 171 92.8966 52.625 173 93 170 173 92.8235
-173 173 92.7778 174 174 90.2308 170 175 92.1429
-180 175 91.5 171 176 92.4194 172 175.091 93
-172 176 91.8889 174 176 90.2222 179 176 90.5455
-185 175.618 93 179 177 92.7 183 177 90.375
-177 178 91.2 178 178 92.7 178.333 178 93
-179 177.333 93 179.143 178 93 180 178 90.6
-176 178.833 93 177 178.818 93 177.286 179 93
-178 179 92.2105 179 179 91.5 204.833 179 93
-180 180 90.5294 204 180.172 93 121 139 93.2727
-123.105 139 96 33 140.857 96 34 141 94.8462
-34 142 93.9 35 143 93.6818 149 143 94.8889
-150 144 94.1818 149 145 93.7895 40 151 94.5
-40.0714 153 96 40 153.071 96 39.3529 156 96
-149.588 156 96 46 156.591 96 45 157.133 96
-48 158 94.8 47 159 93.8571 49 159 94.0714
-50.1818 159 96 45.6667 160 96 47 159.625 96
-52 159.895 96 45.5714 161 96 157 161 93.2308
-51 162 94.0714 52 161.722 96 52.8333 162 96
-54 161.5 96 156 162 95.25 158 162 93.2609
-159 162 93.6 41 163 94.8261 46 163 94.125
-51 162.692 96 52 163 95.4 52.75 163 96
-156 163 95.5714 46 164 93.3158 45.2273 164 96
-52 163.6 96 90 164 93.3214 155 164 93.6667
-43 165 94.1111 46 165 93.75 47 165 93.75
-156 165 93.2 45 166 94.5882 45.7273 166 96
-47 165.273 96 46.2727 166 96 54 166 94
-54.2 166 96 69.25 166 96 162 166 94.7727
-46 166.375 96 46 167 94.9286 54 166.667 96
-64.4615 167 96 69 166.5 96 155 166.474 96
-163 166.455 96 47 168 94.5 72 168 94.5
-94.55 168 96 164 168 94.1111 165 168 95.1
-46 169 95.8846 46.1667 169 96 47.5 169 96
-72 169 95.3182 164 169 94.1111 165 169 94.5556
-166 169 94.8 52 170 93.2 94 169.688 96
-166 170 93.4286 167 170 93.5455 51 170.625 96
-163 171 93.6 166 171 94.3636 168 171 94.375
-168 170.133 96 170 171 94.8 52 172 94
-52.1818 172 96 162 172 94.5 163 172 94.3
-164 172 95.7391 165 172 95.8636 167 172 94.3548
-168 172 94.3548 173 172 93.5172 52 172.5 96
-59 173 95.125 164 173 95.4194 165 173 95.0323
-171 173 93.1818 172 173 93.4545 216 173 95.8
-75 174 95 74.8421 174 96 76 173.533 96
-76 174 95 76.6364 174 96 167 174 95.1429
-172 174 93.8182 214 174 95.4706 168 175 94.5
-172 175 93.1765 183 174.941 96 170 177 94.5
-178 176.65 96 179 176.316 96 204.323 177 96
-176.85 178 96 178 178 93.2 179.591 178 96
-176 179 93.3158 177 179 93.8571 177 178.375 96
-178 178.609 96 177 180 94.1538 68 184.056 96
-124 138.071 99 33 139.357 99 34 140.056 99
-149 141 98.2174 150 140.5 99 149 142 96.2609
-115 143.111 99 41 153 98.6 40 154 98.0526
-41 154 98.7 42 154 98.6 43 154 97.9286
-43 153.773 99 44 155 97.5 44 156 98.1667
-44.7143 156 99 46 157 98.4545 42.8182 158 99
-45 158 97.4444 47 158 98.4706 48 158 98.25
-44 158.846 99 45 159 98.6 46 159 98
-46.75 159 99 47 158.75 99 46 160 97.6364
-46 159.375 99 47 160 97 49.1818 160 99
-51 160 97.5 46 161 97.2 47 161 97.5
-51 160.667 99 53 160.545 99 45.2778 162 99
-51 161.333 99 53 161.625 99 53 162 96.75
-161 162 97.8529 49.9333 163 99 52 162.2 99
-59 163 98.25 44.3158 164 99 60 163.667 99
-64 163.933 99 59 165 97 60 164.333 99
-60 165 97.6364 64.8182 165 99 66 165 97.125
-66.7143 165 99 68.75 165 99 47 166 97.8462
-47.3333 166 99 54 166 96.4 59 166 96
-58.2632 166 99 60 166 97.0909 65 166 98.7143
-64.8182 166 99 66 166 98.0526 66.75 166 99
-69 166 96.4286 70 165.833 99 224 166 98.8
-225 166 98.8 225 165.75 99 46 167 97.5
-47.8182 167 99 59 167 97.3636 58.25 167 99
-60 167 97.7143 67 166.286 99 69 167 96.75
-70 167 98.6 70 166.5 99 70.3333 167 99
-72 167 98.6 71.6667 167 99 72 166.5 99
-223 167 97.8529 224 167 97.6452 47 168 96.75
-46.4545 168 99 47.8571 168 99 56 168 98.7273
-55.8667 168 99 56 167.867 99 56.5 168 99
-61.8182 168 99 64.25 168 99 70 168 96.2609
-71 167.222 99 71 168 96.7895 73 168 97
-74 167.357 99 74 168 97.7727 222 168 97.8529
-223 168 97.3 224 168 98.7391 47 169 97.3636
-56 168.286 99 62 169 97.6552 62.9286 169 99
-64.25 169 99 69 169 96.9 71 169 97.35
-74.1 169 99 92.7 169 99 167 168.2 99
-221 169 97.7 222 169 97.3 223 169 98.7391
-46 170 97.5 52 169.462 99 54.2 170 99
-62 170 97.8182 62.6842 170 99 68 169.875 99
-69 170 98.25 68.5 170 99 70 170 97.1739
-71 170 97.25 72 170 97.5 72.9091 170 99
-74 169.056 99 77 170 97.5 76.4545 170 99
-77 169.571 99 170 170 96.4545 220 170 96.9
-221 170 97.0385 222 170 98.7391 61 171 98.7931
-60.7778 171 99 61.2857 171 99 69 170.5 99
-70 171 97.3333 71 171 97.25 72 171 98.625
-77 171 97.8 77.8571 171 99 94 170.294 99
-164 171 96.2727 165 171 96.4091 218 171 97.4
-219 171 96.6 220 171 96.2 221 171 98.2174
-49 172 96.3333 54 171.75 99 59 171.519 99
-60 172 98 69.1429 172 99 71 172 96.3
-72.4375 172 99 77 171.75 99 216 172 97.1818
-216 171.231 99 217 172 97.2414 218 172 96.5172
-219 172 97.5 220 172 98.7273 48 172.722 99
-50 173 97.875 51.5 173 99 58 173 96.5172
-57.1724 173 99 61 172.286 99 215 173 96.5294
-217 173 96.5294 218 173 97.3548 51 174 98.2174
-67 173.818 99 67.25 174 99 75.5 174 99
-78 174 98.7273 78.1053 174 99 180 173.097 99
-211 174 98.88 216 174 96.5294 58 174.737 99
-67 175 97.8462 66.0909 175 99 76 174.643 99
-77 175 98.4 77.75 175 99 78 174.667 99
-210 175 97.25 212 175 97.8261 213 175 96.6
-214 175 96.2 67 176 98.069 66.3571 176 99
-67.9 176 99 77 175.188 99 178 175.923 99
-178.25 176 99 209 176 96.4545 210 176 96.1154
-211 176 97.56 212 176 98.4444 213 176 98.1
-214 176 98.4231 67 176.5 99 179 176.75 99
-179.095 177 99 210 177 96.5806 212 176.833 99
-214 176.172 99 177 178.579 99 178 178.467 99
-63 183.375 99 66 183.818 99 67 184 98
-151 137 101.824 32 138 101.609 33 137.333 102
-150 138 100.696 33 139 99.5769 150 139 99.6667
-149 140 100.8 123 141 100.579 122 144 100.962
-120.8 145 102 107.773 150 102 41 152 99.5455
-34.5882 153 102 45 155 100.579 45.3913 155 102
-41 156 100.154 42 156 100.111 45 156 99.3158
-42 157 99.2727 43 157 100.111 46 157 99.6
-47 157 101.7 44 158 101.75 47 158 102
-48 158 100 43.8421 159 102 50 159 100.071
-51 160 99.4286 50 161 100.826 54 161 101.7
-55 161 101.5 158 161 101.667 157.25 161 102
-158 160.813 102 51 162 99.75 52 162 99.5455
-53 162 100.125 56 161.077 102 158 161.75 102
-227 162 101.1 228 162 101.739 46 162.444 102
-49 162.667 102 49 163 101.8 50 162.2 102
-60 162.944 102 226 163 100.5 227 163 99.9
-225 164 101.1 226 164 99.9 227 164 100.227
-47 165 101.167 59 165 101.727 65 165 99.8571
-66 165 101.5 80 164.567 102 225 165 99.5294
-226 165 100.111 46 166 101.824 60.875 166 102
-65 166 101 65.2 166 102 66 165.2 102
-66.8 166 102 226 165.944 102 46 167 99.9375
-47 167 101.077 60.75 167 102 61.1429 167 102
-62 166.455 102 64 167 100.5 65 167 100.364
-66 167 100.286 70 167 99.8571 72 166.563 102
-167 167 100.5 47 168 100.636 56 168 99.8571
-65 168 100.2 66 168 100.773 67 168 101.654
-74 167.105 102 94 168 101.786 95.375 168 102
-167 168 99.5455 62.6364 169 102 66 169 101.727
-67 169 101.8 68 169 101.8 75 168.571 102
-75 169 101.25 76 168.455 102 76 169 100.2
-95.9167 169 102 54 169.591 102 55 170 101.182
-56 169.167 102 56 170 100.5 61 170 99.8182
-64.4545 170 102 67 170 101.7 73.5455 170 102
-75 169.75 102 76 169.857 102 76.1429 170 102
-52 170.474 102 53 170.143 102 54.3333 171 102
-61 171 99.6 51 172 102 58 171.727 102
-60 172 101 73 171.667 102 72.9333 172 102
-78 171.917 102 60.25 173 102 72 173 101.182
-78 173 101.25 78 172.333 102 79.5 173 102
-180 172.316 102 67.3333 174 102 68 174 101.25
-68.6667 174 102 77 174 100.579 77.75 174 102
-79 174 102 187 174 101.419 188 174 101.8
-206.895 174 102 58 174.25 102 66 175 102
-68 175 102 77 175 99.6 78 174.75 102
-207 175 101 65.5625 176 102 68.1364 176 102
-173 176 100.688 173 175.632 102 176.565 176 102
-215 176 100.826 215.6 176 102 161 176.074 102
-212 177 99.1034 176.8 178 102 203.5 178 102
-212 178 100.556 203 178.867 102 210 179 100.355
-202.091 180 102 203 181 100.75 66 185 100.08
-200 184.172 102 232 99 104.8 232 98.7143 105
-232 99.5 105 235 111 104.824 235 112 104.824
-151 133 104.471 32 136 103.6 31.3 136 105
-33 135.867 105 150 137 102.167 153 141 103.2
-154 142 104.8 154.75 143 105 230 156 104.419
-49 157 104.318 229 157 104.8 45 158 103.313
-46 158 103.615 229 158 103.7 230 158 104.053
-44 159 103.125 45 159 102.75 46 159 103.8
-53 158.316 105 228 159 104.206 229 159 103.5
-37.1765 160 105 54 160 103.5 164 160 103.8
-229 160 103.5 157.533 161 105 158 160.417 105
-158.875 161 105 228 161 102.682 228.944 161 105
-49 162 102.273 50 162 102.316 59.8 162 105
-62 162 104.545 158 161.875 105 46 163 104
-48 163 102.375 225 163 103.111 45.1429 164 105
-46 163.455 105 47 164 103.05 45 165 103.286
-60 165 102.75 167 165 102.529 46 165.25 105
-60 166 103.105 63 166 105 65 166 102.429
-60 167 102.45 61.8571 167 105 62 166.333 105
-62.6667 167 105 64 167 104.5 63.5 167 105
-64.1 167 105 65 166.4 105 64 167.25 105
-68 168 102.261 69 168 103.962 71 168 103.556
-72 168 104.778 73 168 104.333 74 168 104.684
-96.7143 168 105 166 168 103.875 166.75 168 105
-62 169 103.05 69 169 103.304 71 169 103.304
-73 169 104.063 75 169 102.818 76 169 102.947
-97.5455 169 105 54 170 103.929 55 170 103.125
-56 170 104.143 62 170 103.235 65 170 103.636
-66 170 103.65 74 169.273 105 77 170 103
-52 171 103 53 171 102.692 54 171 103
-71 171 103.304 73 171 102.4 78 171 104.75
-178 170.261 105 179 171 103 181 171 104.419
-52 172 103.179 58 172 103.125 72 172 103.826
-77 171.286 105 182 172 104 184 172 102.882
-188 172 104.8 58 173 103.826 59 173 103.5
-70 173 103.125 72 173 103.8 78 173 103.5
-78.4 173 105 81 173 105 181 173 103.5
-182 173 103.909 188 173 102.783 207 173 104.333
-208.125 173 105 59 174 102.692 69.75 174 105
-80 173.857 105 198 174 102.667 206 174 104.217
-210 173.273 105 67 175 103.615 67.75 175 105
-68.2857 175 105 88 175 104 87.25 175 105
-88.75 175 105 176 175 104.308 176 174.455 105
-177 174.87 105 177 175 104.438 66 176 104.625
-67 176 104.625 68 176 103 88 175.75 105
-173.231 176 105 176 176 104.438 178.067 176 105
-204.091 178 105 203.25 179 105 200.571 180 105
-201 179.4 105 203 179.056 105 206 180 103.8
-201.75 181 105 205 181 104.333 206 181 103.8
-207 181 104.1 173 182 103.56 175.667 185 105
-230 94 107.4 230 93.1429 108 231 95 106.889
-231 96 106.355 231 97 106.182 232 97 106.636
-232 98 105.577 231 99 106.5 233 99 106.333
-233 98.1667 108 232 100 105.2 233.292 100 108
-233 101.5 108 233 102 107.684 233 103 106.111
-233 104 105.882 233 105 106.182 234 105 105.682
-234 106 105.222 235 105.75 108 234 107 105.2
-234 108 105.529 235 110 105.577 235.913 110 108
-234 111 105.529 236 111 106.421 236.292 114 108
-235 116 106.355 235 117 107.032 235 119 107.8
-235 120 107.8 236 120 107.739 236 121 106.696
-236 123 105.667 236 125 106.889 236 126 107.333
-235 127 107.824 236 128 106.355 236 130 107.1
-150 131 107.778 150 132 105.9 149.192 132 108
-151 132 105.818 235 132 107.8 31 135 106.8
-31 134.143 108 32 135 105.136 31 136 107
-33 135.133 108 235 136 107.471 120 139.435 108
-235 140 106.889 155 141 105.667 234 141 107.471
-235 141 107.217 234 142 107.143 235 141.857 108
-234 143 107.032 155 144 105.545 156 144 107.625
-234 144 107.333 233 145 107.824 162 151 107.471
-231 156 106.714 230.933 157 108 225.933 159 108
-57 160 107.684 168 160 107.471 57 161 106
-58 161 106.636 59 161 105.316 60 161 105.783
-158 161 106.05 58 162 108 59 162 106.2
-63 162 106 82 161.833 108 83 162 107.8
-83 161.833 108 84 162 106.759 160 162 106.714
-159.455 162 108 160 161.455 108 160.75 162 108
-46 164 105.6 64 166 106.286 65 166 106.636
-66 166 105.75 173 166 106.2 174 166 107.032
-176 166 107.778 62 167 105.333 64 167 105.231
-174 167 107.55 176 167 107.739 177 167 106.962
-216 167 107.1 168.13 168 108 174 168 105.75
-177 168 106.889 178 168 106.889 218 168 105.2
-74 169 105.333 166 168.25 108 167.2 169 108
-168 168.2 108 179 169 105.529 181 169 106.2
-183 170 105.529 192 169.333 108 195 170 107.471
-207 170 107.8 77 171 105.316 96 170.111 108
-197 171 106.645 198 171 106.457 208 171 106.457
-82 172 107.25 82 171.625 108 82.75 172 108
-197 172 106.5 198 172 106.826 203.5 172 108
-205.75 172 108 207 172 106.826 208 172 106.355
-80 173 106.2 82 172.375 108 175 173 107.087
-174.563 173 108 200 173 107.885 203 173 107.912
-205.455 173 108 209 173 106.105 210 173 105.474
-68 174 105.273 69 174 105.6 90 174 107.526
-89.75 174 108 90.75 174 108 175 174 106.895
-176 174 106.25 203 174 107.5 68 175 105.24
-88 175 105.818 90 174.75 108 177 174.895 108
-206 175 106.5 205.833 175 108 171 176 107.5
-171 175.333 108 172.231 176 108 176 175.933 108
-177.13 176 108 205 175.909 108 205 176 107.864
-206 176 106.636 205 178 105.882 204 179 105.29
-201 180 107.25 202 180 107.211 203 180 106.962
-202 181 106 203 181 107.348 169 182 106.235
-203 182 106.826 204 182 106.2 205 182 105.455
-171 183 105.176 173 183 105.778 204 183 107.1
-205 183 107.778 172 184 106.5 86 189.824 108
-227 88 110.4 226.5 88 111 228 89 109.444
-228 90 108.9 228 91 109.2 229 91 109.174
-229 92 108.667 230 91.8182 111 229 93 108.581
-230 93 108.2 233 101 109.5 232 102 108.24
-230.167 107 111 231 108 110.824 230.833 108 111
-232 109 109.182 236 119 108.545 236.64 125 111
-150 129.966 111 234.692 130 111 149 130.231 111
-148.63 131 111 235 131 109.227 236 131 108.273
-236 132 108.158 31 133 110.25 30.5882 135 111
-128 135 110.423 129 135 110.206 128 136 108.231
-129 136 110.1 129 136.818 111 157 138.643 111
-157 140 109.304 232.316 140 111 235.806 140 111
-156 141 108.136 156 142 109.08 157 142 109.4
-156 143 109.227 158 143 109.313 157 144 108.182
-232 145 109.2 234 145 108.682 234.567 145 111
-162 146 110.143 161 147 109.355 231 147 110.824
-233 147 110.864 164 148 110.471 232 148 110.909
-162 149 109.75 232 149 110.423 232.714 149 111
-231 150 110.423 232.929 150 111 231 151 109.696
-232 151 108.789 231 152 109.421 232 152 109
-231 153 110.053 230 154 108.692 170 157 109.457
-168 158 109.2 171 158 109.457 60 159 110.1
-168 159 108.529 172 159 109.457 223 158.875 111
-224 159 110.739 170 160 109.2 171 160 109.457
-172 160 109.8 174 160 110.143 82 161 108.909
-173 161 109.886 175 161 109.457 177 161 110.206
-177.818 161 111 105 162 110.25 106 162 109.2
-174 162 109.8 175 162 109.457 178 162 110.8
-220 162 110.25 220 161.417 111 106 163 109
-106.25 163 111 160 163 108.429 161 163 109.364
-161.2 163 111 175 163 108.882 161 164 109
-178 164 110.333 160 164.909 111 161.13 165 111
-179 165 108.968 184 165 109.457 183 166 109.457
-185 166 109.457 210 166 110.471 214 166 109.2
-215 166 108.882 66 167 109.6 65.125 167 111
-66 166.417 111 67 166.625 111 67.2727 167 111
-184 167 110.333 185 167 110.679 186 167 110.032
-187 167 109.457 194 167 110.8 193.5 167 111
-195 166.625 111 209 167 110.125 215 167 108.529
-66 168 109.5 65.25 168 111 67 168 110.308
-166.696 168 111 169 167.563 111 169 168 110.222
-170 168 110.735 171 168 110.735 172 167.87 111
-185 168 110.211 187 168 108.529 192 168 110.211
-192.714 168 111 193.25 168 111 195 168 109.645
-201 168 109.853 203 168 110.684 204 168 110.684
-207 167.5 111 210 168 109.826 213 168 110.864
-214 168 110.04 92.6842 169 111 167 168.875 111
-168 168.947 111 169 168.438 111 172 169 109.645
-173 169 109.429 192.818 169 111 194 169 109.5
-193.25 169 111 202 169 110.625 205 169 110.471
-207 169 108.75 93.25 170 111 173 170 109.35
-173.688 170 111 193 169.25 111 94 170.4 111
-95 170.625 111 173 171 111 82 172 108.818
-186 172 110.55 185.727 172 111 205 172 109.636
-205 171.375 111 92 173 110.55 91.25 173 111
-93 172.455 111 93 173 110.4 175 173 110.625
-186 172.375 111 195 173 110.471 195 172.571 111
-196 172.444 111 196 173 109.5 205 173 110.143
-90.5 174 111 91 173.2 111 91 174 108.6
-92 174 110.438 94 174 110.55 95 173.667 111
-95 174 109.875 175 174 109.75 176 174 109.313
-196 174 109.821 197 174 109.889 197.667 174 111
-204 174 108.947 205 173.4 111 205.75 174 111
-91 174.25 111 95 174.75 111 171 175 108.273
-176 175 109.909 195.563 175 111 197 175 110.217
-85 176 108 84.25 176 111 85 175.25 111
-85.1875 176 111 171.857 176 111 177 176 108.29
-196 176 111 197 176 110.143 205 175.333 111
-85 176.188 111 197 176.286 111 212 180.067 111
-207 67 113.333 208 68 112.645 209 68 112.889
-210 68.0667 114 210 70 112.457 213 71 112.313
-214 71 112.75 215 71 113.5 215 72 112.25
-216 73 111.261 217 73 111.273 213 74 112.8
-216 74 111.968 218 74 112.364 218.231 74 114
-218 75 111.783 218 76 112.313 219.091 76 114
-218 77 113.419 219 77 113.679 219.25 77 114
-219 78 113.778 220 78 113.419 220 79 113.143
-221 80 113.419 221.857 81 114 222 82 113.8
-222.167 84 114 223 84 113.143 224 85 113.333
-225 85 113.55 225 87 113.778 226 87 112.696
-226 88 111.783 227 87.2632 114 229 98 111.176
-231 110 111.529 230.04 113 114 231 114 111.529
-232 119 112.773 232 120 111.947 233 121 111.5
-233 128 111.581 234 129 112.227 31 130 113.793
-149 130 111.333 233.375 130 114 234 130 113.348
-31 131 112.636 32 131 112.5 234 131 112.364
-31 132 113.182 30.875 132 114 32 132 112.5
-232 132 112.2 233 132 111.455 131 133 112.962
-132 133 113.1 132 132.182 114 149 132.944 114
-129 134 112.111 130 134 111.581 131 134 111.9
-132 134 113.778 232 133.684 114 233 134 111.931
-130 135 111.2 131 135 112.7 126 135.067 114
-158 136 113.333 31.2857 137 114 232 137 111.581
-157 138 112.08 229.5 138 114 233 138 111.176
-229 142 113.824 230 142 113.143 108 143 113.545
-161 143 111.857 231 144 112.5 165 145 112.8
-164 146 112.313 229 146 113.8 231 146 111.091
-230 147 111.176 232.962 148 114 229 149 111.931
-226 151 113.143 227 152 113.545 229 152 113.909
-232.176 152 114 228 153 112.909 103 154 113.4
-104 154 113.455 101.818 155 114 103 155 111.429
-104 155 113 59 157 112.235 59 158 111.529
-222 157.565 114 177 159 113 220 160 112.545
-106 161.053 114 106.783 162 114 161 163 113.571
-189 163 113.206 106 163.13 114 159.677 164 114
-189 164 112.889 191 164 112.889 197.25 164 114
-208 164 112.457 161.667 165 114 191 165 113.684
-192 165 112.889 198 165 113.25 205 165 113.217
-67 166 112 66.4737 166 114 67 165.667 114
-68 166 112.241 68.8947 166 114 190 166 113.5
-191 166 113.25 192 166 111.947 197 166 113.885
-197 165.667 114 198 166 113.778 199 166 112.5
-203 166 111.75 66 166.75 114 68 167 111.923
-192 167 111.545 193 167 111.273 56 168 112.25
-56 167.125 114 56.5833 168 114 66.1429 168 114
-68 167.947 114 67.8571 168 114 90.625 168 114
-93 167.261 114 167.769 168 114 168 167.25 114
-172 167.391 114 193 168 111.6 56 169 111.75
-56.2 169 114 169 168.609 114 184 169 113.684
-184 168.333 114 185 168.75 114 185 169 113.308
-192.417 169 114 202.65 169 114 203 168.125 114
-204 168.455 114 173 169.857 114 185 170 113.308
-184.6 170 114 193 170 111.9 194 169.444 114
-194 170 112.125 95 170.261 114 185 171 112.263
-186 171 113.182 192.889 171 114 194 171 112
-195 171 112.696 93 171.684 114 185 172 113.182
-186.438 172 114 194 172 113 195 172 111.667
-196 172 112.714 204 171.875 114 205 172 112.875
-204.4 172 114 205.231 172 114 94 173 111.5
-185 172.111 114 205 173 112.5 204.867 173 114
-205.5 173 114 91.8667 174 114 94.6667 174 114
-195 173.722 114 197.429 174 114 206 173.25 114
-206 174 111.429 93 174.393 114 172 175 111.75
-172.125 175 114 196 174.667 114 205 175 113.571
-206.15 175 114 85 176 111.346 171 175.545 114
-176 186.853 114 181 187.808 114 201.75 67 117
-204 67 116.125 203 68 116.471 205 69 116.1
-208 73 116.217 209 73 116.125 208 74 116.333
-207.5 74 117 209 74 115.962 210 76 116.1
-211 76 116.217 215 77 115.2 214 78 115.8
-216 78 115.645 217 78 116.333 213 78.6667 117
-218 79 116.444 221.966 80 117 219 81 115.2
-222 81 114.136 221 82 114.176 221 83 114.857
-225 84.1111 117 223 86.8667 117 224 89 115.7
-225 89 115.227 225 90 115.5 224.697 92 117
-224 95 116.824 234.059 105 117 226 108 116.4
-227 110 116.778 228 111 116.824 228 112 116.206
-228 113 116.419 229 114 114.529 229 115 114.857
-229 118 115.8 230 119 116.885 231 119 115.759
-231 121 114.931 230 122 114.882 30 125 116.087
-31 126 115.5 228.5 126 117 146 127.966 117
-145.955 128 117 146 129 115.655 32 130 114.231
-134 130 116.5 135 130 116.471 230 130 116.778
-132 131 116.069 133 131 114.818 134 131 115.3
-135 131 116.778 132 132 114.182 133 132 114.091
-134 132 115.5 133 133 114.931 159 133 115.5
-229 133 116.143 230 133 115.147 149.433 134 117
-230 134 116.032 231 134 116.1 232 134 114.692
-159 135 114.2 161 135 116.217 228 135 116.8
-229 135 115.889 232 135 115.364 159 136 114.857
-160 136 115.56 161 136 116.739 163 136 116.333
-229 136 116.625 162 137 116.217 230 137 114.4
-164 138 116.739 164 139 115.889 226 142 116.824
-105.867 143 117 226 143 116.143 229 143 114.176
-167 144 115.2 228 144 115.853 229 144 115.235
-104 144.933 117 103.857 145 117 105 145 115.5
-168 145 116.625 229 145 115 168 146 116.885
-169 146 116.778 170 146 116.333 227 146 116.545
-170 148 115.8 172 149 115.457 222.125 149 117
-223 150 115.457 224 151 115.2 220 152 116.143
-221 152 115.853 222 152 115.8 224 152 115.853
-51 152.087 117 221 153 115.457 222 153 115.8
-223 153 116.471 102 154 116.143 104 154 115.5
-219 154 116.5 101.895 155 117 103.545 155 117
-182 154.75 117 216 155 116.471 217 155 116.032
-218 155 116.333 181 156 115.457 182 156 116.4
-216 156 115.8 217 156 116.333 217.75 156 117
-223 155.917 117 161 157 114.8 160.313 157 117
-161 156.083 117 162 157 116 162.333 157 117
-182 157 116.032 185 157 116.206 212 157 116.471
-214 157 116.559 216 157 115.457 217 157 116.333
-217.75 157 117 161 157.55 117 162 157.857 117
-176 158 114.207 183 158 115.853 212 158 115.457
-216 158 115.457 217 158 116.032 218 158 115.929
-185 159 115.457 205 158.833 117 208 159 116.419
-210 159 116.125 189 160 115.457 192 160 116.8
-207 160 116.032 208 160 115.645 209 160 116.217
-217 160 114.9 187 161 114.29 188 161 114.968
-204 161 115.8 205 161 115.645 207 161 116.419
-208 161 116.419 209.5 161 117 217 161 116.069
-103.083 162 117 206 162 116.1 210 162 114.667
-216 162 116.864 217 162 116.88 58 163 116.739
-57.8182 163 117 58.25 163 117 69 162.818 117
-103 163 116.087 103 162.125 117 211 163 114.931
-69 164 116.217 103 163.875 117 162.077 164 117
-68 165 116.25 68 164.813 117 159.933 165 117
-197 165 114.333 69 166 114.667 170 166 114.9
-190 166 114.75 190 165.455 117 191 166 115.2
-56 167 114.75 56 166 117 66 167 114.333
-67 167 116.348 67.3333 167 117 91 167 114.783
-191 167 115.765 192 167 116.455 56 168 117
-67 168 114.692 68 167.385 117 89.0909 168 117
-168.125 168 117 172 168 116.1 171.684 168 117
-184 168 114.6 184 167 117 184.333 168 117
-190.923 168 117 192 168 114.923 193 168 115.333
-193.333 168 117 201.067 168 117 202 167.067 117
-203 168 114.13 204.467 168 117 56 169 114.563
-89.25 169 117 91 169 115 94.6364 169 117
-171 169 115.579 172 169 115.7 184 168.8 117
-184 169 116 185 169 116.25 192 169 114.789
-202 169 116.6 201.923 169 117 204.609 169 117
-79 170 115.875 79 169.727 117 80 169.417 117
-80 170 115.385 185 170 116.571 192 169.737 117
-79 170.273 117 80 170.304 117 94 170.286 117
-185 171 115.737 186 171 114.474 195 171 116.727
-194.875 171 117 204 171 116.8 204 170.857 117
-94 171.455 117 186 172 114.778 194 172 115.286
-194 171.467 117 195 172 116.333 196 172 115
-205 172 114.474 92.2273 173 117 195 173 115.773
-196 173 116.1 205 173 114.6 93 174 116.75
-171 173.889 117 197 174 114.692 205 174 115.286
-206 174 115.636 206 175 114.818 172 175.933 117
-204 185 115.579 176.85 186 117 177 185.813 117
-178 185.417 117 184 186 116.735 184 187.385 117
-200.25 67 120 200.333 69 120 204 70 117.968
-202.125 71 120 204 71 118.313 204 74 119.143
-206 77 118.457 208 77 118.5 207 78 119.032
-210 78 118.25 217 79 117.273 210 79.5455 120
-214 80 119.5 216 80 117.261 217 80 117.103
-216 81 117.667 221 86 118.364 219 87 119.824
-220 87 119.8 220.5 87 120 220 88 119.559
-221 88 119.5 222 87.2857 120 222 89 119.1
-222 90.3333 120 223 90.7692 120 224 91.125 120
-222.545 93 120 224 93 118.56 33 105 119.8
-33 107 119.471 32 108 119.739 33 108 119.824
-223.867 108 120 32 109 118.556 33 109 119.824
-224.526 109 120 31 110 119.526 225 110 119.1
-32 111 118.5 224 111 119.419 224 112 118.457
-225 112 118.2 31 113 117.75 224 113 118.457
-225 113 118.645 226 113 118.3 226 114 119.864
-31 119 117.529 226 119 118.457 226 120 118.457
-227 120 118.258 230 120 117.391 225 121 119.471
-227 121 119.739 229 121 118.08 33 127 118.818
-29.4857 128 120 227.929 128 120 145.147 129 120
-228 129 119.864 226 130 119.143 162 131 118.8
-226 131 119.118 161 132 118.235 164 132 118.8
-227 132 118.457 34.4545 133 120 34 134 119.211
-226 135 118.457 230 135 117.517 231 135 117.409
-230 136 117.429 165 137 117.176 169 136.167 120
-169 137 119.143 168 138 118.457 224 138 118.8
-226 138 118.75 110 139 119.824 167 139 118.645
-225 139 119.032 226 139 119.333 227 139 118.556
-167 140 118 226 140 118.941 228 140 117.265
-224 141 118.8 106.133 142 120 221 142 118.8
-106 142.5 120 105.75 143 120 170 143 118.645
-173 143 118.8 103 144 119.769 105.857 144 120
-220 144 118.457 102 145 117.6 103 145 117.947
-104 144.667 120 105 144.857 120 221 145 118.457
-99 146 118.853 101 146 118.182 102 146 117.231
-219 146 118.457 221 146 118.8 222 146 119.206
-223 146 119.471 174 147 118.2 219 147 118.8
-221 147 119.559 222 147 119.273 223 147 118.909
-220.286 148 120 221 148 119.559 222 148 118.545
-221 149 119.1 179 150 118.457 220.346 150 120
-177 151 118.556 178 151 118.889 179 151 118.457
-213 152 118.8 218 152 117.857 181 153 119.1
-185 153 119.824 215 153 118.457 217 153 117.882
-102 153.85 120 103.438 154 120 210 154 118.457
-215 154 118.2 222 154 117.455 223 154 118.111
-224 154 117.45 104 155 119.143 209 155 118.457
-211 155 118.457 213 155 118.7 219 155 117.273
-221 155 118.759 222 155 119.172 223 155 118.435
-103 155.895 120 104 155.143 120 184 156 117.529
-189 156 118.457 211 156 117.882 213 156 117.968
-218.727 156 120 219 155.87 120 219.429 156 120
-220 156 119.294 222 156 119.04 161 157 118.737
-162 157 118.636 189 157 118.2 201 157 119.206
-219 156.75 120 219 157 119.5 198 158 119.419
-202 158 119.206 203 159 118.4 165 160 119.609
-164.727 160 120 165 159.75 120 202 160 117.182
-210 160 117.6 165 160.6 120 210 161 117.333
-211 161 119.786 211.25 161 120 212.75 161 120
-214 161 118.909 216 161 118.105 57 162 118.688
-57 161.125 120 58 161.083 120 58 162 118.565
-104 162 118.65 105 162 118.111 106 162 117.375
-188 162 119.684 57 163 118.688 67.5333 163 120
-68 162.417 120 101 163 119.308 100.143 163 120
-102 162.739 120 102 163 118.364 103 162.563 120
-104 163 119 188 163 119 57 164 119
-56.5556 164 120 57.8 164 120 101 164 119.217
-102 164 119.25 103 164 118 103.111 164 120
-181 164 119.308 188 164 119.308 189 164 118.889
-57 165 117.75 56.25 165 120 57.25 165 120
-68 165 118.125 68.3125 165 120 162 164.053 120
-162.667 165 120 169 164.5 120 180.739 165 120
-189 165 118.444 190 165 117.75 197 165 119.667
-198 165 119.55 57 165.25 120 68 166 118.826
-69 165.55 120 69 166 118.313 93.2 166 120
-161 165.947 120 182 166 118.364 183 166 117.375
-189.067 166 120 191 165.333 120 198 166 118.25
-199 166 118.95 56 167 117.75 68 167 118
-162 166.261 120 171.519 167 120 183 166.636 120
-190 166.737 120 198 166.35 120 200 167 119.182
-199.25 167 120 200 166.571 120 201 166.632 120
-201 167 117.375 184 168 117.75 193 168 118.579
-192.25 168 120 201 168 118 202 167.417 120
-192 169 119.211 192 168.375 120 203 169 119.87
-203 168.857 120 79 170 117.563 80 170 118.75
-193 170 119.684 203 170 117.391 204 170 117.6
-93 171 119 94 171 118 94.3704 171 120
-94.3704 172 120 94 172.667 120 170.192 175 120
-171 175.808 120 184 184.267 120 176.533 186 120
-180 186 117.25 181 186 117.6 181.8 186 120
-182.091 186 120 185 186 117.091 175 186.588 120
-181 187 120 184 187 117.652 183.053 187 120
-185 187 117.088 182 187.615 120 200.25 68 123
-200.333 69 123 205 80 122.625 207 80 121.556
-208 80 122.423 210 80 120.714 221 79.913 123
-205 80.75 123 207 81 121.889 214 81 120.12
-206 82 122.032 207 82 121.645 208 82 122.8
-213 82 120.333 214 82 120.231 211 83 121.645
-213 83 121.5 210.182 84 123 212 84 121.8
-213 84 122.125 213 84.875 123 214 85.5 123
-216 87 122.739 217 87 122.55 221 87 120.273
-222 87 120.333 218 88 121.2 220 89 121.038
-221 89 120.103 221 90 120.231 221 91 121.5
-223 91 122.25 220 92 122.129 221 92 121.7
-222 92 121.889 222.667 92 123 222 93 120.529
-34 102 121.962 34 101.182 123 33 103 121.895
-34 103 121.7 33 104 120.682 34 104 121.5
-31.8235 105 123 34 105 121.5 32 106 120.667
-222 107 120.529 220 109 122.778 224 109 121
-220 110 122.333 221 110 122.032 222 110 122.206
-223 110 121.909 221 111 122.806 222 111 121.909
-221 114 122.032 222 114 120.857 220 115 122.143
-225 115 120.273 226 115 120.692 223 116 121.25
-224 116 121.125 225 116 120.333 221 117 121.457
-224 117 121.2 222 118 122.333 223 118 122.739
-223 119 122.063 223 120 121.853 222 121 121.457
-224 121 120.529 221 122 121.457 223 122 121.457
-226 122 120.455 227 122 121.219 221 123 121.457
-224 123 121.5 225 123 121.853 226 123 121.909
-227 123 121.219 149 123.7 123 226 124 121.909
-227 124 120.094 34.4737 126 123 226 126 121.125
-161 126.5 123 165 127 122.824 225 127 122.1
-226 127 121.7 34.7391 128 123 134 127.833 123
-145.059 128 123 165 128 121.8 217.875 128 123
-219 128 121.8 223 128 121.8 227 128 122.167
-135 128.077 123 162 129 121.235 164 129 121.8
-167 129 121.8 226 129 120.115 227 129 120.316
-35 130 121.818 136.4 130 123 124 133 121.355
-219 133 121.457 168 134 121.5 220 135 121.8
-219 136 122.786 218 138 121.457 220 138 121.457
-221 138 121.645 222 138 121.304 174 139 121.457
-177 139 122.471 220 139 122.8 221 139 122.8
-222 139 122.217 223 139 120.5 104.6 140 123
-106 140 121.355 173 140 121.2 177 141 122.1
-178 141 122.032 179 141 122.471 221 141 120.818
-105 142 123 106 142 120.857 176 142 122.129
-215 142 122.25 102 143 120.29 103 143 120.261
-104 143 120.75 176 143 121.543 212 143 122.471
-104 144 120.857 116 144 121.714 117 143.818 123
-181 144 121.8 182 144 122.471 212 144 121.457
-214 144 121.886 104.417 145 123 106 145 122
-116 145 120.167 117 145 120.3 179 145 121.457
-215 145 121.8 105 145.438 123 106 145.261 123
-116 145.739 123 181 146 122.778 184 146 121.8
-210 146 122.806 214 146 121.645 216 146 121.457
-46 147 121.111 181 147 122.778 182 147 122.778
-184 147 121.457 205 147 122.471 205 146.5 123
-208 147 121.457 209 147 121.8 211 147 121.8
-91 147.5 123 181 148 121.7 205 148 121.457
-207 148 121.457 211 148 121.457 212 148 122.125
-214 148 122.125 90 149 122.419 188 149 121.8
-210 149 121.457 212.375 149 123 42 150 122.4
-41.625 150 123 42 149.625 123 42.2727 150 123
-89 150 120.882 203 150 121.853 204 150 121.457
-209 150 121.457 210 150 121.645 211 150 122.217
-211.75 150 123 220 150 121.08 52 151 120.692
-208 151 121.457 214 150.625 123 53 152 122.5
-54.75 152 123 62 151.5 123 84 152 120.529
-189 152 121.457 208 152 121.2 177 153 122.609
-176.4 153 123 177 152.727 123 177.75 153 123
-177 153.25 123 103 154.211 123 104 155 120.857
-200 155 121.457 101.313 156 123 103 156 120.375
-217 156 122.182 216.455 156 123 218 155.813 123
-218 156 122.182 219.429 156 123 102 156.846 123
-103 156.933 123 217 157 121.696 216.286 157 123
-218 157 122.182 219 157 120.75 217 157.5 123
-206 159 122.053 207 159 121.875 165 159.813 123
-207 160 121.355 208 159.083 123 209 159.727 123
-209 160 122.438 209.429 160 123 60 161 122.333
-165 160.75 123 166 161 121.091 186 161 122.71
-187 160.364 123 188 161 122.55 207 161 121.696
-208 161 122.053 209 160.333 123 212 161 121.125
-57 161.455 123 70 162 120.273 72 161.263 123
-72 162 121.645 167 162 122.125 166.125 162 123
-167 161.125 123 187 162 120.222 57 163 122.625
-71 163 121 98 163 122.526 98 162.625 123
-99 162.045 123 99 163 120.261 100 163 120.158
-102 163 121.636 101.667 163 123 103 163 120.875
-167 162.467 123 169 163 122.71 168.25 163 123
-181 163 122.55 180.87 163 123 181.75 163 123
-57 164 120.75 58 163.273 123 90.6957 164 123
-93 164 122.4 100 164 121.091 102 164 121.125
-103 164 120.333 161 164 121.2 168 164 122.739
-167.923 164 123 172 163.6 123 182 163.143 123
-57 165 120.375 161 164.6 123 163 164.391 123
-182 165 122.842 182 164.857 123 191.375 165 123
-195 164.333 123 196 164.217 123 198 164.923 123
-172.654 166 123 182 166 120.783 195.8 166 123
-210 166 122.609 209.75 166 123 85 167 122.222
-84.125 167 123 85 166.632 123 85.5833 167 123
-162 166.783 123 163 166.526 123 191 167 121.235
-191 166.167 123 200 167 121.125 201 167 121.235
-210 167 122.438 211 167 122.4 84 168 122.4
-83.25 168 123 169 167.609 123 192 168 120.375
-201 168 120.4 202 168 121.05 203 168 120.783
-211 168 120.2 211.875 168 123 84 168.2 123
-90.125 169 123 91 169.368 123 95.1875 170 123
-211 169.15 123 212 169.375 123 92.4615 171 123
-93 172 121.75 170 171.87 123 170 173 120.75
-171 172.727 123 193 174 122.6 193 173.333 123
-194 173.067 123 194 175 120 194.9 175 123
-171 175.316 123 159 180.31 123 183.4 184 123
-184.545 184 123 182.895 185 123 175.143 186 123
-177 185.4 123 177 186 121.615 180.417 186 123
-181 186 121.091 178 187 121.889 179 187 122.1
-180 187 121.5 183 186.333 123 178 187.909 123
-182 188.435 123 193 188.077 123 92 190.6 123
-203 70 125.71 202 71 124.5 202.37 71 126
-202.286 73 126 208 81 123.12 205 83 125.727
-208 83 123.682 207 84 124.826 206 85 125.778
-205.8 85 126 206.5 85 126 206 86 125.125
-205.364 86 126 206.875 86 126 209 86 125.125
-210.375 86 126 211 85.7727 126 207.4 87 126
-209 87 125.032 210 87 125.333 210.545 87 126
-214 87 124.304 212 87.25 126 211.143 88 126
-213 88 125.625 210.867 89 126 212 89 124.645
-213 90 125.333 216 91 125.7 223.909 91 126
-215 92 125.739 216 92 125.75 224 92 124.636
-214 93 125.778 217 93 124.889 216 94 124.645
-217 94 125.217 218 94 125.625 217 95 125.217
-218 95 125.211 219 95 125.786 36 96 125.8
-36 95.7143 126 216 96 124.645 217 96 124.889
-218 96 124.111 219 96 123.136 35 97 125.778
-36 97 125.471 36 98 125.824 34 99 125.609
-35 99 124.5 34 100 124.421 35 100 124.5
-215 100 124.457 35 101 124.818 216 105 124.457
-218 109 124.5 219 109 124 218 111 123.882
-219 111 123.517 216 112 125.471 221 112 123.176
-215 113 125.5 218 113 125.885 220 113 124
-219 114 125.864 214 116 125.824 215.75 117 126
-217 119 124.457 36 121 124.457 37 121 125.471
-152.6 121 126 155 121 124.457 157 121 124.8
-215 121 124.457 152 122 125.625 153 122 124.853
-166 121.833 126 153 123 123.882 155 123 124.457
-165 123 125.125 218 123 124.457 36 124 124.8
-146.923 124 126 165 124 125.217 170 123.833 126
-218 124 124.8 220 124 123.818 36 125 124.457
-160 125 124.313 165 125 125.125 170 125 124.8
-212 125 125.1 211.4 125 126 219.857 125 126
-221 125 125.25 223 125 125.545 224 125 125.206
-35 126 123.882 36 126 124.645 37 126 124.645
-145.8 126 126 160 126 123.783 170 126 124.457
-212 126 125.778 213 126 125.55 213.6 126 126
-219 126 125.885 223 126 125.545 224 126 124.909
-36 127 125.217 213.25 127 126 36 128 124.826
-37 128 124.889 174 127.25 126 217 127.739 126
-216.571 128 126 228 128 123.75 227.25 128 126
-37 129 124.645 38.5 129 126 174 129 124.645
-214 129 125.55 216 129 125.55 216 128.727 126
-228 128.75 126 38 130 125.471 174 130 124.889
-146.5 131 126 212 131 124.457 37 132 125.559
-176 132 124.645 216 132 124.889 177 133 125.143
-211 133 124.8 215 133 124.457 211 134 124.457
-217 135 124.3 216 136 124.147 217 136 124.5
-176 137 124.111 213 138 124.2 207.167 139 126
-209 139 124.457 217 139 124.125 224 139 125.455
-223.2 139 126 224 138.556 126 225 138.5 126
-225 139 125.143 102 140 124.2 104 140 124.227
-182 140 124.645 183 140 124.7 207.5 140 126
-216 140 124.8 217 140 124.545 43 141 125.824
-103 141 123.947 104.857 141 126 167 141 124.385
-166.364 141 126 167 140.417 126 182 141 124.889
-184 141 124.645 209 141 124.645 216 141 124.345
-218 141 123.818 42 142 124.235 43 142 125.559
-99 142 124.2 105 141.25 126 167 142 124
-183 142 124.645 186 142 124.7 186.722 142 126
-203 142 124.457 207.222 142 126 209 142 124.645
-213 142 124.5 46 142.5 126 168 143 123.13
-169 143 124.3 185 143 124.645 190 143 125.778
-191 143 124.457 192 143 124.645 205 143 124.8
-97 144 123.182 105 144 124.826 116 143.769 126
-168 144 124 169 144 123 184 144 123.882
-190 144 125.032 191 144 124.645 198 144 124.457
-202 144 124.457 105 145 124.105 106 145 124.2
-116.737 145 126 168 144.37 126 169 144.609 126
-188 145 125.1 189 144.125 126 193 145 125.55
-201 145 124.457 205 145 124.457 89 145.25 126
-115 145.857 126 115.25 146 126 194 146 124.457
-90 147 124.5 116 146.111 126 191 147 124.645
-202 147 124.457 196 148 124.8 43 149 124.364
-44 149 125.609 45 149 125.8 59 149 125.824
-191 149 124.457 194 149 123.529 197 149 124.556
-214 149 124.412 216 149 124.56 217 149 124.364
-42 150 123.818 43 149.857 126 44 149.273 126
-59.3333 150 126 60 150 125.75 61 150 125.333
-64 150 124.457 212.25 150 126 215 150 125.833
-216 150 125.864 217 150 124.909 54 151 123.316
-55 151 123.833 56 151 124.5 211.4 151 126
-214.75 151 126 54 152 124.286 59 151.375 126
-177 153 124.286 218 153 125.667 217.727 153 126
-176 154 125.308 102 155 125.8 174 155 125.55
-174 154.571 126 175 155 124.862 214 155 125.118
-215 155 124.5 217 155 124.875 217.4 155 126
-175 156 124.889 176 156 124.929 176.667 156 126
-214 155.909 126 216 156 123.938 217.368 156 126
-218 156 123.6 219 156 123.692 100 156.333 126
-102 157 123.75 103 156.273 126 204 157 125.4
-216 157 124.714 218 157 123.6 219 157 123.391
-100 157.909 126 205 158 123.8 206 158 124.091
-184 159 125.323 184 158.125 126 185 158.217 126
-185 159 124.258 205 159 123.517 208 158.923 126
-165 160 123.333 185 160 123.9 186 160 123.13
-208.654 160 126 209 160 123.75 61 161 123.3
-72 161 123.789 74 161 125.471 94 161 125.455
-94.5455 161 126 180 161 125.727 180 160.714 126
-181 160.444 126 185 161 125.684 57 162 124.2
-57.6 162 126 60 162 125.25 61 162 123.75
-70 162 124.579 73 162 123.556 92 162 124.7
-167 162 125.625 167.333 162 126 168 161.923 126
-168 162 125.143 181 162 123.188 180.063 162 126
-208 162 124.875 60 162.097 126 61 162.273 126
-69 163 124.5 71 163 125.727 71.25 163 126
-167.391 163 126 168 163 123.2 171 162.265 126
-181.25 163 126 207 162.2 126 208 163 126
-90 164 124.92 97.7273 164 126 163 164 125.25
-163 163.813 126 181 164 123.563 182 164 123.783
-190 163.773 126 87 165 125.4 86.6 165 126
-87.8571 165 126 192 165 124.111 194 165 123.1
-86 166 124.35 87 166 124.444 87.6364 166 126
-90.7391 166 126 164.435 166 126 191.857 166 126
-198 166 125.318 210 166 125.25 84.4737 167 126
-86 167 124.25 86.5833 167 126 162 166.6 126
-163 167 124.8 171.2 167 126 189 166.143 126
-210 167 124.125 211 167 123.75 84 168 123.818
-90 168 123.4 211 168 125.211 191 170 124.696
-190.333 170 126 192 169.889 126 192 170 125.25
-169 171 124.765 170 170.842 126 170 171 125.609
-191 170.909 126 192 171 124.263 191.083 171 126
-169 172 124.043 168.375 172 126 192 172 125.455
-193 172 124.875 171 173 124.636 170.737 173 126
-193 173 123.75 194 173 123.75 170 174 125.211
-171 174 125 195 175 124.2 195.13 175 126
-194 175.435 126 195 175.375 126 197 178 124.889
-197 179 124.821 197.733 179 126 197 179.917 126
-175 183 125.6 179 183 125.769 164 183.941 126
-184 184 124.2 175 185 124.889 176 185 125.308
-177 184.714 126 184 185 125.684 170 185.722 126
-170.714 186 126 173 185.714 126 176 185.375 126
-171 186.087 126 172 186.261 126 179 186.455 126
-180 186.333 126 192 186.818 126 182.5 188 126
-93 190 125 96 190.059 126 202.654 72 129
-207 72 128.806 209 72.6087 129 210 73.0909 129
-208 76 128 207.533 76 129 210 79 126.789
-210 78.2632 129 211 79 128.6 210 80 127.364
-210.857 80 129 211 79.6667 129 212 80 128.833
-211.5 80 129 212 79.9091 129 212 81 128.483
-211.5 81 129 212.5 81 129 212 81.4545 129
-207 85 126.857 205.1 86 129 207 86 126.5
-208 86 126.214 211 85.6667 129 212 86 126.5
-213 86 126.5 207 87 128 212 87 126.857
-213 87 127.071 205.833 88 129 207 87.0909 129
-210 88 126.4 211 87.75 129 211 88 127
-206 88.1667 129 210 89 127.773 205 90 128.684
-214 90 126.316 204 90.625 129 205 91 127.889
-211 90.625 129 212 90.4167 129 213 91 127.071
-215 91 126.882 223 91 128.143 204 92 128.125
-223 92 126.882 37 93 128.6 38 92.7143 129
-38.0909 93 129 203 93 128.684 205 93 127.457
-208 93 128.206 209 93 128.032 210 93 128.667
-37 94 128.053 203 94 128.333 209 94 128.333
-213.125 94 129 219 94 127.286 36 95 127
-202.739 95 129 209 95 128.125 34.9333 96 129
-203.5 96 129 209.583 96 129 213 96 128.625
-212.75 96 129 206 97 127.8 208 97 127.457
-210 96.7143 129 210 97 128.684 205 97.5 129
-209 98 127.889 211 98 127.889 212 99 127.889
-213 99 127.5 209 100 127.645 209 101 127.457
-212 102 127.457 208 103 127.8 208 104 127.457
-205 109 128.206 203 110 128.143 206 110 128.032
-207 110 127.457 214 110 127.457 212 111 127.457
-200 111.833 129 201 113 127.457 198.625 114 129
-204 114 127.853 218 114 126.818 199 115 127.8
-200 115 127.457 201 117 127.457 215 117 126.265
-223 117 127.895 222.632 117 129 223.875 117 129
-211 118 127.457 212 118 127.5 223 118 128
-222.143 118 129 223.261 118 129 202 119 128.8
-208 119 127.457 213 119 128.206 214 119 127.182
-202 120 128.419 203 120 128.5 209 120 127.457
-161 120.417 129 204 121 128.118 209 121 128.032
-152 121.818 129 166.6 122 129 205 122 127.457
-29.8235 123 129 167 122.25 129 168.6 123 129
-149 123.7 129 170.25 124 129 188 124 128.909
-187.833 124 129 208 124 127.889 196 125 128.143
-197 125 127.8 206 125 127.457 218 124.955 129
-218.1 125 129 39 126 127.182 189 126 128.824
-199 126 128.032 204 126 127.457 206 126 127.645
-210 126 128.308 133 126.824 129 172.75 127 129
-174 126.857 129 174.286 127 129 199 127 128.333
-205 127 127.457 206 127 127.889 210.455 127 129
-211 127 126.75 214 127 128.077 214.571 127 129
-216 126.25 129 218 127 126.3 217.25 127 129
-173 127.125 129 199 128 128.125 206 128 128.125
-215 128 126.964 228 128 126.818 179 128.182 129
-181 129 127.645 206.833 129 129 39 130 126.581
-146.273 130 129 179 130 127.8 183 130 127.457
-197 130 127.853 198 130 127.889 205 130 127.457
-207 130 128.25 209 129.417 129 39 131 126.529
-40 131 127.2 41.625 131 129 197 131 128.4
-198 131 128.55 201 131 128.125 209 131 127.457
-40 132 127.853 188 133 128.032 40 134 127.286
-180 134 127.543 187 134 127.889 188 134 128.217
-192 134 128.471 193 133.75 129 184 135 128.1
-188.286 135 129 192 135 127.457 43 136 127.8
-43.875 136 129 182 136 127.2 184 136 128.778
-185 136 128.778 186 136 128.125 206 136 127.457
-219 136 128.55 183 137 128.143 184 137 128.778
-185 137 128.778 196 137 128.55 203 137 127.8
-218 137 128.625 217.813 137 129 219 137 127.696
-220.375 137 129 102 138 126.29 184 138 127.75
-187 138 127.645 188 138 127.962 202 138 128.559
-219 137.667 129 220 137.375 129 222 138 128.4
-221.25 138 129 223 138 127.25 224 138 127.875
-224.375 138 129 186 139 128.1 187 139 127.889
-188 139 128.333 201 139 128.8 203 139 128.559
-205 139 128.032 206 139 127.444 223 139 126.429
-222.6 139 129 225 138.714 129 225.105 139 129
-186 140 126.563 187 140 127.111 188 140 127.853
-192 140 127.457 193 140 127.457 197 140 127.645
-200 140 127.457 204 140 128.423 204.714 140 129
-225 139.133 129 104 141 127.636 166.667 141 129
-167 140.143 129 188 141 128.4 189 141 128.909
-190 141 128.182 196 141 127.457 205.167 141 129
-213 141 127.154 214 141 127 105 142 126.818
-166.435 142 129 189 142 128.897 199 142 127.235
-200 142 126.882 201 142 126.176 207 142 128
-48 143 127.5 106 143 128.167 187.5 143 129
-189 143 128.833 188.857 143 129 194 143 127.345
-206 143 126.316 207 143 128 208 143 126.682
-50 143.188 129 207 144 127.615 208 144 127.7
-113.6 145 129 114 144.143 129 188 144.091 129
-114 146 128.217 115 147 128.769 114.714 147 129
-116 146.609 129 43 149 127.636 44 149 127.286
-44.4 149 129 45 148.455 129 46 148.727 129
-46 149 128.182 47 149 127.95 47.4667 149 129
-67 149 126.529 46 149.25 129 47 149.875 129
-59 150 126.094 211.455 150 129 214 150 126.75
-59 151 127 210 151 127.625 210 150.522 129
-211 151 126.3 213.667 151 129 208.813 152 129
-210 152 127.889 211 152 127.95 209 153 129
-211 152.304 129 216 153 128.786 214 153.565 129
-217 154 127.875 218 153.933 129 217.75 154 129
-174 154.5 129 176.895 155 129 205 155 128.71
-206 155 128.118 207 154.625 129 207 155 128.667
-101 156 128 102 156 127.826 174.074 156 129
-177 155.087 129 177 156 126.577 183 156 128.25
-182.125 156 129 204 156 127.147 206 156 128.308
-97 157 127.846 98 156.313 129 98 157 127.821
-100 156.067 129 101 156.625 129 101.25 157 129
-102 157 127.2 176 157 126.115 177 157 126.441
-183 157 127.8 184 156.632 129 184 157 128.125
-202 157 128.824 203 157 126.9 214 156.618 129
-217 157 127.5 178 158 128.71 183 158 128.222
-184 158 126.158 61 159 128.727 62 159 127.645
-95 159 128.4 183 158.778 129 183.1 159 129
-207.435 159 129 58.375 160 129 62 160 126.9
-71.9259 160 129 73 160 127.3 75 159.895 129
-94 160 126.75 95 160 127.038 95.7727 160 129
-179 160 128.8 180 159.045 129 180 160 126.577
-187 160 126.316 204 159.333 129 208 160 127.962
-62.4667 161 129 75 161 127.818 95 161 126.682
-95.5862 161 129 179.357 161 129 185 161 126.6
-186 161 128.348 186 160.545 129 208 161 127.304
-62 161.636 129 61.4286 162 129 71 162 128.625
-71.0769 162 129 92 161.056 129 168.769 162 129
-170 162 126.2 180 161.947 129 186 162 126.75
-187 162 128.217 207 162 126.692 207 161.167 129
-61 162.2 129 88.4545 163 129 89 162.455 129
-90 162.105 129 95 163 127.92 97.875 163 129
-167.833 163 129 181 162.231 129 187 162.75 129
-88 164 127.8 88 163.455 129 89 164 126.9
-95 164 127.714 97 164 128.286 96.6429 164 129
-100.176 164 129 163 163.571 129 163.857 164 129
-172.382 164 129 188 163.067 129 193 163.263 129
-86.5417 165 129 87 164.522 129 89 165 127.125
-90 165 127.5 97 165 128.769 98 165 128.217
-162.045 165 129 196 165 128.273 86 166 128.2
-86.3636 166 129 87.5833 166 129 91 165.261 129
-99 165.333 129 162 166 127.929 168.923 166 129
-194 166 126.818 195 166 128.294 195 165.6 129
-196 166 128.429 197 166 127.909 85 167 127.111
-86 167 127.05 92 167 127.5 93 167 128.5
-95.6667 167 129 165 167 126.857 189 167 127.125
-189.667 167 129 191 166.385 129 193 166.111 129
-166 168 128.1 166.857 168 129 189 168 127.696
-190 168 129 95.3704 169 129 164 168.333 129
-167.25 169 129 188.727 169 129 190 169 126.375
-95 169.909 129 168 170 127.75 169 170 126.783
-169.773 170 129 191 169.125 129 192 170 126.75
-168 171 128.25 167.87 171 129 169.944 171 129
-192 171 128.063 192 172 126.333 193 172 126.474
-193 173 126.45 194 173 126.45 194 174 127.222
-194 175 127.111 195 175 126.6 196 177 127.714
-196 176.75 129 197 177 127.333 197.833 177 129
-196 178 127.364 198.667 178 129 198 179.75 129
-207 180 128 92 181 128.667 92.375 181 129
-196 180.778 129 197 181 128.526 196.4 181 129
-202 181 127.174 204 181 127.765 207 181 127.393
-208 181 128.55 92 182 127.636 92.9091 182 129
-200.75 182 129 202 182 127.038 206 182 128.471
-207 182 128 208 182 127.444 209 182 126.9
-92 183 128.571 92.6667 183 129 174 183 126.273
-173.375 183 129 177 183 127.773 197 183 128.609
-198 183 128.71 207 183 128.333 208 183 126.261
-92 183.125 129 172 184 128.526 171.25 184 129
-171 185 128.455 172 185 127.8 173 185 126.682
-170 185.9 129 170.25 186 129 176 185.929 129
-175.68 187 129 179 187 127.565 178.45 187 129
-180 187 127.385 181 186.4 129 179 188 127
-178.5 188 129 180 188 126.5 181 188 127.5
-182 188 127.688 192.727 189 129 94 189.409 129
-95 190 127 193 189.194 129 86 191 126.5
-90.7368 191 129 87 191.8 129 90 191.452 129
-203 72 130.929 204 72 131.308 207 74 131.727
-208 74 130.962 211 74 130.765 208 75 130
-207.474 75 132 209 75 131.526 209 75.375 132
-208 76.5556 132 211 79 129.6 210 80 130.636
-212 80 129.231 212 81 129.882 213 82 130.5
-214 83 130.2 214.6 83 132 214 84 132
-206 85 130.2 214 85 129.429 213.5 85 132
-215 84.1 132 215 85 129.545 206.667 86 132
-210.727 86 132 215 85.5 132 42 87 131.909
-205.9 87 132 205.182 88 132 207 88 132
-41 89 131.824 205 89 130.846 205 88.2857 132
-206 89 129.882 207 89 130.857 208 89 130
-206 90 129.125 208 90 130.345 209 90 129.529
-210 90 129.261 39 91 131.739 211 91 129.391
-212 91 130.75 216 91 131.571 215.8 91 132
-216 90.7143 132 38 92 131.143 39 92 130.962
-39.6 92 132 203.37 92 132 212 92 130.364
-216 92 130.875 39 93 131 212 93 130.655
-216 92.75 132 211 95 132 212 95 132
-213 95 130.071 215 95 131.609 215 94.25 132
-216 95 132 202.533 96 132 215 95.3333 132
-211 97 129.094 34.5 98 132 203 98 131.129
-204 99 131.419 205 99 131.25 206 99 130.773
-37 100 129.529 201.727 100 132 207 100 130.304
-202 101 131.032 203 101 130.457 204 101 130.8
-202 102.25 132 202.857 103 132 203.167 104 132
-198.346 112 132 196 115.929 132 223 117 130.4
-194 118 131.739 193.889 118 132 223 118 130.636
-194 119 131.419 193.143 119 132 195 120 131.559
-212 120 129.882 153 121 129.667 155 121 130.543
-161 121 129.875 192 121 131.806 192 120.75 132
-192.5 121 132 195 121 131.471 212 121 130.154
-161 122 130.543 166 122 129.45 192.667 122 132
-193.75 122 132 40 123 131.1 152 123 129.857
-166 123 129.581 168 123 129.45 191 123 131.125
-193 122.75 132 193 123 131.909 202 123 129.545
-209 123 129.818 210 123 130.56 41 124 131.684
-159 124 130.543 167 124 130.147 187 124 130.364
-188 123.087 132 189 124 130.5 190 124 130.75
-195 124 129.857 210 124 129.409 218 124 131.625
-218 123.727 132 40 125 130.5 150 125 130.645
-157 125 130.543 165 125 129.529 170 125 130.355
-186 125 129.545 185.64 125 132 187 125 129.261
-191.75 125 132 192 124.5 132 194 125 131.182
-209 125 129.469 217 125 129.563 43 126 130.8
-157 126 130.543 158 126 129.581 160 126 129.2
-161 126 130.2 163 126 130.543 187 126 129.2
-190 126 130.235 201 126 129.094 208 126 129.714
-151 127 130.889 153 127 131.143 154 127 131.471
-155 127 131.118 156 127 131.471 159 127 129.5
-170 127 130.543 188 127 129.818 192 126.6 132
-192 127 131.824 210 127 130.667 133 127.5 132
-160 128 130.3 174 128 131.333 175 127.875 132
-176 127.625 132 180 127.435 132 185 128 131.885
-184.857 128 132 187 128 130.235 188 128 129.818
-191 128 131.206 200 128 129.844 201 128 130.545
-206.913 128 132 209.933 128 132 216 127.889 132
-44 129 130.645 161 129 131.824 164 128.909 132
-184 128.231 132 192 129 130.3 200 129 129.844
-201 129 130.182 207 128.286 132 42 130 130.111
-44 130 131.333 187 130 129.529 188 130 129.529
-189 130 130.08 190 130 129.882 191 130 130.5
-192 130 130.111 194 130 130.2 201 130 129.091
-44 131 131.333 188 131 129.265 189 131 130.773
-192 131 131.217 193 131 130.2 199 131 130.2
-46 132 131.333 192 132 131.333 194 132 130.5
-196 132 129.882 199 132 132 43 133 131.909
-47 133 131.032 106 133 129.882 110 132.265 132
-189.538 133 132 192 133 130 193 133 129.529
-195 133 130.235 197 133 131.217 197.462 133 132
-42 134 130.909 48 134 131.419 189 134 130.071
-190 133.545 132 191 134 130.8 194 134 129.682
-195 134 130.5 196 134 130.3 197.5 134 132
-198.857 134 132 45 134.857 132 103 135 129.265
-196 135 130 101 136 129.265 102 136 129.176
-189 136 129.517 196.571 136 132 218 136 129.167
-217.105 136 132 189 137 129.774 190 137 129.469
-196.696 137 132 201 137 129.9 221 136.875 132
-221 137 130.875 49 137.85 132 199.688 138 132
-217 138 131 220 138 129.682 223 138 130.615
-45 139 130.545 46 139 131.206 49 139 130.457
-52 139 130.457 199 139 129.882 199 138.478 132
-222 138.545 132 223 139 130.286 224 139 130.154
-50 141 130.457 87 141 131.206 131.294 141 132
-168 141 130.105 185 141 131.625 186 141 131.438
-186.188 141 132 204.75 141 132 205 140.813 132
-207.333 141 132 50 142 130.2 86 142 130.457
-106 142 131.143 167 142 130.182 186 142 132
-188 142 129.391 205.417 142 132 106 142.286 132
-187 143 131.25 186.333 143 132 187 142.857 132
-187.667 143 132 206 142.259 132 56 144 130.457
-75 144 130.457 80 144 130.457 85 144 129.265
-158 144 130.875 157.667 144 132 159 143.091 132
-159 144 130.421 159.667 144 132 171 144 129.789
-172 143.25 132 186.813 144 132 189 144 132
-74 145 130.457 81 145 129.529 82 145 130.235
-84 145 129.818 113.818 145 132 158 144.75 132
-159 145 131.308 158.143 145 132 159.545 145 132
-170 145 130.8 172 145 130.853 116.111 146 132
-159 145.4 132 172 146 131.118 73 147 129.176
-114 147 129.556 116 146.375 132 114 148 131
-115 147.947 132 45 149 129.783 46 149 129.6
-47 149 130.75 212 150 129.783 212 151 130.957
-208.8 152 132 210.545 152 132 63 153 131.077
-62.2 153 132 63 152.667 132 64 153 130.95
-208 153 129.75 210.133 153 132 216 153 129.273
-218 153 130.826 65 153.571 132 65 154 131.667
-66 153.667 132 66 154 131.419 207 154 130.875
-206.625 154 132 209 154 131.667 209.5 154 132
-216 154 130.667 217 154 129.474 64.8125 155 132
-66 155 131.118 181 155 130.3 182 155 129.1
-183 155 129.167 203.25 155 132 208 155 130.5
-209 155 131.8 210 155 131.471 211 154.421 132
-211 155 130.969 212 154.192 132 65.6 156 132
-67 155.125 132 67 156 131.323 68 156 131.667
-98.5455 156 132 175 155.818 132 176 155.65 132
-180.923 156 132 182 156 129.115 201 156 130.696
-202 155.419 132 208 156 131.8 209 155.5 132
-210.25 156 132 64 157 131.8 64.5 157 132
-66 157 131.769 68 157 131.118 69 157 131.118
-70.1875 157 132 99 156.357 132 99.4091 157 132
-175.1 157 132 184.077 157 132 200 157 130.543
-206.143 157 132 209 157 131.824 209.667 157 132
-212 156.292 132 214 156.519 132 61.2273 158 132
-65 158 131.654 70 157.75 132 93.6667 158 132
-94 157.474 132 185 158 129.947 184.188 158 132
-200 158 130.543 201 158 130.355 206 158 130.5
-206 157.071 132 61 158.278 132 71.4167 159 132
-72 158.533 132 74 158.824 132 75 159 130.889
-98 158.567 132 178 159 130.174 179 158.1 132
-179 159 129.158 183 158.188 132 184 159 131.348
-184 158.375 132 185 159 131.2 200 159 131.71
-204.25 159 132 207 159 130.579 206.25 159 132
-77 159.455 132 77.75 160 132 181 159.227 132
-185 160 130.742 186 160 129.783 206 160 131.885
-207 160 131.04 77 161 131.118 78 160.4 132
-78 161 131.743 89 161 131.053 92.6 161 132
-178 160.545 132 91 161.474 132 99 163 130.909
-181 162.375 132 186 162.474 132 96 163.571 132
-163 164 129.947 168.265 164 132 184 164 131.471
-183.25 164 132 189 163.45 132 193 164 131.625
-87 165 130.65 87.75 165 132 92 164.409 132
-96 165 129.158 98.9333 165 132 163 165 131.172
-164 165 131.333 183.333 165 132 185 165 130.147
-194 165 130.875 195 165 130.5 87 166 129.75
-97 166 131.684 163 166 131.5 166 165.903 132
-190 165.833 132 189.875 166 132 167 166.567 132
-93 168 129.316 163.769 168 132 167 168 129.091
-168 167.346 132 168 168 130.3 188 168 132
-95 168.273 132 166 169 130.227 167 169 129.1
-189 168.857 132 189 169 131.571 190 169 130.105
-62.75 170 132 63 169.8 132 64 169.143 132
-64 170 129.429 94 170 129.882 190 170 129.45
-191 170 129.778 63 171 131.571 62.75 171 132
-169 170.895 132 176 171 131.25 175.143 171 132
-197 170.625 132 175 172 131.667 176 172 130.5
-178 172 131.71 179 172 131.71 179.429 172 132
-198 172 130.444 199 172 131.4 176 173 131.308
-177 172.667 132 179 173 131.71 179.273 173 132
-175 174 131.4 198 173.909 132 198 175.4 132
-199 175.8 132 197 176.6 132 199 177 131.125
-180 179 131.71 196 178.4 132 201 179 130.444
-200.067 179 132 178 180 131.71 178 179.75 132
-178.75 180 132 92 181 132 178 181 130.895
-177 181 132 178.875 181 132 208.526 181 132
-92 182 131 179 181.091 132 196 181.455 132
-92 183 129.333 171 182.941 132 199 183 130.696
-201 183 130.364 206 183 130 172 183.684 132
-180.875 184 132 198 184 129.794 199 184 130.6
-200 184 130.625 202 184 130.821 203 184 131.471
-204 184 131.824 182 184.6 132 183 184.6 132
-184 184.625 132 199 185 131.4 200 185 130.5
-201 185 130.2 202 185 130.8 203 185 131.1
-204 185 130.962 168 185.045 132 171 186 129.45
-172 186 129.75 191 186 131.571 201 186 129.2
-175 187 131.217 176 188 129.783 178 189 130.579
-179 188.75 132 179 189 131.625 93 189.8 132
-179 189.167 132 193 189.323 132 85 191 131.727
-91 190.056 132 86 68 134.625 87 68 134.125
-85 69 134.206 87 69 134.419 91 69 134.824
-203 72.6538 135 207.278 75 135 208 75.6842 135
-215 77 133.444 49 78 134.8 214 78 134.769
-210 79 132.529 214 78.2857 135 216 78.1333 135
-213 79.8667 135 214 80 133.962 213 81 133.5
-212.375 81 135 211.714 82 135 207 82.375 135
-207 83 134.118 208 83 133.846 209 83 134.824
-209.333 83 135 211.714 83 135 43 84 133.696
-44 84 134.419 44 83.1429 135 206 84 132.125
-207 84 133.846 208 84 133.5 208.714 84 135
-209 83.3333 135 210 84 134.769 210.167 84 135
-213 84 134.143 214 83.5 135 213.667 84 135
-42 85 133 41.5652 85 135 43 85 132.581
-44 85 134.471 207 85 134.75 207.125 85 135
-208 84.4167 135 210 84.3333 135 213.75 85 135
-214 84.3333 135 215 84.625 135 215.25 85 135
-42 86 132.261 43 86 133.2 207 86 132.5
-211 86 133.8 41 87 132.316 43.5909 87 135
-206 87 132.143 41 88 132.1 42 88 132.882
-206 88 133.227 40 89 132.115 205 89 132.6
-206 89 133.714 207 89 133.412 39 90 133.8
-206 89.6 135 40 91 132.176 216 91 132.857
-215 94 132.75 214.4 94 135 215.6 94 135
-214 95 133.421 213.333 95 135 216 94.4 135
-214 96 133.444 215 96 132.9 215.737 96 135
-216 95.375 135 214 97 133.778 215 97 134.053
-214 97.9167 135 210 102 134.71 210 101.727 135
-202.278 103 135 230.5 103 135 40 115 132.581
-196 117.143 135 193.25 119 135 192 120.75 135
-192.667 121 135 43 122 133.355 44.25 122 135
-190.75 122 135 192.75 122 135 193.25 122 135
-193 122.167 135 40 124 132.176 188 123.833 135
-189 123.833 135 190 123.286 135 218 123.421 135
-192 125 132.75 193 125 132.316 218.806 125 135
-192 126 132.75 148 127 132.857 149 127 133.2
-150 127 132.176 209.375 127 135 133 128 133.444
-186.143 128 135 206.125 128 135 209.909 128 135
-216 128 133.2 148 129 133.543 149 129 133.543
-156 129 133.543 163 129 132.857 174 129 132.103
-206 129 134.182 207 129 133.25 216 128.75 135
-154 130 133.543 204 130 134.71 203.85 130 135
-205 130 134.25 206 130 134.684 207 129.368 135
-215 130 134.308 215 129.25 135 148 131 132.857
-163 131 133.543 174 131 134.286 189.353 131 135
-204 130.75 135 215 131 133 215.667 131 135
-151 132 134.118 160 132 133.5 162 132 133.8
-163 132 133.543 166 132 134.471 199 131.462 135
-215 132 133.688 214.125 132 135 150 133 134.143
-189 133 133.75 189 132.286 135 191 133 132.833
-44 134 132.29 45 134 132.529 51 134 134.143
-52 134 134.206 150 134 134.032 156 134 133.645
-157 134 133.889 163 134 133.125 164 134 133.147
-175 134 134.727 189 134 133.227 190 134 133.364
-190.5 134 135 46 135 132.882 47 135 132.882
-51 134.833 135 53 135 134.333 154 135 134.471
-155 135 134.143 164 135 133.455 187.643 135 135
-189 135 133.345 198.333 135 135 47 136 134.559
-47.625 136 135 165 136 134.531 190 136 133.966
-211 136 134.654 210.8 136 135 213 136 133.8
-214 136 134.032 215 136 134.333 46 137 133.182
-47 137 134.559 48 137 134.897 49 136.583 135
-57 137 134.8 57 136.75 135 189 136.455 135
-190 136.526 135 195.5 137 135 211 137 134.118
-210.091 137 135 212 137 134.118 214 137 133.8
-215 137 132.857 216 137 132.1 46 138 132.529
-47 138 133.182 56 138 134.217 56 137.143 135
-55.25 138 135 90 138 132.882 161 138 134.714
-55 139 132.429 55 138.1 135 215 138.609 135
-117 140 134.6 116.714 140 135 118 140 133.8
-119 139.455 135 119 140 134.053 119.316 140 135
-185 139.867 135 69 141 133.8 73 141 133.457
-76 141 134.824 76 140.6 135 79 141 133.457
-186 140.444 135 186.333 141 135 203 141 134.032
-204 141 133.35 207.455 141 135 77 142 132.909
-104.5 142 135 105.75 142 135 168 142 132.321
-169 142 133.179 170 142 133.32 185 142 132.13
-186.333 142 135 203 142 134.824 105 142.6 135
-186 143 132.429 186.545 143 135 187 143 132.857
-159 144 134 170 143.167 135 171 143.391 135
-172 143.105 135 186 143.429 135 187 144 134.25
-187.25 144 135 159 145 133.636 188 144.375 135
-113.5 146 135 115 146 134.7 161 146 133.95
-160 146 135 161 145.125 135 162 146 135
-113 147 132.789 113 146.125 135 161 147 134.125
-160.563 147 135 162 147 134.679 172 147 132.091
-113 148 133.3 112.37 148 135 161 147.467 135
-162 147.273 135 173 148 133.645 174 148 134.739
-178 148 133.6 178 147.417 135 50 149 133.714
-49.8125 149 135 51 149 133.6 112.818 149 135
-114 149 134.727 125 148.04 135 174 149 134
-175 149 133.846 177 149 133.355 178 149 133
-178.783 149 135 51 150 133 50.0909 150 135
-52 149.067 135 53 149.565 135 53.9091 150 135
-113 149.133 135 178 150 133.688 53 150.667 135
-177 151 134.71 178 151 133.8 210 151 132.692
-211 151 132.346 179 152 133.969 179.917 152 135
-210 152 133.125 63 153 133 63.7273 153 135
-178 152.188 135 180 153 133.258 181 153 134.55
-65 153.625 135 66 153.667 135 66.2727 154 135
-180 154 132.103 182 153.769 135 210 154 132.375
-211 153.6 135 179.409 155 135 182.955 155 135
-212 154.263 135 214 155 134.471 213.333 155 135
-65 156 133.688 64.5625 156 135 68 155.3 135
-175 156 132.4 177 156 132.875 183 156 134.885
-198 155.65 135 210 156 132.2 212 156 134.625
-213 156 133.4 214 156 133.826 65 157 132.261
-98.6774 157 135 165 157 134.16 164.364 157 135
-165 156.417 135 176 156.867 135 175.867 157 135
-181 156.077 135 182 157 133.2 183 157 134.333
-198 157 132.529 208 157 132.75 210 157 132.273
-61.1429 158 135 67 158 133.258 70 158 132.273
-71 157.625 135 71 158 132.75 195 158 134.471
-197 158 133.543 205 158 133.5 205 157.5 135
-204.333 158 135 208 158 134.609 209.917 158 135
-210 157.909 135 61 159 134.167 61.4545 159 135
-65.9333 159 135 71 158.375 135 72 158.727 135
-77 158.654 135 208 159 134.6 209 159 134.609
-60 160 132.875 61 160 134.2 62 160 134.9
-78 160 132.222 79 159.217 135 80 159.263 135
-80 160 133.765 200.435 160 135 208 159.143 135
-209 159.214 135 60 161 132.333 61 161 133
-62 161 132.692 79 161 132.771 81 161 133.8
-87.5 161 135 95.5 161 135 169 161 133.385
-182 161 134.143 200 160.909 135 77 162 132.577
-81 162 134.471 92 161.778 135 178 162 132.581
-179 162 132.222 182 162 133.421 186 161.931 135
-72 163 132.818 76 162.323 135 81 162.261 135
-93 162.182 135 178 163 133.846 177.333 163 135
-181 163 133.111 182 163 133.355 183 162.364 135
-183 163 133.645 98 163.769 135 182 164 132.794
-183 164 132.194 187.947 164 135 190 164 132.333
-191 164 132.333 88 164.25 135 88 165 133
-91 164.957 135 168.222 165 135 183 165 132.789
-189 165 133.853 190 165 132.882 195 165 134.25
-195 164.333 135 98.4 166 135 149.588 166 135
-165 166 133.962 166 166 133.125 169 166 133.5
-168.5 166 135 172 166 132.261 173 165.091 135
-182 165.292 135 186 165.955 135 187 166 134.842
-195 166 134.143 97 166.706 135 165 166.6 135
-166 166.192 135 168 166.125 135 168 167 133.174
-169 166.286 135 173 167 134.25 172.125 167 135
-173.875 167 135 195 167 134.053 94 167.091 135
-94 168 132.778 95 167.7 135 173 168 134.679
-174 168 134.032 189 168 132.6 195 168 134.419
-196 167.25 135 196 168 134.471 165.433 169 135
-174 169 133.5 196 169 133.625 63 170 135
-64 170 133.2 174 170 133.645 175 170 133.174
-195 169.545 135 196 170 133.688 197 169.75 135
-197 170 133.875 63 171 134 168 170.5 135
-176 170.067 135 196.417 171 135 86 172 133.543
-174.3 172 135 178 171.8 135 179.875 172 135
-219 171.739 135 83 173 134.778 84.7143 173 135
-87 173 133.543 173.926 173 135 174 172.75 135
-177 172.733 135 179.917 173 135 205 173 133.696
-205 172.091 135 206 173 133.565 206.647 173 135
-81 174 134.52 80.5556 174 135 82 174 134.333
-85 173.667 135 176 173.25 135 178 173.273 135
-179.182 174 135 198 173.857 135 205 173.667 135
-206 174 135 81 174.8 135 86 175 134.087
-174 175 134.143 175 175 132.429 175.316 175 135
-179 174.333 135 86 176 133.421 87 176 133.889
-198 175.364 135 199.261 176 135 207 176 134.053
-207 175.25 135 208 175.571 135 208 176 132.429
-86 177 134.182 85.8696 177 135 87 177 134.308
-176 177 134.609 177 177 134.667 207 177 134.069
-208 177 134.182 208.545 177 135 86 177.333 135
-87 177.545 135 176 178 134.609 177 178 134.625
-177.375 178 135 180 177.222 135 181 177.684 135
-199.929 178 135 200.091 178 135 201 177.565 135
-207 178 132.6 208 178 133.091 208.737 178 135
-176 178.6 135 177 179 134.55 178 178.417 135
-178 179 133.688 179 179 132.273 181 179 132.158
-196 179 133.227 198 178.933 135 199 178.684 135
-177 180 135 179 180 132.75 180 180 132.833
-181 180 132.167 182.065 180 135 197 179.429 135
-197 180 134.143 178 180.909 135 178 181 134.625
-180.375 181 135 182 181 133.364 196 181 133.071
-196.818 181 135 197 180.667 135 198 180.818 135
-177 181.5 135 178 181.333 135 181.125 182 135
-199 182 134.6 182 182.875 135 182 184 134.25
-166 184.045 135 184 184.1 135 174 186 134.318
-180 185.391 135 174 187 132.333 177 186.333 135
-190.4 187 135 90 188 134.609 89.625 188 135
-178 187.087 135 90 189 134.125 90.875 189 135
-174 189 134.1 193 188.591 135 91 189.143 135
-179 190 133.154 180 189.133 135 180 190 132.947
-181 190 134.684 88.4737 191 135 84 192 133.304
-93 191.391 135 80 192.5 135 92 68 135.3
-92.6429 68 138 82 69 136.773 83 69 135.273
-84 68.1923 138 66 70 136.5 66 69.4348 138
-69 70 137.419 72 70 137.824 75 70 136.645
-81 70 136 82 70 136.2 83 70 135.6
-84 70 135.75 86.875 70 138 87 69.9333 138
-89 69.875 138 89.1333 70 138 93 70 136.645
-94 69.1818 138 94 70 137.206 97 70 137.684
-65 71 137.739 66 71 136.962 67 71 137.333
-80 70.9444 138 83 71 137 90 71 137.684
-93 71 136.645 94 71 136.457 97 71 137.217
-97.8571 71 138 63 72 137.679 64 72 137.8
-64 71.3333 138 96 72 137.125 97 72 137.125
-97.875 72 138 62 73 137.778 97 72.875 138
-98 72.3333 138 97.3333 73 138 98 73 137.684
-98.5 73 138 99.25 73 138 101 73 136.889
-202 73 136.2 203 73 136.5 92 73.5 138
-101 74 137.419 202 74 136.636 203 73.5 138
-51 76 136.364 51 75.7778 138 52 76 136.364
-52.75 76 138 211 76 136.147 49 77 136.929
-50 77 135.316 51 77 135.261 52 77 137.053
-52.5 77 138 48 78 136.071 50 78 135.321
-51 78 136.556 47 79 137.455 48 79 135.261
-49 79 136 214 79 136.875 216 79 136.444
-47 80 135.5 48 80 136.5 213 80 135.333
-215 80 136.25 46 81 136.125 213 81 135.536
-214 80.2 138 214 81 136.286 45 82 135.714
-214 82 135.346 218.333 82 138 44 83 135.167
-45 83 135.2 46 83 136.5 207 83 136.071
-209 83 135.15 212 83 135.273 219 83 137.739
-218 83 138 45 84 135.529 207 84 136.5
-208 84 135.714 210 84 135.143 213 84 135.273
-218 84 137.52 217.5 84 138 219 83.3333 138
-207.2 85 138 214 85 135.333 215 85 135.45
-218 85 136.8 218.6 85 138 218 86 138
-40.5 87 138 215 94 135.391 215 95 137.25
-216 95 135.333 215 97 137.571 214 98 135.75
-213 98 138 41.375 99 138 204 99 136.889
-213 99 137.25 213.75 99 138 213 100 137.526
-202 101 135.968 212 101 137.667 211.25 101 138
-212 100.25 138 209.263 102 138 211 101.091 138
-211 102 136.696 210 103 135.938 209.421 103 138
-211.545 103 138 210 103.917 138 42 109 137.545
-42.6842 110 138 197 118 136.25 195 121 137.217
-195.316 121 138 45.5 122 138 192 122 135.783
-193 123 136.5 194.857 123 138 199 124 137.824
-188 125 136.2 189 125 136.2 191 125 135.667
-217 125 137.864 49 126 137.143 188 126 136.355
-190 126 137.032 192 126 136.8 186 127 135.222
-191 126.5 138 208 127 135.6 218 126.375 138
-207 128 136.826 208 128 137.143 99 128.5 138
-103 129 135.882 105 128.172 138 206 129 137.571
-208 129 135.818 97 130 137.471 99 130 136.457
-183 130 136.2 184 130 135.875 204 129.864 138
-205 129.533 138 206 129.333 138 98 131 136.889
-177 131 136.543 186 130.4 138 190 130.143 138
-190.4 131 138 204 131 135.6 203 131 138
-204.444 131 138 31 132 135.783 97 132 136.826
-173 132 135.667 182 132 136.543 184 132 136.25
-198 131.85 138 199 131.739 138 202 132 137.4
-202 131.842 138 203 132 136.25 203.583 132 138
-215 132 138 54 133 136.2 55 133 136.8
-56 132.5 138 89.6 133 138 93 133 136.8
-168 133 136.543 172 133 136.543 175 133 135.194
-177 133 136.2 184 133 136.889 184.909 133 138
-200 133 136.636 201 133 137.55 202 133 136.444
-203 133 137 56 134 137.143 92 134 137.032
-151 134 135.529 152 134 136.543 153 134 135.529
-174 134 135.176 176 134 135.455 180 133.273 138
-184 134 137.625 185 134 137.125 202 134 137.4
-51 135 135.2 54 135 135.6 57 135 136.556
-86 134.833 138 87 135 137.206 152 135 136.543
-160 135 136.355 175 135 135.441 185 135 137
-186 135 136.95 187 134.286 138 187 135 136.421
-201 134.182 138 213 134.727 138 48 136 135.391
-49 136 136.313 50 136 137.8 51 136 137.8
-53 136 135.4 55 136 136.2 57 136 136.125
-58 136 137.1 60 136 136.8 82 136 137.471
-89 136 135.968 152 136 135.968 158 136 136.2
-167 136 136.111 170 136 136.543 174 136 137.118
-176 136 135.577 192.818 136 138 210.6 136 138
-211 135.818 138 219 136 136.962 50 137 136.286
-52 136.533 138 53 136.65 138 55.3333 137 138
-56 137 135.429 153 137 135.857 159 137 136.111
-162 137 135.316 167 137 136.696 170 137 136.543
-177 137 137.55 195 137 137.053 209 137 137.625
-210 136.375 138 219 137 137.516 52 137.467 138
-55.5455 138 138 74 138 136.457 77 138 136.457
-79 138 137.217 80 138 137.217 158 138 137.4
-170 138 136.543 175 138 137.824 209 138 136.5
-210 138 135.794 220 138 137.318 221 138 137.143
-154 139 136.543 171 139 137.679 172 139 137.75
-196 139 136.5 208 139 136.75 209 139 135.875
-210 139 136 211 139 136.429 119 140 136
-155 140 137.471 184 139.625 138 184.2 140 138
-203 140 135.158 207 140 136.5 209 140 136.5
-182.684 141 138 202 140.056 138 208 140.75 138
-103.563 142 138 105.9 142 138 130.735 142 138
-156 142 137.4 185.7 142 138 201 142 136.457
-202 142 135.794 157 143 137.857 201 143 137.032
-202 143 136.645 203 143 137.217 205 142.69 138
-207 142.286 138 170 144 136.154 183 143.182 138
-185 143.261 138 188 144 135.29 155 145 137.182
-170.056 145 138 161.667 146 138 170 146 136.5
-162 146.25 138 169 147 137.471 168.143 147 138
-33.8235 148 138 175 148 137.053 50 149 135.333
-51 149 136.105 112 149 135.794 153 149 135.2
-51 150 137 53 149.522 138 54 150 135.6
-54.5 150 138 113 150 137.438 114 149.37 138
-163 150 137.609 163 149.625 138 179 149.5 138
-56.7273 151 138 58 150.125 138 58 151 137.222
-58.5833 151 138 112 150.933 138 163 151 137.71
-164 151 137.7 164.273 151 138 58 151.368 138
-173 151.333 138 176 151.5 138 64 153 135.333
-210 153 135.176 65 154 135.333 95 153.067 138
-182 154 135.783 210 154 138 121.176 155 138
-181 155 137.5 181 154.375 138 182 155 136.853
-67 155.222 138 98.5667 156 138 164.6 156 138
-182 156 136 211 156 135.692 166 157 135.667
-167 157 137.032 57 158 136.875 56.8 158 138
-58 158 135.375 59 158 135.375 63 158 137.739
-71 158 136.8 92.7368 158 138 165 157.875 138
-165.222 158 138 168 158 137.824 193 158 136.765
-207 157.467 138 208 158 137.25 208 157.947 138
-208.25 158 138 57 158.75 138 58 158.875 138
-59 158.467 138 62 159 135.667 72 159 135.375
-77 159 136.5 81 158.44 138 86 159 137.118
-90 159 136.6 168 159 137.471 170 159 137.735
-192 159 137.4 208 159 135.857 209 158.75 138
-209 159 137.25 73 160 136.2 74 160 136.457
-76 160 137.9 77 159.6 138 168 160 136.929
-171.37 160 138 194 160 136.543 73 161 136.2
-76 160.143 138 84 161 136.543 86 161 136.355
-91 161 136.5 106 161 136.714 105.25 161 138
-106.375 161 138 172.067 161 138 194 161 136.8
-193.263 161 138 195 161 137.25 195.467 161 138
-199 161 138 91 161.286 138 91 162 136.636
-91.625 162 138 106 162 136.875 105.25 162 138
-106.375 162 138 167.588 162 138 195 162 137.55
-200 161.75 138 76.9231 163 138 78 163 135.652
-89 163 136.826 91 162.333 138 176.935 163 138
-187.278 163 138 194 163 136.263 195 163 137.25
-77.75 164 138 194 164 137.143 195 164 135.75
-78 164.25 138 87 164.429 138 90.4348 165 138
-98.5 165 138 119.294 165 138 168 165 135.947
-91 166 136.889 167 165.565 138 168 166 135.222
-90 167 137.735 98 167 137.053 97.25 167 138
-99 166.417 138 99 167 136.688 165.567 167 138
-169 167 135.833 171.857 167 138 87 168 137.1
-86.6667 168 138 89 168 136.8 90 168 137.323
-91 167.857 138 93 167.261 138 99 168 136.565
-100 167.813 138 100 168 137.182 174 167.091 138
-196 167.25 138 63 169 136.875 62.625 169 138
-63 168 138 87 169 136.25 88 169 136.688
-89 169 136.543 90.15 169 138 98.8696 169 138
-100 169 135.273 201 169 137.71 63 169.429 138
-86 170 135.115 88 170 136.645 89 170 137.032
-196 170 136.313 196 169.25 138 197 170 135.45
-201 170 137.667 202 170 137.609 202.188 170 138
-89 171 137.684 100 170.133 138 174 170.636 138
-175 171 137.842 175 170.75 138 197 171 135.778
-201 170.188 138 202 170.75 138 83 172 136.421
-82.4444 172 138 176 172 136.688 177 172 136.138
-178 172 135.48 179 172 135.875 198 172 135.882
-84 173 136 173 172.867 138 174 172.455 138
-175 173 137 178 173 135.45 179 173 136.375
-198 173 135.581 205 173 137.727 206 173 137.75
-80.625 174 138 82.75 174 138 84 173.526 138
-85.0667 174 138 81 174.375 138 85.85 175 138
-175.368 175 138 205 175 137.684 205 174.5 138
-169 176 137.8 168.818 176 138 199 176 135.667
-202.286 176 138 203 175.474 138 204 176 137.323
-205 176 136.412 206 175.417 138 169 177 136.895
-168 177 138 175.75 177 138 176 176.571 138
-177 176.364 138 177.467 177 138 198 177 136.4
-199 177 136.4 202 177 137.55 201.813 177 138
-205 177 136.2 206 177 136 169 177.875 138
-177.333 178 138 179 178 137.143 179.4 178 138
-198 178 136.556 199 178 136.444 201.667 178 138
-203 178 135.375 204 178 135.9 208.526 178 138
-177 179 136.125 177 178.375 138 178 179 137.333
-179 179 137.5 179.167 179 138 197 179 135.45
-201 179 137.333 178 180 137.5 179 180 135.75
-181 180 137.318 182 180 135.333 201.684 180 138
-208.077 180 138 172 180.8 138 181 181 137
-181.714 181 138 198 181 137 201.087 181 138
-209 180.923 138 172 182 136.263 178 182 135.375
-183 182 136.364 197 181.333 138 198 181.045 138
-200 181.727 138 172 183 135.273 173 182.071 138
-173 183 135.4 182 183 135.75 183 183 135.923
-191 183 137.4 190.667 183 138 191 182.8 138
-191.273 183 138 184 183.591 138 187 184 136.645
-188 183.818 138 188.5 184 138 191 183.6 138
-167 184.071 138 189 184.667 138 189 185 137.864
-72 185.75 138 85 186 137.125 85 185.364 138
-89 186 135.577 88.3 186 138 196 186 135.462
-195.313 186 138 72 187 136.25 73 187 136.696
-84 187 136.969 85 187 137.032 90 187 135.857
-90.3226 187 138 174 186.091 138 177.944 187 138
-190.455 187 138 195 187 136.5 196 187 135.577
-198 187 135.231 73 188 137 89 188 135.652
-90.3333 188 138 191 187.75 138 73 188.158 138
-88.8 190 138 90.1053 190 138 180 189.125 138
-182.091 190 138 74 190.842 138 179 190.913 138
-180 190.875 138 181 190.929 138 182 190.286 138
-86 192.045 138 86 69 140.571 87 69 139.5
-89 69 140.625 89.1333 69 141 86.5333 70 141
-89 70 138.857 97 69.2 141 63 71 140
-64 71 138.136 71 71 138.529 72 71 138.882
-79 71 138.12 80 71 138.143 86 71 138.24
-87 70.3684 141 87 71 139 88 71 139.429
-89 71 139.08 98 70.5 141 98 71 138.5
-99 71 138.3 99.6429 71 141 62 72 138.214
-65 72 138.909 73 72 139.355 81 72 138.24
-87 72 139.345 98 72 139 100 72 138.857
-60 73 139.8 61 73 138.833 63 73 138.2
-74 73 139.8 76 73 139.889 80 73 140.217
-81 73 139.556 86 73 139.3 87 73 139.556
-89 73 138.931 97 73 138.167 99 73 139
-102 73 138.96 58 74 139.5 59 74 138.6
-60 74 138.6 61 74 139 62 74 139.4
-63 74 140.1 77 74 139.645 78 74 139.889
-80 74 139.889 89 74 140.1 95 73.5417 141
-98 74 139.5 56 75 138.75 58 75 138.25
-59 75 138.667 60 75 139.75 64 74.6 141
-77 75 140.471 79 74.8333 141 83 75 139.889
-87 75 140.806 90 75 139.457 97 75 140.769
-98 75 140.318 99 75 140.684 203 75 140.6
-204 74.1111 141 52 76 139.125 54 76 138.545
-53.25 76 141 55 76 138.316 57 76 138.818
-59 76 139.962 84 76 139.8 85 76 139.8
-86 76 140.206 100 76 139.7 101 76 139.7
-53 76.375 141 53 77 139.636 87 77 140.471
-99 77 140.679 102 77 140.824 54 77.75 141
-96 78 139.8 99 78 140.032 100 78 140.206
-47.3846 79 141 213.737 80 141 217 80 138.103
-53 80.25 141 216 80.9091 141 207 82.9444 141
-48 84 140.471 219 84 139.2 218 84.75 141
-219 84.4 141 215 96 138.29 214 97 139.5
-212.5 98 141 213 97.6842 141 214 98 139.8
-211.778 99 141 212 98.5 141 213.737 100 141
-211.167 101 141 210 104 139 211 104 139.696
-42 105 138.667 210 104.5 141 211 105 140.8
-210.5 105 141 229 105.25 141 42 107 138.783
-210 107 139.091 210 108 140.526 209.25 108 141
-43 109 138.968 43 111 138.529 45 112 140.471
-201 114 140.76 201 115 139.44 202.8 115 141
-204 115 140.76 203.5 115 141 204.286 115 141
-199 116 138.469 202 116 139.143 203 115.5 141
-203 116 140.647 203.5 116 141 201 117 140.118
-202 117 139.846 203 116.167 141 200 118 140.76
-200.167 118 141 201 117.333 141 48 119 139.8
-198 119 138.818 199 119.818 141 200 119.333 141
-197 122 140.143 198 122 140.8 200 121.25 141
-50 123 139.457 198 123 139.645 199 123 138.261
-200 123 138 197 124 139.543 200 124 138.8
-50 125 139.579 53 125 139.8 99 124.833 141
-103 125 140.824 196 125 138.667 198 125 139.625
-199 125 139.35 200 124.55 141 218 125 139
-100 126 140.143 193 126 138.1 196 126 139.6
-199 125.407 141 218 126 138.818 46 127 140.609
-45 127 141 100 127 139.853 102 127 140.545
-216 127 138.333 217 127 138.231 53 128 139.313
-192 128 139.5 216 128 138.321 54 129 139.645
-57 129 139.457 58 129 139.8 96 129 139.2
-189 129 138.6 131 130 138.103 188 130 138.517
-191 130 139.421 204 130 138.45 205 130 138.75
-206 130 138.2 221 130 139.8 222 129.474 141
-222 130 139.333 55 131 138.529 56 131 139.2
-130 131 140.182 132 131 138.6 188 131 139.636
-204 131 138.571 215 131 138.321 221 131 139.091
-220.125 131 141 222 131 139.2 60 132 139.457
-87 132 139.457 186 132 140.8 187 131.565 141
-188 131.909 141 188.071 132 141 190.5 132 141
-197.3 132 141 203 132 139.75 63 133 139.8
-88 133 138.882 185.923 133 141 201 132.75 141
-202 132.167 141 71 135 139.457 182 134.591 141
-112.87 136 141 115 135.955 141 178 136 140.531
-178.625 136 141 184 136 139.607 215 135.75 141
-52 137 139.75 55 136.462 141 173 137 138.455
-182.556 137 141 184 137 139.125 185 137 138.9
-190.286 137 141 194.667 137 141 199 136.25 141
-216 136.667 141 217 137 138.783 216.056 137 141
-129.308 138 141 183 138 139.781 184 138 139.031
-185 138 139.781 186 138 140.7 193.091 138 141
-207 137.727 141 173 139 139.091 174 139 138.094
-175 139 138.5 179 139 138.115 184 139 138.714
-184.889 139 141 192 138.091 141 193 139 139.889
-194 139 138.667 213 138.867 141 212.75 139 141
-105 139.87 141 109 140 139.765 110 140 140.25
-176 139.828 141 179 140 138.652 180 140 139.636
-191 140 140.118 192 140 139.455 194 140 138.857
-196 140 138.103 197 140 139.44 210 140 141
-103.63 141 141 106 141 139.846 108 141 140.735
-107.25 141 141 109 141 139.6 110.875 141 141
-169 140.818 141 171 141 139.645 173 140.261 141
-180 141 139.778 181 141 140 184.273 141 141
-193 141 139.455 194 141 139.147 195 141 139.412
-196 141 138.9 197 141 139.444 198 141 139.696
-199 141 140.438 106.4 142 141 170 142 140.8
-182 142 139.038 192 141.5 141 198 142 140.4
-199 142 139.385 157 144 138.316 181.87 144 141
-183 144 139 184 144 140.053 184.316 144 141
-201 144 138.9 207.857 144 141 170 145 139.5
-201 145 138.947 202 145 140.571 127.548 146 141
-161 146 138.5 168 145.222 141 201 146 139.875
-161 147 138.75 162 147 138.529 168 147 138.158
-167.053 147 141 211 147 140.667 210.818 147 141
-211 146.714 141 114 148 140.444 125 147.481 141
-212 148 140.76 211.833 148 141 212 147.5 141
-213 147.625 141 213 148 140.182 177.667 149 141
-213 149 139.846 214 149 139.385 220 149 139.364
-219 149 141 220 148.143 141 53 150 139.138
-64 150 140.71 164.933 150 141 214 149.875 141
-57.25 151 141 58 150 141 59 151 141
-62 151 140.118 63 151 140.118 64 151 140.471
-162.333 151 141 173 150.955 141 178 151 140.9
-179 153 138.375 180 153 138.75 180 154 138.75
-181 154 138.29 92 155 140.419 167 155 140.625
-169 155 139.8 170 155 139.8 207 155 140.211
-208 155 139.962 210 155 138.529 67 156 140.864
-68 155.565 141 69 155.222 141 71.5556 156 141
-99.0303 156 141 164.867 156 141 167 156 138.316
-168 156 139.147 169 156 139.2 170.773 156 141
-208 156 140.806 209 156 139.235 65 157 139.5
-90 157 138.783 92 157 139.355 168 157 138.794
-170 157 139.543 187 157 140.8 187 156.818 141
-188 157 139.645 191 156.192 141 191 157 138.9
-195 156.684 141 197 156.848 141 57 158 138.474
-58 158 139.105 59 158 139.05 66 158 140.9
-91 158 139.2 92 158 139.355 176 157.391 141
-187 158 140.625 188 158 139.111 191 158 138.194
-209 158 138.375 84 158.263 141 92 159 138.529
-189 159 139.125 190 159 139.25 200 159 138.857
-92 160 138.577 102 160 140.667 102.6 160 141
-166.63 160 141 188 159.13 141 199 160 140.1
-199 159.7 141 219 160 140.4 220 160 139.875
-76 161 138.529 77 161 139.8 78.5 161 141
-93 161 138.167 103 161 139.895 104 160.813 141
-104 161 138.75 106 161 138.391 181 160.333 141
-200 161 138.333 219 160.75 141 82.75 162 141
-89 162 139.2 90 162 138.231 90 161.077 141
-104 161.75 141 106 162 138.391 172 162 140.318
-193 161.909 141 193.083 162 141 195 162 139.125
-77.8125 163 141 85.8125 163 141 90 163 138.2
-91 163 139.304 185.375 163 141 194 163 140.063
-77.4167 164 141 79 163.909 141 91 163.813 141
-185.4 164 141 194 164 138.273 195 164 138.529
-77 165 138.938 78 165 140.077 178 164.778 141
-195 165 138.529 76 166 139.895 77 166 139.174
-172 166 140.739 184 165.52 141 195 166 138.529
-64 167 140.294 63 167 141 64 166 141
-76 167 139.565 75.45 167 141 77 167 140.55
-97 166.8 141 171 166.231 141 172 167 138.316
-173 167 138.677 200.125 167 141 76 168 140.125
-99 168 140.75 99 167.875 141 173 168 138.321
-174 168 138.968 196 168 138.29 63 169 138.818
-75 169 140.25 74.6316 169 141 100 169 139.304
-174 169 139.313 195 169 139.571 202 169 138.455
-203 169 139.853 205 169 140.667 75 170 140.667
-75.2 170 141 85.32 170 141 174 170 138.75
-175 170 138.29 203 170 140.167 201 170.783 141
-202 171 138.273 202.833 171 141 83 172 140.727
-83.125 172 141 82 173 138.778 83 173 140.318
-84 173 139.579 87 172.545 141 173 173 141
-174 173 139.286 81 174 138.29 82 174 138.265
-87 174 139.8 169 175 140.526 204.714 175 141
-205 174.895 141 168.545 176 141 170 176 139.421
-174 175.467 141 176 177 138.375 177 177 138.75
-202 177 139.125 202.172 177 141 170 177.4 141
-180 178 138.391 208.091 178 141 180 179 139
-51.5667 180 141 180 180 138.231 203.261 180 141
-172.286 181 141 182 181 138.545 183 182 139.636
-185 182 139.929 186 182 140.667 198 181.182 141
-171 183 140.5 175 182.517 141 182 183 138.75
-185 183 140.217 186 183 139.6 191 183 138.6
-167.143 184 141 182 184 139.5 183 183.429 141
-189 184 138.75 189.429 184 141 71 185 139.35
-71 184.267 141 90.5667 185 141 180 184.333 141
-86 185.684 141 86 186 139.714 87 185.933 141
-87 186 140.833 88 186 139.227 74 187 138.667
-75 186.455 141 83 187 138.136 86 187 139.333
-87 187 139.696 106 186.433 141 169 187 140.167
-169 186.688 141 178.625 187 141 192 187 139.125
-74 188 138.857 78 187.895 141 81 188 139.543
-83 188 138.091 84 188 138.103 86 188 140.727
-87 188 139.889 169 188 139.655 168.409 188 141
-170 187.182 141 170.75 188 141 193 187.033 141
-74 189 140.647 75 189 139.5 84 189 139.846
-172.467 189 141 73.9091 190 141 76 190 139.364
-82 190 139.543 83 190 139.543 84 190 140.419
-89 189.75 141 89 190 139.8 180 190 140.1
-180.75 190 141 182 189.889 141 80 191 139.2
-83 191 139.543 84 191 140.032 85 191 140.727
-89 191 139.235 179 190.091 141 182 190.182 141
-84 192 138.794 88 192 139 90 192 139.2
-89 193.13 141 68 68.8529 144 67.5455 69 144
-69 68.6571 144 70 68.4857 144 71 68.4857 144
-72 68.4857 144 73 68.4857 144 74 68.3529 144
-75 68.3429 144 76 68.3529 144 77 68.5862 144
-78 68.7391 144 79 68.9444 144 79.1667 69 144
-83 69 144 91 69 144 92 69 144
-93 69 144 94 69 144 65 69.8235 144
-64.5 70 144 66 69.3529 144 67 69.2143 144
-80 69.1515 144 81 69.1818 144 82 69.1818 144
-84 69.2609 144 85 69.9444 144 85.0833 70 144
-89.2273 70 144 90 69.2609 144 95 69.2727 144
-96 70 144 63 70.8235 144 62.7391 71 144
-64 70.2069 144 86 70.4783 144 87 70.7857 144
-88 70.7391 144 89 70.2941 144 97 70.6 144
-98 71 141.882 97.25 71 144 99 71 143.7
-62 71.7727 144 61.7727 72 144 98 72 141.316
-97 72 144 99 72 141.882 100 71.9167 144
-99.9231 72 144 101 71.7391 144 101.353 72 144
-60 72.8235 144 59.5 73 144 61 72.5 144
-97.3158 73 144 99 73 141.545 99.6207 73 144
-102 72.3793 144 102.529 73 144 57.5 74 144
-58 73.8235 144 59 73.1765 144 73 74 141.783
-87 74 141.316 94.6471 74 144 95 73.6667 144
-95.5 74 144 98 73.7222 144 99 74 142.364
-98.4545 74 144 99.2609 74 144 103 73.7273 144
-103.182 74 144 56 75 144 57 74.2609 144
-67.3333 75 144 68 74.75 144 69 74.5455 144
-70 74.3182 144 71 74.2857 144 72 74.2857 144
-73 74.7727 144 73.4167 75 144 94.0833 75 144
-95.6471 75 144 99 74.4615 144 103.364 75 144
-204 74.3929 144 203.393 75 144 205 74.1765 144
-206 74.7857 144 206.261 75 144 54 76 144
-55 75.4074 144 63.0909 76 144 64 75.6429 144
-65 75.4444 144 66 75.3182 144 67 75.1176 144
-74 75.25 144 75 75.697 144 76 75.8485 144
-76.4545 76 144 80 76 141.818 94 76 141.25
-95 75.4074 144 103.364 76 144 203.324 76 144
-207 75.5 144 207.739 76 144 50.7059 77 144
-51 76.8529 144 52 77 144 53.0833 77 144
-61 77 143.833 61.2 77 144 62 76.75 144
-63 76.0588 144 77 76.1765 144 78 76.2222 144
-79 76.5238 144 79.9091 77 144 103.036 77 144
-203.647 77 144 208 76.2069 144 209 76.8148 144
-209.227 77 144 49 78 144 50 77.4286 144
-53 77.0909 144 60.0909 78 144 61 77.0909 144
-80 77.0455 144 81 77.375 144 82 77.75 144
-82.3636 78 144 84 78 142.364 102.429 78 144
-103 77.0588 144 204 77.5217 144 204.324 78 144
-210 77.6071 144 210.688 78 144 48 78.8214 144
-47.8148 79 144 58.0909 79 144 59 78.5455 144
-60 78.0455 144 83 78.3182 144 84 78.4444 144
-85 78.4444 144 86 78.5455 144 86.9091 79 144
-89 79 141.75 101.389 79 144 102 78.5217 144
-204.647 79 144 211 78.1515 144 212 78.5 144
-212.739 79 144 47.4783 80 144 55 80 144
-56 79.7059 144 57 79.75 144 58 79.0588 144
-87 79.0455 144 88 79.4444 144 89 79.5455 144
-90 79.6429 144 91 79.8182 144 91.6667 80 144
-100.059 80 144 101 79.3043 144 205 79.7059 144
-205.147 80 144 213 79.1765 144 214 79.697 144
-214.455 80 144 46 81 144 47 80.5 144
-53 81 141.75 54.5833 81 144 92 80.1176 144
-93 80.1176 144 94 80.4118 144 95 80.75 144
-96 80.75 144 97 80.6 144 98 80.375 144
-99 80.4118 144 100 80.0455 144 205.5 81 144
-215 80.3529 144 216 80.697 144 216.455 81 144
-45 81.6071 144 44.6667 82 144 52 82 143.833
-52.0909 82 144 53 81.6429 144 54 81.3182 144
-205.971 82 144 217 81.5217 144 217.478 82 144
-44 83 144 51.0588 83 144 52 82.0588 144
-206 82.0435 144 206.647 83 144 218 82.9231 144
-218.056 83 144 43.3529 84 144 49.7059 84 144
-50 83.7826 144 51 83.0455 144 207 83.6667 144
-207.176 84 144 218 84 142 219 83.7391 144
-219.273 84 144 43 84.6667 144 42.7857 85 144
-48.6207 85 144 49 84.5217 144 207.647 85 144
-220 84.5926 144 220.478 85 144 42 86 144
-48.0357 86 144 207.824 86 144 221 85.6667 144
-221.176 86 144 41.2143 87 144 47.5294 87 144
-48 86.0588 144 207.971 87 144 221.824 87 144
-41 87.2727 144 40.5152 88 144 47.0357 88 144
-208 87.1667 144 208.179 88 144 222 87.5 144
-222.176 88 144 40 89 144 46.697 89 144
-47 88.0909 144 208.353 89 144 222.667 89 144
-39.5152 90 144 46.3636 90 144 208 90 144
-218 90 143.824 217.909 90 144 218 89.9412 144
-218.036 90 144 223 89.6471 144 223.261 90 144
-39 91 144 46.0357 91 144 207.586 91 144
-218 91 143.833 217.909 91 144 218.045 91 144
-223.793 91 144 38.5152 92 144 45.697 92 144
-46 91.0909 144 207.486 92 144 218 91.0625 144
-224 91.5 144 224.176 92 144 38.1765 93 144
-45.5455 93 144 207.343 93 144 224.485 93 144
-38 93.5 144 37.8235 94 144 45.3636 94 144
-207.176 94 144 224.824 94 144 37.5152 95 144
-45.0357 95 144 207 95 144 225 94.5 144
-225.176 95 144 37.1765 96 144 44.8529 96 144
-45 95.1667 144 206.824 96 144 225.485 96 144
-37 96.5 144 36.8235 97 144 44.6765 97 144
-206.515 97 144 225.824 97 144 36.6571 98 144
-44.6765 98 144 206.176 98 144 226 97.5 144
-226.176 98 144 36.3429 99 144 44.5143 99 144
-206 99 144 211.793 99 144 212 98.4545 144
-213 98.4 144 213.462 99 144 226.485 99 144
-36.1765 100 144 44.5 100 144 205.824 100 144
-211.75 100 144 213.333 100 144 226.824 100 144
-36 100.5 144 35.8235 101 144 44.3529 101 144
-205.821 101 144 211.522 101 144 213 101 144
-227 100.353 144 227.324 101 144 35.5152 102 144
-44.3636 102 144 205.393 102 144 210.667 102 144
-211 101.522 144 213.179 102 144 227.647 102 144
-35.1765 103 144 43 103 141.682 44 103 142.364
-44.3636 103 144 205.214 103 144 210.353 103 144
-213.185 103 144 228 103 144 35 103.5 144
-34.8235 104 144 44.5455 104 144 205 103.353 144
-204.676 104 144 210 104 141.462 210.379 104 144
-212.706 104 144 213 103.5 144 228 104 144
-34.5152 105 144 44.697 105 144 204.353 105 144
-210.478 105 144 212.538 105 144 228.324 105 144
-34.1765 106 144 44.8529 106 144 204 106 144
-209.944 106 144 210 105.917 144 213 105.5 144
-213.261 106 144 221 106 143.7 220 106 144
-221 105 144 221.091 106 144 228.647 106 144
-34 106.545 144 33.8529 107 144 45 106.833 144
-45.0294 107 144 203.676 107 144 209 107 144
-212 107 141.545 213 107 142.2 213.522 107 144
-219 107 143 218.739 107 144 219 106.647 144
-220 107 143 220.333 107 144 221 106.077 144
-229 107 144 33.5152 108 144 45.0294 108 144
-203.353 108 144 208.708 108 144 212 108 144
-213 107.667 144 219 108 142.2 218.333 108 144
-220 108 143.118 220.179 108 144 229.324 108 144
-33.1818 109 144 45.1818 109 144 203 108.706 144
-202.853 109 144 209 109 142.8 208.5 109 144
-210 108.923 144 209.857 109 144 211 108.179 144
-218 109 142.95 217.759 109 144 218 108.462 144
-219 109 142.2 219.667 109 144 220 108.455 144
-229.647 109 144 33 110 144 45.5294 110 144
-202.697 110 144 209 110 143.824 208 110 144
-209.053 110 144 218 110 143.824 217.941 110 144
-218.167 110 144 219 109.706 144 230 110 144
-32.8235 111 144 45.8529 111 144 202.429 111 144
-209 110.2 144 218 110.2 144 230 111 144
-32.6571 112 144 46 111.455 144 46.1818 112 144
-202.045 112 144 230.176 112 144 32.4857 113 144
-46.5294 113 144 202 112.059 144 201.429 113 144
-230.485 113 144 32.4857 114 144 47 113.941 144
-47.0357 114 144 201.045 114 144 208 114 143.842
-207.8 114 144 208 113.8 144 209 113.8 144
-209 114 143.842 210 113.417 144 210 114 142.95
-211 113.588 144 211 114 142.95 211.583 114 144
-230.824 114 144 32.4857 115 144 47.5294 115 144
-202 115 144 203.417 115 144 204 114.696 144
-205 114.588 144 205 115 142.25 206 114.417 144
-207 114.8 144 207 115 143.727 207.2 115 144
-208 114.2 144 209 114.091 144 210 114.412 144
-211 114.304 144 231 115 144 32.4857 116 144
-48 115.941 144 48.0357 116 144 201 115.6 144
-200.636 116 144 201.8 116 144 203 116 142
-202.2 116 144 203.8 116 144 204.2 116 144
-205 115.636 144 205.8 116 144 206.2 116 144
-207 115.2 144 231 116 144 32.4857 117 144
-48.5294 117 144 200.083 117 144 202 116.077 144
-204 116.043 144 206 116.063 144 231 117 144
-32.4857 118 144 49 117.727 144 49.2143 118 144
-200 117.2 144 199.818 118 144 231 118 144
-32.4857 119 144 49.8214 119 144 199.583 119 144
-231 119 144 32.4857 120 144 50 119.217 144
-50.6207 120 144 99 119.833 144 98.6667 120 144
-100 119.833 144 101 120 143.684 101 119.882 144
-101.167 120 144 199 119.636 144 198.818 120 144
-230.824 120 144 32.4857 121 144 51 120.478 144
-51.5217 121 144 97 121 143.684 97 120.833 144
-96.8333 121 144 98 121 143.684 98 120.667 144
-101.167 121 144 198 121 141.3 199 120.8 144
-199.083 121 144 230.657 121 144 32.4857 122 144
-44 122 141.938 43 122 144 44 121.353 144
-45 121.773 144 45.1786 122 144 52 121.478 144
-52.5217 122 144 97 122 143.684 96.6667 122 144
-100 122 143.684 101 122 143.684 101.333 122 144
-199.647 122 144 230.514 122 144 32.4857 123 144
-43.9565 123 144 45 123 142.263 45.5 123 144
-53 122.478 144 53.5217 123 144 96 122.667 144
-95.6667 123 144 98 123 143.684 100 123 143.684
-101 123 143 102 122.8 144 102.083 123 144
-200 122.5 144 200.353 123 144 230.343 123 144
-32.4857 124 144 44 123.056 144 45 124 143.824
-44.9444 124 144 45.2 124 144 54 123.478 144
-54.7059 124 144 95 124 143.684 95 123.667 144
-94.6667 124 144 96 124 143.684 97 124 143.684
-101 124 141.346 102 124 141.24 103 123.393 144
-103 124 141.783 104 123.966 144 104.059 124 144
-200.273 124 144 230.176 124 144 32.4857 125 144
-45 125 144 46 124.4 144 46.5455 125 144
-55 124.217 144 56 124.955 144 56.0588 125 144
-95 125 143.684 94.6667 125 144 96 125 143.684
-97 125 143 102 125 141.24 104 125 141.75
-105 124.727 144 105.222 125 144 200 124.353 144
-199.607 125 144 230 125 144 32.3429 126 144
-44.5 126 144 46 126 142.286 47 125.417 144
-47.6364 126 144 57 125.941 144 57.0588 126 144
-92 125.833 144 91.6667 126 144 93 125.667 144
-94 125.364 144 102 126 141.75 103 126 141.346
-105 126 141.75 105.643 126 144 197.455 126 144
-198 125.824 144 199 125.5 144 230 126 144
-32.3235 127 144 44.0556 127 144 48 126.8 144
-48.2 127 144 58 126.696 144 58.3889 127 144
-89 127 143.684 89 126.882 144 88.6667 127 144
-90 126.833 144 91 126.667 144 105.821 127 144
-195 126.824 144 194.647 127 144 196 126.485 144
-197 126.152 144 230 127 144 32.3429 128 144
-45 127.773 144 45.8333 128 144 46.1667 128 144
-47 127.706 144 48 127.059 144 59 127.478 144
-59.7059 128 144 88 128 143.684 88 127.667 144
-87.6667 128 144 89 128 143.684 90 128 143
-106 128 144 193.571 128 144 194 127.478 144
-230 128 144 32.4857 129 144 46 128.034 144
-60 129 141.75 60 128.217 144 61 128.955 144
-61.0909 129 144 85 129 143.684 85 128.882 144
-84.6667 129 144 86 128.833 144 87 128.667 144
-89 129 142.364 106.147 129 144 192 129 141.13
-193.227 129 144 230.147 129 144 32.4857 130 144
-62 129.588 144 62.6364 130 144 84 129.667 144
-83.6667 130 144 85 130 143 106.571 130 144
-192 130 142.286 193 130 143.053 193.545 130 144
-220.706 130 144 221 129.815 144 222 129.625 144
-222.353 130 144 230.303 130 144 32.4857 131 144
-63 130.25 144 64 130.588 144 65 130.882 144
-65.3333 131 144 81 130.882 144 80.6667 131 144
-82 130.833 144 83 130.364 144 106.727 131 144
-192 131 143.833 193 131 143.833 194 130.833 144
-194 131 143.824 195 130.917 144 195 131 143.833
-195.091 131 144 197.417 131 144 198 130.759 144
-199 130.708 144 199.412 131 144 220 131 141.25
-219 131 144 220 130.522 144 222 130.545 144
-221.545 131 144 230.303 131 144 32.4857 132 144
-66 131.25 144 67 131.588 144 67.6364 132 144
-75 131.882 144 74.6667 132 144 76 131.882 144
-77 131.882 144 78 131.682 144 79 131.588 144
-80 131.25 144 107 131.375 144 107.357 132 144
-129.167 132 144 130 131.821 144 131 132 142
-130.294 132 144 187 132 144 188 131.739 144
-188.545 132 144 193 132 143.842 194.2 132 144
-195 131.2 144 196.667 132 144 197 131.5 144
-200 131.476 144 200.393 132 144 218 132 142.263
-217.607 132 144 218 131.607 144 219 132 141
-220 132 141.176 221 131.5 144 220.727 132 144
-230.303 132 144 32.6571 133 144 68 132.182 144
-69 132.357 144 70 132.455 144 71 132.455 144
-72 133 141.75 72 132.455 144 73 132.357 144
-74 132.182 144 107.739 133 144 127 133 144
-128 132.5 144 129 132.034 144 130.778 133 144
-186 132.706 144 185.815 133 144 188.739 133 144
-192.2 133 144 193 132.2 144 194 132.091 144
-197 132.455 144 197.214 133 144 201 133 142
-200.739 133 144 202 133 142.364 203 133 141.24
-217 133 142.2 216.586 133 144 217 132.586 144
-218 133 141.571 219 133 143.118 219.294 133 144
-220 132.571 144 230.485 133 144 32.8235 134 144
-108 133.261 144 108.586 134 144 126 133.667 144
-125.353 134 144 130.824 134 144 185.593 134 144
-188 134 142 188.414 134 144 192.059 134 144
-197.176 134 144 201 133.375 144 201.588 134 144
-202 134 142.5 216 134 143.786 215.964 134 144
-216 133.944 144 217 134 141.652 218 134 143
-218.261 134 144 219 133.227 144 230.818 134 144
-33 135 144 108.957 135 144 123 135 144
-124 134.657 144 125 134.176 144 130.657 135 144
-180 135 142 181 135 142.364 186 134.733 144
-186.8 135 144 187.083 135 144 188 134.522 144
-192 135 144 196.667 135 144 197 134.353 144
-201.455 135 144 216 135 141.667 215.588 135 144
-217 135 142.25 217.304 135 144 218 134.273 144
-230.824 135 144 33 136 144 109 135.083 144
-110 135.353 144 111 135.227 144 112 135.478 144
-112.364 136 144 115.294 136 144 116 135.571 144
-117 135.667 144 118 135.971 144 119 135.824 144
-120 135.966 144 121 135.793 144 122 135.586 144
-129.875 136 144 130 135.852 144 180 136 143.727
-181 136 143.8 182 136 143.842 187 135.034 144
-191.455 136 144 195.815 136 144 196 135.815 144
-200.773 136 144 201 135.667 144 216 135.412 144
-217 135.25 144 230.657 136 144 33 137 144
-53 137 141.429 54.0833 137 144 55 136.621 144
-56 136.514 144 57 136.233 144 58 136.393 144
-59 136.739 144 59.375 137 144 113 136.656 144
-114 136.815 144 115 136.227 144 129.185 137 144
-181 137 143.8 182 137 142.765 190 136.733 144
-189.75 137 144 191 136.5 144 194.545 137 144
-195 136.815 144 200 137 143.167 200.227 137 144
-212 137 143.1 213 137 143.211 213.833 137 144
-214 136.917 144 214.091 137 144 215 137 142.421
-216 137 141.176 230.514 137 144 33 138 144
-54.0588 138 144 59 138 141.652 60 137.909 144
-60.0909 138 144 128.821 138 144 129 137.5 144
-180.636 138 144 181 137.2 144 181.364 138 144
-189 138 143.571 190 138 143.571 190 137.8 144
-191 138 141.75 191 137.455 144 192 137.353 144
-193 137.273 144 194 137.214 144 199 137.545 144
-198.545 138 144 200 137.185 144 205.5 138 144
-206 137.824 144 207 137.233 144 208 137.261 144
-209 137.412 144 209.833 138 144 210 138 143.684
-211 138 143.684 211.286 138 144 212 137.545 144
-212.5 138 144 213 138 143.167 214 137.083 144
-214 138 141.938 230.343 138 144 33 139 144
-55 138.727 144 55.5455 139 144 58.5455 139 144
-59 138.783 144 60 138.059 144 129 138.5 144
-129.179 139 144 180.688 139 144 181.833 139 144
-185 138.783 144 184.545 139 144 186 138.621 144
-187 138.5 144 188 138.214 144 189 138.091 144
-190 139 142.286 189.455 139 144 198.059 139 144
-203.739 139 144 204 138.824 144 205 138.176 144
-209.588 139 144 211 139 142.364 212 138.217 144
-212 139 141.75 230.176 139 144 33.3529 140 144
-56 139.152 144 57 139.176 144 58 139.176 144
-73 140 143.813 72.8571 140 144 73 139.941 144
-73.0833 140 144 104 140 144 105 139.227 144
-106 139.571 144 107 139.786 144 108 139.5 144
-109 139.214 144 110 139.353 144 110.478 140 144
-129.647 140 144 161 140 141.24 168 140 142.385
-177 140 144 181 139.313 144 181 140 141.938
-184 139.353 144 183.353 140 144 189.552 140 144
-198.706 140 144 202.393 140 144 203 139.5 144
-209.25 140 144 230 140 144 33.6765 141 144
-73 140.167 144 103.676 141 144 107 141 141.12
-110.739 141 144 129.818 141 144 165 141 143
-173 140.515 144 172.407 141 144 174 140.353 144
-175 140.353 144 176 140.176 144 178 140.313 144
-178.667 141 144 183.217 141 144 190 140.722 144
-190.833 141 144 199 140.294 144 200 141 144
-201 141 144 202 140.333 144 209 140.667 144
-208.882 141 144 230 141 144 34 142 144
-104 141.688 144 104.227 142 144 107 142 142.8
-108 142 144 109.545 142 144 110 141.773 144
-130 142 144 160.818 142 144 161 141.75 144
-162 141.059 144 163 141.304 144 164 141.412 144
-165 141.412 144 166 141.2 144 167 141.091 144
-168 141.091 144 168.909 142 144 171.75 142 144
-172 141.647 144 179 141.5 144 179.393 142 144
-183.964 142 144 191 141.036 144 192 141.773 144
-192.417 142 144 208.455 142 144 230 142 144
-34 143 144 105 142.607 144 106 142.353 144
-107 142.182 144 109 142.176 144 129.571 143 144
-160.304 143 144 169 142.091 144 169.625 143 144
-171.059 143 144 180 142.607 144 180.333 143 144
-184 142.077 144 184.522 143 144 193 142.412 144
-193.625 143 144 195 143 141.3 198 143 144
-208.179 143 144 230 143 144 34 144 144
-128.941 144 144 129 143.941 144 159.818 144 144
-160 143.636 144 170 143.353 144 171 143.091 144
-181 143.815 144 181.179 144 144 184.607 144 144
-194 143.222 144 195 143.643 144 196 143.515 144
-197 143.152 144 199 143.75 144 199.182 144 144
-204 143.848 144 203.545 144 144 205 143.852 144
-205.364 144 144 208 143.455 144 207.5 144 144
-229.824 144 144 34 145 144 127.727 145 144
-128 144.727 144 159 145 143 159.636 145 144
-166 145 144 167 144.727 144 168 144.571 144
-169 144.778 144 170 144.688 144 171 144.625 144
-172 144.588 144 172.304 145 144 182 145 144
-183.75 145 144 184 144.81 144 199.696 145 144
-202 145 144 203 144.261 144 206 144.292 144
-207 144.261 144 229.485 145 144 34 146 144
-64 146 143.824 63.5 146 144 64 145.833 144
-64.1429 146 144 127.5 146 144 160 145.8 144
-160 146 143.727 160.059 146 144 167 146 144
-173 146 144 183 145.5 144 200 145.636 144
-200.8 146 144 201.056 146 144 229.176 146 144
-34.3529 147 144 64 146.2 144 126.375 147 144
-127 146.63 144 158.091 147 144 159 146.091 144
-160 146.091 144 167.222 147 144 173.571 147 144
-201 146.059 144 211 147 141.857 229 147 144
-34.6765 148 144 63.8571 148 144 64 147.8 144
-64.1667 148 144 110 148 144 111 147.824 144
-112 147.848 144 112.455 148 144 124 148 144
-125 147.207 144 126 147.176 144 157.304 148 144
-158 147.059 144 168 147.778 144 168.214 148 144
-174 147.706 144 174.217 148 144 212 147.833 144
-211.909 148 144 213 147.333 144 214 147.657 144
-215 148 144 229 148 144 35 149 144
-64 149 141.682 63 149 144 65 148.455 144
-65.2609 149 144 108.227 149 144 109 148.5 144
-113 148.353 144 113.393 149 144 123.676 149 144
-156.5 149 144 157 148.389 144 169 149 144
-175 149 143 174.588 149 144 211.955 149 144
-216 149 144 220 149 144 228.824 149 144
-35.1765 150 144 59.1667 150 144 60 149.821 144
-61 149.667 144 62 149.5 144 65.7222 150 144
-108 150 141.652 107.357 150 144 108 149.217 144
-113 150 144 123.214 150 144 155.607 150 144
-156 149.5 144 163 150 144 164 149.414 144
-165 149.955 144 165.056 150 144 170 149.848 144
-170.185 150 144 175 150 143.625 174.667 150 144
-177 150 143.684 178 150 141.429 212 149.059 144
-212.941 150 144 215 150 144 228.485 150 144
-35.3429 151 144 58 151 141.6 59.0455 151 144
-66 150.833 144 66.0909 151 144 106.955 151 144
-107 150.909 144 112 150.667 144 111.353 151 144
-122.185 151 144 123 150.214 144 155 151 144
-162.214 151 144 165.214 151 144 171 151 144
-173.714 151 144 174 150.667 144 177 151 141.429
-213 150.036 144 214 150.364 144 228.176 151 144
-35.6571 152 144 60 152 144 62 152 141.682
-66 152 143.842 67 151.909 144 67 152 143.833
-67.2 152 144 94.2174 152 144 95 151.182 144
-96 151.217 144 97 151.696 144 98 151.941 144
-98 152 143.842 99 151.941 144 99 152 143.842
-99.2 152 144 107 151.091 144 108 151.706 144
-109 151.773 144 110 151.586 144 111 151.176 144
-121.571 152 144 122 151.294 144 154.657 152 144
-162.786 152 144 165 152 144 172 151.294 144
-173 151.294 144 187 152 143.769 186.909 152 144
-187 151.833 144 187.083 152 144 227.824 152 144
-228 151.5 144 36 153 144 61 152.343 144
-62 152.486 144 63 152.486 144 64 152.414 144
-65 152.304 144 66 152.059 144 67 152.2 144
-68 153 143.667 67.6667 153 144 68 152.667 144
-68.1667 153 144 73 153 143.769 72.9655 153 144
-73 152.857 144 74 152.417 144 74 153 142.6
-74.3043 153 144 93.1852 153 144 94 152.185 144
-99 153 143.842 99.2 153 144 121.179 153 144
-154.343 153 144 163 152.261 144 164 152.773 144
-168.625 153 144 169 152.778 144 170 152.571 144
-170 153 142.286 170.706 153 144 187 152.056 144
-227.485 153 144 36.3429 154 144 68 153.167 144
-73 154 143.833 72.9412 154 144 74 154 143.824
-74.0435 154 144 92 154 144 93 153.185 144
-99.4118 154 144 121.485 154 144 154.176 154 144
-164 154 143.824 163.944 154 144 164 153.833 144
-165 153.588 144 165 154 142.95 166 153.964 144
-167 153.786 144 168 153.357 144 171 153.417 144
-171.368 154 144 227.176 154 144 36.6571 155 144
-68.4545 155 144 69 154.625 144 70 154.778 144
-71 155 144 72 155 143.833 72 154.941 144
-72.2 155 144 73 154.2 144 74 154.059 144
-89.2 155 144 90 154.879 144 91 154.667 144
-99.25 155 144 121.029 155 144 154 154.5 144
-153.824 155 144 164 154.2 144 164.8 155 144
-166 155 141.429 171.586 155 144 203 155 141.571
-202 155 144 203 154.5 144 204 154.586 144
-204.923 155 144 226.647 155 144 227 154.333 144
-37 156 144 67.4783 156 144 68 155.294 144
-72.5652 156 144 87.5217 156 144 88 155.522 144
-89 155.043 144 99 156 144 120.824 156 144
-121 155.143 144 153.515 156 144 165 156 144
-171.486 156 144 185.955 156 144 186 155.938 144
-187 155.478 144 188 155.393 144 189 155 144
-190 155 144 191 155.393 144 191.773 156 144
-198.759 156 144 199 155.696 144 200 155.179 144
-201 155.176 144 205 155.091 144 206 156 143.625
-205.833 156 144 226.324 156 144 37.5152 157 144
-66.8214 157 144 67 156.688 144 72.1765 157 144
-86 157 144 87 156.522 144 98.3529 157 144
-120.514 157 144 153 157 144 165.485 157 144
-171.486 157 144 186 157 142.364 185.571 157 144
-192 156.185 144 193 156.545 144 193.833 157 144
-195 157 144 197.667 157 144 198 156.786 144
-205 156.909 144 204.917 157 144 225.824 157 144
-226 156.647 144 37.8235 158 144 67 157.294 144
-68 158 144 71.2143 158 144 72 157.214 144
-83.9412 158 144 84 157.957 144 85 157.727 144
-98 157.522 144 97.6071 158 144 120.176 158 144
-152.515 158 144 165.5 158 144 171.657 158 144
-174.5 158 144 175 157.333 144 176 157.414 144
-177 157.786 144 177.6 158 144 185.818 158 144
-194 157.091 144 196 157.353 144 197 157.414 144
-203.455 158 144 204 157.647 144 225.485 158 144
-38 158.5 144 38.1765 159 144 69 158.5 144
-70 158.657 144 71 158.207 144 83 159 144
-97.1818 159 144 101.917 159 144 102 158.955 144
-102.091 159 144 119.824 159 144 120 158.5 144
-152.176 159 144 165.853 159 144 171.5 159 144
-174.5 159 144 178 158.235 144 178.722 159 144
-186 158.273 144 186.696 159 144 200.091 159 144
-201 158.697 144 202 158.364 144 203 158.185 144
-225 159 144 38.5152 160 144 82 160 143
-82.6364 160 144 97 159.8 144 96.9412 160 144
-100.294 160 144 101 159.478 144 103 159.476 144
-103.478 160 144 119.514 160 144 152 159.353 144
-151.676 160 144 166 159.556 144 166.19 160 144
-171.393 160 144 174.966 160 144 179 159.238 144
-179.727 160 144 187 159.241 144 188 159.829 144
-188.5 160 144 195 159.588 144 194.364 160 144
-196 159.786 144 197 159.676 144 198 159.657 144
-199 159.353 144 200 159.034 144 217.647 160 144
-218 159.739 144 219 159 144 220 159.588 144
-220.304 160 144 224.485 160 144 39 161 144
-79 161 141.75 80 161 143 81 161 143.684
-83 160.667 144 83 161 143.684 84 160.667 144
-84.3333 161 144 90 161 144 91 160.824 144
-91.375 161 144 96.9545 161 144 99.5882 161 144
-100 160.417 144 101 161 141.12 104 161 144
-119.514 161 144 151.353 161 144 167 160.944 144
-167.059 161 144 171 160.917 144 170.941 161 144
-175 160.059 144 175.571 161 144 180 160.353 144
-180.917 161 144 181.2 161 144 182 160.81 144
-182.444 161 144 189 160.207 144 190 160.176 144
-191 160.607 144 192 161 144 195 161 142
-194.25 161 144 217 161 143.824 216.909 161 144
-217 160.917 144 218 161 142.714 219 161 141.25
-220 161 144 224 161 144 39.5152 162 144
-79 162 143 80 162 143 81 162 142.364
-85 161.25 144 86 161.941 144 86.0909 162 144
-89 161.586 144 88.2941 162 144 92 161.455 144
-92.3529 162 144 96.7778 162 144 100 161.304 144
-101 161.828 144 102 162 144 103 162 144
-119.514 162 144 151 161.522 144 150.676 162 144
-168 161.727 144 168.6 162 144 171 162 143.684
-170.667 162 144 176 162 144 181 161.045 144
-183 161.313 144 183.917 162 144 193 162 144
-194 162 143.75 194 161.8 144 216 162 143
-215.588 162 144 216 161.588 144 217 162 143.053
-218 162 144 219 161.478 144 223.485 162 144
-39.8235 163 144 78 163 141.6 79 163 142.765
-87 162.588 144 88 162.179 144 92.0345 163 144
-96.9643 163 144 119.514 163 144 150.353 163 144
-168.375 163 144 171 162.286 144 171.217 163 144
-176.485 163 144 184 162.059 144 184.727 163 144
-216 162.412 144 217 162.273 144 223 163 144
-40 163.5 144 40.1765 164 144 77.1667 164 144
-78 163.706 144 78.4545 164 144 91.1852 164 144
-92 163.043 144 97 163.045 144 97.6364 164 144
-119.514 164 144 150 163.667 144 149.824 164 144
-168.043 164 144 171.414 164 144 176.966 164 144
-185 163.5 144 185.375 164 144 222.393 164 144
-40.5152 165 144 64.6471 165 144 65 164.818 144
-66 164.75 144 67 164.909 144 67 165 143.833
-67.0588 165 144 76 165 144 77 164.043 144
-78.3929 165 144 90 165 144 91 164.185 144
-98 164.522 144 98.4783 165 144 119.514 165 144
-149.793 165 144 160 165 143.824 159.917 165 144
-160 164.917 144 161 164.941 144 161 165 143.833
-161.091 165 144 167.515 165 144 168 164.059 144
-171.4 165 144 177 164.059 144 177.727 165 144
-181 164.966 144 180.917 165 144 182 164.966 144
-182.083 165 144 185.478 165 144 199 165 143.842
-198.8 165 144 199 164.8 144 199.091 165 144
-210.966 165 144 211 164.941 144 212 164.909 144
-212 165 143.4 212.077 165 144 221.5 165 144
-222 164.5 144 41 166 144 63.4138 166 144
-64 165.393 144 65 166 141 66.5455 166 144
-67 165.091 144 75.5 166 144 78.1515 166 144
-89.1923 166 144 99 166 141.857 98.7059 166 144
-119.514 166 144 149.739 166 144 160 165.059 144
-161 165.091 144 166.522 166 144 167 165.607 144
-171 165.706 144 170.848 166 144 178 165.214 144
-179 165.176 144 180 165.324 144 183 165.333 144
-183.957 166 144 184.167 166 144 185 165.688 144
-199 166 143.833 198.941 166 144 200 165.588 144
-200 166 142.95 201 166 144 211 166 141.5
-210.773 166 144 212 166 144 221.179 166 144
-41.5152 167 144 63.0556 167 144 65 167 142.263
-65.6875 167 144 66 166.706 144 75.0345 167 144
-78 166.227 144 77.5 167 144 88 167 144
-89 166.227 144 96 166.667 144 95.5 167 144
-97 166.586 144 98 167 143.571 98 166.923 144
-99 167 142.615 119.514 167 144 149.739 167 144
-165.593 167 144 166 166.522 144 170.152 167 144
-184 166.056 144 199 166.167 144 199.217 167 144
-202 166.343 144 203 166.676 144 203.647 167 144
-211 166.455 144 220.824 167 144 221 166.455 144
-42 168 144 63 168 142 64 167.739 144
-65 167.324 144 74.5 168 144 75 167.056 144
-77 167.944 144 76.9655 168 144 87.2143 168 144
-91 168 143.571 91 167.957 144 90.9412 168 144
-92 167.818 144 93 167.966 144 93.1667 168 144
-94.2941 168 144 95 167.478 144 119.353 168 144
-149.786 168 144 165.034 168 144 170 167.455 144
-169.824 168 144 199.5 168 144 204 167.261 144
-205 167.621 144 206 167.739 144 207 167.455 144
-207 168 142.8 207.353 168 144 220.485 168 144
-42.6667 169 144 73.8485 169 144 74 168.773 144
-76.6471 169 144 86.7391 169 144 87 168.5 144
-90 168.727 144 89.7273 169 144 94 168.185 144
-119.029 169 144 149.971 169 144 164.545 169 144
-165 168.091 144 170 169 144 200 168.944 144
-200.029 169 144 204 169 141.125 206.944 169 144
-207 168.857 144 220 169 144 43 169.647 144
-43.1765 170 144 74 170 142.263 73.6071 170 144
-76.2333 170 144 85.8519 170 144 86 169.81 144
-89 169.941 144 88.9412 170 144 118.5 170 144
-119 169.056 144 150 169.083 144 150.324 170 144
-165 170 141.5 164.583 170 144 170.773 170 144
-200.414 170 144 205 170 141.682 206.333 170 144
-219.333 170 144 43.8235 171 144 74 171 143.118
-73.7059 171 144 75 171 143.167 75.2381 171 144
-76 170.304 144 85 171 142.105 85.75 171 144
-87 171 144 88 170.727 144 118.176 171 144
-150.647 171 144 165 170.417 144 166 170.478 144
-167 171 144 170 171 141.167 171 170.455 144
-171 171 143 171.273 171 144 201 171 144
-203 170.688 144 202.688 171 144 204 170.304 144
-205 170.515 144 206 170.353 144 218.647 171 144
-219 170.478 144 44 171.261 144 44.5 172 144
-74 171.294 144 75 171.185 144 84 172 141.875
-85 172 141.75 86 171.25 144 86 172 142.364
-117.853 172 144 118 171.545 144 150.824 172 144
-168 171.607 144 168.478 172 144 171 172 144
-202 171.647 144 218 172 144 45 172.586 144
-45.3529 173 144 117.5 173 144 151 172.353 144
-151.324 173 144 169 173 143.833 168.917 173 144
-169.167 173 144 170 172.545 144 217.333 173 144
-46 174 144 117.029 174 144 151.647 174 144
-168.294 174 144 170 173.833 144 170.056 174 144
-173 174 141.9 216.5 174 144 217 173.393 144
-46.6667 175 144 116.5 175 144 117 174.056 144
-152 174.522 144 152.324 175 144 168.261 175 144
-170.739 175 144 174 175 142.5 203.5 175 144
-204 174.955 144 205 174.815 144 205.179 175 144
-215.5 175 144 216 174.5 144 47 175.393 144
-47.5 176 144 115.848 176 144 116 175.773 144
-152.647 176 144 168.529 176 144 171 175.5 144
-171.261 176 144 202.81 176 144 203 175.2 144
-205.957 176 144 214.393 176 144 215 175.5 144
-48 176.5 144 48.5 177 144 115.176 177 144
-153 176.522 144 153.324 177 144 169 176.593 144
-169.393 177 144 171.333 177 144 202.643 177 144
-206 176.045 144 206.778 177 144 213.393 177 144
-214 176.393 144 49 177.5 144 49.5 178 144
-114.5 178 144 115 177.261 144 154 178 144
-170 177.944 144 171 178 144 203 177.909 144
-203.043 178 144 207 177.261 144 207.607 178 144
-212.667 178 144 213 177.5 144 50 178.5 144
-50.5 179 144 113.848 179 144 114 178.773 144
-155 179 144 183 179 143.824 182.941 179 144
-183 178.955 144 183.167 179 144 203.414 179 144
-208 178.647 144 208.176 179 144 211.697 179 144
-212 178.688 144 51 179.5 144 51.5 180 144
-113 180 144 156 180 144 182.964 180 144
-184 179.278 144 184 180 142.143 185 179.824 144
-185.214 180 144 203.515 180 144 209 179.824 144
-210 180 144 211 179.676 144 52 180.5 144
-52.6071 181 144 112 181 144 157 181 144
-183 181 142.5 182.783 181 144 184 181 141.571
-185 181 141.125 186 180.957 144 186.056 181 144
-202.706 181 144 203 180.773 144 53 181.333 144
-53.8148 182 144 111 182 144 158 181.848 144
-158.227 182 144 165 182 143.824 164.957 182 144
-165 181 144 166 181.333 144 166 182 142.2
-166.706 182 144 172 182 144 173 181.545 144
-173.455 182 144 183 181.455 144 184 182 141.938
-183.353 182 144 187 181.63 144 187.37 182 144
-198.353 182 144 199 181.476 144 200 181.179 144
-201 181.343 144 202 181.343 144 54 182.152 144
-55 182.848 144 55.2273 183 144 110 183 144
-159 182.5 144 159.773 183 144 165 182.043 144
-166 183 142.8 165.786 183 144 167 182.833 144
-167 183 143.667 167.077 183 144 171.739 183 144
-174 182.429 144 175 182.643 144 176 182.286 144
-177 182.214 144 178 182.393 144 179 183 144
-183.462 183 144 188 182.773 144 188.417 183 144
-198.515 183 144 56 183.5 144 57 184 144
-70.5882 184 144 71 183.72 144 72 183.966 144
-72.0588 184 144 87.9583 184 144 88 183.957 144
-89 183.5 144 89.7727 184 144 109 184 144
-160 183.152 144 161 184 144 166 183.5 144
-167 184 141.429 166.5 184 144 168 183.545 144
-168.625 184 144 171.167 184 144 180 183.478 144
-181 184 144 182.545 184 144 183 183.545 144
-189 183.318 144 190 183.706 144 190.217 184 144
-198.182 184 144 58 184.676 144 58.6471 185 144
-70.4138 185 144 73 184.593 144 73.5238 185 144
-87.4138 185 144 90 184.227 144 90.6071 185 144
-108 185 144 162 185 144 166.6 185 144
-169 184.182 144 170 184.176 144 171 184.042 144
-182 184.171 144 190.786 185 144 198.179 185 144
-59 185.176 144 60 185.824 144 60.5 186 144
-71 185.5 144 71.7727 186 144 74 185.455 144
-75 185.957 144 75.0909 186 144 83.3529 186 144
-84 185.676 144 85 185.667 144 86 186 144
-87 185.706 144 90.4286 186 144 107 186 144
-163 186 144 166.414 186 144 178 185.964 144
-177.857 186 144 178.2 186 144 191 185.214 144
-191.786 186 144 196.688 186 144 197 185.815 144
-198 185.192 144 61 186.176 144 62 186.824 144
-62.2609 187 144 72 186.179 144 73 186.667 144
-73.2727 187 144 76 186.303 144 77 186.75 144
-78 186.964 144 79 186.966 144 80 186.647 144
-81 186.514 144 82 186.343 144 83 186.176 144
-90 186.5 144 89.6471 187 144 105.706 187 144
-106 186.848 144 164 186.821 144 164.227 187 144
-166.077 187 144 176 186.767 144 175.611 187 144
-177 186.207 144 178.706 187 144 192 186.214 144
-192.815 187 144 195.522 187 144 196 186.5 144
-63 187.5 144 63.7391 188 144 74 188 144
-89.1471 188 144 103.478 188 144 104 187.586 144
-105 187.343 144 165 187.515 144 166 187.045 144
-169 187.217 144 168.217 188 144 170 187.217 144
-171 187.909 144 171.063 188 144 174.179 188 144
-175 187.324 144 178.5 188 144 193 187.152 144
-194 187.676 144 195 187.522 144 64 188.176 144
-65 188.657 144 66 189 144 74.625 189 144
-85 188.727 144 84.7931 189 144 86 188.407 144
-86.7273 189 144 89 188.5 144 88.7059 189 144
-102.5 189 144 103 188.393 144 168.455 189 144
-170 189 141.429 171.083 189 144 173 189 144
-174 188.227 144 178.485 189 144 67 189.5 144
-68 190 144 75 189.353 144 75 190 141.938
-76 190 143.571 76 189.941 144 76.0357 190 144
-84.9706 190 144 87 189.214 144 88 189.414 144
-101.393 190 144 102 189.5 144 169 189.353 144
-170 189.522 144 171 189.091 144 173 190 144
-179 190 141.167 178.5 190 144 182 190 143
-69 190.343 144 70 190.657 144 71 191 144
-72 191 144 73 190.778 144 74 190.714 144
-75 190.688 144 76 190.083 144 85 190.056 144
-85.6071 191 144 100 191 144 101 190.333 144
-174 191 144 178 191 144 86 191.478 144
-86.3529 192 144 98 192 144 99 191.5 144
-175 191.514 144 176 191.514 144 177 191.514 144
-87 192.815 144 87.1852 193 144 95 193 144
-96 192.657 144 97 192.343 144 88 193.786 144
-89 193.824 144 90 193.647 144 91 193.514 144
-92 193.514 144 93 193.514 144 94 193.343 144
-
-POLYGONS 13733 54932
-3 0 13 17
-3 14 0 17
-3 3 2 4
-3 5 3 4
-3 7 3 6
-3 6 3 5
-3 2 13 4
-3 5 4 13
-3 6 5 13
-3 9 10 11
-3 0 7 13
-3 7 6 13
-3 14 7 0
-3 14 8 7
-3 19 8 14
-3 10 9 20
-3 20 9 126
-3 11 10 15
-3 15 10 20
-3 12 11 16
-3 16 11 15
-3 16 121 12
-3 17 18 14
-3 19 14 22
-3 21 8 19
-3 28 17 13
-3 17 28 18
-3 14 18 22
-3 22 18 28
-3 132 20 126
-3 15 20 132
-3 21 19 29
-3 29 19 22
-3 23 21 29
-3 21 23 24
-3 24 127 21
-3 125 25 26
-3 27 125 26
-3 24 23 29
-3 127 24 30
-3 34 31 25
-3 26 25 32
-3 32 25 31
-3 27 26 32
-3 30 24 38
-3 127 30 33
-3 31 34 36
-3 36 34 35
-3 37 31 36
-3 37 32 31
-3 27 32 37
-3 38 33 30
-3 39 33 38
-3 35 34 39
-3 35 137 36
-3 37 36 137
-3 40 140 42
-3 42 41 40
-3 40 41 43
-3 43 41 42
-3 43 42 47
-3 47 42 46
-3 48 44 45
-3 49 48 45
-3 50 44 48
-3 51 46 58
-3 47 46 51
-3 51 2917 47
-3 50 48 52
-3 52 155 50
-3 48 53 52
-3 54 155 52
-3 53 54 52
-3 46 160 58
-3 160 57 58
-3 51 58 59
-3 65 51 59
-3 60 55 56
-3 61 160 71
-3 160 61 57
-3 57 61 62
-3 58 57 66
-3 66 57 62
-3 63 58 66
-3 64 58 63
-3 59 58 65
-3 65 58 64
-3 56 69 60
-3 70 60 69
-3 62 61 72
-3 66 62 72
-3 63 66 67
-3 64 63 68
-3 68 63 67
-3 65 64 75
-3 75 64 68
-3 75 2917 65
-3 76 60 70
-3 72 61 71
-3 66 72 73
-3 67 66 74
-3 74 66 73
-3 68 67 75
-3 75 67 74
-3 69 165 70
-3 76 70 165
-3 72 71 81
-3 73 72 77
-3 77 72 81
-3 77 74 73
-3 75 74 77
-3 164 78 79
-3 164 76 165
-3 164 79 86
-3 80 71 168
-3 81 71 80
-3 82 80 168
-3 89 82 168
-3 83 80 82
-3 84 80 83
-3 81 80 85
-3 85 80 84
-3 78 86 79
-3 88 86 87
-3 92 89 168
-3 84 83 171
-3 171 83 82
-3 171 85 84
-3 88 87 90
-3 90 87 86
-3 174 91 92
-3 89 92 96
-3 93 94 174
-3 101 93 174
-3 94 95 174
-3 174 95 91
-3 92 91 96
-3 96 91 95
-3 89 96 177
-3 101 97 93
-3 93 97 98
-3 94 93 99
-3 99 93 98
-3 180 95 94
-3 96 95 180
-3 103 173 175
-3 3 173 103
-3 3 7 173
-3 173 7 264
-3 101 100 1
-3 97 101 1
-3 102 97 1
-3 102 98 97
-3 99 98 111
-3 111 98 102
-3 111 94 99
-3 122 103 175
-3 3 103 2
-3 104 100 101
-3 107 104 101
-3 1 100 105
-3 105 100 104
-3 122 2 103
-3 112 264 7
-3 179 185 115
-3 11 179 115
-3 11 106 179
-3 179 106 107
-3 104 107 108
-3 105 104 109
-3 109 104 108
-3 105 110 1
-3 105 109 110
-3 1 110 102
-3 111 102 110
-3 122 13 2
-3 8 112 7
-3 115 185 114
-3 11 115 9
-3 106 11 12
-3 121 106 12
-3 121 107 106
-3 108 107 116
-3 116 107 121
-3 109 108 111
-3 111 108 116
-3 110 109 111
-3 112 8 21
-3 117 112 127
-3 113 123 118
-3 184 113 118
-3 125 184 118
-3 119 184 125
-3 114 119 120
-3 115 114 120
-3 9 115 126
-3 111 116 136
-3 136 116 121
-3 127 112 21
-3 117 127 128
-3 128 193 117
-3 194 123 113
-3 131 118 123
-3 125 118 124
-3 124 118 131
-3 126 119 125
-3 120 119 126
-3 115 120 126
-3 15 121 16
-3 28 13 122
-3 129 193 128
-3 129 130 194
-3 194 130 123
-3 123 130 134
-3 131 123 134
-3 25 124 131
-3 125 124 25
-3 126 125 27
-3 132 136 15
-3 121 15 136
-3 28 122 133
-3 128 127 33
-3 129 128 130
-3 34 131 134
-3 25 131 34
-3 135 126 27
-3 132 126 135
-3 136 132 135
-3 29 133 218
-3 29 22 133
-3 22 28 133
-3 130 128 33
-3 134 130 33
-3 27 219 135
-3 136 135 219
-3 29 38 24
-3 134 33 39
-3 34 134 39
-3 38 29 218
-3 27 37 219
-3 219 37 137
-3 218 39 38
-3 137 35 39
-3 140 234 138
-3 139 236 237
-3 140 138 42
-3 141 139 237
-3 142 139 141
-3 40 43 140
-3 43 234 140
-3 143 144 141
-3 141 144 142
-3 144 147 142
-3 148 42 138
-3 2917 234 43
-3 145 144 143
-3 147 144 145
-3 146 145 143
-3 147 145 146
-3 42 148 46
-3 47 2917 43
-3 154 149 146
-3 147 146 150
-3 150 146 149
-3 151 147 150
-3 154 152 149
-3 149 152 150
-3 44 152 45
-3 44 151 152
-3 151 150 152
-3 44 155 151
-3 46 148 760
-3 153 152 154
-3 45 153 49
-3 152 153 45
-3 44 50 155
-3 154 49 153
-3 154 157 49
-3 157 48 49
-3 48 157 53
-3 155 54 156
-3 244 155 55
-3 55 155 156
-3 46 760 160
-3 51 65 2917
-3 53 156 54
-3 53 157 156
-3 157 158 156
-3 55 158 56
-3 55 156 158
-3 55 60 245
-3 55 245 244
-3 245 60 159
-3 157 163 161
-3 157 161 158
-3 158 161 56
-3 60 162 159
-3 160 760 71
-3 56 161 163
-3 69 56 163
-3 76 162 60
-3 69 163 165
-3 76 164 162
-3 256 168 760
-3 71 760 168
-3 78 164 165
-3 86 252 164
-3 86 88 252
-3 81 75 77
-3 165 359 78
-3 252 88 166
-3 252 166 257
-3 256 167 168
-3 78 359 86
-3 257 166 169
-3 167 261 92
-3 168 167 92
-3 85 171 81
-3 171 75 81
-3 166 90 170
-3 88 90 166
-3 169 166 173
-3 173 166 170
-3 264 169 173
-3 261 259 174
-3 92 261 174
-3 86 359 172
-3 86 172 90
-3 90 172 170
-3 172 173 170
-3 89 177 82
-3 171 82 177
-3 2917 171 177
-3 173 172 175
-3 175 172 359
-3 178 264 112
-3 179 107 176
-3 176 101 174
-3 101 176 107
-3 94 111 180
-3 359 122 175
-3 183 178 182
-3 184 276 183
-3 111 181 180
-3 187 180 181
-3 180 187 96
-3 182 178 112
-3 179 184 185
-3 186 181 111
-3 187 181 186
-3 177 96 187
-3 182 112 117
-3 183 182 188
-3 189 183 188
-3 113 183 189
-3 184 183 113
-3 185 184 190
-3 185 190 114
-3 117 193 182
-3 188 182 191
-3 191 182 193
-3 189 188 194
-3 194 188 191
-3 113 189 194
-3 119 190 184
-3 114 190 119
-3 136 192 111
-3 186 111 192
-3 187 186 192
-3 194 191 193
-3 194 193 129
-3 133 122 218
-3 136 219 220
-3 196 195 197
-3 197 195 295
-3 198 196 197
-3 198 199 196
-3 201 202 200
-3 202 203 205
-3 200 202 205
-3 203 204 205
-3 205 204 206
-3 206 207 291
-3 295 208 197
-3 198 197 208
-3 199 198 209
-3 209 198 208
-3 210 199 209
-3 200 199 211
-3 211 199 210
-3 201 200 211
-3 212 201 211
-3 202 201 213
-3 213 201 212
-3 203 202 213
-3 204 203 214
-3 214 203 213
-3 215 204 214
-3 206 204 215
-3 215 216 206
-3 207 206 216
-3 211 210 217
-3 217 210 209
-3 212 211 217
-3 217 213 212
-3 214 213 217
-3 215 214 217
-3 220 137 39
-3 219 137 220
-3 221 222 223
-3 221 227 224
-3 222 221 225
-3 225 221 224
-3 225 315 222
-3 224 227 228
-3 315 225 228
-3 228 225 224
-3 226 540 230
-3 227 226 231
-3 231 226 230
-3 228 227 232
-3 232 227 231
-3 232 315 228
-3 230 540 138
-3 234 230 138
-3 234 231 230
-3 232 231 315
-3 315 231 234
-3 235 233 229
-3 238 235 229
-3 236 233 235
-3 761 233 236
-3 237 235 238
-3 236 235 237
-3 237 238 141
-3 139 142 236
-3 142 761 236
-3 143 141 238
-3 239 142 147
-3 239 419 142
-3 238 320 143
-3 320 146 143
-3 146 320 154
-3 147 151 239
-3 148 138 760
-3 155 239 151
-3 241 239 155
-3 320 762 154
-3 762 157 154
-3 155 244 241
-3 325 240 243
-3 243 240 242
-3 247 242 240
-3 243 242 248
-3 248 242 247
-3 248 325 243
-3 159 246 245
-3 159 249 246
-3 247 250 248
-3 762 163 157
-3 159 162 249
-3 251 162 164
-3 251 164 253
-3 252 253 164
-3 253 252 336
-3 165 163 262
-3 333 252 254
-3 254 252 257
-3 255 333 254
-3 165 262 359
-3 255 254 258
-3 258 254 257
-3 259 451 260
-3 256 451 261
-3 261 451 259
-3 167 256 261
-3 258 257 263
-3 263 257 169
-3 264 258 263
-3 255 258 264
-3 267 259 260
-3 75 171 2917
-3 263 169 264
-3 264 346 255
-3 351 346 265
-3 265 346 264
-3 259 267 174
-3 269 265 264
-3 178 363 270
-3 363 178 275
-3 271 266 354
-3 271 354 272
-3 272 273 274
-3 271 272 274
-3 268 274 273
-3 267 268 273
-3 267 273 174
-3 264 178 269
-3 269 178 360
-3 275 178 276
-3 184 365 276
-3 179 805 184
-3 354 179 176
-3 272 354 176
-3 174 272 176
-3 273 272 174
-3 178 277 360
-3 270 277 178
-3 276 178 183
-3 122 359 278
-3 187 192 177
-3 279 280 385
-3 385 280 281
-3 391 282 279
-3 279 282 280
-3 281 280 282
-3 283 281 282
-3 281 283 284
-3 122 382 218
-3 1226 192 136
-3 285 286 395
-3 401 287 286
-3 288 286 287
-3 395 286 289
-3 289 286 288
-3 289 290 395
-3 393 395 290
-3 196 290 195
-3 393 290 196
-3 196 199 393
-3 199 200 393
-3 393 200 205
-3 205 291 292
-3 287 401 293
-3 287 293 288
-3 289 288 294
-3 294 288 293
-3 290 289 295
-3 295 289 294
-3 290 295 195
-3 291 205 206
-3 207 296 291
-3 292 291 296
-3 293 297 298
-3 294 293 298
-3 295 294 298
-3 295 298 208
-3 216 215 299
-3 216 299 207
-3 207 299 296
-3 299 409 296
-3 215 409 299
-3 209 409 217
-3 208 409 209
-3 409 215 217
-3 300 301 410
-3 301 304 410
-3 300 302 303
-3 301 300 304
-3 304 300 303
-3 303 302 306
-3 306 302 305
-3 304 303 307
-3 307 303 306
-3 307 308 304
-3 223 302 221
-3 305 302 223
-3 222 305 223
-3 222 309 305
-3 309 306 305
-3 307 306 308
-3 308 306 309
-3 221 302 227
-3 222 315 309
-3 315 308 309
-3 233 415 229
-3 415 414 229
-3 302 226 227
-3 302 540 226
-3 312 310 311
-3 423 312 311
-3 312 314 310
-3 313 312 423
-3 314 312 313
-3 316 313 423
-3 314 313 317
-3 317 313 316
-3 317 914 314
-3 317 316 318
-3 914 317 318
-3 142 419 761
-3 540 760 138
-3 319 316 423
-3 318 316 319
-3 914 318 319
-3 2917 315 234
-3 229 320 238
-3 241 322 321
-3 239 241 321
-3 319 240 325
-3 324 322 241
-3 323 322 324
-3 319 423 240
-3 241 244 324
-3 245 425 244
-3 246 425 245
-3 240 423 247
-3 325 248 250
-3 330 325 250
-3 427 426 249
-3 249 426 246
-3 247 423 250
-3 249 430 327
-3 249 162 430
-3 427 249 327
-3 250 423 329
-3 330 250 329
-3 442 163 762
-3 251 331 162
-3 331 430 162
-3 337 332 328
-3 333 328 332
-3 330 329 334
-3 326 330 434
-3 434 330 334
-3 335 331 251
-3 336 332 337
-3 252 333 336
-3 333 332 336
-3 423 338 329
-3 329 338 334
-3 339 434 338
-3 338 434 334
-3 335 342 443
-3 335 251 342
-3 251 253 342
-3 337 253 336
-3 760 451 256
-3 341 339 338
-3 340 341 338
-3 440 344 441
-3 163 442 262
-3 343 443 342
-3 255 346 333
-3 573 441 344
-3 262 442 349
-3 342 345 343
-3 451 347 260
-3 344 440 348
-3 348 440 356
-3 573 344 357
-3 357 344 348
-3 262 349 454
-3 454 350 262
-3 352 346 351
-3 347 805 179
-3 354 347 179
-3 355 347 354
-3 260 347 355
-3 348 356 357
-3 358 573 357
-3 262 350 359
-3 360 351 265
-3 352 351 360
-3 361 363 362
-3 363 364 362
-3 362 364 365
-3 365 184 805
-3 266 366 354
-3 366 355 354
-3 367 355 366
-3 267 367 268
-3 267 260 367
-3 260 355 367
-3 358 357 368
-3 368 369 358
-3 265 269 360
-3 363 361 270
-3 270 361 370
-3 364 363 371
-3 371 363 275
-3 276 364 371
-3 365 364 276
-3 271 643 266
-3 366 266 832
-3 832 266 643
-3 367 366 474
-3 366 832 474
-3 372 271 274
-3 474 268 367
-3 274 268 372
-3 372 268 474
-3 356 373 357
-3 368 357 374
-3 374 357 373
-3 375 369 368
-3 375 368 374
-3 377 270 370
-3 276 371 275
-3 372 643 271
-3 375 374 378
-3 378 374 373
-3 278 359 376
-3 380 360 277
-3 277 270 377
-3 277 377 380
-3 379 122 278
-3 494 122 379
-3 122 494 382
-3 177 192 1226
-3 518 386 383
-3 507 383 386
-3 385 384 516
-3 387 384 385
-3 507 386 388
-3 388 389 507
-3 389 391 516
-3 385 391 279
-3 385 516 391
-3 281 387 385
-3 386 518 388
-3 389 388 390
-3 389 390 391
-3 387 281 284
-3 284 392 387
-3 285 387 392
-3 393 387 285
-3 285 395 393
-3 391 283 282
-3 391 390 283
-3 283 392 284
-3 283 394 392
-3 285 392 286
-3 392 394 286
-3 283 390 396
-3 396 397 283
-3 398 399 394
-3 398 394 397
-3 397 394 283
-3 399 400 401
-3 399 401 394
-3 394 401 286
-3 292 393 205
-3 382 707 218
-3 402 396 390
-3 403 396 402
-3 403 404 405
-3 403 405 396
-3 396 405 397
-3 400 398 397
-3 400 397 406
-3 406 397 405
-3 400 406 401
-3 292 296 407
-3 405 408 406
-3 401 406 408
-3 297 293 408
-3 293 401 408
-3 296 409 407
-3 297 408 298
-3 532 408 405
-3 298 408 532
-3 39 218 1226
-3 39 1226 220
-3 304 411 410
-3 413 412 414
-3 761 413 414
-3 761 414 415
-3 418 416 539
-3 423 418 539
-3 417 416 418
-3 417 914 416
-3 414 412 229
-3 310 418 311
-3 310 417 418
-3 310 914 417
-3 415 233 761
-3 418 423 311
-3 310 314 914
-3 319 573 914
-3 420 761 419
-3 229 762 320
-3 419 239 421
-3 421 420 419
-3 319 325 573
-3 239 542 421
-3 239 321 542
-3 542 321 322
-3 542 322 422
-3 322 323 422
-3 326 325 330
-3 324 422 323
-3 246 424 425
-3 324 244 422
-3 426 424 246
-3 426 554 424
-3 429 554 426
-3 429 426 428
-3 428 426 427
-3 327 430 557
-3 427 327 431
-3 431 327 557
-3 428 427 431
-3 429 428 431
-3 328 432 564
-3 573 326 440
-3 430 331 433
-3 328 564 337
-3 328 333 432
-3 438 432 333
-3 440 326 434
-3 331 335 433
-3 433 335 449
-3 570 435 337
-3 570 337 564
-3 435 436 437
-3 570 436 435
-3 339 439 434
-3 439 447 434
-3 440 434 447
-3 443 449 335
-3 337 444 253
-3 337 435 444
-3 444 435 445
-3 435 437 445
-3 445 437 446
-3 333 346 438
-3 346 576 438
-3 423 470 338
-3 439 341 447
-3 339 341 439
-3 441 573 440
-3 448 449 443
-3 443 343 448
-3 444 342 253
-3 445 450 444
-3 446 450 445
-3 346 579 576
-3 338 452 340
-3 340 447 341
-3 340 452 447
-3 452 456 447
-3 356 447 456
-3 447 356 440
-3 442 453 349
-3 454 449 448
-3 458 449 454
-3 343 345 455
-3 343 455 448
-3 448 455 454
-3 345 459 455
-3 342 459 345
-3 444 459 342
-3 579 346 352
-3 352 584 579
-3 584 352 586
-3 451 805 347
-3 452 338 470
-3 349 453 457
-3 454 349 458
-3 457 458 349
-3 459 454 455
-3 459 350 454
-3 459 460 350
-3 589 462 461
-3 586 352 353
-3 365 805 598
-3 456 452 470
-3 573 358 464
-3 464 471 573
-3 465 458 457
-3 465 457 466
-3 466 457 453
-3 466 460 465
-3 466 359 460
-3 359 350 460
-3 461 467 589
-3 462 467 461
-3 352 360 595
-3 360 468 595
-3 353 352 607
-3 352 595 607
-3 608 361 469
-3 463 362 598
-3 463 469 362
-3 469 361 362
-3 365 598 362
-3 456 470 356
-3 464 369 375
-3 358 369 464
-3 471 464 375
-3 453 477 466
-3 359 466 472
-3 466 477 472
-3 468 360 639
-3 608 626 370
-3 608 370 361
-3 470 893 356
-3 375 475 471
-3 476 471 475
-3 478 617 472
-3 478 472 477
-3 376 617 479
-3 376 472 617
-3 376 359 472
-3 370 653 377
-3 480 628 473
-3 480 473 629
-3 372 474 485
-3 373 356 893
-3 475 378 481
-3 375 378 475
-3 476 475 482
-3 482 475 481
-3 483 471 476
-3 483 476 482
-3 376 648 278
-3 479 648 376
-3 380 639 360
-3 485 643 372
-3 481 378 678
-3 482 481 679
-3 679 481 678
-3 483 482 486
-3 486 482 679
-3 487 483 486
-3 278 648 684
-3 379 488 484
-3 379 278 488
-3 650 685 484
-3 685 379 484
-3 380 377 987
-3 378 489 678
-3 679 490 486
-3 381 487 490
-3 487 486 490
-3 381 491 492
-3 381 492 487
-3 491 493 664
-3 492 491 664
-3 859 278 684
-3 488 278 859
-3 495 494 685
-3 494 379 685
-3 378 373 496
-3 373 893 496
-3 378 496 489
-3 496 497 489
-3 498 678 489
-3 498 489 497
-3 679 499 490
-3 381 490 500
-3 490 499 500
-3 381 500 491
-3 500 501 491
-3 493 491 501
-3 507 493 501
-3 502 493 507
-3 387 493 502
-3 503 700 382
-3 382 495 503
-3 494 495 382
-3 504 701 687
-3 893 505 496
-3 496 505 497
-3 498 497 505
-3 499 498 506
-3 506 498 505
-3 500 499 506
-3 501 500 506
-3 383 507 501
-3 502 507 508
-3 384 502 508
-3 502 384 387
-3 382 700 707
-3 510 512 513
-3 512 514 513
-3 515 505 893
-3 505 515 506
-3 501 506 515
-3 383 501 518
-3 516 508 507
-3 508 516 384
-3 513 511 510
-3 501 515 518
-3 516 389 519
-3 507 389 516
-3 516 519 389
-3 515 521 518
-3 388 518 521
-3 388 521 390
-3 524 393 292
-3 292 407 524
-3 521 1217 390
-3 522 403 525
-3 522 526 403
-3 399 398 526
-3 399 526 523
-3 523 526 522
-3 523 400 399
-3 523 527 400
-3 390 528 402
-3 529 525 528
-3 529 530 525
-3 528 525 402
-3 402 525 403
-3 530 404 531
-3 530 529 404
-3 531 404 526
-3 526 404 403
-3 398 531 526
-3 398 400 531
-3 400 527 531
-3 529 528 532
-3 532 528 390
-3 404 529 405
-3 529 532 405
-3 407 409 524
-3 218 707 533
-3 220 1226 136
-3 1052 298 532
-3 208 298 1052
-3 533 1226 218
-3 409 208 1052
-3 411 534 410
-3 534 411 1258
-3 535 412 536
-3 411 304 757
-3 1258 411 757
-3 412 413 536
-3 410 540 300
-3 538 537 914
-3 761 536 413
-3 540 302 300
-3 304 308 758
-3 758 757 304
-3 539 914 537
-3 762 412 535
-3 416 914 539
-3 759 758 308
-3 539 537 423
-3 308 315 759
-3 315 2917 759
-3 412 762 229
-3 541 761 420
-3 421 541 420
-3 421 542 541
-3 542 543 541
-3 546 541 544
-3 544 541 543
-3 544 545 546
-3 422 543 542
-3 546 545 547
-3 765 543 422
-3 548 545 544
-3 547 545 548
-3 548 549 547
-3 325 326 573
-3 422 768 765
-3 549 548 769
-3 424 550 425
-3 422 244 768
-3 551 768 244
-3 425 550 552
-3 424 553 550
-3 553 424 554
-3 425 555 244
-3 555 551 244
-3 555 425 556
-3 425 552 556
-3 550 557 552
-3 557 556 552
-3 558 553 559
-3 558 557 553
-3 557 550 553
-3 554 559 553
-3 429 776 554
-3 557 430 556
-3 560 561 430
-3 556 430 561
-3 557 558 431
-3 431 558 562
-3 561 560 558
-3 562 558 560
-3 431 562 429
-3 429 563 776
-3 562 563 429
-3 560 433 565
-3 430 433 560
-3 562 560 566
-3 566 560 565
-3 563 562 566
-3 432 567 564
-3 568 567 432
-3 568 432 438
-3 779 568 438
-3 565 433 569
-3 433 449 569
-3 564 567 570
-3 436 570 785
-3 437 571 572
-3 437 436 571
-3 436 785 571
-3 438 786 572
-3 438 572 779
-3 571 779 572
-3 576 786 438
-3 577 569 449
-3 444 450 575
-3 572 575 446
-3 572 446 437
-3 446 575 450
-3 786 575 572
-3 760 805 451
-3 579 578 576
-3 449 458 577
-3 459 444 588
-3 444 574 588
-3 580 581 582
-3 583 579 584
-3 585 584 586
-3 459 587 460
-3 459 588 587
-3 591 580 590
-3 582 592 580
-3 592 590 580
-3 592 582 581
-3 594 583 593
-3 584 595 583
-3 595 593 583
-3 596 584 585
-3 595 584 596
-3 353 597 586
-3 597 463 598
-3 597 598 586
-3 599 600 601
-3 601 600 814
-3 602 458 465
-3 602 815 458
-3 815 577 458
-3 465 460 587
-3 465 587 602
-3 603 587 588
-3 462 589 467
-3 604 591 590
-3 605 591 604
-3 592 606 590
-3 606 604 590
-3 606 592 581
-3 593 820 594
-3 593 468 820
-3 595 468 593
-3 595 596 607
-3 597 353 607
-3 608 463 609
-3 608 469 463
-3 609 463 610
-3 610 463 597
-3 610 611 609
-3 612 613 614
-3 644 573 471
-3 599 615 616
-3 616 600 599
-3 442 477 453
-3 815 617 618
-3 815 602 617
-3 602 587 617
-3 619 587 603
-3 617 587 619
-3 620 621 622
-3 622 623 620
-3 606 605 604
-3 625 820 468
-3 625 468 639
-3 626 608 609
-3 627 609 611
-3 627 628 609
-3 628 626 609
-3 613 628 627
-3 612 628 613
-3 612 473 628
-3 473 612 629
-3 629 630 631
-3 474 832 833
-3 599 632 615
-3 615 632 633
-3 616 615 634
-3 634 615 633
-3 634 600 616
-3 635 618 478
-3 617 478 618
-3 635 479 619
-3 617 619 479
-3 620 636 621
-3 623 636 620
-3 370 626 640
-3 628 641 626
-3 641 640 626
-3 628 480 641
-3 631 660 629
-3 660 631 642
-3 474 833 485
-3 471 483 644
-3 645 599 680
-3 599 645 632
-3 632 645 646
-3 633 632 647
-3 647 632 646
-3 647 634 633
-3 477 635 478
-3 477 648 635
-3 635 648 479
-3 484 859 649
-3 488 859 484
-3 484 649 650
-3 668 669 624
-3 624 637 668
-3 637 651 668
-3 652 637 638
-3 651 637 652
-3 370 654 653
-3 370 640 654
-3 655 653 654
-3 656 654 640
-3 641 657 640
-3 657 656 640
-3 480 658 641
-3 641 658 657
-3 480 659 658
-3 480 629 659
-3 660 659 629
-3 661 662 663
-3 483 487 644
-3 487 492 644
-3 664 644 492
-3 680 665 645
-3 645 665 666
-3 646 645 667
-3 667 645 666
-3 667 647 646
-3 670 668 651
-3 652 670 651
-3 987 377 653
-3 654 671 655
-3 671 654 672
-3 654 656 672
-3 657 673 656
-3 673 672 656
-3 658 674 657
-3 674 673 657
-3 674 658 659
-3 675 662 661
-3 691 662 675
-3 676 661 663
-3 675 661 676
-3 485 677 643
-3 387 664 493
-3 680 681 665
-3 665 681 682
-3 666 665 683
-3 683 665 682
-3 683 667 666
-3 648 698 684
-3 686 669 687
-3 669 668 687
-3 703 668 670
-3 687 668 703
-3 688 671 672
-3 673 689 672
-3 689 688 672
-3 674 690 673
-3 690 689 673
-3 676 691 675
-3 499 678 498
-3 679 678 499
-3 692 694 693
-3 693 694 680
-3 680 694 695
-3 681 680 696
-3 696 680 695
-3 682 681 697
-3 697 681 696
-3 697 683 682
-3 698 699 684
-3 859 684 699
-3 859 699 707
-3 685 503 495
-3 685 700 503
-3 702 686 701
-3 687 701 686
-3 703 504 687
-3 866 688 689
-3 690 866 689
-3 714 517 693
-3 693 517 704
-3 692 704 509
-3 692 693 704
-3 509 705 692
-3 705 694 692
-3 695 694 706
-3 706 694 705
-3 697 696 706
-3 706 696 695
-3 504 702 701
-3 716 702 504
-3 710 510 511
-3 710 512 510
-3 514 512 867
-3 512 710 867
-3 514 712 711
-3 867 712 514
-3 393 713 387
-3 517 715 704
-3 509 704 715
-3 509 715 705
-3 715 738 705
-3 738 697 706
-3 738 706 705
-3 703 716 504
-3 718 708 717
-3 717 708 709
-3 511 719 710
-3 511 513 719
-3 514 719 513
-3 514 720 719
-3 730 719 720
-3 721 711 722
-3 721 720 711
-3 720 514 711
-3 712 722 711
-3 2917 177 1226
-3 393 520 713
-3 520 1014 713
-3 714 885 723
-3 714 723 724
-3 517 714 725
-3 725 714 724
-3 517 725 726
-3 517 726 715
-3 726 738 715
-3 727 718 717
-3 728 718 727
-3 729 717 709
-3 727 717 729
-3 721 730 720
-3 520 393 877
-3 1021 877 393
-3 1021 393 524
-3 723 885 734
-3 734 885 733
-3 724 723 735
-3 735 723 734
-3 736 724 735
-3 725 724 737
-3 737 724 736
-3 726 725 738
-3 738 725 737
-3 727 739 728
-3 729 739 727
-3 893 521 515
-3 731 522 525
-3 731 732 740
-3 731 740 522
-3 522 740 523
-3 741 523 740
-3 734 733 742
-3 735 734 742
-3 894 743 736
-3 894 736 735
-3 737 736 743
-3 744 738 737
-3 893 1217 521
-3 746 527 741
-3 527 523 741
-3 735 742 894
-3 530 745 525
-3 531 746 530
-3 530 746 745
-3 746 531 527
-3 524 409 901
-3 390 1051 532
-3 707 747 533
-3 532 1051 1052
-3 747 748 533
-3 533 748 749
-3 749 748 902
-3 533 749 902
-3 902 1226 533
-3 913 753 750
-3 752 751 754
-3 1103 410 534
-3 755 753 913
-3 756 755 913
-3 750 753 914
-3 914 753 755
-3 535 754 751
-3 535 536 754
-3 755 756 538
-3 914 755 538
-3 538 756 537
-3 535 751 762
-3 761 764 536
-3 756 423 537
-3 541 546 761
-3 546 764 761
-3 547 763 764
-3 546 547 764
-3 544 543 766
-3 766 543 765
-3 544 766 548
-3 763 549 767
-3 547 549 763
-3 764 763 767
-3 768 766 765
-3 548 766 769
-3 766 768 769
-3 769 767 549
-3 769 770 767
-3 764 767 770
-3 771 764 770
-3 551 769 768
-3 772 769 551
-3 772 773 770
-3 772 770 769
-3 770 773 771
-3 774 771 773
-3 774 554 918
-3 555 775 551
-3 551 775 772
-3 559 773 558
-3 558 773 926
-3 554 773 559
-3 774 773 554
-3 554 776 918
-3 918 776 777
-3 762 930 442
-3 555 924 775
-3 556 924 555
-3 556 925 924
-3 561 926 556
-3 556 926 925
-3 926 561 558
-3 776 563 778
-3 777 776 778
-3 566 778 563
-3 567 777 778
-3 568 777 567
-3 568 779 931
-3 931 779 780
-3 760 1132 805
-3 781 782 783
-3 565 569 791
-3 565 791 566
-3 791 945 566
-3 939 778 945
-3 945 778 566
-3 940 778 939
-3 570 940 784
-3 570 778 940
-3 570 567 778
-3 784 785 570
-3 785 786 571
-3 571 786 779
-3 780 779 786
-3 780 786 787
-3 787 786 576
-3 781 788 782
-3 569 577 791
-3 793 574 792
-3 792 574 794
-3 940 444 784
-3 940 794 444
-3 794 574 444
-3 575 784 444
-3 785 784 575
-3 786 785 575
-3 576 578 787
-3 789 796 797
-3 797 790 789
-3 792 945 801
-3 793 792 801
-3 793 801 574
-3 795 578 803
-3 579 803 578
-3 789 946 798
-3 789 798 796
-3 796 798 799
-3 797 796 800
-3 800 796 799
-3 800 790 797
-3 801 588 574
-3 802 951 580
-3 951 581 580
-3 803 579 583
-3 803 804 1128
-3 804 585 586
-3 804 586 1128
-3 586 598 1128
-3 952 573 825
-3 798 946 806
-3 799 798 807
-3 807 798 806
-3 814 800 807
-3 807 800 799
-3 790 800 814
-3 577 808 953
-3 577 953 950
-3 801 953 808
-3 801 808 588
-3 802 591 954
-3 580 591 802
-3 951 809 581
-3 803 594 810
-3 583 594 803
-3 811 812 804
-3 811 804 810
-3 810 804 803
-3 812 585 804
-3 812 813 585
-3 813 596 585
-3 601 946 599
-3 806 946 601
-3 814 807 806
-3 601 814 806
-3 577 815 808
-3 588 808 816
-3 816 808 815
-3 588 816 603
-3 954 605 957
-3 591 605 954
-3 581 809 606
-3 809 817 606
-3 820 810 594
-3 820 821 810
-3 822 811 810
-3 822 810 821
-3 607 813 822
-3 607 596 813
-3 597 823 610
-3 610 823 611
-3 613 824 614
-3 824 612 614
-3 831 612 824
-3 573 644 825
-3 952 825 664
-3 618 826 815
-3 826 816 815
-3 603 826 619
-3 816 826 603
-3 622 621 827
-3 622 827 623
-3 605 606 957
-3 957 606 817
-3 637 818 819
-3 637 624 818
-3 819 960 637
-3 625 828 820
-3 828 821 820
-3 822 821 829
-3 829 821 828
-3 607 822 830
-3 830 822 829
-3 966 607 830
-3 597 607 966
-3 967 597 966
-3 823 597 967
-3 611 823 627
-3 627 823 968
-3 824 613 627
-3 968 824 627
-3 629 612 831
-3 630 629 831
-3 831 631 630
-3 839 631 831
-3 825 644 834
-3 664 825 834
-3 600 634 814
-3 477 442 648
-3 618 635 826
-3 619 826 635
-3 621 636 827
-3 623 827 636
-3 637 960 638
-3 960 835 638
-3 625 639 828
-3 829 828 836
-3 836 828 639
-3 830 829 837
-3 837 829 836
-3 976 966 830
-3 976 830 838
-3 838 830 837
-3 839 840 642
-3 839 642 631
-3 840 841 842
-3 839 841 840
-3 841 989 842
-3 833 843 485
-3 664 834 644
-3 599 1154 680
-3 647 814 634
-3 648 442 698
-3 649 859 855
-3 855 844 649
-3 844 650 649
-3 650 844 845
-3 845 846 847
-3 844 846 845
-3 624 669 848
-3 624 848 985
-3 638 835 652
-3 835 985 652
-3 639 380 849
-3 836 639 849
-3 836 850 837
-3 653 838 850
-3 838 837 850
-3 653 655 976
-3 653 976 838
-3 976 655 993
-3 851 659 988
-3 988 659 660
-3 840 660 642
-3 840 852 660
-3 852 988 660
-3 842 852 840
-3 853 852 842
-3 854 842 662
-3 854 853 842
-3 662 842 663
-3 663 842 989
-3 995 663 989
-3 677 485 843
-3 1154 693 680
-3 667 814 647
-3 859 990 855
-3 856 844 855
-3 845 857 650
-3 650 857 685
-3 848 669 858
-3 670 985 848
-3 670 848 858
-3 985 670 652
-3 380 987 849
-3 653 850 987
-3 671 993 655
-3 659 862 674
-3 994 659 851
-3 862 659 994
-3 662 691 854
-3 995 676 663
-3 996 387 997
-3 683 814 667
-3 991 685 992
-3 992 685 857
-3 686 861 669
-3 860 861 686
-3 669 861 858
-3 861 703 858
-3 858 703 670
-3 671 688 993
-3 862 863 674
-3 674 863 690
-3 676 864 691
-3 995 864 676
-3 387 870 997
-3 697 892 683
-3 892 814 683
-3 700 999 859
-3 700 859 707
-3 991 999 685
-3 999 700 685
-3 686 702 860
-3 860 702 1006
-3 865 861 860
-3 703 861 865
-3 993 688 1008
-3 688 866 1008
-3 690 1009 866
-3 690 863 1009
-3 868 869 867
-3 870 387 713
-3 870 713 1013
-3 693 1187 714
-3 699 698 707
-3 702 716 1006
-3 1006 716 880
-3 703 865 1018
-3 709 708 872
-3 872 708 871
-3 871 873 872
-3 1009 1008 866
-3 710 874 867
-3 867 875 868
-3 874 875 867
-3 876 867 869
-3 876 712 867
-3 713 1014 1013
-3 1004 1014 520
-3 1004 520 877
-3 1187 1023 714
-3 697 738 892
-3 716 1018 880
-3 1018 716 703
-3 871 708 881
-3 708 718 881
-3 872 882 709
-3 873 882 872
-3 730 710 719
-3 730 883 710
-3 883 874 710
-3 721 722 884
-3 721 884 874
-3 721 874 883
-3 875 874 884
-3 876 722 712
-3 884 722 876
-3 878 877 1021
-3 1046 885 879
-3 714 1023 885
-3 728 886 881
-3 728 881 718
-3 882 729 709
-3 882 887 729
-3 721 883 730
-3 890 1033 731
-3 1033 732 731
-3 892 738 891
-3 728 739 886
-3 739 887 886
-3 729 887 739
-3 525 895 890
-3 731 525 890
-3 741 740 732
-3 733 885 1046
-3 743 897 737
-3 894 897 743
-3 892 737 897
-3 892 744 737
-3 891 738 744
-3 891 744 892
-3 733 1046 742
-3 892 897 899
-3 525 745 895
-3 746 1040 745
-3 898 896 901
-3 901 896 524
-3 742 1046 899
-3 899 894 742
-3 897 894 899
-3 900 898 901
-3 903 1047 901
-3 901 409 903
-3 747 902 748
-3 903 409 1052
-3 904 905 906
-3 909 1093 750
-3 1095 909 750
-3 1095 750 914
-3 751 910 911
-3 912 910 752
-3 752 910 751
-3 750 1093 913
-3 912 754 536
-3 912 752 754
-3 913 1093 756
-3 912 536 764
-3 762 751 911
-3 1258 757 759
-3 1105 914 915
-3 540 410 1103
-3 915 914 916
-3 760 540 1103
-3 757 758 759
-3 916 914 573
-3 759 2917 4237
-3 771 918 764
-3 917 919 923
-3 773 772 920
-3 920 921 773
-3 771 774 918
-3 928 922 919
-3 923 919 922
-3 772 775 924
-3 772 924 920
-3 924 925 920
-3 921 920 926
-3 926 920 925
-3 921 926 773
-3 777 927 918
-3 777 568 927
-3 932 1115 573
-3 922 928 929
-3 938 923 929
-3 929 923 922
-3 931 927 568
-3 1121 927 931
-3 1301 1132 760
-3 929 928 933
-3 933 938 929
-3 780 787 1121
-3 780 1121 931
-3 1121 787 1126
-3 783 934 935
-3 782 934 783
-3 935 781 783
-3 936 781 935
-3 937 928 789
-3 938 933 937
-3 937 933 928
-3 782 943 934
-3 788 943 782
-3 936 788 781
-3 943 788 936
-3 937 789 790
-3 937 790 938
-3 944 945 791
-3 792 939 945
-3 794 939 792
-3 940 939 794
-3 787 578 1126
-3 941 578 795
-3 942 941 795
-3 795 803 1128
-3 795 1128 942
-3 791 577 947
-3 791 947 948
-3 791 948 944
-3 948 1137 949
-3 948 949 944
-3 944 949 945
-3 945 949 801
-3 952 932 573
-3 577 950 947
-3 950 953 947
-3 801 949 1137
-3 801 1137 953
-3 805 1128 598
-3 932 952 1141
-3 938 790 814
-3 802 954 951
-3 951 954 809
-3 956 812 811
-3 1140 813 812
-3 809 957 817
-3 954 957 809
-3 819 958 959
-3 818 958 819
-3 959 960 819
-3 962 955 961
-3 963 956 964
-3 963 961 956
-3 961 955 956
-3 811 964 956
-3 811 822 964
-3 822 1140 964
-3 1140 822 813
-3 824 969 831
-3 664 1141 952
-3 1144 958 624
-3 958 818 624
-3 961 965 962
-3 963 965 961
-3 967 968 823
-3 968 969 824
-3 831 969 970
-3 970 971 831
-3 831 971 839
-3 833 832 972
-3 832 1366 972
-3 930 698 442
-3 1144 624 975
-3 960 975 835
-3 1144 975 960
-3 976 967 966
-3 977 968 967
-3 969 968 977
-3 970 969 978
-3 978 969 977
-3 1155 971 978
-3 978 971 970
-3 979 971 1155
-3 839 971 979
-3 839 980 841
-3 979 980 839
-3 841 980 989
-3 643 1366 832
-3 972 981 833
-3 981 843 833
-3 982 983 844
-3 844 984 846
-3 983 984 844
-3 846 984 847
-3 624 985 975
-3 975 985 835
-3 849 987 836
-3 986 987 849
-3 836 987 850
-3 994 977 967
-3 978 977 994
-3 851 988 978
-3 851 978 994
-3 1155 978 988
-3 1155 852 979
-3 1155 988 852
-3 853 979 852
-3 980 979 853
-3 854 980 853
-3 854 989 980
-3 1382 1366 677
-3 1366 643 677
-3 1382 677 981
-3 843 981 677
-3 996 664 387
-3 693 1154 1365
-3 855 991 856
-3 990 991 855
-3 856 982 844
-3 856 991 982
-3 991 992 982
-3 845 992 857
-3 845 983 992
-3 983 982 992
-3 847 983 845
-3 984 983 847
-3 987 986 849
-3 993 967 976
-3 994 967 993
-3 989 854 1165
-3 854 691 1165
-3 995 989 1165
-3 997 998 1161
-3 996 997 1161
-3 698 930 707
-3 990 859 999
-3 991 990 999
-3 862 1001 863
-3 862 994 1001
-3 994 993 1001
-3 691 1002 1165
-3 995 1002 864
-3 1002 691 864
-3 998 997 870
-3 1161 998 1003
-3 1004 1161 1003
-3 1005 1161 1004
-3 693 1169 1187
-3 1365 1169 693
-3 860 1006 1000
-3 860 1000 1007
-3 1000 1006 1007
-3 1007 865 860
-3 1001 993 1009
-3 1009 993 1008
-3 1001 1009 863
-3 1011 868 1010
-3 1011 1179 868
-3 1179 869 868
-3 1179 1012 869
-3 1013 998 870
-3 1003 998 1014
-3 1014 998 1013
-3 1004 1003 1014
-3 1005 1004 877
-3 1015 1005 877
-3 878 1005 1015
-3 1162 1005 878
-3 1162 878 1163
-3 1163 878 1021
-3 1007 1006 1018
-3 1018 1006 880
-3 865 1007 1018
-3 873 871 1189
-3 871 1188 1189
-3 873 1189 1019
-3 1010 875 884
-3 868 875 1010
-3 876 1011 1010
-3 876 1010 884
-3 869 1020 876
-3 1020 1011 876
-3 1012 1020 869
-3 1015 877 878
-3 1016 1022 879
-3 885 1016 879
-3 1017 1016 885
-3 885 1023 1017
-3 871 881 1024
-3 871 1024 1025
-3 871 1025 1188
-3 873 1026 882
-3 873 1019 1026
-3 1028 1029 1027
-3 1030 1032 1033
-3 1031 1032 1030
-3 1022 1046 879
-3 881 886 1034
-3 881 1034 1024
-3 1034 1035 1024
-3 1024 1036 1025
-3 1024 1035 1036
-3 1036 1196 1025
-3 1036 1026 1196
-3 1036 887 1026
-3 882 1026 887
-3 1027 1037 1028
-3 1029 1037 1027
-3 888 1202 889
-3 1038 888 889
-3 1039 1031 1030
-3 1205 1031 1039
-3 1033 890 1039
-3 1033 1039 1030
-3 1033 1032 1040
-3 1033 1040 732
-3 887 1034 886
-3 1035 1034 887
-3 1036 1035 887
-3 888 1204 1202
-3 1204 888 1038
-3 1205 1039 890
-3 1205 890 895
-3 741 732 1040
-3 1041 524 896
-3 1427 895 745
-3 1040 1427 745
-3 741 1040 746
-3 1022 1210 1046
-3 902 747 707
-3 898 1045 1042
-3 896 898 1042
-3 896 1042 1041
-3 1043 1044 900
-3 1045 900 1044
-3 1045 898 900
-3 1050 899 1046
-3 1043 900 1047
-3 900 901 1047
-3 1049 1046 1048
-3 1050 1046 1049
-3 1433 899 1050
-3 1217 1051 390
-3 1049 1048 1220
-3 1225 1222 1051
-3 1051 1222 1052
-3 1047 903 1215
-3 903 1052 1223
-3 1055 1053 1056
-3 1056 1053 1060
-3 1058 1053 1055
-3 1056 1058 1055
-3 1060 1057 1056
-3 1058 1056 1057
-3 1058 1057 1059
-3 1059 1057 1060
-3 1059 1062 1058
-3 905 1059 1060
-3 904 1061 1062
-3 905 904 1062
-3 905 1062 1059
-3 905 1063 906
-3 905 1060 1063
-3 1060 1238 1063
-3 906 1061 904
-3 906 1063 1061
-3 1063 1064 1061
-3 1064 1062 1061
-3 1238 1064 1063
-3 1065 1237 1066
-3 1067 1066 1237
-3 1238 1067 1237
-3 1067 1238 1068
-3 1066 1067 1070
-3 1070 1067 1068
-3 1238 1239 1069
-3 1238 1069 1068
-3 1070 1068 1069
-3 1072 1066 1070
-3 1242 1069 1239
-3 1070 1069 1071
-3 1071 1069 1242
-3 1072 1070 1071
-3 1071 1242 1073
-3 1072 1071 1073
-3 1073 1242 1074
-3 1072 1073 1076
-3 1076 1073 1074
-3 1076 1074 1075
-3 1074 1242 1077
-3 907 1075 1077
-3 1075 1074 1077
-3 907 1078 1076
-3 907 1076 1075
-3 907 1081 908
-3 1077 1081 907
-3 907 908 1078
-3 908 1081 1080
-3 908 1080 1078
-3 1078 1080 1079
-3 1472 1082 1081
-3 1243 1079 1080
-3 1081 1243 1080
-3 1082 1243 1081
-3 1084 1082 1083
-3 1084 1083 1085
-3 1085 1083 1086
-3 1086 1084 1085
-3 1087 1084 1086
-3 1088 1084 1087
-3 1087 1089 1088
-3 1088 1089 1090
-3 1090 1091 1088
-3 1089 1091 1090
-3 1094 1093 1092
-3 1095 1092 1093
-3 909 1095 1093
-3 1098 1097 1099
-3 1102 1251 1096
-3 1100 1097 1098
-3 1504 1100 1098
-3 910 1100 911
-3 910 1099 1100
-3 1099 1097 1100
-3 1099 910 1101
-3 910 912 1101
-3 1504 911 1100
-3 534 1258 1256
-3 1095 914 1259
-3 1504 762 911
-3 1259 914 1105
-3 1101 912 764
-3 1263 1259 1105
-3 1102 1106 1104
-3 1104 1106 1107
-3 1258 759 4237
-3 1112 1263 1105
-3 1109 1107 1108
-3 1108 1107 1106
-3 915 916 1105
-3 916 1112 1105
-3 1110 1109 1108
-3 916 573 1111
-3 1112 916 1111
-3 1108 1114 1110
-3 1110 1114 1113
-3 573 1268 1111
-3 1268 1112 1111
-3 1114 1270 1113
-3 760 1511 2369
-3 1115 1268 573
-3 1288 917 1116
-3 1276 1115 1290
-3 919 917 1118
-3 917 1288 1118
-3 1116 917 1117
-3 1118 928 919
-3 917 923 1117
-3 1532 927 1119
-3 1290 1115 932
-3 1117 923 938
-3 1121 1119 927
-3 1120 1290 932
-3 1122 1119 1121
-3 1122 1123 1119
-3 1123 1124 1292
-3 1119 1123 1292
-3 1124 942 1292
-3 935 934 1125
-3 935 1125 936
-3 1297 1120 932
-3 928 1118 789
-3 1126 1122 1121
-3 1123 1122 1127
-3 1127 1122 1126
-3 941 1124 1127
-3 1124 1123 1127
-3 942 1124 941
-3 942 1128 1292
-3 1129 1130 1131
-3 1131 1130 1132
-3 934 943 1125
-3 936 1125 943
-3 1133 1134 1135
-3 1135 1136 1133
-3 1297 932 1141
-3 1118 1311 789
-3 1127 1126 578
-3 941 1127 578
-3 1129 805 1132
-3 1130 1129 1132
-3 1133 1315 1134
-3 1136 1315 1133
-3 948 947 1137
-3 1298 1141 1318
-3 1311 946 789
-3 947 953 1137
-3 423 893 470
-3 1142 1318 1141
-3 1143 1318 1142
-3 946 1311 599
-3 956 955 1138
-3 1138 1139 956
-3 956 1140 812
-3 1139 1140 956
-3 959 958 1144
-3 959 1144 960
-3 1138 962 1145
-3 955 962 1138
-3 964 1145 963
-3 964 1139 1145
-3 1139 1138 1145
-3 1140 1139 964
-3 1142 1141 1146
-3 1147 1142 1146
-3 1143 1142 1147
-3 1148 1143 1147
-3 1323 1148 1353
-3 962 965 1145
-3 963 1145 965
-3 974 973 1577
-3 1577 1150 974
-3 664 1151 1141
-3 1151 1146 1141
-3 1147 1146 1151
-3 1152 1147 1151
-3 1148 1147 1152
-3 1153 1148 1152
-3 1160 1148 1153
-3 1353 1148 1160
-3 1149 1343 1154
-3 974 1156 973
-3 974 1157 1156
-3 1157 1150 1158
-3 1157 974 1150
-3 1153 1152 1151
-3 1160 1153 1159
-3 1354 1353 1160
-3 1365 1154 1343
-3 1166 1382 981
-3 664 996 1151
-3 1153 1151 996
-3 1159 1153 996
-3 996 1160 1159
-3 1161 1160 996
-3 1354 1160 1161
-3 1354 1161 1162
-3 1005 1162 1161
-3 1373 1162 1163
-3 1168 1163 1167
-3 1359 1168 1175
-3 1377 1164 1169
-3 707 930 5643
-3 995 1165 1002
-3 1171 1172 1170
-3 1167 1163 1173
-3 1168 1167 1174
-3 1174 1167 1173
-3 1183 1168 1174
-3 1175 1168 1183
-3 1184 1175 1183
-3 1164 1176 1177
-3 1169 1164 1178
-3 1178 1164 1177
-3 1186 1169 1178
-3 1187 1169 1186
-3 1172 1180 1170
-3 1173 1163 1021
-3 1021 1174 1173
-3 1185 1016 1176
-3 1177 1176 1016
-3 1017 1177 1016
-3 1178 1177 1017
-3 1017 1186 1178
-3 1179 1011 1020
-3 1012 1179 1020
-3 1193 1182 1181
-3 1409 1194 1181
-3 1194 1193 1181
-3 1021 1183 1174
-3 1184 1183 1195
-3 1195 1183 1021
-3 1016 1185 1022
-3 1022 1185 1415
-3 1023 1186 1017
-3 1187 1186 1023
-3 1188 1025 1196
-3 1019 1196 1026
-3 1019 1189 1196
-3 1189 1188 1196
-3 1028 1197 1029
-3 1190 1198 1191
-3 1192 1198 1190
-3 1193 1205 1182
-3 1031 1205 1193
-3 1031 1193 1194
-3 1194 1409 1199
-3 1194 1199 1031
-3 1031 1199 1032
-3 524 1195 1021
-3 524 1413 1195
-3 1200 1022 1201
-3 1201 1022 1415
-3 1028 1037 1197
-3 1029 1197 1037
-3 1202 1203 889
-3 1038 1203 1204
-3 1038 889 1203
-3 1206 1040 1032
-3 1206 1032 1199
-3 524 1041 1413
-3 1207 1413 1208
-3 1208 1413 1041
-3 1201 1207 1208
-3 1201 1208 1200
-3 1200 1208 1209
-3 1200 1209 1022
-3 1205 895 1427
-3 1206 1427 1040
-3 1210 1208 1041
-3 1209 1208 1210
-3 1022 1209 1210
-3 1041 1042 1211
-3 1041 1211 1210
-3 1210 1211 1046
-3 1433 892 899
-3 1044 1043 1212
-3 1212 1213 1044
-3 1044 1214 1045
-3 1213 1214 1044
-3 1045 1211 1042
-3 1045 1214 1211
-3 1046 1211 1048
-3 1047 1212 1043
-3 1047 1215 1212
-3 1215 1213 1212
-3 1214 1213 1216
-3 1216 1213 1215
-3 1211 1214 1216
-3 1216 1215 1218
-3 1211 1216 1219
-3 1219 1216 1218
-3 1048 1211 1220
-3 1211 1219 1220
-3 1049 1433 1050
-3 1217 1221 1051
-3 1051 1221 1225
-3 1215 903 1223
-3 1218 1215 1223
-3 1219 1218 1223
-3 1220 1219 1224
-3 1224 1219 1223
-3 1893 1433 1049
-3 1893 1049 1224
-3 1224 1049 1220
-3 902 707 5643
-3 1217 1632 1221
-3 1221 1632 1225
-3 1893 1224 1223
-3 1632 1052 1225
-3 1225 1052 1222
-3 902 5643 1226
-3 1229 1227 1230
-3 1234 1229 1230
-3 1227 1231 1230
-3 1234 1230 1232
-3 1232 1230 1231
-3 1232 1231 1233
-3 1234 1232 1233
-3 1233 1231 1235
-3 1234 1233 1236
-3 1236 1233 1235
-3 1235 1231 1469
-3 1054 1469 1053
-3 1054 1236 1469
-3 1236 1235 1469
-3 1054 1053 1234
-3 1054 1234 1236
-3 1053 1469 1060
-3 1234 1053 1058
-3 1058 1062 1234
-3 1238 1060 1469
-3 1062 1064 1234
-3 1234 1064 1663
-3 1064 1237 1663
-3 1238 1237 1064
-3 1237 1065 1066
-3 1237 1066 1663
-3 1066 1072 1663
-3 1241 1240 1239
-3 1242 1239 1240
-3 1241 1242 1240
-3 1472 1242 1241
-3 1470 1472 1241
-3 1072 1076 1079
-3 1242 1472 1077
-3 1077 1472 1081
-3 1076 1078 1079
-3 1472 1473 1082
-3 1473 1083 1082
-3 1475 1083 1473
-3 1082 1084 1243
-3 1243 1084 1244
-3 1086 1083 1475
-3 1476 1086 1475
-3 1086 1476 1087
-3 1084 1088 1244
-3 1089 1087 1476
-3 1244 1088 1091
-3 1089 1476 1246
-3 1249 1089 1246
-3 1089 1249 1091
-3 1245 1247 1248
-3 1245 1248 1092
-3 1245 1092 1503
-3 1091 1249 1250
-3 1091 1250 1244
-3 1248 1094 1092
-3 1096 1246 1489
-3 1249 1246 1096
-3 1251 1249 1096
-3 1251 1250 1249
-3 1251 1244 1250
-3 1262 1244 1251
-3 1099 1252 1098
-3 1099 1487 1252
-3 1095 1503 1092
-3 1102 1096 1489
-3 1499 1102 1489
-3 1098 1252 1253
-3 1967 1487 1101
-3 1487 1099 1101
-3 1098 1253 1504
-3 1255 1254 1257
-3 1257 1254 1256
-3 1258 1500 1255
-3 1257 1258 1255
-3 1505 1102 1499
-3 1103 534 1502
-3 1256 1502 534
-3 1258 1257 1256
-3 1259 1503 1095
-3 1505 1508 1102
-3 1094 423 1093
-3 1251 1102 1262
-3 1967 1101 764
-3 1102 1104 1262
-3 1260 1259 1263
-3 1506 1259 1260
-3 1093 423 756
-3 1508 1261 1106
-3 1102 1508 1106
-3 1104 1107 1262
-3 1263 1112 1264
-3 1260 1263 1265
-3 1265 1263 1264
-3 1260 1512 1506
-3 1261 1108 1106
-3 1109 1262 1107
-3 1264 1112 1266
-3 1265 1264 1267
-3 1267 1264 1266
-3 1260 1265 1267
-3 1273 1260 1267
-3 1512 1260 1273
-3 1109 1110 1262
-3 1268 1266 1112
-3 1268 1267 1266
-3 1273 1267 1268
-3 1114 1108 1269
-3 1262 1110 1271
-3 1110 1113 1271
-3 1103 1511 760
-3 1272 1512 1273
-3 1270 1271 1113
-3 1114 1269 1275
-3 1114 1275 1271
-3 1114 1271 1270
-3 1274 1517 1518
-3 1517 1274 1269
-3 1275 1269 1274
-3 1272 1273 1278
-3 1276 1272 1278
-3 1277 1275 1274
-3 1279 1280 1277
-3 1115 1273 1268
-3 1115 1278 1273
-3 1284 1279 1281
-3 1282 1280 1279
-3 1284 1282 1279
-3 1115 1276 1278
-3 1284 1281 1283
-3 1286 1282 1284
-3 1285 1283 1281
-3 1284 1283 1286
-3 1286 1283 1285
-3 1287 1285 1281
-3 1287 1286 1285
-3 1289 1276 1290
-3 1525 1288 1287
-3 918 1740 764
-3 1287 1288 1116
-3 918 927 1740
-3 927 1531 1740
-3 1525 1533 1118
-3 1525 1118 1288
-3 1287 1116 1117
-3 1531 927 1532
-3 2369 1301 760
-3 1773 1289 1291
-3 1292 1532 1119
-3 1293 1290 1120
-3 1289 1290 1293
-3 1291 1289 1293
-3 1773 1291 1300
-3 1300 1291 1294
-3 1533 1296 1118
-3 1120 1297 1293
-3 1291 1293 1298
-3 1298 1293 1297
-3 1294 1291 1299
-3 1299 1291 1298
-3 1300 1294 1302
-3 1302 1294 1299
-3 1296 1295 1535
-3 1118 1296 1535
-3 1287 1117 814
-3 1303 1300 1302
-3 1304 1300 1303
-3 1300 1304 1305
-3 1118 1535 1311
-3 1129 1301 805
-3 1131 1301 1129
-3 1132 1301 1131
-3 1135 1134 1538
-3 1135 1538 1136
-3 1298 1297 1141
-3 1302 1299 1308
-3 1308 1299 1298
-3 1303 1302 1309
-3 1309 1302 1308
-3 1304 1303 1309
-3 1305 1304 1310
-3 1310 1304 1309
-3 1312 1311 1535
-3 938 814 1117
-3 1307 1313 1306
-3 1313 1307 1314
-3 1315 1541 1134
-3 1538 1134 1541
-3 1315 1136 1316
-3 1316 1136 1538
-3 1538 1317 1316
-3 1318 1308 1298
-3 1309 1308 1318
-3 1321 1541 1315
-3 1316 1319 1315
-3 1319 1316 1317
-3 1320 1309 1318
-3 1310 1309 1320
-3 1801 599 1311
-3 1321 1315 1322
-3 1315 1319 1322
-3 1322 1319 1317
-3 1318 1143 1320
-3 1310 1320 1323
-3 1323 1320 1143
-3 1324 1310 1323
-3 599 1801 1154
-3 1323 1143 1148
-3 1325 1324 1323
-3 1326 1324 1325
-3 1329 1801 1328
-3 1154 1801 1149
-3 1149 1801 1329
-3 1330 1331 1332
-3 1330 1333 1334
-3 1332 1333 1330
-3 1325 1323 1353
-3 1326 1325 1336
-3 1336 1325 1335
-3 1324 1326 1337
-3 1337 1326 1336
-3 1338 1324 1337
-3 1542 1324 1338
-3 1342 1327 1362
-3 1364 1327 1342
-3 1328 1327 1364
-3 1329 1328 1343
-3 1149 1329 1343
-3 1344 1331 1330
-3 1345 1331 1344
-3 1334 1346 1330
-3 1346 1344 1330
-3 1347 1577 973
-3 1150 1348 1349
-3 1150 1577 1348
-3 1348 1350 1349
-3 1335 1325 1353
-3 1336 1335 1353
-3 1337 1336 1354
-3 1354 1336 1353
-3 1338 1337 1354
-3 1355 1338 1354
-3 1566 1338 1355
-3 1566 1355 1356
-3 1357 1339 1340
-3 1341 1339 1358
-3 1358 1339 1357
-3 1341 1358 1561
-3 1563 1359 1360
-3 1342 1362 1363
-3 1364 1342 1363
-3 1328 1364 1365
-3 1343 1328 1365
-3 1346 1345 1344
-3 1156 1157 1367
-3 1156 1367 1347
-3 1156 1347 973
-3 1367 1157 1158
-3 1367 1158 1368
-3 1349 1158 1150
-3 1349 1369 1158
-3 1369 1368 1158
-3 1350 1369 1349
-3 1351 1369 1350
-3 1351 1352 1370
-3 1371 1370 1352
-3 1355 1354 1162
-3 1372 1356 1355
-3 1162 1372 1355
-3 1374 1373 1357
-3 1358 1357 1163
-3 1163 1357 1373
-3 1561 1358 1168
-3 1168 1358 1163
-3 1562 1561 1168
-3 1359 1562 1168
-3 1360 1359 1375
-3 1362 1361 1377
-3 1377 1361 1376
-3 1363 1362 1377
-3 1169 1363 1377
-3 1365 1363 1169
-3 1364 1363 1365
-3 1382 1378 1366
-3 981 1383 1166
-3 1384 1351 1370
-3 1371 1379 1370
-3 1379 1384 1370
-3 1379 1371 1380
-3 1162 1381 1372
-3 1162 1373 1381
-3 1374 1381 1373
-3 1359 1175 1375
-3 1377 1376 1164
-3 1166 1383 1382
-3 1380 1384 1379
-3 1171 1170 1385
-3 1171 1385 1172
-3 1175 1388 1389
-3 1609 1175 1389
-3 1164 1389 1388
-3 1176 1164 1388
-3 1170 1180 1385
-3 1172 1385 1180
-3 1390 1392 1393
-3 1392 1613 1393
-3 1181 1182 1394
-3 1386 1395 1387
-3 1396 1398 1399
-3 1397 1398 1396
-3 1175 1184 1413
-3 1388 1175 1400
-3 1400 1175 1413
-3 1176 1400 1185
-3 1388 1400 1176
-3 1401 1190 1191
-3 1401 1402 1190
-3 1192 1190 1403
-3 1403 1190 1402
-3 1391 1403 1402
-3 1391 1390 1403
-3 1390 1404 1403
-3 1404 1390 1393
-3 1613 1405 1393
-3 1405 1406 1407
-3 1613 1406 1405
-3 1394 1182 1408
-3 1181 1394 1409
-3 1394 1408 1409
-3 1396 1399 1410
-3 1411 1410 1399
-3 1411 1399 1412
-3 1184 1195 1413
-3 1414 1400 1413
-3 1414 1185 1400
-3 1414 1415 1185
-3 1191 1416 1401
-3 1191 1198 1416
-3 1403 1416 1192
-3 1192 1416 1198
-3 1404 1416 1403
-3 1417 1405 1407
-3 1182 1205 1408
-3 1205 1419 1408
-3 1419 1409 1408
-3 1409 1419 1199
-3 1420 1396 1410
-3 1411 1421 1410
-3 1421 1411 1412
-3 1414 1413 1430
-3 1415 1629 1201
-3 1422 1423 1424
-3 1424 1425 1422
-3 1203 1202 1418
-3 1202 1631 1418
-3 1418 1426 1203
-3 1418 1625 1426
-3 1203 1426 1204
-3 1205 1427 1419
-3 1427 1199 1419
-3 1199 1427 1206
-3 1410 1428 1420
-3 1428 1410 1429
-3 1410 1421 1429
-3 1429 1421 1432
-3 1207 1430 1413
-3 1201 1629 1207
-3 1629 1430 1207
-3 1433 814 892
-3 1422 1431 1423
-3 1425 1431 1422
-3 1426 1631 1202
-3 1204 1426 1202
-3 1429 1432 1428
-3 1632 1217 893
-3 1226 2516 2917
-3 1052 1632 1633
-3 1435 1436 1437
-3 1434 1435 1437
-3 1435 1434 1438
-3 1436 1435 1438
-3 1437 1436 1439
-3 1439 1436 1438
-3 1434 1638 1438
-3 1441 1437 1439
-3 1445 1438 1638
-3 1439 1438 1445
-3 1440 1441 1439
-3 1638 1639 1445
-3 1441 1440 1442
-3 1448 1441 1444
-3 1444 1441 1442
-3 1440 1439 1445
-3 1442 1440 1445
-3 1444 1442 1443
-3 1443 1442 1446
-3 1446 1442 1445
-3 1444 1443 1447
-3 1447 1443 1446
-3 1448 1444 1447
-3 1446 1445 1645
-3 1449 1447 1446
-3 1451 1448 1447
-3 1449 1451 1447
-3 1645 1647 1446
-3 1450 1446 1647
-3 1449 1446 1450
-3 1451 1449 1450
-3 1647 1452 1450
-3 1451 1450 1453
-3 1453 1450 1452
-3 1453 1454 1451
-3 1452 1648 1455
-3 1452 1455 1453
-3 1456 1454 1453
-3 1456 1453 1455
-3 1648 1457 1455
-3 1455 1457 1456
-3 1457 1458 1456
-3 1457 1654 1458
-3 1654 1459 1458
-3 1653 1654 1460
-3 1461 1460 1654
-3 1461 1462 1460
-3 1461 1463 1462
-3 1462 1463 1460
-3 1464 1460 1463
-3 1463 1466 1464
-3 1465 1466 1463
-3 1659 1467 1465
-3 1465 1467 1466
-3 1228 1227 1468
-3 1228 1468 1466
-3 1228 1466 1467
-3 1468 1227 1229
-3 1467 1659 1228
-3 1228 1659 1227
-3 1234 1468 1229
-3 1227 1659 1231
-3 1234 4051 1468
-3 1469 1231 1662
-3 1238 1469 1664
-3 1238 1664 1239
-3 1664 1666 1239
-3 1239 1666 1241
-3 1241 1666 1470
-3 1072 1079 1663
-3 1471 1470 1666
-3 1663 1079 1243
-3 1471 1670 1470
-3 1470 1670 1472
-3 1673 1472 1670
-3 1473 1472 1673
-3 1475 1473 1474
-3 1243 1244 1663
-3 1674 1474 1473
-3 1474 1674 1475
-3 1475 1674 1476
-3 1476 1477 1246
-3 1476 1480 1477
-3 1480 1481 1477
-3 1477 1481 1246
-3 1486 1482 1478
-3 1483 1478 1482
-3 1247 1493 1248
-3 1247 1479 1493
-3 1245 1479 1247
-3 1481 1480 1484
-3 1481 1484 1246
-3 1485 1482 1486
-3 1483 1482 1487
-3 1487 1482 1485
-3 1487 1967 1483
-3 1248 1493 1094
-3 1245 1503 1694
-3 1489 1480 1488
-3 1246 1484 1489
-3 1484 1480 1489
-3 1252 1485 1486
-3 1252 1486 1504
-3 1487 1485 1252
-3 1490 1491 1492
-3 1494 1490 1492
-3 1492 1491 1693
-3 1697 1094 1493
-3 1701 1694 1503
-3 1252 1504 1253
-3 1490 1494 1496
-3 1496 1494 1495
-3 1491 1490 1497
-3 1497 1490 1496
-3 1497 1693 1491
-3 1498 1499 1488
-3 1488 1499 1489
-3 1256 1254 1502
-3 1502 1255 1494
-3 1502 1254 1255
-3 1500 1494 1255
-3 1500 1495 1494
-3 1496 1495 1501
-3 1501 1495 1500
-3 1501 1497 1496
-3 1705 1499 1498
-3 1500 1258 1501
-3 2278 1497 1501
-3 1705 1712 1499
-3 1499 1712 1505
-3 1258 2278 1501
-3 1697 423 1094
-3 1503 1259 1506
-3 1258 4237 2278
-3 1712 1507 1261
-3 1505 1712 1261
-3 1508 1505 1261
-3 1512 1503 1506
-3 1719 1503 1512
-3 2686 1967 764
-3 1103 1978 1511
-3 1507 1509 1510
-3 1261 1507 1513
-3 1513 1507 1510
-3 1108 1261 1513
-3 1514 1512 1515
-3 1513 1510 1721
-3 1108 1513 1269
-3 1262 1271 1519
-3 1511 1724 2369
-3 1272 1515 1512
-3 1513 1721 1269
-3 1272 1276 1515
-3 1721 1516 1518
-3 1269 1721 1517
-3 1517 1721 1518
-3 1514 1515 1276
-3 1271 1275 1519
-3 1518 1277 1274
-3 1277 1519 1275
-3 1731 1514 1276
-3 1518 1516 1520
-3 1279 1518 1520
-3 1277 1518 1279
-3 1277 1280 1519
-3 1519 1280 1524
-3 2686 764 1740
-3 1279 1520 1281
-3 1280 1282 1524
-3 1289 1731 1276
-3 1520 1521 1522
-3 1281 1520 1523
-3 1282 1286 1524
-3 1521 1735 1522
-3 1523 1520 1522
-3 4845 930 762
-3 1523 1522 1525
-3 1281 1523 1287
-3 1287 1523 1525
-3 1287 1524 1286
-3 1773 2021 1289
-3 1526 1529 1528
-3 1527 1530 1526
-3 1530 1529 1526
-3 1522 2034 1525
-3 1530 1528 1529
-3 1533 1525 2034
-3 1292 1531 1532
-3 1128 1531 1292
-3 1753 1300 1534
-3 1533 1776 1535
-3 1296 1533 1295
-3 1301 1128 805
-3 1774 1534 1779
-3 1776 1788 1535
-3 1295 1533 1535
-3 1305 1534 1300
-3 1310 1534 1305
-3 1779 1534 1310
-3 1542 1779 1310
-3 1535 1788 1312
-3 1797 1536 1306
-3 1307 1306 1536
-3 1537 1307 1536
-3 1789 1542 1790
-3 1306 1313 1806
-3 1797 1306 1806
-3 1307 1537 1314
-3 1537 1540 1314
-3 1542 1310 1324
-3 1539 1790 1542
-3 1312 1801 1311
-3 1287 814 4422
-3 1313 1810 1806
-3 1313 1540 1810
-3 1314 1540 1313
-3 1538 1811 1317
-3 1783 1539 1542
-3 1543 1783 1542
-3 1545 1328 1808
-3 1799 1545 1808
-3 1317 1811 1322
-3 1811 1546 1322
-3 1543 1542 1547
-3 1548 1543 1547
-3 1560 1549 1544
-3 1562 1544 1549
-3 1563 1544 1562
-3 1550 1544 1563
-3 1545 1550 1327
-3 1328 1545 1327
-3 1551 1552 1553
-3 1551 1553 1554
-3 1553 1555 1554
-3 1322 1546 1321
-3 1547 1542 1556
-3 1557 1547 1556
-3 1548 1547 1558
-3 1558 1547 1557
-3 1339 1548 1558
-3 1815 1548 1339
-3 1341 1815 1339
-3 1341 1559 1560
-3 1815 1341 1560
-3 1560 1559 1549
-3 1549 1559 1561
-3 1562 1549 1561
-3 1327 1550 1563
-3 1332 1823 1564
-3 1331 1823 1332
-3 1552 1551 1333
-3 1552 1333 1564
-3 1564 1333 1332
-3 1334 1333 1551
-3 1334 1551 1565
-3 1565 1551 1554
-3 1565 1554 1555
-3 1348 1817 1351
-3 1817 1578 1351
-3 1556 1542 1338
-3 1566 1556 1338
-3 1557 1556 1566
-3 1566 1558 1557
-3 1339 1558 1567
-3 1567 1558 1566
-3 1339 1567 1340
-3 1559 1341 1561
-3 1359 1563 1562
-3 1327 1563 1362
-3 1569 1570 1568
-3 1571 1823 1345
-3 1823 1331 1345
-3 1565 1572 1573
-3 1565 1573 1334
-3 1334 1573 1346
-3 1555 1572 1565
-3 1574 1575 1366
-3 1366 1575 972
-3 1575 981 972
-3 1576 1577 1347
-3 1350 1348 1351
-3 1351 1578 1352
-3 1356 1579 1566
-3 1579 1567 1566
-3 1340 1579 1357
-3 1567 1579 1340
-3 1361 1563 1360
-3 1362 1563 1361
-3 1580 1569 1568
-3 1847 1569 1580
-3 1581 1568 1570
-3 1580 1568 1581
-3 1571 1345 1830
-3 1345 1346 1830
-3 1830 1346 1573
-3 1850 981 1575
-3 1347 1367 1576
-3 1367 1368 1576
-3 1369 1582 1368
-3 1368 1582 1576
-3 1582 1369 1351
-3 1352 1578 1834
-3 1371 1352 1834
-3 1583 1585 1586
-3 1584 1585 1583
-3 1579 1587 1841
-3 1579 1356 1587
-3 1356 1372 1587
-3 1841 1357 1579
-3 1841 1595 1357
-3 1595 1374 1357
-3 1360 1588 1589
-3 1375 1588 1360
-3 1361 1360 1590
-3 1360 1589 1590
-3 1590 1376 1361
-3 1581 1847 1580
-3 1383 1850 1597
-3 981 1850 1383
-3 1351 1384 1582
-3 1591 1380 1834
-3 1380 1371 1834
-3 1583 1592 1593
-3 1583 1586 1592
-3 1592 1586 1585
-3 1594 1372 1381
-3 1594 1587 1372
-3 1595 1594 1374
-3 1595 1596 1594
-3 1594 1381 1374
-3 1375 1175 1588
-3 1588 1175 1874
-3 1376 1590 1164
-3 1383 1597 1382
-3 1382 1597 1378
-3 1380 1591 1384
-3 1598 1593 1592
-3 1870 1599 1592
-3 1599 1598 1592
-3 1600 1587 1594
-3 1596 1601 1594
-3 1601 1600 1594
-3 1602 1596 1595
-3 1602 1601 1596
-3 1874 1175 1609
-3 1604 1593 1598
-3 1614 1593 1604
-3 1386 1387 1604
-3 1386 1604 1599
-3 1599 1604 1598
-3 1599 1870 1386
-3 1870 1605 1386
-3 1600 1601 1606
-3 1602 1607 1601
-3 1607 1606 1601
-3 1880 1608 1602
-3 1608 1607 1602
-3 1610 1611 1609
-3 1610 1609 1389
-3 1389 1612 1610
-3 1389 1164 1612
-3 1164 1590 1612
-3 1603 1392 1391
-3 1391 1392 1390
-3 1392 1619 1613
-3 1392 1603 1619
-3 1387 1614 1604
-3 1387 1395 1614
-3 1395 1876 1614
-3 1605 1395 1386
-3 1876 1395 1605
-3 1397 1606 1607
-3 1398 1397 1607
-3 1608 1398 1607
-3 1608 1880 1398
-3 1398 1880 1399
-3 1615 1611 1610
-3 1616 1611 1615
-3 1617 1610 1612
-3 1615 1610 1617
-3 1402 1401 1618
-3 1402 1618 1391
-3 1613 1619 1406
-3 1619 1407 1406
-3 1396 1620 1397
-3 1399 1880 1412
-3 1880 1621 1412
-3 1414 1616 1615
-3 1415 1622 1623
-3 1414 1622 1415
-3 1414 1617 1622
-3 1414 1615 1617
-3 1401 1624 1618
-3 1401 1416 1624
-3 1416 1404 1624
-3 1393 1624 1404
-3 1405 1624 1393
-3 1405 1886 1624
-3 1619 1417 1407
-3 1619 1886 1417
-3 1886 1405 1417
-3 1625 1418 1626
-3 1418 1887 1626
-3 1627 1620 1420
-3 1620 1396 1420
-3 1627 1621 1888
-3 1421 1412 1621
-3 1628 1616 1430
-3 1616 1414 1430
-3 1623 1629 1415
-3 1623 1622 1629
-3 1424 1423 1630
-3 1424 1630 1425
-3 1625 1892 1631
-3 1625 1631 1426
-3 1626 1892 1625
-3 1420 1428 1627
-3 1428 1432 1627
-3 1432 1621 1627
-3 1621 1432 1421
-3 1628 1430 1891
-3 1430 1629 1891
-3 1423 1431 1630
-3 1425 1630 1431
-3 814 1433 1893
-3 1634 1636 1635
-3 1434 1437 1635
-3 1636 1637 1635
-3 1434 1635 1637
-3 1637 1903 1434
-3 1441 1635 1437
-3 1434 1903 1641
-3 1434 1641 1638
-3 1448 1635 1441
-3 1640 1638 1641
-3 1639 1638 1642
-3 1642 1638 1640
-3 1641 1642 1640
-3 1639 1642 1643
-3 1445 1639 1643
-3 1445 1643 1645
-3 1645 1643 1644
-3 1644 1643 1908
-3 1908 1649 1644
-3 1644 1649 1645
-3 1651 1448 1454
-3 1448 1451 1454
-3 1646 1645 1649
-3 1647 1645 1646
-3 1647 1648 1452
-3 1454 1456 1651
-3 1647 1646 1649
-3 1912 1648 1647
-3 1648 1909 1650
-3 1651 1456 1458
-3 1912 1647 1649
-3 1913 1650 1909
-3 1648 1650 1652
-3 1648 1652 1457
-3 1913 1914 1650
-3 1650 1914 1652
-3 1653 1651 1459
-3 1651 1458 1459
-3 1457 1652 1654
-3 1654 1653 1459
-3 1653 1460 1656
-3 1654 1652 1655
-3 1654 1655 1461
-3 1655 1652 1914
-3 1464 1656 1460
-3 1461 1655 1463
-3 1466 1656 1464
-3 1657 1658 1655
-3 1655 1658 1463
-3 1463 1658 1465
-3 1466 1468 1656
-3 1922 1658 1657
-3 1465 1658 1659
-3 1658 1922 1660
-3 1658 1660 1659
-3 1231 1660 1661
-3 1660 1231 1659
-3 1662 1231 1661
-3 4051 1234 1663
-3 1666 1664 1665
-3 1666 1665 1667
-3 1667 1665 1668
-3 1669 1666 1667
-3 1471 1666 1669
-3 1669 1667 1668
-3 1471 1669 1670
-3 1669 1668 1670
-3 1670 1668 1671
-3 1670 1671 1673
-3 1673 1671 1672
-3 1672 1951 1673
-3 1673 1951 1674
-3 1673 1674 1473
-3 1676 1677 1947
-3 1951 1954 1675
-3 1674 1951 1675
-3 1675 1954 1476
-3 1675 1476 1674
-3 1476 1954 1678
-3 1677 1676 1956
-3 1677 1956 1478
-3 1681 1679 1680
-3 1245 1681 1479
-3 1476 1678 1480
-3 1480 1678 1685
-3 1682 1677 1478
-3 1682 1955 1677
-3 1956 1486 1478
-3 1478 1483 1682
-3 1483 1967 1955
-3 1483 1955 1682
-3 1686 1687 1683
-3 1683 1687 1688
-3 1684 1683 1689
-3 1689 1683 1688
-3 1479 1681 1493
-3 1245 1694 1963
-3 1685 1965 1488
-3 1480 1685 1488
-3 1687 1686 1691
-3 1691 1686 1690
-3 1688 1687 1692
-3 1692 1687 1691
-3 1692 1689 1688
-3 1486 1956 1504
-3 2279 1494 1686
-3 1492 1686 1494
-3 1690 1686 1492
-3 1693 1690 1492
-3 1693 1691 1690
-3 1689 1692 1693
-3 1693 1692 1691
-3 1493 1681 1697
-3 1703 1695 1965
-3 1488 1965 1696
-3 1696 1965 1695
-3 1488 1696 1498
-3 1494 2279 1502
-3 1693 1497 2278
-3 1689 1693 2278
-3 1696 1695 1698
-3 1698 1695 1704
-3 1498 1696 1699
-3 1699 1696 1698
-3 1498 1699 1700
-3 1956 3036 1504
-3 1707 1694 1701
-3 1702 1694 1707
-3 1709 1694 1702
-3 1704 1695 1703
-3 1969 1698 1704
-3 1699 1698 1969
-3 1970 1699 1969
-3 1970 1705 1699
-3 1699 1705 1700
-3 1700 1705 1498
-3 1701 1503 1706
-3 1707 1701 1706
-3 1702 1707 1708
-3 1709 1702 1711
-3 1711 1702 1708
-3 1703 1710 1704
-3 1710 1969 1704
-3 1705 1970 1971
-3 1708 1707 1711
-3 1711 1707 1706
-3 1972 1709 1711
-3 1705 1971 1712
-3 1503 1711 1706
-3 1972 1711 1713
-3 1968 1985 1710
-3 1712 1985 1507
-3 1712 1710 1985
-3 1719 1711 1503
-3 1714 1711 1719
-3 1713 1711 1714
-3 1972 1713 1714
-3 1983 1972 1714
-3 1504 3036 762
-3 3634 1978 1103
-3 1719 1512 1514
-3 1983 1714 1719
-3 1985 1509 1507
-3 1509 1985 1715
-3 1718 1715 1717
-3 1715 1718 1509
-3 1509 1718 1510
-3 4845 762 3036
-3 1724 1511 1716
-3 1983 1719 1725
-3 1715 2000 1717
-3 1718 1717 1720
-3 1721 1718 1720
-3 1718 1721 1510
-3 1722 1724 1716
-3 2000 1730 1717
-3 1720 1717 1730
-3 1721 1720 1726
-3 1722 1723 1724
-3 1719 1514 1727
-3 1725 1719 1727
-3 1728 1725 1727
-3 1516 1726 1720
-3 1721 1726 1516
-3 1729 1728 1731
-3 1731 1728 1727
-3 1516 1720 1521
-3 1720 1730 1521
-3 1514 1731 1727
-3 2008 1729 1731
-3 2008 1731 1732
-3 1733 1735 1730
-3 1521 1730 1735
-3 1516 1521 1520
-3 1733 1738 1734
-3 1735 1733 1734
-3 1289 1732 1731
-3 2021 1732 1289
-3 1738 1736 1737
-3 1734 1738 1739
-3 1735 1734 1739
-3 1735 1739 1522
-3 2023 1746 1736
-3 1741 1736 1746
-3 1737 1736 1741
-3 1738 1737 1742
-3 1742 1737 1741
-3 1739 1738 1743
-3 1743 1738 1742
-3 2034 1739 1743
-3 1522 1739 2034
-3 1744 2028 1526
-3 2028 1745 1526
-3 1527 1526 1745
-3 1749 2021 1753
-3 1751 1746 2023
-3 1746 2032 1742
-3 1746 1742 1741
-3 1743 1742 2032
-3 1528 2028 1744
-3 1528 1747 2028
-3 1526 1528 1744
-3 1748 1530 1745
-3 1745 1530 1527
-3 1746 1751 1752
-3 1530 1747 1528
-3 1748 1747 1530
-3 1753 2021 1773
-3 1749 1753 1754
-3 1750 2031 1755
-3 1751 1750 1756
-3 1756 1750 1755
-3 1757 1752 1756
-3 1756 1752 1751
-3 1531 1128 3731
-3 1759 1760 1761
-3 1759 1763 1762
-3 1761 1763 1759
-3 1753 1773 1300
-3 1754 1753 1764
-3 2045 1754 1765
-3 1765 1754 1764
-3 1755 2031 1768
-3 1768 2031 1767
-3 1756 1755 1769
-3 1769 1755 1768
-3 1770 1757 1756
-3 1769 1770 1756
-3 2034 1758 1533
-3 1301 3731 1128
-3 1759 1771 1760
-3 1762 1771 1759
-3 1772 1771 1762
-3 1763 1772 1762
-3 1764 1753 1774
-3 1765 1764 1774
-3 1779 1765 1774
-3 2025 1765 1779
-3 2046 2025 1779
-3 1766 1781 1775
-3 1788 1766 1775
-3 1767 1766 1788
-3 1768 1767 1776
-3 1776 1767 1788
-3 1769 1768 1777
-3 1777 1768 1776
-3 1770 1769 1778
-3 1778 1769 1777
-3 1533 1770 1778
-3 4845 5643 930
-3 1753 1534 1774
-3 1775 1781 1782
-3 1788 1775 1782
-3 1778 1777 1776
-3 1533 1778 1776
-3 2056 1779 1783
-3 1784 2056 1783
-3 2066 1785 1780
-3 1781 1780 1786
-3 1786 1780 1785
-3 1787 1781 1786
-3 2067 1782 1787
-3 1787 1782 1781
-3 1542 1789 1779
-3 1789 1783 1779
-3 1790 1783 1789
-3 2066 2060 1791
-3 1791 2060 1544
-3 1785 2066 1791
-3 1792 1785 1791
-3 1798 1785 1792
-3 1793 1785 1798
-3 1786 1785 1794
-3 1794 1785 1793
-3 1787 1786 1795
-3 1795 1786 1794
-3 1795 2067 1787
-3 2074 1796 1788
-3 1536 1797 2081
-3 2081 1537 1536
-3 1783 1790 1539
-3 1784 1783 1543
-3 1792 1791 1798
-3 1794 1793 1799
-3 1799 1793 1798
-3 1795 1794 1799
-3 1796 1800 1801
-3 1788 1796 1801
-3 1788 1801 1312
-3 1806 1807 1797
-3 2080 1540 2081
-3 1540 1537 2081
-3 1798 1791 1550
-3 1799 1798 1545
-3 1801 1800 1328
-3 1809 1805 2421
-3 2080 2091 1540
-3 2091 1810 1540
-3 1548 1784 1543
-3 1815 1784 1548
-3 1544 1784 1815
-3 1550 1791 1544
-3 1545 1798 1550
-3 1809 1812 1813
-3 1809 1816 1812
-3 1816 1809 2421
-3 1541 1321 1814
-3 1546 1811 2109
-3 1544 1815 1560
-3 1553 1552 1824
-3 1812 1553 1813
-3 1824 1813 1553
-3 1555 1553 1812
-3 1555 1812 1816
-3 1546 2121 1321
-3 1321 2121 1814
-3 2110 2446 1817
-3 2446 1835 1817
-3 1819 1820 1818
-3 1821 2128 1822
-3 1822 2128 1821
-3 1564 1824 1552
-3 1564 1823 1824
-3 1825 1813 1824
-3 1816 1831 1555
-3 1826 2120 1575
-3 1348 1833 2110
-3 1817 1348 2110
-3 1835 1578 1817
-3 1818 1820 1827
-3 1828 1827 1820
-3 1829 2128 1569
-3 1821 1569 2128
-3 1829 1570 2128
-3 1821 2128 1569
-3 1569 2128 1570
-3 1571 1830 1823
-3 1830 1824 1823
-3 1573 1572 1831
-3 1573 1831 1824
-3 1573 1824 1830
-3 1825 1824 1831
-3 1831 1572 1555
-3 1826 1574 1832
-3 1575 1574 1826
-3 1577 1576 1833
-3 1577 1833 1348
-3 1834 1578 1835
-3 1836 2140 1837
-3 1837 1838 1836
-3 1839 1818 1827
-3 1828 1840 1827
-3 1840 1839 1827
-3 1842 1841 1828
-3 1841 1840 1828
-3 1845 1843 1844
-3 1845 1846 1590
-3 1844 1846 1845
-3 1569 1847 1829
-3 1570 1847 1581
-3 1829 1847 1570
-3 1849 1832 1574
-3 1848 1832 1849
-3 1849 1574 1366
-3 1576 1582 1833
-3 1835 1851 1834
-3 1834 1851 1852
-3 1853 1583 1854
-3 1853 2140 1583
-3 1584 1583 1836
-3 1836 1583 2140
-3 1584 1838 1585
-3 1584 1836 1838
-3 1585 1838 1855
-3 1853 1854 1838
-3 1855 1838 1854
-3 1839 1856 1865
-3 1839 1840 1856
-3 1841 1587 1856
-3 1841 1856 1840
-3 1841 1842 1595
-3 1857 1843 1845
-3 1858 1843 1857
-3 1589 1588 1857
-3 1589 1857 1845
-3 1590 1589 1845
-3 1846 1859 1590
-3 1860 2149 1861
-3 1860 1862 1863
-3 1861 1862 1860
-3 1378 2485 1849
-3 1378 1849 1366
-3 1868 1597 1850
-3 1384 1851 1582
-3 1852 1851 1384
-3 1591 1852 1384
-3 1834 1852 1591
-3 1593 1854 1583
-3 1593 1864 1854
-3 1864 1855 1854
-3 1585 1864 1592
-3 1855 1864 1585
-3 1865 1856 1587
-3 1858 1857 1588
-3 1858 1588 2152
-3 2152 1588 1874
-3 1859 2153 1590
-3 1860 1866 2149
-3 1863 1866 1860
-3 1867 1866 1863
-3 1378 1868 2485
-3 1868 1378 1597
-3 1864 1593 1869
-3 1592 1864 1870
-3 1864 1869 1870
-3 1865 1587 1600
-3 1865 1600 1878
-3 1871 1602 1595
-3 1871 1595 1872
-3 1872 1595 1842
-3 1590 2153 1873
-3 1874 1873 2153
-3 1603 2154 1875
-3 1593 1614 1869
-3 1870 1869 1876
-3 1876 1869 1614
-3 1870 1876 1605
-3 1606 1877 1878
-3 1600 1606 1878
-3 1872 1878 1877
-3 1872 1877 1871
-3 1871 1877 1879
-3 1602 1871 1880
-3 1871 1879 1880
-3 1874 1609 1873
-3 1611 1873 1609
-3 1611 1881 1873
-3 1881 1590 1873
-3 1590 1881 1612
-3 1391 1882 1603
-3 1603 1882 2154
-3 1603 1875 1619
-3 1875 2157 1619
-3 1397 1877 1606
-3 1397 1883 1877
-3 1883 1879 1877
-3 1880 1879 1884
-3 1884 1879 1883
-3 1881 1616 1885
-3 1611 1616 1881
-3 1612 1885 1617
-3 1881 1885 1612
-3 1391 1618 1882
-3 1886 1882 1618
-3 1886 1619 2157
-3 1397 1620 1883
-3 1620 1888 1883
-3 1888 1884 1883
-3 1880 1884 1888
-3 1880 1888 1621
-3 1885 1616 1889
-3 1617 1890 1622
-3 1617 1885 1890
-3 1885 1889 1890
-3 1886 1618 1624
-3 1620 1627 1888
-3 1616 1628 1889
-3 1628 1891 1889
-3 1891 1890 1889
-3 1622 1891 1629
-3 1890 1891 1622
-3 1631 2160 1418
-3 1631 1892 2160
-3 893 2500 1632
-3 1895 1896 1894
-3 1896 1632 1894
-3 1633 1632 1896
-3 1633 1896 2163
-3 2163 2173 1633
-3 1893 1223 2515
-3 1633 2173 1898
-3 1052 1633 1898
-3 2172 1052 1898
-3 1635 1899 1634
-3 1634 1899 1636
-3 1899 1900 1636
-3 1900 1902 1636
-3 1637 1636 1901
-3 1902 1903 1636
-3 1901 1636 1903
-3 1637 1901 1903
-3 1902 1904 1903
-3 1906 1903 1904
-3 1641 1903 1906
-3 1635 1448 2180
-3 1906 1904 1905
-3 1642 1906 1643
-3 1641 1906 1642
-3 1643 1906 1910
-3 1910 1908 1643
-3 1651 2180 1448
-3 1906 1905 1907
-3 1910 1906 1907
-3 2189 1908 1910
-3 1649 1908 1911
-3 1911 1908 2189
-3 1911 1912 1649
-3 1912 1909 1648
-3 1912 1913 1909
-3 2183 1914 1911
-3 1911 1914 1912
-3 1913 1912 1914
-3 1653 2180 1651
-3 1656 2180 1653
-3 1914 1916 1915
-3 1914 1915 1655
-3 4051 2180 1656
-3 1915 1657 1655
-3 1918 2198 1915
-3 1918 1915 1917
-3 1917 1915 1916
-3 1657 1915 2198
-3 2199 1657 2198
-3 1916 1919 1917
-3 1918 1917 1920
-3 1920 1917 1919
-3 1918 1920 1921
-3 1920 2203 1922
-3 1920 1922 1921
-3 1657 1921 1922
-3 1923 1922 2203
-3 1924 1922 1923
-3 1924 1925 1922
-3 1922 1925 1660
-3 1660 1925 1661
-3 1927 1926 1662
-3 1927 1662 1661
-3 1468 4051 1656
-3 2557 2563 1926
-3 1926 2563 1662
-3 1469 1662 2563
-3 1664 1469 2220
-3 2219 1929 1928
-3 1930 1929 2219
-3 1929 1930 1931
-3 1664 2220 1932
-3 1936 1933 1930
-3 1931 1930 1934
-3 1934 1930 1933
-3 1932 1935 1937
-3 1932 1937 1664
-3 1933 1936 1938
-3 1934 1933 1938
-3 2226 1937 1935
-3 1664 1937 1665
-3 2226 1939 1937
-3 1937 1939 1941
-3 1665 1937 1941
-3 1939 1943 1940
-3 1941 1939 1940
-3 1665 1941 1668
-3 1938 1936 1942
-3 1941 1940 1944
-3 1944 1940 1943
-3 1668 1941 1945
-3 1945 1941 1944
-3 1944 1943 1946
-3 1945 1944 1946
-3 1668 1945 2233
-3 2233 1945 1946
-3 1936 3036 1942
-3 1942 3036 1947
-3 1938 1942 1947
-3 2234 2232 1946
-3 2234 1946 1943
-3 2233 2236 1671
-3 2233 1671 1668
-3 1671 2236 2238
-3 1671 2238 1948
-3 1947 3036 1676
-3 1948 2238 1949
-3 1949 2238 1952
-3 1671 1948 1950
-3 1950 1948 1949
-3 1672 1671 1951
-3 1671 1950 1951
-3 1950 1949 1953
-3 1954 1950 1953
-3 1951 1950 1954
-3 1949 1952 2247
-3 1953 1949 2247
-3 2606 1947 1677
-3 1953 1678 1954
-3 1244 1262 1663
-3 2256 1678 1953
-3 2606 1677 1955
-3 2254 1679 1245
-3 1679 1958 1680
-3 1245 1679 1681
-3 2258 1957 1678
-3 2254 1245 1963
-3 2272 2254 1963
-3 1678 1957 1959
-3 1684 2279 1683
-3 1680 1958 1681
-3 2272 1963 1961
-3 2275 1960 2276
-3 1959 2276 1960
-3 1959 1960 1685
-3 1678 1959 1685
-3 1967 1966 1955
-3 1966 2263 1955
-3 1683 2279 1686
-3 1684 1689 2278
-3 1962 1960 2275
-3 1965 1960 1962
-3 1685 1960 1965
-3 1964 1961 1963
-3 2272 1961 1964
-3 1958 1697 1681
-3 1964 1963 1694
-3 2279 1103 1502
-3 1975 2281 1964
-3 1965 1962 1703
-3 1709 1964 1694
-3 1962 2275 1968
-3 1968 2275 1976
-3 1703 1962 1968
-3 2281 1975 1973
-3 1968 1976 1977
-3 1703 1968 1710
-3 1969 1710 1971
-3 1970 1969 1971
-3 1972 1964 1709
-3 1975 1964 1972
-3 1974 1973 1975
-3 1710 1712 1971
-3 1968 1977 1985
-3 1979 1975 1972
-3 1974 1975 1991
-3 1973 1974 1991
-3 2288 1973 1991
-3 2287 2293 1976
-3 1977 1976 1980
-3 1981 1977 1980
-3 1982 1977 1981
-3 1977 1982 1985
-3 1983 1979 1972
-3 1975 1979 1983
-3 1991 1975 1983
-3 1976 2293 1986
-3 1980 1976 1984
-3 1984 1976 1986
-3 1981 1980 1984
-3 1982 1981 1984
-3 2296 2288 1991
-3 1982 1984 1985
-3 1987 1511 1978
-3 2304 1988 2300
-3 1986 2300 1988
-3 2000 1986 1988
-3 1715 1984 2000
-3 1984 1986 2000
-3 1985 1984 1715
-3 1511 1989 1990
-3 1716 1511 1990
-3 1987 1989 1511
-3 1992 2296 1991
-3 1988 2304 1995
-3 1990 1994 1716
-3 1983 1725 1991
-3 1992 1991 2008
-3 2330 2004 2304
-3 1995 2304 2004
-3 2305 2001 1996
-3 1993 2305 1997
-3 1997 2305 1996
-3 1723 1722 1998
-3 1723 1998 1993
-3 1723 1993 1997
-3 1716 1999 1722
-3 1722 1999 1998
-3 1999 1716 1994
-3 1991 1725 1728
-3 2008 1991 1728
-3 1988 1995 2000
-3 1996 2001 2002
-3 2003 1996 2002
-3 1724 2003 2369
-3 1724 1997 2003
-3 1997 1996 2003
-3 1723 1997 1724
-3 1729 2008 1728
-3 2000 1995 2005
-3 2005 1995 2004
-3 2006 2000 2005
-3 2007 2000 2006
-3 1730 2000 2007
-3 2002 2001 2369
-3 2003 2002 2369
-3 2321 1992 2008
-3 2004 2330 2009
-3 2013 2004 2009
-3 2005 2004 2010
-3 2010 2004 2013
-3 2006 2005 2011
-3 2011 2005 2010
-3 2007 2006 2012
-3 2012 2006 2011
-3 1730 2007 2012
-3 2331 2686 1740
-3 2013 2014 2010
-3 2011 2010 2015
-3 2015 2010 2014
-3 2012 2011 1733
-3 1733 2011 2015
-3 1730 2012 1733
-3 2016 2014 2013
-3 2015 2014 1733
-3 1733 2014 2016
-3 2706 2355 2001
-3 2321 2008 2019
-3 2019 2008 1732
-3 2017 2321 2019
-3 2018 1736 2016
-3 1733 1736 1738
-3 1733 2016 1736
-3 2363 2331 1740
-3 2017 2019 2020
-3 2021 2017 2020
-3 2366 2363 1740
-3 2001 2355 2369
-3 2021 2019 1732
-3 2020 2019 2021
-3 2017 2021 1749
-3 2341 2017 2024
-3 2024 2017 1749
-3 2022 2027 2018
-3 2360 2022 2018
-3 2027 2023 2018
-3 2018 2023 1736
-3 1740 2367 2366
-3 2022 2360 2030
-3 2027 2022 2026
-3 1531 2367 1740
-3 1745 2028 2377
-3 2029 1745 2377
-3 2025 2024 1749
-3 2030 2371 2036
-3 2022 2030 2031
-3 2031 2030 2038
-3 2026 2022 2031
-3 1750 2026 2031
-3 1751 2027 1750
-3 2027 2026 1750
-3 2023 2027 1751
-3 2032 2033 1743
-3 2033 2034 1743
-3 2035 1748 2029
-3 2029 1748 1745
-3 2045 2025 1749
-3 1781 2036 2371
-3 2038 2030 2037
-3 1746 1752 2039
-3 2039 2040 1746
-3 1746 2040 2032
-3 2040 2041 2032
-3 2033 2032 2042
-3 2042 2032 2041
-3 2034 2042 1758
-3 2034 2033 2042
-3 2035 1747 1748
-3 2035 2044 1747
-3 2044 2043 1747
-3 1754 2045 1749
-3 2025 2045 1765
-3 2037 2030 2047
-3 2047 2030 2036
-3 2038 2037 1766
-3 1766 2037 2047
-3 2048 2038 1766
-3 2031 2038 2048
-3 1752 1757 2049
-3 1752 2049 2050
-3 1752 2050 2039
-3 2050 2051 2052
-3 2050 2052 2039
-3 2039 2052 2040
-3 2041 2040 2053
-3 2053 2040 2052
-3 1758 2042 2053
-3 2042 2041 2053
-3 1761 1760 2054
-3 1761 2055 1763
-3 2054 2055 1761
-3 1784 2046 2056
-3 1781 2379 2061
-3 2061 2379 2057
-3 1766 2036 1781
-3 2047 2036 1766
-3 1767 2048 1766
-3 2031 2048 1767
-3 2058 2049 1757
-3 2058 1757 2059
-3 2059 1757 1770
-3 2051 2058 2059
-3 2052 2051 2059
-3 2052 2059 1533
-3 1758 2052 1533
-3 2053 2052 1758
-3 1760 1771 2054
-3 1772 2054 1771
-3 2055 2054 1772
-3 1763 2055 1772
-3 2056 2046 1779
-3 2046 1784 2060
-3 1533 2059 1770
-3 2057 2060 2066
-3 2061 2057 2062
-3 2062 2057 2066
-3 1781 2061 1780
-3 1780 2061 2062
-3 2063 2064 2065
-3 2060 1784 1544
-3 1780 2062 2066
-3 2067 2071 1782
-3 1782 2071 1788
-3 2071 2074 1788
-3 2063 2068 2064
-3 2067 1795 2069
-3 2071 2067 2070
-3 2070 2067 2069
-3 2411 2072 2071
-3 2073 2071 2072
-3 2074 2071 2073
-3 2075 2094 2076
-3 2075 2077 2078
-3 2076 2077 2075
-3 2077 2402 2078
-3 1797 2080 2081
-3 2079 2080 1797
-3 2082 2419 2407
-3 1795 1799 2069
-3 1808 2069 1799
-3 2070 2069 1808
-3 2070 1808 2071
-3 2072 2071 1328
-3 2071 1808 1328
-3 1800 2072 1328
-3 2073 2072 1800
-3 2074 2073 1800
-3 1796 2074 1800
-3 2083 2094 2075
-3 1802 1803 2083
-3 1802 2083 2078
-3 2078 2083 2075
-3 1802 2402 1804
-3 1802 2078 2402
-3 2084 2085 1805
-3 2086 2088 2089
-3 2089 1807 1806
-3 2089 2088 1807
-3 2088 2090 1807
-3 1797 1807 2090
-3 1797 2090 2091
-3 1797 2091 2079
-3 2429 2091 2090
-3 2080 2079 2091
-3 2092 2419 2082
-3 2092 2082 2407
-3 4422 1524 1287
-3 2093 2094 2083
-3 1803 2093 2083
-3 1803 2095 2093
-3 1804 1803 1802
-3 2084 1805 1809
-3 2096 2087 2086
-3 2089 2097 2086
-3 2097 2096 2086
-3 1806 1810 2098
-3 1806 2098 2089
-3 2089 2098 2097
-3 2091 2429 2099
-3 2091 2099 1810
-3 2098 1810 2099
-3 2443 1538 1541
-3 1811 2443 2108
-3 1811 1538 2443
-3 2101 2419 2092
-3 2124 2419 2101
-3 2102 2101 2092
-3 2103 2094 2093
-3 2104 2094 2103
-3 2105 2093 2095
-3 2103 2093 2105
-3 1813 2106 2107
-3 1813 2107 1809
-3 1809 2107 2084
-3 2099 2097 2098
-3 1814 2443 1541
-3 2108 2109 1811
-3 2447 2123 2100
-3 2123 2111 2100
-3 2124 2101 2112
-3 2101 2102 2112
-3 2113 2112 2102
-3 2102 2125 2113
-3 2103 2116 2104
-3 2105 2116 2103
-3 2106 1813 2117
-3 2118 2107 2106
-3 2118 2106 2119
-3 2119 2106 2117
-3 2119 1816 2118
-3 1816 2421 2118
-3 2819 1826 1832
-3 2120 1826 2819
-3 1546 2109 2130
-3 2446 2131 1835
-3 2111 2122 2458
-3 2111 2123 2122
-3 1819 1818 2124
-3 1819 2124 2112
-3 1819 2112 2113
-3 2113 2125 1819
-3 1819 2125 1820
-3 2114 2115 2126
-3 2127 2126 2115
-3 2117 1825 2129
-3 1813 1825 2117
-3 1816 2129 1831
-3 1816 2119 2129
-3 2119 2117 2129
-3 1546 2130 2121
-3 2123 2458 2122
-3 2132 2458 2123
-3 1818 2133 2124
-3 2142 1828 1820
-3 2142 1820 2125
-3 2127 2134 2126
-3 2134 2135 2136
-3 2134 2127 2135
-3 2137 2135 2127
-3 2135 2138 2139
-3 2137 2138 2135
-3 2138 2144 2139
-3 1825 1831 2129
-3 1850 1575 2120
-3 1837 2140 1838
-3 2133 1818 1839
-3 2133 1839 2146
-3 1842 2142 2141
-3 1842 1828 2142
-3 2136 2135 2143
-3 2135 2139 2143
-3 1843 2144 1844
-3 1843 2139 2144
-3 1843 2143 2139
-3 1844 2144 2480
-3 1846 1844 2480
-3 1832 1848 2484
-3 1582 2476 1833
-3 2476 1851 2131
-3 2476 1582 1851
-3 1835 2131 1851
-3 1838 2140 1853
-3 1865 2145 2146
-3 1839 1865 2146
-3 2142 2146 2145
-3 2142 2145 2141
-3 2141 2145 2151
-3 2141 2151 1842
-3 2143 1843 1858
-3 2143 1858 2479
-3 2148 2479 1858
-3 1846 2148 2147
-3 1846 2147 2153
-3 1846 2153 1859
-3 1861 2150 1862
-3 2149 2150 1861
-3 1862 2150 1863
-3 1849 2484 1848
-3 1849 2485 2484
-3 1850 2156 1868
-3 1865 2151 2145
-3 1842 2151 1872
-3 2152 2148 1858
-3 2152 2147 2148
-3 2153 2147 2152
-3 1867 2149 1866
-3 2150 2149 1867
-3 1863 2150 1867
-3 2154 2485 1868
-3 2154 1868 2155
-3 1868 2156 2155
-3 1878 2151 1865
-3 1878 1872 2151
-3 2153 2152 1874
-3 2155 1875 2154
-3 2155 2156 1875
-3 2156 2157 1875
-3 2490 2489 1882
-3 2489 2154 1882
-3 1882 1886 2490
-3 2158 2490 1886
-3 2157 2158 1886
-3 2492 2493 1887
-3 1887 2493 1626
-3 2159 1887 1418
-3 1418 2160 2159
-3 1892 2889 2160
-3 2889 1892 1626
-3 2500 2906 1632
-3 1894 2162 1895
-3 2162 1896 1895
-3 2163 1896 2507
-3 2163 2508 2164
-3 2507 2508 2163
-3 2508 2165 2164
-3 1897 2166 2161
-3 2167 1897 2161
-3 3403 1893 2515
-3 1894 1632 2504
-3 1632 2168 2504
-3 2504 2162 1894
-3 2169 2163 2164
-3 2169 2173 2163
-3 2165 2169 2164
-3 1897 2171 2166
-3 1897 2170 2171
-3 1897 2167 2170
-3 2170 2167 2172
-3 2161 2172 2167
-3 2172 2161 2515
-3 1898 2173 2915
-3 2171 2170 1898
-3 2171 1898 2915
-3 2172 1898 2170
-3 1052 2515 1223
-3 2172 2515 1052
-3 1635 2174 1899
-3 1899 2174 1900
-3 2174 2175 1900
-3 1902 1900 2175
-3 1902 1905 1904
-3 1905 2176 1907
-3 1907 2176 2177
-3 2178 1907 2177
-3 1910 1907 2179
-3 1907 2178 2179
-3 2181 2182 2176
-3 2176 2182 2177
-3 2521 2178 2182
-3 2182 2178 2177
-3 2178 2521 2179
-3 2191 2179 2521
-3 1910 2191 2189
-3 2179 2191 1910
-3 2184 2182 2181
-3 2185 2182 2184
-3 2521 2182 2186
-3 2186 2182 2185
-3 2521 2186 2191
-3 2189 2187 1911
-3 1911 2187 2183
-3 2187 2188 2183
-3 2183 2188 1914
-3 2184 2181 2525
-3 2185 2184 2525
-3 2523 2185 2525
-3 2186 2185 2523
-3 2187 2189 2190
-3 2188 2187 2190
-3 2188 2190 1914
-3 2191 2192 2189
-3 2190 2189 2193
-3 2193 2189 2192
-3 2196 2190 2193
-3 1914 2190 2196
-3 2192 2191 2194
-3 2194 2193 2192
-3 2194 2196 2193
-3 2196 2194 2195
-3 2196 2197 1914
-3 1914 2197 2200
-3 1914 2200 1916
-3 2196 2200 2197
-3 1916 2200 1919
-3 1921 2198 1918
-3 2199 2198 1921
-3 1657 2199 1921
-3 1919 2200 2201
-3 1919 2202 1920
-3 2201 2202 1919
-3 1920 2202 2203
-3 2201 2200 2204
-3 2202 2201 2203
-3 2201 2204 2203
-3 2203 2204 1923
-3 1923 2205 1924
-3 2962 1924 2205
-3 2962 2546 1924
-3 1925 1924 2546
-3 2204 2206 2207
-3 1923 2204 2208
-3 2208 2204 2207
-3 2209 2962 2205
-3 2209 2205 2208
-3 2208 2205 1923
-3 1925 2546 1661
-3 2546 2549 1661
-3 2208 2207 2210
-3 1926 2209 2208
-3 1926 2208 2210
-3 1927 2549 1926
-3 1926 2549 2209
-3 2549 1927 1661
-3 2210 2207 2557
-3 2210 2557 1926
-3 2574 2563 2562
-3 2563 2574 1469
-3 2213 2212 2217
-3 2212 2213 2211
-3 2211 2213 2214
-3 2214 2212 2211
-3 1469 2574 2220
-3 2215 2213 2217
-3 2214 2213 2216
-3 2216 2213 2215
-3 2216 2572 2214
-3 2215 2217 1928
-3 1928 2218 2215
-3 2218 2216 2215
-3 2218 2572 2216
-3 2217 2219 1928
-3 2218 1929 1931
-3 1928 1929 2218
-3 1931 2572 2218
-3 1930 2219 2217
-3 2220 2226 1932
-3 1930 2217 1936
-3 2220 2574 2221
-3 1932 2226 2222
-3 1932 2222 1935
-3 2220 2221 2224
-3 2224 2221 2223
-3 2226 2220 2225
-3 2225 2220 2224
-3 2222 2226 1935
-3 2224 2223 2227
-3 2225 2224 2228
-3 2228 2224 2227
-3 2226 2225 1939
-3 1939 2225 2228
-3 2227 2579 2230
-3 2227 2230 2228
-3 1943 1939 2230
-3 1939 2228 2230
-3 1934 1938 2587
-3 2582 2229 2579
-3 2230 2579 2229
-3 2582 2231 2229
-3 2229 2231 2234
-3 2230 2229 2234
-3 1943 2230 2234
-3 2232 2233 1946
-3 2587 1938 1947
-3 2234 2235 2232
-3 2235 2236 2232
-3 2233 2232 2236
-3 2234 2231 2237
-3 2234 2237 2240
-3 2235 2234 2238
-3 2238 2234 2240
-3 2236 2235 2238
-3 2240 2237 2239
-3 2237 2231 2245
-3 2245 2231 2586
-3 2239 2237 2245
-3 2240 2239 2241
-3 2238 2240 2244
-3 2244 2240 2241
-3 2239 2245 2242
-3 2241 2239 2242
-3 2244 2241 2242
-3 2238 2244 1952
-3 2242 2245 2243
-3 2246 2242 2243
-3 2244 2242 2246
-3 2587 1947 2606
-3 2245 2586 2249
-3 2244 2246 2250
-3 1952 2244 2247
-3 2244 2250 2247
-3 2247 2248 1953
-3 2243 2245 2249
-3 2246 2243 2250
-3 2250 2243 2249
-3 2247 2250 2251
-3 2252 2247 2251
-3 2248 2247 2253
-3 2253 2247 2252
-3 2248 2253 1953
-3 1676 3036 1956
-3 2250 2249 2605
-3 2615 2250 2605
-3 2251 2250 2615
-3 2251 2615 2255
-3 2251 2255 2252
-3 2253 2252 2256
-3 2256 2252 2255
-3 2253 2256 1953
-3 2258 2255 2615
-3 2256 2255 2258
-3 1955 2257 2606
-3 2254 2601 1679
-3 2256 2258 1678
-3 1679 2601 1958
-3 1958 2601 2265
-3 2615 2261 2258
-3 2258 2261 2262
-3 2257 1955 2263
-3 2259 2254 2272
-3 2272 2273 2260
-3 2260 2273 2266
-3 2274 2260 2266
-3 2267 2268 2269
-3 2262 2261 2269
-3 2258 2262 2270
-3 2258 2270 1957
-3 2264 2279 2271
-3 2279 1684 2271
-3 2278 2271 1684
-3 2266 2273 2274
-3 2262 2269 2275
-3 2270 2262 2276
-3 2276 2262 2275
-3 1957 2276 1959
-3 2270 2276 1957
-3 2274 2273 2272
-3 2269 2268 2280
-3 2263 1966 2277
-3 2272 1964 2274
-3 2268 2267 2280
-3 2275 2269 2280
-3 1966 2648 2277
-3 2280 2267 2653
-3 1958 2265 1697
-3 2281 2274 1964
-3 1967 2648 1966
-3 2288 2274 2281
-3 2275 2280 2282
-3 2279 3634 1103
-3 2282 2280 2283
-3 2275 2282 2287
-3 2275 2287 1976
-3 2288 2281 1973
-3 2288 2658 2274
-3 2282 2283 2285
-3 2285 2283 2284
-3 2287 2282 2286
-3 2286 2282 2285
-3 2290 2284 2662
-3 2284 2290 2285
-3 2286 2285 2291
-3 2291 2285 2290
-3 2287 2286 2292
-3 2292 2286 2291
-3 2287 2292 2293
-3 3634 2294 1978
-3 1978 2294 2295
-3 2289 2288 2297
-3 2299 2289 2297
-3 2293 2292 2291
-3 2295 2294 2301
-3 2288 2296 2303
-3 2297 2288 2303
-3 2299 2297 2298
-3 2291 2290 2300
-3 2293 2300 1986
-3 2291 2300 2293
-3 2688 2307 2668
-3 2668 2307 2676
-3 2295 2301 2302
-3 1978 2302 1987
-3 2295 2302 1978
-3 1992 2303 2296
-3 2298 2297 2313
-3 2299 2298 2313
-3 2691 2299 2313
-3 2300 2685 2304
-3 2307 2688 2305
-3 2305 2688 2706
-3 2306 2307 2305
-3 2302 2301 3172
-3 3172 1987 2302
-3 1989 1987 3172
-3 2297 2303 2308
-3 2313 2297 2321
-3 2321 2297 2308
-3 2305 2706 2001
-3 2306 2305 1993
-3 1998 2306 1993
-3 1998 2310 2306
-3 2310 2307 2306
-3 2310 2317 2307
-3 1990 1989 1994
-3 1994 1989 3172
-3 1992 2308 2303
-3 2321 2308 1992
-3 2691 2313 2314
-3 2328 2315 2309
-3 2316 2309 2315
-3 2304 2309 2316
-3 2310 1998 1999
-3 2310 1999 2317
-3 1999 1994 2318
-3 2324 1994 3172
-3 2318 1994 2324
-3 2312 2320 2311
-3 2320 2319 2311
-3 2339 2315 2328
-3 2304 2316 2330
-3 2330 2316 2322
-3 1999 2323 2317
-3 2318 2323 1999
-3 2324 2323 2318
-3 2320 2325 2319
-3 2313 2321 2326
-3 2314 2313 2333
-3 2333 2313 2326
-3 2334 2314 2333
-3 2327 2314 2334
-3 2315 2339 2345
-3 2316 2315 2345
-3 2329 2316 2345
-3 2322 2316 2330
-3 2330 2316 2329
-3 2326 2321 2017
-3 2333 2326 2332
-3 2721 2327 2334
-3 2336 2335 2328
-3 2335 2337 2328
-3 2337 2338 2328
-3 2339 2328 2338
-3 2329 2345 2346
-3 2009 2330 2329
-3 2332 2326 2341
-3 2341 2326 2017
-3 2333 2332 2341
-3 2334 2333 2341
-3 2715 2342 2336
-3 2336 2342 2335
-3 2337 2335 2343
-3 2343 2335 2342
-3 2339 2338 2344
-3 2345 2339 2344
-3 2346 2345 2350
-3 2009 2329 2346
-3 2346 2013 2009
-3 2706 2340 2355
-3 2355 2340 2347
-3 2344 2338 2349
-3 2345 2344 2361
-3 2361 2350 2345
-3 2013 2346 2742
-3 2744 2013 2742
-3 2362 2013 2744
-3 2013 2362 2016
-3 2351 2352 2353
-3 2353 2354 2351
-3 2369 2355 2730
-3 2347 2730 2355
-3 2739 2348 2370
-3 2740 2370 2356
-3 2342 2715 2357
-3 2357 2715 2356
-3 2337 2343 2364
-3 2338 2337 2358
-3 2358 2337 2364
-3 2349 2338 2359
-3 2359 2338 2358
-3 2344 2349 2360
-3 2360 2349 2359
-3 2360 2361 2344
-3 2362 2744 2755
-3 2016 2362 2018
-3 2331 2363 2738
-3 2756 2738 2363
-3 2343 2342 2371
-3 2364 2343 2371
-3 2359 2358 2030
-3 2360 2359 2030
-3 2361 2360 2365
-3 2365 2018 2755
-3 2362 2755 2018
-3 2366 2756 2363
-3 2348 2334 2341
-3 2370 2348 2341
-3 2357 2356 2371
-3 2342 2357 2371
-3 2358 2364 2030
-3 2030 2364 2371
-3 2018 2365 2360
-3 2761 2366 2367
-3 1531 2368 2367
-3 2372 2373 2374
-3 2374 2375 2372
-3 2025 2341 2024
-3 2372 2376 2373
-3 2375 2376 2372
-3 2046 2341 2025
-3 2370 2341 2046
-3 2356 2370 2046
-3 2028 1747 2767
-3 2377 2028 2767
-3 2035 2377 2378
-3 2035 2029 2377
-3 2371 2356 2046
-3 2379 2371 2046
-3 2381 2380 1747
-3 2380 2767 1747
-3 1747 2043 2381
-3 2378 2043 2044
-3 2381 2043 2378
-3 2035 2378 2044
-3 2379 2046 2057
-3 1781 2371 2379
-3 2382 2384 2385
-3 2385 2050 2049
-3 2385 2384 2050
-3 2384 2386 2050
-3 2386 2051 2050
-3 2381 2387 2380
-3 2388 2387 2381
-3 2378 2388 2381
-3 2389 2383 2382
-3 2390 2383 2389
-3 2385 2391 2382
-3 2391 2389 2382
-3 2049 2058 2392
-3 2049 2392 2385
-3 2385 2392 2391
-3 2058 2789 2392
-3 2058 2051 2789
-3 2051 2386 2789
-3 2057 2046 2060
-3 2389 2393 2390
-3 2391 2393 2389
-3 2789 2391 2392
-3 2394 2398 2395
-3 2065 2799 2396
-3 2064 2799 2065
-3 2396 2063 2065
-3 2395 2397 2394
-3 2398 2397 2395
-3 2397 2399 2400
-3 2398 2399 2397
-3 2399 2401 2400
-3 2077 2814 3259
-3 3259 2402 2077
-3 2064 2403 2799
-3 2068 2403 2064
-3 2396 2404 2063
-3 2063 2404 2068
-3 2068 2404 2403
-3 2396 2418 2404
-3 2801 2406 2405
-3 2394 2397 2408
-3 2409 2408 2397
-3 2409 2400 2410
-3 2409 2397 2400
-3 2401 2410 2400
-3 2076 2813 2412
-3 2094 2813 2076
-3 2814 2077 2412
-3 2412 2077 2076
-3 2804 2815 2402
-3 2413 2414 2415
-3 2817 2414 2413
-3 2404 2417 2403
-3 2417 2404 2416
-3 2418 2416 2404
-3 2405 2406 2419
-3 2407 2419 2406
-3 2072 2411 2071
-3 2420 2813 2094
-3 1804 2815 2827
-3 2402 2815 1804
-3 2084 2829 2085
-3 1805 2085 2817
-3 2085 2829 2817
-3 2817 2413 1805
-3 2421 1805 2413
-3 2421 2413 2415
-3 2118 2421 2415
-3 2422 2424 2425
-3 2423 2424 2422
-3 2425 2424 2426
-3 2426 2086 2087
-3 2426 2424 2086
-3 2424 2428 2086
-3 2427 2088 2428
-3 2088 2086 2428
-3 2088 2429 2090
-3 2427 2429 2088
-3 2416 2430 2417
-3 2433 2434 2824
-3 2824 2435 2433
-3 2844 2092 2407
-3 2420 2094 2436
-3 2095 1803 2437
-3 2095 2437 2420
-3 2095 2420 2436
-3 2827 2437 1804
-3 2437 1803 1804
-3 2422 2425 2440
-3 2426 2440 2425
-3 2087 2096 2440
-3 2426 2087 2440
-3 2441 2427 2428
-3 2429 2427 2442
-3 2442 2427 2441
-3 2429 2442 2099
-3 2444 2445 2833
-3 2432 2444 2833
-3 2432 2431 2444
-3 2431 2110 2444
-3 2446 2110 2431
-3 2100 2434 2433
-3 2100 2111 2434
-3 2433 2435 2447
-3 2433 2447 2100
-3 2864 2419 2124
-3 2102 2092 2844
-3 2436 2104 2448
-3 2094 2104 2436
-3 2095 2448 2105
-3 2436 2448 2095
-3 2829 2107 2118
-3 2829 2084 2107
-3 2853 2438 1832
-3 2819 1832 2438
-3 2096 2839 2440
-3 2441 2839 2097
-3 2839 2096 2097
-3 2099 2441 2097
-3 2442 2441 2099
-3 2443 1814 2449
-3 2108 2443 2449
-3 2109 2108 2450
-3 2450 2854 2109
-3 2110 1833 2445
-3 2110 2445 2444
-3 2131 2446 2457
-3 2111 2451 2452
-3 2123 2843 2451
-3 2123 2447 2843
-3 2452 2451 2843
-3 2102 2453 2125
-3 2102 2844 2453
-3 2849 2455 2114
-3 2454 2455 2849
-3 2115 2114 2456
-3 2114 2455 2456
-3 2104 2116 2448
-3 2105 2448 2116
-3 2819 2439 2120
-3 2109 2467 2130
-3 2467 2109 2854
-3 2458 2451 2111
-3 2123 2451 2132
-3 2132 2451 2458
-3 2849 2114 2459
-3 2114 2126 2459
-3 2115 2456 2470
-3 2127 2115 2470
-3 2462 2463 2464
-3 2464 2465 2462
-3 1832 2868 2853
-3 2130 2466 2121
-3 2467 2466 2130
-3 2133 2864 2124
-3 2133 2468 2469
-3 2133 2469 2864
-3 2468 2125 2469
-3 2468 2142 2125
-3 2134 2459 2126
-3 2134 2136 2470
-3 2137 2127 2470
-3 2137 2471 2138
-3 2470 2471 2137
-3 2138 2471 2144
-3 2472 2461 2460
-3 2473 2472 2460
-3 2474 2475 2463
-3 2483 2462 2465
-3 2483 2474 2462
-3 2463 2462 2474
-3 2439 1850 2120
-3 2476 2131 2457
-3 2146 2468 2133
-3 2146 2477 2468
-3 2142 2468 2477
-3 2143 2470 2136
-3 2143 2478 2470
-3 2478 2471 2470
-3 2144 2471 2479
-3 2471 2478 2479
-3 2479 2480 2144
-3 2473 2481 2472
-3 2481 2865 2472
-3 2481 2473 2482
-3 2474 2483 2475
-3 2868 1832 2484
-3 423 4373 893
-3 2142 2477 2146
-3 2479 2478 2143
-3 2480 2479 2148
-3 1846 2480 2148
-3 2865 2481 2487
-3 2482 2488 2481
-3 2488 2487 2481
-3 2439 2156 1850
-3 2489 2485 2154
-3 2489 2490 2158
-3 2156 2486 2157
-3 2486 2158 2157
-3 2881 2491 2492
-3 2493 2492 2491
-3 2492 1887 2881
-3 2493 2889 1626
-3 2494 2496 2497
-3 2495 2496 2494
-3 2496 2498 2497
-3 814 1893 4422
-3 2159 2881 1887
-3 2499 2881 2159
-3 2160 2499 2159
-3 2499 2160 2889
-3 2494 2497 2892
-3 2892 2497 2498
-3 893 4373 2500
-3 2900 2906 2500
-3 2161 2501 2901
-3 2901 2502 2161
-3 2899 2162 2904
-3 2899 1896 2162
-3 2507 1896 2899
-3 2501 2161 2503
-3 1632 2906 2910
-3 2910 2168 1632
-3 2505 2162 2506
-3 2505 2903 2162
-3 2904 2162 2903
-3 2161 2166 2503
-3 2166 2512 2503
-3 2161 2502 2515
-3 2515 2502 3945
-3 2506 2162 2504
-3 2506 2504 2513
-3 2513 2509 2506
-3 2510 2506 2509
-3 2510 2511 2507
-3 2508 2507 2511
-3 2508 2511 2169
-3 2165 2508 2169
-3 2171 2512 2166
-3 2510 2509 2513
-3 2514 2510 2513
-3 2511 2510 2514
-3 2169 2511 2514
-3 2173 2169 2514
-3 2512 2171 2915
-3 2915 2173 2514
-3 1635 2919 2174
-3 2175 2174 2518
-3 2919 2517 2174
-3 2517 2518 2174
-3 2175 2518 1902
-3 2519 2518 2517
-3 2518 2519 1902
-3 2519 2520 1902
-3 1902 2520 1905
-3 1905 2520 2176
-3 2520 2522 2176
-3 2181 2176 2522
-3 2181 2522 2525
-3 2186 2523 2191
-3 2523 2525 2524
-3 2191 2523 2531
-3 2523 2524 2531
-3 2526 2525 2522
-3 2527 2524 2525
-3 2191 2531 2194
-3 2528 2525 2526
-3 2529 2528 2526
-3 2530 2527 2525
-3 2528 2530 2525
-3 2532 2533 2194
-3 2532 2194 2531
-3 2943 2194 2533
-3 2195 2194 2943
-3 2531 2534 2535
-3 2532 2531 2536
-3 2536 2531 2535
-3 2536 2537 2532
-3 2538 2195 2943
-3 2946 2538 2943
-3 2196 2195 2538
-3 2948 2535 2534
-3 2536 2535 2948
-3 2949 2536 2948
-3 2537 2536 2949
-3 2946 2541 2538
-3 2538 2961 2196
-3 2540 2542 2539
-3 2539 2542 2543
-3 2541 2539 2543
-3 2541 2961 2538
-3 2961 2200 2196
-3 2544 2543 2542
-3 2955 2541 2544
-3 2544 2541 2543
-3 2961 2541 2955
-3 2545 2200 2961
-3 2200 2545 2204
-3 2545 2547 2548
-3 2551 2545 2548
-3 2204 2545 2551
-3 2206 2204 2551
-3 2209 2964 2962
-3 2546 2964 2549
-3 2548 2547 2551
-3 2551 2554 2206
-3 2554 2207 2206
-3 2964 2209 2549
-3 2551 2547 2552
-3 2553 2551 2552
-3 2554 2551 2553
-3 2977 2207 2554
-3 2550 2560 2547
-3 2552 2547 2560
-3 2553 2552 2555
-3 2554 2553 2556
-3 2556 2553 2555
-3 2557 2554 2556
-3 2977 2557 2207
-3 2555 2552 2561
-3 2561 2552 2560
-3 2556 2555 2562
-3 2562 2555 2561
-3 2557 2556 2563
-3 2563 2556 2562
-3 2558 2981 2564
-3 2558 2564 2565
-3 2568 2564 2981
-3 2565 2564 2566
-3 2566 2564 2568
-3 2561 2560 2571
-3 2562 2561 2571
-3 2981 3496 2567
-3 2981 2567 2568
-3 2994 2571 2560
-3 2569 2567 3496
-3 2568 2567 2570
-3 2570 2567 2569
-3 2572 2566 2568
-3 2570 2572 2568
-3 2212 2569 3496
-3 2570 2569 2572
-3 2572 2569 2212
-3 2574 2571 2573
-3 2571 2574 2562
-3 2212 3496 2217
-3 2212 2214 2572
-3 2997 2573 2571
-3 2217 3496 1936
-3 3004 2573 2997
-3 1262 4051 1663
-3 2572 1931 4052
-3 2574 2575 2221
-3 1931 1934 4052
-3 2575 2574 2223
-3 2575 2223 2221
-3 2576 2573 2578
-3 2574 2573 2576
-3 2223 2574 2577
-3 2577 2574 2576
-3 2223 2577 2227
-3 4052 1934 2587
-3 2582 2576 2578
-3 2577 2576 2582
-3 2577 2582 2227
-3 2580 2578 3004
-3 2582 2578 2581
-3 2581 2578 2580
-3 2579 2227 2582
-3 2581 2580 3010
-3 2582 2581 2583
-3 3010 2580 2585
-3 3010 2231 2583
-3 2582 2583 2231
-3 2580 2584 2585
-3 2585 2231 3010
-3 2586 2585 3014
-3 2231 2585 2586
-3 3026 2592 3014
-3 2586 3014 2592
-3 2589 2590 2591
-3 2588 2587 2600
-3 2589 2593 2594
-3 2590 2589 2594
-3 2591 2590 2597
-3 2599 2586 2592
-3 2586 2599 2249
-3 2600 2587 2606
-3 3533 2254 2593
-3 2594 2593 2596
-3 2596 2593 2254
-3 2590 2594 2597
-3 2597 2594 2596
-3 2595 2591 2598
-3 2610 2592 3527
-3 2592 2610 2604
-3 2599 2592 2604
-3 2601 2254 3533
-3 2254 2597 2596
-3 2591 2597 2607
-3 2598 2591 2608
-3 2602 2598 2608
-3 2608 2598 2602
-3 2603 2595 2598
-3 2249 2599 2605
-3 2599 2604 2605
-3 2588 2600 2618
-3 2618 2600 2606
-3 2607 2597 2254
-3 2591 2607 2608
-3 2603 2598 2609
-3 2609 2621 2603
-3 2604 2612 2613
-3 2604 2613 2605
-3 2614 2605 2613
-3 2615 2605 2614
-3 2606 2257 2617
-3 2617 2257 2616
-3 2618 2606 2617
-3 2620 2607 2254
-3 2608 2607 2259
-3 2259 2607 2620
-3 2609 2598 2608
-3 2622 2610 2611
-3 2604 2610 2623
-3 2623 2610 2622
-3 2624 2604 2623
-3 2612 2625 2613
-3 2613 2625 2626
-3 2614 2613 2626
-3 2615 2614 2627
-3 2627 2614 2626
-3 2617 2616 2628
-3 2618 2617 2631
-3 2631 2617 2628
-3 2644 2618 2631
-3 2601 2619 2265
-3 2259 2620 2254
-3 2272 2608 2259
-3 2260 2608 2272
-3 2621 2609 2608
-3 2629 2624 2623
-3 2267 2625 2633
-3 2626 2625 2269
-3 2269 2625 2267
-3 2261 2626 2269
-3 2627 2626 2261
-3 2615 2627 2261
-3 2257 2263 2616
-3 2628 2616 2630
-3 2630 2616 2263
-3 2631 2628 2630
-3 3055 2264 2271
-3 3587 3055 2271
-3 2260 2274 2608
-3 2640 2629 2623
-3 2635 2636 3073
-3 2637 2630 2263
-3 2631 2630 2637
-3 2644 2631 2637
-3 2264 3055 2279
-3 3587 2271 2278
-3 2639 2621 2608
-3 2632 2621 2639
-3 2645 2632 2639
-3 2623 2622 2640
-3 2634 2642 2641
-3 2634 2641 2633
-3 2633 2641 2267
-3 2635 2643 2636
-3 3073 2643 2635
-3 2263 2277 2637
-3 2645 2639 2608
-3 2637 2277 2648
-3 2644 2637 2648
-3 2646 2265 2619
-3 2645 2608 2658
-3 2645 2649 2651
-3 2647 2622 2652
-3 2640 2622 2647
-3 2641 2640 2650
-3 2267 2641 2650
-3 2658 2608 2274
-3 2650 2640 2653
-3 2267 2650 2653
-3 1697 2265 2646
-3 2649 2645 2658
-3 3110 2654 2652
-3 2640 2647 2652
-3 2659 2652 2654
-3 2640 2652 2659
-3 2653 2640 2659
-3 2653 2655 2280
-3 2651 2649 2658
-3 3110 2661 2654
-3 2655 2653 2659
-3 2280 2655 2283
-3 2655 2659 2656
-3 2657 2655 2656
-3 2283 2655 2657
-3 2648 1967 3095
-3 3106 2651 2658
-3 2660 2661 3110
-3 2284 2657 2656
-3 2283 2657 2284
-3 2675 3095 1967
-3 3634 2669 2294
-3 2288 2289 2658
-3 2654 2661 2659
-3 2284 2656 2659
-3 2668 2669 3121
-3 3106 2658 2289
-3 2670 3106 2289
-3 2659 2662 2284
-3 2659 2673 2662
-3 2663 2664 2665
-3 2663 2666 2667
-3 2665 2666 2663
-3 2681 2670 2289
-3 3144 2670 2671
-3 2672 2661 2660
-3 2683 2661 2672
-3 3162 2659 2661
-3 3163 2659 3162
-3 2659 3163 2673
-3 2674 2662 2673
-3 2685 2662 2674
-3 2290 2662 2685
-3 2686 2675 1967
-3 2668 3121 2688
-3 2676 3154 2669
-3 2676 2669 2668
-3 3154 2294 2669
-3 3154 2677 2294
-3 2677 2301 2294
-3 2678 2679 2680
-3 2671 2670 2691
-3 2691 2670 2681
-3 2682 2671 2691
-3 3144 2671 2682
-3 2692 3144 2682
-3 2673 3163 2684
-3 2674 2673 2684
-3 2685 2674 2684
-3 2300 2290 2685
-3 2675 2686 2687
-3 2698 2675 2687
-3 2689 2301 2677
-3 2690 2679 2678
-3 2680 2690 2678
-3 2299 2691 2289
-3 2691 2681 2289
-3 2692 2682 2701
-3 3169 2694 3137
-3 2705 3137 2694
-3 2683 2672 2696
-3 2696 2672 2695
-3 2697 2683 2696
-3 2683 2697 3162
-3 2697 2304 3162
-3 2684 3162 2304
-3 2685 2684 2304
-3 2698 2687 2686
-3 2307 3164 2676
-3 2689 3172 2301
-3 2719 2679 2690
-3 2699 2719 2690
-3 2680 2700 2690
-3 2700 2699 2690
-3 2682 2691 2711
-3 2701 2693 2692
-3 2703 3159 2702
-3 2694 3169 2715
-3 2705 2694 2725
-3 3179 2696 2695
-3 2309 2696 2328
-3 2697 2696 2309
-3 2304 2697 2309
-3 2331 2698 2686
-3 2706 2726 2340
-3 3164 2317 2707
-3 3164 2307 2317
-3 3164 2707 3172
-3 2312 2311 2708
-3 2719 2699 2709
-3 2700 2710 2699
-3 2710 2709 2699
-3 2710 2700 2720
-3 2314 2711 2691
-3 2701 2682 2711
-3 2712 2702 3159
-3 2722 2712 3159
-3 2703 2702 2713
-3 2713 2702 2712
-3 2704 2703 2713
-3 3167 3160 2714
-3 3167 2714 2724
-3 3169 3167 2724
-3 2715 3169 2724
-3 2328 2696 3179
-3 2707 2317 2716
-3 3172 2707 2717
-3 2717 2707 2716
-3 2717 2324 3172
-3 2319 3183 3184
-3 2319 3184 2708
-3 2319 2708 2311
-3 2718 2312 2708
-3 2312 2718 2320
-3 2710 2719 2709
-3 2720 2719 2710
-3 2314 2327 2711
-3 2701 2711 2327
-3 2693 2701 2721
-3 2722 2721 2712
-3 2712 2721 2732
-3 2713 2712 2732
-3 2723 2704 2713
-3 2723 2729 3176
-3 2714 3176 2729
-3 2694 2715 2725
-3 2340 2726 2730
-3 2317 2323 2716
-3 2324 2716 2323
-3 2717 2716 2324
-3 2319 2727 3183
-3 2731 2728 2727
-3 2325 2731 2727
-3 2325 2727 2319
-3 2718 2731 2325
-3 2718 2325 2320
-3 2721 2701 2327
-3 2714 2729 2734
-3 2715 2724 2733
-3 2336 2725 2715
-3 2328 2725 2336
-3 2723 2713 2732
-3 2729 2723 2732
-3 2724 2714 2733
-3 2732 2721 2334
-3 2334 2348 2732
-3 2740 2732 2739
-3 2729 2732 2740
-3 2734 2729 2740
-3 2714 2734 2733
-3 2715 2733 2356
-3 2735 3193 2736
-3 3193 2737 2736
-3 3171 2331 2738
-3 2340 2730 2347
-3 2739 2732 2348
-3 2741 2734 2740
-3 2356 2733 2734
-3 2350 2742 2346
-3 2743 2744 2742
-3 2353 2352 2745
-3 2354 2353 2745
-3 2736 2746 2735
-3 2747 2746 2736
-3 2737 2747 2736
-3 3201 2748 2749
-3 3201 2749 2738
-3 2750 2738 2749
-3 2751 2738 2750
-3 2369 3718 3731
-3 2730 3718 2369
-3 2740 2739 2370
-3 2356 2741 2740
-3 2734 2741 2356
-3 2350 2361 2752
-3 2350 2752 3203
-3 2350 3203 2742
-3 3203 2753 2742
-3 2743 2742 2754
-3 2754 2742 2753
-3 2744 2743 2755
-3 2755 2743 2754
-3 1524 4422 1519
-3 2352 2351 2745
-3 2354 2745 2351
-3 2757 2738 2756
-3 2758 2738 2757
-3 3201 2738 2758
-3 2750 2749 2748
-3 2751 2750 2368
-3 3198 2751 2368
-3 1531 3198 2368
-3 3731 3198 1531
-3 2369 3731 1301
-3 2752 2361 2759
-3 2361 2365 2759
-3 2753 2760 2365
-3 2759 2365 2760
-3 2754 2753 2365
-3 2755 2754 2365
-3 2756 2366 2761
-3 2367 2757 2761
-3 2757 2756 2761
-3 2758 2757 2367
-3 2368 2758 2367
-3 2758 2368 2762
-3 2748 2762 2368
-3 2750 2748 2368
-3 2374 2373 2763
-3 2374 2763 2375
-3 2373 2376 2763
-3 2375 2763 2376
-3 2767 3226 2377
-3 2377 3226 2378
-3 2768 2766 2770
-3 2769 2766 2768
-3 2771 2773 2772
-3 2380 2783 2767
-3 3226 2785 2378
-3 2768 2770 2775
-3 2766 2776 2770
-3 2776 2775 2770
-3 2776 2766 2777
-3 2778 2771 2772
-3 2382 2383 2779
-3 2382 2779 2773
-3 2773 2779 2772
-3 2773 2384 2382
-3 2773 2780 2384
-3 2773 2774 2780
-3 2780 2781 2384
-3 2384 2782 2386
-3 2781 2782 2384
-3 2783 2380 3236
-3 2380 2784 3236
-3 2380 2387 2784
-3 3240 2784 2387
-3 3240 2387 2785
-3 2785 2387 2388
-3 2785 2388 2378
-3 1697 4373 423
-3 3241 2775 2776
-3 2777 3241 2776
-3 2778 2787 3249
-3 2778 2772 2787
-3 2772 2779 2787
-3 2383 2390 2787
-3 2779 2383 2787
-3 2788 2781 2780
-3 3249 2788 2780
-3 2782 2781 2789
-3 2789 2781 2788
-3 2782 2789 2386
-3 2784 2790 3236
-3 3240 2790 2784
-3 2792 2791 2786
-3 2791 2797 2786
-3 2390 3249 2787
-3 2390 2393 3249
-3 3249 2391 2788
-3 3249 2393 2391
-3 2789 2788 2391
-3 2793 2795 2796
-3 2794 2795 2793
-3 2394 2797 2792
-3 2792 2797 2791
-3 2792 2798 2394
-3 2398 2394 2798
-3 2793 2796 2800
-3 2795 2801 2796
-3 2801 2800 2796
-3 2797 2836 3247
-3 2836 2797 2394
-3 2398 2802 2399
-3 2398 2798 2802
-3 2802 2803 2399
-3 2399 2803 2401
-3 2402 3259 2804
-3 2396 2799 2418
-3 2810 2811 2809
-3 2812 2793 2800
-3 2801 2405 2812
-3 2801 2812 2800
-3 2795 2406 2801
-3 2795 2407 2406
-3 2795 2844 2407
-3 2410 2803 2802
-3 2410 2802 2409
-3 2401 2803 2410
-3 2412 2813 2814
-3 2815 2804 2816
-3 2816 2804 2828
-3 2805 2414 2817
-3 2415 2414 2805
-3 2415 2805 2818
-3 2818 2805 2806
-3 2403 2417 2799
-3 2417 2820 2799
-3 2418 2799 2820
-3 2821 2418 2820
-3 2821 2822 2418
-3 2416 2418 2823
-3 2823 2418 2822
-3 2825 2809 2824
-3 2809 2811 2824
-3 2824 2811 2435
-3 2405 3290 2812
-3 2408 2836 2394
-3 2408 2409 2826
-3 2409 3281 2826
-3 2409 2802 3281
-3 2420 2437 2814
-3 2420 2814 2813
-3 2437 2827 2814
-3 2816 2827 2815
-3 2828 2827 2816
-3 2829 2830 2817
-3 2415 2831 2118
-3 2415 2818 2831
-3 2439 2819 2807
-3 3306 2439 2807
-3 3306 2807 2808
-3 2422 3299 2423
-3 2423 3299 2424
-3 2417 2430 2820
-3 2821 2430 2832
-3 2821 2820 2430
-3 2832 2430 2833
-3 2416 2823 2430
-3 2833 2430 2823
-3 2432 2822 2431
-3 2432 2823 2822
-3 2432 2833 2823
-3 2446 2431 3288
-3 2431 2822 3288
-3 3288 2834 2446
-3 2824 2434 2825
-3 3290 2405 2419
-3 2826 2836 2408
-3 2837 2836 2826
-3 3281 2837 2826
-3 2118 2830 2829
-3 2830 2118 2831
-3 2819 2438 2838
-3 2839 3299 2422
-3 2422 2440 2839
-3 2428 3309 2441
-3 2833 2445 2832
-3 3301 2111 2842
-3 3301 2434 2111
-3 2447 2842 2843
-3 2447 2835 2842
-3 2447 2435 2835
-3 3301 2842 2835
-3 2419 3302 3290
-3 3302 2419 2864
-3 2848 3314 2454
-3 3314 3322 2454
-3 2838 2853 3305
-3 2853 2838 2438
-3 2441 3309 2839
-3 3321 2449 1814
-3 3321 2450 2449
-3 2450 2108 2449
-3 2450 2840 2854
-3 2446 2834 2457
-3 2452 2842 2111
-3 2843 2842 2452
-3 2844 2848 2453
-3 2849 2848 2454
-3 2454 3322 2455
-3 2455 3322 2856
-3 2456 2455 2856
-3 2850 2464 2846
-3 2846 2845 2850
-3 2845 2851 2850
-3 2852 2845 2847
-3 2851 2845 2852
-3 1814 2121 3321
-3 3321 2121 2861
-3 2832 2445 3329
-3 3329 2445 1833
-3 2848 2855 2453
-3 2453 2855 2125
-3 2855 2848 3344
-3 2849 3344 2848
-3 2456 2856 2470
-3 2460 2461 2857
-3 2463 2858 2464
-3 2465 2850 2859
-3 2465 2464 2850
-3 2860 2859 2851
-3 2859 2850 2851
-3 2852 2860 2851
-3 2439 3306 2486
-3 2466 2861 2121
-3 2862 2861 2467
-3 2467 2861 2466
-3 2467 2854 2862
-3 2469 2855 2864
-3 2855 2469 2125
-3 2459 3330 2849
-3 2459 2856 3330
-3 2134 2856 2459
-3 2470 2856 2134
-3 2857 2472 2865
-3 2461 2472 2857
-3 2460 2866 2473
-3 2460 2857 2866
-3 2857 2865 2866
-3 2463 2475 2867
-3 2463 2867 2858
-3 2858 2867 3335
-3 2483 2465 2867
-3 3335 2867 2465
-3 2859 3335 2465
-3 2860 3335 2859
-3 2868 2485 2853
-3 1833 2476 3329
-3 2457 2863 2476
-3 2476 2863 3329
-3 2866 2865 2869
-3 2473 2869 2482
-3 2866 2869 2473
-3 2475 2483 2867
-3 2484 2485 2868
-3 2487 2869 2865
-3 2482 2869 2488
-3 2869 2487 2488
-3 2439 2486 2156
-3 2870 2872 2873
-3 2489 3889 2485
-3 2874 3360 3356
-3 2874 2875 2876
-3 3356 2875 2874
-3 2870 2877 2871
-3 2877 2878 2879
-3 2877 2870 2878
-3 2870 2873 2878
-3 3365 2873 2872
-3 2878 2873 3365
-3 2489 2158 3889
-3 2158 2486 3889
-3 2880 3360 2874
-3 2881 3360 2880
-3 2491 2880 2876
-3 2876 2880 2874
-3 2876 2885 2491
-3 2882 2879 2878
-3 3365 2883 2878
-3 2883 2882 2878
-3 2880 2491 2881
-3 2884 2493 2491
-3 2884 2491 2885
-3 2882 2886 3366
-3 2882 2883 2886
-3 2887 2886 2883
-3 2885 2888 2884
-3 2884 2888 2889
-3 2884 2889 2493
-3 2495 2494 2886
-3 2886 2494 3366
-3 2886 2887 2496
-3 2886 2496 2495
-3 2494 3369 3366
-3 2887 2498 2496
-3 2887 2883 2498
-3 2499 2888 2881
-3 2499 2889 2888
-3 2891 2890 2498
-3 2891 2498 2883
-3 2494 2892 3369
-3 2890 2893 2892
-3 2890 2892 2498
-3 2891 2893 2890
-3 3381 2894 2895
-3 2895 2894 2896
-3 2895 2897 3381
-3 2896 2897 2895
-3 3395 4422 1893
-3 1893 3404 3395
-3 2898 2902 3398
-3 2903 2898 3400
-3 2902 2898 2903
-3 3403 3404 1893
-3 2902 3410 3398
-3 2503 2901 2501
-3 2503 2905 2901
-3 2502 2901 2905
-3 2502 2905 3945
-3 2910 2906 2907
-3 2168 2910 2908
-3 3410 2168 2908
-3 2902 2168 3410
-3 2909 2902 2903
-3 2909 2504 2902
-3 2909 3414 2504
-3 2168 2902 2504
-3 2903 2505 2909
-3 2899 3418 2507
-3 2512 2905 2503
-3 2910 2911 2908
-3 2513 2504 3414
-3 2506 2912 2505
-3 2510 2912 2506
-3 2507 2913 2510
-3 2510 2913 2912
-3 2913 2507 3418
-3 2905 2512 2915
-3 3945 2914 2515
-3 2513 3421 2514
-3 3427 3403 2515
-3 3423 2514 3421
-3 3423 2915 2514
-3 2916 3426 2516
-3 2516 1226 3428
-3 2516 3426 2917
-3 2916 2516 3428
-3 2517 2918 2519
-3 2919 2918 2517
-3 2519 2918 2520
-3 2920 2919 2921
-3 2921 2919 1635
-3 2922 2923 3437
-3 2924 2925 2926
-3 2928 2926 2929
-3 2928 2927 2926
-3 2927 2924 2926
-3 2929 2930 2931
-3 2929 2926 2930
-3 2932 2930 2925
-3 2925 2930 2926
-3 2933 2931 2930
-3 2934 2931 2933
-3 2935 2930 2932
-3 2933 2930 2935
-3 2933 2936 2934
-3 2935 2936 2933
-3 2522 3450 2526
-3 2524 2527 2937
-3 2526 3450 2529
-3 3450 2938 2529
-3 2937 2530 2939
-3 2527 2530 2937
-3 2524 2940 2531
-3 2524 2937 2940
-3 2937 2939 2940
-3 2533 3456 2941
-3 2532 3456 2533
-3 2942 2533 2941
-3 2942 2943 2533
-3 2528 2529 2947
-3 2947 2529 2938
-3 2528 2939 2530
-3 2528 2944 2939
-3 2531 2944 2534
-3 2531 2940 2944
-3 2940 2939 2944
-3 2532 2537 3456
-3 3456 2537 2950
-3 2950 2945 2942
-3 2943 2942 2946
-3 2946 2942 2945
-3 2952 2528 2947
-3 2952 2948 2944
-3 2952 2944 2528
-3 2534 2944 2948
-3 2950 2537 2949
-3 2950 2949 2951
-3 2945 2950 2951
-3 2945 2951 2540
-3 2945 2540 2539
-3 2541 2945 2539
-3 2946 2945 2541
-3 3467 3470 2948
-3 2949 2948 2953
-3 2953 2948 3470
-3 2540 2953 2542
-3 2540 2951 2953
-3 2951 2949 2953
-3 3471 2953 3470
-3 2542 3471 2958
-3 2542 2953 3471
-3 2958 2544 2542
-3 2954 2956 2957
-3 3468 2954 2957
-3 2959 2544 2958
-3 2544 2959 2960
-3 2544 2960 2955
-3 2961 2955 2960
-3 2957 2956 2969
-3 2969 2956 2963
-3 3468 2957 2969
-3 2970 3468 2987
-3 2987 3468 2969
-3 2547 2961 2550
-3 2961 2960 2550
-3 2545 2961 2547
-3 2962 2964 2546
-3 3470 2970 2971
-3 2972 3470 2971
-3 2550 2960 2959
-3 2976 2550 2959
-3 3501 2967 2966
-3 3501 2966 2973
-3 2973 2966 2965
-3 2963 2968 2986
-3 2986 2968 2974
-3 2969 2963 2986
-3 2971 2970 2975
-3 2975 2972 2971
-3 2986 2974 2979
-3 2975 2970 2980
-3 2980 2970 2987
-3 2554 2557 2977
-3 2978 2973 2981
-3 2978 2981 2558
-3 2978 2558 2559
-3 2558 2978 2559
-3 2558 3501 2978
-3 3501 2973 2978
-3 2979 2982 2986
-3 2987 2969 2986
-3 2976 2985 2984
-3 2976 2984 2550
-3 2550 2984 2560
-3 2558 2565 3501
-3 2982 2990 2986
-3 2980 2987 2991
-3 2988 2983 2980
-3 2988 2980 2989
-3 2989 2980 2991
-3 2988 2989 3495
-3 2992 2985 3495
-3 2985 2992 2984
-3 2984 2992 2994
-3 2560 2984 2994
-3 2565 2566 3501
-3 2987 2986 2991
-3 2991 2986 2990
-3 3495 2989 2992
-3 2992 2989 2991
-3 2995 2991 2990
-3 2992 2991 3005
-3 3005 2991 2995
-3 2993 2992 3005
-3 2994 2992 2993
-3 2566 2572 3501
-3 2993 3005 2997
-3 2994 2993 2997
-3 2996 2995 3503
-3 3005 2995 2996
-3 2994 2997 2571
-3 2996 3503 2998
-3 3501 2572 4052
-3 3005 2996 2998
-3 2998 3503 2999
-3 3005 2998 2999
-3 2997 3005 3004
-3 3005 2999 3000
-3 3509 3001 3000
-3 3002 3000 3001
-3 3003 3000 3002
-3 3003 3002 3005
-3 3000 3003 3005
-3 3004 2578 2573
-3 3004 3005 2580
-3 3001 3006 3007
-3 3002 3001 3009
-3 3005 3002 3009
-3 3019 3005 3009
-3 2580 3005 3019
-3 2584 2580 3019
-3 2581 3010 2583
-3 3007 3008 3012
-3 3012 3008 3011
-3 3007 3012 3013
-3 3001 3007 3013
-3 3009 3001 3013
-3 2584 3019 3014
-3 2584 3014 2585
-3 3012 3011 3013
-3 3009 3013 3023
-3 3031 3009 3023
-3 3019 3009 3018
-3 3014 3019 3026
-3 3020 3016 3015
-3 3021 3016 3020
-3 3022 3015 3017
-3 3020 3015 3022
-3 2588 4052 2587
-3 3011 3008 3045
-3 3024 3009 3043
-3 3018 3009 3024
-3 3019 3018 3025
-3 3026 3019 3025
-3 3013 3011 3045
-3 3023 3013 3027
-3 3031 3023 3028
-3 3028 3023 3027
-3 3018 3024 3029
-3 3025 3018 3519
-3 2588 3532 4052
-3 2589 3521 3520
-3 2591 3521 2589
-3 2591 3030 3521
-3 3013 3045 3051
-3 3028 3027 3539
-3 3031 3028 3539
-3 3029 3024 3032
-3 3032 3024 3043
-3 3032 3018 3029
-3 3519 3018 3032
-3 3026 3025 2592
-3 3520 2593 2589
-3 3033 2593 3520
-3 2595 3030 2591
-3 2595 3529 3030
-3 3034 3529 2595
-3 3027 3013 3539
-3 3009 3031 3035
-3 3043 3009 3035
-3 3025 3527 2592
-3 3533 2593 3033
-3 2595 3037 3034
-3 2595 3535 3037
-3 3038 3535 2595
-3 3539 3013 3051
-3 3540 3032 3043
-3 2601 3533 3039
-3 2603 3038 2595
-3 2603 3040 3038
-3 3549 3044 3045
-3 3574 3539 3051
-3 3031 3539 3052
-3 3035 3031 3052
-3 3564 3540 3043
-3 3550 2611 3527
-3 3527 2611 2610
-3 2588 2618 3532
-3 3049 3532 2618
-3 2601 3039 2619
-3 2603 2621 3040
-3 3052 3539 3574
-3 3043 3035 3046
-3 2612 3047 3048
-3 2612 2604 3047
-3 3056 3040 2621
-3 3572 3050 3041
-3 3045 3044 3081
-3 3051 3045 3081
-3 3046 3035 3053
-3 3053 3035 3052
-3 3043 3046 3061
-3 3061 3046 3053
-3 3061 3564 3043
-3 3063 2611 3054
-3 2611 3063 2622
-3 2624 3066 2604
-3 3066 3047 2604
-3 2612 2633 2625
-3 2618 2644 3049
-3 3078 2619 3039
-3 3056 2621 2632
-3 3044 3549 3081
-3 3598 3574 3059
-3 3059 3574 3051
-3 3574 3599 3052
-3 3053 3052 3061
-3 3061 3052 3060
-3 3586 3062 3063
-3 3586 3063 3054
-3 2624 2629 3064
-3 3065 3066 3064
-3 3064 3066 2624
-3 3067 2612 3048
-3 3068 3067 3048
-3 2612 3067 2633
-3 3553 3049 3088
-3 2632 3069 3056
-3 3069 2632 3057
-3 2632 3058 3057
-3 2632 3074 3058
-3 3051 3081 3070
-3 3059 3051 3070
-3 3070 3598 3059
-3 3061 3060 3071
-3 3085 3063 3062
-3 2629 2640 3064
-3 3065 3064 3072
-3 3072 3064 2640
-3 3072 2634 3068
-3 3065 3072 3068
-3 2634 2633 3068
-3 3068 2633 3067
-3 2644 2638 3049
-3 3088 3049 2638
-3 2645 3074 2632
-3 3079 3074 2645
-3 3074 3079 3075
-3 3060 3052 3083
-3 3071 3060 3083
-3 3063 3085 2622
-3 3072 2640 2641
-3 2642 3072 2641
-3 2634 3072 2642
-3 2636 2643 3073
-3 2638 2644 3077
-3 3088 2638 3087
-3 3087 2638 3077
-3 3080 3075 3079
-3 3074 3075 3080
-3 3074 3080 3613
-3 3070 3081 3082
-3 3626 3070 3082
-3 3052 3609 3620
-3 3076 3071 3084
-3 3084 3071 3083
-3 3077 2648 3086
-3 2644 2648 3077
-3 3087 3077 3086
-3 2619 3078 2646
-3 3079 2645 2651
-3 3619 3630 3089
-3 3619 3089 3081
-3 3082 3081 3090
-3 3090 3081 3089
-3 3090 3626 3082
-3 3091 3620 3626
-3 3620 3091 3052
-3 3084 3083 3092
-3 3076 3084 3092
-3 3085 3076 3092
-3 2622 3092 2652
-3 3085 3092 2622
-3 3087 3086 3093
-3 3088 3087 3093
-3 3096 3079 2651
-3 3080 3079 3096
-3 3622 3080 3094
-3 3626 3090 3089
-3 3116 3091 3626
-3 2652 3092 3110
-3 3095 3086 2648
-3 3093 3086 3095
-3 3632 3088 3095
-3 3095 3088 3093
-3 4097 2646 3078
-3 3080 3096 3106
-3 3052 3091 3116
-3 3092 3083 3110
-3 3642 3632 3095
-3 1697 2646 4097
-3 3080 3101 3109
-3 3097 3080 3109
-3 3094 3080 3098
-3 3098 3080 3097
-3 3099 3647 3100
-3 3083 3052 3110
-3 3080 3106 3112
-3 3101 3080 3112
-3 3098 3097 3102
-3 3099 3646 3103
-3 3647 3099 3103
-3 3642 3095 3104
-3 3642 3104 3105
-3 2651 3106 3096
-3 3101 3112 3107
-3 3108 3101 3107
-3 3109 3101 3108
-3 3097 3109 3123
-3 3102 3097 3123
-3 3110 3052 3116
-3 2675 3104 3095
-3 3655 3121 3656
-3 3656 3121 3634
-3 2669 3634 3121
-3 3107 3112 3113
-3 3108 3107 3114
-3 3114 3107 3113
-3 3109 3108 3114
-3 3661 3657 3102
-3 3103 3646 3662
-3 3115 3654 3647
-3 3117 3118 3659
-3 3111 3117 3659
-3 3111 3119 3117
-3 3120 3119 3111
-3 2670 3122 3106
-3 3122 3112 3106
-3 3113 3112 3122
-3 3114 3113 3122
-3 3109 3114 3133
-3 3133 3114 3122
-3 3123 3109 3133
-3 3102 3123 3124
-3 3124 3661 3102
-3 3116 3664 3125
-3 3110 3116 3125
-3 2660 3110 3139
-3 3119 3118 3117
-3 3126 3118 3119
-3 3120 3126 3119
-3 3127 3126 3120
-3 3130 3132 3131
-3 3128 3132 3130
-3 3672 3104 2675
-3 2670 3144 3122
-3 3133 3122 3144
-3 3123 3133 3134
-3 3124 3123 3135
-3 3135 3123 3134
-3 3135 3661 3124
-3 3103 3662 3147
-3 3147 3662 3158
-3 3647 3103 3148
-3 3148 3103 3147
-3 3115 3647 3160
-3 3676 3115 3149
-3 3149 3115 3160
-3 3125 3136 3137
-3 3110 3125 3138
-3 3138 3125 3137
-3 3139 3110 3138
-3 3128 3140 3141
-3 3128 3130 3140
-3 2665 2664 3140
-3 2665 3140 3131
-3 3131 3140 3130
-3 3131 3132 3142
-3 3131 3142 2665
-3 2665 3142 2666
-3 3142 2667 2666
-3 3143 2667 3142
-3 3134 3133 3145
-3 3145 3133 3144
-3 3135 3134 3146
-3 3146 3134 3145
-3 3158 3661 3135
-3 3158 3135 3146
-3 3149 3150 3676
-3 3676 3150 3136
-3 3136 3150 3137
-3 3138 3137 3151
-3 3152 3138 3151
-3 3139 3690 2660
-3 2660 3690 2672
-3 2664 3141 3140
-3 2664 2663 3141
-3 2663 3153 3141
-3 2667 3153 2663
-3 3153 2667 3143
-3 3121 3682 2706
-3 2680 3155 3156
-3 2679 3155 2680
-3 2680 3156 3684
-3 2692 3157 3144
-3 3157 3145 3144
-3 3146 3145 3157
-3 3158 3146 3157
-3 3147 3158 3159
-3 3647 3148 3160
-3 3160 3148 3176
-3 3137 3150 3169
-3 2705 3151 3137
-3 3161 3152 3151
-3 3161 3151 2705
-3 3690 3170 2672
-3 3162 2661 2683
-3 2698 3672 2675
-3 3674 3672 3171
-3 3171 3672 2698
-3 3121 2706 2688
-3 2676 3164 3154
-3 2677 3154 2689
-3 2689 3154 3164
-3 3155 2679 3165
-3 2692 2693 3157
-3 3696 3157 2693
-3 3157 3166 3158
-3 3159 3158 3166
-3 2703 3147 3159
-3 2704 3147 2703
-3 2704 3148 3147
-3 3176 3148 2704
-3 3149 3160 3167
-3 3150 3149 3168
-3 3168 3149 3167
-3 3169 3150 3168
-3 2695 2672 3170
-3 2684 3163 3162
-3 3180 3681 3171
-3 2689 3164 3172
-3 2679 2719 3165
-3 2700 2680 3684
-3 3714 2700 3684
-3 3173 3696 2693
-3 3175 3174 3166
-3 3159 3166 3174
-3 3176 2704 2723
-3 3169 3168 3167
-3 3177 3161 2705
-3 3170 3177 3178
-3 2695 3170 3179
-3 3170 3178 3179
-3 2331 3171 2698
-3 3704 3180 3171
-3 2706 3682 2726
-3 2726 3682 3707
-3 3713 2720 3714
-3 2720 2700 3714
-3 3173 2693 3185
-3 2722 3174 3175
-3 3716 2722 3175
-3 3174 2722 3159
-3 2714 3160 3176
-3 2705 2725 3177
-3 3178 3177 3181
-3 3179 3178 3182
-3 3182 3178 3181
-3 3179 3182 2328
-3 2720 3726 2719
-3 3713 3726 2720
-3 2721 3185 2693
-3 3716 3185 2722
-3 3185 2721 2722
-3 3181 3177 2725
-3 3182 3181 2725
-3 2328 3182 2725
-3 2726 3707 3720
-3 3183 2727 3186
-3 2718 3189 2731
-3 2738 3704 3171
-3 3704 2738 3198
-3 2730 2726 3720
-3 3732 3187 3188
-3 3732 3186 3187
-3 3186 2727 3187
-3 2728 3187 2727
-3 2728 3189 3187
-3 2728 2731 3189
-3 3731 3717 3198
-3 3720 3718 2730
-3 1262 1519 4422
-3 2735 3191 3193
-3 3190 3191 2735
-3 3192 3193 3191
-3 2737 3194 3195
-3 2737 3193 3194
-3 3194 3196 3195
-3 3198 2738 2751
-3 2735 2746 3190
-3 2747 3190 2746
-3 3191 3190 2747
-3 3191 2747 3192
-3 2747 2737 3192
-3 3195 3199 2737
-3 3199 3192 2737
-3 3196 3199 3195
-3 3200 3199 3196
-3 3197 3200 3196
-3 2752 3202 3739
-3 2752 3739 3203
-3 2758 3204 3201
-3 3201 3204 2748
-3 3205 3202 3207
-3 3206 3202 3205
-3 2752 3207 3202
-3 2752 2759 3207
-3 2760 3203 3739
-3 3208 2760 3739
-3 3203 2760 2753
-3 2758 2762 3204
-3 2748 3204 2762
-3 3206 3205 3209
-3 3205 3210 3209
-3 3207 3211 3205
-3 3211 3210 3205
-3 2759 3211 3207
-3 2759 3213 3211
-3 2759 3208 3213
-3 3208 2759 2760
-3 3210 3212 3209
-3 3213 3212 3210
-3 3211 3213 3210
-3 3214 2764 2765
-3 3214 3750 2764
-3 3214 2773 3215
-3 3216 2773 3214
-3 2765 3216 3214
-3 2765 3217 3216
-3 2765 2764 3217
-3 3217 3218 3216
-3 3217 2764 3750
-3 2768 3219 2769
-3 2766 2769 3779
-3 2769 3219 3779
-3 3779 3220 2766
-3 3221 3223 3222
-3 3222 3223 3224
-3 2771 3771 3215
-3 2773 2771 3215
-3 3216 2774 2773
-3 3216 3218 2774
-3 2767 2783 3225
-3 3225 3226 2767
-3 2768 3227 3219
-3 3227 2768 2775
-3 3228 3229 2777
-3 3228 2777 3220
-3 3220 2777 2766
-3 3230 3231 3765
-3 3247 3221 3232
-3 3222 3233 3221
-3 3233 3232 3221
-3 3233 3222 3224
-3 2771 2778 3771
-3 2780 2774 3249
-3 3234 3235 3236
-3 3236 3235 2783
-3 3235 3237 2783
-3 3225 2783 3238
-3 3238 2783 3237
-3 3238 3239 3240
-3 3238 3240 3225
-3 3225 3240 3226
-3 2785 3226 3240
-3 3227 2775 3241
-3 3241 2777 3229
-3 3241 3229 3242
-3 3250 3242 3229
-3 3243 3231 3230
-3 3251 3231 3243
-3 3244 3245 3230
-3 3245 3243 3230
-3 2786 3247 3232
-3 2792 2786 3232
-3 2798 2792 3232
-3 2798 3232 3233
-3 2778 3249 3248
-3 3234 3819 3255
-3 3236 3819 3234
-3 3239 2790 3240
-3 3820 3227 3241
-3 3241 3242 3820
-3 3250 3820 3242
-3 3245 3252 3243
-3 3252 3251 3243
-3 3835 3245 3244
-3 3835 2795 3245
-3 2795 3252 3245
-3 3246 3247 3811
-3 2786 2797 3247
-3 3233 3812 2798
-3 2790 3819 3236
-3 2794 2793 3257
-3 2794 3257 3251
-3 2794 3251 3252
-3 3251 3257 3256
-3 2795 2794 3252
-3 3247 3271 3811
-3 2798 3812 3258
-3 2804 3259 3253
-3 3253 3260 2804
-3 3260 3253 3254
-3 3261 3263 3262
-3 3262 3263 3274
-3 3255 3265 3264
-3 3265 3255 3266
-3 3267 3268 3269
-3 3822 3268 3267
-3 3269 3833 2811
-3 3268 3833 3269
-3 2793 3834 3257
-3 2795 3835 3270
-3 2836 3271 3247
-3 3272 2798 3258
-3 2798 3272 2802
-3 2804 3260 3273
-3 2805 3285 3261
-3 2806 2805 3261
-3 3262 2806 3261
-3 2806 3262 3274
-3 3264 2807 3286
-3 2808 2807 3264
-3 2808 3264 3275
-3 3275 3264 3265
-3 3276 3265 3266
-3 3275 3265 3276
-3 2810 2809 3277
-3 2810 3277 3267
-3 2810 3267 3269
-3 2811 2810 3269
-3 3833 4338 2811
-3 3834 2812 3278
-3 3834 2793 2812
-3 3278 3279 3280
-3 3834 3278 3280
-3 3270 3280 3279
-3 2795 3270 2844
-3 2836 3293 3271
-3 3281 3272 3258
-3 3293 3281 3258
-3 3272 3281 2802
-3 2804 3282 3283
-3 2804 3283 2828
-3 3273 3282 2804
-3 2805 2817 3284
-3 2805 3284 3285
-3 2806 2831 2818
-3 2806 3274 2831
-3 3838 2831 3274
-3 3286 2807 2819
-3 3275 3298 2808
-3 3298 3275 3276
-3 3288 2822 3287
-3 2809 3289 3277
-3 2825 3289 2809
-3 2811 4338 2435
-3 4338 3301 2435
-3 3290 3278 2812
-3 3290 3279 3278
-3 3270 3279 3291
-3 3291 3279 3290
-3 3270 3291 2844
-3 2836 3292 3293
-3 3293 3292 3281
-3 2814 2827 3294
-3 2827 2828 3294
-3 3294 2828 3283
-3 2817 2830 3284
-3 3284 2830 2831
-3 3284 2831 3285
-3 3295 3297 2838
-3 3296 3297 3295
-3 2838 3297 2819
-3 2424 3299 3845
-3 3309 2428 3845
-3 2428 2424 3845
-3 2822 3300 3287
-3 2822 2821 3300
-3 2821 2832 3300
-3 3312 2834 3288
-3 3301 2825 2434
-3 2835 2435 3301
-3 3302 3291 3290
-3 3302 3313 3291
-3 3291 3313 2844
-3 2837 3292 2836
-3 3281 3292 2837
-3 3295 3303 3304
-3 3295 3305 3303
-3 2838 3305 3295
-3 3298 3306 2808
-3 3306 3298 3276
-3 3307 3308 3299
-3 3307 3299 2839
-3 2840 3310 2841
-3 3310 2840 2841
-3 3311 2840 3310
-3 2844 3313 3314
-3 2848 2844 3314
-3 2845 3315 3316
-3 2846 3315 2845
-3 2847 3316 3303
-3 2847 2845 3316
-3 3316 3304 3303
-3 3305 3317 3303
-3 3317 2847 3303
-3 3305 2853 3318
-3 3305 3318 3317
-3 3319 3308 3307
-3 3858 3308 3319
-3 2839 3320 3307
-3 3307 3320 3319
-3 3327 2839 3309
-3 2450 3321 2840
-3 2840 3321 3310
-3 2854 2840 3311
-3 2834 3312 2457
-3 2846 2464 3323
-3 2846 3323 3324
-3 2846 3324 3315
-3 2847 3856 3325
-3 2847 3325 2852
-3 3317 3856 2847
-3 3318 3856 3317
-3 3326 3856 3318
-3 3318 2853 3326
-3 3319 3867 3858
-3 3320 3867 3319
-3 3327 3320 2839
-3 3321 2861 3328
-3 2832 3329 3300
-3 3302 3347 3863
-3 3330 3864 3344
-3 3330 3331 3332
-3 3864 3330 3332
-3 3322 3332 3331
-3 3322 3331 3333
-3 2856 3322 3334
-3 3334 3322 3333
-3 2464 2858 3335
-3 2464 3335 3323
-3 3335 3336 3323
-3 2860 3866 3323
-3 2860 3323 3336
-3 3324 3323 3866
-3 3325 2860 2852
-3 3866 2860 3325
-3 2485 3326 2853
-3 2485 3337 3326
-3 3337 3857 3326
-3 3338 3857 3337
-3 3339 3306 3858
-3 2854 3340 2862
-3 3345 2854 3311
-3 3345 3340 2854
-3 2457 3312 2863
-3 2864 3341 3302
-3 3302 3341 3347
-3 3342 3341 2864
-3 2855 3343 2864
-3 2864 3343 3342
-3 2855 3344 3343
-3 3344 2849 3330
-3 2856 3331 3330
-3 3333 3331 2856
-3 3334 3333 2856
-3 2860 3336 3335
-3 3873 3338 3337
-3 2486 3306 3339
-3 3350 2861 2862
-3 2862 3340 3350
-3 3345 3350 3340
-3 3348 3341 3342
-3 3347 3341 3348
-3 2485 3873 3337
-3 3339 3349 2486
-3 3345 3880 3350
-3 3346 3880 3345
-3 3348 3353 3347
-3 3353 3352 3347
-3 3348 3358 3353
-3 3873 2485 3889
-3 3354 2486 3349
-3 3355 3351 3877
-3 3356 3355 3877
-3 2871 3358 2870
-3 2871 3353 3358
-3 3359 3358 3891
-3 3359 2872 3358
-3 2872 2870 3358
-3 2486 3354 3889
-3 3360 3351 3355
-3 3361 3351 3360
-3 3356 3360 3355
-3 3356 3362 2875
-3 3356 3357 3362
-3 2875 3362 2876
-3 2871 2877 3353
-3 2877 3891 3353
-3 2879 3363 3359
-3 2879 3359 3891
-3 2879 3891 2877
-3 2872 3363 3365
-3 3359 3363 2872
-3 2876 3362 2885
-3 3363 2882 3364
-3 2879 2882 3363
-3 3363 3364 3365
-3 3894 2881 2888
-3 3894 2888 3362
-3 3366 3364 2882
-3 3366 3365 3364
-3 3365 3367 2883
-3 3365 3366 3367
-3 2885 3362 2888
-3 3369 3368 3366
-3 3368 3367 3366
-3 3367 3368 2883
-3 2883 3370 2891
-3 2883 3368 3370
-3 3368 3369 3370
-3 2893 3369 2892
-3 3370 3369 2893
-3 2891 3370 2893
-3 3372 3373 3371
-3 3375 3372 3371
-3 2894 3375 3373
-3 3373 3375 3371
-3 2894 3374 3376
-3 2894 3373 3374
-3 2500 4373 3952
-3 3381 3372 3375
-3 3375 2894 3381
-3 3377 2894 3376
-3 2896 2894 3377
-3 2896 3377 2897
-3 3381 3382 3383
-3 3381 2897 3382
-3 3382 2897 3377
-3 3386 3385 3378
-3 3387 3386 3378
-3 3389 3379 3380
-3 3388 3379 3389
-3 3391 3390 3384
-3 3385 3391 3384
-3 3392 3391 3385
-3 3386 3393 3385
-3 3393 3392 3385
-3 3387 3394 3386
-3 3394 3393 3386
-3 3395 3394 3387
-3 3396 3379 3388
-3 3405 3379 3396
-3 3397 3388 3389
-3 3396 3388 3397
-3 2900 2500 3952
-3 3398 3399 2898
-3 3402 3401 3382
-3 3940 3390 3391
-3 3392 3393 3403
-3 3394 3404 3393
-3 3404 3403 3393
-3 3395 3404 3394
-3 3397 3405 3396
-3 3411 2900 3952
-3 3406 3399 3410
-3 3398 3410 3399
-3 2899 2904 3400
-3 2906 2900 3411
-3 3407 3406 3408
-3 3406 3409 3408
-3 3410 3409 3406
-3 3400 2904 2903
-3 3411 3408 2906
-3 2906 3408 2907
-3 2907 3408 3412
-3 3954 3408 3409
-3 2908 3954 3409
-3 2908 3409 3410
-3 3414 2909 3413
-3 2505 4514 2909
-3 2909 4514 3413
-3 3956 3951 3403
-3 3934 3403 3951
-3 2907 3412 3953
-3 2910 2907 3953
-3 2911 2910 3954
-3 2910 3953 3954
-3 3954 2908 2911
-3 2505 3416 4514
-3 2912 3415 3416
-3 2912 3416 2505
-3 2912 2913 3417
-3 3415 2912 3417
-3 3418 3422 3417
-3 3417 2913 3418
-3 3418 3943 3422
-3 2915 3945 2905
-3 3945 3955 2914
-3 3427 3956 3403
-3 3419 3416 3415
-3 3420 3416 3419
-3 3417 3421 3415
-3 3421 3419 3415
-3 3422 3421 3417
-3 3943 3423 3422
-3 3423 3943 3945
-3 3423 3945 2915
-3 3955 3424 2914
-3 3414 3959 2513
-3 3420 3419 2513
-3 3420 2513 3959
-3 3421 2513 3419
-3 3422 3423 3421
-3 3427 2515 2914
-3 3427 2914 3424
-3 2916 3962 3425
-3 3426 2916 3425
-3 4531 3965 1226
-3 3428 1226 3965
-3 3426 3425 2917
-3 1226 5643 4531
-3 3428 3965 3430
-3 3428 3430 3431
-3 3429 2916 3428
-3 3431 3429 3428
-3 3432 2918 3433
-3 3433 2918 2919
-3 3432 2520 2918
-3 2919 3435 3433
-3 3435 2919 2920
-3 3433 3434 3438
-3 3433 3435 3434
-3 2921 3436 2920
-3 2920 3436 3435
-3 2520 4582 2522
-3 3438 3434 3437
-3 3434 3435 3437
-3 3439 3437 3435
-3 3440 3439 3436
-3 3439 3435 3436
-3 3975 3436 2921
-3 1635 3975 2921
-3 3437 2923 3438
-3 3440 3437 3439
-3 3440 2922 3437
-3 1635 2180 3975
-3 2922 3441 2923
-3 3441 2922 3440
-3 2924 3978 2925
-3 3442 2925 3978
-3 3978 2927 3443
-3 3978 2924 2927
-3 3442 3978 3443
-3 3442 3443 2928
-3 3442 2928 2929
-3 2931 3442 2929
-3 2931 3444 3442
-3 2925 3442 2932
-3 2932 3442 3444
-3 2928 3443 2927
-3 3444 2934 3445
-3 2931 2934 3444
-3 2932 3445 2935
-3 3444 3445 2932
-3 2934 2936 3445
-3 2935 3445 2936
-3 2522 3995 3450
-3 4002 3446 3447
-3 3983 3447 3446
-3 3983 3448 3447
-3 3447 3449 4002
-3 3448 3449 3447
-3 3451 3452 3449
-3 3451 3453 3454
-3 3449 3453 3451
-3 3450 3459 2938
-3 3455 3450 3995
-3 3459 3450 3455
-3 2941 3456 4020
-3 4020 2942 2941
-3 3457 3451 3454
-3 2938 3459 2947
-3 4020 3456 2950
-3 2950 2942 4020
-3 3459 3460 2947
-3 2948 2952 3461
-3 3462 4024 4027
-3 3463 3464 4028
-3 2952 3463 3465
-3 2952 3460 3463
-3 2952 2947 3460
-3 3464 3463 3460
-3 2952 3465 3461
-3 3465 3466 3461
-3 2948 3461 3467
-3 3461 3466 3467
-3 3463 4028 3481
-3 3463 3481 2954
-3 3468 3463 2954
-3 3468 3465 3463
-3 3466 3465 3469
-3 3469 3465 3468
-3 3467 3466 3469
-3 3467 3469 3470
-3 2954 3481 2956
-3 2970 3469 3468
-3 3470 3469 2970
-3 3471 3473 2958
-3 2958 3474 2959
-3 3473 3474 2958
-3 3475 3476 3477
-3 3472 3496 3478
-3 3472 3478 3479
-3 3480 4033 3472
-3 3479 3480 3472
-3 2956 3481 2963
-3 3470 2972 3471
-3 2972 3473 3471
-3 3474 3473 3482
-3 3474 3482 2959
-3 3483 3476 3475
-3 3486 3476 3483
-3 3483 3475 3486
-3 3478 3496 2965
-3 3478 2965 2966
-3 2967 3478 2966
-3 2967 3484 3478
-3 3484 3479 3478
-3 4642 3480 3479
-3 3484 4642 3479
-3 3481 2968 2963
-3 3493 2968 3481
-3 3473 2972 3487
-3 3482 3473 3485
-3 3485 3473 3487
-3 2959 3485 2976
-3 3482 3485 2959
-3 2965 3496 2973
-3 2967 3501 3484
-3 3501 4642 3484
-3 2968 3493 2974
-3 2972 2975 3487
-3 3485 3487 3488
-3 3485 3488 2976
-3 2974 3493 2979
-3 2975 2980 2983
-3 3487 2975 2983
-3 2976 3488 3489
-3 3491 3492 3490
-3 2973 3496 2981
-3 2982 2979 3493
-3 3487 2983 3495
-3 3488 3487 2985
-3 2985 3487 3495
-3 3489 3488 2985
-3 2976 3489 2985
-3 3492 3494 3490
-3 3497 2982 3493
-3 2982 3497 2990
-3 3495 2983 2988
-3 3493 3502 3497
-3 2990 3497 3499
-3 3499 3497 3498
-3 2990 3499 3500
-3 3497 3502 3505
-3 3498 3497 3506
-3 3506 3497 3505
-3 3499 3498 3500
-3 3500 3498 3506
-3 2990 3500 3503
-3 2990 3503 2995
-3 3507 3504 3502
-3 3505 3502 3504
-3 3505 3504 3506
-3 3506 3504 3507
-3 3507 3508 3506
-3 3509 3506 3508
-3 3503 3500 2999
-3 3500 3506 2999
-3 3506 3509 3000
-3 2999 3506 3000
-3 3509 3510 3001
-3 3001 3510 3006
-3 3510 3007 3006
-3 1936 4702 3036
-3 3007 3510 3008
-3 3511 3518 3510
-3 3008 3510 3518
-3 3511 3513 3518
-3 3015 3016 3512
-3 3015 3512 3017
-3 3511 3514 3513
-3 3512 3021 3515
-3 3016 3021 3512
-3 3017 3515 3022
-3 3512 3515 3017
-3 3516 3513 3514
-3 3517 3516 3514
-3 3518 3513 3516
-3 3518 3045 3008
-3 3021 3020 3515
-3 3022 3515 3020
-3 3521 3030 3522
-3 3524 3523 3525
-3 3531 3516 3517
-3 3518 3516 3526
-3 3526 3516 3531
-3 3549 3518 3526
-3 3518 3549 3045
-3 3032 3527 3519
-3 3519 3527 3025
-3 3033 3520 3521
-3 3522 3543 3521
-3 3528 3543 3522
-3 3030 3528 3522
-3 3030 3529 3528
-3 3523 3524 3536
-3 3530 3525 3523
-3 3536 3530 3523
-3 3526 3531 3563
-3 3032 3540 3541
-3 3527 3032 3541
-3 3521 3577 3033
-3 3577 3533 3033
-3 3571 3528 3529
-3 3534 3571 3529
-3 3034 3037 3529
-3 3529 3037 3534
-3 3537 3530 3536
-3 3537 3536 3538
-3 3531 3537 3538
-3 3531 3538 3563
-3 3532 4063 3542
-3 3037 3544 3534
-3 3544 3556 3534
-3 3535 3544 3037
-3 3038 3544 3535
-3 3544 3038 3040
-3 3545 3042 3041
-3 3545 3041 3546
-3 3041 3547 3546
-3 3524 3548 3536
-3 3536 3548 3561
-3 3562 3536 3561
-3 3538 3536 3562
-3 3526 3563 3549
-3 3541 3540 3550
-3 3550 3540 3564
-3 3541 3550 3527
-3 4063 3049 3553
-3 4063 3532 3049
-3 4063 3553 3542
-3 3533 3554 3039
-3 3577 3554 3533
-3 3543 3555 3521
-3 3528 3570 3543
-3 3571 3570 3528
-3 3534 3556 3571
-3 3040 3557 3544
-3 3546 3559 3558
-3 3546 3558 3545
-3 3545 3558 3560
-3 3042 3560 3041
-3 3545 3560 3042
-3 3548 3547 3573
-3 3573 3547 3041
-3 3561 3548 3573
-3 3538 4069 3563
-3 2611 3550 3564
-3 3552 3565 5316
-3 3551 3565 3552
-3 3551 3047 3565
-3 3551 3048 3047
-3 3542 3553 3566
-3 3577 3576 3554
-3 3521 3579 3577
-3 3555 3567 3521
-3 3567 3579 3521
-3 3543 3568 3555
-3 3568 3567 3555
-3 3569 3568 3543
-3 3570 3569 3543
-3 3557 3556 3544
-3 3040 3056 3557
-3 3557 3056 3582
-3 3560 3558 3572
-3 3560 3572 3041
-3 3050 3573 3041
-3 3549 3563 3585
-3 3564 3061 3575
-3 2611 3575 3054
-3 3564 3575 2611
-3 3565 3066 5316
-3 3047 3066 3565
-3 3048 3551 3068
-3 3039 4081 3078
-3 4081 3039 4072
-3 3554 4074 3039
-3 4074 3554 3576
-3 3579 3578 3577
-3 3567 3580 3579
-3 3568 3580 3567
-3 3569 3581 3568
-3 3556 3582 3571
-3 3557 3582 3556
-3 3057 3589 3069
-3 3057 3058 3589
-3 3593 3558 3559
-3 3572 3558 3593
-3 3572 3583 3050
-3 3050 3583 3573
-3 3583 3561 3573
-3 3584 3561 3585
-3 3563 3584 3585
-3 3549 3585 3081
-3 3598 3599 3574
-3 3586 3054 3575
-3 5316 3066 3065
-3 3611 3566 3553
-3 3577 4074 3576
-3 4089 4074 3577
-3 3578 4089 3577
-3 3579 4089 3578
-3 3580 4089 3579
-3 3580 3568 4083
-3 3581 3588 3568
-3 3588 4083 3568
-3 3569 3588 3581
-3 3570 3588 3569
-3 3571 3604 3570
-3 3604 3588 3570
-3 3582 3604 3571
-3 3056 3589 3582
-3 3056 3069 3589
-3 3058 3590 3589
-3 3058 3591 3590
-3 3074 3591 3058
-3 3591 3074 3592
-3 3559 3594 3593
-3 3572 3593 3595
-3 3583 3572 3596
-3 3596 3572 3595
-3 3585 3561 3597
-3 3599 3609 3052
-3 3061 3071 3600
-3 3575 3061 3600
-3 3062 3601 3085
-3 3586 3601 3062
-3 3065 3602 5316
-3 3068 3602 3065
-3 3566 3611 3603
-3 3566 3603 3612
-3 3587 2279 3055
-3 3604 4083 3588
-3 3605 3604 3582
-3 4085 3582 3589
-3 3590 4085 3589
-3 3074 3606 3592
-3 3594 3606 3593
-3 3583 3596 3615
-3 3561 3583 3615
-3 3597 3561 3615
-3 3585 3597 3607
-3 3081 3585 3619
-3 3598 3070 3608
-3 3599 3598 3609
-3 3609 3598 3608
-3 3610 3600 3076
-3 3600 3071 3076
-3 3601 3076 3085
-3 3553 3088 3611
-3 3603 3611 3612
-3 5338 3587 2278
-3 3613 3606 3074
-3 3613 3593 3606
-3 3595 3593 3613
-3 3596 3595 3614
-3 3614 3595 3613
-3 3615 3596 3614
-3 3597 3615 3617
-3 3617 3615 3616
-3 3607 3597 3618
-3 3618 3597 3617
-3 3585 3607 3625
-3 3625 3607 3618
-3 3619 3585 3625
-3 3626 3608 3070
-3 3609 3608 3620
-3 3620 3608 3626
-3 3612 3611 3621
-3 3621 3611 3088
-3 3078 4081 4097
-3 3622 3613 3080
-3 3622 3614 3613
-3 3615 3614 3623
-3 3623 3614 3622
-3 3623 4697 3616
-3 3623 3616 3615
-3 3617 3616 4697
-3 3624 3617 4697
-3 3617 3624 3618
-3 3625 3618 3624
-3 3627 3612 3621
-3 4672 3612 3627
-3 3094 3644 3622
-3 3644 3623 3622
-3 3644 3636 3623
-3 3625 3624 3628
-3 3619 3625 3629
-3 3639 3619 3629
-3 3630 3619 3639
-3 3089 3631 3626
-3 3621 3088 3632
-3 3632 4116 3621
-3 4116 4117 3621
-3 3627 3621 3633
-3 3633 3621 4117
-3 3643 4672 3627
-3 3643 3627 3633
-3 2279 3635 3634
-3 4115 3637 3628
-3 3625 3628 3638
-3 3638 3628 3637
-3 3629 3625 3639
-3 3639 3625 3638
-3 3630 3639 3649
-3 3089 3630 3640
-3 3640 3630 3649
-3 3641 3089 3640
-3 3631 3089 3641
-3 3116 3626 3631
-3 4117 3643 3633
-3 3094 3098 3644
-3 3645 3636 3644
-3 3645 3644 3646
-3 3645 3646 4115
-3 3637 4115 3646
-3 3637 3646 3099
-3 3100 3637 3099
-3 3638 3637 3100
-3 3647 3638 3100
-3 3647 3639 3638
-3 3648 3639 3647
-3 3649 3639 3648
-3 3640 3649 3650
-3 3650 3641 3640
-3 3651 3116 3631
-3 3632 3642 3105
-3 4116 3632 3652
-3 3652 3632 3105
-3 3098 3102 3644
-3 3649 3648 3654
-3 3654 3648 3647
-3 3654 3650 3649
-3 4694 4168 3655
-3 3634 4694 3655
-3 3653 3634 3655
-3 3656 3653 3655
-3 3634 3653 3656
-3 3102 3657 3644
-3 3646 3644 3662
-3 3662 3644 3657
-3 3658 3650 3654
-3 3664 3116 3651
-3 3659 3660 3111
-3 3104 3672 3105
-3 3672 3652 3105
-3 3662 3657 3661
-3 3654 3115 3658
-3 3658 3115 3663
-3 3118 4162 3660
-3 3659 3118 3660
-3 3120 3665 3666
-3 3120 3111 3665
-3 4163 3652 3672
-3 3655 4168 3121
-3 3663 3115 3676
-3 3663 3676 3677
-3 3664 3668 3125
-3 3669 4162 3118
-3 3669 3118 3126
-3 3126 3127 3670
-3 3127 3120 3666
-3 3127 3666 3670
-3 3670 3666 3129
-3 3129 3665 3128
-3 3129 3666 3665
-3 3671 3128 3665
-3 3671 3132 3128
-3 4163 3672 3673
-3 4163 3674 3667
-3 3675 3667 3674
-3 4170 3667 3675
-3 3662 3661 3158
-3 3668 3677 3676
-3 3668 3676 3136
-3 3125 3668 3136
-3 3126 3678 3669
-3 3670 3678 3126
-3 3129 3678 3670
-3 3129 3128 3678
-3 3141 3679 3671
-3 3141 3671 3678
-3 3141 3678 3128
-3 3132 3671 3680
-3 3680 3671 3679
-3 3132 3143 3142
-3 3132 3680 3143
-3 3673 3672 3674
-3 4163 3673 3674
-3 3675 3674 3681
-3 3153 3679 3141
-3 3680 3679 3153
-3 3143 3680 3153
-3 3171 3681 3674
-3 3704 4170 3675
-3 3121 4168 3682
-3 3161 3688 3152
-3 3138 3152 3689
-3 3689 3152 3688
-3 3689 4189 3139
-3 3689 3139 3138
-3 3690 3139 4189
-3 3675 3681 3691
-3 3682 3706 3692
-3 3156 3165 3694
-3 3155 3165 3156
-3 4193 3684 3694
-3 3694 3684 3156
-3 4195 3684 4193
-3 3686 4196 3685
-3 3695 4196 3686
-3 3687 3695 3686
-3 3157 3696 3166
-3 3688 3161 3697
-3 3177 3170 4833
-3 4833 3170 3690
-3 3180 3691 3681
-3 3704 3691 3180
-3 3675 3691 3704
-3 3717 4180 3704
-3 3692 3706 3720
-3 3165 2719 3694
-3 4193 3694 2719
-3 3684 4195 3714
-3 3699 3700 3701
-3 3173 3701 3696
-3 3173 3699 3701
-3 3702 3175 3701
-3 3696 3701 3175
-3 3696 3175 3166
-3 3161 3703 3697
-3 3177 3703 3161
-3 3703 3177 4833
-3 3717 3704 3198
-3 3705 4180 3717
-3 3692 3720 3707
-3 3682 3692 3707
-3 3708 3710 3711
-3 3709 3710 3708
-3 3710 3712 3711
-3 4841 4193 2719
-3 3714 3727 3713
-3 3715 3700 3699
-3 3173 3185 3715
-3 3173 3715 3699
-3 4190 3705 3718
-3 3706 4190 3718
-3 3719 3706 3718
-3 3720 3706 3719
-3 3183 3721 3184
-3 3184 3728 2708
-3 3721 3728 3184
-3 2708 3728 2718
-3 3708 3722 3709
-3 3722 3723 3724
-3 3722 3708 3723
-3 3708 3711 3723
-3 3725 3711 3712
-3 3723 3711 3725
-3 4841 2719 3726
-3 3185 4211 3715
-3 4211 3185 3716
-3 3705 3717 3731
-3 3718 3705 3731
-3 3720 3719 3718
-3 3183 3186 3721
-3 3728 3189 2718
-3 3723 3729 3724
-3 3725 3729 3723
-3 4841 3726 4223
-3 3726 3713 4223
-3 3727 3730 3713
-3 3730 4223 3713
-3 3187 3189 3733
-3 3733 3189 3728
-3 3734 3186 3732
-3 3188 3734 3732
-3 3188 3735 3734
-3 3188 3187 3735
-3 3735 3187 3733
-3 3193 3192 3736
-3 3193 3737 3194
-3 3736 3737 3193
-3 3194 3738 3196
-3 3737 3738 3194
-3 3196 3738 3197
-3 3199 3736 3192
-3 3737 3736 3199
-3 3200 3737 3199
-3 3738 3737 3200
-3 3197 3738 3200
-3 3202 3206 4254
-3 3206 4253 4254
-3 3202 4254 3740
-3 3202 3740 3739
-3 3739 3740 3208
-3 4253 3206 3209
-3 3741 4253 3209
-3 3740 4254 3742
-3 3740 3742 3213
-3 3208 3740 3213
-3 3743 3744 3745
-3 3745 3746 3743
-3 3212 3747 3741
-3 3212 3741 3209
-3 3212 3213 3748
-3 3742 3748 3213
-3 3749 3750 3214
-3 3743 3746 3761
-3 3751 3752 3746
-3 3752 3761 3746
-3 3752 3753 3754
-3 3751 3753 3752
-3 3741 3755 3756
-3 3741 3747 3755
-3 3212 3757 3747
-3 3758 3748 4268
-3 3758 3757 3748
-3 3757 3212 3748
-3 3215 3749 3214
-3 3215 3759 3749
-3 3750 3749 3760
-3 3760 3749 3759
-3 3217 3760 3218
-3 3217 3750 3760
-3 3754 3762 3752
-3 3762 3761 3752
-3 3774 3754 3753
-3 3762 3754 3774
-3 3219 3778 3779
-3 3763 4266 4262
-3 4267 3764 4262
-3 3764 3763 4262
-3 3765 3764 4267
-3 3223 3221 3766
-3 3756 3755 3223
-3 3756 3223 3766
-3 3224 3223 3755
-3 3224 3755 3767
-3 3767 3755 3747
-3 3757 3768 3747
-3 3768 3767 3747
-3 3758 3769 3757
-3 3769 3768 3757
-3 3769 3770 3771
-3 3758 3770 3769
-3 3770 3772 3771
-3 3771 3772 3215
-3 3759 3215 3772
-3 3760 3759 2774
-3 3760 2774 3218
-3 3761 3762 3773
-3 3774 3775 3762
-3 3775 3773 3762
-3 3775 4277 3776
-3 3774 4277 3775
-3 3234 3777 3235
-3 3778 3219 3227
-3 3778 3227 4278
-3 3220 3779 3228
-3 3228 3779 4279
-3 4279 3229 3228
-3 3780 4266 3763
-3 3764 3781 3763
-3 3781 3780 3763
-3 3765 3231 3781
-3 3765 3781 3764
-3 3765 3796 3230
-3 3782 3783 3246
-3 3246 3783 3247
-3 3783 3766 3247
-3 3766 3221 3247
-3 3224 3767 3233
-3 3784 3768 3785
-3 3784 3767 3768
-3 3769 3785 3768
-3 3786 3785 3769
-3 3769 3771 3786
-3 3801 3786 3771
-3 3771 2778 3801
-3 4285 3249 2774
-3 3775 3790 3773
-3 3790 3789 3773
-3 3776 3790 3775
-3 3791 3776 4277
-3 3791 3790 3776
-3 3234 3255 3807
-3 3235 3777 3793
-3 3794 3237 3793
-3 3237 3235 3793
-3 3237 3239 3238
-3 3794 3239 3237
-3 4278 3227 3795
-3 3229 4279 3821
-3 3250 3229 3821
-3 3780 3781 4294
-3 3231 3251 4294
-3 3781 3231 4294
-3 3244 3230 3796
-3 4296 3783 3797
-3 3783 3782 3797
-3 3246 3797 3782
-3 3767 4297 3798
-3 3767 3798 3233
-3 3233 3798 3812
-3 3784 4297 3767
-3 3802 3801 2778
-3 2778 3248 3802
-3 3248 3249 4285
-3 3248 4285 3802
-3 3254 3803 3787
-3 3787 3260 3254
-3 3804 3787 3788
-3 3804 3260 3787
-3 3805 3790 3791
-3 3792 3805 3791
-3 3807 3255 3806
-3 3794 3819 2790
-3 3239 3794 2790
-3 3795 3227 3820
-3 4294 3251 3823
-3 3808 3835 3244
-3 3808 3244 3809
-3 3809 3244 3796
-3 3810 4296 3797
-3 3811 3810 3797
-3 3246 3811 3797
-3 3812 3813 4306
-3 3812 3798 3813
-3 3803 3254 3814
-3 3814 3254 3253
-3 4314 3260 3804
-3 3817 3831 3818
-3 3255 3264 3806
-3 3821 3820 3250
-3 3821 3822 3820
-3 3822 3833 3268
-3 3821 3833 3822
-3 3256 3823 3251
-3 3257 3824 3825
-3 3257 3825 3256
-3 3256 3825 3823
-3 3809 3825 3824
-3 3809 3824 3808
-3 3808 3824 3826
-3 3808 3826 3835
-3 3827 3810 3811
-3 3811 3271 3827
-3 3812 4306 3830
-3 3258 3830 3829
-3 3258 3812 3830
-3 4320 3253 3259
-3 3260 4314 3273
-3 3261 3815 3816
-3 3263 3261 3816
-3 3817 3263 3816
-3 3818 3263 3817
-3 3274 3263 3818
-3 3274 3818 3831
-3 3264 3286 3806
-3 3255 3819 3266
-3 3795 3820 3843
-3 3822 3267 3843
-3 3822 3843 3820
-3 3257 3834 3824
-3 3834 3826 3824
-3 3826 3834 3835
-3 3271 3836 3828
-3 3830 3836 3829
-3 3829 3836 3837
-3 3829 3837 3258
-3 3259 2814 4330
-3 4330 4320 3259
-3 3273 4314 4332
-3 3261 3285 3815
-3 3831 3838 3274
-3 3839 3831 3832
-3 3839 3840 3831
-3 3840 3838 3831
-3 3286 3842 3806
-3 3267 3277 3843
-3 3835 3834 3280
-3 3270 3835 3280
-3 3293 3836 3271
-3 3293 3837 3836
-3 3837 3293 3258
-3 2814 3294 4331
-3 2814 4331 4330
-3 3294 3283 3282
-3 3294 3282 4331
-3 4331 3282 4332
-3 4332 3282 3273
-3 3815 3285 4347
-3 4348 3838 4340
-3 3840 4340 3838
-3 3841 3296 4335
-3 3844 3297 3841
-3 3297 3296 3841
-3 3844 3286 2819
-3 3844 4342 3286
-3 4342 3842 3286
-3 3266 4336 3276
-3 3288 3287 4913
-3 3287 4337 4913
-3 3312 3288 4913
-3 3277 3846 3843
-3 3289 3846 3277
-3 4338 4345 3301
-3 3285 2831 4347
-3 4348 4347 2831
-3 3838 4348 2831
-3 3296 3295 4335
-3 3844 2819 3297
-3 3287 3300 3850
-3 3287 3850 4337
-3 2825 3846 3289
-3 2825 3301 3846
-3 3846 3301 4345
-3 3863 3847 3302
-3 3847 3853 3302
-3 3853 3313 3302
-3 3304 3856 4335
-3 3295 3304 4335
-3 3848 3306 4336
-3 4336 3306 3276
-3 3299 3308 3848
-3 3845 3299 3848
-3 3309 3845 4357
-3 3310 3849 3311
-3 3851 3847 3863
-3 3314 3313 4361
-3 3313 3853 4361
-3 3314 4361 4362
-3 3854 3314 4362
-3 3316 3315 3855
-3 3316 3855 3856
-3 3316 3856 3304
-3 3306 3848 3858
-3 3848 3308 3858
-3 3309 4357 3859
-3 3309 3859 3327
-3 3849 3321 3860
-3 3310 3321 3849
-3 3311 3849 3861
-3 3849 3860 3861
-3 3862 3852 3851
-3 3863 3862 3851
-3 3314 3854 3864
-3 3314 3865 3322
-3 3864 3865 3314
-3 3855 3324 3866
-3 3315 3324 3855
-3 3325 3856 3855
-3 3325 3855 3866
-3 3326 4364 3856
-3 3857 4364 3326
-3 3327 3867 3320
-3 3860 3328 3868
-3 3321 3328 3860
-3 3868 4374 3861
-3 3868 3861 3860
-3 3311 3861 4374
-3 3311 4374 3869
-3 3850 3300 3329
-3 3347 3862 3863
-3 3871 3343 3870
-3 3864 3870 3343
-3 3344 3864 3343
-3 3865 3864 3332
-3 3322 3865 3332
-3 3858 3867 3339
-3 3328 2861 3868
-3 2861 3874 3868
-3 3311 3869 3345
-3 3345 3872 3877
-3 3345 3869 3872
-3 3872 3876 3877
-3 2863 4378 3329
-3 4378 2863 3312
-3 3347 3878 3862
-3 3343 3871 3342
-3 3338 3873 3857
-3 3867 3879 3339
-3 2861 3350 3874
-3 3877 3875 3346
-3 3345 3877 3346
-3 3342 4399 3348
-3 4395 3857 3873
-3 4395 3349 3879
-3 3349 3339 3879
-3 3880 3874 3350
-3 3880 3346 3875
-3 3880 3875 3881
-3 3877 3351 3881
-3 3877 3881 3875
-3 3877 3876 3356
-3 3882 3352 3883
-3 3882 3878 3352
-3 3878 3347 3352
-3 3348 3883 3884
-3 3348 4399 3883
-3 3882 3883 4399
-3 3348 3884 3358
-3 3885 3887 3888
-3 3886 3887 3885
-3 3887 4407 3888
-3 3889 4395 3873
-3 3354 3349 3889
-3 3349 4395 3889
-3 3874 3880 3361
-3 3880 3881 3361
-3 3881 3351 3361
-3 3356 3876 3357
-3 3876 3362 3357
-3 3353 3883 3352
-3 3353 3890 3883
-3 3890 3884 3883
-3 3358 3884 3891
-3 3884 3890 3891
-3 3893 3885 3892
-3 3892 3888 4407
-3 3892 3885 3888
-3 3891 3890 3353
-3 3361 3360 3894
-3 2881 3894 3360
-3 3896 3895 3898
-3 3895 3899 3898
-3 3900 3899 3895
-3 3904 3903 3897
-3 3903 3910 3897
-3 3899 3905 3898
-3 3906 3905 3899
-3 3900 3906 3899
-3 3906 3900 3907
-3 3900 3901 3907
-3 3908 3901 3902
-3 3907 3901 3908
-3 3909 3905 3906
-3 3909 3898 3905
-3 3904 3910 3903
-3 3913 3373 3372
-3 3374 3911 3376
-3 3374 3913 3911
-3 3374 3373 3913
-3 3912 3914 3911
-3 3914 3376 3911
-3 3916 3913 3372
-3 3376 3914 4473
-3 3372 3381 3916
-3 3376 4473 4486
-3 3376 4486 3377
-3 3920 3921 3919
-3 3916 3381 3929
-3 3377 4486 3382
-3 3384 3918 3917
-3 3385 3384 3917
-3 3917 5068 3385
-3 4476 3378 3385
-3 3378 3926 3387
-3 3378 4476 3926
-3 3379 3922 3380
-3 3923 3920 3919
-3 3924 3920 3923
-3 3925 3919 3921
-3 3923 3919 3925
-3 3922 3379 3927
-3 3380 3927 3389
-3 3922 3927 3380
-3 3923 2899 3924
-3 3923 3925 3928
-3 3923 3928 2899
-3 3929 3381 3383
-3 3929 3383 3401
-3 3401 3383 3382
-3 4506 3402 3382
-3 3384 3390 3918
-3 3387 3926 3395
-3 3927 3405 3930
-3 3379 3405 3927
-3 3389 3930 3397
-3 3927 3930 3389
-3 2898 3399 3924
-3 3399 3935 3924
-3 3400 2898 3924
-3 3924 2899 3400
-3 2899 3928 3936
-3 4506 3932 3402
-3 4506 3939 3932
-3 3933 3390 3940
-3 3940 3391 3942
-3 3391 3392 3934
-3 3942 3391 3934
-3 3392 3403 3934
-3 3397 3930 3405
-3 3407 3935 3406
-3 3931 3935 3407
-3 3399 3406 3935
-3 3401 3402 3937
-3 3402 3932 3937
-3 3937 3932 3938
-3 3939 3938 3932
-3 3940 3939 3933
-3 3942 3941 3940
-3 3934 3951 3942
-3 3931 3408 3952
-3 3407 3408 3931
-3 3943 3418 2899
-3 3943 2899 3936
-3 3937 5130 3401
-3 5130 3937 3946
-3 3937 3938 3946
-3 3939 3947 3938
-3 3947 3946 3938
-3 3948 3947 3939
-3 3940 3949 3939
-3 3949 3948 3939
-3 3941 3950 3940
-3 3950 3949 3940
-3 3942 3951 3941
-3 3951 3950 3941
-3 3408 3411 3952
-3 3408 3953 3412
-3 3953 3408 3954
-3 3413 4514 4511
-3 3944 3945 3943
-3 5130 3946 3956
-3 3946 3947 3956
-3 3948 3956 3947
-3 3949 3956 3948
-3 3951 3956 3949
-3 3950 3951 3949
-3 3957 4511 4513
-3 3957 3414 4511
-3 3414 3413 4511
-3 3427 5130 3956
-3 3414 3957 3958
-3 3957 4513 3958
-3 3414 3958 3959
-3 4514 3416 3960
-3 3960 3416 3420
-3 3960 3420 3959
-3 3960 3959 3961
-3 3960 3961 4525
-3 3427 3964 5130
-3 2917 3425 3962
-3 3963 3959 3958
-3 3961 3959 3963
-3 4525 3961 3963
-3 3427 3424 3964
-3 3966 2916 3429
-3 3430 3965 4529
-3 3431 3430 3966
-3 3429 3431 3966
-3 3967 3969 3970
-3 3968 3967 3970
-3 4532 3968 3970
-3 3971 4532 3970
-3 3970 3969 4545
-3 4548 3971 3970
-3 2520 3432 4578
-3 3432 3972 4578
-3 3433 3972 3432
-3 3433 3438 3972
-3 2520 4578 4582
-3 3438 3973 3972
-3 3440 3436 4588
-3 4588 3436 3975
-3 3974 3973 2923
-3 3973 3438 2923
-3 3974 3440 4588
-3 4588 3975 3977
-3 2923 3441 3974
-3 3440 3974 3441
-3 3980 3977 3975
-3 3975 2180 3980
-3 3980 3979 3977
-3 4601 3980 2180
-3 4582 3986 2522
-3 3984 3981 3983
-3 3982 3983 3981
-3 3983 3982 4605
-3 3983 3985 3984
-3 3983 3446 3985
-3 3986 3987 2522
-3 3987 3995 2522
-3 3987 3986 3988
-3 3988 3986 3989
-3 3986 3990 3989
-3 3446 4002 3991
-3 3446 3991 3985
-3 3983 4605 3448
-3 4605 4611 3448
-3 2180 4051 5237
-3 3992 3993 3994
-3 3994 3993 4621
-3 3987 3996 3995
-3 3988 3997 3987
-3 3997 3996 3987
-3 3998 3989 3999
-3 3998 3997 3989
-3 3997 3988 3989
-3 3999 4000 4012
-3 3999 3989 4000
-3 4001 4000 3990
-3 3990 4000 3989
-3 4002 3449 4003
-3 4003 4004 4002
-3 4611 3449 3448
-3 4003 3449 4611
-3 3994 4006 4005
-3 3994 4005 3992
-3 3992 4005 4007
-3 3993 3992 4008
-3 4008 3992 4007
-3 4022 4621 3993
-3 4008 4022 3993
-3 4009 3995 3996
-3 4010 3997 4011
-3 4010 4009 3997
-3 4009 3996 3997
-3 3998 4011 3997
-3 4001 4012 4000
-3 4013 4002 3452
-3 4013 3991 4002
-3 3452 4002 3449
-3 4004 4014 4002
-3 3449 4002 4014
-3 3453 3449 4015
-3 3449 4014 4015
-3 4015 3454 3453
-3 4016 3454 4015
-3 4017 4005 4006
-3 4007 4005 4018
-3 4018 4005 4017
-3 4022 4008 4018
-3 4018 4008 4007
-3 4009 4019 3455
-3 3995 4009 3455
-3 4019 4009 4010
-3 3451 4013 3452
-3 3457 4631 3451
-3 3451 4631 4013
-3 4016 3457 3454
-3 4631 3457 4016
-3 4021 4006 4031
-3 4017 4006 4021
-3 4017 4021 3458
-3 4017 4022 4018
-3 3459 3455 4019
-3 3459 4019 4023
-3 4023 4019 3461
-3 3461 4019 4010
-3 4021 4031 4024
-3 3458 4021 4025
-3 4021 4024 4025
-3 3458 4025 4017
-3 4022 4017 4025
-3 4023 4026 3460
-3 3459 4023 3460
-3 3461 4026 4023
-3 4024 4031 4027
-3 3462 4025 4024
-3 3464 3460 4026
-3 3464 4026 4028
-3 4028 4026 4029
-3 3461 4030 4026
-3 4030 4029 4026
-3 4030 3461 4010
-3 3481 4028 4032
-3 4032 4028 4029
-3 4030 4032 4029
-3 4033 4031 3472
-3 4033 4027 4031
-3 3462 4027 4033
-3 3477 3476 4034
-3 3477 4034 3475
-3 3472 4031 3496
-3 4033 3480 4642
-3 3462 4033 4642
-3 3476 3486 4034
-3 3475 4034 3486
-3 3493 3481 4032
-3 3493 4032 4647
-3 4647 4032 4629
-3 4035 4036 4636
-3 4636 4037 4035
-3 4038 4039 4036
-3 4035 4038 4036
-3 4035 3490 4038
-3 4035 3491 3490
-3 3491 4040 3492
-3 3491 4037 4040
-3 3491 4035 4037
-3 4040 4638 3492
-3 4041 4039 4038
-3 3490 3494 4042
-3 3490 4042 4038
-3 4038 4042 4041
-3 3494 4043 4042
-3 3492 4043 3494
-3 3492 4044 4043
-3 4638 4044 3492
-3 4045 4039 4041
-3 4042 4046 4041
-3 4046 4045 4041
-3 4046 4042 4043
-3 4045 4047 4039
-3 4046 4047 4045
-3 4647 3502 3493
-3 3502 4647 3507
-3 4642 3501 5261
-3 3507 4647 4050
-3 4050 3508 3507
-3 3509 3508 4050
-3 3496 4702 1936
-3 5261 3501 4052
-3 3510 3509 4050
-3 4050 5269 3510
-3 3510 4053 3511
-3 3510 5269 4053
-3 3511 4053 3514
-3 4052 3532 5285
-3 3514 4054 3517
-3 4053 4054 3514
-3 4055 3524 3525
-3 4056 4055 3525
-3 3517 4054 3531
-3 5285 3532 4057
-3 4058 5285 4057
-3 4059 3524 4055
-3 3525 3530 4056
-3 4056 3530 4060
-3 4054 4061 3531
-3 3532 3542 4057
-3 4059 4066 3524
-3 3530 4062 4060
-3 3537 4062 3530
-3 4061 3537 3531
-3 4062 3537 4061
-3 3542 3566 4057
-3 4058 4057 3566
-3 3547 4065 3546
-3 3546 4065 4064
-3 3548 4066 3547
-3 3547 4066 4065
-3 4066 3548 3524
-3 4067 3551 3552
-3 3546 4064 3559
-3 3562 3561 4068
-3 3562 4069 3538
-3 4068 4069 3562
-3 4067 3552 5316
-3 4672 4058 3566
-3 4676 3559 4064
-3 4068 3584 4071
-3 3561 3584 4068
-3 3563 4069 4071
-3 4069 4068 4071
-3 3551 4070 3068
-3 4072 3039 4073
-3 3039 4074 4073
-3 3563 4071 3584
-3 3586 3575 4678
-3 4075 3586 4678
-3 4073 4082 4072
-3 4074 4082 4073
-3 4089 3580 4083
-3 4077 3559 4676
-3 4077 3594 3559
-3 4678 3575 3600
-3 4078 4678 3600
-3 3586 4075 3601
-3 4075 4079 3601
-3 5316 3602 4080
-3 4080 3602 4070
-3 4070 3602 3068
-3 3612 4672 3566
-3 3587 4076 5326
-3 4076 3587 5338
-3 4082 4081 4072
-3 4084 3604 3605
-3 4085 3590 3592
-3 3591 3592 3590
-3 3592 3606 4690
-3 3606 3594 4690
-3 4690 3594 4077
-3 3610 4087 4086
-3 3610 4086 4078
-3 3610 4078 3600
-3 3610 3076 4087
-3 4079 3076 3601
-3 4686 3076 4079
-3 5326 2279 3587
-3 4082 4097 4081
-3 4083 3604 4122
-3 3582 4108 3605
-3 3592 4099 4085
-3 4099 3592 4695
-3 4090 4078 4092
-3 4091 4078 4090
-3 4078 4086 4092
-3 4086 4093 4092
-3 4093 4087 4094
-3 4093 4086 4087
-3 3076 4094 4087
-3 3076 4686 4094
-3 4683 3634 3635
-3 3604 4105 4122
-3 4107 4105 3604
-3 4084 4107 3604
-3 4098 4107 4084
-3 3605 4098 4084
-3 4108 4098 3605
-3 4720 4108 3582
-3 3582 4085 4720
-3 4099 4720 4085
-3 3623 4100 4697
-3 3628 3624 4697
-3 4090 4101 4091
-3 4092 4101 4090
-3 4093 4101 4092
-3 4111 4095 4102
-3 4103 4095 4096
-3 4102 4095 4103
-3 4082 4112 4097
-3 4074 4112 4082
-3 4089 4104 4074
-3 4083 4122 4089
-3 4122 4121 4089
-3 4107 4106 4105
-3 4124 4107 4098
-3 4108 4124 4098
-3 4720 4099 4704
-3 4721 4099 4695
-3 3623 3636 4100
-3 4100 3636 4114
-3 4110 4111 4102
-3 4110 4102 4103
-3 4672 3643 4118
-3 4672 4118 4714
-3 3634 4683 4694
-3 4104 4112 4074
-3 4104 4089 4733
-3 4105 4746 4122
-3 4106 4746 4105
-3 4107 4123 4106
-3 4124 4123 4107
-3 4108 4141 4124
-3 4099 4721 4704
-3 4113 4114 3636
-3 4128 4115 3628
-3 4109 3631 3641
-3 4109 4725 3631
-3 4714 4118 4119
-3 4714 4119 4132
-3 1697 4097 4120
-3 4120 4097 4112
-3 4120 4104 4731
-3 4120 4112 4104
-3 4121 4733 4089
-3 4125 4734 4721
-3 4126 4114 4113
-3 4136 4114 4126
-3 3636 3645 4127
-3 3636 4127 4113
-3 4113 4127 4126
-3 4115 4128 3645
-3 4127 3645 4128
-3 3641 3650 4109
-3 4109 3650 5374
-3 4725 3651 3631
-3 4138 3651 4725
-3 4117 4116 3652
-3 3652 4129 4117
-3 4117 4130 3643
-3 4117 4129 4130
-3 3643 4130 4118
-3 4131 4132 4118
-3 4118 4132 4119
-3 5338 2278 3683
-3 1697 4120 4731
-3 4121 4134 4733
-3 4134 4133 4733
-3 4766 4134 4122
-3 4134 4121 4122
-3 4746 4106 4782
-3 4123 4782 4106
-3 4124 4135 4123
-3 4141 4135 4124
-3 4136 4126 4137
-3 4127 4137 4126
-3 4142 4127 4128
-3 4129 3652 4148
-3 4130 4129 4139
-3 4139 4129 4148
-3 4140 4130 4139
-3 4118 4130 4140
-3 4755 4118 4140
-3 4131 4118 4755
-3 4741 4132 4758
-3 4135 4141 4123
-3 4141 4782 4123
-3 4136 4137 4154
-3 4127 4142 4137
-3 4142 4154 4137
-3 3658 5374 3650
-3 3651 4138 3664
-3 4143 4147 4145
-3 4144 4147 4143
-3 4146 4145 4147
-3 3111 3660 4774
-3 4845 3036 4702
-3 4139 4148 4149
-3 4150 4140 4139
-3 4150 4139 4149
-3 4152 4153 4166
-3 1697 4731 4780
-3 4155 4154 4142
-3 4156 5374 3658
-3 3658 3663 4156
-3 4157 4144 4143
-3 4158 4144 4157
-3 4145 4159 4143
-3 4159 4157 4143
-3 4160 4159 4145
-3 4146 4160 4145
-3 4147 4161 4146
-3 4161 4160 4146
-3 3660 4162 4147
-3 4162 4161 4147
-3 3111 4774 4802
-3 3665 3111 4802
-3 3652 4163 4148
-3 4149 4148 4164
-3 4164 4148 4163
-3 4150 4149 3667
-3 3667 4149 4164
-3 4151 4150 3667
-3 4151 3667 4775
-3 3667 4171 4775
-3 4165 4166 4167
-3 4166 4165 4152
-3 3663 4806 4786
-3 3663 4786 4156
-3 3663 3677 4806
-3 3664 4806 3668
-3 3664 4138 4806
-3 4157 4800 4158
-3 4159 4800 4157
-3 4160 4800 4159
-3 4172 4800 4160
-3 4161 4172 4160
-3 4162 3669 4161
-3 3665 4802 3671
-3 3667 4164 4163
-3 3667 4170 4171
-3 4167 4171 4170
-3 4167 4170 4165
-3 4165 4170 4152
-3 4763 3682 4168
-3 3668 4806 3677
-3 3669 4172 4161
-3 3678 4172 3669
-3 3678 4801 4172
-3 4802 4801 3678
-3 3671 4802 3678
-3 4170 3704 4152
-3 4762 4152 3704
-3 4763 4184 3682
-3 4173 4174 4175
-3 4175 4176 4177
-3 4174 4176 4175
-3 4176 4178 4177
-3 3704 4180 4762
-3 4181 4182 4183
-3 3706 3682 4184
-3 4175 4174 4173
-3 4177 4174 4175
-3 1697 4780 4838
-3 4179 4185 3685
-3 3685 4185 3686
-3 4185 3687 3686
-3 4186 3687 4185
-3 4187 4815 4188
-3 4188 3689 3688
-3 4188 4815 3689
-3 3689 4815 4189
-3 4190 4181 4180
-3 4182 4181 4190
-3 4183 4182 4190
-3 4184 4183 4190
-3 3706 4184 4190
-3 4192 3693 4191
-3 4193 4194 4195
-3 3685 4196 4835
-3 3695 3687 4197
-3 3687 4186 4197
-3 4188 4198 4187
-3 3688 4198 4188
-3 3688 3697 4198
-3 3690 4189 4833
-3 4190 4180 3705
-3 3693 4199 4191
-3 4192 3698 3693
-3 4192 4199 3698
-3 3693 3698 4199
-3 4204 4194 4193
-3 4195 4194 4204
-3 4835 4196 4200
-3 3695 4200 4196
-3 4201 3701 4197
-3 4201 4202 3701
-3 4197 3701 3695
-3 3700 4200 3701
-3 3695 3701 4200
-3 3701 4202 3702
-3 3697 4832 4198
-3 3697 3703 4832
-3 4833 4832 3703
-3 3709 4203 3710
-3 3710 4203 3712
-3 4193 4841 4204
-3 4205 4195 4204
-3 3714 4195 4205
-3 3714 4205 4206
-3 4202 4207 4208
-3 4202 4201 4207
-3 4208 4207 3715
-3 4200 3700 4207
-3 3715 4207 3700
-3 3702 4202 4208
-3 3702 4208 4837
-3 3702 4837 3175
-3 4837 4208 4209
-3 4837 3716 3175
-3 3683 2278 4237
-3 3683 4237 4823
-3 3724 3709 3722
-3 3724 4210 3709
-3 4210 4203 3709
-3 3712 4210 3725
-3 4203 4210 3712
-3 4206 4846 3727
-3 4206 3727 3714
-3 4208 4211 4209
-3 4208 3715 4211
-3 4837 4211 3716
-3 3721 4212 5455
-3 3721 3186 4212
-3 3721 5455 4213
-3 4213 3728 3721
-3 4850 1697 4838
-3 3724 3729 4210
-3 3725 4210 3729
-3 4214 4215 4216
-3 4216 4217 4214
-3 4846 4229 3730
-3 3727 4846 3730
-3 4218 4219 4212
-3 4218 4212 3186
-3 3733 3728 4213
-3 4220 4215 4214
-3 4221 4215 4220
-3 4217 4222 4214
-3 4222 4220 4214
-3 4223 3730 4229
-3 4224 4219 4218
-3 4225 4219 4224
-3 3186 3734 4224
-3 4218 3186 4224
-3 3735 3733 4236
-3 4220 4226 4221
-3 4222 4226 4220
-3 4227 4226 4222
-3 4229 4228 4223
-3 4232 4245 4234
-3 4233 4245 4232
-3 4248 4225 4224
-3 4235 4225 4248
-3 3734 4236 4224
-3 4224 4236 4248
-3 3735 4236 3734
-3 4229 4238 4228
-3 4239 4229 4846
-3 4239 4238 4229
-3 4239 4231 4240
-3 4231 4230 4240
-3 4230 4241 4240
-3 4242 4230 4231
-3 4241 4230 4242
-3 4232 4244 4233
-3 4244 4232 4243
-3 4232 4234 4243
-3 4245 4243 4234
-3 4243 4246 4247
-3 4245 4246 4243
-3 4869 4228 4238
-3 4869 4238 4239
-3 4249 4239 4240
-3 4241 4249 4240
-3 4249 4241 4242
-3 4243 4250 4244
-3 4247 4250 4243
-3 4870 4239 4251
-3 4239 4249 4251
-3 4252 4251 4249
-3 4256 4249 4242
-3 4256 4252 4249
-3 4870 4255 4260
-3 4870 4251 4255
-3 4251 4252 4255
-3 4256 4255 4252
-3 3741 4257 4253
-3 4254 4257 3742
-3 4254 4253 4257
-3 3745 3744 4258
-3 4259 3745 4258
-3 4259 4871 3745
-3 4871 3746 3745
-3 4871 3751 3746
-3 4260 4255 4261
-3 4256 4261 4255
-3 4256 4262 4261
-3 4872 4257 3741
-3 4872 3742 4257
-3 4872 3748 3742
-3 3744 3743 4258
-3 3743 3761 4276
-3 3743 4276 4259
-3 3743 4259 4258
-3 4263 3751 4871
-3 3753 3751 4264
-3 3751 4263 4264
-3 4265 3753 4264
-3 1697 4850 4373
-3 4270 4260 4261
-3 4266 4270 4261
-3 4262 4266 4261
-3 3741 3756 4872
-3 4269 4268 3748
-3 4269 4272 4268
-3 4277 3774 4265
-3 4265 3774 3753
-3 4271 3765 4267
-3 4872 3756 3766
-3 3770 3758 4268
-3 4272 3770 4268
-3 3770 4272 3772
-3 3772 4272 4274
-3 4273 3759 4274
-3 3759 3772 4274
-3 4273 2774 3759
-3 4275 4276 3761
-3 3761 3773 4275
-3 3777 3234 4874
-3 4882 3777 4874
-3 3778 4279 3779
-3 4278 4279 3778
-3 4266 4293 4270
-3 4293 4266 3780
-3 3765 4280 3796
-3 4271 4280 3765
-3 4296 4281 3783
-3 3783 4281 3766
-3 3785 3786 4282
-3 3784 3785 4282
-3 4283 4284 4274
-3 4274 4284 4273
-3 4273 4284 4285
-3 2774 4273 4285
-3 3787 4299 4276
-3 3788 4275 4286
-3 3788 4276 4275
-3 3788 3787 4276
-3 3773 3789 4286
-3 4275 3773 4286
-3 4277 4302 3791
-3 3791 4302 3792
-3 3234 3807 4874
-3 3794 3793 3777
-3 3794 3777 4287
-3 4287 3777 4882
-3 4288 4289 4290
-3 4290 4886 4288
-3 4291 4279 4278
-3 4291 4278 3795
-3 4291 3795 4292
-3 3821 4279 4291
-3 4294 4884 3780
-3 3780 4884 4293
-3 4280 4884 4294
-3 4280 4294 4295
-3 4280 4295 3796
-3 4304 4281 4305
-3 4281 4296 4305
-3 4297 4309 3798
-3 3799 4297 3784
-3 3800 3799 3784
-3 3800 3784 4298
-3 4298 3784 4282
-3 3786 4298 4282
-3 3786 4885 4298
-3 4885 4311 4298
-3 4283 4885 3801
-3 4885 3786 3801
-3 3802 4283 3801
-3 4284 4283 3802
-3 4285 4284 3802
-3 3803 4299 3787
-3 3788 4286 3804
-3 3789 3804 4286
-3 3789 3790 4300
-3 3804 3789 4300
-3 3790 3805 4300
-3 4300 3805 4301
-3 4302 4301 3792
-3 4302 4303 4301
-3 4301 3805 3792
-3 4302 4893 4303
-3 3807 3806 4350
-3 3819 3794 4287
-3 3823 4295 4294
-3 3796 4295 3825
-3 3825 4295 3823
-3 3796 3825 3809
-3 4306 4307 4308
-3 4306 3813 4307
-3 4309 3813 3798
-3 3799 4319 4297
-3 4297 4319 4309
-3 3799 4310 4319
-3 3800 4310 3799
-3 3800 4311 4310
-3 3800 4298 4311
-3 3814 3253 4312
-3 3814 4312 4313
-3 3814 4313 3803
-3 3803 4313 4299
-3 4300 4314 3804
-3 4315 4314 4300
-3 4301 4315 4300
-3 4303 4315 4301
-3 3815 4315 4303
-3 3815 4303 3816
-3 4893 4316 4303
-3 3816 4303 4316
-3 3817 3816 4316
-3 4919 4317 3817
-3 3831 3817 4317
-3 3827 4308 4327
-3 3271 4308 3827
-3 3828 4306 4308
-3 3828 4308 3271
-3 4306 3836 3830
-3 4306 3828 3836
-3 4328 4309 4318
-3 4319 4318 4309
-3 3253 4320 4312
-3 4320 4321 4312
-3 4322 4313 4312
-3 4322 4312 4321
-3 3817 4316 4919
-3 3832 4324 4323
-3 3831 4324 3832
-3 3831 4317 4324
-3 4323 4324 4333
-3 4333 4325 4326
-3 4324 4325 4333
-3 3266 3819 4336
-3 4339 4304 4305
-3 4305 4296 4339
-3 3810 4339 4296
-3 3810 3827 4339
-3 4319 4328 4318
-3 4329 4328 4319
-3 4310 4329 4319
-3 4321 4320 4331
-3 4331 4320 4330
-3 4322 4321 4332
-3 4332 4321 4331
-3 4314 4906 4332
-3 4906 4322 4332
-3 3832 4323 3839
-3 3840 3839 4323
-3 3840 4323 4333
-3 4325 4334 4326
-3 4334 4333 4326
-3 3841 4335 4910
-3 4910 4911 3841
-3 3841 4911 3844
-3 4342 3844 4911
-3 3806 3842 4350
-3 4922 4913 4337
-3 3843 4344 3795
-3 3821 4338 3833
-3 4327 4339 3827
-3 4925 3815 4347
-3 3840 4333 4340
-3 4334 4341 4333
-3 4349 4341 4334
-3 3842 4342 4350
-3 4343 3795 4344
-3 3843 3846 4344
-3 4345 4338 4355
-3 4347 4348 4925
-3 4949 4348 4340
-3 4333 4949 4340
-3 4349 4333 4341
-3 4335 3856 4363
-3 4933 3312 4913
-3 4351 3795 4343
-3 4352 3795 4351
-3 4344 4351 4343
-3 3846 4353 4344
-3 4344 4353 4351
-3 3846 4345 4353
-3 4353 4345 4354
-3 4355 4356 4345
-3 4356 4354 4345
-3 4356 4346 3847
-3 4355 4346 4356
-3 3847 4346 3853
-3 3845 3848 4357
-3 4964 4337 3850
-3 4933 4379 3312
-3 4351 4353 4352
-3 4354 4358 4353
-3 4356 4359 4354
-3 4359 4358 4354
-3 3851 3852 4359
-3 3851 4359 4356
-3 3847 3851 4356
-3 4360 3853 4346
-3 4360 4368 3853
-3 4368 4361 3853
-3 4363 3856 4364
-3 4363 4364 4950
-3 4950 4364 4365
-3 4364 3857 4365
-3 3859 4357 4962
-3 4964 3850 4366
-3 4353 4380 4352
-3 4353 4358 4380
-3 4359 4367 4358
-3 4367 4380 4358
-3 3852 3862 4367
-3 4359 3852 4367
-3 4360 4382 4368
-3 4361 4368 4369
-3 4362 4361 3864
-3 3864 4361 4369
-3 4362 3864 3854
-3 3327 4372 3867
-3 3327 3859 4372
-3 3859 4962 4372
-3 4374 4375 3869
-3 4376 4377 3850
-3 4377 4366 3850
-3 3850 3329 4376
-3 4379 4378 3312
-3 4381 4380 4367
-3 3862 4381 4367
-3 4368 4382 4399
-3 3870 4399 3871
-3 3870 4369 4399
-3 4369 4368 4399
-3 3864 4369 3870
-3 4383 4371 4370
-3 4383 4370 4371
-3 4372 4384 3867
-3 3868 3874 4374
-3 4403 4385 4374
-3 4375 4374 4385
-3 4386 4375 4385
-3 3869 4375 4386
-3 3869 4386 3872
-3 3872 4386 4973
-3 3876 4387 4388
-3 3876 3872 4387
-3 3872 4973 4387
-3 4974 4376 4389
-3 4974 4388 4376
-3 4377 4376 4387
-3 4387 4376 4388
-3 3329 4389 4376
-3 4378 4389 3329
-3 4378 4390 4391
-3 4392 4378 4379
-3 4390 4378 4392
-3 3862 3878 4381
-3 3878 4382 4381
-3 3871 4399 3342
-3 4393 4383 4401
-3 4394 3857 4395
-3 4394 4395 4396
-3 4396 3879 3867
-3 4396 3867 4384
-3 3874 4403 4374
-3 3876 4388 4974
-3 4397 4391 4390
-3 4392 4398 4390
-3 4398 4397 4390
-3 4392 4416 4398
-3 3878 4399 4382
-3 4401 4402 4393
-3 4402 4400 4393
-3 4396 4395 3879
-3 4397 4404 4419
-3 4397 4398 4404
-3 4416 4404 4398
-3 3878 3882 4399
-3 4402 4405 4400
-3 4405 4402 4412
-3 3886 3885 4406
-3 3886 4407 3887
-3 4406 4407 3886
-3 4403 3874 3361
-3 4415 3362 4974
-3 3362 3876 4974
-3 4408 4419 4404
-3 4416 4409 4404
-3 4409 4408 4404
-3 4410 4400 4411
-3 4400 4405 4411
-3 4412 4413 4405
-3 4413 4411 4405
-3 4412 5012 4413
-3 4406 3893 4414
-3 3885 3893 4406
-3 4407 4414 3892
-3 4407 4406 4414
-3 4998 4990 4418
-3 3894 4415 3361
-3 3361 4415 4403
-3 3362 4415 3894
-3 3896 4416 3895
-3 3896 4409 4416
-3 3896 4408 4409
-3 4416 3900 3895
-3 4420 3900 4416
-3 4411 4417 4410
-3 3897 4417 4411
-3 3897 4411 4413
-3 4413 3904 3897
-3 4413 5021 3904
-3 4413 5012 5021
-3 3893 3892 4414
-3 4990 4425 4418
-3 3898 4419 4408
-3 3896 3898 4408
-3 3901 3900 5020
-3 3900 4420 5020
-3 5020 3902 3901
-3 4421 3902 5020
-3 3897 3910 4417
-3 4425 4424 4418
-3 4426 4427 4419
-3 4426 4419 3898
-3 3906 4428 4438
-3 3906 4439 4428
-3 3902 4421 3908
-3 4421 4429 3908
-3 3904 5021 5028
-3 4430 4431 4432
-3 4431 4433 4432
-3 4434 4423 4436
-3 4437 4424 4425
-3 5634 4426 4446
-3 3898 3909 4446
-3 4426 3898 4446
-3 3909 3906 4438
-3 3907 4449 4439
-3 3907 4439 3906
-3 3907 4440 4449
-3 3907 3908 4440
-3 3908 4429 4440
-3 3910 4441 4417
-3 5028 3910 3904
-3 4441 3910 5028
-3 4432 4442 4430
-3 4443 4442 4432
-3 4433 4443 4432
-3 4434 4444 4435
-3 4436 4444 4434
-3 4445 4437 4425
-3 4451 4445 4425
-3 3909 4447 4446
-3 4447 3909 4448
-3 3909 4438 4448
-3 4451 4450 4445
-3 4467 4451 4425
-3 4447 5634 4446
-3 3912 3911 5042
-3 3911 4452 5042
-3 4453 3912 5042
-3 4454 4456 4457
-3 4455 4456 4454
-3 4458 4445 4450
-3 4459 4445 4458
-3 4451 4460 4450
-3 4460 4458 4450
-3 4460 4451 4467
-3 3913 5075 3911
-3 3911 5075 4452
-3 3912 4453 3914
-3 4453 4473 3914
-3 4463 4455 4454
-3 4457 4464 4454
-3 4464 4463 4454
-3 4464 4457 4465
-3 4458 4466 4459
-3 4460 4466 4458
-3 4467 4466 4460
-3 4479 4461 4468
-3 4462 4469 4461
-3 4469 4468 4461
-3 4469 4462 4470
-3 4471 4472 3915
-3 3913 3916 5075
-3 3917 4474 4475
-3 4463 4476 5068
-3 4464 4477 4463
-3 4477 4476 4463
-3 4478 4464 4465
-3 4477 4464 4478
-3 4479 4468 4480
-3 4468 4469 4480
-3 4481 4469 4470
-3 4481 4482 4469
-3 4482 4480 4469
-3 4471 4482 4481
-3 4471 4483 4482
-3 3915 4483 4471
-3 4484 3915 4472
-3 4484 4472 4492
-3 3916 4485 4493
-3 3916 4493 5075
-3 4486 4473 4487
-3 3917 3918 4474
-3 3917 5067 5068
-3 3917 4475 5067
-3 5068 4476 3385
-3 3926 4476 4477
-3 5069 4477 4478
-3 4480 4488 4479
-3 3920 4488 4480
-3 3920 4480 4482
-3 3921 3920 4482
-3 3921 4482 4489
-3 4489 4482 4483
-3 4483 3915 4490
-3 4483 4490 4489
-3 3915 4484 4490
-3 4490 4484 4491
-3 4492 4491 4484
-3 3916 3929 4485
-3 4493 4485 4494
-3 4486 4493 4494
-3 4486 4494 3382
-3 3926 5069 5082
-3 4477 5069 3926
-3 3395 5088 4422
-3 4495 3924 4496
-3 4495 4488 3924
-3 4488 3920 3924
-3 4489 4495 3925
-3 4489 3925 3921
-3 3925 4495 4496
-3 4497 4489 4490
-3 4497 4490 4498
-3 4490 4491 4498
-3 4492 4498 4491
-3 4485 3929 4499
-3 4500 4501 4494
-3 4500 4494 4499
-3 4499 4494 4485
-3 4494 4502 3382
-3 4494 4501 4502
-3 4506 3382 4502
-3 4496 3924 4504
-3 4504 3924 4503
-3 3928 4504 5090
-3 3928 4496 4504
-3 3928 3925 4496
-3 3928 5090 3936
-3 4498 4505 4497
-3 5091 4498 4492
-3 4499 3929 3401
-3 4499 3401 4500
-3 3918 3390 4474
-3 4474 3390 5087
-3 3395 3926 5088
-3 5083 5095 3931
-3 3924 3935 4503
-3 3936 5090 4512
-3 4498 4507 4505
-3 5091 4507 4498
-3 4506 5094 3939
-3 3939 5094 5087
-3 3939 5087 3933
-3 3933 5087 3390
-3 3935 3931 5095
-3 3935 5095 5097
-3 5097 4503 3935
-3 5098 3944 4508
-3 5117 4500 3401
-3 5677 4237 2917
-3 4508 3943 3936
-3 3944 3943 4508
-3 3944 5104 4510
-3 3944 4510 3945
-3 3955 3945 4510
-3 3955 4510 4515
-3 3401 5130 5117
-3 3955 4515 5134
-3 4516 4517 5123
-3 3960 4518 4514
-3 3964 5129 5130
-3 4519 4517 4516
-3 4519 4516 4520
-3 4513 4521 3958
-3 4518 3960 4525
-3 3955 5134 3424
-3 3424 5134 4522
-3 5129 3964 4522
-3 4523 4519 4520
-3 4523 3966 4519
-3 3966 4523 2916
-3 4530 2916 4523
-3 4530 3962 2916
-3 3958 4521 3963
-3 4521 4524 3963
-3 4525 4524 4526
-3 4524 4525 3963
-3 4525 4526 4527
-3 3424 4522 3964
-3 4531 5643 5140
-3 4519 3966 4528
-3 3962 4530 2917
-3 5677 2917 4530
-3 4527 4524 4521
-3 4526 4524 4527
-3 3430 4529 4528
-3 4528 3966 3430
-3 4529 3965 4531
-3 3968 4536 3967
-3 4532 4533 3968
-3 3968 4533 4536
-3 4535 3969 3967
-3 4535 3967 4534
-3 4534 3967 4536
-3 4533 4532 4552
-3 4552 4532 3971
-3 4533 4552 4551
-3 4538 4537 4539
-3 4540 4541 5727
-3 5727 4541 4534
-3 4542 4534 4541
-3 4543 4534 4542
-3 4535 4534 4544
-3 4544 4534 4543
-3 3969 4535 4545
-3 4535 4544 4545
-3 4546 3970 4545
-3 4546 4547 3970
-3 3970 4547 4548
-3 4548 4560 3971
-3 4552 3971 4550
-3 4550 3971 4560
-3 4538 4554 4537
-3 4537 4554 4555
-3 4556 4537 4555
-3 4539 4537 4556
-3 5179 4541 4540
-3 5157 4541 5179
-3 4557 4541 5157
-3 4541 4557 4542
-3 4543 4542 4558
-3 4558 4542 4557
-3 4544 4543 4558
-3 4545 4544 4558
-3 4558 5159 4545
-3 4546 4545 5159
-3 4559 4548 4549
-3 4560 4548 4559
-3 4552 4550 4561
-3 4561 4550 4560
-3 4551 4552 4561
-3 4553 4551 4562
-3 4562 4551 4561
-3 4562 4563 4553
-3 4564 4565 4566
-3 5154 4556 4554
-3 4555 4554 4556
-3 4558 4557 5171
-3 5172 4558 5171
-3 4560 4559 4561
-3 4562 4561 4567
-3 4568 4562 4567
-3 4569 4563 4562
-3 4568 4569 4562
-3 5168 5177 4564
-3 5168 4570 5177
-3 4565 4564 5177
-3 4561 4559 4580
-3 4580 4567 4561
-3 4571 4568 4567
-3 4572 4573 4574
-3 4569 4568 4571
-3 4572 4574 4575
-3 4577 5174 4576
-3 4578 3972 4579
-3 5177 4570 5192
-3 4577 4576 4581
-3 4581 5187 4577
-3 5213 4579 4583
-3 5213 4582 4579
-3 4582 4578 4579
-3 3972 4583 4579
-3 3972 3974 4583
-3 3973 3974 3972
-3 4584 4586 4587
-3 4585 4584 4587
-3 4589 4590 4585
-3 4585 4590 4584
-3 4584 4590 4591
-3 4586 4584 4592
-3 4592 4584 4591
-3 4593 4587 4586
-3 4592 4593 4586
-3 3977 4600 4588
-3 4589 4594 3976
-3 3976 4595 4589
-3 4595 4590 4589
-3 4591 4590 4596
-3 4596 4590 4595
-3 4596 4592 4591
-3 4593 4592 4596
-3 4589 5235 4597
-3 4589 4597 4594
-3 4594 4597 4598
-3 3976 4594 4599
-3 4594 4598 4599
-3 3976 4599 4595
-3 4599 5238 4595
-3 5238 4596 4595
-3 4582 5213 5240
-3 4600 3977 3979
-3 3979 3980 4600
-3 4600 3980 4601
-3 4602 4597 5235
-3 4598 4597 4603
-3 4603 4597 4602
-3 4599 4598 5238
-3 5238 4598 4603
-3 4582 5240 3986
-3 4600 3981 4604
-3 4600 3982 3981
-3 3982 4600 4605
-3 4605 4600 4601
-3 5237 4605 4601
-3 5237 4601 2180
-3 4606 5235 4635
-3 5235 4606 4602
-3 4606 4603 4602
-3 5238 4603 4606
-3 4604 3984 4607
-3 3981 3984 4604
-3 4608 4604 4609
-3 4609 4604 4607
-3 4605 4608 4609
-3 5237 4608 4605
-3 4635 4610 4606
-3 4606 4610 4615
-3 3985 4607 3984
-3 4609 4607 4611
-3 4609 4611 4605
-3 4619 4612 5237
-3 4635 4613 4610
-3 4610 4613 4614
-3 4615 4610 4614
-3 5241 4606 4615
-3 4616 3986 5240
-3 4616 4617 3986
-3 3986 4617 3990
-3 3985 3991 4618
-3 4607 3985 4618
-3 4611 4607 4618
-3 4620 4612 4619
-3 5237 4051 4619
-3 4635 3994 4613
-3 4621 4613 3994
-3 4621 4614 4613
-3 4615 4614 5241
-3 5241 4614 4621
-3 4622 4616 5240
-3 4623 4616 4622
-3 3999 4623 3998
-3 3999 4617 4623
-3 4617 4616 4623
-3 4012 4617 3999
-3 4012 4624 4617
-3 3990 4617 4001
-3 4001 4617 4624
-3 3991 4625 4618
-3 4003 4625 4004
-3 4003 4611 4625
-3 4611 4618 4625
-3 4626 4627 4620
-3 4626 4619 4628
-3 4620 4619 4626
-3 4051 4628 4619
-3 4635 4006 3994
-3 4622 5240 4629
-3 4011 4629 4010
-3 4011 4622 4629
-3 4011 4623 4622
-3 3998 4623 4011
-3 4001 4624 4012
-3 4013 4625 3991
-3 4013 4630 4625
-3 4004 4625 4014
-3 4014 4625 4630
-3 4014 4631 4015
-3 4630 4631 4014
-3 4015 4631 4016
-3 4632 4627 4626
-3 4632 4626 4633
-3 4022 4642 4621
-3 4642 5241 4621
-3 4631 4630 4013
-3 4632 4634 4627
-3 4633 4634 4632
-3 4031 4006 4635
-3 4642 4022 4025
-3 4010 4629 4030
-3 4629 4032 4030
-3 4025 3462 4642
-3 4031 4635 3496
-3 4643 4647 4629
-3 4036 4039 5246
-3 4036 5246 4636
-3 5246 4637 4636
-3 4037 4638 4040
-3 4037 4636 4638
-3 4636 4637 4638
-3 5245 4637 5246
-3 4044 5245 4043
-3 4044 4637 5245
-3 4044 4638 4637
-3 4639 4046 5245
-3 4046 4043 5245
-3 4640 4039 4047
-3 4640 4641 4039
-3 4641 5246 4039
-3 4639 5249 4047
-3 4639 4047 4046
-3 4640 4047 5249
-3 4645 4644 4640
-3 4641 4640 4644
-3 5249 4645 4640
-3 4650 4644 4646
-3 4646 4644 4645
-3 4648 4649 4650
-3 4650 4646 4648
-3 4048 4651 4049
-3 4048 4652 4653
-3 4048 4049 4652
-3 4649 4653 4652
-3 4649 4648 4653
-3 4648 4656 4653
-3 4050 4647 4643
-3 4654 4655 4048
-3 4655 4651 4048
-3 4048 4653 4654
-3 4654 4653 4656
-3 4654 4657 4655
-3 4656 4657 4654
-3 5261 5256 4642
-3 4658 5261 4052
-3 5269 4050 5268
-3 5266 4659 4658
-3 4052 5266 4658
-3 4053 5269 5274
-3 5274 4660 4053
-3 4053 4660 4661
-3 4054 4053 4661
-3 4662 4660 5274
-3 4662 4661 4660
-3 4661 4061 4054
-3 4663 5285 4058
-3 4663 5292 5285
-3 4059 4055 4664
-3 4056 4060 4664
-3 4055 4056 4664
-3 4661 4662 4061
-3 4664 4665 4059
-3 4060 4062 4665
-3 4060 4665 4664
-3 4062 4061 4665
-3 4665 4061 4666
-3 4666 4061 4662
-3 5292 4663 4058
-3 4668 4064 4065
-3 4065 4066 4669
-3 4066 4059 4669
-3 4665 4670 4059
-3 5308 4670 4665
-3 5308 4665 4666
-3 5292 4058 4672
-3 4065 4669 4668
-3 4059 4670 4669
-3 4067 4671 5306
-3 5306 3551 4067
-3 5306 4070 3551
-3 4668 4673 4064
-3 4673 4676 4064
-3 4669 4674 4668
-3 4674 4673 4668
-3 4670 4677 4669
-3 4677 4674 4669
-3 4675 4677 4670
-3 4675 4670 5308
-3 4067 5316 4671
-3 5306 4679 4070
-3 4674 4677 4673
-3 5319 4677 4675
-3 4070 4679 5317
-3 4673 4077 4676
-3 4077 4673 4677
-3 4078 4680 4678
-3 4680 4681 4678
-3 4079 4678 4681
-3 4678 4079 4075
-3 5316 4080 5320
-3 4070 5317 5320
-3 4080 4070 5320
-3 4682 4683 4684
-3 5314 4682 4684
-3 4677 5327 4077
-3 4078 4685 4680
-3 4685 4686 4680
-3 4681 4680 4686
-3 4079 4681 4686
-3 4088 5320 4080
-3 5320 4088 4080
-3 4682 5324 4687
-3 4682 4687 4688
-3 4683 4682 4688
-3 5326 4076 5338
-3 4695 3592 4689
-3 3592 4690 4689
-3 4077 4696 4690
-3 4696 4077 5327
-3 4100 5327 5325
-3 5325 4697 4100
-3 4078 4091 4692
-3 4091 4691 4692
-3 4685 4078 4693
-3 4693 4078 4692
-3 4094 5331 4093
-3 4094 4685 5331
-3 4094 4686 4685
-3 4685 4693 5331
-3 4096 4095 5341
-3 4688 4687 4694
-3 4683 4688 4694
-3 4684 4683 3635
-3 4689 4722 4695
-3 3628 4697 4698
-3 4699 4091 4101
-3 4699 4700 4091
-3 4700 4691 4091
-3 4701 4699 4101
-3 4701 4101 5331
-3 4093 5331 4101
-3 4095 4111 5341
-3 5341 4103 4096
-3 5318 5298 4715
-3 4715 5298 4672
-3 5318 4715 4716
-3 4687 5324 4703
-3 4694 4687 4703
-3 4722 4721 4695
-3 4689 4705 4722
-3 4690 4706 4689
-3 4706 4690 4696
-3 3628 4698 4128
-3 4707 4708 4109
-3 4709 4700 4711
-3 4710 4700 4709
-3 4712 4699 4701
-3 4712 4711 4699
-3 4700 4699 4711
-3 4713 5341 4111
-3 4713 4110 5341
-3 4110 4103 5341
-3 4715 4672 4714
-3 4694 4703 4168
-3 4104 4733 4732
-3 4720 4719 4108
-3 4736 4722 4705
-3 4689 4723 4705
-3 4723 4736 4705
-3 4706 4723 4689
-3 4723 4706 4724
-3 4708 4725 4109
-3 4708 4726 4725
-3 4710 4709 4726
-3 4709 4727 4726
-3 4711 4728 4709
-3 4728 4727 4709
-3 4728 4711 4712
-3 4111 4110 4713
-3 4132 4741 4714
-3 4715 4714 4741
-3 4716 4715 4729
-3 4716 4729 4742
-3 4718 4717 4730
-3 4703 4718 4168
-3 4731 4104 4732
-3 4719 4141 4108
-3 4721 4734 4704
-3 4125 4721 4735
-3 4735 4721 4722
-3 4736 4785 4722
-3 4724 4738 4723
-3 4738 4737 4723
-3 4724 4749 4738
-3 4136 4750 4100
-3 4136 4100 4114
-3 4109 5374 4707
-3 4726 4752 4725
-3 4727 4739 4726
-3 4739 4752 4726
-3 4739 4728 4712
-3 4739 4727 4728
-3 4715 4741 4759
-3 4729 4715 4742
-3 4742 4715 4759
-3 4742 4761 4762
-3 4764 4730 4717
-3 4718 4730 4764
-3 4168 4718 4764
-3 4732 4745 4731
-3 4733 4745 4732
-3 4766 4122 4746
-3 4768 4719 4720
-3 4704 4769 4720
-3 4769 4768 4720
-3 4734 4769 4704
-3 4734 4125 4747
-3 4734 4747 4769
-3 4125 4735 4747
-3 4737 4738 4748
-3 4749 4748 4738
-3 4749 4750 4751
-3 4136 4751 4750
-3 4128 4771 4142
-3 4725 4752 4138
-3 4754 4755 4140
-3 4755 4756 4131
-3 4131 4756 4740
-3 4756 4757 4740
-3 4131 4776 4132
-3 4131 4740 4776
-3 4740 4757 4776
-3 4776 4758 4132
-3 4758 4777 4741
-3 4759 4741 4777
-3 4760 4742 4759
-3 4761 4742 4760
-3 4743 4763 4764
-3 4744 4743 4764
-3 4717 4744 4764
-3 5379 5338 3683
-3 4780 4731 4765
-3 4765 4731 4745
-3 4733 4780 4745
-3 4780 4765 4745
-3 4733 4133 4780
-3 4746 4781 4766
-3 4782 4169 4746
-3 4719 4767 4141
-3 4747 4770 4769
-3 4735 4770 4747
-3 4722 4785 4735
-3 4785 4770 4735
-3 4748 5372 4737
-3 4749 5372 4748
-3 5372 4749 4154
-3 4749 4751 4154
-3 4136 4154 4751
-3 4144 4772 4773
-3 4147 4144 4773
-3 4773 4753 4147
-3 4774 3660 4753
-3 3660 4147 4753
-3 4140 4150 4754
-3 4151 4754 4150
-3 4755 4754 4151
-3 4775 4755 4151
-3 4775 4756 4755
-3 4775 4757 4756
-3 4777 4758 4776
-3 4759 4778 4779
-3 4153 4779 4166
-3 4153 4760 4779
-3 4760 4759 4779
-3 4152 4760 4153
-3 4152 4762 4760
-3 4762 4761 4760
-3 4168 4764 4763
-3 4133 4134 4780
-3 4746 4169 4781
-3 4767 4783 4141
-3 4719 4784 4767
-3 4784 4783 4767
-3 4768 4784 4719
-3 5369 4784 4768
-3 5369 4768 4769
-3 4770 4798 4769
-3 4155 4771 4154
-3 4142 4771 4155
-3 4786 5394 5374
-3 4786 5374 4156
-3 4787 4788 4158
-3 5385 4788 4787
-3 4158 4788 4772
-3 4158 4772 4144
-3 4753 4789 4774
-3 4790 4775 4171
-3 4166 4779 4778
-3 4166 4778 4167
-3 4167 4778 4791
-3 4792 5354 4180
-3 4794 5354 4792
-3 4793 4794 4792
-3 4763 4794 4795
-3 4134 4803 4780
-3 4796 4803 4134
-3 4766 4796 4134
-3 4781 4796 4766
-3 4169 4796 4781
-3 6695 4169 4782
-3 6695 4782 4141
-3 4783 6695 4141
-3 4783 4784 4797
-3 5369 4804 4784
-3 4804 4797 4784
-3 4805 4804 5369
-3 5388 4798 4770
-3 4785 5388 4770
-3 4799 5385 4787
-3 4158 4800 4787
-3 4800 4799 4787
-3 4774 4789 4801
-3 4802 4774 4801
-3 4791 4171 4167
-3 4181 4792 4180
-3 4794 4793 4184
-3 4795 4794 4184
-3 5379 3683 4823
-3 4812 4803 4796
-3 4797 4804 4783
-3 4786 4806 5394
-3 4807 4816 5385
-3 5385 4799 4807
-3 4799 4808 4807
-3 4800 4809 4799
-3 4809 4808 4799
-3 4810 4809 4800
-3 4810 4800 4172
-3 4801 4789 4172
-3 4181 4183 4792
-3 4183 4793 4792
-3 4184 4793 4183
-3 4763 4795 4184
-3 4174 4811 4176
-3 4176 4811 4178
-3 4838 4780 4803
-3 4812 4838 4803
-3 3685 4813 4179
-3 4814 4179 4813
-3 5406 5394 4806
-3 4808 4817 4807
-3 4817 4816 4807
-3 4820 4817 4809
-3 4817 4808 4809
-3 4810 4820 4809
-3 4811 4174 4177
-3 4178 4811 4177
-3 3685 4818 4813
-3 4179 4814 4825
-3 4185 4825 4186
-3 4185 4179 4825
-3 4815 4827 4819
-3 4815 4187 4827
-3 4816 4189 4815
-3 4820 4189 4816
-3 4817 4820 4816
-3 4822 4192 4191
-3 4812 4824 4838
-3 3685 4835 4818
-3 4819 4826 5433
-3 4827 4826 4819
-3 4187 4198 4827
-3 4189 4820 4833
-3 4191 4199 4821
-3 4822 4199 4192
-3 4835 5430 4818
-3 4207 4186 4825
-3 4836 4207 4825
-3 4197 4207 4201
-3 4186 4207 4197
-3 5433 4829 5439
-3 5433 4826 4829
-3 4827 4830 4826
-3 4830 4829 4826
-3 4198 4831 4827
-3 4827 4831 4830
-3 4832 4831 4198
-3 5434 4838 4824
-3 5434 4824 4828
-3 4204 4834 4205
-3 4834 4206 4205
-3 4200 5437 4835
-3 4200 4836 5437
-3 4836 4200 4207
-3 4830 5439 4829
-3 4831 5439 4830
-3 4832 5439 4831
-3 4834 4841 4839
-3 4204 4841 4834
-3 4839 4206 4834
-3 4209 4211 4837
-3 4422 6658 1262
-3 4215 5445 4216
-3 5445 4217 4216
-3 4840 4217 5445
-3 4219 4849 6840
-3 5455 4212 4219
-3 5455 4219 6840
-3 4213 5455 3733
-3 4215 4221 5445
-3 5445 4221 5448
-3 4217 4840 4842
-3 4842 4222 4217
-3 5449 4222 4842
-3 4225 4849 4219
-3 3733 5455 4236
-3 4226 5448 4221
-3 4227 5449 4226
-3 4226 5449 5448
-3 5449 4227 4222
-3 4843 4841 4869
-3 4841 4223 4869
-3 4846 5462 4231
-3 4233 4848 4245
-3 4847 4848 4233
-3 4225 4235 4849
-3 4236 5455 4856
-3 4231 4239 4846
-3 4231 5462 4242
-3 5462 4859 4242
-3 4233 4244 4847
-3 4244 4851 4847
-3 4851 4848 4847
-3 4245 4848 4851
-3 4246 4245 4852
-3 4247 5468 4853
-3 4247 4246 5468
-3 4246 4852 5468
-3 5468 4854 4853
-3 4864 6882 4849
-3 4235 4248 4855
-3 4235 4855 4849
-3 4855 4248 4856
-3 4856 4248 4236
-3 4223 4228 4869
-3 4859 4256 4242
-3 4244 4250 4851
-3 4250 5468 4851
-3 4853 4250 4247
-3 4853 4854 4250
-3 4854 5468 4250
-3 4860 4861 4862
-3 4861 4863 4862
-3 4855 4864 4849
-3 4865 4858 4857
-3 4867 4857 4858
-3 4867 4866 4857
-3 4866 4865 4857
-3 4869 4239 4870
-3 4859 5482 4256
-3 4868 4860 4862
-3 4863 4868 4862
-3 4867 4865 4866
-3 5481 4870 4260
-3 4262 4256 5482
-3 4259 4276 4871
-3 4276 4873 4871
-3 4263 4871 4873
-3 4263 4265 4264
-3 4873 4265 4263
-3 5481 4260 4270
-3 5481 4270 5483
-3 4262 5482 5484
-3 4267 5484 4875
-3 4267 4262 5484
-3 3748 4872 4269
-3 4872 4876 4269
-3 4265 4881 4277
-3 4265 4873 4881
-3 4270 4879 5483
-3 5484 4879 4878
-3 5484 4878 4875
-3 4875 4878 4880
-3 4267 4880 4271
-3 4875 4880 4267
-3 5489 4876 3766
-3 4876 4872 3766
-3 4876 5491 4269
-3 4272 4269 5491
-3 4272 5491 4274
-3 4873 4276 5504
-3 4277 4881 5493
-3 4302 4277 5495
-3 4277 5493 5495
-3 5506 4874 3807
-3 4290 4883 5497
-3 5497 5486 4290
-3 4270 4293 4879
-3 4293 4878 4879
-3 4880 4878 4884
-3 4884 4878 4293
-3 4271 4884 4280
-3 4880 4884 4271
-3 4281 4898 5489
-3 3766 4281 5489
-3 4283 5491 4885
-3 4274 5491 4283
-3 4276 4299 4892
-3 4892 5504 4276
-3 3807 4894 5506
-3 3807 4350 4894
-3 4290 4289 4883
-3 4886 4290 5486
-3 5498 4887 5486
-3 4887 4886 5486
-3 5498 5507 4887
-3 4281 4304 4898
-3 4885 5491 4311
-3 4888 5518 4890
-3 4889 5518 4888
-3 4890 5518 4891
-3 4893 5495 5519
-3 4302 5495 4893
-3 4287 4882 3819
-3 4288 4895 4289
-3 4886 4895 4288
-3 4896 4895 4886
-3 4887 4912 4886
-3 4897 4887 5507
-3 4897 4912 4887
-3 4291 4292 5522
-3 3821 4291 5522
-3 3813 4899 4307
-3 4307 4899 4308
-3 4309 4899 3813
-3 4309 4900 4901
-3 4309 4901 4899
-3 4901 4900 4902
-3 4311 5491 5503
-3 4311 5503 4310
-3 4310 5503 5526
-3 4888 4903 4889
-3 4890 4903 4888
-3 4904 4903 4890
-3 4891 4904 4890
-3 4905 4904 4891
-3 5518 4905 4891
-3 4299 4313 4906
-3 4892 4299 4906
-3 5519 4892 4906
-3 4315 5519 4314
-3 5519 4315 4893
-3 3815 4893 4315
-3 3815 4907 4893
-3 4316 4893 4907
-3 4325 4921 4909
-3 5505 4911 4910
-3 5528 4911 5505
-3 4894 4350 5544
-3 4963 4877 4237
-3 4896 4886 4912
-3 4897 4913 4912
-3 4355 3821 5522
-3 4898 4914 5525
-3 5531 4327 4308
-3 4900 4328 4915
-3 4309 4328 4900
-3 4916 4902 4900
-3 4916 4900 4917
-3 4917 4900 4915
-3 4917 5526 4916
-3 4917 4310 5526
-3 4313 4322 4906
-3 4906 4314 5519
-3 3815 4918 4907
-3 4918 4316 4907
-3 4316 4918 4919
-3 4908 4317 4920
-3 4920 4317 4919
-3 4926 4921 4908
-3 4926 4908 4920
-3 4317 4908 4921
-3 4317 4921 4324
-3 4921 4325 4324
-3 4927 4325 4909
-3 4909 4910 4927
-3 4928 4927 4910
-3 5528 5532 4911
-3 4882 4336 3819
-3 4913 4922 4912
-3 4914 4898 4935
-3 4304 4924 4898
-3 4924 4935 4898
-3 4936 4924 4304
-3 4936 4304 4339
-3 5531 5550 4327
-3 4329 4915 4328
-3 4917 4915 4329
-3 4310 4917 4329
-3 4918 3815 4925
-3 4919 4918 4925
-3 4925 4926 4920
-3 4925 4920 4919
-3 4325 4927 4334
-3 4910 4335 4928
-3 4342 4911 4929
-3 4929 4911 5532
-3 4930 4931 5548
-3 5548 4932 4930
-3 4913 4923 4933
-3 3795 4952 4292
-3 4338 3821 4355
-3 4935 4924 4934
-3 4936 4934 4924
-3 4339 4937 4936
-3 4339 4938 4937
-3 4339 4327 5550
-3 5541 4925 4348
-3 4334 4927 4349
-3 4335 4363 4928
-3 4939 5554 4940
-3 4929 5532 4342
-3 4940 4941 4939
-3 4342 5544 4350
-3 4342 5532 5544
-3 4962 4336 4882
-3 3848 4336 4962
-3 4942 4931 4930
-3 4943 4931 4942
-3 4944 4930 4932
-3 4942 4930 4944
-3 4945 4922 4337
-3 4954 4935 4934
-3 4936 4946 4934
-3 4946 4954 4934
-3 4946 4936 4937
-3 4339 4947 4938
-3 5550 4947 4339
-3 4348 4948 5541
-3 4948 4348 4949
-3 4949 4333 4349
-3 4950 5553 4960
-3 5553 4950 5564
-3 4940 5554 4951
-3 4941 4940 4951
-3 4942 4944 4943
-3 3795 4352 4952
-3 4946 4955 4954
-3 4955 4946 5573
-3 4948 4959 4956
-3 4948 4949 4959
-3 4349 4959 4949
-3 4928 4363 4960
-3 4960 4363 4950
-3 4961 5564 4950
-3 3848 4962 4357
-3 4964 4945 4337
-3 4360 4346 4953
-3 5572 4954 4957
-3 4955 4958 4954
-3 4958 4957 4954
-3 4958 4955 5573
-3 4961 4950 4365
-3 4966 4945 4964
-3 4933 5592 4379
-3 4380 4952 4352
-3 4360 4953 4382
-3 4371 5577 4957
-3 4371 4957 4958
-3 4957 5577 5572
-3 4958 5573 4371
-3 5573 5577 4371
-3 4965 4961 4365
-3 3857 4965 4365
-3 4962 4971 4372
-3 4966 4964 4973
-3 4964 4967 4973
-3 4366 4377 4967
-3 4964 4366 4967
-3 4381 4952 4380
-3 4382 4953 4381
-3 4371 4383 5577
-3 5577 4383 5582
-3 4371 5577 4383
-3 5577 5582 4383
-3 4981 4968 4965
-3 3857 4981 4965
-3 3857 4394 4981
-3 4969 4970 4384
-3 4969 4384 4372
-3 4971 4969 4372
-3 4971 4972 4969
-3 4973 4385 4403
-3 4973 4386 4385
-3 4967 4387 4973
-3 4377 4387 4967
-3 5590 4974 4389
-3 4389 4975 5590
-3 4378 4975 4389
-3 4379 5592 4392
-3 5592 4985 4392
-3 4383 4393 5582
-3 5582 4393 5605
-3 4383 5582 4401
-3 5582 4986 4401
-3 4968 4978 4976
-3 4979 4978 4968
-3 4993 4968 4980
-3 4993 4979 4968
-3 4981 4980 4968
-3 4394 4396 4981
-3 4969 4994 4970
-3 4994 4969 4982
-3 4969 4972 4982
-3 4983 4972 4971
-3 4983 4984 4972
-3 4984 4982 4972
-3 4975 4378 4391
-3 4975 4391 5597
-3 5597 4391 4397
-3 4985 4416 4392
-3 4393 4400 5605
-3 4986 4402 4401
-3 5599 4402 4986
-3 4987 4988 4989
-3 4989 5600 4987
-3 4990 4977 4976
-3 4991 4990 4976
-3 4978 4992 4976
-3 4992 4991 4976
-3 4979 4992 4978
-3 4984 4995 4982
-3 4995 4994 4982
-3 5603 4984 4983
-3 4995 4984 5603
-3 5597 4397 4419
-3 5009 5597 4419
-3 4402 5599 4412
-3 4987 4997 4988
-3 5600 4997 4987
-3 4977 4990 4998
-3 4991 4999 4990
-3 4992 5000 4991
-3 5000 4999 4991
-3 5007 4979 4993
-3 5007 5000 4979
-3 5000 4992 4979
-3 4994 4995 5008
-3 5008 4995 5603
-3 4974 5590 4415
-3 5613 4416 4985
-3 4410 5605 4400
-3 4410 5001 5002
-3 4410 5002 5605
-3 4412 5001 5003
-3 4412 5599 5001
-3 5002 5001 5599
-3 4412 5003 5012
-3 5006 4996 5606
-3 5006 5005 4996
-3 5005 5004 4996
-3 4998 4418 4977
-3 5000 5007 4999
-3 4415 7464 4403
-3 5009 5010 5011
-3 4416 5010 5017
-3 4416 5613 5010
-3 5011 5010 5613
-3 4416 5017 4420
-3 4410 4417 5001
-3 4417 5012 5001
-3 5012 5003 5001
-3 5005 5013 5004
-3 5014 5013 5005
-3 5006 5014 5005
-3 4977 5015 5016
-3 4977 4418 5015
-3 4999 5007 4425
-3 4990 4999 4425
-3 4419 5025 5009
-3 5025 5010 5009
-3 5017 5010 5025
-3 4420 5017 5018
-3 5018 5019 4420
-3 5019 5020 4420
-3 5012 4417 5021
-3 5015 4434 5016
-3 5015 4423 4434
-3 4423 5015 5022
-3 5022 5015 4418
-3 4418 4424 5022
-3 5023 4427 4426
-3 5023 5024 4427
-3 4419 4427 5024
-3 4419 5024 5025
-3 4428 5025 4438
-3 4428 5018 5025
-3 5018 5017 5025
-3 4439 5018 4428
-3 4439 5026 5018
-3 5026 5019 5018
-3 5020 5019 5027
-3 5027 5019 5026
-3 4421 5027 4429
-3 5020 5027 4421
-3 5028 5021 4417
-3 4431 4430 5029
-3 5029 5030 4431
-3 4431 5030 4433
-3 5016 4434 5031
-3 5031 4434 4435
-3 5022 4436 4423
-3 5022 5033 4436
-3 5033 5032 4436
-3 4424 5033 5022
-3 4424 4437 5033
-3 4437 5034 5033
-3 5007 5628 4425
-3 5023 4426 5634
-3 5025 5024 4448
-3 4438 5025 4448
-3 4449 5026 4439
-3 4449 5027 5026
-3 4429 5027 4440
-3 4417 4441 5028
-3 4430 4442 5029
-3 4443 5029 4442
-3 5030 5029 4443
-3 4433 5030 4443
-3 4435 5035 5031
-3 4444 5035 4435
-3 4436 5032 4444
-3 4444 5032 5035
-3 4437 4445 5034
-3 5034 4445 5036
-3 4440 5027 4449
-3 4467 4425 5628
-3 5037 4447 4448
-3 5634 4447 5037
-3 5038 5046 5045
-3 5047 5046 5038
-3 4456 4455 5047
-3 4445 4459 5036
-3 4467 5036 4459
-3 5048 5041 5040
-3 5049 5041 5048
-3 4461 5050 5051
-3 4462 4461 5052
-3 4461 5051 5052
-3 5053 4462 5052
-3 4452 5075 5054
-3 5042 4452 5055
-3 5055 4452 5054
-3 4453 5055 4473
-3 5042 5055 4453
-3 5043 5044 5056
-3 5044 5067 5056
-3 5045 5058 5044
-3 5058 5067 5044
-3 5046 5058 5045
-3 5047 5059 5046
-3 5059 5058 5046
-3 4455 4463 5059
-3 5047 4455 5059
-3 4456 5047 5641
-3 5641 4457 4456
-3 5641 4465 4457
-3 4467 4459 4466
-3 5048 5060 5049
-3 5050 4461 4479
-3 5050 4479 5071
-3 4462 5053 4470
-3 5053 5061 4470
-3 5063 4471 5062
-3 5063 5640 4471
-3 4472 4471 5640
-3 5075 5064 5054
-3 5055 5054 5065
-3 5065 5054 5064
-3 5055 5065 4473
-3 4475 4474 5066
-3 5056 5066 5057
-3 5056 4475 5066
-3 5067 4475 5056
-3 5058 5068 5067
-3 4463 5068 5059
-3 5059 5068 5058
-3 4465 5641 4478
-3 5641 5069 4478
-3 4479 5070 5071
-3 4481 5070 5072
-3 4481 5061 5070
-3 4481 4470 5061
-3 5071 5070 5061
-3 4481 5062 4471
-3 4481 5072 5062
-3 5072 5073 5062
-3 5074 5063 5062
-3 5073 5074 5062
-3 5642 4472 5640
-3 4472 5642 4492
-3 4486 5064 5075
-3 4487 5064 4486
-3 5065 5064 4487
-3 4473 5065 4487
-3 5066 4474 5076
-3 4479 4488 5070
-3 4488 5077 5070
-3 5077 5072 5070
-3 5073 5072 5078
-3 5078 5072 5077
-3 5644 5074 5073
-3 5078 5644 5073
-3 5644 5079 5642
-3 4492 5642 5080
-3 5642 5079 5080
-3 4486 5075 4493
-3 4488 4495 5077
-3 4489 5077 4495
-3 5078 5077 4489
-3 5078 4489 5644
-3 4489 4497 5644
-3 4497 5084 5079
-3 4497 5079 5644
-3 5085 5647 5080
-3 5085 5080 5084
-3 5084 5080 5079
-3 5647 4492 5080
-3 4501 5086 4502
-3 4500 5086 4501
-3 4502 5086 4506
-3 5076 4474 5087
-3 5087 5081 5076
-3 3926 5082 5088
-3 5083 3931 5109
-3 5089 5083 5096
-3 4503 5090 4504
-3 5096 5090 4503
-3 4497 4505 5084
-3 5084 4505 5085
-3 5086 4500 5092
-3 5093 5086 5092
-3 4506 5086 5093
-3 4506 5093 5094
-3 5083 5089 5095
-3 5096 5097 5089
-3 5097 5095 5089
-3 5097 5096 4503
-3 5666 5090 5096
-3 5090 5666 4512
-3 5098 4505 4507
-3 5098 5654 4505
-3 5654 5085 4505
-3 4507 5091 5098
-3 5098 5091 5099
-3 5099 5091 5104
-3 5100 5101 5102
-3 5102 5103 5100
-3 5092 4500 5118
-3 5098 4508 5654
-3 4508 5659 5654
-3 5099 3944 5098
-3 3944 5099 5104
-3 4510 5104 5105
-3 5100 5108 5101
-3 5103 5108 5100
-3 5118 4500 5117
-3 5109 3952 4509
-3 3931 3952 5109
-3 3936 5666 5659
-3 5659 4508 3936
-3 4515 4510 5105
-3 4515 5105 5106
-3 5110 5106 5107
-3 5110 5111 5106
-3 5111 4515 5106
-3 5125 4511 4514
-3 5666 3936 4512
-3 4515 5111 5127
-3 5120 5119 5112
-3 5112 5672 5120
-3 5121 5674 5114
-3 5114 5113 5121
-3 5113 5122 5121
-3 5122 5113 5114
-3 4511 5125 4513
-3 5125 4514 4518
-3 5126 5125 4518
-3 5128 5681 5118
-3 5118 5117 5128
-3 5117 5129 5128
-3 5130 5129 5117
-3 5119 5131 5135
-3 5119 5120 5131
-3 5682 5120 5672
-3 5131 5120 5682
-3 5121 5686 5674
-3 5122 5686 5121
-3 5116 5115 5132
-3 5123 4517 5132
-3 5123 5132 5115
-3 5123 5124 4516
-3 5124 5133 4516
-3 4513 5125 5697
-3 4518 5680 5126
-3 5127 5134 4515
-3 5681 5129 4522
-3 5681 5128 5129
-3 5682 5135 5131
-3 4517 4519 5136
-3 5132 4517 5136
-3 4516 5133 4520
-3 5133 5137 4520
-3 4513 5697 4521
-3 5680 4518 5138
-3 5138 4518 4525
-3 5681 4522 5134
-3 4519 4528 5136
-3 4523 4520 5137
-3 4527 5138 4525
-3 4527 5139 5138
-3 4528 5712 5136
-3 4530 4523 5137
-3 5712 4530 5137
-3 5141 4527 4521
-3 4527 5141 5142
-3 4527 5142 5143
-3 5139 4527 5144
-3 5144 4527 5143
-3 5699 4531 5140
-3 5699 5708 4531
-3 5708 5715 4531
-3 4529 5145 4528
-3 4528 5145 5716
-3 5716 5712 4528
-3 4529 4531 5715
-3 4529 5715 5145
-3 4536 5146 4534
-3 5147 5146 4536
-3 4533 5148 4536
-3 5148 5147 4536
-3 5149 5148 4533
-3 4551 5152 4533
-3 5727 4539 4540
-3 4547 4546 5150
-3 4547 5150 5146
-3 4547 5146 5147
-3 4548 4547 5147
-3 4548 5147 5148
-3 5149 5160 5151
-3 5151 4549 5149
-3 5148 5149 4548
-3 4548 5149 4549
-3 4553 5152 4551
-3 5164 5152 4553
-3 5153 5154 4538
-3 4554 4538 5154
-3 4539 5155 4540
-3 5155 5156 4540
-3 5157 5158 4557
-3 5160 5150 4546
-3 5160 4546 5159
-3 5160 5159 5161
-3 5161 5162 5160
-3 5160 5162 5151
-3 5151 5162 5163
-3 4549 5163 4559
-3 5151 5163 4549
-3 5164 4563 5165
-3 5164 4553 4563
-3 5165 5166 5167
-3 5164 5165 5167
-3 5153 5168 4564
-3 4566 5153 4564
-3 5154 5153 4566
-3 4565 5154 4566
-3 4565 5169 5154
-3 4556 5154 5169
-3 5169 5155 4556
-3 4556 5155 4539
-3 5156 5155 5170
-3 4540 5156 5170
-3 5179 4540 5170
-3 4557 5158 5171
-3 5158 5157 5171
-3 4558 5172 5159
-3 5161 5159 5172
-3 5163 5162 5184
-3 5184 5162 5161
-3 5163 5184 4559
-3 5165 4569 5173
-3 4563 4569 5165
-3 5166 5165 5173
-3 5768 5167 5166
-3 5768 5166 5174
-3 5174 4577 5768
-3 5175 5176 5153
-3 5168 5153 5176
-3 5168 5176 4570
-3 4565 5177 5169
-3 5155 5169 5783
-3 5170 5155 5783
-3 5179 5170 5178
-3 5157 5179 5180
-3 5171 5157 5181
-3 5181 5157 5180
-3 5172 5171 5181
-3 5183 5172 5182
-3 5161 5172 5183
-3 5184 5161 5183
-3 4567 5185 4571
-3 4571 5173 4569
-3 4571 5185 5173
-3 4572 5173 4573
-3 4573 5173 5185
-3 4575 5173 4572
-3 4575 5186 5173
-3 5186 5166 5173
-3 5174 5186 4576
-3 5174 5166 5186
-3 4577 5187 5768
-3 5188 5189 5175
-3 5217 5188 5175
-3 5175 5189 5190
-3 5176 5175 5191
-3 5191 5175 5190
-3 4570 5176 5192
-3 5176 5191 5192
-3 5192 5193 5177
-3 5204 5177 5193
-3 5169 5177 5204
-3 5179 5178 5205
-3 5180 5179 5195
-3 5195 5179 5194
-3 5196 5180 5195
-3 5181 5180 5196
-3 5784 5183 5182
-3 5784 5197 5183
-3 5184 5183 5197
-3 4559 5184 5209
-3 5209 5184 5197
-3 4559 5209 4580
-3 4580 5198 4567
-3 5185 4567 5199
-3 5199 4567 5198
-3 4573 5199 4574
-3 4573 5185 5199
-3 4574 5186 4575
-3 4574 5199 5186
-3 5199 5212 5186
-3 4576 5186 4581
-3 5186 5212 4581
-3 5214 4583 3974
-3 5217 5200 5201
-3 5188 5217 5201
-3 5189 5188 5202
-3 5202 5188 5201
-3 5190 5189 5203
-3 5203 5189 5202
-3 5191 5190 5193
-3 5193 5190 5203
-3 5192 5191 5193
-3 5194 5179 5205
-3 5206 5195 5205
-3 5205 5195 5194
-3 5206 5824 5195
-3 5195 5824 5196
-3 5181 5196 5207
-3 5207 5196 5824
-3 5172 5181 5207
-3 5182 5172 5207
-3 5223 5182 5207
-3 5208 5784 5182
-3 5208 5182 5223
-3 4580 5209 5825
-3 5825 5198 4580
-3 5198 5210 5199
-3 5211 5199 5210
-3 5212 5199 5211
-3 4581 5212 5224
-3 4581 5224 5225
-3 5225 5187 4581
-3 5213 4583 5214
-3 4585 4587 5215
-3 5216 5218 5217
-3 5217 5218 5200
-3 5201 5200 5219
-3 5219 5200 5218
-3 5202 5201 5220
-3 5220 5201 5219
-3 5193 5203 5220
-3 5220 5203 5202
-3 5221 5207 5857
-3 5222 5207 5221
-3 5223 5207 5222
-3 5208 5223 5228
-3 5197 5208 5228
-3 5209 5197 5228
-3 5211 5210 5233
-3 5212 5211 5229
-3 5229 5211 5233
-3 5224 5212 5229
-3 5187 5225 5230
-3 5879 5214 3974
-3 5879 3974 4588
-3 5226 4589 4585
-3 5215 5226 4585
-3 5215 4587 4593
-3 5215 4593 5226
-3 5227 5226 4593
-3 5217 5226 5227
-3 5217 5227 5216
-3 5216 5227 5231
-3 5218 5216 5231
-3 5219 5218 5231
-3 5220 5219 5231
-3 5222 5221 5857
-3 5223 5222 5228
-3 5228 5222 5857
-3 5825 5209 5228
-3 5233 5210 5232
-3 5224 5229 5234
-3 5225 5224 5234
-3 5230 5225 5234
-3 5226 5235 4589
-3 4596 5227 4593
-3 5825 5228 5874
-3 5210 5825 5874
-3 5234 5229 5233
-3 4600 5879 4588
-3 5227 4596 5238
-3 5238 5231 5227
-3 5233 5232 5234
-3 5879 4600 5236
-3 5236 4600 4604
-3 4608 5236 4604
-3 4608 5239 5236
-3 5237 5239 4608
-3 5237 4612 5239
-3 5238 4606 5241
-3 4628 5242 4626
-3 5242 4628 4051
-3 5243 4620 4627
-3 5242 5244 5243
-3 5242 5243 4633
-3 5242 4633 4626
-3 4051 5244 5242
-3 4627 4634 5243
-3 4633 5243 4634
-3 5244 4051 5964
-3 4643 4629 6015
-3 4639 5245 5246
-3 4641 5247 5248
-3 4641 5248 5246
-3 6028 5249 5248
-3 5246 5248 5249
-3 5246 5249 4639
-3 5247 5250 5251
-3 4641 5250 5247
-3 4641 4644 5250
-3 4645 5249 6028
-3 5250 4644 4650
-3 4645 6028 5252
-3 4645 5252 4646
-3 4650 4649 5250
-3 4649 5253 5250
-3 4646 5252 4648
-3 4049 4651 5253
-3 5253 4652 4049
-3 5253 4649 4652
-3 4648 5252 4656
-3 5256 6052 4642
-3 4651 4655 5253
-3 5254 4655 4657
-3 5254 6064 4655
-3 6064 5253 4655
-3 4657 4656 5255
-3 5254 4657 5255
-3 4656 5258 5255
-3 4656 6066 5258
-3 5254 5257 6064
-3 5257 5258 5259
-3 5257 5254 5258
-3 5254 5255 5258
-3 6053 5256 5265
-3 5259 5258 5262
-3 5260 4051 1262
-3 5265 5256 5261
-3 5259 5262 5264
-3 5264 5262 5263
-3 4658 5265 5261
-3 4658 4659 5265
-3 5265 4659 5267
-3 5267 4659 5266
-3 5268 4050 6143
-3 4052 5267 5266
-3 5270 5275 5268
-3 5275 5269 5268
-3 5276 5275 5270
-3 5276 5277 5275
-3 5278 5271 5273
-3 5278 5277 5271
-3 5272 5271 5276
-3 5276 5271 5277
-3 5267 4052 5285
-3 5269 5279 5274
-3 5275 5280 5269
-3 5280 5279 5269
-3 5280 5277 5281
-3 5280 5275 5277
-3 5278 5281 5277
-3 5279 5282 5274
-3 5282 5287 5274
-3 5283 5279 5284
-3 5283 5282 5279
-3 5280 5284 5279
-3 5274 5286 4662
-3 5287 5286 5274
-3 5282 5288 5287
-3 5288 5282 5283
-3 4662 5286 6230
-3 6230 5286 5287
-3 6241 4662 6230
-3 6241 5289 4662
-3 5290 5289 6241
-3 5290 5291 5295
-3 4666 4662 5289
-3 4666 5289 5302
-3 5296 5302 5289
-3 5290 5293 5289
-3 5293 5296 5289
-3 5294 5293 5290
-3 5295 5294 5290
-3 6274 5295 5291
-3 5299 5285 5292
-3 4667 5296 5294
-3 5294 5296 5293
-3 4667 5294 5297
-3 5297 5294 5295
-3 5305 5295 6274
-3 5297 5295 5305
-3 4672 5298 5292
-3 5299 5292 5298
-3 5302 5308 4666
-3 4667 5304 5296
-3 5296 5304 5303
-3 4667 5305 5304
-3 4667 5297 5305
-3 5302 5309 5308
-3 5309 5302 5296
-3 5303 5309 5296
-3 5310 5309 5303
-3 5304 5310 5303
-3 5305 5310 5304
-3 4671 5316 5306
-3 5306 5311 4679
-3 5299 5298 5318
-3 5307 5300 5314
-3 5315 5307 5314
-3 6326 5315 4684
-3 5319 4675 5308
-3 5316 5317 5306
-3 4679 5311 5317
-3 5311 5306 5317
-3 5321 5299 5318
-3 5322 5299 5321
-3 4682 5300 5324
-3 5314 5300 4682
-3 4684 5315 5314
-3 5317 5316 5320
-3 6369 5322 5323
-3 5327 4677 5325
-3 5319 5325 4677
-3 5328 5325 5319
-3 6380 5328 5319
-3 5308 6380 5319
-3 5335 5321 5318
-3 5322 5321 5335
-3 5328 4697 5325
-3 4691 5330 4692
-3 5329 5330 4691
-3 4692 5331 4693
-3 5330 5331 4692
-3 5332 5333 5334
-3 5343 5333 5332
-3 5336 5322 5335
-3 5323 5322 5336
-3 6369 5323 5345
-3 5346 5324 6378
-3 5337 5326 6440
-3 5326 5338 6440
-3 4696 5327 5339
-3 5327 4100 5339
-3 4698 4697 5328
-3 4698 5328 6380
-3 5329 4700 5340
-3 4691 4700 5329
-3 5331 5340 4701
-3 5331 5330 5340
-3 5330 5329 5340
-3 5342 5343 5332
-3 5334 5344 5332
-3 5344 5342 5332
-3 4716 5335 5318
-3 4716 5336 5335
-3 5345 5354 6369
-3 4717 5324 5346
-3 4718 5324 4717
-3 4703 5324 4718
-3 5337 2279 5326
-3 4706 4696 5347
-3 5347 5339 5348
-3 5347 4696 5339
-3 5349 5348 5339
-3 5349 5339 4100
-3 5349 4100 5350
-3 4698 5351 4128
-3 4707 5352 6415
-3 4708 4707 6417
-3 4707 6415 6417
-3 4708 6417 5357
-3 4710 5353 4700
-3 5358 5353 4710
-3 4700 5353 5340
-3 4701 5340 4712
-3 4712 5340 5353
-3 5344 5343 5342
-3 5345 5323 5336
-3 5354 5345 5336
-3 6428 6369 5354
-3 4743 5346 6405
-3 4717 5346 5355
-3 5356 4724 5347
-3 4724 4706 5347
-3 5350 4100 6501
-3 4708 5357 4726
-3 5358 4710 4726
-3 5358 4726 5357
-3 6485 5353 5358
-3 6485 4712 5353
-3 4742 5336 4716
-3 4762 5336 4742
-3 5354 5336 4180
-3 6405 6465 4763
-3 4743 6405 4763
-3 5346 4743 4744
-3 5355 5346 4744
-3 4717 5355 4744
-3 5360 4736 4723
-3 4749 5356 4750
-3 4724 5356 4749
-3 6501 4100 4750
-3 4771 4128 5351
-3 5352 4707 5374
-3 4712 6485 4739
-3 4762 4180 5336
-3 4794 6465 5359
-3 4763 6465 4794
-3 3635 5361 4684
-3 4785 4736 5363
-3 5363 4736 5360
-3 5360 4723 5365
-3 4723 4737 5365
-3 5362 3635 2279
-3 6440 5338 5379
-3 4737 5372 5365
-3 5375 4138 4752
-3 4739 5375 4752
-3 4753 4773 5366
-3 4757 5367 4776
-3 4775 5367 4757
-3 6567 4776 5367
-3 4777 4776 5368
-3 4759 4777 5368
-3 4778 4759 5368
-3 5368 6598 4778
-3 4794 5359 5354
-3 4769 4798 5369
-3 5371 5370 5365
-3 5372 5371 5365
-3 4154 4771 5373
-3 4138 5375 6615
-3 4788 5385 6623
-3 4773 4772 4788
-3 4773 4788 6623
-3 5366 4773 6623
-3 4753 5366 5376
-3 5377 5376 5378
-3 5377 4753 5376
-3 4753 5377 4789
-3 5367 4775 4790
-3 4790 6567 5367
-3 6598 4791 4778
-3 5369 5386 4805
-3 5369 4798 5386
-3 4785 5363 5389
-3 5364 5389 5363
-3 5389 5364 6603
-3 5371 5381 5370
-3 5381 5380 5370
-3 5372 5382 5371
-3 5382 5381 5371
-3 5383 5382 5372
-3 5383 5372 4154
-3 5373 5383 4154
-3 5394 5384 5374
-3 4138 6615 4806
-3 5395 4172 5378
-3 5377 5378 4172
-3 5377 4172 4789
-3 4171 6660 4790
-3 4791 6660 4171
-3 6598 6660 4791
-3 4804 6695 4783
-3 4798 5387 5386
-3 5387 4798 5388
-3 5388 4785 5401
-3 4785 5389 5401
-3 6603 6680 5389
-3 5381 5390 5380
-3 5391 5390 5382
-3 5390 5381 5382
-3 5383 5391 5382
-3 6609 5392 5393
-3 5384 5393 5392
-3 5384 5394 5393
-3 4810 5395 5396
-3 4172 5395 4810
-3 5411 5399 5398
-3 4796 6676 4812
-3 4169 6676 4796
-3 6695 6676 4169
-3 6677 6695 4804
-3 4805 5386 5417
-3 5387 5417 5386
-3 5417 5388 5400
-3 5417 5387 5388
-3 5401 5400 5388
-3 6680 5402 5389
-3 5402 5401 5389
-3 5430 5370 5380
-3 4813 5380 5390
-3 5390 4814 4813
-3 5390 5391 4814
-3 5393 5404 6609
-3 5404 5403 6609
-3 5405 5404 5393
-3 5394 5405 5393
-3 5394 5406 5405
-3 5406 4806 5407
-3 5407 4806 6615
-3 4819 5385 4815
-3 5385 4816 4815
-3 4810 5396 4820
-3 4820 5396 5408
-3 4191 5409 6667
-3 5397 4191 6667
-3 5397 4822 4191
-3 5410 4822 5397
-3 5397 6692 5410
-3 5398 5413 5411
-3 5399 5413 5398
-3 5413 5399 5414
-3 5415 6677 5416
-3 6677 4804 5416
-3 4805 5416 4804
-3 5417 5416 4805
-3 5400 5401 5418
-3 5401 5402 5418
-3 6680 5419 5402
-3 5419 5418 5402
-3 6680 5430 5419
-3 5380 4818 5430
-3 4813 4818 5380
-3 4825 4814 5420
-3 5403 5404 5431
-3 5405 5421 5404
-3 5421 5431 5404
-3 5422 5421 5405
-3 5406 5423 5405
-3 5423 5422 5405
-3 5424 5423 5406
-3 5407 5425 5406
-3 5425 5424 5406
-3 5426 5425 5407
-3 5407 5427 5426
-3 5427 6707 4819
-3 5385 4819 6707
-3 4191 4821 5409
-3 5428 5410 6692
-3 4822 5410 5428
-3 5414 5411 5413
-3 4823 6720 5379
-3 4828 4824 4812
-3 6676 4828 4812
-3 5429 5415 5416
-3 5417 5429 5416
-3 5400 5418 5419
-3 5421 5422 5431
-3 5423 5431 5422
-3 5424 5432 5423
-3 5432 5431 5423
-3 5425 5432 5424
-3 5426 5432 5425
-3 5427 5433 5426
-3 5433 5432 5426
-3 4819 5433 5427
-3 4820 6739 4833
-3 5408 6739 4820
-3 4821 4199 5409
-3 4822 5428 4199
-3 4823 5444 6720
-3 5419 5435 5400
-3 5435 5419 5430
-3 4825 5438 4836
-3 5420 5438 4825
-3 5432 6757 5431
-3 5439 5432 5433
-3 4833 6739 6782
-3 4835 5436 5430
-3 5430 5436 5435
-3 5436 4835 5437
-3 5438 5437 4836
-3 5439 4832 5443
-3 6779 5443 4832
-3 6779 4832 5440
-3 4833 5440 4832
-3 5440 4833 6782
-3 5441 4206 4839
-3 5438 5436 5437
-3 5439 5442 6818
-3 5443 5442 5439
-3 4838 5434 4850
-3 5441 4839 4841
-3 5447 6818 5442
-3 5447 5442 5443
-3 5456 5444 4823
-3 4840 5449 4842
-3 4840 5445 5449
-3 5445 5448 5449
-3 5450 6815 5446
-3 5451 6815 5450
-3 4843 4844 5450
-3 4843 5450 5441
-3 5441 5450 5446
-3 4841 4843 5441
-3 6830 4846 4206
-3 5452 5453 5454
-3 6882 6840 4849
-3 4823 4237 5456
-3 4843 5451 5450
-3 4843 5450 4844
-3 5453 5457 5458
-3 5453 5452 5457
-3 5459 5457 5454
-3 5454 5457 5452
-3 5457 5460 5461
-3 5459 5460 5457
-3 4869 5451 4843
-3 5458 5463 5471
-3 5458 5457 5463
-3 5457 5461 5463
-3 5460 5464 5461
-3 5464 5463 5461
-3 5465 5466 5467
-3 4245 5468 4852
-3 4851 5468 4245
-3 4856 5455 4855
-3 4858 6890 4867
-3 4858 5478 6890
-3 6890 5470 4867
-3 4869 5479 5451
-3 5464 5471 5463
-3 5472 5473 4860
-3 5473 4861 4860
-3 5473 4863 4861
-3 5474 4863 5473
-3 5469 5477 5476
-3 5455 4864 4855
-3 4858 4865 5478
-3 5470 6949 4867
-3 4859 5480 5482
-3 5472 4860 6904
-3 4860 4868 6904
-3 5474 4868 4863
-3 6904 4868 5474
-3 5476 6926 5475
-3 5456 4237 6980
-3 6983 5478 4867
-3 4867 5478 4865
-3 4867 6949 6983
-3 4870 5479 4869
-3 5479 4870 6920
-3 4870 5482 5480
-3 4870 5480 6920
-3 4877 6980 4237
-3 5481 5482 4870
-3 6933 5496 4874
-3 4877 7000 6980
-3 5483 5482 5481
-3 5482 5483 5484
-3 4882 4874 5496
-3 5486 5488 5487
-3 5484 5483 4879
-3 5489 5490 4876
-3 5490 5491 4876
-3 4873 5504 5492
-3 4873 5492 4881
-3 5492 5493 4881
-3 5495 5493 5494
-3 5485 4874 5506
-3 5497 7032 5486
-3 5487 5499 5486
-3 5499 5498 5486
-3 5500 5499 5487
-3 5488 5508 5487
-3 5508 5500 5487
-3 5508 5488 5501
-3 5515 5489 4898
-3 5489 5515 7034
-3 5489 5502 5490
-3 5503 5490 5502
-3 5491 5490 5503
-3 4910 5485 5505
-3 5506 5505 5485
-3 4882 5496 4962
-3 5497 4883 4289
-3 5507 5498 5499
-3 5500 5507 5499
-3 5509 5512 5511
-3 5510 5512 5509
-3 5511 5512 5513
-3 5513 5514 5525
-3 5512 5514 5513
-3 4898 5514 5515
-3 4889 5517 5518
-3 5516 5517 4889
-3 5519 5504 4892
-3 4910 5527 5485
-3 5520 5505 5506
-3 5521 5520 5506
-3 5506 4894 5521
-3 4289 4895 5497
-3 5497 4895 4896
-3 5497 4896 5535
-3 4897 5507 5500
-3 5508 4913 5500
-3 4913 4897 5500
-3 5501 4913 5508
-3 5523 5510 5509
-3 5511 5524 5509
-3 5524 5523 5509
-3 5513 5530 5511
-3 5530 5524 5511
-3 5525 5530 5513
-3 5514 4898 5525
-3 5531 4308 4899
-3 7067 5531 4899
-3 4901 7067 4899
-3 5502 7067 4901
-3 4902 5502 4901
-3 4902 5526 5502
-3 5526 5503 5502
-3 4889 4903 5516
-3 4904 5516 4903
-3 5517 5516 4904
-3 4905 5517 4904
-3 5518 5517 4905
-3 4909 4921 5527
-3 4909 5527 4910
-3 5505 5520 5528
-3 5528 5520 5521
-3 4894 5544 5528
-3 5521 4894 5528
-3 5535 4896 4912
-3 5523 5524 5536
-3 5530 5529 5524
-3 5529 5536 5524
-3 5525 4914 5530
-3 4902 4916 5526
-3 4921 5543 7180
-3 4921 7180 5527
-3 5528 5544 5532
-3 7237 4373 4850
-3 4912 4922 5535
-3 4913 5501 4923
-3 5501 5558 4923
-3 4355 5522 5549
-3 5530 5536 5529
-3 4914 5536 5530
-3 5538 5537 5531
-3 5531 5537 5550
-3 4926 4925 5541
-3 4926 5541 4921
-3 5541 5542 4921
-3 5543 4921 5542
-3 7192 5533 5545
-3 5534 5545 5533
-3 5545 5546 5547
-3 5534 5546 5545
-3 7197 5535 4922
-3 4933 4923 5558
-3 4935 5559 4914
-3 4937 7169 7211
-3 4938 7169 4937
-3 5538 4938 5537
-3 5538 7169 4938
-3 4938 5550 5537
-3 5540 5551 5539
-3 4845 7220 5643
-3 5552 4927 5563
-3 5563 4927 4928
-3 5553 5554 5555
-3 4939 5555 5554
-3 5547 5556 5545
-3 5548 4943 5557
-3 4931 4943 5548
-3 4932 5557 4944
-3 5548 5557 4932
-3 4922 4945 7197
-3 4346 4355 5549
-3 5559 4935 5560
-3 5561 7211 7248
-3 5561 4946 7211
-3 4946 4937 7211
-3 4938 4947 5550
-3 5541 4948 5542
-3 5562 5542 4948
-3 4927 5552 4349
-3 4349 5552 7223
-3 5553 5555 4960
-3 5564 5554 5553
-3 5554 5565 4951
-3 5554 5564 5565
-3 4951 5565 5570
-3 4951 5570 4941
-3 4943 4944 5557
-3 4292 4952 5576
-3 5566 4953 4346
-3 7248 4954 5567
-3 7248 5560 4954
-3 5560 4935 4954
-3 7248 5567 5561
-3 5561 5567 5573
-3 5561 5573 4946
-3 4948 4956 5562
-3 5562 4956 5568
-3 5569 4349 7223
-3 5569 4959 4349
-3 5563 4928 4960
-3 5570 5565 5564
-3 5570 5564 4961
-3 4953 5566 5571
-3 4954 5572 5567
-3 5573 5567 5572
-3 5574 5587 5568
-3 4959 5575 5574
-3 4959 5574 5568
-3 4959 5568 4956
-3 4959 7302 5575
-3 4959 5569 7302
-3 5580 4933 5558
-3 5580 5592 4933
-3 5571 7361 4381
-3 4953 5571 4381
-3 5577 5573 5572
-3 5587 5574 5578
-3 5574 5579 5578
-3 7302 5579 5575
-3 5579 5574 5575
-3 4965 7344 4961
-3 7345 4971 4962
-3 4973 7464 4966
-3 7464 4945 4966
-3 4952 5581 5576
-3 4381 5581 4952
-3 7361 5581 4381
-3 5583 5584 5585
-3 5586 5587 5578
-3 5579 5588 5578
-3 5588 5586 5578
-3 5588 5579 7302
-3 7344 4965 4968
-3 7344 4968 4977
-3 5589 4384 4970
-3 7345 5596 4971
-3 4975 5591 5580
-3 4975 5580 5590
-3 5592 5580 5591
-3 4989 7402 5584
-3 5600 4989 5583
-3 5584 5583 4989
-3 5594 5587 5586
-3 5602 5587 5594
-3 5594 5586 5588
-3 4977 4968 4976
-3 7410 4993 4980
-3 7410 4980 5589
-3 5589 4980 4981
-3 4396 5589 4981
-3 5589 4396 4384
-3 4994 5589 4970
-3 4994 5595 5596
-3 4994 5596 5589
-3 4983 5596 5595
-3 4983 4971 5596
-3 4973 4403 7464
-3 5597 5591 4975
-3 5597 5592 5591
-3 4985 5592 5598
-3 5592 5597 5598
-3 4986 5582 5599
-3 5582 5605 5599
-3 5607 4996 5593
-3 7402 4988 5600
-3 4989 4988 7402
-3 5602 5594 5601
-3 4993 7410 5623
-3 4983 5595 5603
-3 5603 5595 4994
-3 5009 5604 5597
-3 5604 5598 5597
-3 5598 5604 4985
-3 5607 5606 4996
-3 4988 4997 5600
-3 5609 5602 5601
-3 5610 5601 5594
-3 5609 5601 5610
-3 5007 4993 5623
-3 5008 5603 4994
-3 7486 4415 5590
-3 5604 5009 5612
-3 4985 5604 5613
-3 5604 5612 5613
-3 5599 5605 5002
-3 4996 5004 5593
-3 5593 5004 5615
-3 5006 5606 5614
-3 5614 5606 5607
-3 5617 5607 7447
-3 5614 5607 5617
-3 4977 5619 7477
-3 5611 4977 7477
-3 5011 5612 5009
-3 5613 5612 5011
-3 5013 5615 5004
-3 5616 5615 5014
-3 5014 5615 5013
-3 5014 5617 5616
-3 5006 5617 5014
-3 5006 5614 5617
-3 5016 5618 5619
-3 4977 5016 5619
-3 5007 5623 5628
-3 5016 5620 5618
-3 5620 5621 5618
-3 5619 5618 5622
-3 5622 5618 5621
-3 5619 5622 7503
-3 4963 4237 5677
-3 5023 5625 5024
-3 5624 5625 5023
-3 5031 5620 5016
-3 5031 5626 5620
-3 5626 5627 5620
-3 5032 5621 5627
-3 5621 5620 5627
-3 5033 5621 5032
-3 5622 5621 5033
-3 5034 5622 5033
-3 5034 5628 5622
-3 5628 7503 5622
-3 5623 7503 5628
-3 5624 5023 7530
-3 5023 5634 7530
-3 7540 5625 5624
-3 4448 5625 7540
-3 4448 5024 5625
-3 5031 5035 5626
-3 5032 5626 5035
-3 5627 5626 5032
-3 5034 5036 5628
-3 5037 4448 7540
-3 5039 5630 5631
-3 5038 5630 5039
-3 5631 5038 5039
-3 5628 5036 4467
-3 5040 5041 5629
-3 5040 5629 5633
-3 5044 5043 7556
-3 5045 5044 5630
-3 5044 7556 5630
-3 5630 5038 5045
-3 5047 5038 5631
-3 7565 5049 5639
-3 7565 5632 5049
-3 5632 5041 5049
-3 5048 5040 5633
-3 5048 5633 5639
-3 5051 5050 5635
-3 5051 5636 5052
-3 5635 5636 5051
-3 5052 5636 5053
-3 5056 5057 5637
-3 5056 5637 5638
-3 5056 5638 5043
-3 5047 5631 5641
-3 5049 5060 5639
-3 5048 5639 5060
-3 5071 5635 5050
-3 5071 5636 5635
-3 5053 5071 5061
-3 5636 5071 5053
-3 5057 5066 5637
-3 5640 5074 5642
-3 5063 5074 5640
-3 5066 5076 5637
-3 5645 5638 5637
-3 5645 5637 5076
-3 5069 5641 5082
-3 5074 5644 5642
-3 5645 5076 5081
-3 5641 7610 5082
-3 4373 7616 3952
-3 5081 5087 5645
-3 5088 5082 7610
-3 3952 7616 4509
-3 5109 5652 5083
-3 5646 5096 5083
-3 5647 5085 5654
-3 4492 5648 5091
-3 4492 5647 5648
-3 5647 5654 5648
-3 5649 7640 7620
-3 7620 5650 5649
-3 5651 5093 5092
-3 5094 5093 5651
-3 5087 5094 5645
-3 5094 5651 5645
-3 5096 5646 5653
-3 7666 5096 5653
-3 5666 5096 7666
-3 5091 5648 5104
-3 5655 7640 5649
-3 5650 5656 5649
-3 5656 5655 5649
-3 5105 5656 5650
-3 5102 5101 5657
-3 5102 5657 5103
-3 5116 7680 5115
-3 5115 7680 5665
-3 5109 5658 5652
-3 5660 5648 5659
-3 5659 5648 5654
-3 5104 5648 5660
-3 5655 5104 5660
-3 5105 5104 5655
-3 5656 5105 5655
-3 5107 5662 5661
-3 5107 5106 5662
-3 5106 5105 5662
-3 5101 5108 5657
-3 5103 5657 5108
-3 5118 7671 5092
-3 5663 5664 5112
-3 5671 7680 5116
-3 5115 5665 5123
-3 7686 5109 4509
-3 7686 5658 5109
-3 5660 5659 5666
-3 5107 5661 5110
-3 5661 5111 5110
-3 5661 5662 5111
-3 5112 5673 5672
-3 5114 5667 5668
-3 5668 5669 5670
-3 5667 5669 5668
-3 5671 5670 5669
-3 7777 7761 4509
-3 7761 7686 4509
-3 5662 5127 5111
-3 5683 7724 5674
-3 5114 5674 7724
-3 5668 5675 5122
-3 5114 5668 5122
-3 5670 5676 5668
-3 5676 5675 5668
-3 5671 5116 5670
-3 5116 5676 5670
-3 5124 5123 5665
-3 5679 5678 5691
-3 5127 5693 5681
-3 5127 5662 5693
-3 5681 5693 5118
-3 5119 5135 5112
-3 5673 5695 5672
-3 5695 5682 5672
-3 5673 5683 5695
-3 5683 5674 5684
-3 5685 5684 5674
-3 5674 5686 5685
-3 5122 5675 5687
-3 5676 5688 5675
-3 5688 5687 5675
-3 5116 5132 5688
-3 5116 5688 5676
-3 5703 5137 5665
-3 5124 5137 5133
-3 5665 5137 5124
-3 5689 5678 5679
-3 5690 5689 5679
-3 5691 5678 5689
-3 5691 5689 5692
-3 5125 7784 5697
-3 5126 7784 5125
-3 5127 5681 5134
-3 5694 5135 5682
-3 5695 5694 5682
-3 5708 5695 5683
-3 5685 5700 5684
-3 5686 5696 5685
-3 5696 5686 5122
-3 5687 5696 5122
-3 5132 5136 5688
-3 7803 5689 5690
-3 5692 5689 7803
-3 5680 5138 7824
-3 5695 5699 5694
-3 5699 5698 5694
-3 5708 5699 5695
-3 5684 5708 5683
-3 5685 5701 5700
-3 5696 5702 5685
-3 5702 5701 5685
-3 5688 5136 5703
-3 5704 5703 5136
-3 5703 5704 5137
-3 5138 5705 7824
-3 5706 5705 5138
-3 5139 5707 5138
-3 5138 5707 5706
-3 7826 5707 5139
-3 5140 5643 5698
-3 5699 5140 5698
-3 5700 5708 5684
-3 5701 5709 5700
-3 5702 5710 5701
-3 5710 5709 5701
-3 5711 5710 5702
-3 5136 5712 5704
-3 5137 5704 5712
-3 5141 7840 5713
-3 7824 5705 5142
-3 7824 5142 5713
-3 5713 5142 5141
-3 5705 5706 5142
-3 5142 5706 5143
-3 5144 5143 5714
-3 5143 5706 5714
-3 7826 5139 5144
-3 5714 7826 5144
-3 5700 5715 5708
-3 5709 5715 5700
-3 5710 5715 5709
-3 5711 5145 5710
-3 5145 5715 5710
-3 5711 5716 5145
-3 5716 5717 5712
-3 5712 5717 4530
-3 5677 4530 5718
-3 5141 4521 7840
-3 5716 5718 5717
-3 4530 5717 5718
-3 4539 5719 5720
-3 4539 5721 5719
-3 4539 5722 5721
-3 4539 5723 5722
-3 4539 5724 5723
-3 4539 5725 5724
-3 5727 5726 4539
-3 4539 5726 5725
-3 5727 5729 5728
-3 5727 5730 5729
-3 5727 5731 5730
-3 4534 5732 5731
-3 4534 5731 5727
-3 5733 4534 5146
-3 5745 5733 5146
-3 5734 5749 5149
-3 5734 5149 4533
-3 4533 5735 5734
-3 5152 5736 4533
-3 4533 5736 5735
-3 5152 5737 5736
-3 4538 5738 5739
-3 4538 5740 5738
-3 4539 5741 4538
-3 4538 5741 5740
-3 5741 4539 5720
-3 4534 5742 5732
-3 5743 5742 4534
-3 5744 5743 4534
-3 5733 5744 4534
-3 5746 5745 5146
-3 5150 5747 5746
-3 5146 5150 5746
-3 5149 5748 5160
-3 5149 5749 5748
-3 5152 5750 5737
-3 5751 5750 5152
-3 5152 5759 5751
-3 5152 5164 5759
-3 5153 5752 5753
-3 4538 5754 5153
-3 5153 5754 5752
-3 5754 4538 5739
-3 5150 5755 5747
-3 5150 5160 5755
-3 5160 5756 5755
-3 5160 5757 5756
-3 5748 5758 5160
-3 5758 5757 5160
-3 5760 5761 5759
-3 5164 5760 5759
-3 5164 5167 5762
-3 5760 5164 5762
-3 5153 5763 5764
-3 5763 5153 5753
-3 5765 5761 5760
-3 5766 5761 5765
-3 5762 5767 5760
-3 5767 5765 5760
-3 5167 5767 5762
-3 5167 5768 5767
-3 5768 5769 5767
-3 5771 5770 5768
-3 5175 5772 5773
-3 5153 5774 5175
-3 5175 5774 5772
-3 5774 5153 5764
-3 5776 5766 5765
-3 5775 5766 5776
-3 5767 5776 5765
-3 5777 5767 5769
-3 5776 5767 5777
-3 5768 5778 5771
-3 5779 5778 5768
-3 5780 5217 5781
-3 5175 5782 5217
-3 5217 5782 5781
-3 5782 5175 5773
-3 5170 5783 5178
-3 5198 5785 5786
-3 5787 5198 5786
-3 5776 5788 5775
-3 5788 5789 5790
-3 5788 5776 5789
-3 5791 5776 5777
-3 5789 5776 5791
-3 5792 5779 5187
-3 5779 5768 5187
-3 5792 5187 5793
-3 5795 5794 5217
-3 5780 5795 5217
-3 5204 5817 5169
-3 5817 5818 5169
-3 5819 5169 5818
-3 5796 5797 5783
-3 5796 5783 5819
-3 5819 5783 5169
-3 5798 5783 5797
-3 5799 5783 5798
-3 5800 5783 5799
-3 5801 5783 5800
-3 5802 5783 5801
-3 5820 5802 5803
-3 5178 5802 5820
-3 5178 5783 5802
-3 5820 5205 5178
-3 5197 5784 5208
-3 5198 5825 5804
-3 5198 5804 5785
-3 5210 5198 5805
-3 5805 5198 5787
-3 5789 5806 5790
-3 5791 5806 5789
-3 5807 5793 5187
-3 5214 5808 5809
-3 5213 5214 5809
-3 5214 5810 5808
-3 5214 5811 5810
-3 5812 5811 5214
-3 5217 5814 5813
-3 5814 5217 5794
-3 5835 5838 5193
-3 5815 5816 5204
-3 5815 5204 5838
-3 5838 5204 5193
-3 5817 5204 5816
-3 5821 5205 5820
-3 5205 5821 5822
-3 5823 5205 5822
-3 5205 5823 5206
-3 5823 5840 5206
-3 5824 5206 5840
-3 5824 5857 5207
-3 5826 5804 5210
-3 5210 5804 5825
-3 5805 5826 5210
-3 5827 5807 5187
-3 5213 5809 5240
-3 5809 5828 5240
-3 5214 5829 5812
-3 5829 5214 5879
-3 5830 5829 5879
-3 5831 5226 5832
-3 5226 5833 5832
-3 5850 5833 5226
-3 5226 5834 5850
-3 5226 5217 5834
-3 5217 5813 5834
-3 5220 5868 5193
-3 5835 5193 5868
-3 5836 5837 5835
-3 5838 5835 5837
-3 5840 5823 5839
-3 5841 5824 5840
-3 5841 5842 5824
-3 5854 5824 5842
-3 5857 5824 5854
-3 5187 5230 5843
-3 5843 5827 5187
-3 5828 5844 5240
-3 5879 5845 5830
-3 5879 5846 5845
-3 5847 5846 5879
-3 5226 5849 5235
-3 5849 5848 5235
-3 5831 5849 5226
-3 5868 5220 5231
-3 5851 5852 5835
-3 5851 5835 5868
-3 5836 5835 5852
-3 5854 5842 5853
-3 5855 5857 5854
-3 5855 5856 5857
-3 5230 5234 5858
-3 5230 5858 5859
-3 5230 5859 5843
-3 5240 5844 5860
-3 5861 5240 5860
-3 5879 5862 5847
-3 5879 5863 5862
-3 5235 5864 5865
-3 5864 5235 5848
-3 5866 5867 5231
-3 5866 5231 5885
-3 5868 5231 5867
-3 5857 5856 5869
-3 5870 5857 5869
-3 5871 5857 5870
-3 5872 5857 5871
-3 5872 5873 5857
-3 5857 5873 5228
-3 5228 5873 5874
-3 5874 5232 5210
-3 5234 5893 5875
-3 5234 5875 5876
-3 5234 5876 5858
-3 5861 5877 5240
-3 5879 5878 5863
-3 5880 5879 5236
-3 5235 5865 5881
-3 5882 5883 5231
-3 5884 5231 5883
-3 5885 5231 5884
-3 5874 5873 5886
-3 5887 5874 5886
-3 5888 5874 5887
-3 5889 5874 5888
-3 5890 5874 5889
-3 5890 5891 5874
-3 5904 5874 5891
-3 5232 5874 5905
-3 5905 5874 5904
-3 5234 5232 5909
-3 5909 5232 5908
-3 5910 5234 5909
-3 5892 5234 5910
-3 5892 5893 5234
-3 5240 5877 5894
-3 5895 5240 5894
-3 5236 5896 5880
-3 5236 5897 5896
-3 5897 5236 5898
-3 5900 5899 5235
-3 5881 5900 5235
-3 5238 5901 5231
-3 5901 5902 5231
-3 5902 5882 5231
-3 5904 5891 5903
-3 5906 5232 5905
-3 5907 5232 5906
-3 5908 5232 5907
-3 5911 5892 5910
-3 5895 5912 5240
-3 5236 5913 5898
-3 5236 5239 5913
-3 5239 5914 5913
-3 5915 5914 5239
-3 5235 5916 5917
-3 5916 5235 5899
-3 5919 5920 5901
-3 5919 5901 5918
-3 5918 5901 5238
-3 5902 5901 5920
-3 5921 5902 5920
-3 5922 5240 5912
-3 5239 5923 5915
-3 4612 5923 5239
-3 5924 5923 4612
-3 5925 5235 5917
-3 5926 5927 5918
-3 5926 5918 5935
-3 5935 5918 5238
-3 5919 5918 5927
-3 5240 5928 5929
-3 5240 5922 5928
-3 5930 4620 5931
-3 5930 5924 4620
-3 5924 4612 4620
-3 5925 5932 5235
-3 5241 5944 5933
-3 5241 5933 5934
-3 5241 5934 5238
-3 5935 5238 5934
-3 5240 5929 5936
-3 5936 5937 5240
-3 5931 4620 5938
-3 5939 5931 5938
-3 5939 5938 5940
-3 5235 5941 5942
-3 5941 5235 5932
-3 5241 5943 5944
-3 5937 5945 5240
-3 4620 5243 5938
-3 5244 5938 5243
-3 5938 5946 5940
-3 5938 5244 5946
-3 5947 5946 5244
-3 5948 5235 5942
-3 5949 5943 5241
-3 5945 5950 5240
-3 5244 5951 5947
-3 5952 5951 5244
-3 5235 5953 4635
-3 5235 5948 5953
-3 5241 5954 5955
-3 5241 5955 5949
-3 5956 5240 5950
-3 5952 5244 5957
-3 4635 5958 5959
-3 4635 5959 3496
-3 5953 5958 4635
-3 5241 4642 5960
-3 5960 5954 5241
-3 5961 5240 5956
-3 5961 5962 5240
-3 5244 5963 5957
-3 5964 5963 5244
-3 5965 3496 5959
-3 4642 5966 5967
-3 4642 5967 5960
-3 5240 5962 4629
-3 5962 5968 4629
-3 5964 4051 5969
-3 5965 5970 3496
-3 5971 5966 4642
-3 5972 4629 5968
-3 5973 5974 5975
-3 5975 5976 5973
-3 4051 5977 5969
-3 5978 5977 4051
-3 5979 3496 5970
-3 5980 5971 4642
-3 5972 5981 4629
-3 5982 5974 5973
-3 5983 5974 5982
-3 5984 5973 5976
-3 5982 5973 5984
-3 5985 5978 4051
-3 5979 5986 3496
-3 4642 5987 5988
-3 4642 5988 5980
-3 4629 5981 5989
-3 5982 5990 5983
-3 5984 5990 5982
-3 5991 5985 4051
-3 5991 4051 5992
-3 5986 5993 3496
-3 5994 5987 4642
-3 4629 6000 6015
-3 5995 4629 5989
-3 6000 4629 5995
-3 5992 4051 5996
-3 3496 5997 5998
-3 5997 3496 5993
-3 5999 5994 4642
-3 6001 5996 4051
-3 5998 6002 3496
-3 6003 5999 4642
-3 6009 6003 4642
-3 6000 6004 6015
-3 6005 6001 4051
-3 6005 4051 6006
-3 6002 6007 3496
-3 6009 4642 6008
-3 6004 6010 6015
-3 6006 4051 6011
-3 3496 6012 6013
-3 6012 3496 6007
-3 4642 6014 6008
-3 6016 6011 4051
-3 6013 6017 3496
-3 6018 6014 4642
-3 6015 6019 4643
-3 5248 5247 6027
-3 5248 6027 6028
-3 6020 6016 4051
-3 6020 4051 6021
-3 6017 6022 3496
-3 6023 6018 4642
-3 6019 6024 4643
-3 5251 6025 6026
-3 5250 6025 5251
-3 6027 5247 5251
-3 6027 5251 6026
-3 6029 6021 4051
-3 3496 6022 6030
-3 6031 6023 4642
-3 6024 6032 4643
-3 6025 5250 6033
-3 5252 6028 6034
-3 6035 6029 4051
-3 3496 6036 6037
-3 6030 6036 3496
-3 4642 6052 6053
-3 6038 6031 4642
-3 6053 6038 4642
-3 6032 6039 4643
-3 5250 5253 6033
-3 6033 5253 6040
-3 6041 5252 6034
-3 6042 6035 4051
-3 6042 4051 6043
-3 6037 6044 3496
-3 6045 6038 6053
-3 4643 6039 6046
-3 5253 6047 6048
-3 6048 6040 5253
-3 6041 6049 5252
-3 6050 6043 4051
-3 4702 3496 6051
-3 3496 6044 6051
-3 6054 6045 6053
-3 6055 4643 6046
-3 6062 4643 6055
-3 5253 6056 6047
-3 6049 6057 4656
-3 5252 6049 4656
-3 4051 6058 6050
-3 4702 6059 6060
-3 6051 6059 4702
-3 6053 6052 5256
-3 6061 6054 6053
-3 6065 6056 5253
-3 6064 6065 5253
-3 4656 6067 6066
-3 4656 6057 6067
-3 6058 4051 6068
-3 6060 6069 4702
-3 6070 6061 6053
-3 6062 6063 4643
-3 6063 6071 4643
-3 6064 5257 5259
-3 6064 5259 6065
-3 6065 5259 6072
-3 6066 6073 5258
-3 6068 4051 6074
-3 4702 6075 6087
-3 4702 6069 6075
-3 6070 6053 6076
-3 4050 4643 6077
-3 6077 4643 6071
-3 5259 6078 6079
-3 6079 6072 5259
-3 6073 6093 5258
-3 6080 6094 6073
-3 6094 6093 6073
-3 6080 6081 6094
-3 6082 6083 6084
-3 6084 6085 6082
-3 5260 6086 4051
-3 6086 6074 4051
-3 6087 6088 4702
-3 6089 5265 6090
-3 6089 6076 5265
-3 6076 6053 5265
-3 6077 6091 4050
-3 5264 6092 5259
-3 5259 6092 6078
-3 5258 6093 5262
-3 6095 6094 6081
-3 6096 6097 6098
-3 6096 6083 6099
-3 6098 6083 6096
-3 6100 6082 6101
-3 6100 6099 6082
-3 6083 6082 6099
-3 6085 6101 6082
-3 5260 6102 6086
-3 6088 6103 4702
-3 6090 5265 6104
-3 6091 6105 4050
-3 6092 5264 6106
-3 5263 6107 6122
-3 5262 6107 5263
-3 5262 6093 6107
-3 6094 6107 6093
-3 6108 6107 6094
-3 6095 6108 6094
-3 6109 6097 6096
-3 6110 6097 6109
-3 6099 6111 6096
-3 6111 6109 6096
-3 6112 6099 6100
-3 6111 6099 6112
-3 6102 5260 6113
-3 4702 6103 6114
-3 6104 5265 6115
-3 4050 6116 6117
-3 6116 4050 6105
-3 6118 6106 5264
-3 6119 6106 6118
-3 5264 6120 6118
-3 5264 5263 6120
-3 6120 6121 6118
-3 6122 6120 5263
-3 6123 6124 6125
-3 6110 6123 6125
-3 6110 6109 6123
-3 6109 6126 6123
-3 6127 6111 6128
-3 6127 6126 6111
-3 6126 6109 6111
-3 6112 6128 6111
-3 6129 6113 5260
-3 6114 6130 4702
-3 5265 5267 6115
-3 5267 6131 6115
-3 4050 6117 6143
-3 6117 6132 6143
-3 6133 6119 6118
-3 6134 6119 6133
-3 6135 6118 6121
-3 6133 6118 6135
-3 6136 6124 6123
-3 6137 6124 6136
-3 6138 6126 6139
-3 6138 6136 6126
-3 6136 6123 6126
-3 6127 6139 6126
-3 5260 6140 6129
-3 6130 6141 4702
-3 6131 5267 6142
-3 6133 6144 6134
-3 6135 6144 6133
-3 6136 6145 6137
-3 6138 6145 6136
-3 6140 5260 6146
-3 6141 6147 4702
-3 6148 5267 6149
-3 6148 6142 5267
-3 6143 6154 5268
-3 6143 6150 6154
-3 6146 5260 6151
-3 6147 6152 4702
-3 5267 6153 6149
-3 6154 6155 5268
-3 6151 5260 6156
-3 6152 6157 4702
-3 5267 6159 6158
-3 5267 6158 6153
-3 6155 6160 5268
-3 6161 6162 6163
-3 6161 6164 6165
-3 6163 6164 6161
-3 6165 6166 6167
-3 6164 6166 6165
-3 6167 6168 6169
-3 6166 6168 6167
-3 6168 6170 6169
-3 6171 6156 5260
-3 6157 6172 4702
-3 5267 6173 6159
-3 6174 5270 5268
-3 6174 5268 6160
-3 5271 6175 6176
-3 5272 6175 5271
-3 5273 6177 6178
-3 5273 5271 6177
-3 5271 6176 6177
-3 6177 6179 6178
-3 6178 6180 6181
-3 6179 6180 6178
-3 6182 6161 6183
-3 6182 6181 6161
-3 6162 6161 6180
-3 6180 6161 6181
-3 6165 6183 6161
-3 6184 6183 6165
-3 6167 6184 6165
-3 6185 6184 6167
-3 6169 6185 6167
-3 6186 6185 6169
-3 6170 6186 6169
-3 5260 6187 6171
-3 6172 6188 4702
-3 6189 6173 5267
-3 6189 5267 6190
-3 5284 6191 6192
-3 6191 5284 6193
-3 6194 6174 6195
-3 5276 6174 6194
-3 5276 5270 6174
-3 5273 6197 5278
-3 5276 6194 5272
-3 5272 6194 6196
-3 5272 6196 6175
-3 5273 6198 6197
-3 5273 6178 6198
-3 6198 6208 6199
-3 6198 6178 6208
-3 6200 6181 6201
-3 6200 6208 6181
-3 6208 6178 6181
-3 6182 6201 6181
-3 6187 5260 6202
-3 6188 6203 4702
-3 5285 6190 5267
-3 5285 6204 6190
-3 6205 5284 6192
-3 6206 6193 5284
-3 6206 5284 5280
-3 6195 6206 5280
-3 6194 6195 5280
-3 6194 5280 5281
-3 6194 6207 6196
-3 6194 5281 6207
-3 6197 6207 5278
-3 5278 6207 5281
-3 6202 5260 6209
-3 6203 6210 4702
-3 5285 6212 6211
-3 5285 6211 6204
-3 5283 6213 6214
-3 6205 6213 5283
-3 5284 6205 5283
-3 6209 5260 6215
-3 6210 6216 4702
-3 5285 6217 6212
-3 5288 5283 6214
-3 6218 5288 6214
-3 6215 5260 6219
-3 6216 6220 4702
-3 5285 6221 6217
-3 6221 5285 6222
-3 6238 6223 6224
-3 6223 6238 6225
-3 6238 6226 6227
-3 6225 6238 6227
-3 6227 6226 6228
-3 5287 6229 6230
-3 6218 6229 5288
-3 6229 5287 5288
-3 5260 6231 6219
-3 6220 6232 4702
-3 5285 6233 6222
-3 6233 5285 6234
-3 6235 6236 6237
-3 6235 6238 6239
-3 6236 6235 6239
-3 6224 6239 6238
-3 6240 6228 6226
-3 6242 6241 6230
-3 6242 5291 6241
-3 6242 6243 5291
-3 5260 6244 6231
-3 6232 6245 4702
-3 6246 6247 6248
-3 6248 6249 6246
-3 5285 6251 6234
-3 6251 5285 6252
-3 6253 6235 6237
-3 6254 6253 6237
-3 6238 6235 6268
-3 6268 6235 6253
-3 6255 6238 6268
-3 6226 6238 6256
-3 6256 6238 6255
-3 6257 6240 6226
-3 6256 6257 6226
-3 5291 5290 6241
-3 5291 6243 6258
-3 6244 5260 6259
-3 6245 6260 4702
-3 6261 6247 6246
-3 6249 6262 6246
-3 6262 6261 6246
-3 6263 6249 6250
-3 6262 6249 6263
-3 5285 6264 6252
-3 6253 6266 6267
-3 6254 6266 6253
-3 6255 6268 6269
-3 6256 6255 6270
-3 6270 6255 6269
-3 6271 6257 6256
-3 6271 6256 6272
-3 6272 6256 6270
-3 6273 5291 6258
-3 6273 6274 5291
-3 6259 5260 6275
-3 6260 6276 4702
-3 6277 6278 6279
-3 6277 6261 6278
-3 6261 6262 6278
-3 6280 6262 6263
-3 6278 6262 6280
-3 5285 5299 6264
-3 5299 6281 6265
-3 5299 6265 6264
-3 6283 6284 6285
-3 6267 6284 6283
-3 6267 6283 6253
-3 6253 6283 6286
-3 6287 6253 6286
-3 6268 6253 6287
-3 6288 6268 6287
-3 6269 6268 6288
-3 6270 6269 6288
-3 6272 6270 6289
-3 6289 6270 6288
-3 6290 6272 6291
-3 6291 6272 6289
-3 6290 6291 6292
-3 6274 6294 5305
-3 6275 5260 6295
-3 6276 6296 4702
-3 6278 6297 6279
-3 6297 6278 6316
-3 6298 6316 6280
-3 6280 6316 6278
-3 6298 6299 6316
-3 5299 6300 6282
-3 5299 6282 6281
-3 6300 5299 6301
-3 6303 6283 6285
-3 6304 6303 6285
-3 6286 6283 6305
-3 6305 6283 6303
-3 6287 6286 6306
-3 6306 6286 6305
-3 5300 6287 6306
-3 6288 6287 5300
-3 5307 6288 5300
-3 5307 6307 6288
-3 6307 6289 6288
-3 5301 6291 6307
-3 6291 6289 6307
-3 5301 6308 6291
-3 6308 6292 6291
-3 6309 6293 6292
-3 6309 6292 6310
-3 6310 6292 6308
-3 5305 6311 6312
-3 6311 5305 6294
-3 6295 5260 6313
-3 6296 6314 4702
-3 6297 6316 6315
-3 6317 6316 6299
-3 5322 6301 5299
-3 6319 6302 6301
-3 6319 6301 5322
-3 6319 5322 6320
-3 6304 6324 6303
-3 6303 6324 5324
-3 6305 6303 5324
-3 6306 6305 5324
-3 5300 6306 5324
-3 6307 5307 6325
-3 5301 6307 6326
-3 6307 6325 6326
-3 5301 6326 6308
-3 6310 6308 6327
-3 6327 6308 6326
-3 6327 6328 6310
-3 6329 6348 5309
-3 6329 5309 6330
-3 6330 5309 5310
-3 5310 6331 6330
-3 6312 5310 5305
-3 6331 5310 6312
-3 6313 5260 6332
-3 6314 6333 4702
-3 6334 6315 5313
-3 5312 5313 6316
-3 6316 5313 6315
-3 5312 6316 6317
-3 6335 6317 6318
-3 6335 5312 6317
-3 6335 6336 5312
-3 6337 6320 5322
-3 6337 5322 6338
-3 6339 6340 6341
-3 6340 6339 6342
-3 6342 6362 6343
-3 6322 6343 6362
-3 6322 6362 6321
-3 6321 6362 5324
-3 6323 6321 5324
-3 6324 6323 5324
-3 5307 5315 6325
-3 6326 6325 5315
-3 6327 6326 4684
-3 6327 4684 6328
-3 6328 4684 6344
-3 5308 6345 6346
-3 5309 6347 5308
-3 5308 6347 6345
-3 6348 6347 5309
-3 6332 5260 6349
-3 6333 6350 4702
-3 5313 6351 6334
-3 6353 6352 6351
-3 5312 6353 6351
-3 5312 6351 5313
-3 5312 6354 6353
-3 6355 6354 5312
-3 6336 6355 5312
-3 5322 6356 6338
-3 6356 5322 6357
-3 6358 6359 6360
-3 6341 6359 6358
-3 6341 6358 6339
-3 6339 6358 6361
-3 6342 6339 6362
-3 6362 6339 6361
-3 5324 6362 6378
-3 6363 6344 4684
-3 6364 5308 6365
-3 6365 5308 6346
-3 6349 5260 6366
-3 6350 6367 4702
-3 6353 6368 6352
-3 6369 6370 6357
-3 6369 6357 5322
-3 6370 6369 6371
-3 6373 6374 6375
-3 6374 6373 6376
-3 6376 6378 6377
-3 6360 6377 6378
-3 6360 6378 6358
-3 6361 6358 6378
-3 6362 6361 6378
-3 6363 4684 6379
-3 6380 5308 6381
-3 6381 5308 6364
-3 6366 5260 6382
-3 6367 6383 4702
-3 6384 6372 6371
-3 6384 6371 6369
-3 6384 6369 6385
-3 6388 6386 6387
-3 6375 6386 6388
-3 6375 6388 6373
-3 6376 6373 6388
-3 6378 6376 5346
-3 5346 6376 6388
-3 6379 4684 6389
-3 6381 6391 6380
-3 6391 6390 6380
-3 6391 6381 6392
-3 5343 6393 6394
-3 5333 5343 6395
-3 5343 6394 6395
-3 6395 5334 5333
-3 6396 5334 6395
-3 6397 6382 5260
-3 6383 6398 4702
-3 6399 6385 6369
-3 6399 6369 6400
-3 6400 6402 6401
-3 6403 6404 6405
-3 6387 6406 6388
-3 6407 6389 4684
-3 6390 6408 4698
-3 6380 6390 4698
-3 6391 6409 6390
-3 6409 6408 6390
-3 6410 6391 6392
-3 6410 6411 6391
-3 6411 6409 6391
-3 6411 6412 6413
-3 6410 6412 6411
-3 6412 6414 6413
-3 6416 6417 6415
-3 6419 6420 6421
-3 6419 6421 6393
-3 6419 6393 5343
-3 6422 5344 6396
-3 5344 5334 6396
-3 1262 6397 5260
-3 6424 6397 1262
-3 6398 6425 4702
-3 6369 6428 6400
-3 6402 6400 6428
-3 6426 6402 6428
-3 6426 6428 6427
-3 6432 6465 6433
-3 6433 6465 6434
-3 6465 6404 6435
-3 6434 6465 6435
-3 6388 6406 6405
-3 5346 6388 6405
-3 4684 6436 6407
-3 6436 4684 6437
-3 6438 6472 2279
-3 6438 2279 6439
-3 6439 2279 5337
-3 6440 6441 6439
-3 6440 6439 5337
-3 5347 5348 6442
-3 5349 6443 5348
-3 5348 6443 6442
-3 6443 5349 5350
-3 6444 6443 5350
-3 4698 6408 5351
-3 6409 6445 6408
-3 6411 6445 6409
-3 6446 6413 6447
-3 6446 6445 6413
-3 6445 6411 6413
-3 6414 6447 6413
-3 6415 6448 6449
-3 6415 5352 6448
-3 6417 6418 6450
-3 6417 6450 5357
-3 6451 5357 6450
-3 6452 6453 6454
-3 6452 6420 6455
-3 6454 6420 6452
-3 6420 6419 6455
-3 6419 6456 6455
-3 5343 6456 6419
-3 5343 6457 6456
-3 6457 6458 6456
-3 6423 5344 6422
-3 6423 6457 5344
-3 6457 5343 5344
-3 6459 6424 1262
-3 6425 6460 4702
-3 6461 6428 5359
-3 5359 6428 5354
-3 6461 5359 6462
-3 6462 5359 6463
-3 6463 5359 6464
-3 5359 6465 6466
-3 6464 5359 6466
-3 6466 6465 6467
-3 6467 6465 6468
-3 6430 6468 6465
-3 6430 6465 6429
-3 6431 6429 6465
-3 6432 6431 6465
-3 6404 6465 6405
-3 6495 6469 4684
-3 6469 6437 4684
-3 2279 6471 6470
-3 6472 6471 2279
-3 6473 6441 6440
-3 5356 6474 6475
-3 6442 5356 5347
-3 6474 5356 6442
-3 5350 6501 6444
-3 6444 6501 6476
-3 6477 6445 6478
-3 6477 6408 6445
-3 6479 6478 6445
-3 6446 6479 6445
-3 6480 6448 5352
-3 6480 5352 6481
-3 6482 5357 6483
-3 6483 5357 6451
-3 5357 6484 5358
-3 6482 6484 5357
-3 6484 6485 5358
-3 6486 6487 6488
-3 6453 6486 6488
-3 6453 6452 6486
-3 6452 6489 6486
-3 6455 6490 6452
-3 6490 6489 6452
-3 6491 6456 6492
-3 6491 6490 6456
-3 6490 6455 6456
-3 6458 6492 6456
-3 6493 6459 1262
-3 6460 6494 4702
-3 6541 6496 6495
-3 4684 6541 6495
-3 4684 5361 6541
-3 2279 6497 6498
-3 6497 2279 6470
-3 6499 6473 6440
-3 4750 5356 6500
-3 6500 5356 6475
-3 6501 6502 6476
-3 4771 5351 6503
-3 6503 5351 6408
-3 6503 6408 6477
-3 5352 5374 6481
-3 6481 5374 6504
-3 6482 6483 6505
-3 6505 6506 6507
-3 6505 6507 6482
-3 6482 6507 6484
-3 6485 6507 4739
-3 6485 6484 6507
-3 6508 6509 6510
-3 6487 6508 6510
-3 6487 6486 6508
-3 6486 6511 6508
-3 6489 6512 6486
-3 6512 6511 6486
-3 6513 6490 6514
-3 6513 6512 6490
-3 6512 6489 6490
-3 6491 6514 6490
-3 6515 6493 1262
-3 6494 6516 4702
-3 6539 6496 6541
-3 6517 6496 6539
-3 6518 2279 6519
-3 2279 6520 6519
-3 6520 2279 6498
-3 6440 6521 6499
-3 5363 5360 6523
-3 6522 5363 6523
-3 4750 6500 6524
-3 6557 6524 6525
-3 4750 6524 6557
-3 4750 6557 6526
-3 4750 6526 6527
-3 4750 6527 6501
-3 6502 6501 6527
-3 6503 6528 4771
-3 5374 6529 6530
-3 6530 6504 5374
-3 4739 6507 6506
-3 4739 6506 6531
-3 6532 6509 6508
-3 6533 6509 6532
-3 6511 6534 6508
-3 6534 6532 6508
-3 6535 6512 6536
-3 6535 6534 6512
-3 6534 6511 6512
-3 6513 6536 6512
-3 6537 6515 1262
-3 1262 6595 6537
-3 4702 6516 4845
-3 6516 6538 4845
-3 6540 6539 6541
-3 6542 6541 5361
-3 6542 5361 6543
-3 6544 5362 6545
-3 5362 6546 6545
-3 5362 6547 6546
-3 6547 2279 6548
-3 6548 2279 6549
-3 6549 2279 6550
-3 2279 6551 6550
-3 6518 6551 2279
-3 6553 6521 5379
-3 5379 6521 6440
-3 5364 5363 6522
-3 5364 6522 6554
-3 6523 6555 6522
-3 6555 6554 6522
-3 5360 6556 6523
-3 6556 6555 6523
-3 5360 5365 6556
-3 6528 6558 4771
-3 5374 6559 6560
-3 6560 6529 5374
-3 6561 5375 6562
-3 6562 5375 4739
-3 6562 4739 6531
-3 6532 6563 6533
-3 6534 6563 6532
-3 6564 6563 6534
-3 6535 6564 6534
-3 6538 6566 4845
-3 4776 6568 5368
-3 6567 6568 4776
-3 6568 6569 5368
-3 5368 6569 6570
-3 6598 5368 6571
-3 5368 6570 6571
-3 6598 6571 6572
-3 6572 6573 6598
-3 5361 6575 6543
-3 3635 6576 5361
-3 5361 6576 6575
-3 5362 6577 3635
-3 6577 6576 3635
-3 6544 6577 5362
-3 5362 2279 6547
-3 5379 6552 6553
-3 5379 6578 6552
-3 5364 6554 6603
-3 6555 6579 6554
-3 6579 6603 6554
-3 6556 6580 6555
-3 6580 6579 6555
-3 5365 5370 6580
-3 6556 5365 6580
-3 5373 6581 6582
-3 6581 5373 6583
-3 6558 5373 4771
-3 6583 5373 6558
-3 5374 6584 6585
-3 6585 6559 5374
-3 5375 6586 6615
-3 6587 5375 6561
-3 6586 5375 6587
-3 6623 6588 5366
-3 6588 6589 5366
-3 6590 6591 5366
-3 6590 5366 6589
-3 6591 6592 6593
-3 6591 6593 5366
-3 5366 6594 5376
-3 5366 6593 6594
-3 5376 6594 5378
-3 6595 6565 6537
-3 6566 6596 4845
-3 4790 6597 6567
-3 6597 6568 6567
-3 6599 6573 6574
-3 6599 6598 6573
-3 6599 6600 6598
-3 5379 6601 6602
-3 5379 6602 6578
-3 6603 6579 6604
-3 6604 6580 6605
-3 6604 6579 6580
-3 5383 5373 6606
-3 6607 6606 5373
-3 5373 6582 6608
-3 6607 5373 6609
-3 6609 5373 6610
-3 6610 5373 6608
-3 6609 6611 5392
-3 6610 6611 6609
-3 6611 6612 5392
-3 5392 5374 5384
-3 5392 6612 5374
-3 6612 6613 5374
-3 6613 6584 5374
-3 6586 6614 6615
-3 6616 6614 6586
-3 6587 6616 6586
-3 6618 6619 5385
-3 5385 6619 6620
-3 6623 5385 6621
-3 6621 5385 6620
-3 6621 6622 6623
-3 6625 6626 6588
-3 6625 6588 6624
-3 6624 6588 6623
-3 6626 6627 6628
-3 6626 6628 6588
-3 6588 6628 6589
-3 6629 6590 6589
-3 6629 6589 6630
-3 6630 6589 6628
-3 6592 6629 6630
-3 6593 6592 6630
-3 6593 6630 5395
-3 5378 6593 5395
-3 6594 6593 5378
-3 6631 6595 1262
-3 6596 6632 4845
-3 6597 4790 6633
-3 4790 6660 6633
-3 6660 6634 6633
-3 6660 6598 6635
-3 6598 6636 6635
-3 6637 6636 6598
-3 6600 6637 6598
-3 5379 6638 6601
-3 6638 5379 6639
-3 6603 6640 6680
-3 6641 6605 6580
-3 6580 5370 6641
-3 5391 6642 6643
-3 5383 6644 5391
-3 5391 6644 6642
-3 6645 6644 5383
-3 6606 6645 5383
-3 6646 6645 6606
-3 6647 6646 6606
-3 6647 6648 6649
-3 6647 6606 6648
-3 6606 6607 6648
-3 6609 6648 6607
-3 5385 6651 6652
-3 6652 6653 5385
-3 6617 6618 5385
-3 6617 5385 6653
-3 6654 6623 6622
-3 6624 6623 6655
-3 6655 6623 6654
-3 6656 6625 6624
-3 6656 6624 6657
-3 6657 6624 6655
-3 6627 6656 6657
-3 6628 6627 6657
-3 6628 6657 5396
-3 6628 5396 5395
-3 6630 6628 5395
-3 1262 6658 6631
-3 6659 4845 6632
-3 6661 6660 6635
-3 6662 6661 6635
-3 6663 6664 6665
-3 6665 6666 6663
-3 5397 6667 6668
-3 5397 6668 6669
-3 6669 6670 5397
-3 6670 6671 5411
-3 6671 6672 5411
-3 5399 5411 6673
-3 5411 6672 6673
-3 6674 5399 6673
-3 6675 6639 5379
-3 5417 5400 6700
-3 6678 6700 5400
-3 6679 6680 6640
-3 6641 6680 6679
-3 6641 5430 6680
-3 6641 5370 5430
-3 4814 6681 6682
-3 4814 6643 6681
-3 4814 5391 6643
-3 6683 6649 6648
-3 6609 5403 6648
-3 6615 6650 5407
-3 5407 6650 6684
-3 6685 6686 5385
-3 6651 5385 6686
-3 5408 6654 6687
-3 6655 6654 5408
-3 5396 6655 5408
-3 6657 6655 5396
-3 6659 6689 4845
-3 6663 6690 6664
-3 6666 6690 6663
-3 5409 6691 6667
-3 6692 5397 6670
-3 5411 5412 6692
-3 5411 6692 6670
-3 5399 6674 5414
-3 6674 6693 5414
-3 6694 6675 5379
-3 6724 6723 6676
-3 6695 6724 6676
-3 6728 6727 6695
-3 6677 6729 6695
-3 6729 6728 6695
-3 6677 5415 6729
-3 5417 6696 6697
-3 5417 6698 6696
-3 6699 6698 5417
-3 6700 6699 5417
-3 5400 6701 6678
-3 5400 6702 6701
-3 5420 4814 6682
-3 6703 5420 6682
-3 6648 6704 6683
-3 5403 6705 6704
-3 5403 6704 6648
-3 5407 6684 6706
-3 5407 6706 5427
-3 6707 5427 6706
-3 5385 6707 6708
-3 5385 6708 6709
-3 6685 5385 6709
-3 5408 6710 6711
-3 6710 5408 6687
-3 6688 6658 6712
-3 6689 6713 4845
-3 6714 5409 6715
-3 6714 6691 5409
-3 6692 6716 5428
-3 5412 6716 6692
-3 5412 6717 6716
-3 5412 5411 6717
-3 6745 6717 5411
-3 6718 6745 5411
-3 6718 5411 6719
-3 6719 5411 5414
-3 6719 5414 6693
-3 5379 6720 6694
-3 6676 6722 6721
-3 6723 6722 6676
-3 6725 6724 6695
-3 6726 6725 6695
-3 6727 6726 6695
-3 6729 5415 6730
-3 5415 5429 6730
-3 6731 5429 6732
-3 6732 5429 5417
-3 6732 5417 6697
-3 5400 6733 6702
-3 5400 6734 6733
-3 6735 5420 6703
-3 5403 6736 6705
-3 5403 5431 6736
-3 5431 6737 6736
-3 5431 6738 6737
-3 5408 6711 6739
-3 6712 6658 6740
-3 6713 6741 4845
-3 6715 5409 6742
-3 5409 4199 6742
-3 5428 6743 4199
-3 4199 6743 6742
-3 6716 6744 5428
-3 6744 6743 5428
-3 6717 6744 6716
-3 5444 6746 6720
-3 6676 6747 4828
-3 6747 6676 6721
-3 6766 6749 6748
-3 5429 6766 6748
-3 5429 6748 6730
-3 6766 5429 6767
-3 6750 5429 6731
-3 6767 5429 6750
-3 5400 6751 6734
-3 5435 6752 6751
-3 5435 6751 5400
-3 6753 5420 6735
-3 6753 6754 5420
-3 5431 6755 6738
-3 6771 6756 6755
-3 5431 6771 6755
-3 6771 5431 6757
-3 6758 6774 5432
-3 5439 6758 5432
-3 6782 6739 6759
-3 6740 6658 6760
-3 6741 6761 4845
-3 6763 6746 5444
-3 4828 6765 6764
-3 4828 6747 6765
-3 5435 6768 6752
-3 6768 5435 6769
-3 5420 6754 5438
-3 6754 6770 5438
-3 6772 6771 6757
-3 5432 6772 6757
-3 6773 6772 5432
-3 6774 6773 5432
-3 5439 6775 6758
-3 6775 5439 6776
-3 5443 6777 6778
-3 5443 6779 6777
-3 6780 6779 5440
-3 6759 6781 6782
-3 6783 6760 4422
-3 4422 6760 6658
-3 6761 6784 4845
-3 5444 6785 6786
-3 6762 5444 6786
-3 6763 5444 6762
-3 5434 4828 6787
-3 6788 4828 6764
-3 6787 4828 6788
-3 6789 6791 5446
-3 6790 6791 6789
-3 5446 6792 5441
-3 6791 6792 5446
-3 6792 6793 5441
-3 4206 5441 6794
-3 5441 6793 6794
-3 4206 6794 6795
-3 6796 4206 6795
-3 5435 6797 6769
-3 5436 6797 5435
-3 6798 5436 6799
-3 6799 5436 5438
-3 6799 5438 6770
-3 6800 6776 5439
-3 6801 5443 6802
-3 6802 5443 6778
-3 5440 6803 6780
-3 5440 6804 6803
-3 6804 5440 6782
-3 4422 6805 6783
-3 6784 6806 4845
-3 6807 6808 6809
-3 6809 6810 6807
-3 5444 6811 6785
-3 6787 6827 5434
-3 6812 6787 6788
-3 6812 6813 6787
-3 6813 6827 6787
-3 6812 6814 6813
-3 5446 6815 6789
-3 6816 4206 6796
-3 5436 6817 6797
-3 6798 6817 5436
-3 5439 6818 6800
-3 6819 6818 5447
-3 5443 6801 5447
-3 5447 6801 6820
-3 6805 4422 6821
-3 6822 4845 6806
-3 6807 6823 6808
-3 6810 6823 6807
-3 5456 6824 6825
-3 6811 5444 5456
-3 6825 6811 5456
-3 6826 6846 6827
-3 6846 5434 6827
-3 6828 6827 6813
-3 6814 6828 6813
-3 6815 5451 6829
-3 6816 6830 4206
-3 5447 6831 6819
-3 6831 5447 6820
-3 5454 5453 6832
-3 6821 4422 6833
-3 6822 6834 4845
-3 6858 6835 6836
-3 6836 6837 6858
-3 6882 6838 6839
-3 6882 6839 6840
-3 6840 6841 5455
-3 5456 6842 6843
-3 5456 6843 6844
-3 6844 6824 5456
-3 5434 6846 6845
-3 5451 6847 6829
-3 6848 6847 5451
-3 6849 4846 6830
-3 6850 4846 6849
-3 5459 6832 6851
-3 5459 5454 6832
-3 6851 6832 6852
-3 5453 5458 6832
-3 6852 6832 5458
-3 5460 5459 6853
-3 5459 6851 6853
-3 5460 6853 6854
-3 6854 6855 5460
-3 6833 4422 6856
-3 6834 6857 4845
-3 6859 6835 6858
-3 6860 6858 6837
-3 6860 6861 6858
-3 6882 6862 6863
-3 6863 6838 6882
-3 6864 5455 6841
-3 6864 6865 5455
-3 5456 6866 6842
-3 5434 6868 6867
-3 5434 6845 6868
-3 5451 6869 6848
-3 6870 4846 6871
-3 6871 4846 6850
-3 6870 5462 4846
-3 6872 6852 5458
-3 5458 5471 6872
-3 5460 6855 5464
-3 6855 6873 5464
-3 5467 5466 6874
-3 5467 6874 5465
-3 6875 6856 4422
-3 6857 6876 4845
-3 6878 6879 5475
-3 6879 6880 5475
-3 6880 6859 5475
-3 6858 5475 6859
-3 6858 5476 5475
-3 6858 5469 5476
-3 5469 6858 6927
-3 6927 6858 6861
-3 6927 6861 6881
-3 6882 6883 6884
-3 6862 6882 6884
-3 6885 5455 6865
-3 6866 5456 6886
-3 5434 6887 4850
-3 5434 6888 6887
-3 6867 6888 5434
-3 6889 6890 5478
-3 5470 6891 6892
-3 5470 6890 6891
-3 5451 6893 6869
-3 6893 5451 5479
-3 6894 6893 5479
-3 6895 6870 6871
-3 6896 6895 6871
-3 6897 6870 6895
-3 5462 6870 6897
-3 5462 6898 4859
-3 5462 6897 6898
-3 5471 6900 6899
-3 5471 6899 6872
-3 5464 6901 5471
-3 6873 6901 5464
-3 5466 5465 6874
-3 4422 6902 6875
-3 6876 6903 4845
-3 5473 5472 6904
-3 5473 6904 5474
-3 5475 6877 6878
-3 5475 5474 6877
-3 5474 6905 6877
-3 5469 6927 5477
-3 6906 6927 6881
-3 6906 6907 6927
-3 6882 6908 6909
-3 6883 6882 6909
-3 4864 6910 6911
-3 6885 6910 4864
-3 6885 4864 5455
-3 5456 6912 6913
-3 6913 6886 5456
-3 6887 6914 4850
-3 6889 5478 6915
-3 6892 6949 5470
-3 6892 6916 6949
-3 5479 6917 6894
-3 6918 5479 6919
-3 6896 5479 6895
-3 6896 6919 5479
-3 5479 6920 6895
-3 6920 6897 6895
-3 5480 6898 6920
-3 6898 6897 6920
-3 4859 6898 5480
-3 5471 6921 6900
-3 6922 6921 5471
-3 6901 6922 5471
-3 6902 4422 6923
-3 6903 6924 4845
-3 5474 6925 6905
-3 5475 6925 5474
-3 6926 6925 5475
-3 5476 5477 6927
-3 6928 6927 6907
-3 6928 6929 6927
-3 6928 6930 6929
-3 4874 6931 6932
-3 6932 6933 4874
-3 6934 6935 6936
-3 6936 6937 6938
-3 6935 6937 6936
-3 6937 6939 6938
-3 6882 6940 6908
-3 6941 6940 6882
-3 6942 6941 6882
-3 6882 6943 6942
-3 4864 6944 6882
-3 6882 6944 6943
-3 6911 6944 4864
-3 6980 6945 6946
-3 6980 6946 6912
-3 6980 6912 5456
-3 6914 6947 4850
-3 6948 6915 5478
-3 5479 6950 6917
-3 6951 6950 5479
-3 6918 6951 5479
-3 6952 6953 6954
-3 6954 6955 6952
-3 4422 6956 6957
-3 4422 6957 6923
-3 6924 6958 4845
-3 6926 6959 6925
-3 6960 6959 6926
-3 5476 6960 6926
-3 6961 6960 5476
-3 6927 6961 5476
-3 6962 6961 6927
-3 6963 6962 6927
-3 6964 6963 6927
-3 6929 6964 6927
-3 6965 6964 6929
-3 6965 6966 6967
-3 6965 6929 6966
-3 6968 6966 6930
-3 6930 6966 6929
-3 6968 6969 6966
-3 6970 6971 6972
-3 6970 6973 6974
-3 6972 6973 6970
-3 6973 6975 6974
-3 5485 6976 6977
-3 6931 4874 6977
-3 6977 4874 5485
-3 6936 6933 6934
-3 6938 6978 6936
-3 6979 6938 6939
-3 6978 6938 6979
-3 4850 6947 6981
-3 5478 6982 6948
-3 6983 6982 5478
-3 6985 6986 6987
-3 6986 6988 6987
-3 6952 6989 6953
-3 6955 6989 6952
-3 4422 6990 6956
-3 6991 4845 6958
-3 6966 6992 6967
-3 6969 6992 6966
-3 6993 6971 6970
-3 6994 6971 6993
-3 6974 6995 6970
-3 6995 6993 6970
-3 6996 6974 6975
-3 6995 6974 6996
-3 5485 6997 6998
-3 5485 6998 6976
-3 6936 5496 6933
-3 5496 6936 6978
-3 6999 6978 6979
-3 5496 6978 6999
-3 7001 4850 6981
-3 7028 4850 7001
-3 7002 7003 7004
-3 7002 7005 7006
-3 7004 7005 7002
-3 7005 7007 7006
-3 7008 7009 5488
-3 6984 5488 7009
-3 6985 5488 6984
-3 6987 5488 6985
-3 5488 7010 7011
-3 5488 6988 7010
-3 5488 6987 6988
-3 6990 4422 7012
-3 6991 7013 4845
-3 5494 7014 7015
-3 7015 7016 5494
-3 7016 7017 5494
-3 7018 7017 7019
-3 7020 6993 7021
-3 7020 7018 6993
-3 6994 6993 7019
-3 7019 6993 7018
-3 6995 7021 6993
-3 7022 7021 6995
-3 6996 7022 6995
-3 7024 7025 5485
-3 7025 6997 5485
-3 7026 5496 6999
-3 7000 4877 7027
-3 7028 7029 4850
-3 7002 7030 7003
-3 7030 7002 7031
-3 7002 7006 7031
-3 7007 7032 7006
-3 7032 7031 7006
-3 5486 7032 7008
-3 7008 7032 7007
-3 5488 5486 7008
-3 5488 7011 5501
-3 5501 7011 7033
-3 7034 7035 7036
-3 7036 7037 7034
-3 7037 7038 7034
-3 7040 7012 4422
-3 7013 7041 4845
-3 5493 7042 7043
-3 5492 7042 5493
-3 7014 5494 7043
-3 7043 5494 5493
-3 5494 7017 5495
-3 5495 7017 7018
-3 7044 7018 7020
-3 5495 7018 7044
-3 5485 7045 7046
-3 7046 7047 5485
-3 7023 5485 7047
-3 7024 5485 7023
-3 7048 5496 7026
-3 4877 7049 7050
-3 7050 7027 4877
-3 4850 7029 7051
-3 7052 7031 5497
-3 7031 7032 5497
-3 7053 5501 7033
-3 7054 7056 7081
-3 7055 7056 7054
-3 7081 7057 5512
-3 7056 7057 7081
-3 7057 7058 5512
-3 7058 7059 5512
-3 7059 7060 5512
-3 7060 7061 5512
-3 5515 7062 7063
-3 5515 7063 7064
-3 5515 7064 7065
-3 5515 7065 7035
-3 7035 7034 5515
-3 7034 7038 7066
-3 7034 7066 5489
-3 7067 7066 7068
-3 7067 5489 7066
-3 5489 7067 5502
-3 7040 4422 7039
-3 4422 7069 7039
-3 7070 4845 7041
-3 7071 7072 5504
-3 7072 5492 5504
-3 7072 7042 5492
-3 5495 7073 5519
-3 7073 5495 7044
-3 5485 7074 7075
-3 7045 5485 7075
-3 5496 7048 4962
-3 4962 7048 7076
-3 7049 4877 7077
-3 7051 7078 4850
-3 7052 5497 7079
-3 7080 5501 7053
-3 7082 7054 7081
-3 5512 5510 7081
-3 5512 7061 7083
-3 5512 7083 5514
-3 5514 7083 7084
-3 5514 7084 7085
-3 5514 7114 5515
-3 7086 7114 5514
-3 7087 7088 5515
-3 7088 7062 5515
-3 7067 7068 7089
-3 7067 7089 5531
-3 7070 7093 4845
-3 5519 7094 7071
-3 5519 7071 5504
-3 7094 5519 7095
-3 5519 7096 7123
-3 5519 7097 7096
-3 5519 7073 7097
-3 7098 7100 5527
-3 7099 7100 7098
-3 5527 7100 5485
-3 7100 7074 5485
-3 4962 7101 7102
-3 7101 4962 7076
-3 7077 4877 7103
-3 7078 7104 4850
-3 5497 5535 7079
-3 7079 5535 7105
-3 7080 7106 5501
-3 5522 7107 7108
-3 4292 7107 5522
-3 5522 7108 7109
-3 5522 7109 7110
-3 7111 5522 7110
-3 5523 7082 7081
-3 7112 7082 5523
-3 7081 5510 5523
-3 5514 7085 7113
-3 7086 5514 7113
-3 7115 5515 7114
-3 7087 5515 7115
-3 7116 5531 7117
-3 7090 5531 7089
-3 7090 7117 5531
-3 4422 7091 7092
-3 4422 7118 7091
-3 7069 4422 7092
-3 7119 4845 7093
-3 7119 7120 4845
-3 7095 5519 7121
-3 5519 7122 7121
-3 7123 7122 5519
-3 7145 7124 5527
-3 7098 5527 7124
-3 7102 7125 4962
-3 4963 7129 7130
-3 7103 4877 4963
-3 7130 7103 4963
-3 4850 7131 7154
-3 4850 7104 7131
-3 7132 7105 5535
-3 5501 7106 5558
-3 7106 7133 5558
-3 7107 4292 7134
-3 5522 7111 7135
-3 5549 7135 7136
-3 5549 5522 7135
-3 5523 7137 7112
-3 7162 7138 7137
-3 5523 7162 7137
-3 5523 5536 7162
-3 7139 7171 5538
-3 7139 5538 7140
-3 7140 5538 5531
-3 5531 7141 7140
-3 7142 7141 5531
-3 7116 7142 5531
-3 7118 4422 7143
-3 7120 7144 4845
-3 7180 7145 5527
-3 7146 7124 7145
-3 4962 7147 7148
-3 7147 4962 7125
-3 7192 7149 7150
-3 7126 7192 7150
-3 7127 7192 7126
-3 7127 5533 7192
-3 5533 7151 5534
-3 5533 7128 7151
-3 5533 7127 7128
-3 7151 7152 5534
-3 7129 4963 7153
-3 7154 7155 4850
-3 5535 7156 7132
-3 7156 5535 7157
-3 7133 7158 5558
-3 7159 7134 4292
-3 5549 7136 7160
-3 5549 7160 7161
-3 5536 7163 7162
-3 7164 7163 5536
-3 7164 5536 4914
-3 7167 7169 7168
-3 7169 5538 7170
-3 7171 7170 5538
-3 5539 7172 7173
-3 7173 7174 5539
-3 5540 5539 7175
-3 5539 7174 7175
-3 7176 5540 7175
-3 4422 7177 7143
-3 7144 7178 4845
-3 5543 7179 7180
-3 7145 7180 7181
-3 7182 7146 7145
-3 7182 7145 7183
-3 7183 7145 7181
-3 7182 7183 7184
-3 7186 5555 4939
-3 7186 4939 7187
-3 7188 7187 4939
-3 7148 7189 4962
-3 7192 7190 7191
-3 7149 7192 7191
-3 5534 7193 5546
-3 5534 7152 7193
-3 5546 7193 5547
-3 7153 4963 7194
-3 4850 7195 7237
-3 4850 7155 7195
-3 5535 7196 7157
-3 7197 7196 5535
-3 7198 5558 7158
-3 7200 7159 4292
-3 7200 4292 7201
-3 5549 7202 7203
-3 5549 7161 7202
-3 7204 7205 5549
-3 7206 5549 7205
-3 7208 7207 7164
-3 4914 7208 7164
-3 7209 7208 4914
-3 4914 5559 7209
-3 5559 7210 7209
-3 7211 7165 7166
-3 7212 7211 7166
-3 7167 7165 7211
-3 7169 7167 7211
-3 7213 7214 7215
-3 7172 7213 7215
-3 7172 5539 7213
-3 5539 7216 7213
-3 5539 5551 7217
-3 5539 7217 7216
-3 7218 7217 5551
-3 7218 5551 5540
-3 7218 5540 7176
-3 7177 4422 7219
-3 7178 7220 4845
-3 7179 5542 7221
-3 5543 5542 7179
-3 7180 7179 7222
-3 7222 7179 7221
-3 7181 7180 7223
-3 7223 7180 7222
-3 5552 7181 7223
-3 7183 7181 5552
-3 5563 7183 5552
-3 7184 7183 5563
-3 5563 7224 7185
-3 5563 7185 7184
-3 5563 7226 7225
-3 7224 5563 7225
-3 5555 7227 7228
-3 7186 7227 5555
-3 7229 7188 4941
-3 7188 4939 4941
-3 7229 4941 7230
-3 7189 7231 4962
-3 7192 7232 7190
-3 7233 7232 7192
-3 7192 5545 7233
-3 5545 7234 7233
-3 5556 7235 5545
-3 5545 7235 7234
-3 7193 7235 5556
-3 5547 7193 5556
-3 7194 4963 7236
-3 7239 7197 4945
-3 7239 4945 7240
-3 7241 7198 7199
-3 7242 7241 7199
-3 7198 7241 5558
-3 4292 7243 7201
-3 5549 7203 7244
-3 7204 5549 7244
-3 5549 7206 7245
-3 7246 5549 7245
-3 5559 7247 7210
-3 5560 7248 7249
-3 5560 7249 5559
-3 5559 7249 7247
-3 7212 7249 7248
-3 7211 7212 7248
-3 7250 7251 7252
-3 7214 7250 7252
-3 7214 7213 7250
-3 7213 7253 7250
-3 7254 7253 7216
-3 7253 7213 7216
-3 7217 7254 7216
-3 7255 7254 7217
-3 7218 7255 7217
-3 4422 7256 7219
-3 7220 7257 5643
-3 5542 5562 7258
-3 5542 7258 7221
-3 7258 7259 7221
-3 7223 7259 5569
-3 7223 7222 7259
-3 7222 7221 7259
-3 7260 7226 4960
-3 4960 7226 5563
-3 7260 4960 7261
-3 7228 4960 5555
-3 7261 4960 7228
-3 4941 5570 7262
-3 7262 7230 4941
-3 7231 7263 4962
-3 7236 4963 7264
-3 7237 7238 4373
-3 7238 7265 4373
-3 7266 7240 4945
-3 7241 7242 7267
-3 7267 5558 7241
-3 7267 7268 5558
-3 4292 5576 7243
-3 7243 5576 7269
-3 4346 7270 7271
-3 4346 7246 7270
-3 4346 5549 7246
-3 7250 7272 7251
-3 7253 7272 7250
-3 7273 7272 7253
-3 7254 7273 7253
-3 7256 4422 7274
-3 5643 7257 7275
-3 7276 5643 7275
-3 7258 7277 7278
-3 7258 5562 7277
-3 5562 5568 7277
-3 5569 7258 7279
-3 5569 7259 7258
-3 7258 7278 7279
-3 5570 4961 7280
-3 5570 7280 7281
-3 5570 7281 7262
-3 4962 7263 7282
-3 7283 4962 7282
-3 7264 4963 7284
-3 4373 7285 7286
-3 7285 4373 7265
-3 7287 7266 4945
-3 7316 7287 4945
-3 7268 7288 5558
-3 7289 7269 5576
-3 4346 7271 7290
-3 7290 5566 4346
-3 7290 7291 5566
-3 7291 5571 5566
-3 4422 7292 7274
-3 7276 7293 5643
-3 7295 7297 7298
-3 7296 7297 7295
-3 7297 7299 7298
-3 5568 7300 7301
-3 5587 7300 5568
-3 7301 7277 5568
-3 5569 7279 7302
-3 4961 7303 7304
-3 7280 4961 7304
-3 4962 7283 7305
-3 7306 4962 7305
-3 7284 4963 7307
-3 7286 7308 4373
-3 7309 7310 7311
-3 7309 7312 7313
-3 7311 7312 7309
-3 7312 7314 7313
-3 7316 4945 7315
-3 5580 5558 7317
-3 7317 5558 7288
-3 5576 7319 7318
-3 5576 7318 7289
-3 7320 5581 7322
-3 7322 5581 7323
-3 7361 5571 7324
-3 5571 7291 7324
-3 7325 7326 7327
-3 7327 7328 7325
-3 7330 7331 7332
-3 7331 7333 7332
-3 4422 7334 7335
-3 7335 7292 4422
-3 7293 7336 5643
-3 5585 7337 7338
-3 7294 5585 7338
-3 7294 7295 5585
-3 7295 7339 5585
-3 7340 7298 7341
-3 7340 7339 7298
-3 7339 7295 7298
-3 7299 7341 7298
-3 5587 7342 7300
-3 7302 7343 7377
-3 4961 7344 7303
-3 7345 4962 7346
-3 7346 4962 7306
-3 7307 4963 7347
-3 7308 7348 4373
-3 7309 7349 7310
-3 7313 7349 7309
-3 7350 7349 7313
-3 7314 7350 7313
-3 7464 7351 7352
-3 7315 4945 7464
-3 7352 7315 7464
-3 5580 7317 7353
-3 5576 7355 7319
-3 5576 7356 7355
-3 5576 7357 7356
-3 7321 5581 7320
-3 7321 7357 5581
-3 7357 5576 5581
-3 5581 7358 7323
-3 5581 7359 7358
-3 7361 7360 5581
-3 7362 7326 7325
-3 7363 7326 7362
-3 7364 7325 7328
-3 7364 7365 7325
-3 7365 7362 7325
-3 7364 7366 7365
-3 7367 7329 7330
-3 7368 7329 7367
-3 7369 7367 7332
-3 7367 7330 7332
-3 7333 7369 7332
-3 7334 4422 7370
-3 7371 5643 7336
-3 5585 5584 7337
-3 5584 7372 7337
-3 5583 5585 7373
-3 7373 5585 7339
-3 7374 7339 7375
-3 7374 7373 7339
-3 7340 7375 7339
-3 7342 5587 7376
-3 7377 7378 7302
-3 7302 7378 5588
-3 7379 7380 4977
-3 7380 7344 4977
-3 5589 7381 7382
-3 5589 7383 7381
-3 5589 7384 7385
-3 5589 7385 7383
-3 7346 7385 7384
-3 7346 7384 7345
-3 7345 7384 7386
-3 7345 7386 5596
-3 7347 4963 7387
-3 7348 7388 4373
-3 7464 7389 7390
-3 7390 7351 7464
-3 5590 7353 7354
-3 5590 7354 7391
-3 5580 7353 5590
-3 5581 7392 7359
-3 7360 7392 5581
-3 7362 7393 7363
-3 7393 5593 7394
-3 7393 7362 5593
-3 7362 7365 5593
-3 5593 7365 7366
-3 5593 7366 7395
-3 5593 7396 5607
-3 5593 7395 7396
-3 7396 7397 5607
-3 7367 7398 7368
-3 7369 7398 7367
-3 4422 7399 7400
-3 7400 7370 4422
-3 7371 7401 5643
-3 5584 7402 7372
-3 7372 7402 7403
-3 5600 5583 7402
-3 7403 7402 5583
-3 7373 7404 5583
-3 7404 7403 5583
-3 7374 7404 7373
-3 5602 7405 7406
-3 5602 7406 7376
-3 5602 7376 5587
-3 5588 7407 7408
-3 5594 5588 7408
-3 7407 5588 7378
-3 4977 7409 7379
-3 7410 7411 7412
-3 7410 5589 7411
-3 7411 5589 7413
-3 5589 7414 7413
-3 5589 7415 7414
-3 7416 5589 7417
-3 7417 5589 7382
-3 5596 7384 5589
-3 7386 7384 5596
-3 7387 4963 7418
-3 7388 7419 4373
-3 7389 7464 7420
-3 5590 7421 7422
-3 7421 5590 7391
-3 5593 7423 7394
-3 5607 7424 7447
-3 5607 7397 7424
-3 7424 7425 7447
-3 7425 7426 7428
-3 7426 7427 7428
-3 7427 7429 7428
-3 7399 4422 7430
-3 7431 5643 7401
-3 5602 7433 7405
-3 5594 7408 7434
-3 7409 7435 7436
-3 7409 4977 7435
-3 4977 5611 7435
-3 7410 7437 7438
-3 7412 7437 7410
-3 5589 7439 7415
-3 7416 7439 5589
-3 4963 7461 7440
-3 4963 7440 7418
-3 7441 4373 7419
-3 7464 7442 7443
-3 7464 7443 7420
-3 5590 7422 7486
-3 7422 7444 7486
-3 5593 7445 7423
-3 7446 7445 5593
-3 5608 7447 7425
-3 5608 7425 7428
-3 7448 7428 7449
-3 7448 5608 7428
-3 7429 7449 7428
-3 4422 7450 7430
-3 5643 7431 7451
-3 7452 5643 7451
-3 7453 7432 7433
-3 7454 7432 7453
-3 5602 5609 7453
-3 7433 5602 7453
-3 5594 7455 5610
-3 7455 5594 7434
-3 5611 7456 7457
-3 7457 7435 5611
-3 7410 7458 7459
-3 7438 7458 7410
-3 7461 4963 7460
-3 7462 4373 7441
-3 7462 7463 4373
-3 7465 7442 7464
-3 7466 7486 7444
-3 5593 5615 7446
-3 7446 5615 7467
-3 7447 7493 5617
-3 7447 5608 7468
-3 7447 7468 7493
-3 7468 5608 7469
-3 7469 5608 7448
-3 7450 4422 7470
-3 7452 7471 5643
-3 7472 7454 7453
-3 7473 7454 7472
-3 5609 7474 7453
-3 7453 7474 7472
-3 5609 7475 7474
-3 5610 7475 5609
-3 5610 7476 7475
-3 5610 7455 7476
-3 7477 7478 5611
-3 5611 7478 7456
-3 7410 7459 7480
-3 7410 7480 5623
-3 4963 7507 7481
-3 4963 7481 7460
-3 7463 7482 4373
-3 7464 7483 7465
-3 7464 7484 7483
-3 4415 7485 7464
-3 7464 7485 7484
-3 7487 7486 7466
-3 7487 7488 7486
-3 7487 7489 7488
-3 5615 7490 7467
-3 5617 7491 7492
-3 7493 7491 5617
-3 7494 7493 7468
-3 7469 7494 7468
-3 7495 7494 7469
-3 4422 7496 7497
-3 7497 7470 4422
-3 5643 7471 7498
-3 7499 5643 7498
-3 7472 7500 7473
-3 7474 7500 7472
-3 7501 7500 7474
-3 7475 7501 7474
-3 5619 7502 7477
-3 7502 7503 7477
-3 7504 7478 7477
-3 7504 7477 7505
-3 7505 7477 7503
-3 7479 7504 7505
-3 7479 7505 5623
-3 7480 7479 5623
-3 7507 4963 7506
-3 4963 5677 7506
-3 7508 4373 7482
-3 4415 7509 7485
-3 4415 7510 7509
-3 4415 7486 7522
-3 7511 7522 7488
-3 7522 7486 7488
-3 7489 7511 7488
-3 5615 7512 7490
-3 5616 7512 5615
-3 7492 5616 5617
-3 7512 5616 7492
-3 7496 4422 7513
-3 5643 7499 7514
-3 7515 5643 7514
-3 7503 7502 5619
-3 5623 7505 7503
-3 7506 5677 7516
-3 4373 7508 7517
-3 7517 7518 4373
-3 7519 7510 4415
-3 7520 7510 7519
-3 7521 7519 7522
-3 7519 4415 7522
-3 4422 7523 7513
-3 5088 7523 4422
-3 7524 5643 7515
-3 5677 7525 7516
-3 7526 4373 7518
-3 7527 7520 7519
-3 7528 7519 7521
-3 7528 7529 7519
-3 7530 7540 5624
-3 5088 7531 7532
-3 7532 7523 5088
-3 7524 7533 5643
-3 5677 7534 7535
-3 5677 7535 7525
-3 4373 7526 7536
-3 7536 7537 4373
-3 5629 7527 7519
-3 5629 5041 7527
-3 5041 7538 7527
-3 5629 7519 7529
-3 5629 7529 7539
-3 5634 7540 7530
-3 7542 5631 5630
-3 7542 7543 5631
-3 7544 5631 7543
-3 5088 7545 7546
-3 7546 7531 5088
-3 5643 7533 7547
-3 7548 5643 7547
-3 5677 7549 7550
-3 7534 5677 7550
-3 7551 4373 7537
-3 5041 5632 7538
-3 7538 5632 7552
-3 5633 7553 7567
-3 5629 7553 5633
-3 5629 7539 7553
-3 7553 7554 7567
-3 5037 7540 5634
-3 5043 7555 7556
-3 7541 7542 5630
-3 7541 5630 7556
-3 7557 5631 7544
-3 5088 7558 7559
-3 7559 7545 5088
-3 5643 7548 7560
-3 7561 5643 7560
-3 5677 7562 7549
-3 4373 7551 7563
-3 7563 7564 4373
-3 5632 7565 7552
-3 7566 7565 5639
-3 5633 7567 5639
-3 5043 5638 7555
-3 7555 5638 7568
-3 5641 7569 7570
-3 5641 7557 7569
-3 5641 5631 7557
-3 5088 7571 7572
-3 7572 7558 5088
-3 5643 7561 7573
-3 7574 5643 7573
-3 5677 7575 7576
-3 5677 7576 7562
-3 7577 4373 7564
-3 5639 7578 7566
-3 7567 7579 5639
-3 7579 7578 5639
-3 7580 5638 7581
-3 7580 7568 5638
-3 5641 7582 7583
-3 5641 7570 7582
-3 5088 7584 7585
-3 7585 7571 5088
-3 5643 7574 7586
-3 7587 5643 7586
-3 5677 7588 7589
-3 7575 5677 7589
-3 4373 7577 7590
-3 7591 7592 7593
-3 7593 7594 7591
-3 5638 5645 7581
-3 7581 5645 7595
-3 5641 7583 7596
-3 7596 7597 5641
-3 5088 7598 7599
-3 7599 7584 5088
-3 5643 7587 7600
-3 7601 5643 7600
-3 5677 7602 7588
-3 4373 7590 7603
-3 7604 7592 7591
-3 7605 7591 7594
-3 7605 7606 7591
-3 7606 7604 7591
-3 7605 7607 7606
-3 7595 5645 7609
-3 7597 7610 5641
-3 5088 7611 7612
-3 7610 7611 5088
-3 7612 7598 5088
-3 5643 7601 7613
-3 7614 5643 7613
-3 5677 7615 7602
-3 4373 7603 7616
-3 7618 7604 7617
-3 7606 7619 7604
-3 7619 7617 7604
-3 7607 7620 7606
-3 7620 7619 7606
-3 7621 7607 7608
-3 7621 7620 7607
-3 7623 7624 5645
-3 7624 7609 5645
-3 5643 7614 7625
-3 5643 7625 7626
-3 5677 7627 7615
-3 7616 7628 7629
-3 7630 7631 7632
-3 7630 7633 7634
-3 7632 7633 7630
-3 7633 7635 7634
-3 5083 5652 7636
-3 5646 5083 7636
-3 5646 7636 7637
-3 7638 5646 7637
-3 7617 7639 7618
-3 7639 7640 7641
-3 7639 7617 7640
-3 7617 7619 7640
-3 7620 7640 7619
-3 7621 5650 7620
-3 5650 7622 7642
-3 5650 7621 7622
-3 7642 7643 5650
-3 5651 5092 7644
-3 7644 7645 5651
-3 5651 7645 7646
-3 5645 5651 7647
-3 5651 7646 7647
-3 7648 5645 7647
-3 7623 5645 7648
-3 5643 7626 7649
-3 5643 7649 7650
-3 7651 5643 7650
-3 5677 7652 7627
-3 7616 7629 7653
-3 7616 7653 7654
-3 7630 7655 7631
-3 7655 7656 7657
-3 7655 7630 7656
-3 7630 7634 7656
-3 7658 7634 7635
-3 7658 7659 7634
-3 7659 7656 7634
-3 7658 7660 7659
-3 7636 5652 7661
-3 5646 7638 7662
-3 5653 5646 7663
-3 5646 7662 7663
-3 7666 5653 7664
-3 5653 7663 7664
-3 7666 7664 7665
-3 7668 7641 7640
-3 7640 5655 7668
-3 5650 7669 5105
-3 5650 7643 7669
-3 7669 7670 5105
-3 5092 7671 7644
-3 5643 7651 7672
-3 7673 5643 7672
-3 5664 7674 7675
-3 5664 7676 7677
-3 7675 7676 5664
-3 7678 7679 7680
-3 5665 7680 7681
-3 5677 7682 7652
-3 4509 7683 7684
-3 4509 7654 7683
-3 4509 7616 7654
-3 7656 7685 7657
-3 7685 7686 7687
-3 7685 7656 7686
-3 7656 7659 7686
-3 5658 7659 7688
-3 5658 7686 7659
-3 7660 7688 7659
-3 7689 5658 7688
-3 5652 5658 7712
-3 5652 7712 7690
-3 5652 7690 7661
-3 5666 7666 7667
-3 5666 7667 7691
-3 7691 7692 5666
-3 5660 7693 7694
-3 7668 5660 7694
-3 5655 5660 7668
-3 5105 7670 7695
-3 5105 7695 5662
-3 5662 7696 7697
-3 5662 7695 7696
-3 7671 5118 7698
-3 5643 7673 7699
-3 7700 5643 7699
-3 5664 5663 7674
-3 5663 7701 7674
-3 7677 7702 5664
-3 5664 7702 5112
-3 7703 5112 7702
-3 5671 7704 7678
-3 7680 5671 7678
-3 5665 7681 7705
-3 7705 7706 5665
-3 5677 7707 7682
-3 4509 7684 7708
-3 7686 7709 7687
-3 5658 7689 7710
-3 5658 7710 7711
-3 7712 5658 7711
-3 5660 5666 7713
-3 5666 7692 7713
-3 7713 7693 5660
-3 5662 7697 7714
-3 7698 5118 7715
-3 5643 7700 7716
-3 5643 7716 7717
-3 7718 5643 7717
-3 5663 7719 7701
-3 5112 7719 5663
-3 7720 7719 5112
-3 5112 7703 7721
-3 5673 5112 7722
-3 5112 7721 7722
-3 5114 7724 7726
-3 7724 7725 7726
-3 7727 5667 7726
-3 5667 5114 7726
-3 7727 7728 5667
-3 7728 5669 5667
-3 7704 5671 5669
-3 7728 7704 5669
-3 7706 7729 5665
-3 5677 7730 7707
-3 4509 7708 7731
-3 4509 7731 7777
-3 7686 7761 7709
-3 7709 7761 7732
-3 5662 7714 7736
-3 7736 7737 5662
-3 7738 7739 5118
-3 7715 5118 7740
-3 7740 5118 7739
-3 5643 7718 7741
-3 5643 7741 7742
-3 7743 5643 7742
-3 5112 7744 7720
-3 5112 7746 7745
-3 5112 7745 7744
-3 5673 7723 7747
-3 5673 7722 7723
-3 7747 7748 5673
-3 7750 7751 5683
-3 7751 7752 5683
-3 7752 7753 5683
-3 7724 5683 7754
-3 5683 7753 7754
-3 5665 7755 7756
-3 7755 5665 7729
-3 5677 7757 7758
-3 7730 5677 7758
-3 7777 7731 7759
-3 7777 7759 7760
-3 7777 7778 7761
-3 5679 5691 7779
-3 5126 7762 7763
-3 5126 7764 7762
-3 7734 5126 7733
-3 7734 7764 5126
-3 7733 5126 5680
-3 7733 5680 7735
-3 7735 5680 7765
-3 5662 7737 7766
-3 5662 7766 5693
-3 7767 5693 7766
-3 5118 7768 7769
-3 7738 5118 7769
-3 5643 7743 7770
-3 5698 5643 7770
-3 7771 5698 7770
-3 5112 5135 7746
-3 5135 5694 7772
-3 5135 7772 7746
-3 5683 5673 7748
-3 7749 5683 7748
-3 7750 5683 7749
-3 5665 7756 5703
-3 7756 7773 5703
-3 5677 7774 7775
-3 5677 7775 7776
-3 7776 7757 5677
-3 7779 7780 5679
-3 5679 7780 5690
-3 5691 7781 7779
-3 5692 7783 7782
-3 5692 7782 5691
-3 5691 7782 7781
-3 7785 7784 5126
-3 7785 5126 7763
-3 7765 5680 7786
-3 5693 7767 7787
-3 5693 7787 7788
-3 5118 5693 7789
-3 7789 5693 7788
-3 7768 5118 7789
-3 5698 7771 7790
-3 5698 7790 7791
-3 7792 5698 7791
-3 7772 5694 5698
-3 5698 7793 7772
-3 5696 7794 7795
-3 5687 7796 5696
-3 5696 7796 7794
-3 7797 7796 5688
-3 5688 7796 5687
-3 5688 5703 7797
-3 7798 5703 7773
-3 5677 7800 7801
-3 7801 7774 5677
-3 7802 5690 7780
-3 7803 7783 5692
-3 7803 7804 7783
-3 7784 7806 5697
-3 7806 7805 5697
-3 7786 5680 7807
-3 5698 7792 7808
-3 7809 5698 7808
-3 7810 7793 5698
-3 7810 5698 7811
-3 7811 7812 7813
-3 7810 7811 7813
-3 7813 7812 7814
-3 5696 7795 5702
-3 7795 7815 5702
-3 5703 7816 7797
-3 5703 7817 7816
-3 7799 5703 7798
-3 7799 7817 5703
-3 7818 7819 5677
-3 7819 7800 5677
-3 5690 7802 7820
-3 7803 5690 7820
-3 7821 7803 7820
-3 7804 7803 7821
-3 7822 7804 7821
-3 7805 7823 5697
-3 7824 7825 5680
-3 7825 7807 5680
-3 5706 5707 7826
-3 5698 7809 7827
-3 5698 7827 7828
-3 7829 5698 7828
-3 7829 7830 5698
-3 7830 7831 5698
-3 7832 5698 7831
-3 7811 5698 7832
-3 7833 7811 7832
-3 7812 7811 7833
-3 7834 7812 7833
-3 7814 7812 7834
-3 5702 7815 7835
-3 5711 5702 7835
-3 7836 5711 7835
-3 5677 7837 7838
-3 7818 5677 7838
-3 7839 4521 7823
-3 4521 5697 7823
-3 5713 7825 7824
-3 5713 7840 7825
-3 7826 5714 5706
-3 5711 7836 7841
-3 5716 7841 7842
-3 5716 5711 7841
-3 5718 7843 5677
-3 7843 7844 5677
-3 7837 5677 7844
-3 4521 7839 7845
-3 4521 7845 7846
-3 4521 7846 7847
-3 4521 7847 7840
-3 5716 7842 7848
-3 5716 7848 7849
-3 7850 7851 5718
-3 7852 5718 7851
-3 7843 5718 7852
-3 5716 7849 7853
-3 5716 7853 5718
-3 5718 7853 7854
-3 7855 5718 7854
-3 5718 7855 7856
-3 5718 7856 7857
-3 5718 7857 7858
-3 5718 7858 7859
-3 7850 5718 7859
-
-CELL_DATA 13733
-POINT_DATA 7860
-NORMALS normals float
--0.133614 -0.057263 -0.989378 -0.0307275 -0.537162 -0.842919 -0.864861 -0.161839 -0.47521
--0.0591288 -0.790848 -0.60915 -0.72247 0.175378 -0.66879 0.236808 -0.629513 -0.740024
-0.197983 -0.368125 -0.908453 0.355323 -0.801092 -0.48166 0.285198 -0.791312 -0.540821
--0.618792 -0.400138 -0.676007 -0.398669 -0.360336 -0.843339 0 -0.0860472 -0.996291
-0.65077 -0.224068 -0.72546 -0.616992 0.576954 -0.535205 0.303636 -0.510558 -0.804448
-0.0991771 0.682572 -0.724058 0.372129 0.614105 -0.695985 -0.490425 0.764772 -0.41786
-0.0313472 0.583987 -0.811158 0.399766 -0.323516 -0.857627 0.216481 0.546615 -0.808918
-0.390625 0.179303 -0.902919 -0.088772 0.773204 -0.627914 -0.161114 0.301929 -0.939618
-0.336389 -0.421911 -0.841922 -0.529158 -0.497371 -0.687469 -0.448965 -0.270927 -0.851486
-0.456537 0.204655 -0.865847 -0.370621 0.853657 -0.365937 -0.188935 0.739997 -0.645529
-0.0329652 -0.212296 -0.976649 -0.149265 -0.468952 -0.870519 0.135512 0.597534 -0.79031
--0.431091 0.395359 -0.811081 -0.313014 -0.35348 -0.881518 0.208532 0.181332 -0.961058
-0.440965 0.440965 -0.781728 0.381019 0.634407 -0.672571 -0.260464 0.83826 -0.479039
-0 0.637398 -0.770535 0.253912 -0.463967 -0.848683 -0.745225 -0.1198 -0.655963
--0.819732 -0.123691 -0.559232 0.351087 -0.152592 -0.923826 0.299891 -0.766145 -0.568407
--0.0578228 -0.708329 -0.70351 -0.298115 -0.407947 -0.862964 0.626218 0.27526 -0.72944
--0.428964 0 -0.903322 -0.840707 0.309226 -0.444512 0.612134 -0.612134 -0.500582
-0.778143 0.124987 -0.615526 0.298546 0.138859 -0.94424 -0.483754 0.68549 -0.544138
-0.150583 0.282344 -0.947421 0.318835 -0.670203 -0.670203 -0.447214 0 -0.894427
--0.557993 -0.557993 -0.614238 -0.350425 -0.313294 -0.882638 0.678742 0.132751 -0.722279
-0.184754 -0.606401 -0.773398 -0.555685 -0.412346 -0.721932 -0.54253 -0.19323 -0.817511
--0.454534 -0.307546 -0.835951 0.309976 0.302415 -0.901366 0.791268 0.485184 -0.372145
--0.601158 0 -0.79913 -0.195297 0.328291 -0.924167 0.561633 0.64151 -0.522527
--0.430992 0.549168 -0.716003 0.450158 -0.054019 -0.891313 -0.0141727 -0.37479 -0.927001
--0.483179 0.180464 -0.856721 -0.327193 0.433721 -0.839542 0.334286 0.754839 -0.564332
-0.671316 0.671909 -0.312846 0.344796 0.158164 -0.925257 0.22389 0.743178 -0.630524
--0.553661 0.562312 -0.614218 -0.166154 -0.166154 -0.972001 -0.0172758 -0.302326 -0.953048
-0.591926 0.484469 -0.644137 -0.687459 0.261533 -0.677496 -0.505059 0.325209 -0.799471
-0.166733 0.45256 -0.876008 0.588363 0.588363 -0.55467 -0.406719 0.382316 -0.829707
-0.473568 -0.163299 -0.865486 0.720113 -0.256824 -0.644577 0.236649 -0.191878 -0.95246
-0.413754 0.227159 -0.881593 -0.417457 -0.790013 -0.449009 0.124878 -0.405854 -0.905366
--0.39225 -0.851721 -0.347435 -0.239402 -0.729666 -0.640527 -0.0931752 -0.0931752 -0.99128
-0.123225 0.432494 -0.893177 -0.249097 -0.886882 -0.389089 0.217978 -0.743821 -0.631836
-0.732431 0.259049 -0.629634 -0.737644 -0.569222 -0.363137 -0.669417 -0.68991 -0.275509
-0.821447 -0.111914 -0.559196 -0.924616 0.233679 -0.300798 -0.731344 -0.200835 -0.651768
--0.487093 0.295284 -0.821917 0.119911 -0.875437 -0.468222 -0.0338245 -0.717313 -0.69593
--0.0261782 0.279234 -0.959866 -0.0250979 0.633721 -0.773154 0.119187 0.815737 -0.566011
-0.879941 0.148971 -0.451122 0.201057 -0.61231 -0.764626 -0.220722 -0.715565 -0.662758
--0.919569 -0.0491032 -0.389849 -0.835811 -0.311849 -0.451853 0.523791 0.363162 -0.770555
-0.492487 -0.363645 -0.790708 -0.236316 -0.379469 -0.894516 0.285703 -0.82894 -0.480866
--0.603185 -0.603185 -0.521857 0.582435 0.465226 -0.666584 -0.634173 0.76534 -0.109907
--0.584343 -0.235207 -0.776673 -0.0678275 -0.131887 -0.988941 -0.269185 -0.72255 -0.636757
--0.634909 -0.317455 -0.704353 0.0535556 -0.444923 -0.893966 0.512611 -0.367788 -0.775862
-0.341278 -0.713496 -0.611925 -0.487268 -0.603938 -0.630736 -0.378509 -0.485634 -0.787966
-0.0320423 0.339926 -0.939906 -0.550019 0.821907 -0.148148 0.0585813 -0.422704 -0.904372
-0.382161 0.543608 -0.747291 0.500733 0.646371 -0.575734 0.0850264 0.786494 -0.611717
--0.159823 -0.820268 -0.549196 0.365676 -0.424613 -0.828242 0.0242708 -0.651266 -0.758462
--0.507728 0.237573 -0.828113 0.60161 -0.6034 -0.523425 -0.809091 0.35261 -0.470147
-0.216092 -0.520584 -0.826012 -0.357151 -0.0957722 -0.929124 -0.846672 0.235721 -0.477055
-0.660332 -0.623161 -0.419085 -0.68403 -0.523612 -0.507872 -0.923242 0.314121 -0.22125
--0.0158154 -0.661987 -0.749348 0.647451 -0.716615 -0.259365 -0.887292 0.0362983 -0.459778
--0.880705 0.414627 -0.229004 -0.880691 0.463666 -0.09694 0.854087 -0.349399 -0.385299
-0.591791 -0.197264 -0.781582 -0.69874 0.685205 -0.205562 -0.644528 0.34271 -0.683472
-0.519893 -0.777214 -0.354472 -0.588419 -0.588419 -0.55455 -0.814164 0.524526 -0.249018
-0.666706 -0.72418 -0.176256 -0.767549 0.610615 -0.194978 0.596127 -0.675259 -0.434347
--0.568865 0.667022 -0.481118 0.468899 -0.549215 -0.691735 -0.673848 -0.595175 -0.43783
--0.37961 -0.541691 -0.749978 0.649603 -0.356158 -0.67169 0.467638 -0.171231 -0.867176
-0.197129 0.824751 -0.530025 -0.315227 0.736623 -0.598347 -0.189691 -0.331959 -0.924024
--0.432596 -0.884943 -0.172444 -0.653129 0.0762328 -0.753399 -0.196901 -0.798542 -0.568824
-0.595899 0.595899 -0.538339 -0.0833766 -0.90672 -0.413409 0.244745 -0.840249 -0.483819
--0.0411872 0.720775 -0.691944 -0.346388 -0.148984 -0.926185 0.262214 -0.510627 -0.818843
--0.32034 -0.0488322 -0.946043 0.0269138 -0.558461 -0.829094 -0.231713 -0.311614 -0.921524
-0.415067 -0.105914 -0.903605 0.113699 0.437303 -0.892098 0.687616 -0.181196 -0.703102
--0.730426 -0.191407 -0.655623 -0.0673477 -0.43776 -0.896566 0.587931 -0.355209 -0.726749
-0.407993 0.710211 -0.573709 0.0627344 -0.643028 -0.763269 -0.716044 -0.492216 -0.494979
--0.625571 -0.657112 -0.420552 -0.125133 -0.871118 -0.474864 -0.513312 0.500792 -0.696935
-0.205739 -0.154691 -0.966303 0.139194 -0.63921 -0.756331 -0.183705 -0.7983 -0.573558
-0.129194 -0.79939 -0.586758 0.395605 -0.699374 -0.595292 0 -0.714057 -0.700088
-0.0821513 -0.670499 -0.737348 0 -0.947723 -0.319096 0 -0.424893 -0.905244
-0.232035 0.261205 -0.93698 -0.26748 0.823524 -0.500263 -0.505771 0.579733 -0.638831
--0.302437 0.55059 -0.778064 -0.0322538 0.628948 -0.776778 0.216548 0.804992 -0.552353
--0.0276135 0.796846 -0.603551 0.0606424 0.818673 -0.571049 0.42076 0.688839 -0.590307
-0.442564 0.636671 -0.631495 0.0703097 0.953021 -0.294631 -0.393632 0.883207 -0.254949
-0 0.842439 -0.538792 0.247275 0.851023 -0.463265 -0.53666 -0.712685 -0.451749
-0.330773 -0.301587 -0.894223 -0.311853 -0.648992 -0.693943 -0.0186271 -0.614693 -0.788546
-0.778019 0.198507 -0.596055 -0.721324 -0.65162 -0.234698 -0.244691 -0.700758 -0.670123
-0.722534 0.148377 -0.675225 -0.94044 -0.111906 -0.321012 -0.414019 -0.785113 -0.460636
-0.578245 -0.302339 -0.757776 0.804844 0.371467 -0.462859 -0.215747 -0.449986 -0.866583
-0.873669 0 -0.486522 -0.796789 -0.150159 -0.585304 0.577632 -0.654494 -0.48783
--0.919215 0.189644 -0.345078 -0.815376 0.574037 -0.0751172 0.94216 -0.314825 -0.114973
--0.526794 0.237428 -0.816159 0.367513 -0.929476 0.0317603 -0.438774 0.371842 -0.818053
-0.647808 -0.0398651 -0.76076 0.204368 -0.978894 -0.000987286 0.26964 -0.955995 -0.115618
-0.631516 -0.66722 -0.394976 -0.501994 0.643066 -0.578332 0.464369 0.337251 -0.818916
-0.953793 -0.124408 -0.2735 -0.151531 0.567922 -0.809013 0.764898 -0.642514 0.0458939
-0.2831 -0.886154 -0.366858 0.607346 -0.764806 0.214946 0.270611 -0.704715 -0.655855
-0.401862 -0.438789 -0.803723 -0.434244 -0.672652 -0.599143 0.726992 -0.275329 -0.629028
-0.592987 -0.393762 -0.702366 -0.474079 -0.574123 -0.667557 -0.503787 -0.440437 -0.743111
--0.457974 -0.673915 -0.57974 -0.588721 0.792639 -0.158528 0.0695623 -0.890398 -0.449836
-0.457902 -0.737537 -0.496352 0.970729 0.0507571 -0.234752 0.707754 -0.540756 -0.454606
--0.697492 -0.656992 -0.286122 -0.725648 -0.563773 -0.394455 0.985733 -0.147733 -0.0806586
--0.550024 -0.829022 -0.100971 0.512143 -0.857839 -0.0426786 0.322015 -0.946725 -0.00429354
--0.522973 -0.852252 0.0129129 -0.649531 -0.759452 0.0366402 0.14246 -0.939007 -0.313002
--0.280881 -0.853879 -0.438175 -0.0711379 -0.995931 0.0553295 -0.548838 0.804265 -0.227891
--0.74702 0 -0.664801 0.0171827 -0.326472 -0.945051 0.410419 -0.679111 -0.608575
--0.364289 0.167455 -0.916107 0.246603 -0.332377 -0.910336 0.451961 -0.335743 -0.826443
-0.144032 -0.882629 -0.44746 -0.38057 -0.225126 -0.896931 -0.575825 0.465475 -0.67213
-0.112 0.0263529 -0.993359 0.281641 -0.345346 -0.895217 -0.652357 -0.588712 -0.477334
--0.0965727 -0.915831 -0.389778 0.660328 -0.660328 -0.357678 -0.279956 0.36428 -0.888214
--0.100151 -0.0166918 -0.994832 -0.887081 -0.100325 -0.450581 0.76069 0.544434 -0.353471
--0.402301 0.504888 -0.763702 -0.349163 0.311494 -0.883774 0.441792 0.834495 -0.329298
--0.559507 -0.808386 -0.182932 -0.138395 -0.827316 -0.544421 -0.631133 -0.746974 -0.209046
--0.173925 -0.780433 -0.600562 0.767655 -0.0383828 -0.639713 -0.453607 -0.685278 -0.569767
-0.551526 -0.14722 -0.821063 0.826474 0.363649 -0.429767 0.8577 0.388891 -0.336325
-0.823711 0.279248 -0.493478 0.333318 -0.754251 -0.565689 0.0406417 -0.746792 -0.663815
-0.015947 -0.534225 -0.845192 -0.520495 0.0208198 -0.853611 0.661244 -0.495308 -0.563406
-0.913519 0.321215 -0.249607 -0.747552 0.00807074 -0.664154 0.461353 -0.53233 -0.709773
-0.292762 -0.56131 -0.774094 0.190724 -0.486347 -0.852696 -0.888497 0.430483 -0.158928
-0.994314 -0.0509905 0.0934825 0.986835 -0.131761 0.0937882 0.90288 -0.379832 0.201332
-0.619007 -0.75584 0.213394 0.869212 -0.160118 -0.467796 0.824087 -0.222516 -0.52093
-0.60237 0.798086 -0.0144975 -0.0559393 -0.964954 -0.256389 -0.379812 0.634713 -0.672965
-0.648721 -0.131186 -0.749634 0.977478 -0.153099 0.145248 -0.681476 -0.526052 -0.508782
-0.253505 -0.869394 -0.424134 -0.295363 0.210974 -0.9318 0.771082 -0.571005 0.281756
--0.520388 -0.81452 -0.256423 -0.932492 -0.332476 0.141129 -0.387589 0.66745 -0.635834
-0.72924 0.447094 -0.517992 0.490614 0.598931 -0.632913 0.554927 0.541393 -0.631625
--0.0398377 -0.632976 0.773146 0.833643 0.0106877 0.5522 0.277725 -0.55545 -0.783801
--0.428552 -0.68747 0.586284 0.232916 -0.842788 -0.485241 -0.207499 -0.735837 -0.644584
--0.128406 -0.342416 -0.930733 -0.160642 0.973546 -0.162488 -0.986898 0.0986898 0.127639
-0.451855 -0.636122 -0.62544 0.64379 0.539243 -0.542911 0.593303 0.25522 -0.763449
-0.234245 -0.669273 -0.705126 0.35794 0.188615 -0.914496 -0.643042 0.270755 -0.716372
-0.521396 -0.109909 -0.846207 0.91988 -0.041365 -0.390013 -0.946342 0.288601 -0.145419
-0.72821 0.682613 -0.0612429 -0.346952 -0.919119 -0.186664 0.0326775 -0.980326 -0.19466
-0.297089 -0.871314 -0.390576 0 -0.849343 -0.527841 0.0658001 -0.870586 -0.487596
-0.74046 0.64113 -0.20167 -0.540906 0.801701 -0.254355 0.833497 -0.00766434 -0.552471
-0.72087 -0.493227 -0.486903 -0.912475 -0.382435 0.14537 0.254155 -0.914959 -0.313458
--0.66355 -0.737278 0.126976 -0.327662 0.703275 -0.630905 -0.471757 -0.36856 -0.801005
-0.245787 -0.825896 -0.50743 -0.79949 0.588196 -0.121827 -0.554541 -0.831811 0.0239616
--0.0360758 0.742401 -0.668984 -0.522275 0.838219 0.156897 0.317629 -0.923394 0.215534
-0.290532 0.576195 -0.763931 -0.77193 0.604489 -0.196766 -0.130676 -0.659232 -0.740498
--0.459006 -0.442006 -0.770677 -0.374676 -0.769072 -0.517827 -0.376284 0.430038 -0.820657
-0.222776 -0.879965 -0.419562 -0.48734 0.46584 -0.738575 -0.249152 -0.738395 -0.626654
--0.706638 0.0936891 -0.701345 -0.382983 0.718093 -0.581091 0.0830439 -0.110725 -0.990376
-0.260005 -0.913991 -0.311476 0 0.999101 0.0423861 0.444728 -0.690636 -0.570298
-0.0428856 0.950631 -0.307347 0.815639 0.577103 0.0410385 0.942857 0.171429 0.285714
--0.728315 0.662105 0.176561 -0.722965 -0.690103 -0.032862 -0.910416 0.0343553 -0.412264
--0.128238 0.881635 -0.454175 -0.186605 0.92473 -0.331742 -0.486271 0.75559 -0.43889
--0.746592 0.409132 -0.524605 -0.67561 -0.275249 -0.683951 0.959044 0.280696 0.0380109
--0.551393 0.600772 -0.578826 0.682383 0.720548 -0.123144 -0.129602 -0.931015 -0.341196
-0.899206 0.0372805 -0.435934 -0.865383 -0.397797 -0.304745 0.355155 -0.856956 -0.373486
--0.121418 -0.689481 -0.714054 0.723358 -0.632815 -0.276221 -0.226561 -0.696637 -0.680711
-0.511263 -0.723072 -0.464519 -0.911951 -0.130058 -0.38914 0.937919 -0.290078 -0.190162
-0.760164 0.550687 -0.344809 0.766852 0.546222 -0.337015 0.934208 -0.3242 -0.148829
--0.982977 0.174299 -0.0580998 0.177826 -0.98367 -0.0277619 -0.728453 -0.67903 0.0909671
-0.778298 -0.598196 -0.190822 0.504274 0.784427 -0.361085 0.313858 -0.859187 -0.404092
-0.818402 -0.572881 -0.0450121 0.902922 0.409137 -0.131676 -0.0824148 0.970663 -0.225878
-0.26844 -0.96313 -0.017896 0.954296 0.149554 -0.258752 0.698362 -0.101079 -0.708572
--0.990127 -0.0735905 0.119306 -0.519702 0.814759 0.257057 -0.661742 0.672771 0.330871
--0.106395 -0.984152 0.14186 0.586209 0.768585 -0.256195 -0.0510752 -0.752508 -0.6566
-0.534006 -0.738057 -0.412444 -0.746554 0.590949 -0.305673 0.951414 0.0126434 0.307655
--0.405861 -0.900274 0.157425 0.402726 -0.836431 0.371747 -0.48941 -0.870062 0.0589104
-0.786062 -0.550243 -0.281672 0.894147 0.108601 0.434404 0.931719 -0.0291162 0.362012
--0.46618 -0.884546 -0.0159378 -0.294639 -0.837308 -0.460547 -0.0271759 0.570694 -0.820713
--0.646277 0.656016 -0.389832 0.838007 0.164315 0.520331 -0.451493 -0.799787 0.395594
--0.694515 -0.0292427 -0.718884 0.0571292 0.956915 -0.284694 0.463583 -0.86278 0.201745
--0.527545 -0.83658 0.147754 -0.53086 -0.812675 0.240307 0.703842 0.703842 0.0959785
-0.14104 0.967135 -0.211561 -0.0949207 -0.976327 -0.194361 0.902432 -0.258894 -0.344371
--0.166339 -0.970311 0.17558 -0.960289 0.0561572 -0.273299 0.431889 -0.431889 -0.791797
-0.629445 0.769322 0.109279 -0.972387 -0.233373 0 -0.707308 0.579529 -0.404799
-0.575168 -0.692435 -0.435564 -0.722346 0.685303 -0.0926085 0.403399 0.576284 0.71075
--0.838388 0.540438 0.0709405 0.618425 -0.531767 -0.578597 0.666068 -0.609667 -0.429721
--0.591621 0.591621 -0.547694 -0.571101 0.598297 -0.562036 -0.522678 0.709348 -0.472899
-0.248187 -0.849265 0.465997 0.749401 0.343811 -0.565856 0.327269 0.139263 -0.934613
-0.470209 -0.798609 -0.37567 -0.448116 0.426572 0.785639 -0.355483 -0.891999 0.27923
--0.816525 -0.199965 -0.541573 0.626849 -0.690813 -0.360331 0.932835 0.339604 0.120366
-0.750775 0.459982 -0.474081 -0.84453 0.341834 -0.412211 0.573251 -0.473762 -0.66853
-0.278974 -0.852913 -0.441264 0.0873541 -0.762893 -0.640597 -0.983169 0.172055 0.0614481
--0.602585 -0.71815 0.348069 -0.297116 0.847331 -0.440172 0.303829 0.717405 -0.626911
-0.653544 -0.308205 -0.691296 -0.201612 -0.632644 -0.74774 -0.279857 0.612659 -0.739141
--0.068935 -0.0771416 -0.994634 0.33931 -0.819482 -0.461863 -0.883753 -0.45613 0.10453
--0.254414 0.166439 0.952666 -0.249208 0.320836 -0.913761 -0.207199 0.148716 -0.966929
-0.304056 -0.33407 -0.892159 -0.170821 0.134216 -0.976118 0 -0.311641 -0.9502
-0.694672 -0.709144 0.120603 0.859581 -0.509036 -0.0447504 -0.781435 0.407462 0.472582
--0.647169 -0.392224 0.653706 -0.886995 0.0490504 0.459166 -0.497468 0.297268 -0.814958
-0.0882852 0.0294284 -0.99566 -0.269897 -0.304247 -0.913559 -0.719314 0.401156 -0.567152
--0.133211 -0.793344 -0.594021 0.102573 -0.981767 -0.160036 -0.479456 0.76713 -0.426184
-0.53753 0.808457 0.239703 -0.402972 0.914818 0.0268648 0.917997 -0.396562 0.00452816
-0.980883 0.0779716 0.178295 0.883936 0.441968 0.152713 -0.716192 -0.695922 -0.0525508
--0.0555452 0.864653 -0.499289 -0.243071 0.729213 -0.63966 0.952863 -0.276809 0.124209
--0.211241 -0.977383 -0.00998402 -0.540551 0.390592 -0.745146 -0.458135 0.823741 -0.33401
-0.369622 -0.870401 -0.325241 -0.146564 -0.840301 -0.521931 0.72583 -0.672963 -0.142449
--0.29592 -0.883917 -0.362107 0.647963 -0.416547 -0.637678 -0.149366 -0.852922 -0.500214
--0.746148 -0.662663 -0.0643531 0.855179 -0.117505 -0.504838 0.794308 0.21938 -0.566522
-0.239602 0.339436 -0.909601 -0.318953 0.134296 -0.938208 0.472654 -0.759727 -0.446557
-0.496001 -0.807052 -0.320392 0.576018 -0.62402 -0.528017 -0.116539 0.773139 -0.623438
-0.71045 0.333298 -0.619817 -0.105028 -0.992996 0.0541056 0.693252 -0.683712 -0.227904
--0.66256 -0.603026 0.444267 -0.0633257 -0.909588 0.410658 0.278523 -0.960424 -0.00320141
-0.329474 -0.929344 0.166631 0.23583 -0.946032 0.222277 0.17609 0.440225 0.880451
--0.741536 -0.670913 0 -0.757684 -0.651961 0.0293676 0.915488 -0.0938963 -0.391234
-0.0657912 -0.997833 0 -0.0423798 0.720457 -0.692204 0.548646 0.759664 -0.349139
--0.393073 -0.917171 -0.0655122 0.721223 0.523468 -0.453672 0.517381 0.776071 -0.360599
--0.928473 -0.295423 -0.225084 0.710282 -0.701925 -0.0529229 0.698377 0.704904 -0.124011
--0.95902 -0.139857 -0.246415 0.898349 -0.431207 -0.0838459 -0.724146 0.599293 0.341264
-0.740475 -0.598136 -0.306481 -0.762629 -0.635902 -0.11843 0.104777 -0.681047 -0.724704
-0.638241 -0.769309 0.0284929 0.994249 -0.0887288 0.0599629 0.17609 -0.968496 0.17609
-0.513226 -0.856379 -0.0566906 0.296071 0.911897 0.284228 -0.735612 0.559065 0.382518
--0.730931 0.608526 0.308926 0.89569 -0.432749 0.102317 0.124686 -0.992063 -0.0162633
--0.417759 -0.908461 -0.0132622 0.323677 -0.921233 -0.215784 -0.965722 -0.259028 0.0168931
--0.982888 -0.182016 -0.0283136 0.299775 0.930552 -0.210259 0.301131 0 0.953583
-0.976112 0.208611 -0.0607151 -0.890387 0.0460545 0.452869 0.813767 0.48358 0.322387
-0.839341 0.453698 0.299441 0.0112225 0.864131 0.503141 -0.860695 0.43913 0.257623
-0.01133 -0.940393 -0.339901 0.361886 -0.882096 -0.301571 -0.283706 -0.831774 -0.477141
-0.753653 -0.0519761 -0.655214 0.558975 -0.264243 -0.785953 0.586881 -0.8031 -0.102962
--0.895676 0.422393 0.139101 0.200534 -0.968295 0.148968 0.755142 -0.655406 0.014248
--0.409691 -0.872821 0.265211 -0.722956 0.690464 -0.0243693 -0.790186 0.603615 0.10609
--0.369077 0.918116 0.144377 -0.19593 0.979651 -0.04354 -0.218537 0.967805 0.124878
--0.13994 0.965583 0.219239 -0.102463 0.973399 0.204926 -0.297193 0.934035 0.198129
--0.522716 -0.678668 -0.515924 0.578153 -0.140245 -0.803785 -0.691431 0.718024 0.0797805
-0.435884 -0.89158 -0.12284 -0.606334 -0.785479 -0.124023 0.730789 0.501956 0.462587
-0.829482 0.47399 0.295454 0.692996 0.679921 0.239716 0 0.462566 0.886585
-0.186443 0.865288 0.465312 0.908919 -0.398649 -0.122252 -0.651332 0.195812 0.733092
-0.0958325 0.972015 0.214482 0.576707 0.527885 0.623495 -0.783524 0.547223 0.29434
--0.713561 0.5622 0.418046 -0.813596 0.355572 0.460033 -0.637132 -0.58963 -0.496385
-0.252222 0.252222 -0.934221 0.71509 0.659113 -0.232844 0.250099 -0.701892 -0.666932
-0.830773 0.288001 0.47631 0.196129 0.442546 0.875035 -0.926488 0.188352 0.325798
-0.654477 -0.711388 -0.2561 -0.433262 -0.753876 0.493919 0.660852 -0.189307 0.726249
--0.48085 -0.824314 0.298814 0.983296 -0.150169 -0.102855 0.520532 -0.753605 -0.401405
--0.491369 -0.728328 -0.477592 0.358962 0.243277 -0.90109 0.689078 0.689078 -0.224374
--0.717496 0.573997 -0.394623 0.264013 0.940669 -0.213166 -0.529192 0.797988 0.288395
--0.261115 -0.821228 0.507349 -0.680331 -0.684186 0.262753 -0.218519 -0.963269 -0.156085
-0.652871 -0.748414 0.116774 0.203874 -0.974064 -0.0981614 0.205266 -0.173687 0.963171
--0.171388 0.0507816 0.983894 -0.350738 -0.85736 0.376719 -0.855798 -0.474442 0.206192
--0.475789 -0.836182 0.272809 -0.135139 0.844618 0.518032 0.84978 0.186952 0.492872
--0.486418 0.856759 0.171352 0.307937 -0.865918 -0.394159 -0.438607 -0.758597 -0.481824
-0.659006 0.110713 -0.743945 0.69225 0.686197 -0.223436 0.231633 -0.146029 0.96178
-0.539235 0.550958 0.636923 -0.383801 -0.733736 0.56065 0.893078 -0.435089 -0.114497
-0.506432 -0.350607 0.787783 -0.604419 0.36457 0.708354 -0.873243 -0.169356 0.456909
-0.688789 -0.439653 0.576433 -0.885817 0.117133 0.449009 0 -0.999061 0.0433356
-0.871587 0.0901642 -0.481878 -0.511752 -0.0261691 -0.858735 -0.53265 -0.764754 -0.362539
--0.489831 -0.473503 -0.732025 0.450223 0.452841 -0.769568 0.769039 0.607173 -0.199799
--0.378939 0.801186 -0.463148 -0.718397 -0.689075 0.0952976 0.184114 0.97763 0.101694
--0.382269 0.888214 0.254846 0.867466 -0.485462 -0.108765 -0.560007 -0.222072 0.798171
--0.913832 -0.290254 0.284012 0.560901 -0.780385 0.276386 -0.368434 -0.846421 -0.384483
--0.38097 -0.881165 -0.280018 -0.210366 -0.839178 -0.501525 0.0851775 -0.00967926 -0.996319
-0.52573 0.738864 -0.421531 0.541798 0.823036 -0.170489 -0.601124 0.743495 -0.293029
-0.0634667 0.335467 -0.939912 -0.164716 -0.973322 -0.159725 0.874235 0.298474 0.382919
-0.975442 0.177995 0.129729 -0.932739 -0.328536 0.148533 -0.310257 -0.810372 -0.497028
-0.620221 0.334651 -0.709461 0.587911 0.732468 -0.343294 -0.74274 0.275875 -0.610107
-0.239939 0.945067 0.221985 -0.192387 0.902738 0.384774 0.908868 -0.0873912 -0.407825
--0.9459 0.169696 0.276542 -0.940466 0.175983 0.290781 0.36958 -0.90952 -0.19022
--0.460918 -0.800411 -0.383272 0.572474 0.677593 -0.461672 0.223733 -0.968343 0.110701
--0.216985 0.278012 0.935749 0.791297 0.238404 0.563038 0.79788 -0.555363 -0.234433
-0.0708869 -0.992416 0.100423 -0.555622 -0.807224 0.199185 -0.868642 -0.414275 0.271729
-0.142525 -0.891428 -0.430166 -0.668659 0.260825 -0.696323 -0.486004 0.602064 -0.633497
-0.123554 0.809965 -0.573316 0.22312 -0.80881 0.5441 0.509371 -0.709386 0.487147
--0.85552 -0.392807 0.337326 0.128324 -0.991598 0.0163322 0.04847 0.981518 0.185129
--0.160852 0.97798 0.132971 -0.783356 -0.0257743 -0.621039 0.396049 -0.203525 -0.895389
-0.800749 -0.0250234 -0.598477 0.197399 0.540055 -0.818153 -0.0079445 0.897728 -0.440478
-0.373377 0.886251 -0.274134 0.141833 -0.921916 0.360493 -0.929152 0.349305 -0.121092
--0.978305 0.142402 -0.150472 0.148585 0.728276 -0.668982 0.644562 0.528742 -0.552242
-0.41021 0.876547 -0.251779 0.329187 -0.938472 -0.104435 -0.419297 -0.898714 -0.128461
--0.403814 0.779454 -0.478942 -0.155245 0.851859 -0.500235 -0.654974 0.664606 -0.359594
-0.623948 -0.263531 -0.73569 -0.91542 -0.191728 -0.353903 0.556984 -0.718688 -0.41624
--0.299696 -0.775301 -0.555958 0.0263015 -0.836387 -0.547509 0.329968 -0.532663 -0.779353
--0.871129 -0.454099 -0.186891 0.610586 0.732157 -0.301878 0.682646 0.626428 -0.376273
-0.656219 0.686047 -0.31419 -0.702782 -0.649801 -0.289579 0.909282 -0.357218 -0.213544
--0.956792 0.278167 -0.0846846 0.741177 -0.626202 -0.241926 0.680638 -0.686146 -0.25678
-0.558265 -0.197035 -0.805927 -0.586108 -0.0572744 -0.808206 0.867414 0 -0.497587
-0.522385 -0.700066 -0.486848 0.374142 0.363513 -0.853157 0.431889 -0.431889 -0.791797
-0.831385 -0.356979 -0.42587 0.766349 0.569701 -0.2969 -0.78086 -0.496911 -0.378599
--0.0498854 -0.997708 -0.0457283 0.898977 -0.433004 -0.0659396 0.886174 -0.43135 -0.169214
--0.19776 -0.939362 -0.280161 -0.457524 0.481138 -0.747782 0.475591 -0.744403 -0.468698
-0.0990088 -0.964033 -0.246653 -0.601644 0.595687 0.532147 0.683818 0.683818 0.254532
--0.524195 0.725137 0.446537 -0.752249 -0.451349 -0.480006 0.15757 -0.601632 -0.783077
-0.290014 -0.913545 -0.285181 0.220903 -0.965483 -0.138 -0.794953 -0.539432 0.277603
--0.326052 -0.846725 -0.420413 0.903413 -0.171776 -0.392858 0.338093 0.899623 -0.276355
--0.34795 -0.394343 -0.850544 -0.548044 -0.631898 -0.548044 -0.724555 -0.169577 -0.66803
--0.0188745 -0.968891 -0.246767 -0.64358 -0.64358 -0.414258 0.356294 -0.456056 -0.815517
--0.648772 -0.689441 -0.322127 -0.465801 -0.237753 -0.852351 0.741325 0.585257 -0.328499
--0.779814 -0.582047 -0.23046 0.928625 0.19967 -0.312711 0.874323 -0.483668 -0.0403057
--0.0607823 -0.850952 -0.521715 -0.118168 -0.948487 -0.293953 -0.308258 -0.703795 -0.640039
-0.753462 0.453637 -0.475929 0.0160721 -0.962033 -0.272461 -0.830418 0.553612 -0.0626109
-0.968504 -0.141732 0.204724 0.79849 -0.598867 0.0614223 0 -0.848336 -0.529458
--0.82896 -0.524195 -0.195049 0.844479 0.52011 -0.12783 0.767202 -0.627521 -0.132732
--0.353643 0.640381 -0.681798 0.25207 -0.930719 -0.264996 0.305425 -0.916274 -0.259148
--0.384486 0.90221 0.195415 0.822951 0.565779 -0.0514344 -0.152098 -0.221233 -0.963287
--0.354471 -0.16953 -0.91957 -0.196067 0.980334 -0.0224076 0.133009 0.975401 -0.17579
-0.542551 -0.613318 -0.574003 0.0839211 -0.917138 -0.389634 0.710839 0.690135 0.135727
-0.732502 -0.138581 -0.666511 0.629762 0.414389 -0.657025 0.528107 0.55369 -0.64384
--0.491848 0.86233 -0.1203 0.379547 0.919673 -0.100726 -0.167817 0.976388 0.136033
-0.431277 -0.782524 -0.449062 -0.662868 -0.224902 -0.714161 0.22194 0.887761 -0.403264
-0.0235352 0.0823732 -0.996324 0.420952 -0.762634 -0.491111 -0.752994 0.648856 -0.109478
--0.92798 0.107075 0.356915 -0.701876 0.694926 -0.156358 -0.392322 0.603572 0.694107
--0.618742 -0.563607 0.547271 0.184252 0.982043 -0.0405227 -0.792281 0.313923 0.523205
-0.519907 0.854133 -0.0123787 -0.790345 -0.451626 0.41399 0.994274 0.0994274 0.0391684
-0.758853 -0.649703 -0.0450461 -0.771996 -0.571631 -0.277958 -0.395817 -0.918132 0.0190427
-0.108157 -0.973417 0.201894 0.375903 -0.884477 -0.276399 0.468316 -0.81339 -0.345075
-0.460938 0.784575 -0.414704 0.570948 0.741135 -0.353183 -0.572372 -0.803757 -0.162375
-0.662022 -0.165505 0.730982 0.820325 -0.392329 -0.416107 0.185374 0.98164 -0.0449392
--0.345809 0.912937 -0.216707 -0.95324 -0.300571 -0.0314884 -0.947779 -0.31749 -0.0302372
--0.0734306 -0.996558 0.0384637 -0.888005 -0.186481 -0.420323 -0.38819 -0.916742 0.094306
-0.549025 0.695432 0.463622 0.676753 -0.728811 0.104116 -0.717518 0.391374 0.576189
-0.585463 -0.712237 -0.387236 0.335432 0.934417 -0.119797 -0.371232 0.877457 0.303735
--0.662085 0.0827606 0.744845 0.848308 0.0614716 -0.525923 0.905197 -0.201155 -0.374372
--0.596285 -0.745356 0.298142 0.286282 -0.866402 -0.409134 0.135725 -0.841956 -0.522197
--0.616898 -0.663344 -0.423571 0.533046 -0.78434 -0.31729 0.637231 0.756711 -0.146032
--0.991192 0.052168 0.121725 0.384619 -0.915758 -0.115996 0.311161 -0.889033 -0.335857
--0.926151 -0.139271 -0.350498 0.98582 -0.167403 0.0116252 -0.938026 -0.343943 -0.0425586
--0.748222 -0.407409 0.523625 -0.670201 0.736762 0.0895131 0.75071 0.619153 0.230399
-0.48915 0.850043 -0.195342 0.504961 0.844554 -0.178164 -0.536778 0.782554 -0.315402
-0.688318 0.51766 -0.508179 0.294609 -0.922464 -0.249532 0.864722 0.502097 -0.0123975
-0.605492 0.749313 -0.268159 0.839586 0.529429 0.121658 0.217879 0.917911 -0.331615
-0.757777 0.277496 0.590568 0.864994 0.445953 0.230024 -0.388816 0.772288 -0.502388
-0.65577 0.733198 -0.179964 -0.415453 -0.127365 -0.900654 -0.314221 -0.287478 -0.904777
--0.449256 0.256718 -0.855725 0.106878 -0.299781 -0.948002 -0.267316 0.169883 -0.948515
-0.305573 -0.672644 -0.673925 -0.328982 -0.769959 -0.546749 -0.948924 -0.141738 -0.281875
-0.817136 -0.548751 -0.176527 -0.677952 -0.623459 -0.389462 0.685388 -0.292848 -0.666696
-0.838632 -0.00618156 -0.544664 0.843287 -0.130996 -0.521255 -0.204589 -0.7573 -0.620193
-0.357737 -0.829122 -0.429628 -0.638917 -0.610451 -0.468118 0.469127 0.69267 -0.547839
--0.268075 0.842522 -0.467217 -0.550732 -0.483631 -0.680291 0.826703 0.40761 -0.387836
-0.907922 -0.344613 -0.238578 0.0448372 -0.941581 -0.333788 -0.486454 -0.758296 -0.433993
-0.394619 -0.841407 -0.369202 -0.664798 -0.47826 -0.573857 0.276694 -0.122975 -0.953057
--0.883592 0.465557 -0.0502072 0.462115 -0.777194 -0.427106 0.603159 -0.356707 -0.713414
-0.820164 0.340068 -0.460092 0.952035 0.0115749 -0.30577 -0.0800304 0.98323 -0.163872
--0.814202 0.576286 0.0704937 0.282028 -0.568795 -0.772614 0.903205 0.418662 -0.0945708
-0.376086 0.621111 -0.687591 -0.637916 0.0609773 -0.767688 -0.57735 -0.57735 -0.57735
-0.276421 -0.900183 -0.336545 0.35853 -0.90913 -0.211988 0.30702 0.846952 -0.434063
--0.452599 -0.243188 -0.857912 -0.765682 -0.566025 -0.305526 0.66924 0.547077 -0.502816
--0.0733032 0.704525 -0.705883 -0.897898 -0.242961 -0.367082 0.770579 -0.597782 -0.221055
--0.311776 0.770271 -0.556307 0.541317 -0.589939 -0.599123 -0.485384 -0.654705 -0.579451
-0.467348 -0.233674 -0.852632 0.344958 0.936315 -0.0657063 0.905647 -0.416108 0.0815898
-0.204546 -0.920458 -0.333043 0.828805 -0.214514 -0.516784 0.493847 0.823079 -0.280457
-0.417315 -0.602789 -0.680069 -0.715093 -0.666336 -0.211277 -0.486664 -0.811107 -0.324443
--0.668648 -0.728751 -0.147754 -0.98481 -0.171271 -0.0285452 -0.583193 -0.770648 -0.256883
-0.724062 0.395093 -0.565363 0.431021 0.636194 -0.639905 0.453626 0.583736 -0.673406
-0.38199 -0.273335 -0.88282 -0.114376 0.564731 -0.817311 -0.620628 0.639645 -0.453514
--0.457017 0.888877 0.0321449 0.87115 0.195564 0.450391 -0.912988 0.300749 0.275687
-0.633054 -0.296257 -0.715174 0.571811 -0.62993 -0.525567 0 0.0634628 -0.997984
-0.649847 -0.361026 -0.668849 -0.781651 0.586238 -0.21295 -0.783687 0.391844 -0.481968
--0.898908 -0.437864 0.015454 0.714292 0.479267 -0.509989 -0.399538 -0.762754 -0.508503
--0.814241 -0.425626 -0.394784 0.3771 -0.627326 -0.681365 0.646204 -0.427328 -0.632307
--0.779839 -0.241456 -0.577538 -0.0748111 -0.654597 -0.752267 -0.176038 0.909527 -0.376525
-0.331348 0.649953 -0.683937 -0.0898383 -0.235826 -0.967634 -0.468896 -0.805914 -0.36144
-0.5891 0.0632205 -0.805583 -0.956807 -0.264417 -0.12085 -0.651873 0.641186 -0.404897
-0.00783244 -0.871638 -0.490087 0.156549 -0.834926 -0.527627 0.416594 -0.505777 -0.755407
--0.199523 -0.737045 -0.645721 0.278518 0.875341 -0.39523 -0.415601 0.373479 -0.82933
-0.857881 0.0504636 -0.511364 -0.19959 -0.471758 -0.858841 -0.0649442 -0.828039 -0.556897
-0.140919 -0.79407 -0.591265 0.517987 -0.426577 -0.741432 -0.527934 0 -0.849285
-0.901637 0.324026 -0.286458 -0.339653 -0.915176 -0.217 0.984734 -0.0364716 -0.170201
-0.885734 -0.207594 -0.415188 -0.858898 0.458079 0.229039 0.803824 -0.506112 -0.312598
--0.27654 -0.72098 -0.635384 0.0623288 -0.849938 -0.523184 -0.166814 -0.925299 -0.34058
-0.292642 -0.899488 -0.324473 -0.318389 -0.833989 -0.450655 -0.978475 -0.070904 -0.193804
--0.0285972 -0.972306 -0.231955 0.117531 -0.919095 -0.3761 -0.957871 -0.133723 -0.254168
--0.823829 -0.457683 -0.334414 0.398265 0.792466 -0.461933 0.428799 -0.227011 -0.874413
--0.170514 -0.882662 -0.437987 -0.309645 0.945233 0.103215 0.299377 0.94349 -0.142128
--0.686641 0.672336 0.276564 0.79082 0.39394 0.468417 0.198386 0.839325 0.506139
--0.599515 0.792319 0.113188 -0.505675 0.852423 0.13292 0.686569 0.473733 -0.551544
--0.317313 -0.463766 -0.827184 -0.885988 -0.437782 -0.152876 -0.462528 -0.886512 -0.012848
--0.895062 0.401235 -0.194616 0.978544 -0.144845 0.146529 -0.920899 0.327367 -0.211603
-0.872236 0.208885 -0.442234 0.262363 0.910983 -0.318237 0.856852 -0.509602 0.078169
-0.452362 0.876452 0.164924 0.258517 0.939418 -0.225084 -0.577073 -0.146094 -0.803519
-0.907065 -0.420878 0.00967536 -0.680325 0.255122 -0.687074 -0.0663093 0.582048 -0.810446
-0.241924 0.836654 -0.491408 -0.214169 0.938494 -0.270853 -0.510582 0.807553 -0.295235
--0.504783 -0.261739 -0.82261 0.188695 -0.677906 -0.71052 0.477558 -0.586803 -0.653911
--0.263785 -0.338687 -0.903166 -0.75132 0.0655221 -0.656677 0.727267 -0.595036 -0.342074
-0.126841 -0.692484 -0.710196 -0.89961 0.188291 -0.394015 0.971484 -0.139854 -0.191466
-0.937898 -0.346129 -0.0232614 -0.411939 0.56794 -0.712566 0.98726 0.13226 -0.088458
-0.84923 -0.36028 -0.386014 0.289955 -0.849693 -0.440395 -0.275267 -0.572488 -0.772324
--0.634616 0.0475962 -0.771361 -0.768179 0.303905 -0.563509 0.409018 -0.553643 -0.725385
--0.332772 -0.181342 -0.925407 0.972512 -0.230689 -0.0316632 -0.461936 0.14838 -0.874413
--0.41959 0.13741 -0.897253 0.525532 -0.586224 -0.616569 0.917388 -0.391152 -0.0734801
--0.786912 0.208901 -0.580629 0.946439 -0.259633 -0.191951 0.975783 0.118072 -0.184137
--0.0359614 0.471647 -0.881054 0.00288181 0.370312 -0.928903 -0.282292 0.341722 -0.896402
--0.530768 0 -0.847517 0.714956 -0.492864 -0.495906 0.257836 -0.699282 -0.666727
--0.389729 0.167027 -0.905656 -0.259181 0.610927 -0.74806 0.184859 0.0591548 -0.980983
--0.792411 -0.113653 -0.599307 -0.0431343 -0.197422 -0.979369 -0.533551 0.568348 -0.626342
--0.166914 -0.926267 -0.337888 -0.555622 -0.65112 -0.517037 -0.967191 -0.0541803 -0.248204
-0.355469 -0.823079 -0.442925 -0.443465 -0.518587 -0.731031 -0.962629 -0.172669 -0.208642
--0.897661 -0.368472 -0.241728 0.111658 -0.899335 -0.422764 -0.985853 0.131067 -0.104474
-0.84965 -0.515126 -0.112876 -0.31059 0.148658 -0.938848 -0.546689 -0.81886 -0.17493
-0.0932093 -0.0955993 -0.991046 0.873465 -0.11493 -0.473127 -0.570436 -0.371767 -0.732388
-0.709737 0.415677 -0.568758 -0.392645 -0.208593 -0.895722 0.867856 0.3632 -0.338986
-0.142514 0.0729142 -0.987103 0.837133 -0.107522 -0.536328 0.486846 -0.699546 -0.523084
-0.571804 0.507796 -0.644347 -0.324074 0.544199 -0.773837 0.587523 -0.587523 -0.556447
-0.988308 -0.0515375 -0.143497 0.917428 0.397619 0.0150234 -0.835169 -0.378436 -0.399098
-0.756881 -0.47434 -0.449592 0.557993 -0.557993 -0.614238 0.645238 -0.737415 -0.199717
--0.536173 -0.632409 -0.559086 -0.0521256 -0.79926 -0.598721 0.334866 -0.837718 -0.431384
-0.79371 0.163781 -0.585833 -0.655386 -0.573462 -0.491539 -0.865591 -0.0748042 -0.495132
-0.43624 -0.833989 -0.337872 -0.0930372 -0.868347 -0.487153 -0.227076 -0.866197 -0.445129
--0.221386 -0.854474 -0.469961 -0.381018 -0.847195 -0.37025 -0.570541 0.0691565 0.818352
-0.98138 -0.160694 -0.105216 -0.247 0.968627 0.0274444 -0.885824 0.420198 0.19685
--0.531494 0.341675 -0.775095 0.421847 0.888099 -0.182554 -0.0482555 0.965109 -0.257362
--0.942078 0.285478 -0.176045 0.583927 -0.237896 -0.776166 0.419812 0.257826 -0.87022
-0.35965 -0.0384092 -0.932296 0.799879 -0.131939 -0.585479 -0.56129 -0.799013 -0.215712
-0.725606 -0.0846922 -0.682878 -0.315342 -0.386549 -0.866683 -0.271599 -0.364468 -0.890728
--0.537244 -0.672859 -0.508556 -0.911339 0.0233079 0.410996 0.499059 -0.767783 -0.401807
-0.0522273 -0.377777 -0.924422 -0.117719 -0.375663 -0.919249 -0.181005 -0.837847 -0.515024
--0.158557 -0.372608 -0.914343 0.980312 -0.121694 -0.155498 -0.219502 -0.969891 0.105497
--0.903913 -0.18403 0.386102 -0.136131 -0.658635 -0.740046 0.227687 -0.607165 -0.761256
-0.0231565 -0.708202 -0.70563 0.348935 -0.747719 -0.564943 -0.147009 -0.65104 -0.744671
--0.42495 -0.459539 -0.779898 0.594258 0.556527 -0.580633 -0.325345 -0.945592 0.0025368
--0.188083 -0.442548 -0.876799 0.0850369 -0.357863 -0.929894 -0.389308 -0.448572 -0.804501
-0.670611 0.63708 0.380013 0.909109 0.37532 0.18071 -0.646918 -0.752538 0.123223
-0.255233 -0.478561 -0.84014 0.411 -0.135232 -0.901549 0.375551 -0.187775 -0.90758
--0.656132 -0.549009 -0.517764 -0.3431 -0.740116 -0.578369 -0.168283 -0.501845 -0.848429
-0.232733 0.806808 -0.543044 -0.114145 -0.984498 -0.133169 0.0698558 0.878187 0.47319
-0.960232 0.0751202 0.268908 0.511673 -0.473514 -0.71692 0.132824 -0.136849 -0.981647
--0.887468 -0.320718 -0.33097 0.193703 -0.830886 -0.52164 -0.903527 -0.172972 -0.392071
-0.658512 0.70729 -0.257104 -0.180472 0.789563 -0.586532 0.285217 0.918699 0.273208
-0.58228 0.804605 0.116456 -0.738717 -0.110808 0.664845 0.939025 -0.222655 0.262024
--0.464892 0.858465 0.216597 0.317284 -0.784144 -0.533339 0.135133 -0.713777 -0.687213
-0.199732 0.965371 -0.16783 -0.591054 -0.797923 0.118211 -0.895819 0.422518 -0.137792
--0.976474 0.205573 -0.0650983 -0.985232 0.168897 -0.0281495 0.830002 -0.536817 0.15141
-0.881484 0.336567 0.331224 -0.934465 -0.271554 -0.230288 0.493791 -0.841532 -0.219076
--0.714548 -0.519671 -0.468363 0.429581 -0.801884 -0.415261 0.437341 -0.799514 -0.411716
--0.968303 -0.162936 -0.189316 -0.0718217 -0.655373 -0.751883 0.103111 0.523737 -0.845617
-0.719326 -0.31275 -0.620288 -0.118581 0.783188 -0.610372 -0.500901 0.712981 -0.490669
-0.928063 -0.326783 -0.178641 -0.574786 -0.0334178 -0.817621 -0.35944 0.86132 -0.359069
--0.252345 -0.400784 -0.880735 -0.499005 0.483651 -0.719079 -0.210502 0.834124 -0.50983
--0.40673 0.777216 -0.480111 -0.00439597 0.84073 -0.541437 0.291792 0.827992 -0.478839
-0.302693 0.91365 -0.27133 -0.130404 0.891094 -0.43468 0.0603017 0.983449 -0.170855
--0.186761 -0.832641 -0.521373 -0.679514 -0.434134 -0.591429 0.420585 -0.723185 -0.547825
--0.245572 -0.0731492 -0.966614 -0.661545 0.340598 -0.668095 0.629657 -0.553173 -0.545465
--0.358405 -0.248571 -0.899866 0.891806 -0.452011 -0.0191974 -0.754601 0.0855841 -0.650578
-0.356064 -0.715145 -0.601486 0.995831 -0.0142262 -0.090099 -0.58215 0.429977 -0.690087
--0.724248 0.347639 -0.595493 -0.801478 0.281976 -0.527373 -0.779075 0.302749 -0.548985
--0.898627 0.149771 -0.412357 0.914188 -0.148247 -0.377205 0.992642 -0.0428094 0.113266
-0.0517198 -0.947414 -0.315805 -0.927056 0.0902244 -0.363905 -0.559794 -0.737206 -0.378363
--0.958316 -0.180477 -0.221494 -0.714704 -0.565303 -0.411863 0.646173 0.396238 -0.652269
-0.892075 0.079219 -0.444889 -0.800266 -0.561011 -0.211754 -0.996918 0.0657309 -0.0428246
--0.189974 -0.93027 -0.313859 0.290537 -0.646816 -0.705136 0.490444 -0.759708 -0.426975
-0.901897 0.167689 -0.398073 0.890305 0.39509 -0.22641 0.724946 -0.54371 -0.422885
-0.793386 -0.288132 -0.536207 -0.776237 -0.292262 -0.558605 0.976611 0.213166 0.0281372
-0.842339 0.304002 -0.445025 0.814105 0.306631 -0.493164 0.305038 0.0938579 -0.947704
-0.710796 -0.527646 -0.465143 0.374728 -0.498793 -0.781527 0.242357 -0.73988 -0.627568
--0.867817 0.0565968 -0.49365 0.726207 0.6205 -0.295979 0.927935 0.371065 -0.0353137
-0.652765 -0.293271 -0.698491 0.696431 -0.115888 -0.708204 -0.302605 0.048315 -0.951891
-0.520128 0.779495 -0.349076 0.488382 -0.586761 -0.645906 0.327712 -0.0121375 -0.9447
-0.457791 -0.3689 -0.808913 -0.00402853 -0.739235 -0.673436 0.868894 -0.408891 -0.278983
--0.641868 -0.421128 -0.640825 0.986782 0.150123 -0.0610255 -0.779776 -0.320574 -0.537756
-0.651451 -0.138391 -0.745962 -0.869597 0.0763549 -0.487823 0.710504 0.617323 -0.337781
-0.220767 -0.0229966 -0.975055 -0.0934787 -0.933175 -0.347053 0.0896729 -0.174364 -0.98059
-0.501089 -0.418718 -0.757354 0.172447 -0.172447 -0.969806 0.171111 -0.841528 -0.512397
-0.556848 -0.556848 -0.616312 0.180093 0 -0.98365 -0.244977 -0.792573 -0.558404
--0.269363 -0.778844 -0.566432 0.378509 -0.485634 -0.787966 0.286378 -0.266507 -0.920305
-0.217689 0.0473238 -0.97487 0.200596 -0.351042 -0.914621 -0.101472 -0.854825 -0.508898
-0.178932 -0.178932 -0.967454 -0.0207192 -0.361976 -0.931957 0.498923 -0.507459 -0.702539
-0.483004 -0.509034 -0.712455 0.76903 0.587655 0.251507 -0.301348 0.919499 0.252411
--0.0384775 -0.577162 -0.815723 0.082675 -0.277205 -0.957247 0.238274 -0.201616 -0.95004
--0.765755 -0.402021 -0.501995 -0.69594 -0.510917 -0.504609 -0.13824 -0.984957 0.10368
--0.502977 -0.863808 0.0291581 0.545883 -0.745784 0.381862 -0.953289 0.223045 0.203694
--0.850018 0.525734 0.032756 0.409694 -0.594898 -0.691554 -0.674859 -0.503077 0.539887
--0.0078526 -0.753849 -0.657001 0.737376 -0.63715 0.224315 -0.474709 -0.833032 0.284092
-0.279673 -0.619451 -0.733528 0.172541 -0.366033 -0.914467 0.157571 -0.0555251 -0.985945
-0 0.320807 -0.947145 -0.113267 -0.550789 -0.826923 -0.258576 -0.430959 -0.86453
--0.347626 -0.61694 -0.706075 -0.394927 0.668337 0.630364 0.862274 0.485029 -0.145708
-0.210028 0.977087 0.0344973 -0.499032 0.738152 0.453981 -0.786821 0.236416 0.570106
-0.695176 0.283864 -0.660417 -0.176292 0.557082 -0.81153 -0.534678 -0.0379013 -0.844205
-0 -0.542159 -0.840276 -0.302755 -0.513602 -0.802841 -0.291386 -0.388514 -0.874157
-0.278614 -0.767009 -0.577989 -0.228 -0.182875 -0.956333 -0.754886 -0.310732 -0.577575
-0.269663 -0.910112 0.314607 0.833897 -0.551655 -0.0171056 -0.727183 -0.650326 0.219731
-0.930932 0.241584 -0.273865 -0.529984 0.711485 0.461417 -0.849591 0 0.527442
--0.230759 0 0.973011 0.0269059 0.666241 0.745251 -0.281486 0.910101 0.304109
--0.327088 -0.727603 -0.602998 -0.0227522 -0.712902 -0.700894 0.66698 -0.618231 -0.415847
-0.478994 -0.319329 -0.817676 -0.427317 -0.0899615 -0.899615 -0.0149172 -0.615334 -0.788125
-0.0405642 -0.699732 -0.713253 0.329685 0.576949 -0.747287 -0.29226 0.670479 -0.68194
--0.0274813 -0.659552 -0.751156 -0.135381 -0.631778 -0.763235 -0.185869 -0.430745 -0.883126
--0.888935 -0.146262 -0.434054 0.968516 0.0131871 0.248601 0.562413 -0.788051 -0.250335
--0.161129 -0.986917 -0.00559477 -0.547542 -0.752558 0.365861 0.74427 0.0636547 0.664838
--0.488658 0.730359 0.477273 0.614369 -0.78882 -0.0176979 -0.570599 -0.570599 -0.59062
--0.380847 -0.914032 -0.139644 0.861457 -0.267811 -0.431473 -0.909721 0.1077 -0.40101
--0.128373 -0.826398 -0.548258 0.714629 -0.691576 0.105017 -0.0867184 -0.552259 0.82915
--0.997986 0.0608753 0.0178322 0.459158 -0.880053 0.121167 0.313637 -0.947183 0.0669092
--0.357703 -0.933826 0.00422068 0.561474 -0.827436 -0.00985042 0.911792 -0.293076 -0.287649
-0.102258 0.2876 0.952276 0.641782 -0.187839 0.743527 -0.586427 -0.662095 -0.466619
--0.970237 -0.222192 -0.0962831 0.213508 0.781899 0.585703 0.713906 0.695119 0.0845415
--0.381851 0.575194 0.723423 -0.309021 0.0457809 0.949953 -0.393099 0.48295 -0.782453
-0.634537 -0.625066 0.454594 0.953295 -0.120956 0.276763 0.873406 0.291135 0.390386
--0.280131 0.931437 0.232276 0.204539 0.562482 0.801111 -0.097859 0.831801 -0.546379
-0.907674 0 -0.419677 0.819948 0.571479 -0.0331292 -0.720129 -0.49272 0.488509
--0.537713 -0.778958 0.322628 0.668143 -0.348287 0.657481 -0.687771 0.723042 0.0646623
--0.0484929 0.994104 0.0969857 0.808223 -0.528712 -0.259305 -0.791052 0.566536 -0.230811
-0.752408 -0.165439 0.637583 -0.824815 -0.045823 0.563543 -0.940138 -0.197126 0.277998
-0.772106 -0.292395 -0.564231 0.667928 0.742142 -0.0556606 -0.836563 0.497088 0.230358
-0.186484 -0.959063 -0.213125 0.0693341 -0.990487 -0.118858 0.472632 0.836734 0.276577
--0.0268747 -0.698743 -0.714868 0.924193 -0.370082 0.0943742 -0.969623 -0.102912 0.221904
-0.248282 -0.910366 0.331042 0.948932 -0.199775 -0.24417 -0.365232 0.896478 -0.250866
--0.738858 -0.577498 -0.347254 -0.693041 -0.713791 -0.100982 -0.624894 -0.621727 -0.472189
-0.695174 -0.695174 -0.18294 -0.991053 -0.125374 -0.0457715 0.58828 -0.788073 -0.181294
--0.595792 -0.746726 -0.295689 -0.759902 -0.597864 -0.255163 0.591665 0.792456 -0.148139
--0.137568 -0.792204 -0.594548 -0.176128 -0.401005 -0.898985 0.393653 -0.719251 -0.572465
-0.55508 -0.80699 -0.201625 -0.0898359 0.285728 -0.954091 0.0976536 -0.19194 -0.976536
-0.427482 -0.61799 -0.659809 0.578262 -0.813487 -0.0620733 -0.255468 -0.271109 -0.928028
--0.523024 0.156704 -0.837789 0.683384 -0.416816 -0.599375 -0.395116 0.531363 -0.749358
--0.301731 0.484682 -0.821001 0.845864 -0.510983 -0.153006 0.819229 -0.569405 0.0681339
-0.709237 0.164138 -0.685596 0.207528 0.6127 -0.762581 0.923431 -0.310708 -0.225245
--0.162754 0.787458 -0.594492 0.652019 0.0197582 -0.757945 0.768873 -0.253047 -0.587198
--0.621695 0.321359 -0.714299 0.591213 -0.564986 -0.57555 -0.160851 0.0419611 -0.986086
-0.628373 -0.265136 -0.731334 0.729737 -0.367285 -0.576702 0.112827 -0.126101 -0.98558
--0.664376 0.408847 -0.625659 -0.410122 0.31638 -0.855397 -0.337348 0.363297 -0.868454
-0.685398 -0.602109 -0.409504 -0.697605 0.379467 -0.607743 -0.0654955 -0.688832 -0.721956
--0.871567 -0.0234853 -0.489713 0.670593 -0.741681 -0.0146125 -0.865168 0.146297 -0.479668
--0.8769 0.10167 -0.469798 -0.847356 -0.194703 -0.494043 -0.829636 0.173678 -0.530603
--0.901618 -0.0424442 -0.430445 -0.886804 -0.0928051 -0.452732 -0.811178 -0.0201535 -0.584451
--0.85455 0.278911 -0.438125 -0.661704 0.676585 -0.323081 -0.429258 -0.520739 -0.737949
--0.422608 -0.808144 -0.410251 -0.777924 0.0138915 -0.628205 -0.868429 0.0315543 -0.494808
--0.761754 -0.364631 -0.535514 0.807114 -0.417473 -0.417473 -0.609969 -0.738179 -0.288149
--0.949876 -0.0166645 -0.312182 -0.959867 0.157535 -0.232029 0.883655 -0.294552 -0.363858
--0.758329 -0.262279 -0.59678 -0.711843 -0.4919 -0.501312 -0.153665 -0.881345 -0.446786
-0.652715 -0.141231 -0.744324 -0.298263 -0.742896 -0.599287 -0.894969 0.444145 -0.0420212
--0.424483 -0.849683 -0.312815 -0.0522991 -0.780217 -0.623319 0.73675 -0.0437674 -0.674747
-0.845535 0.431687 -0.314192 -0.801317 0.489281 -0.34423 -0.927278 0.161833 -0.337588
-0.754098 0.324301 -0.571109 0.756034 0.574219 -0.314142 -0.459049 -0.86686 -0.194495
-0.776158 -0.0757228 -0.625975 -0.960802 0.277236 0 -0.725056 -0.28665 -0.6262
-0.717335 -0.531622 -0.450343 -0.812963 -0.0150549 -0.582121 -0.792509 -0.074795 -0.605256
--0.644503 -0.245979 -0.723954 -0.565292 0.0699885 -0.821916 -0.480075 -0.801048 -0.357561
-0.508248 -0.512954 -0.691782 -0.871898 -0.272468 -0.406886 0.520541 -0.362801 -0.772924
-0.522675 -0.441918 -0.729053 -0.662861 -0.628622 -0.406755 -0.758493 -0.204926 -0.618623
--0.537976 -0.37459 -0.755158 0.932353 0.346853 -0.10203 -0.816905 -0.00464811 -0.576753
--0.383825 0.119945 -0.915583 -0.292393 -0.247722 -0.923656 -0.475811 -0.254623 -0.841885
-0.943693 0.321587 0.0776246 -0.0446794 -0.854494 -0.517537 0.238988 0.942297 0.234436
--0.780142 0.61709 0.102848 0.825891 -0.560899 0.0574149 0.0991213 0.429526 0.897598
--0.964809 -0.244802 0.0960009 0.411222 -0.712785 -0.568185 0.242342 -0.693802 -0.678167
--0.163558 -0.906226 -0.389877 0.260388 -0.698313 -0.666751 -0.564163 -0.57856 -0.589057
--0.00563318 0.9982 0.0597117 -0.996706 -0.0699794 -0.0409879 -0.368071 0.926019 -0.0837409
-0.21344 -0.649488 -0.729801 -0.420871 -0.899368 -0.118338 0.97701 0.212449 -0.0178101
-0.214514 -0.477185 -0.85222 0.0847024 -0.0889375 -0.992429 -0.450341 -0.378696 -0.808568
--0.172528 -0.73739 -0.653062 -0.80767 -0.560697 0.182449 -0.302778 0.43692 -0.847011
--0.29517 -0.361763 -0.884309 -0.716899 0.109357 -0.688547 -0.00174721 -0.676172 -0.736742
-0.111441 0.984393 0.136205 0.677331 0.727815 -0.107279 0.523706 0.851896 -0.00232758
--0.55464 0.741248 0.378054 -0.961 0.0864778 0.262681 0.572965 -0.791734 -0.211823
--0.625792 -0.727271 -0.281888 -0.366019 -0.524073 -0.76901 0.299987 -0.784325 -0.542994
-0.0899026 -0.70124 -0.707234 -0.726774 -0.34349 -0.594823 -0.540466 -0.493469 -0.681458
--0.100363 -0.451634 -0.886541 0.908532 0.345828 -0.23446 -0.889587 -0.167233 0.425051
-0.111754 -0.621633 -0.775295 -0.349217 -0.133035 -0.92755 0.236301 0.843931 0.481603
-0.512517 0.772843 0.374219 -0.999969 -0.00476176 0.00634901 0.567379 -0.756505 -0.32524
--0.532288 -0.846394 -0.0169279 -0.476215 -0.878352 -0.0414483 0.632215 0.12772 0.764193
--0.0429579 0.948003 0.31535 0.956566 -0.206483 -0.205781 0.873818 0.484142 -0.0452653
--0.636874 0.770953 0.00474862 -0.506477 0.569787 -0.647166 -0.0814436 -0.977323 0.195465
--0.141925 -0.978539 -0.149395 0.415453 -0.909612 0.00232467 0.9282 -0.330592 0.170745
-0.882775 0.396348 0.252222 -0.809829 0.583077 0.0647864 -0.910695 0.395136 0.120423
-0.862701 0.38634 0.326326 0.988963 -0.0830152 0.122718 0.381722 0.819996 0.426492
--0.702105 0.706334 0.0902303 -0.635553 -0.566701 -0.524331 0.188958 0.6771 0.711218
-0.93302 0.0222148 0.359139 0.675939 -0.692629 0.251739 -0.72403 0.686661 0.0653963
--0.915396 0.349515 0.199723 -0.48367 -0.860083 -0.162235 0.862666 0.342529 0.37213
--0.851916 0.523678 -0.000835212 0.808312 -0.5819 0.0895773 0.618689 -0.471382 0.628509
--0.749072 0.650357 0.1262 0.10313 0.980641 0.166456 0.682158 -0.731202 -0.00222927
--0.951088 -0.118595 -0.285249 0.77083 -0.632254 0.0779491 0.211129 0.889759 0.404664
--0.542737 0.839349 0.0305026 0.789355 -0.612946 -0.0348831 -0.802624 -0.526311 -0.280699
-0.696452 -0.712102 -0.0886867 -0.972939 -0.023615 -0.229853 -0.531443 0.77455 0.342988
-0.590401 -0.801961 -0.0910202 0.868927 0.463428 -0.173785 0.981048 -0.151578 -0.120701
--0.80975 0.563304 -0.164297 0.649936 -0.747776 -0.135695 -0.919676 -0.326727 -0.217818
-0.832367 -0.542793 -0.111985 -0.887132 -0.3314 -0.321203 -0.919632 0.386829 -0.0681209
--0.918796 0.350723 0.181125 0.186736 -0.982362 0.00968799 -0.859083 0.501132 0.104131
--0.961772 0.225352 0.1556 0.277818 -0.884901 -0.373854 0.662087 -0.735246 -0.145098
--0.650969 -0.754723 -0.0814409 -0.647192 -0.616373 -0.448583 0.804875 -0.593398 -0.00736487
-0.120998 0.992372 0.0236056 -0.193053 0.978683 0.0700657 -0.676753 0.104116 -0.728811
--0.239465 -0.810878 -0.533979 -0.580163 0.463296 -0.669901 -0.60503 0.537085 -0.587774
--0.518402 0.439682 -0.733443 -0.562085 0.436355 -0.702606 -0.608176 0.351391 -0.711791
--0.683912 0.254025 -0.683912 -0.479149 0.199326 -0.854801 -0.272635 0.576555 -0.77023
--0.215907 0.663423 -0.716418 -0.394579 0.506252 -0.766823 -0.406585 0.609878 -0.680248
-0.297571 0.732482 -0.612309 -0.0874499 0.911977 -0.400812 -0.522842 0.692766 -0.4967
--0.814067 0.323509 -0.482323 0.826154 -0.56344 0.00224542 -0.489245 0.462437 -0.739453
-0.77798 -0.430456 -0.457661 -0.566856 0.474453 -0.673475 -0.708262 0.397687 -0.583275
-0.806212 -0.58939 0.0514062 -0.817192 0.498769 -0.288835 -0.679102 0.469527 -0.564239
--0.773952 0.348278 -0.528867 -0.910986 0.0700759 -0.40644 -0.978773 -0.13328 -0.155691
--0.78692 0.041236 -0.615676 0.955127 -0.267503 0.127183 -0.70305 0.212241 -0.67873
--0.572229 0.171218 -0.802022 -0.407421 0 -0.913241 -0.531609 -0.182043 -0.827195
--0.770144 0.0738629 -0.633579 -0.823196 -0.00460744 -0.567739 -0.800541 0.198299 -0.56552
--0.464681 0.52922 -0.709929 -0.445637 0.728326 -0.520527 -0.844319 0.360537 -0.396407
--0.803115 -0.473484 -0.361689 -0.760715 -0.41624 -0.498053 -0.900008 0.133334 -0.414979
-0.525763 -0.126183 -0.84122 -0.747258 0.161173 -0.644693 -0.551081 -0.76919 -0.323507
--0.572163 -0.754913 -0.320525 -0.897505 -0.110123 -0.427034 0.742705 -0.553222 -0.377274
--0.167768 -0.894763 -0.413828 0.59585 -0.546195 -0.588756 -0.554865 -0.615994 -0.559175
--0.566758 -0.775831 -0.277257 -0.204349 -0.819952 -0.534714 0.666597 -0.367943 -0.64828
-0.812309 0.445752 -0.376111 -0.420328 -0.754858 -0.503501 0.492021 0.00531915 -0.870567
-0.852066 0.41589 -0.317834 0.792062 0.517678 -0.323493 0.593697 -0.521295 -0.613005
--0.705055 -0.236478 -0.668562 -0.620622 0.404258 -0.671866 -0.822447 0.568842 0
-0.11671 0.729157 -0.674322 -0.331979 0.799635 -0.500373 -0.803889 0.500019 -0.322092
-0.798379 -0.0523527 -0.599875 0.369866 0.156217 -0.915858 -0.619742 0.236812 -0.748225
-0.147107 0.249524 -0.95713 -0.94483 -0.181092 -0.272951 0.797186 -0.028269 -0.603072
-0.656777 -0.402486 -0.637691 0.314249 -0.196992 -0.928677 0.42417 -0.24661 -0.871357
--0.3767 0.219742 -0.899895 0.149819 -0.301842 -0.941512 -0.636536 -0.642656 -0.426397
-0.392456 -0.364706 -0.844374 0.453076 -0.372224 -0.810044 -0.601956 -0.566373 -0.562913
--0.769846 -0.60387 -0.206587 -0.648616 -0.253806 -0.717551 -0.482492 0.516685 -0.707275
-0.579276 -0.177645 -0.795539 -0.416049 0.462771 -0.782781 -0.664953 0.31518 -0.677125
--0.309773 -0.937782 -0.156861 -0.28769 -0.939543 -0.185724 -0.654088 -0.735849 -0.175202
-0.821154 0.186192 -0.539479 -0.743262 -0.408794 -0.529574 0.532575 -0.282284 -0.797922
--0.264237 -0.397348 -0.878802 0.0706018 -0.600115 -0.796792 -0.778534 -0.257697 -0.572256
--0.0263625 -0.254837 -0.966624 0.156417 -0.449142 -0.879662 -0.72083 -0.511382 -0.46786
--0.449142 -0.156417 -0.879662 -0.55333 0.166757 -0.816099 -0.372586 -0.62904 -0.682267
--0.165314 -0.521468 -0.837104 -0.0278004 -0.185336 -0.982282 -0.2608 0.587367 -0.766148
-0.411074 -0.88683 -0.211069 0 0.211055 -0.977474 0.40504 0.495825 -0.76818
-0.272106 0.705253 -0.654658 0.880827 0.463391 0.0970186 -0.901997 0.43139 -0.0174299
--0.100298 0.254602 -0.961831 0.712622 -0.698888 0.0610383 -0.762781 -0.642749 0.0709864
-0.542105 -0.496929 -0.677631 -0.506658 -0.608718 -0.610541 -0.1159 -0.321207 -0.93989
-0.477504 0.187591 -0.85837 0.384429 -0.242307 -0.890787 0.598357 -0.295391 -0.74479
--0.294199 -0.501868 -0.813373 0.663932 0.165983 -0.729139 0.814149 0.32566 -0.480736
--0.721139 -0.655581 -0.22399 0.247493 -0.489361 0.836226 0.87133 -0.483522 -0.0836124
--0.163022 0.984484 -0.0649265 -0.905469 0.347303 0.243939 -0.847847 0.520966 0.0987452
-0.292962 -0.404503 -0.866343 0.0265558 -0.68455 -0.728482 0 -0.73366 -0.679517
--0.26173 -0.628348 -0.732582 -0.00576413 -0.201744 -0.979421 0.782567 -0.146079 -0.605185
-0.677627 -0.511417 -0.528464 0.53679 -0.84314 -0.0311772 0.00518468 -0.995459 0.0950525
--0.18027 -0.755749 -0.62956 0.131033 -0.512738 -0.848487 0 -0.263428 -0.964679
-0.0960711 -0.148345 -0.984258 0.242487 -0.664796 -0.706573 -0.196046 -0.844506 -0.498373
-0.125768 -0.440786 -0.888758 -0.244309 -0.745455 -0.620169 -0.228088 -0.740599 -0.632051
--0.122469 0.35652 -0.926226 0.257634 -0.434757 -0.862908 0.00588786 -0.812524 -0.582898
--0.25625 -0.318246 -0.912719 0.02465 0 -0.999696 0.686449 0.171612 -0.706638
--0.77205 0.353728 -0.528029 0.409933 -0.625121 -0.664213 0.471881 -0.434815 -0.766984
--0.0935671 -0.340244 -0.935671 0.13288 0 -0.991132 0.225659 0.0569847 -0.972538
-0.166533 -0.313345 -0.934923 0.463903 -0.746279 -0.477349 -0.807694 0.472775 -0.352298
-0.616546 0.784695 0.0642236 0.0344266 -0.496727 -0.867224 0.226224 -0.690792 -0.686752
-0.00989547 -0.951202 -0.308409 -0.668022 -0.276926 -0.690694 0.255987 0.252662 0.933077
-0.455952 0.237345 0.857773 -0.265447 0.245028 0.932469 -0.0574943 0.767959 0.637913
-0.904957 -0.0530101 0.422187 0.654389 0.75029 0.0940213 0.150119 -0.850672 -0.503807
-0.34337 0.587598 0.732684 0.0545363 -0.96711 0.248443 -0.830342 0.556603 0.0269394
-0.674611 0.732767 0.0891727 0.819487 0.569374 0.0652255 0.891889 -0.445384 -0.0785311
--0.482966 -0.0817328 -0.871816 -0.975184 -0.0872116 0.203494 -0.0860946 0.941769 0.325051
-0.805688 -0.591934 0.0219235 0.343258 0.86368 0.369094 -0.966533 0.250162 0.0568549
-0.591278 0.743866 0.311534 0.743494 0.650557 0.154895 0.943002 0.189716 -0.273415
-0.874134 -0.277382 -0.398683 0.67779 -0.550704 -0.487161 0.33154 0.754817 0.565979
-0.626842 -0.676591 0.386386 -0.598319 0.800793 0.0272997 0 -0.871576 -0.490261
-0.0722282 -0.967055 -0.244105 -0.139767 -0.941485 -0.306711 0.828475 0.555684 -0.0696009
-0.903477 -0.424268 -0.0610457 -0.954305 0.183792 -0.235631 -0.946472 -0.165543 -0.277104
-0.62114 0.763484 0.176852 -0.669754 0.740255 0.0587504 -0.827886 0.454002 -0.329374
-0.854212 -0.51096 0.0961315 0.763126 0.457875 0.456058 -0.639139 0.768489 0.0304352
--0.726498 0.687076 -0.0112635 0.827618 -0.529078 0.187416 -0.0556839 0.997249 0.0489344
-0.238792 0.878661 0.413442 -0.898035 0.436249 -0.0567479 0.0794507 -0.979177 -0.186817
-0.477464 -0.878192 -0.0284204 0.248372 -0.931394 0.266113 -0.953889 -0.0260367 -0.299027
-0.065624 -0.976008 -0.20761 -0.4787 -0.656139 -0.583376 0.793964 -0.53758 -0.283952
-0.870715 -0.477104 -0.119276 -0.904923 0.3541 -0.236067 0.971278 -0.182912 0.152191
-0.823809 -0.566067 0.03011 0.796188 -0.60419 0.0322235 -0.974865 -0.162277 -0.152661
-0.970984 0.192592 0.141769 0.931307 0.347631 -0.108724 -0.205526 0.976251 0.0685088
--0.798314 -0.434083 0.417452 -0.417846 -0.473559 -0.775337 0.78154 -0.623635 -0.0165593
-0.828034 -0.520319 -0.208873 -0.473877 -0.880563 -0.00707279 -0.745437 -0.64853 0.154057
-0.550147 -0.696653 -0.460449 -0.926113 0.356864 -0.122326 -0.863385 0.400411 -0.306981
--0.864079 0.29614 -0.407023 0.347919 -0.748956 -0.56393 0.167435 -0.771399 -0.61393
--0.879002 0.355188 0.318115 -0.536021 -0.716349 -0.446684 0.645486 -0.761253 -0.0619761
-0.403714 -0.847329 -0.345034 -0.246641 -0.44043 -0.863243 -0.693521 0.709105 -0.127275
--0.825708 -0.324556 -0.461378 0.982818 0.0530375 -0.176792 0.746583 -0.584152 -0.318403
--0.510715 -0.2293 -0.828608 0.906152 0.247132 -0.34324 0.122792 -0.960899 -0.248184
-0.310242 0.916184 0.253688 -0.708175 -0.465174 -0.531132 0.978202 -0.145819 -0.147844
--0.945683 0.282989 -0.160002 -0.494376 -0.861905 -0.112752 -0.539 -0.842296 0.00404395
-0.449857 0.878736 -0.159535 0.528707 0.827357 0.189603 0.537905 0.815755 0.212607
-0.064815 0.914355 0.399693 0.0703927 0.240253 0.968155 0.493916 0.631321 0.597898
--0.61754 -0.782218 -0.0823387 -0.810859 0.548522 -0.20404 -0.36257 0.611997 -0.702854
--0.778382 0.555209 -0.293027 -0.353858 0.234048 -0.905542 -0.697202 0.312684 -0.645088
--0.3748 0.3748 -0.847968 0.0431331 0.539164 -0.841096 -0.116571 0.657874 -0.744052
--0.249592 0.660891 -0.707762 0.0597491 0.336768 -0.93969 -0.577712 0.659838 -0.480483
--0.60388 0.530683 -0.594731 -0.150688 0.539966 -0.828088 -0.369478 -0.383689 -0.846326
--0.707931 0.353966 -0.611181 -0.306082 0.83371 -0.459609 -0.465637 0.456639 -0.758066
-0.153931 0.262965 -0.952447 0.213066 0.319599 -0.923287 -0.309679 0.424909 -0.850618
--0.0362285 -0.00905712 -0.999303 -0.771425 0.115714 -0.625711 -0.810519 0.0457551 -0.583922
--0.451093 0.663373 -0.597035 -0.312808 0.904909 -0.288603 -0.799353 0.583714 -0.14252
--0.593688 -0.604582 -0.531051 -0.716216 -0.648564 -0.257681 0.389333 -0.449012 -0.804243
-0.574993 0.146991 -0.804846 -0.631734 -0.539535 -0.556609 0.696127 0.126568 -0.706674
--0.661887 0.625641 -0.412891 0.134114 -0.560673 -0.817104 0.833614 0 -0.552348
--0.890851 0.234503 -0.389092 -0.912051 -0.343773 -0.223569 -0.879735 -0.149288 -0.45142
-0.516374 0.344249 -0.784124 -0.539225 -0.644543 -0.542034 -0.555452 -0.336169 -0.760567
--0.551223 0.045306 -0.833127 0.344184 -0.251519 -0.904586 -0.379469 0.236316 -0.894516
--0.0505197 0.523332 -0.85063 -0.428999 0.712708 -0.554983 -0.423668 0.738436 -0.524612
-0.414105 -0.164673 -0.895209 -0.699193 0 -0.714933 -0.503052 0.220748 -0.835589
--0.193854 0.693313 -0.694073 -0.749304 -0.194264 -0.633092 -0.559887 0.352447 -0.749872
-0.121946 0.858652 -0.497842 -0.782248 -0.349631 -0.515603 0.913806 -0.214453 -0.344917
--0.997963 0 -0.0637986 -0.934474 0.254436 -0.249039 -0.970636 0.23386 -0.0563426
--0.615577 -0.685302 -0.389135 -0.560925 -0.362052 -0.744501 0.307347 -0.53607 -0.786236
--0.669301 0 -0.742992 0.401257 -0.517128 -0.756023 0.395116 -0.531363 -0.749358
--0.632136 -0.102429 -0.768058 0.805925 -0.0215323 -0.591627 0.519204 -0.705333 -0.482631
--0.672804 -0.067374 -0.736747 0.553892 0.568681 -0.608116 -0.71218 0.0727614 -0.698216
--0.363524 -0.813978 -0.453088 0.561699 -0.27675 -0.779682 0.404642 -0.617612 -0.674404
-0.542029 -0.496095 -0.678302 0.17444 -0.0847279 -0.981016 -0.570814 -0.32865 -0.752436
--0.303507 0.360772 -0.881888 -0.410297 -0.776689 -0.477923 0.407867 -0.210306 -0.888491
-0.372813 0.135367 -0.917979 -0.317082 0.018119 -0.948225 -0.831034 0.0494128 -0.554023
-0.55003 -0.523838 -0.650432 -0.305021 -0.570503 -0.762554 -0.833039 -0.183966 -0.521731
--0.421117 -0.197667 -0.885205 -0.902386 -0.374105 -0.213882 -0.347955 -0.665913 -0.659914
--0.960518 -0.274434 -0.0457389 -0.968183 -0.212205 0.132628 0.238512 -0.0226325 -0.970876
-0.422694 -0.422694 -0.801661 0.380996 -0.627881 -0.678681 -0.864546 -0.364306 0.346181
--0.330467 -0.165233 -0.929241 -0.290911 -0.661823 -0.690914 0.0875772 -0.860865 -0.50124
-0.683175 -0.704524 -0.192143 -0.564599 -0.793711 0.226385 0 0.175069 -0.984556
--0.37607 -0.75214 -0.541162 -0.455337 -0.610873 -0.64769 -0.578046 -0.611896 -0.539857
--0.454739 0 -0.890625 0.321236 0.470648 -0.821766 0.309639 0.379102 -0.872012
--0.174146 0.245853 -0.953535 0.270138 -0.433858 -0.85953 0.0202675 0.668827 -0.743141
-0.0359715 0.373359 -0.926989 -0.315727 -0.315727 -0.894781 -0.380819 -0.635748 -0.671417
--0.423972 0.527501 -0.7362 -0.641047 -0.166119 -0.749308 -0.54974 -0.66345 -0.507562
--0.87643 -0.316259 -0.363112 0.256253 -0.169224 -0.951682 -0.82949 -0.49722 -0.254398
-0.660376 -0.23983 -0.711607 -0.115367 -0.195076 -0.973979 0.00509622 -0.225508 -0.974228
--0.23051 -0.669224 -0.706403 -0.501724 -0.666412 -0.551514 0.495783 -0.452462 -0.741268
-0.156365 -0.721412 -0.674621 -0.133386 -0.306152 -0.942592 -0.356597 -0.662251 -0.658986
-0.735799 0.674674 -0.0584333 -0.63828 0.760538 -0.119082 -0.172447 -0.172447 -0.969806
--0.492528 -0.379489 -0.783201 0.325622 0.842744 -0.428664 0.107415 0.747668 -0.655328
--0.81243 -0.183011 -0.553593 -0.983947 -0.178461 0 -0.172447 -0.172447 -0.969806
-0.082675 -0.277205 -0.957247 -0.14805 -0.345451 -0.926685 0.536267 0.701781 -0.468958
-0.312591 0.842878 -0.437999 -0.0678658 0.729558 -0.680544 -0.83351 -0.176319 -0.523615
--0.0240081 -0.970826 0.23858 -0.976271 -0.21639 0.00838721 0.121592 -0.688336 -0.715128
-0.253107 -0.523776 -0.813385 -0.221956 -0.635875 -0.739188 -0.0115213 -0.724692 -0.688976
-0.386263 0.920088 -0.0651006 0.222209 0.96929 -0.105358 -0.0538851 0.948377 -0.312533
--0.515738 0.055012 -0.854979 -0.427164 -0.768895 -0.475743 0.872329 -0.187977 -0.45134
--0.696362 0.666457 -0.266298 0.378509 -0.485634 -0.787966 -0.135512 -0.597534 -0.79031
--0.12771 -0.989754 -0.0638551 -0.14718 -0.987332 -0.0592808 -0.18581 -0.854396 -0.485264
-0.170756 -0.282894 -0.943829 -0.260393 -0.791765 -0.552542 -0.388232 0.522619 0.759042
-0.638935 -0.0418974 0.768119 -0.537887 0.758559 0.367786 0.00162546 -0.831423 -0.555637
-0.697849 0.536807 -0.474179 0.509548 -0.774121 0.375629 0.502088 -0.793742 -0.343339
-0.761545 -0.598772 -0.248035 0.718602 -0.617745 -0.319378 -0.655845 -0.139119 -0.741966
--0.526761 -0.325527 -0.78521 -0.760006 0.313617 -0.569241 0.792057 0.243343 0.559848
-0.27298 0.961115 0.0417052 -0.135909 0.96431 0.227235 -0.455563 0.754413 0.472571
-0.0211604 0.921441 -0.387941 -0.545395 0.253523 -0.798918 -0.807688 -0.264334 -0.527037
--0.401322 0.825934 0.395947 0.974495 -0.0417342 0.220496 0.984002 -0.127601 0.124329
-0.689761 0.720147 0.074952 0.398757 0.806309 0.436873 0.399496 0.559294 0.726356
-0.105949 0.994286 -0.0130398 0.676602 0.67255 0.299811 -0.109824 0.93223 -0.344797
--0.850381 -0.390716 -0.35241 0.274537 0.137269 0.951728 0.747409 0 0.664364
-0.944553 0.280813 -0.17019 -0.691431 -0.718024 -0.0797805 0.412394 -0.830269 0.374945
-0.0349829 -0.988267 0.148677 -0.17372 -0.978318 0.112766 -0.550285 -0.822469 -0.143981
-0.597449 0.74922 0.285876 0.700209 -0.65902 0.274592 -0.284758 0.801629 0.525646
--0.542715 -0.50395 0.671933 0.934404 -0.0133486 -0.355964 -0.610997 -0.73741 -0.287941
-0.936698 0.342018 -0.0749769 0.852352 -0.437889 -0.285919 -0.499767 0.866067 -0.0126647
--0.971465 0.124172 0.202084 0.603574 0.720053 0.342378 0.888564 -0.458445 -0.0167852
-0.955239 -0.114 0.272988 -0.278246 0.924176 0.261684 0.348285 0.868507 0.352693
--0.375022 0.912919 0.16105 -0.6494 -0.684822 -0.330604 0.754167 -0.270397 -0.598429
--0.16011 -0.936841 -0.310957 -0.564127 -0.798593 -0.209785 -0.838848 0.522174 0.153845
-0.509181 -0.86066 -0.000343577 0.56089 -0.820125 0.113121 -0.749457 0.356538 0.557848
-0.757747 -0.652537 0.00394044 -0.855023 0.510462 0.0914577 0.317331 -0.769286 0.554527
--0.641643 0.641643 0.420224 0.706267 -0.462727 -0.535789 -0.0413064 -0.888088 -0.457813
--0.275058 -0.933038 0.231911 -0.854788 -0.518817 0.012922 0.153124 -0.922995 -0.353035
-0.577741 -0.812855 -0.0740391 0.396683 -0.895789 0.200509 0.70818 -0.682192 0.181918
-0.428481 -0.895219 0.122423 -0.476731 0.800909 0.362316 -0.473672 0.879163 -0.0520321
-0.258292 0.926072 0.275092 0.25796 -0.51592 -0.816874 -0.742338 0.652228 -0.153402
--0.631057 0.308815 -0.711618 0.759959 -0.643043 0.094647 -0.43105 0.826179 -0.3628
-0.781053 -0.574353 -0.245103 0.325906 -0.422797 -0.845593 -0.145221 -0.875773 -0.460361
--0.250892 -0.802855 -0.540812 0.972572 -0.0342254 -0.230071 0.25179 -0.795428 -0.551268
--0.129511 -0.647553 -0.750934 0.485874 -0.85679 -0.172735 -0.682432 -0.554476 -0.476281
-0.944536 0.277064 0.176313 -0.862268 0.22419 0.454128 -0.964739 0.0639285 0.255327
--0.931844 -0.362605 -0.013577 -0.594279 -0.772562 -0.223562 0.840345 -0.541131 0.0315954
-0.337175 -0.937691 -0.083952 -0.196653 0.947336 0.252749 0.567186 0.823586 0.00258989
--0.154528 0.881383 0.446415 -0.151051 0.868543 0.472034 0.219365 0.877462 -0.426544
-0.668805 0.622144 -0.406986 -0.600171 0.493881 0.629187 0.237233 0.964443 0.116487
--0.864581 0.432291 -0.256172 0.743713 0.131362 0.655465 0.987282 -0.0806346 0.137013
--0.110199 0.539397 0.834809 -0.184052 0.94071 -0.28494 -0.806674 -0.235797 0.541919
--0.824177 0.524476 0.213675 -0.79624 0.498977 -0.342088 0.18834 0.690065 -0.698813
--0.0866422 0.880174 -0.466676 -0.647615 0.674422 -0.354612 0.766549 -0.618904 0.171349
--0.874694 0.35783 -0.326906 0.500186 0.0218937 -0.865641 -0.428552 0.220262 -0.876258
--0.633891 0.465654 -0.617534 0.317038 0.462008 -0.828273 0.45888 0.209489 -0.863449
--0.172331 0.623042 -0.762969 -0.436479 0.421808 -0.79471 -0.436819 0.422177 -0.794327
--0.204932 0.63529 -0.744587 -0.551799 0.469195 -0.689474 -0.0814733 0.537724 -0.839175
-0.0705667 0.650782 -0.755978 0.0268041 0.830926 -0.555737 -0.403932 0.580653 -0.706881
--0.45241 0.407383 -0.793325 -0.706872 -0.115358 -0.697872 0.312871 0.368741 -0.875295
--0.781045 0.292892 -0.551528 -0.643803 0.366898 -0.671493 -0.55345 0.675872 -0.486713
--0.674034 0.26364 -0.690052 -0.620867 0.46565 -0.630629 -0.648835 0.511203 -0.563635
-0.414562 0.910015 -0.00337042 -0.370703 0 -0.928751 -0.160067 0.101506 -0.981873
-0.535569 -0.494819 -0.684339 0.619153 -0.755367 -0.21464 -0.649905 -0.400235 -0.646093
-0.720422 -0.432253 -0.542355 0.408888 -0.713695 -0.568726 -0.712135 -0.577994 -0.39848
-0.83064 -0.139465 -0.539061 -0.202699 -0.719788 -0.663942 0.873608 -0.0513887 -0.48391
--0.943873 -0.330306 -0.00130685 0.917684 0 -0.397311 -0.936431 -0.211366 -0.280038
--0.635925 0.236485 -0.734626 -0.786572 -0.0172602 -0.617258 -0.806092 0.307588 -0.505575
--0.625074 0 -0.780565 -0.0319201 0.516273 -0.855829 -0.0713707 0.0356854 -0.996811
--0.537102 -0.559349 -0.631387 -0.3801 0.471936 -0.795488 -0.749884 -0.326389 -0.575451
--0.735108 -0.385716 -0.557529 -0.736127 0.114607 -0.66707 -0.65306 -0.483595 -0.582794
-0.477285 0.369327 -0.797369 -0.747115 -0.0498077 -0.662826 -0.205603 0.699771 -0.68414
--0.364781 0.674051 -0.642331 -0.522794 -0.459039 -0.71831 0.185773 0 -0.982593
--0.882847 0.0509335 -0.46689 0.671071 0.0447381 -0.740042 -0.52554 -0.21146 -0.824071
--0.497897 -0.342304 -0.796823 -0.436782 -0.288301 -0.852117 0 -0.185408 -0.982662
--0.723993 -0.00559789 -0.689784 -0.454739 0 -0.890625 -0.297124 0 -0.954839
-0.22072 0.839394 -0.496689 -0.258042 0.642919 -0.721158 -0.402083 0.467097 -0.787496
-0.133029 0.768613 -0.62573 0.131468 0.821464 -0.5549 -0.278108 0.661446 -0.696523
--0.835613 -0.33955 -0.431807 -0.151789 -0.893317 -0.423019 -0.863961 -0.2239 -0.451044
--0.839578 -0.423524 -0.340199 0.867114 -0.00530345 -0.498082 -0.904054 0.138161 -0.404472
-0.180169 -0.750704 -0.635596 0.0305688 -0.730056 -0.682704 -0.423027 -0.687823 -0.58987
--0.492764 0.236527 -0.8374 0.822643 -0.364328 -0.43649 0.0683147 -0.959512 -0.273259
--0.997079 -0.0487461 0.0587908 0.0222418 -0.578286 -0.815531 -0.76425 -0.390849 -0.51299
--0.5314 -0.442833 -0.722159 -0.177164 -0.500682 -0.847308 0.547588 -0.305631 -0.778933
-0.474633 -0.870765 -0.128421 0.397145 -0.723829 -0.564223 -0.0380044 -0.547264 -0.836097
-0.395116 -0.531363 -0.749358 -0.11476 -0.774954 -0.621511 0.0101811 -0.897637 -0.440617
-0.883631 -0.239682 -0.402181 0.978105 -0.204513 0.0385314 -0.435043 -0.791438 -0.429375
--0.333969 0.0811067 -0.939088 0.428472 -0.265245 -0.863746 -0.508177 0.182626 -0.841668
--0.772113 -0.15745 -0.615672 -0.470757 0.262312 -0.842366 0.0920962 0.446937 -0.889812
--0.0210331 0.57922 -0.8149 -0.634238 0.27247 -0.723535 0 -0.180093 -0.98365
-0.621395 -0.517209 -0.588527 -0.127733 0.58088 -0.803905 -0.261064 0.124687 -0.957235
--0.713487 -0.249232 -0.654844 -0.919597 -0.038546 -0.390967 -0.826018 -0.0225278 -0.563194
--0.636143 -0.373933 -0.674904 0.519706 -0.377321 -0.766508 -0.0341066 0.0341066 -0.998836
-0.177046 -0.481884 -0.858162 0.488382 -0.586761 -0.645906 -0.387423 -0.819548 -0.422191
--0.628337 0.7181 -0.299208 -0.97997 -0.0544428 -0.191558 0.288155 -0.288155 -0.9132
--0.328004 -0.770429 -0.546674 -0.319041 -0.738927 -0.593464 0.0421692 -0.685708 -0.726655
-0.598082 -0.642938 -0.478465 0.354843 -0.593661 -0.722255 -0.11671 -0.786079 -0.607008
-0.925631 -0.0970419 -0.365773 0.492707 0.854026 0.166973 -0.557297 0.827398 -0.0695197
-0.46927 -0.210363 -0.857632 0.570595 -0.423409 -0.703666 -0.117946 -0.451565 -0.884408
-0 -0.179487 -0.98376 0.846403 -0.50626 -0.165238 -0.644232 -0.759273 0.0920331
-0.812889 -0.452536 0.366638 -0.509134 -0.83879 0.192909 0.218713 -0.132745 -0.966718
--0.200509 -0.200509 -0.958954 0.192226 -0.973665 -0.122579 -0.516551 -0.856214 0.00846805
--0.0354702 -0.986073 0.162488 0.409464 0.394299 -0.82272 0.13231 -0.573343 -0.808561
--0.490945 -0.499693 -0.713638 -0.106641 -0.00784122 -0.994267 -0.409572 -0.253756 -0.876276
-0.625638 -0.687389 -0.368882 0.494146 -0.484163 -0.722085 -0.3461 -0.359944 -0.866404
--0.172447 -0.172447 -0.969806 -0.318335 -0.695493 -0.644167 -0.224632 -0.703848 -0.673897
-0 -0.587764 -0.809032 0.153572 -0.661029 -0.734477 0.00854327 -0.341731 -0.939759
--0.575751 -0.589459 -0.566612 0.488449 -0.636069 -0.597355 -0.30195 -0.433514 -0.849054
-0 -0.175069 -0.984556 0.230173 -0.0886227 -0.969106 0.451094 0.263138 -0.852803
--0.256417 0.682522 -0.684408 -0.349964 -0.817377 -0.457625 0.509858 -0.509858 -0.692884
-0.0929787 0.0929787 -0.991317 0.735538 0.465457 -0.492274 -0.726582 -0.59617 0.341556
-0.785634 -0.583274 -0.206328 0.139874 0.963575 0.227943 -0.602536 -0.763212 0.233363
--0.279498 -0.792159 -0.542554 -0.210776 -0.321124 -0.923284 -0.19265 -0.17179 -0.966113
-0.0960711 -0.148345 -0.984258 0.349424 -0.255216 -0.901536 0.644899 -0.12441 -0.754074
-0.858479 -0.280656 -0.429239 -0.82493 -0.434405 -0.361638 0.731604 -0.491344 -0.472585
--0.141882 -0.141882 -0.979663 0.208143 -0.976118 -0.0622036 0.728672 -0.613151 -0.305094
--0.340743 -0.908647 -0.241359 -0.0150653 -0.858722 -0.51222 -0.184493 -0.798436 -0.573117
-0 -0.185408 -0.982662 -0.423191 -0.423191 -0.801136 0.423718 -0.501943 0.754
-0.914698 -0.0531801 0.400624 -0.0418217 0.888712 0.456554 -0.968621 0.0284889 0.246903
-0.0250435 -0.751305 0.659479 -0.358429 0.907385 -0.219503 -0.996783 0.0419208 -0.0683153
--0.119944 -0.420374 -0.899388 0.934608 -0.142688 0.325805 -0.0671048 -0.971254 0.228392
-0.502134 0.819272 0.276866 0.616506 0.616506 0.489735 -0.0298865 0.999538 0.00553454
-0.289798 0.955825 -0.049147 -0.747094 0.516174 -0.418825 0.275001 -0.910122 0.309922
--0.299544 -0.948843 0.0998479 0.710932 -0.640053 0.291389 0.798598 -0.466295 0.38054
--0.0722302 -0.996777 -0.0349113 -0.268286 -0.960636 -0.0721198 -0.0161611 -0.985825 0.166998
-0.622713 0.178399 0.761842 -0.271273 0.883079 0.38286 0.113325 0.869937 -0.479965
-0.531963 0.0115144 0.846689 -0.354269 0.919412 0.170808 -0.784283 0.61792 0.0554544
--0.976588 0.151139 0.153076 -0.972625 0.196841 -0.123508 -0.72475 0.102208 0.681389
-0.828698 -0.510537 -0.229372 -0.790963 -0.0903958 0.60515 0.894124 0.0286272 0.446903
--0.275851 0.927108 0.253727 -0.542035 0.832958 0.111265 0.729044 -0.557877 0.396572
--0.639486 -0.689102 0.340876 -0.924675 -0.377418 0.0503224 -0.219365 -0.731218 -0.645909
-0.891443 0.432647 -0.134707 -0.142372 0.968598 0.203833 -0.235422 0.881707 0.408864
--0.814427 0 0.580265 -0.470187 -0.606294 0.641352 0.645084 -0.763198 0.0373523
--0.763394 0.643827 0.0521193 0.716086 0.461247 0.5239 0.849921 -0.449344 -0.275179
--0.914794 -0.333429 0.227986 0.963175 -0.157253 0.218095 0.969073 0.199515 0.145225
--0.0623225 0.996256 0.0599139 0.674192 -0.244272 0.696991 0.371349 0.516538 0.771549
--0.569795 0.776663 -0.268566 -0.718254 0.64363 -0.264293 -0.718274 0.517692 -0.464841
-0.480531 -0.835574 0.266282 0 0.890064 0.455835 0.365912 0.643118 0.672687
-0.832113 0.421851 0.360041 0.954546 0.130835 0.267813 -0.72099 0.674474 0.158928
-0.476716 -0.762746 -0.43699 -0.21813 -0.916637 -0.334956 0.858905 0.394416 0.326678
--0.816859 0.315719 0.482766 0.417419 -0.849571 0.322477 -0.454239 -0.883701 -0.112871
--0.561202 -0.810967 -0.165483 0.394132 0.878868 -0.268795 0.964523 -0.0595029 0.257206
-0.964573 -0.123663 0.233036 -0.769838 0.620974 0.147446 -0.859744 0.510178 0.0236194
--0.424986 -0.786224 -0.448596 0.89496 0.356203 -0.268636 -0.693899 0.696463 0.182875
--0.0058703 -0.817929 -0.57529 -0.113789 -0.785143 -0.608771 -0.773993 0.456103 0.43921
-0.312699 0.799121 0.513445 -0.111902 0.973338 0.200228 -0.576003 0.805213 -0.1409
--0.982313 -0.133382 0.131417 0.395951 -0.905306 -0.153767 0.498366 -0.835842 0.230216
--0.220191 0.790099 0.572066 0.624134 0.271363 0.732679 -0.419525 0.483477 0.768277
-0.632047 0.765289 0.121854 0.196978 0.875974 0.440305 -0.79877 -0.26753 0.538883
-0.297715 -0.952687 0.0612688 -0.580683 -0.763926 0.281468 -0.0227317 -0.941743 -0.335564
--0.601703 -0.791714 -0.105562 0.100041 -0.969632 -0.223169 -0.721377 0.55087 -0.41971
-0.985732 0.0490414 0.161019 -0.556792 0.82601 0.0876998 -0.596851 -0.750327 0.284215
-0.878503 0.459525 -0.130649 0.059197 -0.980263 -0.188628 -0.371376 0.00884229 -0.92844
-0.57772 -0.804488 -0.137981 0.107465 -0.0179108 -0.994048 -0.686893 0.482398 -0.543572
--0.240862 0.51314 0.823816 -0.926045 0.37362 -0.0533743 -0.412635 -0.909913 0.0423215
-0.906899 -0.378443 -0.185244 0.48306 -0.852947 -0.197825 -0.943578 0.229741 0.238493
-0.536044 -0.838564 -0.0973017 -0.818782 -0.438633 -0.370401 0.867657 -0.495804 -0.0367262
-0.569369 -0.765426 -0.299904 -0.202798 0.916731 0.344205 0.446501 0.788353 0.423246
--0.736485 0.675257 0.0402355 0.984051 0.140318 0.109339 0.943237 0.210987 0.256494
--0.579521 0.788357 0.206516 -0.71773 0.239243 0.653932 -0.987262 -0.0239204 0.157295
-0.0166855 -0.920734 -0.389833 -0.751227 0.659395 0.0292666 0.516148 0.842823 -0.152449
--0.329945 0.942416 0.0546615 0.970761 0.142024 -0.193528 -0.0254645 0.96765 0.251007
-0.98907 0.121111 -0.0841046 0.723093 0.61011 -0.323886 -0.933481 -0.283745 -0.21932
--0.798414 0.562519 -0.214725 -0.441277 0.375903 -0.814845 -0.242647 -0.0808824 -0.966737
--0.853984 0.204956 -0.478231 0.989226 -0.0613474 -0.132919 -0.277813 0.909421 -0.309472
--0.0427886 0.996974 -0.064896 -0.568726 0.820137 -0.0626494 0.181231 0.9834 -0.00891299
--0.461182 -0.733552 0.499212 -0.987359 0.0658239 0.144186 -0.90507 -0.318266 0.282053
--0.993195 0.116088 -0.00931568 0.0815103 0.151376 -0.98511 -0.949476 0.291748 -0.115663
--0.0710296 0.756256 -0.650408 0.114096 0.932051 -0.343895 -0.480534 0.439512 -0.758891
--0.736143 0.313542 -0.59982 -0.234798 0.626128 -0.743527 -0.412541 0.164372 -0.895987
--0.925036 0.143975 -0.351538 0.66157 0.0374474 -0.748948 -0.185527 0.272833 -0.944003
-0.5317 0.745858 -0.401237 0.0477638 0.987686 -0.148977 -0.505042 0.603245 -0.617274
--0.0350279 0.612227 -0.789905 0.6321 0.330034 -0.70109 0.771794 0.00627475 -0.635841
--0.650412 0.459625 -0.604739 -0.0762216 -0.70505 -0.70505 -0.496523 -0.553814 -0.668397
--0.165255 -0.694072 -0.700682 -0.792172 0.433567 -0.429515 -0.423179 0.215207 -0.880117
-0.0894459 0.673826 -0.733456 -0.895594 0.0334801 -0.443612 -0.887991 0.426662 -0.171554
--0.144472 -0.764993 -0.627626 -0.664857 -0.441506 -0.602526 -0.766713 -0.606981 -0.209104
--0.857561 -0.0751252 -0.508867 -0.282113 0.408106 -0.868252 0.0240754 -0.214672 -0.976389
-0.542341 0.198275 -0.816427 0.629121 0.351881 -0.693099 0.361147 -0.208119 -0.908988
-0.157398 -0.724033 -0.671567 -0.371133 -0.871357 -0.320932 0.406464 -0.468768 -0.784247
-0.312422 -0.551724 -0.7733 -0.455835 -0.0267213 -0.889663 -0.228108 -0.409086 -0.883525
--0.497743 -0.617619 -0.608932 -0.409339 -0.7567 -0.509752 -0.729704 -0.508382 -0.457252
-0.656527 0.025579 -0.753869 0.760126 0.302839 -0.574889 -0.842957 -0.469264 -0.263088
-0.54045 -0.237798 -0.807072 -0.629224 -0.641809 -0.438359 0.827071 0.109236 -0.551381
--0.373767 -0.289837 -0.881075 0.893271 0.0915583 -0.440096 -0.311345 0.166368 -0.935621
--0.205981 -0.137321 -0.968873 -0.694872 0.0534517 -0.717144 -0.448149 0.0206045 -0.893722
--0.499994 0.314238 -0.807007 -0.392693 0.145716 -0.908052 -0.767328 -0.00537847 -0.641233
--0.138503 -0.246228 -0.959265 -0.100131 0.807082 -0.581887 -0.816115 0.0429534 -0.576292
--0.830445 -0.337487 -0.443241 -0.335017 0.00744482 -0.942183 -0.423305 -0.100787 -0.900364
--0.297061 -0.0206124 -0.954636 0.718451 0.0671799 -0.692326 0.797564 0.118416 -0.591498
--0.604608 -0.763446 -0.227155 -0.186032 -0.677774 -0.711347 0.324318 -0.746686 -0.580756
--0.450544 -0.0813013 -0.889044 -0.457855 -0.848157 -0.266456 -0.287508 -0.713168 -0.639321
-0.401061 -0.749153 -0.527181 0.178405 -0.766553 -0.616902 0.147486 -0.516902 -0.843244
-0.332688 -0.266844 -0.904496 -0.480452 0.182781 -0.857763 0.699503 -0.14626 -0.699503
--0.652521 -0.756581 0.0424404 0 0 -1 0.574039 -0.732031 -0.366893
-0.0215465 0.797221 -0.603303 -0.366363 0.838326 -0.403718 0.540566 -0.0766156 -0.837806
-0.293806 -0.321788 -0.900073 0 -0.805683 -0.592347 0.58472 -0.577319 -0.569917
--0.643565 0.213155 -0.735112 -0.759482 -0.165432 -0.629142 -0.483722 0.668977 -0.564342
--0.206678 0.792266 -0.574106 -0.0288845 0.788133 -0.614827 -0.55797 0.52973 -0.638792
-0.759035 0.185262 -0.624135 0.363141 0.276421 -0.889786 0.481804 0.0161499 -0.87613
--0.942707 -0.306703 0.13129 0.0975776 -0.780621 -0.617341 0.408642 -0.207282 -0.888845
--0.362616 0.442157 -0.82037 0.172079 0.465394 -0.868215 0.544485 0.69033 -0.476425
--0.365771 -0.802035 -0.472177 -0.13498 -0.781247 -0.609454 -0.589435 -0.63244 -0.502579
-0.365376 0.152051 -0.918358 0.857891 -0.0919169 -0.505543 0.483016 -0.438554 -0.75787
-0.479833 -0.125979 -0.868268 0.428564 -0.767844 -0.476182 -0.669657 -0.685368 -0.286061
--0.584652 -0.733349 -0.346961 -0.630364 0.775832 0.0269386 0.702414 0.702414 -0.115015
-0.587823 -0.182105 -0.788227 0.762597 -0.0649019 -0.64361 0.574273 -0.19292 -0.795608
-0.452318 -0.452318 -0.768646 -0.568191 -0.409674 -0.71367 -0.552606 -0.566003 -0.611774
--0.552647 -0.82897 -0.0859673 0.761816 0.128864 -0.634847 0.379944 0.293593 -0.877181
--0.825219 0.5639 0.0320919 -0.449142 -0.156417 -0.879662 0.72444 -0.10363 -0.681503
-0.324992 -0.181527 -0.928131 -0.540602 -0.422114 -0.727715 0.51775 -0.285291 -0.806563
--0.554546 -0.284383 -0.782052 -0.133974 -0.173529 -0.975673 -0.330467 -0.165233 -0.929241
--0.244907 0.379966 -0.89199 -0.024013 -0.515648 -0.856464 0.0603724 -0.603724 -0.794904
-0.561852 -0.494688 -0.663028 -0.432075 0.0652188 -0.899476 -0.757459 0.269319 -0.594746
--0.188802 0.0917038 -0.977724 -0.253825 0.779287 -0.572961 0.263356 -0.784216 0.561826
-0.60898 -0.750797 0.255827 0.276018 0.552036 0.78681 -0.513996 0.747631 0.420542
--0.532352 -0.760503 0.371801 -0.133219 -0.666095 -0.733873 -0.589831 0.518208 -0.619322
-0.124862 -0.264413 -0.956293 0.165416 -0.478328 -0.862461 -0.875574 0.149034 -0.459521
--0.543368 0.123027 -0.830431 -0.497284 0.0252588 -0.86722 0.764705 -0.0791655 -0.6395
-0.607932 -0.645026 -0.46299 -0.581591 0.803149 -0.129242 -0.424753 0.817144 0.389694
-0.83265 0.550926 0.0563447 -0.270036 0.938696 0.214314 0.149199 -0.0239454 -0.988517
-0.194734 -0.301523 -0.933361 -0.110504 0 -0.993876 -0.256578 -0.843645 -0.471625
--0.400846 -0.754534 -0.519616 0.786517 -0.32386 -0.525837 0.555913 -0.526654 -0.643115
--0.261925 -0.641027 -0.721443 -0.612827 0.779962 -0.126898 0.514418 -0.163678 0.841774
--0.0646994 -0.139931 -0.988045 0.646157 -0.332785 -0.68683 0.913205 -0.145859 -0.380502
-0.0755444 -0.522145 -0.849504 -0.806435 0.280012 -0.520823 -0.354884 0 -0.93491
--0.181037 -0.929324 -0.321844 0.445548 -0.661135 -0.603645 -0.208956 0.46676 0.859344
--0.704145 0.631129 0.325356 0.109766 -0.259888 -0.95938 -0.788177 -0.498977 -0.360276
--0.401809 -0.385644 -0.830559 0.568719 -0.290243 -0.769622 0.549939 -0.46946 -0.690778
--0.363265 -0.690573 -0.625418 0.910828 -0.27297 -0.309644 -0.142386 0.987209 -0.0717203
-0.699557 -0.679852 0.220049 -0.853627 0.284542 0.436298 0.324002 -0.616962 -0.717203
--0.582605 -0.543416 -0.604376 -0.0985291 0.239285 -0.965937 0.0603236 -0.475492 -0.877649
--0.25542 0 -0.96683 0.481442 -0.813153 -0.327104 -0.518022 -0.84937 -0.101115
--0.971218 -0.194552 -0.137422 0.461727 -0.887022 -0.000247841 -0.175985 -0.984321 -0.0119312
--0.151461 -0.731338 -0.664984 -0.408019 -0.848249 -0.337629 0.0300072 -0.49762 -0.866876
-0 -0.25542 -0.96683 0.232757 -0.411802 -0.881047 -0.362132 -0.641275 -0.676482
-0.606449 -0.741216 0.287783 0.293729 -0.917009 0.269849 -0.160886 -0.326504 -0.931403
--0.535961 -0.375173 -0.756301 -0.408275 -0.898718 0.160057 0.104298 -0.208596 -0.972425
--0.271329 -0.407547 -0.871944 0.235196 -0.0306778 -0.971464 -0.0768463 0.922156 0.379109
--0.694839 0.191197 0.693284 -0.629876 -0.404648 0.66296 0.171286 -0.236777 -0.956346
-0.16836 -0.274186 -0.946825 0 -0.724005 -0.689795 -0.0958648 -0.636026 -0.76569
--0.0688492 0.907334 -0.414734 0.0720212 0.916019 -0.394616 -0.300483 0.832339 -0.465749
-0.445947 -0.876246 -0.182551 0.0776202 -0.993539 -0.0827949 -0.548156 -0.754604 0.360691
-0.0170736 0.273177 -0.961812 -0.335984 -0.0912549 -0.937437 -0.441987 -0.338543 -0.830684
-0.126111 -0.693611 -0.709225 0.635762 0.771252 0.031267 -0.163299 0.701899 -0.693304
--0.387619 0.113702 -0.914781 -0.6267 -0.586958 -0.512569 0.636046 0.158279 -0.755244
-0.482455 0.0331458 -0.875293 0.714132 -0.0892666 -0.694296 0.779214 -0.25568 0.572235
--0.418474 -0.89534 -0.152467 0.292683 -0.097561 -0.951219 -0.206772 -0.935644 -0.286035
-0.134147 0.972568 -0.190042 0.0410159 0.750004 0.66016 0.200766 0.790517 0.578597
-0.325909 0.678978 0.657854 0.209063 0.928485 -0.306933 0.890858 -0.206446 0.404663
-0.839116 0.427626 0.336184 0.129066 0.530605 0.837735 0.801616 0.248904 0.543561
-0.290777 0.717249 0.633247 -0.555659 0.782755 0.280246 -0.981049 0.178373 0.0756732
-0.535912 -0.602901 0.591024 -0.613857 -0.371237 0.696679 -0.868085 -0.0190788 0.496049
-0.637757 -0.699839 0.3217 0.715899 0.166664 0.678021 -0.941787 -0.0425323 -0.333508
--0.390771 0.882853 -0.260514 -0.660552 0.590438 -0.46374 0.623763 0.733839 0.269074
-0.0144218 -0.973473 0.228346 -0.923465 -0.259298 -0.282802 0.602693 0.609244 0.515346
-0.646749 -0.729533 0.222482 -0.389103 -0.915112 -0.105682 -0.557366 -0.804395 -0.20565
-0.0460165 -0.966347 0.253091 0.473718 0.702629 0.530946 -0.36819 0.911494 0.183346
-0.920294 -0.0626903 0.386172 0.566078 0.649209 0.508019 -0.400389 0.883808 0.242017
-0.107032 0.791103 0.602246 0.851886 -0.387471 0.352357 -0.698937 0.712301 -0.0641472
-0.436605 0.703781 -0.560418 0.827097 -0.232813 0.511575 0.00514209 0.742175 0.670186
--0.97065 0.0500804 -0.235226 -0.994384 0.057813 -0.0886466 -0.805787 0.401439 0.435377
-0.0855229 0.958325 0.27258 -0.829449 0.32249 0.456086 -0.105929 0.658274 0.745288
--0.670837 0.213448 0.710223 0.937375 0.124064 0.325478 0.88404 0.276743 0.376678
--0.463262 0.8165 0.344551 0.76058 -0.645527 0.0693831 0.982153 -0.0637072 -0.176965
-0.710444 -0.647925 -0.274705 -0.120542 -0.98945 0.0803614 -0.340571 -0.84512 0.412048
-0.745192 0.628883 -0.2218 -0.892643 -0.241861 0.380384 0.497432 0.834363 0.237485
-0.792949 0.109914 -0.599292 0.509942 0.747914 -0.424951 -0.0398567 0.99841 -0.0398567
--0.185057 0.981606 0.0469347 0.215159 0.66063 0.719218 0.924525 -0.365326 0.108587
--0.919617 -0.391427 0.0330119 -0.0499747 -0.998357 0.0280161 -0.249731 -0.968003 0.0245767
-0.726701 -0.0641207 -0.683954 0.208396 -0.968932 -0.133201 0.171561 -0.981113 -0.0893546
-0.983822 -0.168166 -0.0617616 0.645454 0.368348 0.66911 -0.449547 0.877687 0.166053
--0.137044 -0.939732 -0.313244 0.663553 -0.744598 -0.0726025 -0.421637 -0.737865 -0.527046
-0.942883 0.0574669 0.328129 0.905207 -0.373301 0.203091 -0.257075 0.956559 0.137505
--0.129518 0.979908 0.151673 0.757905 -0.606733 -0.239697 -0.864204 -0.251266 -0.435909
--0.279377 0.95525 0.0971923 0.164566 0.919298 0.357505 0.416017 0.886297 0.203487
--0.505457 0.315911 0.80294 -0.466701 0.132768 0.874393 0.656575 -0.366616 0.659168
-0.272729 0.873174 0.403962 -0.829695 -0.140709 0.540191 -0.801073 -0.563995 0.200476
-0.857995 -0.472093 -0.202419 -0.908661 0.147067 0.390777 -0.0739412 -0.985882 0.15023
--0.906681 0.0546992 -0.418256 -0.676726 0.502087 -0.53847 0.909123 0.284535 -0.304198
--0.69733 -0.686764 0.205149 -0.554284 -0.832311 0.00531262 0.766618 -0.622362 -0.157995
--0.0734825 -0.981516 0.176708 -0.18421 -0.97222 -0.144412 0.578781 -0.720523 0.381916
-0.980987 -0.158048 -0.112632 -0.663863 0.743847 -0.0773174 0.00736467 -0.979502 -0.201301
-0.974387 0.111722 -0.19516 -0.563754 -0.317517 -0.762472 0.821896 -0.115656 0.557773
-0.840799 -0.450428 0.300285 -0.653473 0.756901 -0.00861895 -0.647625 0.761127 0.0356083
-0.422265 0.777187 0.466555 -0.721025 0.675819 0.152945 -0.692976 0.702392 0.162573
-0.722882 -0.684516 0.0942304 0.541656 -0.0492415 0.839157 0.713851 -0.695309 0.0834371
-0.879118 0.295715 0.37377 0.96499 -0.236752 0.112882 0.730211 -0.683181 -0.00742588
--0.870976 0.491082 0.0154428 -0.918998 0.370755 -0.134103 -0.95269 -0.0790501 -0.293485
-0.950151 0.160415 0.267358 -0.632724 0.764542 0.12303 0.371687 -0.877865 -0.301995
--0.746607 -0.411175 -0.522985 -0.996271 0.0379532 0.0774877 -0.973645 0.216366 -0.0721218
-0.496914 -0.819696 -0.284912 -0.945534 -0.280158 -0.16576 0.13028 0.70514 0.696997
-0.188894 -0.554088 0.810744 -0.868409 -0.169371 0.466026 0.190266 -0.874654 0.445846
--0.409669 0.718718 0.561797 -0.249379 0.892778 0.375177 -0.286159 0.950614 0.120193
-0.368298 0.909472 -0.192918 0.309305 0.565341 0.76467 -0.153646 -0.171722 0.97309
-0.920076 -0.26439 0.289066 0.866675 0.454878 -0.204843 -0.161646 0.971446 -0.173678
--0.313982 0.921559 -0.228351 0.540462 0.808422 0.23314 -0.935596 -0.165529 0.311865
--0.315534 0.919775 -0.23335 0.123151 0.985211 -0.119136 0.423102 -0.883142 0.202597
--0.814527 -0.550356 0.183452 -0.870338 0.490779 0.040604 0.635008 0.759741 0.139853
-0.346862 0.923006 0.166572 0.138148 0.989628 -0.0393882 -0.835204 -0.528989 0.150352
-0.256576 -0.837052 0.483231 0.41113 -0.828846 0.379456 0.339057 -0.856564 0.389023
-0.0881929 -0.264579 0.960323 0.89914 -0.167889 0.404178 0.0615907 0.588961 0.805811
--0.126984 0.991592 0.0248987 -0.87468 0.471182 0.113674 0.250648 -0.943617 0.216246
--0.214176 -0.942376 0.257012 -0.975106 0.0286796 0.219877 -0.713099 0.693524 0.102537
--0.907426 0.36297 0.211733 -0.70946 0.701444 0.0681402 0.0514998 -0.885796 0.461209
-0.477187 -0.827124 0.296916 -0.717137 0.358569 0.597614 0.403604 -0.861021 0.309429
--0.291659 0.556803 -0.777757 -0.986657 -0.130252 0.0976888 0.69208 0.0768978 -0.717713
--0.666319 -0.0888426 -0.740355 0 0.999989 0.00476185 -0.22439 0.940992 -0.253344
--0.717168 0.649934 -0.251507 -0.514956 0.836804 -0.185956 -0.407553 -0.584159 -0.701897
--0.847143 -0.331942 -0.414927 0.0431467 0.848553 -0.527349 -0.519903 0.852641 -0.0519903
--0.10897 0.796083 -0.595296 0.329238 -0.93284 -0.146328 -0.280591 -0.795009 -0.5378
-0.391983 0.744768 -0.540065 -0.525994 0.713849 -0.462332 -0.187814 -0.77597 -0.602159
-0.557839 0.424072 -0.713427 -0.844915 -0.455553 -0.28034 0.0729597 -0.496126 -0.86518
--0.00704243 0.640861 -0.767625 -0.481616 0.854254 -0.195693 -0.703482 0.572602 -0.420999
--0.484667 -0.274155 -0.830624 0.204732 0.584948 -0.784806 -0.816358 -0.19948 -0.542004
-0.313793 -0.926031 -0.209764 -0.685239 -0.711043 -0.157691 0.803183 -0.274421 -0.528762
-0.877625 0.0706135 -0.474119 -0.798958 -0.510612 -0.317714 0.00539076 0 -0.999985
--0.0771935 -0.439117 -0.895107 0.183726 -0.110869 -0.976705 0.668356 0.200917 -0.716193
-0.604408 -0.304476 -0.736196 -0.869006 -0.025559 -0.494141 0.623928 0.0605303 -0.779134
--0.941095 0.218178 -0.25834 -0.743661 0.40669 -0.530633 -0.294724 -0.854699 -0.427349
--0.873177 0.311768 -0.374649 0.782583 -0.0622195 -0.619429 -0.843976 -0.53427 0.047538
--0.628695 0.603547 -0.490382 0.762248 -0.31208 -0.567083 -0.861042 -0.315841 -0.398561
--0.778741 -0.507254 -0.369128 -0.42219 0.509539 -0.74975 0.172483 0.172483 -0.969793
-0.553028 -0.563979 -0.613259 0.420491 -0.591386 -0.688077 -0.59626 0.59626 -0.537538
-0 -0.143589 -0.989637 0 -0.432897 -0.901444 -0.042924 -0.126906 -0.990986
--0.556175 -0.498639 -0.664852 -0.586204 -0.103807 -0.803486 -0.5199 -0.0879433 -0.849688
--0.313539 0 -0.949575 -0.579962 -0.297416 -0.758411 -0.469937 -0.16366 -0.867396
--0.155191 -0.39592 -0.905076 -0.427715 -0.427715 -0.796316 -0.298438 -0.235307 -0.924968
--0.25542 0 -0.96683 -0.423431 0 -0.905928 -0.132191 0 -0.991224
--0.707368 -0.485599 -0.513638 -0.330467 -0.165233 -0.929241 -0.674422 -0.513411 -0.530626
-0 0.230805 -0.973 -0.0597167 0.17915 -0.982008 -0.586297 -0.377836 -0.716586
--0.172447 -0.172447 -0.969806 0.175069 0 -0.984556 -0.133423 0.222371 -0.965789
-0.643257 0.757345 0.112469 0.665527 0.744119 0.0579688 -0.947659 -0.299019 -0.11194
-0.0212536 0.17503 -0.984334 -0.0969803 0.562486 -0.8211 -0.455376 -0.885453 0.0927618
-0.982315 -0.0605536 0.177175 -0.61987 -0.783887 0.0358197 0.626527 0 -0.7794
-0 -0.195557 -0.980692 -0.498237 0.486937 -0.717393 -0.845802 -0.127289 -0.518089
-0.501584 0 -0.865109 0 -0.0480727 -0.998844 0.247475 0.247475 -0.936756
-0.171035 -0.95851 0.228047 -0.544173 -0.229125 -0.80708 0.521558 0.462619 -0.716911
--0.675914 -0.667248 0.312923 0.52245 -0.8127 0.258 -0.195557 0 -0.980692
--0.984739 -0.0599483 0.163388 0.472562 -0.836072 0.278691 0.411622 -0.886571 0.211088
--0.218638 -0.881923 0.417624 0.694576 -0.694576 0.187425 0.232311 -0.546207 -0.804791
-0.111943 -0.567709 -0.815583 0.655627 0.109967 -0.747034 -0.561904 -0.275844 -0.779855
--0.149572 0.202363 -0.967821 0.0857304 0.0857304 -0.992623 -0.296679 0.941633 0.159089
--0.446721 0.887487 0.113169 0.856361 -0.324379 -0.401775 0.576977 0.0940259 -0.81133
-0.0688846 0.251578 -0.965382 -0.172447 0.172447 -0.969806 0.300108 0.200072 -0.932688
--0.738603 0.281173 -0.612705 0.0425635 -0.998883 0.0205271 0.229846 -0.919382 0.31923
-0.126139 -0.986587 0.103614 0.124193 -0.989536 0.0734473 0.452953 0.0654266 -0.88913
--0.00508037 0 -0.999987 0.538409 0.198361 -0.819004 -0.865946 0.382366 -0.322387
--0.789659 0.0535362 -0.611205 0.93286 -0.237879 -0.270529 0.620645 -0.746713 -0.239207
-0.599293 0.724146 -0.341264 -0.732201 -0.666237 -0.141456 -0.430444 -0.901882 -0.0364397
-0.0901019 -0.95508 0.282319 0.682593 0.0374693 -0.729837 0.815201 0 -0.579178
-0.0259785 -0.929042 -0.36906 -0.71174 0.652429 -0.260312 -0.231655 -0.817109 -0.527892
-0.0174929 -0.552483 -0.833341 0.74628 -0.564577 -0.35259 0.726239 -0.0264488 -0.686933
--0.927635 0.334059 0.167029 -0.0436685 -0.375549 -0.925773 0.219376 -0.383615 -0.897058
--0.425108 0.242417 -0.872076 0.329003 0.310726 -0.891743 0.109489 0 -0.993988
-0.397227 -0.687096 -0.608366 -0.546354 -0.714462 -0.437083 0.583549 0.12799 -0.801928
-0.655027 0.154953 -0.739547 0.817504 0.099876 -0.567197 -0.278014 0.636506 -0.719422
-0.424149 0.678248 -0.600064 -0.635402 -0.394892 -0.66357 -0.390559 -0.386314 -0.835599
-0.739463 0.225398 -0.634343 0.722494 -0.125552 -0.679882 0.804525 -0.496023 -0.326649
-0.545706 -0.36951 -0.752108 0 0.132589 -0.991171 0.605665 0.223876 -0.763577
--0.284537 -0.785047 -0.550218 0.294689 -0.678677 -0.672723 0.149357 0.460874 -0.874807
-0.687954 0 -0.725754 -0.299843 -0.465393 -0.832768 0.598635 -0.603424 -0.526798
-0.731639 -0.529377 -0.429494 0.602229 -0.356157 -0.714473 0.333962 0.305576 -0.89168
--0.242339 0.314525 -0.917794 -0.497679 -0.130162 -0.857539 -0.294744 -0.126319 -0.94719
--0.428243 0.817554 0.384986 0.622071 -0.429014 -0.654962 0.326843 -0.362795 -0.87267
--0.3676 -0.197415 -0.908789 0.822263 -0.369475 -0.432865 -0.35897 0.166963 -0.918294
-0.725959 -0.436415 0.531531 0.798561 -0.293901 0.525284 0 -0.676436 0.736502
--0.604206 0.609241 0.513575 -0.231295 -0.762899 -0.603728 0.449134 -0.691834 -0.56537
--0.0518748 0.10375 -0.99325 0.602678 0.0827511 -0.793682 -0.530196 0.151803 -0.834175
-0.165497 -0.803841 0.571358 -0.444921 -0.289552 0.847469 0.783503 0.383416 0.488995
-0.483077 -0.634039 0.603847 0.163302 0.969816 0.181077 -0.1954 0.98043 0.0239965
--0.389313 0.908397 -0.152481 0.299667 -0.466149 -0.832409 0.137031 -0.236868 -0.961829
-0.601839 -0.0947777 -0.792974 -0.161495 -0.77245 -0.614199 -0.183883 -0.348838 -0.918966
--0.280702 0.573879 -0.769331 -0.487241 0.648067 -0.585325 0.643089 -0.749384 0.157672
-0.565406 -0.824767 -0.00864536 -0.911609 0.104184 -0.397635 -0.891602 -0.253777 -0.375025
-0.517288 -0.660717 -0.543936 0.525293 -0.233464 -0.818267 0.676675 0.0424282 -0.735059
--0.306654 -0.403031 -0.862282 0 -0.278157 -0.960536 0.10493 -0.314791 -0.943343
--0.172439 -0.623969 -0.762186 0.668872 -0.536069 -0.515015 0.726475 0.152053 -0.670159
--0.84123 -0.387913 -0.376637 0.59115 0.698632 -0.403057 0.823398 0.385968 -0.415987
-0.106888 0.956368 -0.271909 0.47685 0.541508 -0.692375 -0.136187 -0.00567446 -0.990667
--0.661598 -0.497522 -0.561035 0 -0.285738 -0.958308 0.843392 -0.526448 -0.107438
-0.274146 -0.609214 -0.744112 -0.468236 -0.717962 -0.515059 0.751858 0.273403 -0.599967
-0.954202 -0.148505 -0.2597 -0.734667 -0.0192657 -0.678154 0.155893 -0.568552 -0.807741
--0.430524 -0.527604 -0.732314 -0.704419 -0.351344 -0.616727 -0.941018 -0.27882 -0.191689
-0.562007 -0.589422 -0.580284 0.556402 -0.525144 -0.643926 0.979045 -0.0559454 -0.195809
--0.916496 -0.212826 -0.338733 -0.910914 -0.179862 -0.371328 0.54976 -0.326371 -0.768925
-0.823957 -0.324067 -0.46484 0.0953891 -0.317964 -0.943292 -0.738019 0.546491 -0.395823
-0.329136 -0.738063 -0.58901 0.495584 -0.650275 -0.575794 -0.760372 -0.230097 -0.607363
-0.972335 -0.152681 0.176788 -0.247391 0.965624 -0.0798036 0.227384 -0.968006 0.106113
-0.901801 -0.332075 0.276552 -0.0711611 -0.947658 0.311257 0.140252 -0.918653 0.369331
--0.621543 -0.779547 0.0774018 0.91459 0.250573 -0.317392 0.804573 -0.378622 -0.457502
-0.671444 -0.400009 -0.623824 0.293508 0.905397 -0.306774 -0.14704 0.974141 -0.171547
--0.769258 -0.415815 0.485118 -0.813039 0.492103 0.31113 -0.745524 0.635176 0.201857
-0.0947376 -0.720748 -0.686692 0.334992 -0.937977 -0.0893311 -0.0170181 -0.991306 0.130472
-0.186891 0.409954 -0.892754 0.298121 0.95278 -0.0577442 -0.564954 0.695328 -0.444237
--0.285975 -0.222425 -0.932065 0.833103 0.484642 0.266575 0.559668 0.822328 0.102707
-0.82239 0.216711 0.526033 -0.859304 -0.394815 -0.325142 0.870448 0.387098 0.304099
-0.326204 -0.820714 0.469062 -0.272914 -0.94649 0.172265 -0.307926 -0.835799 0.454557
--0.377904 -0.920267 0.101474 0.379991 0.923864 0.0456229 0.27047 0.959923 0.0734368
--0.907951 0.36318 0.209104 -0.54294 -0.827151 -0.145045 -0.567032 -0.808855 -0.155656
-0.860864 0.479826 -0.16935 -0.656845 0.749181 -0.0853409 0.339534 0.881557 0.327985
-0.0530097 0.689127 0.722699 -0.67747 0.164435 0.716935 -0.790441 -0.234205 0.565995
-0.0322058 0.955438 -0.29343 -0.590012 0.590012 -0.551156 0.884118 -0.463081 -0.0623758
--0.67414 0.735736 -0.0650186 -0.91007 0.201826 0.361991 -0.414751 0.582894 0.698725
-0.775483 -0.178623 0.605574 0.1426 0.901463 0.408692 -0.895211 0.0354038 0.444234
-0.494864 0.345619 0.797281 0.151667 0.933473 0.325 0.494524 0.450187 0.743491
--0.11886 0.984361 -0.13002 -0.742923 0.309996 -0.593269 -0.826573 -0.275524 -0.490778
--0.713162 -0.665618 -0.219892 0.107999 -0.862893 0.493712 -0.668426 -0.42153 0.612796
-0.732081 0.0170251 0.681005 -0.761813 0.627981 0.158997 -0.60463 0.763136 0.228136
-0.814006 -0.0307172 0.580043 0.886447 0.0448204 0.460654 0.430911 -0.899216 0.0756766
--0.834017 -0.476581 -0.278006 -0.764471 -0.420901 0.488289 0.924827 -0.288031 0.248461
-0.450952 0.742645 0.495097 0.305142 0.933735 0.187154 -0.0974951 0.822038 0.561025
--0.171133 0.677401 0.715431 0.820962 -0.56521 0.0809879 0.790612 -0.611033 0.0396472
--0.853855 0.492772 -0.167656 0.646857 0.757603 -0.0872544 -0.877944 0.231183 0.419248
-0.781429 0.603208 0.159713 0.123034 0.954677 0.271024 -0.602238 0.663367 0.444132
-0.34682 0.829648 0.437492 -0.613503 0.560385 0.556402 -0.930951 -0.131847 0.340508
-0.912091 -0.165588 0.375061 -0.143247 0.962328 0.231093 0.527443 0.704356 0.475065
--0.73662 0.673403 -0.0626066 0.625738 -0.779689 0.0231755 -0.976936 0.0585186 -0.205357
--0.89319 -0.443772 0.0726446 -0.912663 -0.0641022 0.403654 -0.90457 -0.120245 0.409015
--0.965814 -0.207253 0.155725 0.858966 -0.460974 0.222893 0.701885 -0.712257 0.00691512
--0.0340011 -0.827361 -0.560641 -0.77167 -0.338782 -0.538287 -0.920225 -0.319336 -0.226298
--0.732257 -0.679953 -0.0382439 -0.334789 -0.932627 -0.134624 0.981843 0.0730674 -0.175057
-0.983404 0.0459665 -0.175508 0.718093 0.695021 0.0358886 0.456378 0.889457 0.0242122
--0.1093 0.976869 0.183793 0.556377 -0.828232 0.0669081 0.797056 -0.599337 -0.0741447
--0.275749 0.624835 -0.730441 0.548589 -0.822883 -0.148032 -0.300049 -0.862642 -0.40721
--0.0534147 -0.986391 -0.155496 0.823127 0.469235 0.319814 0.476461 0.682057 0.554783
-0.120242 0.901814 0.415057 -0.969943 -0.0365535 0.240573 0.530243 0.845 -0.0694078
-0.963615 0.235028 -0.127307 -0.222518 -0.971662 -0.0797357 0.242703 0.955643 -0.166858
-0.707656 0.647572 0.282617 0.86375 0.462908 0.199128 0.730136 0.380012 0.567884
--0.908267 0.17841 0.378445 0.897266 0.327638 0.295917 0.62797 0.65202 0.424882
--0.969913 -0.13204 -0.204533 0.309728 0.939509 -0.14626 -0.584816 0.811083 -0.0116035
--0.992025 0.114754 0.0521341 -0.201264 0.967781 -0.151305 -0.487205 0.867834 -0.097441
-0.836936 0.531264 -0.131514 0.742367 0.667217 -0.060933 -0.217208 -0.87413 0.434416
-0.306422 -0.94591 0.106581 0.252596 -0.8055 0.536064 0.24317 -0.940582 0.23701
-0.939034 0.195763 -0.282652 -0.749052 0.542011 -0.380979 0.921365 0.165175 -0.351857
-0.740634 -0.384329 -0.551138 -0.363888 -0.907528 -0.209711 0.17328 -0.958524 -0.226288
--0.30323 -0.952143 0.0384092 0.880712 -0.439715 -0.176057 0.661341 -0.740603 -0.118893
-0.101353 -0.994637 0.0206142 0.161383 -0.981749 -0.100616 -0.2495 -0.842061 -0.478208
--0.145196 -0.923357 -0.355428 -0.868831 -0.186722 -0.45855 0.810466 -0.25963 -0.525107
--0.265396 -0.940805 -0.210834 0.648096 -0.363566 -0.669172 0.960941 -0.0105021 -0.276555
--0.946306 -0.226291 0.230862 -0.652514 0.00526221 0.757758 -0.0437809 -0.718007 0.694657
--0.938791 -0.336283 0.0747297 -0.2118 -0.969823 -0.120763 -0.275402 -0.950996 -0.14057
--0.440281 -0.522193 0.730388 -0.718678 0.327717 0.613272 0.672565 -0.325607 0.664558
--0.907898 0.41903 -0.0116397 -0.970987 -0.18132 -0.15591 0.48366 -0.870587 0.0902831
-0.525126 -0.0145868 0.850899 0.749726 -0.646576 0.140888 0.598312 0.444461 0.666691
--0.655326 -0.6746 -0.339799 0.823216 0.128127 0.553081 -0.154807 0.877656 0.453601
--0.895835 0.440452 0.0590113 -0.84036 0.503562 -0.200553 -0.708394 0.702903 -0.0640667
-0.921436 -0.36737 0.126472 0.864675 -0.498321 0.063357 -0.975243 -0.019477 -0.220276
--0.503076 -0.416689 -0.757155 0.674162 -0.732531 -0.0943632 -0.904376 0.222616 -0.364069
-0.868548 -0.388027 -0.308316 -0.747161 0.633011 -0.202603 -0.053242 0.298155 -0.953031
-0.605262 -0.671463 -0.427545 -0.961025 0.187517 -0.203144 0.899104 0.422028 0.116211
-0.801056 0.585719 -0.12346 -0.403295 0.88985 0.213356 -0.565497 0.759382 0.321795
-0.987215 0.0881084 0.13283 -0.949529 0.170702 0.263165 -0.934238 -0.356579 0.00713159
--0.299684 0.789167 0.536101 0.361516 0.893748 0.265558 -0.195447 0.951177 0.23888
-0.833412 -0.507814 0.218061 -0.258731 -0.668066 0.697672 0.698858 -0.624862 0.348059
--0.148604 0.652564 0.743019 0.14157 -0.37752 0.915116 -0.37459 0 0.927191
--0.768366 0.555973 0.317029 0.919919 0.215046 0.327879 -0.990085 0.119177 -0.0743582
-0.950314 -0.266088 0.161553 -0.239335 -0.73077 0.639291 0.260221 -0.785937 0.560881
-0.491809 -0.412485 0.766799 0.378423 0.6775 0.630706 0.380476 0.88647 0.263457
-0.756507 -0.65393 0.0085481 -0.326836 -0.884379 -0.333244 0.708466 0.655496 0.261536
-0.492276 0.868449 0.0588254 0.345989 0.851543 0.393911 0.407102 -0.693581 0.594318
--0.576904 -0.457104 0.676932 0.847669 0.337882 0.409015 0.742929 0.611445 0.272381
-0.700824 -0.712007 -0.0434908 0.475483 0.832095 0.285541 0.658145 0.658145 0.365636
-0.832426 0.0582116 0.55107 0.788202 0.0297435 0.614698 0.651707 0.465797 0.59859
--0.0346193 0.979726 0.19733 -0.147418 0.967433 0.205771 -0.718491 -0.694857 0.030725
--0.938765 0.235545 -0.251475 0.691282 -0.628592 0.356372 0.780483 -0.537356 0.319523
--0.572271 -0.45088 0.684991 -0.841616 0.255035 0.476066 0.463893 0.884295 0.0531544
-0.771709 0.6288 0.0952727 -0.100257 0.989198 0.10694 -0.166482 0.965594 0.199778
-0.387115 0.883912 0.262378 -0.480241 0.865153 -0.144492 -0.626087 0.779017 -0.0338703
--0.202675 0.97863 -0.0347442 -0.282004 0.952066 -0.118506 -0.425091 0.902906 -0.0637087
-0.5488 0.832523 0.0756593 -0.222703 0.960615 -0.166196 0.404422 0.913358 0.0471237
--0.440282 -0.87416 0.204931 0.172043 -0.927122 0.332936 0.582501 -0.701441 0.410699
-0.338416 -0.0273719 0.940598 0.223578 -0.91511 0.33554 0.337478 0.826822 0.449971
-0.951425 -0.214495 0.220867 -0.720844 -0.503891 0.475897 -0.772683 -0.576238 0.266292
-0.157717 -0.97259 -0.17086 -0.847561 0.530647 -0.0073701 0.441633 -0.883266 -0.157482
--0.707635 0.70381 0.0624759 0.566219 -0.724761 0.392579 0.507093 0.169031 0.845154
--0.379071 0.324918 0.866449 -0.934703 0.354203 0.0295169 0.8 0.6 0
--0.968274 -0.0305771 0.248014 0.323587 -0.846305 0.423153 0.923508 -0.382918 0.0225246
--0.945638 0.3199 0.0585897 -0.92389 -0.148236 0.352779 -0.821489 0.410744 0.395532
-0.567814 0.786203 -0.243869 -0.797812 -0.602791 0.0118194 0.663011 0.279608 -0.694432
--0.630759 -0.608627 0.481369 -0.875577 -0.430516 0.219137 0.123613 -0.988903 0.0824086
-0.571771 0.177228 -0.801042 -0.77956 -0.625426 -0.0335932 -0.87093 -0.45754 0.17927
-0.354707 -0.36259 -0.861807 0.030052 -0.957909 -0.285494 -0.839178 0.342522 -0.422444
-0.566257 -0.452559 -0.688871 -0.369468 -0.385142 -0.845671 -0.461181 -0.0272888 -0.886886
--0.407831 0.480728 -0.776257 -0.387238 -0.741126 -0.548433 0.35976 0.299397 -0.883705
-0.0221855 0.192274 -0.98109 -0.167261 0.957948 0.233151 0.0790021 0.974359 0.210672
-0.0416105 0.970912 0.235793 -0.619476 -0.77877 -0.0988212 0.717143 -0.250568 -0.650325
-0.757263 -0.028576 -0.652485 -0.912356 -0.36374 0.187882 -0.0381181 0.0889423 -0.995307
--0.311458 -0.934374 -0.173032 0.817402 0.19659 -0.541486 -0.223864 0.466699 -0.855615
-0.809424 -0.57816 0.102784 0.748834 -0.157649 -0.643735 -0.487377 -0.433224 -0.758143
--0.9674 -0.107489 -0.22931 0.539375 -0.353275 0.764377 0.524331 0.635553 0.566701
--0.666895 -0.611321 0.426072 -0.990641 0.130815 -0.0389483 0.391348 -0.535529 0.748368
--0.157112 -0.843336 -0.513908 -0.912871 -0.365148 0.182574 -0.749074 -0.0995502 -0.654964
-0.322788 0.0370075 -0.945748 -0.263274 0.614305 -0.743852 -0.453511 0.717401 -0.528833
-0.839846 0.311148 -0.444798 -0.965111 -0.161247 -0.206301 -0.735422 0.0232851 -0.677209
--0.862863 0.21461 -0.457613 -0.0959334 0.419003 -0.902903 0.319076 -0.0299134 -0.947257
--0.730122 0.540831 -0.417642 -0.655516 0.460633 -0.598429 -0.76833 -0.18568 -0.61253
--0.851079 -0.499786 -0.160866 -0.676383 -0.697941 -0.235342 0.28543 0.924404 -0.252995
--0.865371 -0.397553 -0.305099 -0.85425 -0.470042 -0.222078 -0.643708 -0.743483 -0.181311
--0.320134 -0.147363 -0.935841 -0.795769 -0.51946 -0.311308 -0.632008 -0.0574552 -0.772829
--0.183694 0.671357 -0.718009 -0.592225 -0.744157 0.309032 -0.0817317 -0.687508 0.721563
-0.143158 -0.823156 0.549472 -0.133221 -0.717342 -0.683866 -0.336195 -0.770448 -0.541648
--0.0824786 -0.412393 -0.907265 -0.813482 -0.171921 -0.5556 -0.777154 -0.16239 -0.607997
-0.107518 -0.295676 0.949219 0.478444 -0.722357 0.499291 0.411476 -0.257172 -0.874386
--0.564649 -0.0996439 -0.819294 0.651038 0.421969 -0.630945 -0.645161 -0.415147 0.641421
--0.109675 -0.250687 0.961836 0.281709 -0.888291 0.362738 -0.155999 -0.189428 -0.969423
-0.293346 -0.258835 -0.9203 0.263598 -0.263598 -0.927918 0.0433038 0.158781 -0.986364
-0.810293 0.23402 -0.53727 -0.0708804 -0.432877 -0.898662 0.142177 -0.277062 -0.950275
-0 0.253012 0.967463 -0.379967 -0.287542 0.879173 -0.660942 -0.710266 -0.242236
--0.00861109 -0.999963 -0.000717591 0.461757 -0.799194 -0.384797 0.388164 -0.659411 -0.643822
--0.75955 -0.379775 -0.528068 -0.502656 -0.677047 -0.537535 0.175132 0.916075 0.360742
-0.283368 0.902466 0.324436 0.715145 -0.552612 -0.428004 0.236102 -0.681105 0.693074
-0.19549 0 0.980706 0 -0.706566 0.707647 0.618815 -0.374817 0.690348
--0.866634 -0.312135 -0.389251 -0.873185 -0.478844 0.0908622 -0.31719 -0.261072 -0.911719
-0.619827 0.216219 -0.754363 0.388103 0.388103 -0.835914 -0.85118 -0.275382 -0.446831
-0.133732 -0.105788 -0.985355 0.441379 0.891117 0.105329 0.533347 -0.478644 -0.697453
-0.399762 -0.261913 0.878403 0.647459 0.00130273 0.762099 -0.587672 0.402092 0.702114
--0.626249 0.0447321 0.778338 0 -0.501806 0.86498 -0.39884 0.16758 -0.901579
-0.835364 0.271903 -0.477741 0 0.423036 -0.906113 0.360268 0.838057 -0.409717
-0.40156 -0.558507 0.725824 -0.179132 -0.569009 0.802584 0.00613572 -0.654477 0.756057
-0 -0.652141 0.758097 0 -0.724005 0.689795 0.311837 -0.623673 0.716791
-0.39968 -0.325454 0.856934 0.150796 0.552918 -0.819477 -0.138478 -0.553913 -0.820978
--0.31691 -0.636168 -0.703462 -0.715076 0.667754 -0.206811 0.343255 -0.899886 0.269038
--0.058261 -0.802942 0.593203 -0.552275 -0.591443 0.587526 -0.359813 -0.768692 0.528817
--0.0479092 -0.910276 0.411221 0.0980957 -0.972334 0.212002 -0.500128 -0.823847 -0.266735
--0.434547 -0.880381 -0.189997 -0.73962 0.325635 -0.589003 -0.274968 0 -0.961453
--0.0337316 -0.464146 -0.885116 0.837203 0.141188 -0.528353 -0.00184239 0.182397 -0.983223
-0.963078 0.266531 0.0379815 -0.880658 -0.470216 -0.0577807 -0.345702 -0.888949 0.300432
-0.496918 0.175992 -0.849764 -0.263281 -0.623355 0.736282 0.405375 -0.585225 0.70227
--0.138413 -0.989816 -0.0332621 -0.156821 -0.374803 -0.913745 0.704014 -0.179153 -0.687218
--0.160456 -0.677765 -0.717558 0.996562 0.0683127 0.0468813 0.801537 -0.0716319 -0.593639
-0.379186 0.315167 -0.869993 -0.1138 -0.710198 -0.694744 0.218208 -0.293741 -0.930646
-0.394224 0.194032 -0.898298 0.167283 0.683469 -0.710553 0 0.760034 -0.649884
--0.0681252 0.346465 -0.935586 -0.30227 -0.0259089 -0.95287 -0.455913 -0.644806 -0.613489
-0.215119 0.225875 -0.950108 0.630857 -0.376284 -0.67855 0.929806 0.170964 -0.325932
--0.779166 0.35014 -0.519905 -0.35576 0 -0.934577 0.355314 0.87052 -0.34051
-0.220674 -0.299486 -0.92823 -0.799715 -0.336722 -0.497066 0.0233819 -0.140291 -0.989834
--0.243373 0.491565 -0.836142 -0.519122 0.849473 -0.0943858 0.491325 0.164189 -0.855361
-0.199089 -0.170648 -0.965009 -0.216983 -0.760268 -0.6123 0.334149 -0.942425 -0.0134376
-0.949603 -0.279794 -0.14131 -0.584431 -0.652191 -0.482791 -0.027351 -0.537903 -0.842563
-0.189589 0.108735 -0.975824 0.740397 0.498254 -0.451171 0.777968 0.563356 -0.278201
-0.597671 -0.605605 -0.525387 0.362821 0.571128 -0.736324 0.922932 -0.229862 -0.308805
-0.385831 -0.90522 -0.178076 -0.602383 -0.761838 -0.238197 0.582575 -0.588123 -0.560998
-0.266404 -0.133202 -0.954613 0.314997 -0.0633957 -0.946973 0.850919 0.33429 -0.4052
--0.987785 -0.104239 -0.115821 0.622746 -0.404558 -0.669717 -0.375952 -0.621059 -0.68771
-0.813313 -0.240297 -0.529886 -0.244476 -0.700173 -0.670812 -0.277144 -0.705624 -0.65214
-0.73243 0.0415295 -0.679574 0.986537 0.0544296 0.154217 0.615961 0.733768 0.286663
-0.616041 0.773443 0.149261 0.70385 -0.0454097 -0.708896 -0.587203 -0.268107 -0.763748
-0.843237 -0.527389 0.103983 -0.866153 0.278655 -0.414886 -0.767205 0.639724 0.0463568
--0.694629 0.7113 0.107436 -0.313249 -0.865523 -0.390827 -0.638247 -0.707328 -0.303856
-0.512049 -0.753581 0.412215 0.0742819 -0.909603 0.408784 -0.433559 0.872504 -0.225307
-0.736309 -0.412988 -0.535994 0.183294 -0.843305 -0.505213 -0.0189262 -0.480949 -0.876544
-0.1776 -0.350125 -0.919712 -0.0818006 -0.96252 -0.258581 -0.219074 -0.955087 -0.199537
--0.527875 -0.842354 -0.10857 0.247274 -0.931592 -0.266443 -0.542872 -0.67582 -0.498556
-0.294744 -0.126319 -0.94719 -0.234806 -0.712455 -0.661267 0.820648 0.562414 -0.101129
-0.191893 0.965237 -0.177465 0.796596 0.411286 0.443034 -0.642803 0.653822 0.39915
--0.732479 0.644874 0.218203 0.916885 0.216487 0.335342 0.678735 0.709587 0.189223
--0.923451 0.383319 0.0174236 0.490758 -0.457144 -0.741739 -0.236099 -0.607113 -0.75873
--0.399497 0.916087 0.0344394 0.949939 -0.0436419 -0.309373 -0.68483 -0.249029 0.68483
-0.352752 0.647048 -0.67594 0.478836 -0.85027 0.218534 -0.74563 0.664583 0.0486281
-0.563337 0.826227 0 0.720216 -0.330099 0.610183 -0.187108 0.982319 -0.00623695
--0.315064 0.933941 -0.168785 0.245169 -0.964484 0.0982987 0.119944 -0.420374 -0.899388
-0 -0.589777 -0.807566 0 -0.699193 -0.714933 -0.378538 -0.614196 -0.692439
-0.965134 0.23815 0.10863 0.971272 0.129503 -0.19965 -0.111979 0.993081 -0.0353619
--0.886187 -0.158973 0.435201 -0.937662 0.317595 0.141153 -0.866843 -0.298306 0.399496
--0.877954 0.45548 0.147426 0.90494 -0.397534 0.151822 -0.999671 0 -0.0256326
--0.271329 -0.407547 -0.871944 0.245978 -0.70176 -0.668601 0.155893 -0.568552 -0.807741
--0.557396 -0.405064 -0.72473 0.390873 0.870007 -0.30051 0.811941 -0.582687 -0.0350249
--0.298246 -0.898246 0.322807 0.649004 -0.7604 0.0242166 -0.68699 -0.610088 0.394763
-0.452039 -0.880077 0.145346 -0.802921 -0.00613586 0.596055 -0.964678 0.15152 -0.215495
-0.0744809 -0.9757 0.206064 -0.356966 -0.474504 0.804625 -0.188334 -0.867437 -0.460525
-0.719104 -0.563221 0.407028 -0.982481 -0.104459 -0.154336 0.242026 -0.892469 0.380686
--0.564821 -0.800404 0.200825 0.627277 -0.466811 -0.623387 0.637568 0 -0.770394
--0.142326 0.906669 -0.397107 0.159465 0.955366 -0.248689 -0.76274 -0.290672 -0.577701
-0.74587 0.617038 -0.250883 -0.81045 -0.479654 -0.336309 0.402746 -0.684668 0.607475
-0.658069 -0.731188 -0.17975 0.159197 0.987019 -0.0212262 -0.608463 0.571842 0.550245
-0.81123 0.504278 0.295989 -0.931872 -0.337191 0.133854 0.361893 0.932219 0.000763488
--0.760264 0.410953 -0.503107 -0.299494 0.861957 0.409064 0.258938 0.490132 0.832299
--0.601025 0.758216 0.252739 -0.60909 0.673264 0.419195 0.330928 0.931923 0.148347
-0.370937 0.928658 4.67317e-018 -0.737688 -0.436198 0.515313 -0.717518 -0.0326145 0.695776
--0.411705 0.799192 -0.437941 -0.832317 -0.392603 -0.391294 0.807314 -0.438668 0.394733
--0.167761 -0.0524254 0.984433 0.883076 0.0169618 0.468924 0.398877 0.656771 0.63996
--0.550062 0.741453 0.38429 0.269297 0.96283 -0.0209044 -0.780604 -0.483975 0.395506
--0.406482 -0.269789 0.872918 0.439425 -0.0298928 0.897782 0.20025 0.810206 0.550878
-0.71028 0.325003 0.6244 0.163913 0.980285 0.11034 0.706998 -0.255723 0.659363
--0.681199 0.618602 0.391536 -0.0740353 0.329794 0.941146 -0.43931 0.761009 0.47736
--0.435495 0.899894 0.0231236 0.805272 0.368949 -0.464127 -0.0156035 0.915408 -0.402225
-0.781356 -0.612276 0.120833 0.814023 -0.260067 0.519357 0.473539 0.796306 0.376374
-0.298136 0.951485 0.076104 -0.445801 -0.655864 0.609183 -0.273077 -0.109231 0.955771
-0.314567 -0.56075 0.765903 -0.202444 0.91642 0.345239 -0.145551 0.836917 0.527622
-0.345219 -0.455689 0.82047 0.109863 -0.576781 0.809477 -0.291199 0 0.956663
--0.689988 0.605675 0.396327 -0.779207 0.611971 -0.135381 -0.947068 0 -0.321033
-0.905529 -0.405661 -0.124326 -0.957779 0.191881 -0.214105 0.570971 0.401648 0.71601
--0.609188 -0.793025 -0.00120155 0.22393 -0.453529 0.862651 -0.298246 -0.561404 0.77193
--0.016947 -0.995634 0.091796 0.114627 -0.984316 -0.134102 0.76324 0.626272 0.158896
--0.780768 -0.0803318 0.619635 -0.0273474 -0.683685 0.729264 0.852852 0.497026 0.160027
-0.764328 0.60805 0.214659 -0.785482 0.607238 -0.119501 -0.798365 -0.10563 -0.592837
-0.424906 -0.465741 0.776235 0.275393 -0.768981 0.576912 -0.912551 0.323436 -0.250278
--0.691563 -0.720303 -0.053888 0.814957 0.568197 0.114 0.938593 -0.152877 0.309309
--0.0306653 0.967137 0.252399 0 0.999012 0.0444406 -0.122325 0.960364 0.250475
--0.575306 -0.815582 0.0620429 0.542611 -0.663519 0.515088 -0.614936 0.786501 0.0571884
-0.309303 0.662791 0.681938 0.453619 -0.857548 -0.242571 0.325035 -0.787823 -0.523152
--0.36419 -0.582704 -0.726513 -0.753345 0.120135 -0.646559 -0.0994293 -0.867548 0.487313
-0.192513 -0.941751 -0.275761 -0.768165 0.584621 -0.26104 -0.515661 0.515661 -0.684242
--0.632944 0.637947 0.438641 -0.568495 0.59692 0.566127 -0.648077 0.761306 0.0202524
-0.159836 -0.82674 -0.539402 -0.908765 0.024747 -0.416574 0.145153 -0.79507 -0.588892
--0.802954 -0.370481 -0.466914 -0.734038 -0.250939 0.631045 -0.621609 0.359879 0.695766
--0.632406 -0.213986 0.744494 0.182029 0.923914 0.336525 0.799461 0.572663 -0.181438
-0.862405 -0.311735 0.398847 -0.388229 0.915205 0.108064 -0.31451 0.904216 -0.288925
--0.371498 -0.894791 0.247665 0.204669 0.96003 0.190926 -0.483809 0.743171 0.462196
-0.469073 0.835769 -0.285415 0.993743 -0.106441 -0.0338403 0.553575 0.609784 0.567202
-0.544186 0.493953 0.678139 -0.369926 0.908427 -0.194719 -0.441629 0.612082 -0.655987
-0.949654 0.260179 -0.174537 0.626501 -0.750153 -0.211582 -0.0895616 -0.993198 -0.0744118
--0.689787 0.338757 0.639874 -0.765414 -0.634917 -0.104983 0.668823 0.412376 -0.618564
--0.238575 0.865341 -0.440758 0.758853 -0.457257 0.463743 0.778364 -0.333329 0.532016
--0.474954 -0.633272 -0.611052 -0.785467 0.499843 -0.364964 0.0092984 -0.920542 -0.390533
--0.527143 -0.811955 0.250699 0.858022 -0.269183 -0.437423 -0.486986 0.872854 0.031162
--0.660371 -0.609574 -0.438554 -0.678026 -0.620321 -0.394313 -0.5705 0.801753 0.178105
-0.977199 0.068692 -0.200906 0.903148 -0.401399 -0.152326 -0.701963 0.447823 0.553808
--0.567391 0.769922 0.292039 -0.532566 0.790644 0.302086 0.649099 -0.74896 -0.133149
--0.538312 -0.820533 -0.192213 0.472901 -0.858963 0.196334 0.599272 -0.414755 0.684727
--0.0792451 -0.871696 -0.483598 0.136622 -0.914773 -0.380165 -0.835916 0.0272952 -0.548179
-0.789339 0.592004 0.162715 0.638063 0.749724 0.175467 0.172341 0.982346 -0.0727664
--0.449201 -0.711235 0.540705 0.119806 -0.907281 -0.403097 0.505122 -0.842952 -0.185157
--0.675275 -0.369933 -0.638086 -0.253837 -0.930737 0.263239 0.313045 -0.922659 0.225173
--0.515346 -0.804469 -0.295377 -0.0862739 0.901083 0.424979 0.724233 0.485998 0.489175
-0.257861 0.759646 0.597031 0.932992 0.115541 0.340845 0.215433 -0.0615522 0.974577
--0.360523 0.733178 0.576605 -0.246761 0.856111 0.454074 -0.418989 0.80354 0.422815
-0.40057 0.35215 0.845893 -0.927404 0.345937 0.1423 -0.343669 -0.862136 0.372308
--0.351982 -0.854814 0.381314 -0.286761 -0.742204 0.605724 -0.469965 -0.724208 0.504634
--0.533947 -0.158207 0.830585 -0.0396385 -0.87771 0.47755 0.486597 0.71118 0.507392
--0.78616 0.54793 0.285876 0.749396 0.659043 -0.0637784 -0.843981 0.279303 0.457915
-0.0431624 0.156464 0.98674 0.917384 0.352563 -0.184676 0.0663639 0.859781 0.506332
-0.982786 -0.133659 0.127544 0.330211 0.749706 0.573499 0.407645 0.733761 0.543526
--0.325328 0.325328 0.887875 0.691598 0.296399 -0.658665 -0.0286735 0.93189 0.361605
-0.811029 0.575569 0.104649 -0.835007 0.544827 0.0769864 -0.605674 0.795532 -0.0169357
-0.526432 -0.723844 -0.446005 -0.858721 0.511499 0.0311131 0.95516 -0.294414 -0.0314641
-0.654318 -0.752291 -0.0769786 -0.184002 0.950676 0.249717 -0.766319 0.484996 0.421348
-0.814556 -0.30927 0.490766 0.747596 -0.142399 0.648708 0.150572 0.983936 0.0959089
--0.707383 0.697349 -0.115389 -0.0524396 -0.830294 0.554853 -0.422703 -0.329105 0.8444
--0.0389351 0.49591 0.867501 -0.367122 -0.453782 0.811975 -0.39595 -0.444575 0.803478
-0.325111 -0.0237886 0.945377 -0.222089 0.888354 0.401875 -0.013383 0.843126 0.537549
-0.059459 0.959272 0.276154 0.465452 -0.717806 0.517792 0.500189 -0.180068 0.846987
--0.137309 0.52635 0.839108 -0.337721 0.621407 0.706963 -0.0715918 0.8342 0.546795
-0.437739 0.835922 0.331087 -0.313847 0.936785 0.154704 -0.316154 0.839023 0.442818
-0.826227 0.338002 0.450669 -0.363858 0.909645 -0.200385 0.509167 0.737621 0.443468
--0.889945 -0.0778334 -0.449378 -0.639379 0.715837 -0.280664 0.0616832 0.953938 -0.293593
-0.916946 -0.16374 -0.363867 0.805817 0.351409 -0.476624 -0.421712 0.822072 -0.382566
-0.659112 0.483905 -0.57568 0.0866908 0.99413 0.0647366 -0.620591 0.663146 -0.418456
-0.596674 0.769434 0.227927 -0.306038 -0.889423 -0.339511 -0.198727 -0.817677 -0.540288
--0.16199 0.241365 -0.956819 -0.0259789 0.777923 -0.627823 0.128085 0.577638 -0.806182
-0.241196 -0.952135 0.187785 0.615898 -0.784377 0.0736399 0.490558 -0.865848 -0.0982902
-0.397915 -0.862814 0.311793 -0.076443 0.0955537 -0.992485 0.344402 -0.593367 0.727532
-0.304721 0.557874 -0.77196 0.34759 -0.385168 0.854884 0.350881 -0.818723 0.454504
-0.719072 0.694651 0.0198988 -0.409496 0.834609 0.368431 0.669983 0.736982 -0.0893311
-0.771905 0.500695 -0.391748 0.851906 0.377427 -0.363049 -0.718531 0.695165 -0.0214196
--0.673618 0.721355 0.16089 -0.340565 0.936554 -0.0829582 -0.703328 0.708697 -0.0554788
--0.62385 0.779813 0.0519875 0.904023 -0.420476 0.0770872 -0.274518 -0.877431 -0.39339
-0.664087 -0.193795 -0.722102 -0.277649 -0.771865 -0.571957 -0.855761 0.403953 0.323256
--0.980981 -0.161503 0.107669 -0.329698 -0.941995 -0.0627997 -0.318638 -0.88094 -0.349877
--0.913812 0 -0.406138 -0.843795 0.281265 -0.457056 -0.809858 -0.0449921 -0.584898
-0.642086 -0.713429 -0.280615 -0.677066 -0.112844 -0.727219 -0.479839 -0.221464 -0.848945
--0.593281 -0.741602 -0.313121 -0.810737 -0.585093 -0.0192656 0.700229 -0.0479288 -0.712308
-0.868324 0.183022 -0.460996 -0.990763 0.0176472 0.134455 -0.989301 -0.058887 0.133477
--0.596471 -0.796965 -0.0952348 0.0651251 -0.716376 -0.694668 0.432176 -0.85327 -0.291811
--0.16173 -0.549883 -0.819434 -0.808247 -0.153567 -0.568467 -0.739123 -0.558113 -0.377104
--0.00482716 -0.391 -0.920378 0.751728 0.381391 -0.538001 -0.782525 0.595786 0.180811
--0.0433646 0.520375 -0.852836 -0.72194 -0.469261 -0.508524 0.8223 0.441605 -0.358898
--0.558705 -0.649001 0.516379 -0.122262 -0.217176 -0.968445 0.771176 0.396563 -0.498021
--0.485481 -0.729729 0.48146 -0.739498 -0.372247 -0.560869 -0.753035 -0.637183 0.164123
--0.384129 -0.85523 0.34789 -0.408185 -0.910361 0.0680309 -0.890682 -0.435701 -0.129811
--0.417446 -0.834891 0.358742 0.569232 0.182244 -0.801724 0.0217289 0.999528 -0.0217289
-0.293995 0.930985 0.216413 0.428122 0.887267 -0.171662 -0.571268 0.736852 -0.361527
-0.899559 0.311847 0.30585 0.779239 0.618808 -0.0993148 -0.939353 0.139904 -0.313118
-0.797465 -0.194225 0.57125 -0.280294 -0.779216 0.560587 -0.90969 -0.414222 -0.0297458
--0.962264 -0.226415 -0.150943 0.418821 -0.732937 0.536091 -0.672912 -0.716482 0.183962
--0.159153 -0.925074 0.344831 -0.363915 0.166424 0.916444 -0.284834 0.575146 0.766861
--0.922282 0.372087 0.104631 0.922211 -0.269318 0.277479 0.807698 -0.0695976 -0.585474
--0.481251 -0.704689 0.521355 -0.756467 -0.550158 0.353673 -0.442581 -0.785225 0.433063
--0.539279 -0.41483 0.732867 0.747241 -0.314455 -0.585448 0.842745 -0.256488 -0.473281
--0.677798 -0.551429 0.48633 0.0859382 -0.880866 0.465499 -0.52058 -0.77123 0.366334
--0.0380571 -0.938742 0.342514 0.713643 -0.198685 -0.671743 -0.350684 -0.769412 0.533878
--0.138461 -0.860866 0.48963 -0.592205 -0.572016 0.56753 0.298066 0.938909 -0.172066
-0.292737 0.360292 -0.885717 -0.609509 -0.0156955 -0.792624 -0.975401 -0.220289 -0.00809461
-0.226415 -0.509434 -0.830189 -0.63785 -0.494817 0.590172 0.277409 -0.569419 0.773826
-0.681484 -0.453204 0.574618 -0.446719 0.824045 -0.348412 0.51393 -0.765361 0.387425
--0.84761 -0.081501 0.524323 0.783492 0.61996 0.042307 -0.827831 -0.477595 -0.294276
--0.441068 -0.866097 0.235236 -0.551845 0 0.833947 0.175069 0 0.984556
-0 -0.454739 0.890625 0.17378 -0.568735 0.803953 -0.493062 -0.571798 0.655696
-0.940981 0.209107 0.266136 0.451165 -0.892154 0.0226148 -0.892489 -0.435089 0.118999
-0 -0.195557 0.980692 0.751783 0.573536 0.325388 0.752332 0.596134 0.280393
-0.197539 0.395078 0.897157 -0.561401 -0.800219 0.210897 -0.246252 -0.969016 -0.0191884
-0.809813 0.524227 0.263417 0.910246 0.379269 0.166156 -0.759757 0.291306 0.5813
--0.172447 -0.172447 0.969806 -0.196671 -0.763545 0.615078 0.959401 0.266693 0.0917839
-0.4073 -0.492154 0.769345 0.80829 0.11547 0.57735 -0.990492 -0.137568 0
--0.281662 -0.537523 0.794818 -0.280577 -0.542448 0.79185 0.121636 -0.429782 0.894702
-0.132161 0.0213975 0.990997 -0.507118 -0.507118 0.696895 0.0118686 0.999929 0.00098905
--0.0506589 -0.905106 0.422158 0.932648 0.185624 0.309373 -0.673277 -0.0968744 0.733016
-0.945484 0.297152 0.133268 0.919568 0.33984 0.197241 -0.868611 -0.38537 -0.311456
-0.368731 -0.538557 -0.757624 -0.0650865 0.0735761 -0.995163 0.337086 0.204659 -0.91896
-0.314574 -0.340888 -0.885911 -0.876715 0.23123 0.421787 -0.0176222 -0.418527 0.908033
--0.135326 -0.582698 0.801342 0.540635 -0.138302 0.829811 -0.499233 0.0274447 0.866033
--0.159867 -0.188933 0.968889 0.947565 0.0485338 0.315855 -0.782687 -0.538732 0.311719
--0.904768 0.392635 0.165021 0.363733 0.544511 -0.755781 0.0826539 0.870818 -0.484608
--0.0118038 0.755442 -0.65511 0.385896 -0.0110256 -0.922476 0.569415 -0.251897 0.782505
-0.0355019 -0.443773 0.895436 -0.180905 -0.671932 0.718179 0.787789 -0.342626 0.511855
-0.656553 -0.632645 0.410729 -0.982679 -0.0289023 0.183048 0.56552 0.557749 -0.607538
-0.489065 0.619483 -0.614049 -0.449277 -0.587709 0.672866 -0.210012 -0.926893 0.31107
-0.562404 0.778392 0.278941 0.605463 0.762982 0.226433 -0.0221856 0.321691 0.946585
--0.27345 0.626657 0.729744 -0.143918 0.949248 0.279671 0.882628 -0.233014 -0.408256
-0.583178 -0.479771 -0.655532 -0.0129257 -0.843399 -0.537133 0.313224 -0.792495 -0.523299
-0.137234 -0.772338 -0.620211 0.129915 -0.75587 -0.641702 0.529696 -0.815144 0.23444
--0.376512 -0.909517 0.176119 0.867327 -0.412509 0.278532 0.433694 -0.501216 0.748794
-0.882248 0.0577171 0.467234 0 -0.689184 0.724587 0.620613 -0.297554 0.725466
-0.673255 0.290017 0.68016 0.684599 0.489865 0.539775 0.648062 -0.539542 -0.537504
-0.024134 -0.877121 -0.479664 -0.377302 -0.747617 -0.546545 -0.405857 -0.789166 -0.460973
--0.270585 -0.947047 -0.172874 -0.309803 -0.727292 -0.612428 -0.370652 -0.833377 0.409999
-0.449384 -0.755973 -0.475983 -0.0992201 -0.988232 -0.116418 0.163172 -0.979035 0.121923
-0.965393 0.0546449 0.25501 0.955532 -0.241761 0.168849 0.268769 0.761512 0.589799
--0.717536 0.694877 -0.0478357 -0.878072 -0.435326 0.1987 -0.918316 -0.395168 0.0232011
--0.201291 0.978272 0.0496517 0.217787 -0.745062 -0.630437 0.247182 -0.72645 -0.641226
--0.0932922 -0.713411 -0.694508 -0.124591 -0.662302 -0.738805 -0.126111 -0.693611 -0.709225
--0.819069 0.565132 -0.0987529 -0.93673 0.326121 -0.12721 0.80039 -0.0188981 0.599181
-0.773185 -0.036082 0.633153 -0.974482 -0.214048 0.0675941 -0.118932 -0.793781 -0.596462
-0.660087 0.660087 0.358566 -0.683426 0.729604 0.024628 0.825296 0.293417 -0.482486
-0.400152 0.639933 -0.656022 -0.330778 0.873827 -0.356389 0.728524 -0.414529 0.54536
--0.993146 0.0522708 -0.104542 0.42005 -0.725105 0.545692 0.53976 -0.725303 0.42731
-0.480591 -0.756341 0.443825 -0.920498 0.114466 -0.373605 -0.37285 0.915915 -0.1486
-0 0.80975 -0.586775 0.279475 0.784908 -0.553003 0.0700335 0.964906 -0.253084
--0.229426 0.964466 -0.131031 0.0737118 -0.986604 -0.145533 0.840993 -0.434513 -0.322381
-0.52657 -0.182274 -0.830361 0.312081 -0.92946 -0.196747 -0.334275 -0.315173 -0.888215
-0.27134 0.943793 -0.188759 -0.401074 0.860683 -0.313632 -0.378267 0.342242 0.860107
-0.976251 -0.205526 -0.0685088 -0.122878 0.988872 0.0838688 -0.872789 0.417421 0.252982
-0.976102 0.0377658 0.214006 0.651681 0.75762 -0.0363829 0.364101 -0.7756 0.51563
-0.742195 -0.656862 0.13296 -0.871366 -0.309023 0.381085 0.146872 -0.78273 0.604783
-0.877004 -0.372166 0.303901 0.957069 0.0118614 0.289617 0.558115 -0.796969 0.230971
--0.82509 -0.437877 0.357057 -0.399533 -0.528 0.749392 -0.730739 0.540921 0.416443
-0 0.845299 0.534293 0.134867 0.990863 0.000917466 0.606041 0.795429 0.00252517
-0.836213 0.470829 -0.28119 -0.445512 0.860086 0.248538 0.423396 -0.729626 0.537012
--0.305044 -0.934501 0.183457 0.806679 0.590989 0.000539224 0.342321 -0.222509 0.912856
-0.241416 0.64858 0.721846 0.200802 0.312538 0.928439 -0.535649 -0.204807 0.819228
--0.982708 0.1121 0.147371 -0.0159597 -0.877784 0.478791 0.67601 -0.720258 -0.155687
--0.49998 0.862466 0.0785683 -0.533904 0.782134 0.321267 -0.826654 0.296921 0.477997
-0.226547 -0.841459 0.490534 -0.495535 -0.31297 0.810244 -0.299892 -0.886638 0.352048
-0.54181 -0.725035 0.425165 0.245359 -0.500156 0.830447 0.363325 0.835104 -0.413033
--0.590006 0.548805 -0.592204 -0.116529 0.169081 0.978689 -0.706242 0.684456 0.180948
--0.309995 0.476063 -0.822962 0.95009 -0.19489 -0.243613 0.475945 0.655064 -0.586828
-0.728125 -0.630945 0.267849 -0.0407481 0.890951 0.452267 -0.582969 0.80907 0.0745233
--0.0549774 0.923621 -0.379344 -0.513722 0.834798 -0.197997 -0.557588 0.811228 -0.176081
-0.765321 0.26353 0.587227 -0.675956 0.731082 -0.0927525 -0.58211 0.40905 0.702727
--0.594237 0.801932 -0.0615391 0.723883 -0.685921 -0.0742002 -0.896904 0.294657 -0.329758
--0.638909 0.729387 -0.244521 -0.666179 0.460368 -0.586743 -0.678242 0.413304 -0.607592
-0.960313 0.122187 0.250738 0.913422 0.404416 0.0459035 -0.4968 0.867295 0.0314359
-0.876056 0.259828 -0.40622 -0.341332 0.898593 -0.275723 -0.872526 -0.119972 -0.473609
-0.584025 0.805516 0.100298 0.222134 -0.456384 0.861609 -0.311531 -0.914709 -0.2574
-0 -0.983582 -0.180463 -0.174272 -0.894402 -0.411915 0.0946618 0.636816 0.765183
--0.989303 -0.0594693 -0.133204 -0.20138 -0.47599 0.856084 0.892971 0.140995 0.427462
-0.222449 0.826241 0.517535 0.530197 0.745678 -0.403554 0.774297 0.526993 -0.350347
-0.494518 -0.85912 -0.131778 0.620653 -0.776792 -0.106695 -0.426685 -0.694779 -0.578983
-0.764098 0.363617 0.532858 0.361256 -0.794763 0.487695 -0.622033 -0.551448 0.55586
-0.959018 0 -0.283346 -0.194219 -0.920341 0.339488 0.208337 -0.876339 0.434311
--0.928985 0.364538 0.0640229 -0.707637 0.435469 0.556432 0.714521 0.136193 0.68623
-0.608432 -0.0612033 0.791242 -0.74959 -0.617309 -0.23884 -0.597472 -0.792565 -0.121933
--0.501535 -0.844691 -0.186976 0.84596 -0.484014 0.223791 -0.862354 -0.505442 -0.029558
--0.879617 -0.473284 -0.0477132 0.92322 0.0869844 -0.374296 0.78666 -0.248249 -0.565277
--0.44754 -0.888317 0.102961 -0.342413 -0.924516 -0.167402 -0.0276609 0.874084 -0.484987
--0.325084 0.945244 -0.0288963 0.774788 -0.615273 0.145408 -0.424469 -0.859505 0.28474
-0.873828 0.160835 -0.458865 0.630084 -0.422443 -0.651564 0.195384 -0.784541 -0.58849
--0.508922 0.675479 0.533597 -0.0545349 0.974688 0.216818 -0.177901 0.899011 0.400164
--0.476704 0.727146 0.493976 -0.908257 -0.416233 0.0426587 0.751682 -0.652623 0.0951742
--0.435742 -0.86247 0.257439 0.507963 -0.736138 -0.447297 0.0781703 -0.906776 -0.414303
--0.335164 -0.918402 -0.210247 -0.596191 -0.122268 0.793478 -0.649051 0.102482 0.75381
-0.888894 0.165376 0.427221 -0.918033 -0.393443 -0.0491803 0.527496 0.805815 0.269091
--0.929075 0.360048 0.0847665 -0.633245 -0.697642 0.335107 -0.17146 -0.925188 0.338568
--0.377802 -0.763377 0.523947 -0.278163 0.960533 0.00144877 0.636431 -0.383329 0.669338
-0.354603 -0.839506 0.411687 -0.952117 0.07129 0.297306 0.0171572 0.998693 0.0481355
-0 -0.974802 -0.22307 0.271945 -0.960733 -0.055124 -0.334501 -0.836773 0.433497
-0.599162 0.800444 -0.0171635 0.212221 -0.88361 0.417367 0.677376 -0.693698 0.244835
-0.0219415 -0.727446 0.685814 -0.269743 0.351839 0.896352 -0.34553 0.8828 0.318234
--0.0328036 0.880377 0.47314 -0.689033 0.714695 -0.120185 0.605622 -0.175543 0.776149
-0.535361 0.414935 0.735675 -0.885942 0.3648 -0.286406 -0.277827 0.845221 -0.456524
--0.169461 0.782128 -0.599632 0.584915 -0.779887 -0.222825 0.302739 -0.930641 -0.205563
-0.185381 -0.975458 0.118806 0.976954 -0.144377 0.157211 0.631576 -0.672323 0.386125
--0.86472 -0.0238269 -0.50169 -0.64589 -0.25329 -0.720188 -0.557171 0.78004 0.284777
--0.708727 0.590606 0.385863 -0.848634 -0.494632 0.187508 -0.969816 0.231324 -0.0771081
-0.194631 0.915417 -0.352322 -0.327382 0.944849 -0.00897883 0.605589 -0.789899 0.0965432
-0.629575 -0.198813 0.751072 -0.554213 -0.810811 0.188235 -0.943854 0.328847 0.0316199
-0.365393 -0.917264 0.158477 0.149393 -0.953978 -0.260014 -0.0996518 -0.866971 -0.488294
-0.950321 0.10182 0.294147 -0.357663 -0.925321 0.125933 0.733973 0.53509 -0.418286
-0.137962 0.984228 -0.110729 0.0876307 0.820962 0.564219 -0.561393 0.773908 0.293093
-0 -0.914429 0.404747 0 -0.62788 0.77831 0.495251 -0.839773 0.222504
--0.757878 0.611192 0.228178 0.891005 -0.18472 0.414716 0.665947 -0.745266 -0.0330495
-0.63056 -0.677268 -0.379081 -0.0272008 -0.994528 -0.100869 0.815211 -0.490259 0.308346
--0.553932 0.658963 0.50885 -0.667498 -0.451267 -0.592287 0.84932 -0.116523 0.514857
--0.91859 0.380106 0.108225 -0.871966 0.38644 0.300564 0.768589 -0.638718 0.0361996
-0.619813 0.215587 0.754555 -0.34832 0.34832 0.870257 0 0.863779 -0.503871
--0.889261 -0.370525 -0.26819 0.879936 -0.288775 0.377255 -0.163912 0.861059 0.481363
-0.802858 -0.539062 0.254621 0.810407 -0.476505 0.340858 -0.870374 0.486587 -0.0753867
--0.746696 0.662248 0.0622247 -0.460255 -0.887635 -0.0164377 -0.127855 -0.990877 -0.0426184
--0.76004 0.649094 -0.0318809 0.763761 -0.609075 -0.213767 0.33931 0.0657978 0.938371
-0.995588 -0.060645 0.0715948 -0.249263 0.926948 -0.280421 -0.60159 0.767546 -0.221275
-0.749145 0.649551 0.129868 -0.317376 0.372175 0.872214 0.563123 -0.412957 0.715792
--0.501663 0.0876942 0.860607 0.907507 0.380871 0.177113 0.947121 0.282254 0.152627
--0.154801 -0.942629 -0.295781 -0.95041 -0.256197 -0.176308 0.892504 -0.0263146 0.450272
--0.0551289 0.98707 0.150511 -0.670795 0.585071 0.455769 -0.92149 0.356335 0.154539
-0.67505 0.319615 0.664947 0.838591 0.268349 0.474083 -0.525761 -0.467343 0.710751
-0.819567 -0.402838 0.407469 -0.579188 -0.780295 -0.235966 0.778029 -0.602345 -0.178473
--0.389986 -0.91729 0.0805604 -0.365704 -0.683289 -0.631962 0.744031 -0.644087 0.177679
-0 -0.993263 0.115881 0.112211 -0.94756 0.29923 0.879996 0.118177 0.460046
-0.693532 -0.704541 0.150449 -0.725772 -0.652632 0.217544 -0.815089 -0.565128 0.127516
--0.168956 -0.92926 0.328526 0.816034 0.1515 0.557796 -0.935008 -0.189282 0.299887
-0.575748 0.663926 -0.477197 -0.710934 0.680731 -0.176572 0.946574 0.153445 0.28364
-0.446711 0.893423 0.0473785 -0.685454 0.697804 -0.2079 0.604175 -0.648929 0.462455
-0.847875 -0.529405 0.0289518 0.86957 -0.48236 -0.105723 -0.817904 -0.505664 0.274477
-0.655328 0.602811 0.455153 -0.665534 0.543604 0.511428 0.719596 0.474341 0.507131
--0.725722 0.302971 0.617686 -0.974869 0.141911 0.171733 0.815892 -0.565685 -0.119664
--0.642664 -0.731708 0.227126 0.92752 -0.209047 0.30985 -0.608522 0.0747307 0.790011
--0.394443 0.661272 0.63807 -0.295373 0.945194 0.139154 -0.78874 0.613802 0.0337069
--0.385115 0.135504 -0.912866 -0.221351 0.544863 -0.808782 -0.0461717 0.998767 0.0182257
-0.416136 0.808493 0.416136 -0.826732 0.300275 0.475761 -0.963011 -0.249362 0.10212
-0.886783 -0.446581 0.119088 0.854321 -0.0678032 0.515305 0.224021 0.950944 0.213353
-0.46955 0.812992 0.344336 0.641377 0.408994 0.649123 -0.8007 0.402122 0.444046
-0.902565 0.357773 -0.239532 -0.307914 -0.902323 -0.301667 -0.241942 -0.957545 -0.156751
-0.958194 -0.283909 -0.0354887 -0.498761 -0.546262 0.672931 0.166099 -0.861342 0.480105
--0.0416921 -0.481354 0.875534 -0.920533 0.38377 -0.0730684 0.612958 -0.290349 -0.734833
--0.343579 -0.343579 -0.874017 -0.511089 -0.584102 -0.630565 -0.609956 -0.43874 -0.659894
-0.603958 -0.795944 -0.0413304 -0.917812 -0.12132 0.378026 0.931316 -0.334376 -0.144373
-0.674781 0.687675 -0.267907 0.537652 0.752712 -0.379941 -0.560346 0.828218 -0.00820018
-0.586744 0.757878 -0.285223 -0.714804 -0.0238268 -0.698919 0.790435 -0.59912 0.127544
--0.562124 0.811274 0.160782 0.154868 -0.542037 0.825961 0.668151 0.70991 0.222717
--0.240452 0.951187 -0.193456 -0.429097 0.894287 0.126991 -0.335591 -0.929912 -0.150475
--0.210184 0.97459 -0.0774362 -0.760155 -0.305761 -0.573301 0.479909 -0.87477 0.0668227
--0.721273 0.656607 -0.220527 -0.357147 0.664399 0.656521 0.28204 0.378991 0.881374
-0.702879 -0.711184 -0.0133378 0.713275 0.394178 0.579536 -0.685865 0.727432 -0.0207838
--0.568874 0.733732 -0.37151 0.371274 0.85945 0.351429 -0.715244 0.694207 -0.0806402
--0.175969 0.907842 -0.380601 0.698151 -0.713006 -0.0648637 0.389244 0.758469 -0.522699
-0.953043 -0.0914082 -0.28871 0.636914 0.756475 0.148613 0.00965772 0.950078 -0.311864
--0.274688 0.864996 -0.419915 -0.161561 0.98637 0.0311784 0.659398 -0.67938 -0.321928
-0.535644 -0.84238 0.0590073 -0.347294 -0.88035 -0.323064 -0.607834 -0.487768 -0.626594
--0.154945 -0.985868 0.0636907 -0.615443 -0.553899 -0.560737 -0.464606 -0.872205 -0.152968
-0.359253 0.146086 -0.921735 0.0444477 0.112427 -0.992665 -0.355045 -0.0730133 -0.931994
-0.0674104 0.269642 -0.960598 -0.191121 0.210233 -0.958788 -0.228765 0.591634 -0.773069
-0.00978398 0.743583 -0.668572 0.437264 0.896952 -0.0654027 0.415123 0.909468 -0.0232384
--0.538665 0.819915 -0.193856 -0.551434 0.797567 -0.244556 0.595659 -0.0374086 -0.802366
-0.414913 -0.827079 -0.379192 0.30393 -0.649204 -0.697252 0.542147 -0.715456 -0.44068
--0.522983 0.298517 -0.798359 -0.0838339 0.854366 -0.512866 0.257119 0.817507 -0.515337
--0.301512 0.819938 -0.486612 0.115936 0.830872 -0.544253 -0.568658 0.434602 -0.69839
--0.129469 0 -0.991583 0 -0.286888 -0.957964 0.396823 -0.235874 -0.887071
-0.455331 -0.659765 -0.597816 -0.0958466 -0.443734 -0.891018 0.492498 0.357252 -0.79361
--0.245426 -0.47449 -0.845355 0.115963 0.552531 -0.825386 0.419206 0.375752 -0.826484
-0.693484 -0.1517 -0.70432 -0.116862 0.629659 -0.768032 -0.205244 0.840999 -0.500595
-0.576685 0.0678454 -0.814144 -0.199622 0.829201 -0.522089 0.0382157 0.636928 -0.769975
--0.132784 0.708183 -0.69343 -0.509512 0.445823 -0.735962 0.551977 -0.296608 -0.779324
--0.621821 -0.74489 0.241819 0.173984 -0.951112 0.255176 0.0641335 0.689436 -0.721502
-0.384586 0.590081 -0.709858 -0.977292 0.141508 0.157723 -0.254904 -0.892165 0.372915
--0.299088 -0.94711 -0.116312 -0.326407 -0.940819 0.0912019 0.633746 -0.660714 -0.402272
-0.768 -0.6 -0.224 0.26906 -0.858646 0.436272 -0.570063 -0.819726 -0.0554806
--0.399285 -0.613471 -0.681341 0.514472 0.35586 -0.780181 0.833419 0.44824 -0.323255
-0.84591 0.422955 -0.324878 -0.745351 -0.643481 -0.174311 0.507703 0.58509 -0.632382
-0.641742 0.647196 -0.411466 -0.846289 -0.531477 -0.0364195 -0.0377937 0.259517 -0.964999
-0.474143 0.720697 -0.505752 0.811386 -0.298932 0.502287 0.319102 -0.78366 0.532964
--0.326634 0.0130654 -0.945061 0.480956 0.775735 -0.408554 0.816645 0.576703 -0.0224507
--0.831019 -0.250951 0.496417 -0.490006 -0.601371 -0.631068 0.893498 0.0845509 -0.441036
-0.763268 -0.637292 -0.106215 -0.0642451 -0.936143 -0.3457 -0.431452 -0.748863 -0.503044
--0.796918 -0.446582 -0.4068 0.886277 -0.276366 0.371665 -0.426638 -0.781221 -0.455712
-0.607777 0.00542658 -0.794089 0.802224 0.36572 -0.471896 -0.869659 0.49359 0.00783477
--0.71059 0.688726 -0.14394 0.885195 -0.42083 -0.198322 0.587107 -0.569098 0.575701
-0.561558 0.505402 0.65515 0.815869 0.273909 -0.509247 -0.98744 0.143628 0.0658293
--0.773334 -0.559509 -0.298167 -0.643952 -0.13365 -0.753302 -0.0106825 -0.758459 -0.651634
--0.0861221 0.5844 0.806882 0.89086 0.222715 0.395938 0.414513 -0.612759 0.672834
--0.933702 0.322464 0.155617 0.403577 -0.828969 -0.387216 -0.589968 -0.543392 -0.597213
-0.0960738 0.288221 0.952732 -0.759953 -0.595639 0.260164 0.058722 -0.998274 0
--0.823847 -0.561068 0.0804908 -0.0323125 0.972067 -0.23247 -0.555582 0.694477 -0.457198
--0.971022 -0.0357431 -0.236302 -0.924955 -0.295986 -0.238433 -0.22434 -0.931012 0.287903
-0.933969 0.324859 0.148894 0.851205 0.206353 -0.482564 -0.753044 -0.331278 0.568489
-0.750727 -0.034124 0.65973 -0.625343 -0.606951 0.490465 -0.446065 -0.592582 0.670725
--0.923537 -0.0157474 0.383186 -0.341077 0.420397 0.840793 0.207583 0.928019 0.309339
-0.548625 0.648375 0.527844 0.970118 0.191682 -0.148761 0.246795 0.943394 0.221585
--0.805546 0.109847 0.582262 -0.0574128 -0.80059 0.596456 0.939336 -0.34205 -0.0254657
--0.611717 -0.694063 0.379578 0.00944936 -0.982733 0.184787 0.837139 -0.335124 -0.432309
-0.867052 -0.144121 -0.476917 -0.62838 -0.583709 0.51422 -0.814936 -0.382599 0.435313
--0.762198 -0.396171 0.51196 0.666667 -0.133333 -0.733333 0.0066872 -0.595161 0.803579
--0.264305 -0.816942 0.512591 -0.624136 -0.289599 0.725663 0.322258 -0.314065 0.893036
--0.396763 -0.523727 0.75385 0.0234246 -0.726164 0.687123 0.174694 -0.744069 0.644859
-0.699113 0.636239 -0.326253 0.710531 -0.4222 -0.562933 -0.492213 -0.118658 0.862349
--0.155189 -0.731085 0.664403 -0.310017 -0.75782 0.574106 -0.852302 -0.171869 0.494006
--0.0637487 -0.812796 0.57905 0.22359 0.941931 -0.250547 -0.644618 -0.738952 -0.196006
-0.506935 0.76695 -0.393452 -0.467142 0.27479 -0.840398 -0.200632 -0.72536 -0.658483
--0.191611 -0.8191 -0.540704 0.358312 -0.879151 -0.314177 0.143058 0.839276 -0.524548
--0.461237 -0.864036 -0.201748 -0.550213 -0.431616 -0.714824 -0.269224 -0.423066 -0.865179
-0.0698754 -0.635866 0.76863 0.172456 -0.426183 0.888047 0.66742 0.725401 -0.168358
-0.386712 0.858631 -0.336461 -0.576683 0.384455 -0.720854 -0.435259 -0.0423404 -0.899309
--0.155511 -0.459672 0.874367 -0.433461 -0.791066 0.431655 -0.604078 0.745775 0.280909
--0.996926 -0.0772811 -0.0128802 -0.060117 -0.865685 0.496967 0.6506 0.74819 -0.13012
--0.50084 -0.797035 -0.337483 -0.98064 0.0492949 0.189512 0.0126828 -0.674 -0.738622
-0.6305 -0.339879 0.697819 0 -0.472408 0.88138 -0.445054 -0.376861 0.812344
-0.573308 0.806359 0.145269 -0.317861 0.946014 0.063428 0.555598 0.811046 0.183071
-0.554127 0.829097 0.0744419 -0.390133 -0.23242 0.890942 -0.908379 -0.416506 -0.0370227
--0.768679 -0.361731 -0.527525 0.404002 -0.404002 -0.820709 0.513144 -0.372556 -0.77323
-0.542005 -0.527357 -0.654313 -0.347528 -0.538328 -0.767742 -0.286044 -0.618654 -0.731741
--0.156417 -0.449142 0.879662 0.284843 -0.0931216 0.95404 -0.397439 0.228527 0.888717
--0.152511 0.0538274 0.986835 -0.258021 -0.488103 0.833775 -0.840079 0.294433 0.455606
--0.931626 0.2465 0.267042 0.473692 0.68183 0.557426 0.225875 -0.309977 0.923523
--0.779569 -0.550896 0.297969 0.389904 -0.322095 -0.862687 -0.457239 -0.452489 -0.765628
--0.769422 -0.129357 0.625505 0 -0.454739 0.890625 0.712958 -0.235879 0.660343
-0.590895 -0.401198 0.699916 -0.692747 0.161911 0.70277 -0.347437 -0.820281 0.454341
-0.488719 -0.57264 0.658207 -0.153549 0.472832 0.867671 -0.243055 -0.884449 0.39834
--0.0845631 0.819611 -0.566645 0.735378 0.1329 -0.664498 0.241294 -0.487415 -0.839168
--0.343322 -0.672138 -0.656019 -0.365424 -0.637432 -0.67834 -0.0832131 0.254534 0.963477
-0.120501 -0.271127 0.954971 0.309647 -0.465699 0.829001 0.604564 -0.310033 0.733745
-0.325999 -0.10161 0.939894 0.338341 0.931664 0.132394 0.71773 -0.118145 0.686225
--0.242618 -0.679331 0.692565 0.516544 0.843397 -0.147862 0.484088 0.633273 -0.603842
-0.661233 0.418971 -0.622281 0.31461 0.750833 -0.58075 -0.206203 0.904889 -0.372366
-0.0224029 0.847576 -0.530201 -0.190866 0.438992 -0.877984 0.275766 -0.529172 -0.802453
-0.31833 -0.48339 -0.815475 0.0705311 -0.712364 -0.698257 -0.131773 -0.779013 -0.613004
--0.193575 -0.71323 -0.67367 -0.489911 0.553631 0.67341 -0.276104 -0.516582 0.810499
--0.285549 -0.095183 0.953626 -0.0892342 0 0.996011 0.539156 -0.589431 0.601566
--0.474298 -0.380462 0.793908 -0.986091 -0.152084 0.0670476 0.420109 0.904591 -0.0722769
-0.441151 0.893024 -0.0888429 -0.43675 0.780551 -0.447202 0.415877 -0.883738 -0.214603
--0.188738 0.924816 -0.330292 0.121147 0.987349 -0.102302 -0.779696 0.60643 0.155939
--0.48517 -0.749809 -0.449885 -0.381799 0 0.924245 0.494724 -0.169152 0.852429
--0.456887 -0.45452 0.764635 0.0189 -0.7686 0.63945 -0.305122 0 0.952313
--0.883178 -0.0334176 0.467846 0.975461 0.0248701 0.218765 0.696289 0.690828 0.194779
-0.443242 0.89612 -0.0224833 -0.369419 -0.181656 -0.911335 0.451936 -0.885795 -0.105452
--0.72774 -0.610632 0.312287 0 -0.61519 -0.788379 0.133662 -0.61917 -0.773798
-0.113717 -0.760903 -0.638824 -0.369801 -0.665642 -0.648204 -0.0342371 -0.725827 0.687025
--0.167154 -0.297295 0.94004 0.16328 -0.569211 0.805815 0.743706 0.424975 0.516041
-0.490768 -0.208642 0.84594 0.287294 -0.721474 -0.63003 -0.742765 -0.427652 -0.515184
--0.676961 0.132552 0.723985 -0.164613 -0.420322 0.892318 -0.572824 -0.329707 0.750444
-0.272078 -0.743681 0.610665 0.659524 0.544182 0.51855 0.339597 0.25412 0.905592
--0.245284 -0.531449 0.810801 -0.310388 -0.843483 0.438401 -0.955175 -0.212261 -0.206365
--0.783488 0 0.621407 -0.31772 0.926235 0.202838 -0.397139 0.917528 0.0205417
-0.400384 0.85243 0.336236 0.123878 0.916698 0.379893 -0.310369 -0.846462 0.432636
-0.845257 0.432523 0.313791 0.655033 0.74668 0.115764 -0.407329 -0.878302 0.250337
-0.991945 -0.101338 0.0760036 -0.997329 0 0.0730367 0.898404 0.431997 0.0790521
--0.727004 0.2812 0.626412 -0.975467 -0.00950748 -0.21994 0.728168 0.102717 0.677658
-0.59963 -0.237136 0.764337 -0.766545 0.178928 0.61676 0.568873 -0.644363 0.511057
--0.0122066 -0.772068 0.635422 -0.331944 -0.881242 0.336491 -0.0746191 -0.983867 0.162596
--0.859657 -0.459269 0.223746 0.799719 0.517609 -0.304188 0.646401 -0.609812 0.458579
--0.432498 -0.900382 -0.0475093 -0.364245 0.610786 -0.70304 -0.915037 -0.174293 0.36377
-0.824065 0.560746 -0.0804965 -0.489021 0.789957 -0.3699 0.975721 -0.136391 0.171363
--0.853388 0.426694 -0.299434 0.608354 -0.01767 0.793469 0.659089 0.0063374 0.752038
--0.948889 0.289914 0.124741 -0.314891 0.944674 0.0918433 0.831238 0.465312 -0.304185
-0.094667 0.9493 -0.299779 0.809295 -0.012302 0.587273 -0.845043 -0.423074 0.326971
-0.808137 -0.493278 -0.321855 -0.129371 0.954112 -0.270062 -0.873153 0.293771 0.388975
--0.916029 0.373197 -0.147017 -0.573422 -0.798089 0.185045 -0.728867 -0.684582 -0.0100463
-0.662043 0.367159 0.65337 0.0576586 0.897827 0.436558 -0.932517 0.345674 -0.104506
-0.773286 -0.594163 0.221355 -0.160785 0.920046 0.3573 -0.652284 -0.489828 0.578441
--0.719465 -0.527608 0.451664 -0.197394 -0.958769 0.204443 0.625048 -0.644351 0.440598
--0.450171 -0.467825 0.760583 -0.681206 -0.390797 0.619061 -0.269787 -0.926849 0.261084
-0.488812 -0.852821 0.183738 0.24203 -0.96812 0.0645413 0.152247 0.792952 -0.589956
--0.1013 0.964653 -0.243274 0.36482 0.781757 -0.505729 0.120654 0.890714 0.43826
--0.750137 0.641055 -0.162306 -0.300564 0.826551 -0.475893 0.889031 0.457648 0.0135305
-0.0175601 -0.807767 -0.589241 -0.627992 -0.250176 -0.736912 -0.832573 -0.0101197 -0.553822
--0.180239 0.959128 -0.218146 -0.975822 0.203105 0.0807432 0.446144 0.892288 0.0691209
--0.18645 -0.849383 -0.493747 -0.47971 -0.830184 -0.284029 -0.873968 -0.0771149 0.479826
--0.812278 0.330308 0.48073 0.642143 0.762545 0.0785956 0.685601 0.713303 -0.145431
-0.293974 0.551202 0.780869 -0.42041 -0.371525 0.827783 0.728482 0.0466762 -0.683473
--0.891428 -0.445714 -0.0818219 0.916834 -0.00274091 0.399259 0.532432 -0.846287 -0.0177477
-0.494079 -0.868381 0.0424209 -0.487983 0.486076 0.724985 0.620801 0.558721 0.549942
-0.311032 -0.948301 -0.0631279 0.699592 -0.699592 -0.145405 0.584159 -0.767357 -0.264427
-0.425544 -0.830331 -0.35981 0.464224 -0.858815 -0.216638 -0.188658 -0.981024 -0.044719
--0.659388 -0.746212 -0.0915165 0.771295 -0.290089 -0.566527 0.48177 0.404687 -0.777256
--0.194547 0.960578 -0.1986 -0.0345892 0.992606 0.116346 0.330335 0.739792 0.586163
--0.554409 0.671126 0.492159 0.104307 0.382459 0.918066 -0.464886 0.757472 0.458385
-0.696904 -0.420772 0.580754 0.82618 -0.563304 -0.0107296 -0.701191 -0.643716 -0.306531
--0.637416 -0.762623 -0.11003 0.58002 0.305686 -0.755071 0.385464 0.566682 -0.72821
-0.488593 0.576477 -0.654944 0.232487 0.854254 -0.464974 0.864582 0.27765 0.418818
--0.717908 0.683609 0.131478 0.481512 -0.502773 0.71789 0.654403 -0.364243 -0.662634
-0.566525 0.446772 -0.692419 -0.334364 -0.675893 0.656787 0.383583 -0.280166 0.879984
--0.82266 0.558234 0.107729 0.157532 0.984574 0.0761404 0.0894869 0.995541 0.029829
--0.456209 0.82688 -0.328851 -0.873372 0.487054 0 0.61682 0.106348 0.779887
-0.906605 -0.215459 0.362829 -0.735083 -0.479402 0.479402 -0.697206 -0.681626 0.222015
-0.337685 -0.92096 -0.194425 -0.78914 -0.39457 -0.470715 -0.451943 0.795246 -0.404142
-0.423041 0.867963 -0.260146 0.0770327 -0.99661 0.0288872 0.182021 -0.982915 0.0273032
--0.406562 -0.877078 -0.255814 0.998458 -0.0264492 0.0488051 -0.985628 -0.0467954 0.162321
--0.225258 -0.946086 -0.232767 0.908438 -0.417071 -0.0281424 0.19366 -0.937125 0.290332
-0.384013 -0.776411 -0.49972 0.370627 0.688307 -0.623594 0.881539 -0.467803 0.0636275
--0.935347 0.289678 -0.203008 0.930651 -0.101641 0.351509 -0.990077 0.12673 0.0607247
-0.505532 -0.767014 0.395129 0.780537 -0.617513 -0.0971554 -0.87798 0.432438 0.205299
-0.0433967 -0.902651 0.42818 0.291171 -0.934174 0.206246 0.979034 -0.19221 0.067442
--0.933366 0.35779 -0.0285195 0.978478 0.181628 -0.0979368 0.976701 0.111094 0.183614
-0.722059 -0.499788 0.478375 0.726421 0.682865 0.0775144 0.275503 0.771407 0.573611
-0.117289 0.640673 0.758803 0.217482 -0.931812 0.290565 0.109131 -0.992576 0.0536996
--0.850588 0.514502 0.108571 -0.755283 0.422272 0.501233 0.795559 0.595362 -0.112382
--0.965902 0.0616179 0.251468 0.393091 -0.91277 -0.111043 0.627833 0.623675 0.465677
-0.815527 0.547 0.188964 -0.129827 0.536618 0.833778 -0.629313 0.0646238 0.77446
--0.627186 -0.677179 0.384795 0.142175 -0.95994 0.241455 0.838717 -0.279572 0.467325
--0.828097 0.559978 -0.0260671 -0.793616 0.605257 0.0619489 -0.732389 0.642249 -0.226102
--0.919556 0.276615 -0.279107 -0.80546 0.577246 0.134243 0.85064 -0.515539 -0.103108
--0.529412 0.705882 0.470588 0.204655 0.708985 0.674875 -0.0936265 0.206624 0.973931
--0.430175 -0.0977054 0.897442 -0.87821 -0.40941 0.247247 0.817799 -0.572902 0.0546677
-0.274368 -0.00783907 0.961593 0.468355 0.212223 0.857674 -0.867086 -0.412898 -0.278706
-0.333247 0.773089 0.539704 -0.738222 0.0025812 0.674553 -0.729397 -0.388927 0.562775
--0.0345494 -0.958747 -0.282154 -0.759089 -0.498152 -0.41908 -0.883272 0.430186 -0.186469
-0.782948 -0.445471 0.434221 -0.702032 0.226257 0.675247 -0.818275 0.221564 0.53041
--0.759455 -0.607564 0.232583 0.038568 -0.994504 -0.0973383 0.741072 -0.553145 -0.380582
--0.402702 -0.434919 -0.805405 -0.591824 -0.313319 -0.742681 0.179559 -0.193371 -0.964555
-0.779622 -0.507457 0.366984 -0.0705151 -0.564121 0.822676 0.555662 0.789844 0.259586
-0.701905 0.712266 -0.00259006 -0.393066 -0.426583 -0.814571 -0.638362 -0.0640302 -0.767069
--0.156625 0.86731 -0.472485 -0.154957 0.923893 -0.349871 -0.566104 0.299702 -0.767923
--0.0540124 -0.900207 0.432099 0.717203 0.646973 0.258931 0.0387284 0.96821 -0.247124
--0.852252 0.233952 -0.467903 0.770828 -0.513885 -0.376492 -0.433293 0.0772538 -0.897936
--0.441542 -0.532343 -0.722254 0.586711 0.369167 -0.720754 -0.597891 -0.0128579 -0.801474
-0.817247 0.0674791 -0.572323 -0.284468 -0.924521 -0.253651 -0.0394122 -0.992603 -0.114831
-0.586584 -0.782685 -0.208143 0.210896 -0.723071 -0.657793 0.784555 -0.564991 -0.255458
--0.985826 0.125934 -0.110848 0.428532 0.836033 0.342651 0.544306 0.834603 0.0846699
--0.0273532 0.877789 0.478266 0.213399 0.87769 0.429093 -0.616112 0.724439 -0.309184
-0.725074 0.623471 0.292493 0.158607 0.929215 0.33377 0.241388 0.836883 0.491283
-0.277472 0.501692 0.819337 -0.586161 0.806416 0.0781548 -0.76939 0.377436 0.515346
-0.999076 0 -0.042971 0.901624 -0.276498 -0.332599 0.674453 0.551825 -0.490511
--0.302206 0.910816 -0.28122 -0.823832 0.322169 -0.466378 0.54395 0.390528 -0.742701
--0.786183 0.293769 -0.543706 0.923501 0.340491 0.17667 0.972855 0.221754 0.0661684
-0.249189 0.386672 0.887913 0.461058 0.675504 0.57543 -0.07817 -0.986144 -0.146318
--0.251057 -0.502114 -0.827558 0.781083 0.414068 -0.467395 0.162452 0.699794 -0.695628
-0.389264 -0.528137 -0.754682 -0.636464 -0.603463 -0.48036 0.922692 0.168944 -0.346551
--0.218208 0.877029 0.428024 0.0545856 0.846076 0.53026 -0.968434 -0.220467 -0.11632
-0.783573 -0.602749 -0.150687 0.166574 -0.760448 -0.627672 0.318941 0.528531 -0.786722
-0.707104 -0.335421 -0.622493 0.531772 -0.335856 -0.777444 0.705496 -0.264561 -0.657483
-0.90796 -0.0974804 -0.407561 0.141996 -0.812534 -0.565355 0.12281 -0.973037 -0.195237
--0.830287 -0.0919985 -0.549691 -0.907136 0.412125 -0.0851879 0.813701 0.28835 -0.504723
--0.980578 0.155423 0.119629 -0.21579 0.951074 0.221118 0.884389 -0.365954 -0.289714
-0.175323 0.91001 -0.375692 -0.294649 0.955378 -0.0208338 0.803538 0.583107 -0.119636
--0.0328396 0.97026 0.239828 -0.762362 0.39702 0.511057 -0.644103 0.644103 -0.412629
--0.861474 0.501651 0.0787934 0.757674 0.631395 -0.165134 -0.173715 0.98398 -0.0400881
-0.0590994 0.98105 0.184521 -0.485725 0.794409 0.364672 -0.601819 0.71081 0.364093
-0.0892751 0.982026 0.166297 0.755531 -0.458715 0.46771 -0.778652 0.593134 0.204679
-0.253929 0.948003 0.191858 0.253345 0.957082 0.140747 -0.01281 0.999179 0.03843
--0.784161 0.61138 -0.106327 -0.472775 0.8678 0.152994 -0.20039 0.901035 0.384682
--0.450055 0.725713 0.520376 -0.466501 0.641439 0.609043 -0.307698 -0.946762 -0.0946762
-0.606794 0.794186 0.0327193 -0.768634 0.409112 0.491761 -0.83657 0.375603 0.398841
-0.0107634 0.8826 0.470002 -0.305333 0.395137 0.866394 0.0352067 0.95058 0.308477
-0.69164 0.332688 0.641056 0.845559 0.383356 0.371575 0.673364 -0.424423 0.605348
-0.810594 0.583705 0.0471877 0.558877 0.0745169 0.825896 -0.753087 0.423041 0.503881
-0.457134 -0.0489787 0.888048 -0.556414 -0.529127 0.640647 -0.88778 0.333531 0.317181
--0.997911 0.0636821 -0.0108395 -0.0206386 -0.97591 0.217196 0.576738 -0.814743 -0.059724
--0.688388 0.697176 0.20017 0.46534 0.850908 0.24375 0.204143 0.74805 0.631464
-0.620335 0.592866 0.513512 -0.0176425 -0.970336 0.241114 0.792424 -0.255187 0.554025
--0.988113 -0.0306392 -0.150643 -0.291551 0.892875 0.34318 0.188902 -0.981878 0.0152229
-0.992506 0.0577038 0.107714 -0.903829 0.0703452 -0.422071 0.506059 -0.857637 0.0914458
-0.888234 -0.41419 -0.198715 0.0314464 0.993183 0.112246 0.0985576 0.995086 -0.00950994
-0.00309445 0.996412 0.0845815 0.0966845 0.995281 0.00821502 0.970079 -0.0928306 -0.22434
-0.0858495 0.985225 0.148193 0.459898 -0.813099 0.356881 0.420206 -0.452529 0.786539
--0.67743 -0.658185 0.328451 -0.603843 -0.738414 0.300196 0.538519 -0.817208 0.20535
--0.856362 0.486709 -0.172505 0.440858 -0.896412 0.0457186 -0.496167 -0.857016 -0.139077
--0.493412 -0.695837 -0.521878 0.121931 0.738758 -0.66285 0 0.69568 -0.718351
-0.117862 0.833876 -0.53922 -0.301478 0.836417 -0.457731 0.415422 0.671664 -0.613427
-0.431768 -0.895729 0.106048 0.732543 0.0261622 -0.680218 -0.0326107 -0.605627 -0.79508
--0.827311 -0.15551 -0.539791 0.779259 -0.610771 0.140407 0.529982 -0.714323 -0.457013
-0.54406 -0.746676 -0.382718 0.444184 -0.895533 -0.026866 -0.612625 -0.722253 -0.321001
-0.471829 0.688978 -0.55017 -0.223669 0.688465 -0.689919 -0.13129 0.774159 -0.619226
-0.0911533 0.299504 -0.949731 0.892607 -0.318788 -0.318788 0.0223457 -0.938521 -0.344497
--0.444963 -0.874583 -0.192647 -0.60169 -0.575867 -0.553486 0.342074 0.724872 -0.597951
--0.270215 0.628249 -0.72958 0.121069 0.407716 -0.905047 -0.23157 0.605852 -0.76113
--0.342352 0.569403 -0.747379 0.117507 0.568803 -0.814036 0.023847 0.7614 -0.647843
--0.526226 0.585519 -0.616648 -0.231181 0.854087 -0.46593 -0.784243 0.54556 -0.295512
-0.9009 -0.345628 -0.262526 -0.35482 -0.906762 -0.227786 -0.227612 -0.699695 -0.677215
-0.202606 0.162084 -0.965753 0.331769 0.539125 -0.774128 0.330417 0.788996 -0.517987
-0.22223 0.864528 -0.450783 -0.0817823 0.324208 -0.942444 0.112184 0.518025 -0.847977
--0.129178 0.172871 -0.976437 -0.715707 0.486015 -0.50155 0.0109128 0.979177 -0.202714
--0.10432 0.799788 -0.591148 -0.33193 -0.86539 -0.375397 0.188744 0.0330303 -0.981471
-0.475564 0.466758 -0.745638 0.464235 0.714406 -0.523554 0.182576 0.845068 -0.50252
-0.0765634 0.796955 -0.599166 -0.168661 0.748856 -0.640912 -0.0476265 0.483069 -0.874286
-0.356329 -0.344451 -0.868552 -0.390794 0.256037 -0.884152 -0.696654 0.171308 -0.696654
--0.126787 0.235461 -0.963578 -0.803303 0.087633 -0.589089 -0.98186 -0.11417 0.151381
--0.191918 -0.967673 0.163636 -0.00956072 -0.984755 0.173686 -0.389125 0.243203 -0.888501
--0.574119 -0.812714 0.0994146 0.00366827 0.201755 -0.979429 0.243627 0.705803 -0.665198
-0.427219 0.759135 -0.491119 -0.337822 0.445311 -0.829201 0.186444 0.445845 -0.875477
-0.329095 0.329095 -0.885095 -0.285756 0.417995 -0.862336 0.312529 0.659652 -0.683509
--0.428604 -0.898519 0.0946715 0.889324 0.0896797 -0.448398 -0.474634 0.443728 -0.76015
-0 -0.241626 -0.970369 0.664454 0.45961 -0.589287 0.0151411 0.847901 -0.529938
-0.101695 0.38983 -0.915254 0.0947333 0.271776 -0.957686 0.334016 0.513871 -0.79017
--0.798846 -0.589048 0.121934 0.652356 -0.753425 -0.0823527 0.478811 -0.806061 0.34786
-0.552936 0.535923 -0.638003 0.430075 -0.900803 0.0599109 -0.812626 0.58231 -0.0235386
-0.739027 0.451547 -0.499944 0.0858603 -0.932198 0.351618 0.592979 -0.662741 -0.45733
-0.229178 -0.965324 -0.125006 -0.865837 0.151789 -0.476745 -0.290488 0.544665 -0.786738
-0.566408 0.82264 0.0494483 0.238092 0.965783 -0.102838 -0.931211 0.271112 -0.243608
-0.913181 0.391363 0.11373 0.844132 0.522029 0.122177 -0.85241 -0.522741 -0.0118208
-0.773164 0.629435 -0.0776468 0.42169 -0.901543 0.0969401 -0.40193 -0.818801 0.409899
-0.877593 -0.00566189 -0.479373 0.996265 -0.0797012 -0.0332089 -0.630452 -0.302759 0.71475
-0.469776 -0.058722 0.88083 0.885716 -0.36621 0.285303 0.806559 -0.12566 -0.577644
--0.0478107 -0.273204 0.960767 -0.125909 -0.924588 0.359562 0.739254 -0.576042 0.348825
-0.810052 -0.236301 -0.536635 0.851356 -0.0949053 -0.515931 0.8308 -0.200538 -0.519187
--0.981549 0.0885608 0.169468 -0.779176 0.446306 0.440108 -0.266874 0.951168 0.155106
--0.220171 0.798397 0.560435 -0.198288 0.925346 0.323137 -0.313712 0.686775 0.655686
--0.669239 -0.540294 0.5101 -0.528226 0.136947 0.837988 -0.711376 0.643626 0.282292
--0.868 -0.432311 0.244301 -0.64222 -0.725087 0.248601 0.0137037 -0.986669 0.162161
--0.429028 -0.899734 0.0800853 -0.796435 -0.584053 0.156759 -0.930467 -0.266065 0.251875
--0.928756 -0.321726 0.184132 -0.459829 -0.887945 -0.0105708 0.65052 -0.359335 -0.669106
--0.595695 -0.689505 0.411983 -0.592954 -0.67838 0.433828 -0.932875 -0.201208 0.298764
--0.548243 0.146952 0.823307 -0.124359 0.683972 0.71883 -0.622472 0.77809 0.0842931
-0.294561 -0.13105 -0.946604 0.434018 0.648209 0.625663 0.560395 0.557255 0.612719
--0.768221 0 0.640184 -0.0907617 0.0819377 0.992496 -0.794135 -0.560566 0.234767
-0.744918 -0.157802 -0.648225 0.267261 -0.455916 -0.848947 -0.2543 -0.736411 -0.626921
-0.195894 -0.138278 -0.970827 -0.435293 -0.114005 0.893041 0.0790537 -0.837969 0.539961
--0.345503 -0.877873 0.331611 -0.773505 -0.630704 0.0624754 -0.194607 0.7914 -0.579495
-0.463032 -0.40981 -0.785912 -0.53091 -0.3492 0.772136 -0.48301 -0.802979 0.34918
--0.373332 -0.919782 0.120931 -0.691705 -0.620847 -0.368909 -0.378586 0.107728 0.919276
-0.772425 0 0.635105 0.311129 -0.677475 -0.666503 0 -0.913276 -0.407341
-0.69236 0.437533 -0.573761 -0.426071 -0.809534 -0.403879 0.51719 -0.292749 -0.804247
--0.275126 -0.776825 0.566435 -0.641663 -0.278551 -0.714617 0.420445 -0.544391 -0.725855
-0 -0.352946 -0.935644 0.399175 -0.536822 -0.743291 -0.378509 -0.485634 -0.787966
--0.564532 0.0903252 0.820454 0.00265338 -0.934652 0.355553 -0.0899031 -0.611341 0.786244
--0.8985 -0.252409 0.359149 0.673672 0.688717 -0.26802 -0.294485 -0.0631039 -0.95357
--0.830727 -0.420057 -0.365301 0.658488 0.719872 0.219496 -0.213353 0.963834 0.159703
--0.627803 0.700068 0.340248 0.546366 -0.561496 -0.621456 0.397347 -0.397347 -0.827182
--0.363614 -0.886822 0.285187 0.898894 -0.254554 0.356641 0.506943 -0.699884 0.50316
--0.573804 -0.538189 -0.617334 -0.483412 -0.0303714 -0.874866 0.598451 -0.619825 0.507615
-0.832499 0.445981 0.328705 -0.691032 -0.707291 0.149046 0.172447 -0.172447 -0.969806
--0.147857 -0.535454 -0.831521 -0.796696 -0.534456 0.282193 -0.197786 -0.928159 0.315279
-0.780603 -0.617143 0.0989653 0.820248 -0.568277 0.0652267 -0.973758 -0.0226455 0.226455
-0.919315 0.315586 0.235088 -0.600009 0.695182 -0.395868 0.307166 -0.557185 -0.771488
--0.357909 -0.586027 -0.726962 -0.991927 0.0148882 0.12593 -0.0436156 0.992255 -0.116308
-0.112852 0.94439 -0.308857 0 -0.699193 -0.714933 0.425581 -0.816792 0.389526
-0.554604 -0.805184 0.209984 -0.249555 -0.960203 0.125428 -0.907917 -0.0466872 0.416542
--0.819624 -0.015762 0.572686 0.897071 -0.135263 0.420675 -0.184387 0.964488 -0.189115
-0.785175 0.141838 -0.602812 -0.138233 0.990354 -0.00946802 -0.189037 -0.578924 0.793166
-0.80907 0.367141 0.458926 0.712364 0.274947 0.64571 -0.0772307 -0.724038 0.685423
--0.537326 -0.828757 0.156341 0.644661 0.764466 0.00190166 -0.633842 -0.741595 0.219732
--0.918632 -0.260508 -0.29707 -0.7758 -0.123306 -0.618813 -0.869091 -0.364103 -0.334829
-0.974566 -0.0251501 0.222683 0.856428 0.260562 0.445689 0 0.286582 0.958056
--0.622242 -0.656182 0.426896 -0.357277 -0.849524 0.388152 0.37847 0.879466 0.288617
-0.498339 0.839761 0.215544 -0.144164 -0.677962 0.720822 0.23215 -0.747922 0.621868
--0.0706076 -0.723728 0.686463 -0.717444 0.105168 0.688631 -0.689846 0.489349 0.533526
--0.731974 -0.671632 0.114562 0.0533486 0.906926 0.417897 0.494058 0.56507 0.660759
-0.729844 0.00793309 0.683568 -0.482697 -0.848026 -0.218757 -0.419436 -0.885477 -0.200009
--0.00301935 0.960153 0.279458 0.440196 0.752001 0.490635 -0.518201 0.782381 0.345467
--0.205353 -0.966659 0.152971 0.211218 -0.766884 0.606033 -0.834638 0.244123 0.493745
-0.799797 -0.307182 0.515716 0.527763 -0.0232623 0.849073 0.32594 -0.211257 0.921484
--0.274095 -0.713168 0.645185 -0.883103 -0.186223 0.43064 -0.551854 -0.827781 -0.101173
-0.968937 0.238534 0.0652922 -0.743488 0.529791 0.408102 0.545829 -0.433453 0.71707
--0.0797452 0 0.996815 0.391437 -0.669001 0.631834 -0.994407 -0.0678005 0.0809839
-0.652413 -0.609865 0.449913 -0.0276256 -0.910692 0.412161 -0.462232 -0.850126 0.252242
-0.270156 -0.689204 0.672319 -0.107629 0.522768 0.845654 -0.85372 0.357847 -0.378295
-0.362319 -0.687358 0.629495 0.0133976 -0.697707 0.716258 0.0683529 -0.772767 0.630998
-0.0312361 -0.777431 0.628192 -0.367265 -0.477998 0.797894 -0.38953 0.174335 0.904364
--0.158268 0.939195 0.304735 -0.657367 -0.734704 0.167564 0.338555 -0.63728 0.692283
-0.862128 0.00451376 0.50667 0.623929 -0.736236 0.26205 0.290356 -0.758885 0.582912
-0.778424 -0.346822 0.523231 -0.606172 -0.589621 0.533762 0.75355 -0.58685 0.29626
-0.246752 -0.809346 0.532984 -0.52009 -0.821074 0.235252 -0.709675 -0.68583 0.161238
-0.724845 -0.50997 0.463175 -0.916951 -0.395842 0.0501066 0.676329 0.736447 -0.0150295
-0.767536 -0.167899 0.618626 -0.726525 -0.676171 0.122286 0.807047 0.590411 -0.00949268
-0.536529 0.75552 -0.375935 0.189109 0.866118 0.462686 0.442605 -0.872192 0.208285
-0.762131 -0.568369 -0.31002 -0.913272 -0.258988 -0.31442 0.69705 -0.0279752 0.716477
-0.789299 -0.613216 0.0311944 0.605487 -0.630201 0.486037 0.760199 -0.612195 0.21752
--0.0822578 0.740321 0.667202 -0.856848 0.386508 -0.341209 0.413355 0.908883 0.0554045
-0.863375 -0.234283 0.446873 0.839448 -0.395966 0.372208 0.172774 0.777482 0.604708
--0.370247 0.887797 0.273373 -0.0265889 0.868572 0.49485 -0.703839 0.614933 -0.355624
-0.703157 -0.559768 0.438439 -0.295777 -0.371963 0.879863 -0.402732 -0.826118 0.394127
-0.751439 -0.644091 0.143131 -0.202927 0.96954 -0.137164 0.159409 0.299785 -0.940594
--0.345135 0.446563 0.825508 -0.755784 0.644915 0.113472 -0.0127457 -0.939996 0.340948
-0.554481 -0.73529 -0.389744 0.0383201 0.996322 -0.0766402 0 -0.993884 0.110432
-0.0623914 0.0594204 0.996281 -0.198595 -0.0379667 0.979346 -0.552502 -0.357105 0.753139
-0.95364 -0.283515 0.100948 0.0788381 -0.996887 -0.00103734 -0.623823 -0.516158 -0.586879
-0.619117 -0.711247 -0.332898 -0.587694 0.350116 -0.729407 0.425525 -0.633559 -0.646167
--0.792719 0.125052 -0.596623 0.549647 0.682485 0.48177 0.284613 0.868068 0.406759
-0.125081 0.646252 0.752803 -0.482884 0.46248 0.743596 0.0495907 0.963994 -0.261258
--0.220279 0.885436 -0.409244 -0.769262 -0.210159 -0.603382 0.463245 0.863706 -0.198534
-0.457551 0.889148 0.00801034 0.106283 0.978284 0.177943 -0.824598 0.385214 0.414305
--0.970146 -0.233118 0.0668742 0.99625 0.0510898 -0.0698227 -0.35326 0.855806 0.377895
--0.221715 0.565373 0.794478 -0.193881 0.320325 0.927255 -0.925243 0.0155069 0.379057
--0.843303 0.0018575 -0.537435 -0.894793 -0.13778 -0.424691 0.799902 0.47053 -0.372503
--0.316261 0.67903 0.662493 0.597121 0.11642 0.793658 -0.584023 0.460358 0.668572
--0.651687 0.267705 0.709675 0.730825 0.375507 0.56999 0.678212 0.452142 0.579306
-0.440507 0.652459 0.616645 -0.343026 0.883311 0.319524 0.00573542 0.81443 0.580234
--0.074976 0.995877 -0.0510706 0.256632 0.946919 -0.193609 0.713131 0.671647 -0.200836
-0.233665 0.826294 -0.512483 -0.883754 0.0489375 -0.465386 0.536882 -0.649454 -0.538486
--0.412153 0.527015 0.743226 0.47761 0.365454 0.798957 -0.198993 0.979813 0.0191922
-0.83459 -0.316449 0.45091 0.520414 0.122544 0.845075 0.585649 0.151293 0.79632
--0.742989 -0.398677 -0.53761 0.250072 0.953478 0.168357 -0.0907066 0.379318 0.920809
-0.0711989 -0.750327 0.657221 0.238656 -0.765445 0.59761 -0.858499 -0.505471 -0.086474
--0.148188 0.254037 0.955775 0.230954 0.798552 0.555855 -0.227606 0.878812 0.419385
-0.830754 -0.527494 0.177759 0.483491 -0.84246 0.237692 -0.547495 -0.79833 -0.250835
--0.596855 -0.778153 -0.195557 0.657571 0.553195 0.511444 -0.588348 0.784465 0.196116
-0.751382 -0.253756 -0.609125 0.69777 0.279108 -0.659709 0.569258 0.597721 -0.564514
-0.57905 0.539268 0.611466 0.355506 -0.0334594 0.934075 -0.695148 0.718065 0.0339511
-0.258622 0.862073 0.435826 -0.32263 0.897752 -0.299919 -0.594266 0.779492 -0.198089
--0.906621 -0.139084 -0.398364 0.426953 -0.760511 0.489218 -0.229504 -0.944247 -0.236062
--0.527683 -0.828512 -0.187401 -0.532891 -0.444664 -0.719932 -0.352344 -0.932926 -0.0741776
--0.257656 -0.96621 -0.00715711 -0.25711 -0.939012 -0.228365 -0.969541 0.153364 -0.19097
-0.799125 -0.599344 0.0467573 0.777426 -0.628471 0.025166 -0.966318 -0.256574 -0.0199928
-0.894109 0.296593 -0.335562 0.690268 -0.711399 -0.132067 0.686383 -0.11969 -0.717323
-0.713259 0.632277 -0.302469 -0.712278 0.651226 -0.261847 0.255656 -0.941177 -0.220965
-0.828486 0.555535 0.0706461 -0.666811 -0.742253 -0.0665188 0.837255 0.52587 -0.149886
--0.935068 -0.289133 -0.205059 0.703161 -0.689533 -0.173519 -0.949556 -0.0091597 -0.313465
-0.590602 0.309984 0.74505 -0.830706 -0.480177 0.281704 0.508962 -0.840972 0.18364
-0.259785 0 -0.965666 0.837165 0.429937 0.338096 -0.454403 -0.495712 0.740126
--0.77485 -0.478956 -0.412563 -0.0814985 -0.995301 0.0522949 0.714269 0.236299 -0.658774
--0.634238 -0.369972 0.678869 0.781088 0.618361 0.0867875 0.474481 0.800686 0.365746
-0.520859 -0.129625 0.843744 0.90976 0.304175 0.282514 -0.746589 -0.603824 0.279288
-0.126534 -0.989943 -0.063267 -0.503895 -0.852012 -0.142002 0.410782 -0.898505 -0.15475
--0.356862 -0.172444 -0.918103 0.655409 0.607867 0.448259 -0.46487 -0.542042 0.700061
-0.00422915 -0.90081 -0.434193 -0.191351 -0.867457 -0.459242 0.821086 -0.454422 -0.345425
--0.546042 0.58859 -0.596154 -0.93058 0.113535 -0.348038 -0.753609 -0.628008 -0.194111
-0.438023 0.109506 0.892269 0.777655 0.330412 0.534866 -0.889174 -0.0967962 -0.447213
-0.160625 -0.103259 -0.981599 -0.0679258 -0.666908 -0.742038 -0.728188 0.305994 0.613279
--0.833474 -0.0123217 0.552422 -0.107566 0.0759289 0.991294 -0.180939 -0.719548 0.670456
--0.350117 -0.73456 0.58124 0.775063 0.60803 -0.171976 0.547788 -0.620137 -0.561568
--0.852937 -0.0140401 -0.521824 -0.941919 -0.217366 0.256009 0.682862 -0.72604 0.0810265
-0.226125 -0.767773 0.599494 -0.77116 -0.632747 0.0703052 0.881302 0.375022 -0.287517
-0.886711 0.28195 -0.366398 0.880522 0.266924 -0.391705 0.329377 -0.838118 -0.434821
--0.0988595 -0.97384 -0.204605 -0.467157 -0.647056 -0.602564 0.463428 0.868927 -0.173785
--0.538635 0.817571 -0.203591 0.504489 -0.246379 -0.827519 -0.159358 -0.830206 -0.534194
--0.520467 -0.546931 -0.655729 0.395295 0.796767 0.45706 -0.168681 0.984547 0.0470471
--0.256167 0.966621 0.004627 0.989896 -0.134516 0.0448385 -0.826469 0.373294 0.421427
-0.343333 -0.924358 -0.166385 0.844812 -0.0808081 -0.528926 -0.666903 0.283434 -0.689134
-0.999991 -0.00306746 -0.00306746 0.970461 -0.206424 -0.124882 -0.19123 -0.956151 0.221827
--0.207602 0.851885 -0.480826 -0.936313 0.317231 -0.150605 0.106412 -0.127695 -0.986088
--0.680817 0.732192 -0.0195712 0.139002 -0.914116 -0.380882 0.911713 0.363804 -0.190858
--0.0763092 0.985661 -0.150499 -0.0643992 0.965988 -0.250441 -0.532559 0.817202 -0.220369
-0.0588725 0.408645 0.910793 -0.376454 0.792696 0.479494 0.564532 0.8054 -0.18065
-0.888415 0.376903 -0.262037 0.042241 0.995884 -0.0801862 0.978205 -0.0670004 -0.196534
-0.558875 0.62795 0.541607 0.362945 0.798117 0.480917 -0.342674 0.920935 -0.185615
-0.686221 0.721715 0.0907074 0.728373 0.681881 -0.067155 0.296334 0.931334 -0.211667
--0.560047 0.665716 0.493123 -0.728108 0.6721 0.134687 0.809224 0.325276 0.489237
-0.26383 0.906776 0.328863 -0.983703 0.14414 0.107479 -0.429642 0.839754 0.331996
--0.563812 0.82589 0.00459786 -0.812234 0.54149 0.216943 0.298822 0.914343 0.273281
-0.258055 0.918501 0.299606 0.892747 0.334366 0.301996 -0.85362 0.219279 0.472493
--0.700469 0.62234 0.349337 0.724669 0.537697 0.430972 -0.851145 -0.338675 0.401063
-0.452102 0.322536 0.83161 0.640457 0.751488 -0.158367 -0.418052 -0.8813 -0.220325
--0.341742 -0.93979 -0.00251281 0.932318 -0.334771 -0.136788 -0.147033 0.952039 0.268335
--0.43836 -0.769566 0.464337 0.170428 0.806892 0.565579 0.381367 0.560659 0.734998
-0.368843 -0.319411 0.872887 -0.24938 -0.798426 0.54802 -0.0984517 -0.950836 0.293628
-0.66899 -0.561804 0.48665 -0.573497 0.517834 -0.634783 -0.934294 0.219331 -0.281048
-0.566153 -0.781677 -0.261631 0.839666 -0.138027 -0.525271 -0.312362 0.94996 0.00261234
-0.910303 -0.40317 0.0938195 0.401091 -0.0668485 0.913596 -0.754771 -0.55993 0.341759
--0.994941 0.0826658 -0.0570787 0.725394 0.6883 0.00686926 0.265795 0.9093 0.320198
-0 -0.185408 0.982662 -0.368689 -0.345428 0.862988 -0.823699 -0.0296295 0.566252
--0.706004 -0.644612 -0.293316 -0.313848 -0.849235 -0.424617 0.157286 0.259059 0.952969
--0.568035 0.0908856 0.817971 0.897795 -0.439829 0.0226716 -0.304582 0.64458 0.701246
--0.241642 0.283963 0.927887 -0.393831 0.65717 0.64267 -0.384949 0.88418 0.264652
-0.501991 -0.00994041 -0.864816 0.892835 0.275335 0.356421 0.996713 0.0228604 0.0777253
-0.235249 0.88545 0.400794 0.0265536 0.862992 -0.504519 -0.461695 0.619809 -0.634567
-0.015591 0.930263 -0.366562 -0.279485 -0.960092 0.0105233 -0.274154 -0.961669 0.00568194
--0.201044 -0.979353 0.0211785 -0.0885584 -0.996071 0 0 -1 0
-0 -0.999816 -0.0191892 -0.0667311 -0.997587 -0.0191465 -0.0785018 -0.996512 -0.0283222
-0 -0.999901 -0.014081 0.111426 -0.993624 -0.0171897 0.182745 -0.983081 0.0124766
-0.14425 -0.988923 0.0349697 0.209281 -0.975923 0.061447 0.20126 -0.977087 0.0692509
-0 -0.995197 0.0978883 -0.10444 -0.974769 0.197275 0 -0.983175 0.182666
-0 -0.990057 0.140664 0.0975198 -0.991451 0.0866843 -0.446082 -0.894992 0
--0.465128 -0.885243 0 -0.308237 -0.951157 -0.0170229 -0.263313 -0.964684 0.00718127
-0.1499 -0.983638 0.0999335 0.0198833 -0.994163 0.106044 -0.0851522 -0.991866 0.0946136
-0.354005 -0.919619 0.170241 0.608501 -0.760931 0.22519 0.607536 -0.761714 0.225149
--0.682813 -0.716331 0.143649 -0.43741 -0.874004 0.211633 0.30826 -0.943021 0.12525
-0.695662 -0.664041 0.274049 -0.564745 -0.825265 0 -0.610299 -0.792104 0.0102787
--0.46671 -0.884401 -0.00408499 0.430166 -0.866834 0.252104 0.146086 -0.980865 0.128695
--0.235457 -0.963758 0.125423 -0.698113 -0.704852 0.125786 0.796187 -0.442326 0.412837
-0.73523 -0.487031 0.471421 0.825203 -0.255697 0.503645 0.0075539 -0.89136 0.453234
--0.712932 -0.697357 0.0736295 -0.669195 -0.738447 0.0829133 0.863017 -0.249821 0.439079
-0.924922 -0.0660658 0.374373 -0.725353 0.565463 0.392574 -0.532116 -0.821564 0.20466
--0.668001 -0.705112 0.237892 0.336973 -0.937546 0.0863569 0.399804 -0.914306 0.0648134
--0.328104 -0.944567 0.0118388 -0.388972 -0.92125 0 -0.437541 -0.898948 0.0212141
-0.842528 -0.454397 0.289257 -0.919454 -0.060292 0.388549 -0.916877 -0.297229 0.266443
-0.614886 -0.788568 0.0086409 0.769212 -0.638913 -0.0101843 -0.489603 -0.870405 0.0518098
--0.517831 -0.854646 0.0378242 -0.475235 -0.879761 -0.0131553 -0.454792 0.773371 -0.441658
-0.457439 0.470894 -0.754327 0.637711 0.755443 -0.150434 0.195588 0.97794 -0.0733455
--0.351294 0.91877 -0.180151 0.569061 -0.803759 0.173612 -0.73254 -0.656961 0.17829
-0.15325 -0.973776 0.168149 -0.661326 -0.726081 0.188294 0.883769 -0.459398 -0.0889158
-0.908735 -0.400459 -0.117617 -0.487417 -0.870388 0.0696311 -0.486002 -0.872009 0.05833
-0.30655 0.892601 -0.330593 0.287824 0.897735 -0.33351 0.198127 0.936202 -0.290295
-0.140983 0.94177 -0.305276 0.0184246 0.95071 -0.309534 -0.266425 0.916503 -0.298396
--0.439484 0.867163 -0.23427 -0.453132 0.863108 -0.22297 0.928792 -0.271056 -0.252733
--0.708115 -0.624926 -0.328695 -0.366922 -0.927089 0.0766459 0.975779 -0.110088 -0.18904
--0.515842 -0.851813 0.0912198 -0.894821 -0.434946 0.100591 0.168938 -0.985625 0.00180683
-0.610801 -0.790751 0.0404458 0.62596 -0.778972 0.0370939 -0.679775 -0.722261 0.127458
--0.474595 -0.877109 0.0737466 0.460456 0.850674 -0.253641 0.29013 0.924335 -0.24785
-0.180154 0.948812 -0.259422 0.165823 0.939665 -0.299219 0.282149 0.900644 -0.330502
--0.455763 0.862374 -0.220434 -0.311262 0.92517 -0.217201 -0.24785 0.95001 -0.189871
--0.214222 0.959033 -0.185375 -0.184099 0.796646 -0.575728 0.589037 -0.674199 -0.445523
--0.0897068 -0.937437 -0.336401 0.961929 0.166077 -0.217051 -0.987045 0.150574 0.0554062
-0.604209 -0.796135 0.0331723 0.544451 -0.83808 0.0345683 -0.28431 -0.948035 0.142823
--0.222907 -0.964731 0.140025 0.149932 -0.97456 0.166591 -0.448672 -0.88538 0.12164
-0.327741 0.853608 -0.404893 0.356679 0.857281 -0.37128 0.427049 0.847627 -0.314894
-0.479715 0.839502 -0.255168 -0.180057 0.964724 -0.19206 -0.17241 0.949471 -0.262258
--0.401497 0.867562 -0.293492 -0.390424 0.877381 -0.278874 0.879973 0.436878 -0.186507
--0.8848 0.465867 0.00985042 0.536194 -0.843495 0.0318177 0.605344 -0.794767 0.0436388
-0.616143 -0.78655 0.0413109 -0.609367 -0.781239 0.135415 -0.454729 -0.878828 0.144508
--0.333345 -0.935307 0.118666 0.596007 0.736388 -0.320169 0.359282 0.851087 -0.382842
--0.381715 0.880964 -0.279637 -0.388603 0.850528 -0.354387 -0.421969 0.843939 -0.331223
--0.430517 0.844565 -0.318378 -0.111816 0.901373 -0.418359 0.764673 0.614553 -0.193905
-0.875611 0.446136 -0.185119 -0.87505 0.483939 0.009489 -0.87991 0.475038 0.00987847
-0.583376 -0.811049 0.043256 0.455673 -0.888468 0.0546554 -0.784014 -0.607878 0.125727
--0.812292 -0.56948 0.125995 0.52514 0.8029 -0.2821 0.470129 0.831596 -0.295679
-0.588126 0.743735 -0.317752 -0.329969 0.889279 -0.316708 -0.0609368 0.962802 -0.263247
--0.0487821 0.963446 -0.263423 -0.26952 0.919791 -0.285207 -0.465079 0.84739 -0.256188
--0.106709 0.895169 -0.432764 0.619572 0.756938 -0.207787 0.687799 0.699214 -0.195019
--0.90749 0.418979 -0.0303091 0.398396 -0.915758 0.051644 0.452701 -0.891031 0.0335334
-0.526696 -0.849625 0.02701 -0.846911 -0.50641 0.162144 0.632236 0.632236 -0.447834
-0.0810448 0.921649 -0.379466 0.311677 0.885447 -0.344734 0.533229 0.797007 -0.283632
--0.467859 0.846086 -0.255435 -0.257223 0.932138 -0.254863 -0.105308 0.967076 -0.231677
--0.149137 0.955078 -0.256094 -0.234589 0.927496 -0.291064 -0.210937 0.922849 -0.322265
-0.462607 0.856168 -0.230153 0.607283 0.764151 -0.217441 -0.915423 0.401011 -0.0345132
--0.917805 0.394702 -0.0429383 0.545751 -0.837912 0.00765966 0.536292 -0.837903 -0.101538
-0.514291 -0.852072 -0.0973555 -0.438949 -0.893575 0.0940605 -0.643464 -0.747248 0.166055
-0.331179 0.804293 -0.49339 0.652385 0.671787 -0.350849 -0.167097 0.925588 -0.339655
--0.139846 0.929562 -0.341113 -0.277767 0.902352 -0.329555 -0.162397 0.924959 -0.343624
-0.042895 0.93654 -0.347926 0.197486 0.895271 -0.399361 0.0469726 0.935839 -0.349284
-0.206169 0.91721 -0.34091 0.452113 0.861337 -0.231715 -0.906546 0.412737 -0.0884435
-0.478404 -0.874821 -0.0762803 0.525524 -0.849231 -0.0512869 0.582049 -0.812504 -0.0325002
--0.674652 -0.73764 0.0270694 -0.745972 -0.665709 0.0188854 0.565346 0.785774 -0.250884
-0.545339 0.80327 -0.239507 0.336209 0.906564 -0.255159 0.504298 0.800663 -0.323452
--0.863022 0.501553 -0.0603085 0.674282 -0.738209 -0.019787 0.792273 -0.607985 -0.0515567
--0.83483 -0.548247 0.0498406 0.640116 0.735073 -0.223426 0.569923 0.786184 -0.238962
--0.860948 0.505315 -0.058522 -0.828601 0.553486 -0.0841081 0.847111 -0.511494 -0.144143
-0.838008 -0.525074 -0.148458 -0.845244 -0.528173 0.0812146 0.607048 0.767285 -0.2068
-0.56719 0.795933 -0.211626 0.637268 0.737754 -0.222729 -0.873019 0.481051 -0.0801752
--0.889695 0.44926 -0.0812946 0.720579 -0.633612 -0.281605 0.559646 -0.819889 -0.12074
-0.563916 -0.818588 -0.109145 -0.846393 -0.523492 0.097849 -0.838657 -0.535475 0.0996064
-0.778682 0.597046 -0.192849 0.722873 0.660975 -0.201412 -0.944739 0.320337 -0.0696634
-0.635403 -0.769735 -0.0614203 0.706902 -0.706216 -0.0393486 -0.747686 -0.657963 0.0897223
-0.84117 0.510537 -0.178283 -0.985739 0.165025 -0.0329462 0.82516 -0.564333 0.0252922
-0.842692 -0.537594 0.0293678 -0.766405 -0.637963 0.0750128 0.879043 0.439522 -0.184673
-0.843606 0.506872 -0.177228 -0.98623 0.1627 -0.029661 0.892631 -0.450742 -0.00643918
--0.787627 -0.611447 0.0759991 -0.844881 -0.529365 0.0771261 0.879973 0.436878 -0.186507
--0.987768 0.15465 -0.0199549 -0.985775 0.165093 0.0315033 0.901295 -0.433181 -0.00465786
-0.906341 -0.422545 -0.0011836 -0.894208 -0.440431 0.0800783 0.917305 0.346811 -0.195637
-0.882356 0.432583 -0.185256 -0.996776 -0.0190001 0.0779493 0.860584 -0.507798 0.0391984
--0.875593 -0.477047 0.0759135 0.914808 0.347158 -0.206418 -0.918262 -0.375653 0.125218
--0.647596 0.627359 0.432481 -0.574074 0.683601 0.450698 -0.628074 0.664893 0.404278
--0.658946 0.629894 0.411126 0.833918 -0.547733 0.0675979 0.840194 -0.537841 0.0692894
--0.895805 -0.441217 0.0534809 0.914241 0.355832 -0.19377 -0.958697 -0.265429 0.102213
--0.485848 -0.696872 0.527562 -0.374688 -0.745019 0.551866 -0.538516 -0.66768 0.514008
-0.915806 -0.384406 0.116326 -0.911935 -0.4079 0.0446234 0.946198 0.252955 -0.201799
-0.916367 0.351076 -0.192397 -0.980923 -0.115036 0.156704 -0.462568 -0.72496 0.510357
-0.938309 -0.327317 0.11153 0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338
-0.951038 0.208849 -0.227835 -0.973728 -0.156552 0.165366 0.935161 -0.334447 0.116703
--0.947121 -0.318063 0.0424084 -0.946323 -0.320875 0.0388939 0.939721 0.268262 -0.21204
--0.970249 -0.173227 0.169145 0.937562 -0.330556 0.108213 -0.940597 -0.336391 0.0460259
-0.938056 0.283766 -0.198817 -0.970969 -0.173905 0.164244 0.942445 -0.316493 0.107842
-0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338 0.965795 0.178257 -0.188318
-0.94359 0.267626 -0.194972 -0.958271 -0.238916 0.156961 0.932844 -0.333618 0.136021
--0.955365 -0.292313 0.0427776 -0.964187 -0.262245 0.0396281 0.977703 0.0987872 -0.185307
--0.927979 -0.331878 0.169444 0.934909 -0.329621 0.131511 -0.967903 -0.24577 0.0525545
-0.982451 0.085296 -0.165878 -0.9542 -0.24866 0.166347 0.939229 -0.315413 0.135511
-0.937489 -0.317879 0.141657 -0.968373 -0.243346 0.0550971 0.983436 0.0874351 -0.158771
--0.970969 -0.173905 0.164244 0.951928 0.306221 -0.00782675 0.744662 0.667362 0.0103067
--0.447367 0.858657 -0.250141 -0.920055 0.277962 -0.276109 0.930883 -0.332917 0.150409
--0.959368 -0.259522 0.11073 0.980586 0.0876947 -0.175389 -0.984588 -0.0919425 0.148774
-0.972924 0.205659 -0.105466 -0.939769 -0.284404 -0.189602 0.91166 -0.378968 0.158931
--0.95251 -0.284331 0.108994 -0.94166 -0.319294 0.106431 0.976638 0.0810446 -0.199021
--0.960915 -0.208065 0.182621 0.807409 0.585228 -0.0748237 -0.999142 -0.0344532 0.0229688
-0.907595 -0.389554 0.156585 0.898921 -0.414243 0.14263 -0.935161 -0.334447 0.116703
-0.968309 -0.00756491 -0.249642 -0.943049 -0.298862 0.146083 0.827908 0.551939 -0.0996556
-0.829409 0.553701 -0.0741315 -0.988999 0.0766979 0.126484 0.923209 -0.350874 0.156754
--0.938228 -0.330791 0.101521 0.81747 0 -0.575971 0.886783 -0.136041 -0.441712
-0.953334 -0.135022 -0.270043 -0.914936 -0.375234 0.148631 0.979671 0.163446 -0.116317
--0.963879 -0.205729 0.169155 0.970969 -0.173905 0.164244 -0.942445 -0.316493 0.107842
--0.94166 -0.319294 0.106431 0.940581 -0.229456 -0.250316 -0.915144 -0.379766 0.135234
--0.912054 -0.39573 0.107493 0.975988 -0.184472 -0.115832 0.994562 -0.07154 -0.0756873
--0.924056 -0.334353 0.185281 -0.96241 -0.212743 0.168844 0.973323 -0.159799 0.164642
--0.932844 -0.333618 0.136021 0.958965 -0.188685 -0.211623 -0.929024 -0.353084 0.110664
-0.981489 0.19151 0.00177324 -0.914695 0.195669 0.353619 0.927322 -0.339685 0.157127
--0.942986 -0.305259 0.132647 0.967742 -0.176726 -0.179562 -0.944318 -0.324169 0.0563772
-0.778301 0.622885 -0.0791354 0.799704 0.595128 -0.0793504 -0.8851 0.366684 0.286604
--0.827431 0.48322 0.286107 -0.5688 -0.724941 0.388494 0.558626 0.791388 0.248278
-0.034426 0.998353 0.0459013 -0.617527 -0.693453 0.371191 0.920138 -0.349707 0.176216
--0.936023 -0.320393 0.145633 -0.927877 -0.338893 0.155552 0.979754 -0.101184 -0.172753
-0.981068 -0.085914 -0.173564 -0.938781 -0.343883 0.0208414 0.886292 0.462413 -0.0256896
--0.678384 -0.345007 0.648664 -0.819457 -0.320657 0.475047 -0.940819 -0.210288 0.26578
-0.686347 0.630996 0.361624 0.751684 0.602857 0.267457 0.706789 0.660391 0.25364
--0.819705 0.102463 0.563547 -0.8922 -0.181026 0.413774 -0.627888 -0.689446 0.361138
-0.933945 -0.320608 0.157981 -0.918705 -0.372095 0.13239 0.981989 -0.0742681 -0.173727
--0.917171 -0.398376 0.00965761 0.947075 0.290642 0.136296 -0.226875 -0.948751 0.22
--0.557122 -0.793708 0.244218 0.587346 0.306441 0.749079 0.874185 0.417752 0.247557
--0.906806 -0.303399 0.292664 -0.913171 -0.31716 0.255985 0.927322 -0.339685 0.157127
--0.956602 -0.274784 0.0969827 0.94461 -0.272176 -0.183391 -0.933106 -0.359366 0.0130463
--0.943618 -0.330819 0.0119795 0.368099 -0.609268 0.70235 0.913666 0.201007 0.353284
--0.66647 -0.719787 0.194228 -0.65525 -0.721163 0.224879 -0.297492 -0.946762 0.12305
-0.898269 0.175236 0.402994 0.92303 0.26147 0.282221 0.910131 0.340691 0.23578
--0.414276 -0.659075 0.627691 -0.768872 -0.586989 0.253535 -0.867554 -0.438009 0.23558
-0.920138 -0.349707 0.176216 -0.982641 -0.175995 0.0586652 0.91092 -0.365516 -0.19137
--0.969412 -0.230631 0.0839648 -0.755723 -0.432203 0.49202 0.948314 0.0278916 0.316105
--0.785132 -0.42864 0.44703 0.556362 -0.568725 0.605816 0.656064 -0.498123 0.566969
-0.276547 -0.769146 0.576139 -0.543138 -0.78524 0.297319 0.970969 -0.173905 0.164244
--0.982995 -0.179131 0.0404011 0.929544 -0.325885 -0.172474 -0.928036 -0.356484 0.108025
--0.781546 -0.390773 0.486295 0.32972 -0.74187 0.583879 0.982172 -0.0879557 0.166139
--0.984305 -0.174911 0.0234358 0.925966 -0.337834 -0.168689 0.922301 -0.342488 -0.17906
--0.840928 -0.522527 0.140736 0.960749 -0.239534 0.139946 -0.995476 -0.0885055 0.0345593
-0.893041 -0.408998 -0.187614 -0.8376 -0.529841 0.133024 -0.899114 -0.436794 0.0283632
-0.935161 -0.334447 0.116703 -0.997618 0 0.0689857 0.843606 -0.506872 -0.177228
-0.84233 -0.508536 -0.178528 -0.994726 -0.101503 -0.014764 0.344364 0.0153051 0.938711
-0.384816 0.25161 0.888037 0.45747 0.0714796 0.886348 0.334283 -0.276146 0.90111
-0.388453 -0.371265 0.843367 -0.0610664 0.692086 0.719227 0.341072 -0.259577 0.903488
--0.531593 0.607067 0.590659 -0.487994 -0.350143 0.799538 -0.848697 -0.414609 0.328348
-0.963556 -0.255241 0.0800755 -0.994649 0 0.103311 0.886275 -0.419608 -0.196078
--0.437057 0.874115 -0.211907 0.405084 0.914226 0.00991031 0.488817 0.86761 0.091162
-0.210173 0.928038 0.307526 -0.469168 0.310748 0.82663 0.0414232 0.925119 0.377412
--0.66882 0.299209 0.680554 -0.802416 0.0272005 0.596145 -0.797353 -0.246454 0.550898
-0.144292 -0.272552 0.95126 0.319219 -0.520209 0.792137 0.0466797 -0.855794 0.515206
--0.598057 -0.628148 0.497754 0.994258 -0.089038 0.0593587 -0.994649 0 0.103311
-0.816194 -0.5454 -0.190699 0.813785 -0.548357 -0.192508 -0.67218 -0.640671 -0.371099
--0.557019 -0.768686 -0.314406 -0.0780157 -0.84517 -0.528773 -0.740772 -0.666695 0.082308
-0 -0.853639 -0.520865 0 -0.999504 0.0314805 0 -0.994853 0.101328
-0 -0.909398 0.415926 0 -0.934997 0.354654 -0.147687 -0.912182 0.382248
--0.837426 -0.233381 0.494218 0.995086 0 0.0990135 -0.994649 0 0.103311
-0.835057 -0.518216 -0.184747 -0.926832 -0.344868 -0.148485 -0.0234658 -0.863541 -0.503732
--0.00729327 -0.99772 0.0670981 0.0127155 -0.925688 0.378074 0.995086 0 0.0990135
--0.994649 0 0.103311 0.820178 -0.547229 -0.166876 0.811536 -0.559388 -0.168805
--0.956952 -0.264351 -0.119839 -0.982107 -0.175595 -0.0680601 0.995086 0 0.0990135
--0.994649 0 0.103311 0.803754 -0.56963 -0.17176 -0.932644 -0.351766 -0.0802274
-0.994258 0.089038 0.0593587 -0.994649 0 0.103311 0.797774 -0.57796 -0.171809
-0.754661 -0.632201 -0.175526 -0.297991 -0.736701 -0.60702 -0.39539 -0.691932 -0.604067
-0.0430287 -0.774517 -0.631088 0.48321 -0.683083 -0.547637 0.485352 -0.7371 -0.470232
-0.578083 -0.662522 -0.476323 -0.928843 -0.368139 -0.0415336 -0.975413 -0.220063 0.0118953
-0.98126 0.175193 0.0802233 -0.994649 0 0.103311 0.718864 -0.672108 -0.177497
-0.695091 -0.695091 -0.183567 -0.551784 -0.551784 -0.625355 -0.58159 -0.63064 -0.513855
--0.626391 -0.584163 -0.516128 0 -0.40364 -0.914918 -0.245541 -0.613852 -0.750264
-0.773549 -0.0521494 -0.631587 -0.627189 -0.137893 0.766564 -0.935451 0.350794 0.0433079
--0.898769 0.436471 0.0413227 0.982812 0.158012 0.0954571 -0.994649 0 0.103311
-0.185375 0.17796 0.96642 0.857402 -0.483663 0.175877 -0.338906 0.897994 0.280623
--0.712029 0.66542 0.224121 -0.780361 0.588177 0.212333 0.695091 -0.695091 -0.183567
-0.695091 -0.695091 -0.183567 -0.40364 0 -0.914918 -0.613852 -0.245541 -0.750264
-0 0 -1 0.382859 -0.316729 -0.867814 0.6379 -0.38274 -0.668276
--0.837997 0.535257 -0.106115 0.979643 0.159679 0.12166 -0.994649 0 0.103311
-0.738928 -0.627898 0.244395 -0.713958 -0.294895 0.63506 -0.909343 0.239301 0.340339
-0.695091 -0.695091 -0.183567 0.673365 -0.714803 -0.188773 -0.564888 -0.451911 -0.690419
--0.522083 -0.540085 -0.660104 0 -0.342852 -0.939389 -0.229748 -0.742263 -0.629493
-0.0276674 -0.774687 -0.631739 0.58132 -0.72818 -0.36307 0.529586 -0.781548 -0.329728
--0.912074 0.372537 -0.171281 -0.961153 0.247659 -0.121864 0.973547 0.173 0.149255
--0.994649 0 0.103311 0.748742 -0.614416 0.248752 0.635278 -0.541163 0.550967
-0.674978 -0.528131 0.51525 0.4346 -0.39114 0.811253 0.647272 -0.736992 -0.194632
-0.592917 -0.77952 -0.201986 -0.374299 -0.374299 -0.848411 -0.522083 -0.540085 -0.660104
--0.484928 -0.464723 -0.740863 0 0 -1 -0.32432 -0.32432 -0.888613
--0.15923 -0.641385 -0.750514 0.129084 -0.619922 -0.773973 0.547381 -0.800591 -0.243777
-0.437088 -0.782692 -0.443111 0.570316 -0.795567 -0.204483 0.571862 -0.794706 -0.20351
--0.940204 -0.335531 -0.0586132 0.971269 0.176995 0.15909 -0.991959 -0.073494 0.103032
-0.890045 0.193488 0.412774 -0.601734 0.657157 0.45394 -0.559559 0.742089 0.36905
-0.593383 -0.776323 -0.212648 0.690387 -0.682013 -0.241294 0.695867 -0.676604 -0.240784
--0.334529 -0.559575 -0.758265 -0.351027 -0.604546 -0.715055 -0.229748 -0.742263 -0.629493
--0.511382 -0.665985 -0.543095 0 0.208691 -0.977982 0.576997 -0.552269 -0.601726
-0.695706 -0.683943 -0.219579 0.765076 -0.601888 -0.228887 -0.88332 -0.466227 -0.04877
--0.696474 -0.717474 0.012444 0.982172 0.0879557 0.166139 -0.991745 -0.0846403 0.0963246
-0.80803 0.512788 0.290062 -0.0340272 0.782625 0.621563 -0.650659 0.679684 0.338633
--0.575574 0.698237 0.425652 0.573936 -0.783507 -0.238148 0.570736 -0.786242 -0.23682
--0.304518 -0.790296 -0.531697 -0.352924 -0.764669 -0.53919 -0.269052 -0.739894 -0.616578
--0.336836 -0.759934 -0.555916 0.22181 -0.208763 -0.95248 -0.201876 -0.232063 -0.951521
-0.689665 -0.515507 -0.508541 0.911446 -0.334489 -0.239547 -0.32526 -0.94218 0.0806431
--0.310025 -0.947492 0.0783771 -0.513201 -0.857889 0.0255324 0.985993 0 0.166785
--0.995816 0 0.0913839 0.922812 -0.350879 0.159065 -0.769477 -0.246993 0.588982
--0.680666 -0.490079 0.544533 0.607283 -0.764151 -0.217441 0.598502 -0.772542 -0.21207
--0.266017 -0.752103 -0.602972 -0.278994 -0.80958 -0.516471 -0.404761 -0.769046 -0.494708
--0.0803889 -0.840429 -0.535926 -0.334393 -0.759983 -0.557321 0.968851 -0.186702 -0.162698
--0.442193 -0.895896 0.0428444 -0.484923 -0.87324 0.0479871 -0.375434 -0.9257 0.0461502
--0.346325 -0.934029 0.0874559 0.985993 0 0.166785 -0.991745 0.0846403 0.0963246
-0.492928 -0.860757 0.126966 0.0776973 -0.99064 0.112229 -0.0571247 -0.991282 0.11873
--0.493055 -0.84793 0.19471 -0.653859 -0.553454 0.515904 0.590372 -0.780377 -0.20609
-0.572871 -0.793442 -0.205594 -0.324841 -0.593574 -0.736307 -0.45913 -0.688695 -0.561159
--0.404494 -0.674157 -0.617977 -0.281767 -0.569727 -0.772022 -0.350017 -0.725961 -0.592004
-0.985853 -0.159009 -0.0530029 -0.864813 -0.480157 0.146788 -0.692506 -0.714244 0.101443
-0.983335 -0.0733832 0.166335 -0.991959 0.073494 0.103032 0.00402836 -0.993661 0.112346
-0.587596 -0.69129 -0.420535 0.58271 -0.785392 -0.208824 0.56284 -0.791292 -0.238892
-0.562033 -0.79094 -0.241935 -0.226493 -0.82773 -0.513385 -0.241248 -0.861599 -0.446595
--0.365597 -0.8165 -0.446841 -0.0694331 -0.883694 -0.462887 -0.292104 -0.823202 -0.48684
--0.431539 -0.721202 -0.541887 0.961957 -0.269611 0.0441523 -0.73451 -0.576341 0.358227
--0.952994 -0.155379 0.260117 0.970003 -0.163404 0.179981 -0.994649 0 0.103311
-0.521358 -0.801554 -0.292741 0.471267 -0.826425 -0.308107 -0.517718 -0.711862 -0.474575
--0.457399 -0.73991 -0.493274 -0.350017 -0.725961 -0.592004 0.938158 -0.332209 0.097448
--0.711954 -0.561604 0.421571 -0.738749 -0.211071 0.640077 -0.776984 0.365639 0.512449
-0.526008 0.850448 0.00736319 0.561594 0.827147 -0.0209819 -0.398197 0.911999 -0.0984787
--0.996499 -0.0379831 -0.0744768 0.973268 -0.0957941 0.20874 -0.994649 0 0.103311
-0.432317 -0.845277 -0.314021 0.277767 -0.902352 -0.329555 0.29672 -0.896508 -0.328984
-0.30655 -0.892601 -0.330593 -0.211224 -0.895818 -0.391017 -0.246372 -0.893097 -0.376401
--0.19087 -0.90133 -0.388809 -0.380769 -0.826024 -0.415571 0.91681 -0.368812 0.153092
--0.574699 -0.549468 0.606471 0.00420699 -0.37863 0.925539 -0.202648 0.572181 0.794696
-0 0.447214 0.894427 -0.630304 0.467218 0.620019 -0.614424 0.384409 0.688995
--0.597018 0.447763 0.665641 0.345204 0.927614 0.14271 0.219501 0.969407 0.109858
--0.229929 0.965862 0.119341 -0.518612 0.842456 0.14598 0.761176 0.567208 0.314463
-0.480353 0.857773 0.182992 0.412654 0.903095 0.118895 -0.83391 -0.525598 -0.168348
--0.73334 -0.668785 -0.122223 0.977765 0 0.209704 -0.990783 0.0880882 0.102909
-0.318775 -0.888499 -0.330079 0.414728 -0.854726 -0.312161 0.393909 -0.871766 -0.291306
--0.167097 -0.925588 -0.339655 -0.210937 -0.922849 -0.322265 0 -0.938787 -0.344499
--0.123661 -0.931581 -0.341855 -0.122384 -0.945694 -0.301139 -0.20314 -0.91973 -0.335902
--0.28152 -0.89949 -0.334162 0.896953 -0.419203 0.140515 0.871755 -0.470252 0.137501
--0.268549 -0.960267 0.0759533 0.175164 -0.967724 0.181186 0.856429 -0.394109 0.333477
-0.445689 -0.869571 0.212622 -0.336085 -0.93357 0.124476 0.0232069 -0.999117 -0.0350139
-0.373427 -0.908543 -0.187355 0 -0.357789 0.933803 -0.323885 -0.689561 0.647769
--0.677957 0.0739589 0.731372 0.94085 -0.210308 0.265652 0.847716 0.493216 0.195232
--0.82378 0.554737 0.116848 -0.850412 0.525255 0.0301072 0.724963 0.626742 0.285698
-0.717732 0.67434 0.173569 0.683848 0.706168 0.183517 0.425656 0.243232 0.871582
--0.379604 -0.827626 0.413445 -0.799874 -0.599905 0.017775 -0.784501 -0.613566 0.0899658
-0.97202 -0.108245 0.208472 -0.980301 0.1742 0.0930774 0.342227 -0.896509 -0.28134
-0.149137 -0.955078 -0.256094 0.0528742 -0.971123 -0.232647 0 -0.972483 -0.232972
-0 -0.90031 -0.435249 -0.0528742 -0.971123 -0.232647 -0.149137 -0.955078 -0.256094
--0.234589 -0.927496 -0.291064 0.78306 -0.599178 0.166741 -0.502994 -0.864119 0.0171964
--0.441164 -0.896792 0.0337502 -0.327019 -0.94308 0.0604809 0.970338 -0.188498 0.15137
--0.82888 -0.559316 0.0110834 -0.893176 -0.448092 -0.0380928 0.963121 0.216896 -0.159229
--0.759243 -0.172095 0.627641 -0.150614 -0.506612 0.848917 -0.326814 -0.673139 0.663383
-0.987592 -0.127364 0.091869 0.984198 -0.176688 0.0116819 -0.391963 0.905571 -0.162192
--0.806214 0.586434 -0.0781912 -0.444323 0.654278 -0.611962 -0.927756 -0.0655707 -0.367382
-0.601259 0.720474 0.345551 0.73298 0.662853 0.152857 0.686924 0.703664 0.18164
--0.284726 -0.260999 0.922394 -0.571962 -0.784995 0.237995 -0.573067 -0.796486 0.192884
--0.621233 -0.762161 0.182152 0.938767 -0.287472 0.18994 -0.981345 0.178831 0.0705833
-0.803877 -0.572697 0.160625 0.832671 -0.512363 0.210101 -0.544894 -0.838298 0.0186288
--0.480725 -0.876849 0.00632533 0.994235 0.0699282 0.081284 -0.973598 0.122971 -0.192316
-0.738164 0.649585 -0.182081 0.860037 0.474696 -0.187086 -0.991592 -0.0517088 0.118626
-0.961565 0.272979 -0.0295963 -0.799181 0.592106 -0.103538 -0.967347 0.190745 -0.166901
--0.911891 -0.333191 -0.239664 0.860748 0.472624 0.189049 0.865778 0.469974 0.171908
-0.863642 0.474633 0.169839 0.114888 0.0774826 0.990352 -0.7072 -0.65397 0.268685
--0.693397 -0.690052 0.207434 -0.602114 -0.772772 0.200705 0.965312 -0.182386 0.186835
--0.994258 0.089038 0.0593587 0.750582 -0.592685 0.292147 -0.397157 -0.917569 -0.0182601
--0.388419 -0.921292 -0.0187255 -0.450752 -0.892649 0 0.929841 0.356706 0.0903121
--0.39972 -0.799439 0.448466 -0.0508834 -0.85371 0.518257 -0.692984 0.694726 -0.192689
-0.0248318 0.980858 -0.193137 0.162674 0.967991 -0.191129 0.662743 0.717365 -0.214845
--0.984132 -0.176639 0.0168228 0.856534 0.514883 -0.0352879 0.936277 0.349317 -0.0369269
--0.942913 -0.331188 0.035067 0.403378 0.541117 0.737887 0.994668 0.0219412 0.100767
--0.704075 -0.656962 0.26959 -0.603306 -0.784298 0.14456 -0.724981 -0.660808 0.194253
-0.981579 0.0849699 0.17112 -0.998223 0 0.0595954 0.727857 -0.618455 0.296204
-0.0147027 -0.940973 0.338162 0.0770382 -0.969719 0.231757 0.582397 -0.804078 0.119466
-0.66045 -0.737666 0.140195 -0.582227 -0.812493 0.0294295 -0.179542 -0.980125 -0.0843751
-0.229626 -0.971496 -0.0588786 0.08238 -0.99386 -0.073869 -0.01356 -0.997112 -0.0747306
--0.00279177 -0.997221 -0.0744473 -0.178722 -0.983813 -0.0130727 -0.416589 -0.909073 0.00627838
-0.765165 0.633543 0.114658 0.792715 0.598654 0.114961 -0.575386 -0.405201 0.710453
--0.0360068 -0.711135 0.702133 0.631299 -0.26971 0.72713 0.13398 0.973679 -0.184389
--0.786589 -0.587223 -0.190908 0.683335 0.729251 -0.0352922 0.72863 0.683751 -0.0397755
--0.798233 -0.578233 0.168732 -0.866879 -0.482376 0.125837 0.323581 -0.942908 0.0788656
--0.502939 -0.858277 0.102046 0.973728 0.156552 0.165366 -0.998223 0 0.0595954
-0.777952 0.529219 -0.3387 0.749279 0.613653 -0.249019 0.309423 0.948679 -0.0653135
-0.20013 0.979296 0.0304582 0.089334 0.982674 0.162392 -0.235125 0.953014 0.190998
--0.546514 0.805437 0.229332 -0.568801 0.78387 0.249027 0.485678 -0.857445 0.170016
--0.159158 -0.968464 0.191691 -0.636435 -0.766822 0.0832775 0.799041 0.585829 0.135416
--0.0232585 -0.424468 0.905144 0.756611 0.346981 0.554206 -0.707849 -0.671763 -0.218369
--0.847774 -0.51472 -0.127839 -0.656344 -0.725433 -0.207267 0.407615 0.912807 0.0251809
-0.530167 0.847803 -0.012388 -0.558937 -0.792326 0.24456 -0.621979 -0.753065 0.214559
-0.322649 0.875361 -0.360058 0.278898 0.756639 -0.591366 -0.26714 0.252299 -0.930044
--0.327934 0.213539 -0.92025 -0.509336 -0.0836223 -0.856495 -0.744883 -0.440047 -0.501506
--0.865884 -0.368839 -0.337938 0.974931 0.158911 0.155747 -0.998223 0 0.0595954
-0.886257 -0.418595 -0.198309 -0.819473 -0.281649 0.499138 -0.916385 -0.078894 0.392447
--0.898507 -0.211238 0.384791 0.989082 -0.0196767 0.146045 0.938853 0.309822 0.150217
--0.784379 -0.182088 0.592953 0 -0.471215 0.882018 0.604551 -0.453413 0.654931
--0.170221 -0.958912 0.226962 0.340323 0.850809 0.400381 0.0535363 0.963654 0.261733
-0.322316 0.799344 0.507111 0.240544 0.955847 0.168803 0.119379 0.967217 0.224141
-0.0841203 0.96101 0.263407 0.242414 0.965428 0.0958381 -0.667303 -0.696589 0.263574
--0.78311 -0.594693 0.181875 -0.583646 -0.781176 0.221631 0.418615 0.897032 0.141753
-0.409875 0.900101 0.147717 0.327479 0.936939 0.122079 -0.0806806 0.996095 0.035858
--0.478523 0.849237 -0.223185 -0.616534 0.561904 -0.551498 -0.560483 0.552552 -0.616884
-0.43921 0.380418 -0.813865 0.323313 0.0668923 -0.943925 0.281222 0.55646 -0.781836
--0.414636 -0.763803 -0.494653 -0.560148 -0.737139 -0.37797 -0.491984 -0.242527 -0.836141
--0.484683 -0.846938 -0.218583 0.972022 0.172729 0.159181 -0.982641 0.175995 0.0586652
-0.524648 -0.851137 -0.0176141 0.283137 -0.958311 0.0383739 -0.286332 -0.94321 0.16843
--0.486938 -0.844547 0.222782 -0.889608 -0.255526 0.378556 0.959574 -0.242135 0.143488
-0.882036 -0.450006 0.139671 -0.742364 0.593891 0.310143 0.918054 0.0612036 0.391703
--0.299391 -0.953943 -0.0189158 -0.408799 -0.907228 -0.0991028 -0.149332 -0.981512 0.119729
--0.188888 -0.969078 0.158775 -0.214925 -0.965081 0.149754 -0.06556 -0.971108 0.22946
-0.891861 0.0964174 0.441913 0.942344 -0.105825 0.317474 -0.98989 0.00856306 0.141576
-0.574859 0.817835 0.0261383 0.550082 0.833389 0.0536054 0.453329 0.880641 0.137707
--0.874919 -0.271263 -0.401164 -0.337804 -0.855989 -0.391372 -0.25232 -0.820983 -0.512173
--0.290521 -0.933019 -0.212304 0.972073 0.177141 0.153934 -0.929024 0.353084 0.110664
-0.180625 -0.981099 0.0694205 0.0125628 -0.995155 0.0975114 -0.158983 -0.977415 0.139228
--0.314324 0.679726 0.662701 0.0455877 0.747638 0.662541 -0.27552 0.74046 0.613032
--0.470453 0.623969 0.623969 0.852567 0.518954 0.0617802 0.078002 0.972492 0.219486
--0.282537 0.936832 0.206202 0.0781423 0.967762 0.239436 0.290705 0.935707 0.19986
-0.162957 0.972994 0.163484 -0.649065 0.740365 0.174855 -0.859571 0.508927 0.0461662
-0.938298 -0.295476 0.179694 -0.323151 -0.799539 0.506271 0.539562 -0.756329 0.369918
-0.0591047 -0.990004 0.12806 -0.447683 0.826491 0.34131 -0.372896 0.864362 0.337382
--0.623361 -0.749652 -0.222359 -0.841719 -0.497379 -0.210055 0.923711 -0.300417 0.237713
--0.747978 0.635781 0.190556 0.615968 0.782256 -0.0930588 0.645985 0.760378 -0.0672901
--0.924648 -0.344908 -0.161446 0.982172 0.0879557 0.166139 -0.93006 0.340688 0.137551
--0.468715 0.338517 0.815912 0.998236 -0.0576002 -0.0143583 -0.338731 0.193561 0.920758
--0.981036 -0.193008 -0.0177724 0.970405 -0.193783 0.144095 -0.191495 -0.833568 0.518164
--0.464684 -0.883052 0.0654866 -0.676968 -0.734808 0.0421014 -0.0893582 -0.994723 0.0504072
--0.0905864 -0.990233 0.10598 -0.180049 -0.978796 0.0976737 0.527412 -0.846036 0.0778419
-0.750225 -0.653257 0.102071 -0.877754 0.455368 -0.148952 0.615922 -0.74676 0.250977
-0.408844 -0.906834 0.102467 -0.738009 0.654412 0.164583 -0.228873 0.972709 -0.0381454
-0.337487 0.935758 -0.102269 0.581949 0.807511 -0.0962396 -0.913794 -0.406131 -0.0061535
--0.90515 -0.419733 0.0672855 0.985993 0 0.166785 -0.973323 0.159799 0.164642
-0.893689 -0.438371 -0.0956583 0.734908 -0.666249 -0.126582 -0.34802 -0.912492 0.215037
-0 -0.9837 0.179816 -0.256757 -0.960868 0.103963 -0.534985 -0.841855 0.0712107
-0.992076 0.0888426 0.0888426 -0.77454 -0.580905 0.250276 -0.731025 -0.629021 0.264453
--0.151516 -0.925564 0.346949 0.144294 -0.945232 0.292771 0.0801606 -0.921847 0.379173
--0.0369768 -0.90593 0.421809 -0.288508 -0.601059 0.745313 -0.0283629 -0.855615 0.516835
-0.630647 -0.667527 0.395845 0.752454 -0.620057 0.222132 -0.859289 -0.492892 0.136672
--0.858604 -0.506671 0.0779977 0.78356 -0.609436 0.12092 0.773686 -0.613753 0.157216
--0.83706 0.506832 -0.206039 0.397346 -0.914024 0.0817053 0.640441 -0.765318 0.0642225
-0.626561 -0.775742 0.0751431 -0.904265 -0.368404 0.215833 0.985993 0 0.166785
--0.985993 0 0.166785 0.127883 -0.989553 -0.0665629 -0.234956 -0.971224 0.0389789
--0.222632 -0.960744 0.165547 -0.0664783 -0.986728 0.148152 0.854386 0.515038 0.0689927
--0.883359 -0.419596 0.208844 0.746926 -0.630354 0.211557 0.391488 -0.897001 0.205246
--0.644467 -0.731907 0.221299 0.74956 -0.643764 0.154037 0.728101 -0.667812 0.154586
--0.84479 0.495855 -0.20114 -0.939313 0.337442 -0.0618315 0.577231 -0.812488 0.0816531
-0.54668 -0.829782 0.112265 0.0757077 -0.791146 0.606924 0.122598 -0.98078 0.151787
--0.935367 -0.344489 0.0801019 0.982172 0.0879557 0.166139 -0.991737 0 0.128284
-0.698525 0.709022 0.0966993 0.709161 0.698746 0.0940498 -0.921047 -0.292973 0.256591
--0.924892 -0.296325 0.238257 0.433101 -0.880099 0.194548 -0.605116 -0.759848 0.237625
-0.759829 -0.631018 0.156451 0.772156 -0.617008 0.151905 -0.968309 -0.239311 0.0714704
-0.526635 -0.840004 0.130571 0.163394 -0.972194 0.167751 -0.29119 -0.934755 0.203569
--0.25437 -0.951374 0.173732 0.796281 -0.566678 0.21169 0.828117 -0.516914 0.216846
--0.183889 -0.981474 0.0537944 -0.320398 -0.946777 0.0309718 0.2411 -0.966844 0.0841678
-0.233528 -0.969895 0.069054 -0.903472 -0.428388 0.0148887 -0.611621 -0.79001 -0.0424737
-0.95884 0.249869 0.134877 -0.995086 0 0.0990135 0.842244 0.527974 0.108947
-0.749169 0.654664 0.100806 -0.763318 -0.501609 0.407103 -0.924073 -0.100311 0.368819
-0.925196 0.201129 0.321807 0.380651 0.827094 0.413547 -0.0736462 0.97213 0.222575
--0.113333 0.988034 0.104615 0.125218 0.990362 0.059194 0.0616862 0.99647 -0.0569411
--0.604642 0.77921 -0.165047 -0.654665 0.737226 -0.167066 0.595467 -0.782614 0.181476
--0.473794 -0.85559 0.208531 -0.6647 -0.724096 0.184008 0.840159 -0.507061 0.192413
--0.64744 -0.761694 -0.0253898 -0.490858 -0.871197 0.00863829 0.167001 -0.983267 0.0727743
--0.236405 -0.971655 0 0.932844 0.333618 0.136021 -0.982641 0.175995 0.0586652
--0.39749 0.0709803 0.914857 0.80754 0.13459 0.574251 -0.39443 0.302396 0.867745
--0.663323 0.151617 0.732813 0.89597 0.443798 0.0167471 -0.912339 -0.180567 0.36747
--0.861592 -0.292516 0.414841 -0.899625 -0.282235 0.333194 0.886292 -0.462413 0.0256896
--0.841918 0.528263 -0.110055 -0.0856621 -0.980355 0.177669 0.73686 -0.653738 0.172233
--0.147438 -0.989063 0.0040955 -0.406043 -0.912823 -0.043394 0.960749 0.239534 0.139946
--0.929024 0.353084 0.110664 -0.320564 0.0674871 0.94482 0.39365 0.919182 -0.0119893
-0.726182 0.68718 -0.0210488 -0.724245 -0.654157 0.218052 -0.449876 -0.736161 0.505646
--0.84227 -0.409501 0.350558 0.746128 -0.664265 -0.0452199 -0.848602 0.516435 -0.114763
--0.352292 -0.935056 -0.0395094 0.922438 -0.359595 0.140711 0.987849 0.0884641 0.127781
--0.934583 0.342345 0.096723 0.257508 0.835331 0.485707 0.0494662 0.831032 0.554021
--0.217452 0.848061 0.483226 0.322634 0.939848 0.112221 0.0790893 0.996705 0.0179748
--0.180111 0.978306 -0.102358 -0.333222 0.928936 -0.161372 0.916886 0.387913 0.0940396
-0.161262 0.983526 0.0816756 0.238774 0.971075 0 -0.777287 -0.606089 0.168764
--0.74616 -0.633307 0.205349 0.776905 -0.629617 -0.00107903 0.762229 -0.64725 0.00859036
--0.872436 0.473766 -0.120006 -0.863423 0.485162 -0.13827 0.901675 0.430157 -0.0441187
-0.983641 0.178108 -0.026986 -0.213526 0.97368 0.0797165 -0.264783 0.957141 0.117354
--0.398744 0.886098 0.236293 0.992076 0.0888426 0.0888426 -0.964809 0.244802 0.0960009
-0.195266 0.78616 0.586365 0.747579 0.615653 0.249193 -0.883377 0.376598 0.278961
--0.841635 0.479792 0.247892 0.631517 0.758482 0.16091 0.509108 0.846123 0.157752
--0.73302 0.640187 -0.229873 -0.985746 0.0789435 -0.148572 0.94526 0.322741 0.0481914
--0.707235 -0.681672 0.18746 -0.749768 -0.638475 0.173774 0.745203 -0.66536 0.0443573
--0.561706 0.6366 -0.528419 -0.843485 0.316307 -0.434147 0.907987 -0.404496 0.109285
--0.869999 -0.39875 0.29 -0.80228 0.566315 -0.188772 0.965174 0.25152 0.0719457
--0.98126 0.175193 0.0802233 0.420999 0.90047 0.109148 0.214094 0.961517 0.172189
-0.177858 0.966364 0.185763 0.289185 0.937659 0.19279 -0.887417 0.371686 0.272656
-0.867886 0.286595 0.405756 0.879213 0.432113 0.200654 0.713733 0.678553 0.173641
--0.743582 -0.659084 -0.112664 0.796122 0.601769 0.0637452 -0.783658 -0.602979 0.149319
--0.730793 -0.660824 0.171037 0.560643 0.824475 -0.076951 0.0938288 0.995588 0.000955
--0.771634 0.635276 0.031711 -0.801444 0.59723 0.031681 0.727177 -0.677801 0.108628
-0.717909 -0.686696 0.11426 -0.403455 -0.14483 -0.903464 -0.754303 -0.258618 -0.603443
--0.739379 -0.285893 -0.609577 -0.902111 0.0674808 -0.426194 0.898344 -0.425962 0.107401
-0.530778 -0.836912 0.133612 -0.654043 -0.744256 0.135319 0.935161 0.334447 0.116703
--0.968373 0.243346 0.0550971 0.271817 -0.888631 -0.369392 0.905576 -0.424178 -0.00248785
--0.898645 0.246485 0.362881 -0.878041 0.269225 0.395679 0.942709 0.00771658 0.333528
-0.944479 0.0718895 0.320611 -0.532907 -0.836714 -0.126171 -0.418588 -0.906668 -0.0523235
-0.688407 0.716801 0.110871 0.762943 0.642586 0.0707184 -0.90686 -0.392522 0.153399
-0.998228 -0.0462258 0.0374804 -0.997735 -0.057916 0.0342231 0.491553 -0.849046 0.193642
--0.451911 -0.891608 0.0284989 -0.72445 -0.678208 -0.123311 -0.154193 -0.90974 -0.385483
-0.521877 -0.84215 0.135751 0.0316642 -0.987177 0.156458 0.94166 0.319294 0.106431
--0.945479 0.321611 0.051337 0.504367 -0.852206 0.139136 0.0773271 -0.947258 0.311004
--0.270119 -0.764532 0.585257 -0.393708 0.51711 0.759994 -0.337067 0.41068 0.847188
--0.511949 0.500043 0.698473 0.749796 0.644924 0.147914 0.372719 0.873962 0.311884
--0.27968 0.925729 0.254567 -0.387366 0.867965 0.31078 -0.209284 0.863295 0.459262
--0.221396 0.846047 0.484962 -0.225881 0.797226 0.55983 -0.22643 0.769375 0.597321
--0.370753 0.750334 0.547303 0.936041 -0.0744578 0.343924 0.22259 -0.926929 0.302087
--0.0853507 -0.971545 0.220943 -0.27938 -0.954058 0.108262 -0.394411 -0.91891 -0.00662875
-0.899368 0.412949 0.143561 0.751775 0.647856 0.122955 -0.938592 -0.319268 0.130814
-0.733675 -0.669384 0.116817 -0.938927 -0.333841 0.0834602 0.137194 -0.968931 0.205791
--0.146459 -0.97814 0.147622 -0.020719 -0.80804 0.588764 0.150539 -0.784057 0.602156
-0.0168332 -0.52183 0.852883 -0.249279 -0.807447 0.534686 0.937562 0.330556 0.108213
-0.942445 0.316493 0.107842 -0.93994 0.336695 0.0561158 0.236437 -0.956391 0.171506
-0.0787831 -0.982312 0.169871 -0.0329484 -0.98484 0.170308 -0.0917315 -0.974491 0.204825
--0.187575 -0.935656 0.298936 -0.22054 -0.803395 0.5531 -0.0340662 0.0170331 0.999274
--0.393818 -0.393818 0.830551 0.120903 -0.70527 0.698553 -0.70527 0.120903 0.698553
--0.671994 -0.186091 0.716794 0.954748 0.168736 0.244917 0.953272 0.197675 0.228465
-0.935294 0.277849 0.219148 -0.580904 0.783082 0.22211 -0.792735 0.0468434 0.607764
--0.94386 0.152858 0.292854 0.667641 0.731633 0.137727 0.784931 0.605469 0.131491
--0.600932 0.348833 0.719164 -0.714862 0.194962 0.671537 0.987926 0.0177048 0.153913
--0.960602 -0.241393 0.137742 0.729484 -0.66932 0.140939 0.173191 -0.899037 0.402166
-0.424978 0.882816 0.200076 0.39292 0.894521 0.21318 -0.103486 0.952782 0.285478
--0.21034 0.893083 0.397692 -0.539139 0.787489 0.298648 -0.0822085 -0.829234 0.552823
-0.935161 0.334447 0.116703 -0.944881 0.32297 0.0537605 -0.223261 -0.458925 0.859967
-0.784895 -0.242509 0.570201 0.829037 -0.138173 0.541854 -0.661083 -0.669713 0.338309
--0.687977 -0.651833 0.319062 0.573134 0.807597 0.138941 0.65065 0.744605 0.149055
--0.9574 -0.109048 0.267382 0.991783 0.117286 0.0510981 -0.951919 -0.257508 0.165949
-0.895763 0.0453551 0.442212 0.912843 0.0370907 0.406624 0.882829 -0.0764655 0.463428
--0.517766 0.534577 0.667941 -0.0185995 0.658955 0.751953 -0.034456 0.955934 0.291551
-0.343907 0.910341 0.230234 0.45066 0.870621 0.197292 -0.777171 0.564647 0.277809
--0.92431 0.299776 0.236187 0.915302 0.380062 0.133326 -0.945479 0.321611 0.051337
-0.61184 0.772478 0.170087 0.0868562 0.959366 0.268465 -0.18378 0.966933 0.176819
--0.0796151 0.987227 0.138 -0.133291 0.911708 0.388616 -0.0562991 0.925181 0.375327
--0.264587 0.841867 0.470376 0.609402 -0.370421 0.701012 -0.666254 -0.674645 0.317743
-0.299222 0.933099 0.199481 0.18655 0.967198 0.172417 0.474731 0.864116 0.167134
--0.969563 -0.217657 0.112126 0.949223 0.314029 0.019032 -0.946577 -0.28256 0.155408
--0.937489 -0.317879 0.141657 0.902487 -0.0638929 0.425952 0.83711 -0.413388 0.358269
-0.403713 0.858964 0.314954 -0.982239 0.010807 0.187322 0.170172 0.96184 0.214256
-0.322634 0.939848 0.112221 0.235282 0.957355 0.167672 -0.251342 0.952172 0.173767
--0.650482 0.757175 0.0596562 0.890888 0.428295 0.151266 0.907316 0.395497 0.142689
--0.916348 0.396628 0.0547073 0.79735 0.601228 -0.0525137 0.816542 0.569431 0.0949051
--0.936468 -0.248335 0.247703 0.622716 0.770025 0.138877 0.639269 0.757837 0.130452
-0.328412 0.921155 0.208854 -0.90309 -0.429338 -0.00986984 0.962071 0.272799 0
-0.952346 0.304588 0.0162447 -0.900467 -0.409868 0.145494 0.882518 -0.468838 -0.0367716
--0.984232 -0.0461571 0.170751 0.756585 0.596597 0.267678 0.734355 0.622262 0.271132
-0.230891 0.935931 0.265936 0.189247 0.96344 0.189657 0.189054 0.962454 0.194782
--0.189464 0.964546 0.183723 -0.487393 0.856514 0.169799 -0.391319 0.904234 0.170972
-0.734944 0.673608 -0.0781624 0.68022 0.730716 -0.0579226 0.216172 0.976324 0.00774349
-0.0927428 0.99513 0.0333874 -0.705545 0.70769 0.0371716 -0.849536 0.263464 -0.457029
--0.909507 0.196297 -0.36642 0.898921 0.414243 0.14263 -0.907331 0.412992 0.0786651
-0.972589 0.00495136 -0.232478 0.963906 0.19031 -0.18619 -0.849418 -0.501891 0.163079
-0.479853 0.870845 0.106634 0.620652 0.778636 0.0922828 -0.847093 -0.529328 -0.0473859
-0.936479 0.350724 0 -0.886935 -0.436849 0.150029 0.979753 -0.188784 -0.0666717
--0.98167 0.0994456 0.162586 0.905524 0.109557 0.409908 0.967228 0.00614113 0.253834
--0.430995 0.889658 0.150838 -0.4468 0.880649 0.157567 -0.423661 0.90028 -0.100031
--0.290129 0.928414 -0.232104 0.462084 0.873942 -0.15068 0.625276 0.769006 -0.132889
--0.676037 -0.730851 -0.0939666 -0.627252 -0.774974 -0.0772701 0.915704 0.380649 0.12881
-0.910762 0.390913 0.133042 -0.94485 0.320375 0.0679584 0.935441 -0.261671 -0.237653
-0.463751 -0.879528 -0.106609 -0.646283 -0.752002 0.129656 -0.833262 -0.528879 0.161124
-0.556124 0.826158 0.0904978 0.545323 0.831994 0.102023 0.496161 0.858403 0.130261
--0.84961 -0.52248 -0.0719597 -0.829593 -0.549583 -0.0986588 0.922822 0.385228 0
--0.904864 -0.404737 0.131941 0.979963 -0.199179 0 -0.988907 0.0111331 0.148118
-0.950273 0.291417 0.109809 0.32035 0.944621 0.0711888 -0.209442 0.977802 -0.00608843
--0.334132 0.942514 0.00479042 -0.417537 0.908529 0.0154643 0.876575 -0.443532 0.186803
--0.372264 0.908099 -0.191772 -0.0882881 0.975584 -0.201101 0.304687 0.935642 -0.178157
--0.435788 -0.896981 0.0742598 -0.528449 -0.84741 0.0513582 0.904864 0.404737 0.131941
--0.94561 0.317556 0.0705679 -0.940309 0.331525 0.0768753 0.328661 -0.943846 0.0337088
--0.130234 -0.985437 0.109332 -0.613055 -0.778677 0.133517 0.737178 0.641024 -0.213675
--0.941726 -0.325287 -0.0856723 0.0731249 0.967077 0.24375 0.0333514 0.9682 0.247945
--0.0491532 0.966679 0.251227 0.950925 0.309421 0 0.935084 0.354427 0
--0.915704 -0.380649 0.12881 0.957916 -0.280314 0.0618193 -0.986087 -0.143278 0.084281
-0.961897 -0.242722 0.125856 -0.567532 0.82305 0.0222562 -0.790305 0.609033 -0.0670562
-0.832218 -0.523935 0.181399 0.668505 -0.724698 0.167072 -0.336249 -0.939275 0.0685467
--0.373255 -0.914115 0.158351 -0.308917 -0.940954 0.13848 -0.346823 -0.931835 0.106756
-0.891109 0.438905 0.115268 -0.909999 0.407034 0.0788965 0.655354 0.472465 -0.589311
-0.715155 0.131873 -0.686413 -0.970202 -0.240965 0.0253648 -0.980567 -0.182926 0.0709014
-0.55495 0.793739 0.249016 0.564847 0.796469 0.215836 -0.74402 0.6392 0.194569
--0.795926 0.597597 0.0968449 0.987001 0.160715 0 -0.910762 -0.390913 0.133042
--0.898921 -0.414243 0.14263 0.9271 -0.356142 0.11683 0.855212 -0.493465 0.158443
--0.966198 -0.256732 -0.0234648 0.835548 -0.538439 0.109282 -0.752948 0.649358 -0.106788
--0.63996 0.734769 -0.224867 0.644276 -0.746059 0.168239 0.421389 -0.893143 0.157251
-0.302968 -0.939202 0.161583 -0.0432635 -0.822006 -0.567833 -0.730952 -0.472755 -0.49215
--0.00879051 -0.959924 -0.280124 -0.0714231 -0.975179 -0.209583 -0.187769 -0.964695 -0.18468
--0.312614 -0.94709 -0.0727582 -0.331391 -0.941849 0.0556724 0.69814 0.679073 0.226847
-0.704182 0.678293 0.209874 0.136649 0.976065 0.169185 -0.782013 0.616988 0.0882119
--0.962902 0.26848 0.0271878 0.87301 0.47564 0.1078 -0.894208 0.440431 0.0800783
-0.58504 0.645561 -0.490896 0.565425 0.565425 -0.60049 0.345295 0 -0.938494
-0.183808 -0.76865 -0.612692 0 -0.87317 -0.487416 0.256686 -0.81284 -0.52288
-0.369262 -0.812376 -0.45132 -0.324628 -0.945655 -0.018819 0.125901 -0.99192 -0.0155877
-0.279469 -0.958763 -0.051678 -0.979733 -0.139762 0.143489 0.842539 -0.401381 0.359194
-0.816503 0.468688 0.337126 0.656996 -0.399171 0.639546 -0.987105 0.151862 -0.0506207
-1 0 0 -0.872008 -0.466563 0.148061 0.62707 -0.777092 0.0539647
-0.618165 -0.784549 0.0485288 -0.925432 -0.311053 -0.216385 -0.912262 -0.334167 -0.236878
-0.834184 -0.540728 0.108402 0.871034 -0.478699 0.110216 -0.603543 0.766511 -0.219538
--0.219701 0.957567 -0.186539 -0.164018 0.973854 -0.157183 -0.109557 0.99348 -0.031539
--0.307155 0.950999 0.035441 0.17421 -0.968971 0.175348 0.166698 -0.972992 0.15968
-0.353095 -0.920885 0.165211 0.54846 -0.822689 0.14958 -0.77583 -0.573902 -0.262153
--0.890532 -0.287568 -0.352502 0.620804 0.64591 0.444301 0.626694 0.663362 0.408907
-0.618814 0.673415 0.404453 0.726395 -0.333287 0.601057 0.229135 -0.910085 0.345316
--0.682228 -0.730959 0.0162435 0.894208 0.440431 0.0800783 -0.907331 0.412992 0.0786651
-0.681032 0.376741 -0.627902 -0.241627 -0.638585 -0.730634 -0.366851 -0.791307 -0.489135
-0.567982 -0.743976 -0.351989 0.601696 -0.75212 -0.268843 0.561811 -0.783055 -0.266819
--0.544378 -0.838636 -0.0185274 -0.466562 -0.881284 -0.0752192 0.821962 -0.557699 -0.115544
-0.99236 -0.0870827 -0.0874017 -0.994794 0.0306877 0.0971778 0.779985 -0.548672 0.300969
-0.314976 -0.926439 0.206159 0.0796151 -0.987227 0.138 -0.118885 -0.990709 0.0660473
-1 0 0 -0.866056 -0.478626 0.144445 -0.876693 -0.463248 0.129658
-0.692094 -0.711521 -0.12142 0.673143 -0.641088 -0.368626 -0.840155 0.228775 -0.491734
--0.794007 0.174681 -0.582271 0.904379 -0.415125 0.0988393 -0.188828 0.964867 -0.182688
--0.540485 0.83688 0.0866467 -0.750966 0.659385 -0.0355224 0.472117 -0.881286 0.020983
--0.689591 -0.678858 -0.252224 -0.76161 -0.58942 -0.269323 0.690456 0.0470766 0.721841
-0.844057 0.19916 0.497899 0.776658 0.44287 0.44796 -0.227808 -0.672703 0.703971
--0.686188 -0.648067 0.330387 -0.470251 -0.853687 0.223791 0.865962 0.49676 0.0577907
--0.94485 0.320375 0.0679584 0.810314 0.450174 -0.375145 -0.385487 -0.416151 -0.82354
--0.124783 -0.945051 -0.302172 -0.435675 -0.89242 -0.117358 0.845825 0.506554 -0.167283
--0.90183 0.432091 -0.00038614 1 0 0 -0.89611 -0.430805 0.106743
-0.933381 0.285803 -0.217065 -0.863862 0.284682 -0.41557 -0.920171 0.288747 -0.264404
-0.909999 -0.407034 0.0788965 -0.76547 0.642157 -0.0411043 -0.682768 0.720467 -0.121474
-0.487663 -0.624719 0.609845 -0.232717 -0.867757 0.439137 0.87627 0.474048 0.0861905
--0.946459 0.317841 0.056505 -0.942007 0.332123 0.0481338 0.477676 0.877509 0.0424601
-0.0474296 0.986536 -0.156518 -0.909538 0.400197 -0.112176 0.665187 0.741896 -0.0843615
-0.837273 0.520343 -0.16798 -0.897915 0.440169 0.000488263 -0.814913 0.579494 0.0102154
-1 0 0 -0.946887 -0.315629 0.0615072 -0.964187 -0.262245 0.0396281
-0.913814 0.396829 -0.0864277 -0.982288 0.0762009 -0.171185 0.88096 -0.463637 0.0945998
--0.765014 0.639602 -0.0752473 -0.938451 0.345317 -0.00812512 0.802708 0.596364 -0.00310001
--0.911935 0.4079 0.0446234 0.405731 0.894223 0.189072 0.330252 0.920704 0.207937
-0.0132112 0.95121 0.308262 -0.855886 0.109428 0.505455 -0.880425 0 0.474186
--0.894675 -0.0378345 0.445112 0.784203 0.615061 0.0820082 0.523255 0.850394 0.0550795
--0.978238 -0.19341 0.0751261 0.748462 0.656814 0.0916485 0.683425 0.727721 -0.0579108
--0.84381 0.536501 -0.0122825 -0.875652 0.482762 -0.0132554 1 0 0
--0.998383 -0.0380227 0.0422474 0.68437 -0.28888 0.669467 0.756813 -0.24925 0.604242
-0.701308 -0.137098 0.699551 -0.622639 0.437793 0.648582 -0.623985 0.339192 0.703983
--0.666768 0.35864 0.653298 0.78887 0.613957 -0.0272198 0.909601 0.407789 -0.0795857
--0.964919 -0.225766 -0.134017 0.874059 -0.476451 0.0949511 0.466345 -0.875391 0.12733
--0.191218 -0.978682 -0.0749441 -0.18324 -0.980797 -0.0667926 0.185905 -0.979727 -0.0746564
-0.206426 -0.976194 -0.0665889 -0.91413 -0.36041 0.185666 -0.392605 0.326002 0.859991
--0.111041 0.142767 0.983508 -0.441563 0.454179 0.773786 -0.493862 0.409681 0.766982
-0.804592 0.572029 0.159418 0.789212 0.592309 0.162218 -0.696034 0.685325 0.214164
--0.671285 0.706616 0.223762 -0.817155 0.547715 0.179627 0.754161 0.651321 0.0837957
-0.77317 0.634173 0.00579153 -0.896946 0.441779 0.0178497 0.862379 0.493586 0.112583
-0.599199 0.783999 0.162192 -0.452839 0.251577 0.855363 -0.832275 -0.488101 0.262824
--0.89702 -0.0967048 0.431281 0.883359 0.462319 0.0770532 -0.887349 -0.450996 0.0959912
-0.627455 0.778103 0.029252 -0.944143 0.328398 -0.0273665 -0.993313 0.0180057 -0.114036
-0.999408 0 -0.0344137 -0.998955 -0.0284287 0.0357992 0.670098 -0.383875 0.635302
--0.640411 0.15137 0.752968 0.682656 0.730145 0.0294609 0.709228 0.704913 -0.00970806
--0.862109 -0.49602 -0.103594 -0.793538 -0.602136 -0.0879165 0.320821 -0.937495 0.13482
-0.0602766 -0.997713 0.0305881 -0.110478 -0.993817 0.0110316 0.467763 -0.883552 0.0230994
-0.402916 -0.895479 0.189144 0.238213 -0.944344 0.226869 -0.786527 -0.566171 0.246628
-0.857732 -0.219715 0.464781 0.859164 -0.271201 0.433921 -0.390518 0.836011 0.385462
--0.0214505 0.87782 0.478511 -0.315553 0.930052 0.188225 0.940861 0.0775968 0.329786
-0.966406 -0.211753 0.145674 -0.816968 -0.576683 0 0.934871 0.354583 0.0169167
--0.877317 0.477987 0.0429295 0.995081 0.0990068 -0.003342 -0.506055 -0.815438 0.281014
--0.580456 -0.792608 0.186665 -0.702755 -0.679441 0.210938 0.873762 0.479722 0.0800368
--0.879136 -0.467433 0.0928828 -0.839357 -0.533423 0.104593 0.792351 0.598665 -0.117385
-0.608994 0.793169 -0.00289584 -0.386139 -0.91992 -0.0681422 -0.501173 -0.864928 -0.0269448
-0.0353772 -0.995515 -0.0877355 0.225014 -0.964347 -0.139295 0.131541 -0.978663 -0.157849
--0.92299 -0.301215 -0.239498 0.994016 0.0808006 -0.0735061 -0.999674 0.0237077 -0.00948307
-0.786206 0.614147 0.0685787 0.745826 0.664091 0.0522191 -0.827312 -0.561551 0.0146811
-0.398312 -0.895884 0.196823 0.890365 -0.257455 0.375455 0.947689 -0.238664 0.211953
--0.311313 0.939372 0.143747 -0.421666 0.893895 0.152152 -0.474223 0.868607 0.143646
-0.783056 -0.613877 0.099896 0.955642 0.293845 0.0201067 0.948216 0.31657 0.0258831
--0.869706 0.493266 0.0173076 0.397071 -0.887569 -0.233571 -0.210322 -0.974072 0.0833535
--0.42977 -0.883827 0.184791 0.817617 0.557814 0.142637 0.870774 0.484908 0.0813462
--0.896909 -0.426012 0.118609 -0.899513 -0.419499 0.122055 0.838843 0.514054 -0.17914
--0.46401 -0.882192 -0.0801993 -0.427994 -0.899229 -0.0905994 -0.449055 -0.888681 -0.0927182
-0.0184781 -0.999355 0.0307968 0.203288 -0.969071 0.139911 0.141264 -0.979215 0.145544
--0.374923 -0.917243 0.134529 -0.648587 -0.760662 0.0269943 0.963864 0.247301 -0.0990371
--0.991303 0.122134 -0.0490118 0.903905 0.418992 0.086033 -0.941562 -0.336377 0.0176268
--0.999317 -0.03624 0.00724799 0.927754 -0.36205 0.0905126 -0.511409 0.843703 0.163175
--0.212154 0.960347 0.180896 -0.00765895 0.967216 0.253839 -0.178031 0.922856 0.341529
--0.812055 0.165164 0.559721 -0.928033 -0.164527 0.334195 0.912076 0.407963 -0.0410359
--0.83404 0.551393 0.0185342 0.893366 0.421589 0.155434 0.885165 0.440939 0.148513
--0.926284 -0.338503 0.165572 0.822803 0.530898 -0.202835 0.843827 0.497414 -0.201334
--0.687959 -0.713822 -0.13104 -0.695958 -0.70123 -0.154657 -0.211188 -0.96277 0.168743
-0.9139 0.395713 -0.0905412 -0.966118 0.249114 -0.0675129 0.943885 0.305949 0.124405
-0.911594 0.4008 0.0914105 -0.933941 0.352142 0.061242 0.919684 -0.392399 0.0143062
-0.916233 -0.400521 0.0100402 -0.471059 -0.203593 0.858285 -0.915223 -0.345325 0.207646
--0.919381 -0.326333 0.219647 0.869706 0.493266 -0.0173076 -0.856248 0.516528 0.00617672
--0.863412 0.5045 0 0.949901 0 0.312551 0.966694 0.133233 0.218522
--0.829007 -0.531972 0.172494 0.854524 0.481433 -0.194963 0.840974 0.507777 -0.186883
--0.696513 -0.697582 -0.168075 -0.691162 -0.703023 -0.167489 0.904852 0.419322 -0.0735652
-0.913292 0.397282 -0.089807 -0.965403 0.252157 -0.0664415 -0.943215 0.327134 -0.0577045
-0.881904 -0.386588 0.269806 0.893837 -0.441355 0.0791225 -0.844528 0.50902 0.166346
-0.886347 -0.463017 0.0020044 -0.0828959 -0.828959 0.553133 -0.804999 -0.542142 0.240952
-0.808104 0.58812 -0.0329227 -0.837432 0.546542 0 0.534473 -0.749104 0.391386
-0.728828 -0.596314 0.336482 -0.379356 -0.895194 0.233918 -0.453989 -0.868649 0.198353
--0.766829 -0.616239 0.179505 0.801561 0.389275 -0.453834 0.674657 -0.500177 -0.542827
--0.273896 -0.903855 -0.328675 -0.502434 -0.846655 -0.175317 0.943631 0.313417 -0.106444
--0.965631 0.253008 -0.0595312 0.480927 -0.874065 0.0687038 0.33854 -0.939856 0.0453944
-0.457787 -0.884002 0.0947145 -0.792912 -0.448754 0.412202 -0.873995 0.430419 0.225547
--0.914481 0.145486 0.37757 -0.924688 0.260226 0.277912 0.705414 -0.705414 0.0691582
--0.559827 -0.828604 -0.00296991 -0.535111 -0.844212 -0.0310209 0.0216605 -0.982702 0.183924
-0.0438133 -0.986753 0.156204 -0.478183 -0.847161 0.231646 0.792308 0.609598 0.0252596
-0.806769 0.590681 -0.014824 -0.821657 0.569983 0 -0.758782 0.651344 0
-0.419925 -0.835832 0.353621 -0.381501 -0.902954 0.197816 0.369933 -0.494845 -0.786307
-0.147043 -0.735215 -0.661693 0.364599 -0.798177 -0.479563 0.0134744 -0.881226 -0.472503
-0.937113 0.329655 -0.114662 0.942484 0.315008 -0.111777 -0.943881 0.312655 -0.106472
-0.708104 -0.689293 0.153176 0.666982 -0.698981 0.257993 -0.652166 -0.652166 0.386469
--0.195227 -0.980728 -0.00765596 0.810902 0.584913 0.0177246 -0.759496 0.650492 -0.00500152
--0.788524 0.61494 -0.00882193 0.902719 0.410994 -0.127212 -0.930072 0.35149 -0.106866
--0.899866 0.424305 -0.101025 0.436202 0.00411512 0.899839 0.534324 0.0360218 0.844512
-0.235431 -0.0692444 0.969421 -0.599185 -0.607869 0.52103 0.812685 0.582424 -0.0180597
--0.835147 0.548455 -0.0415496 0.88482 0.44965 -0.122098 -0.878117 0.462348 -0.123063
-0.806244 0.35495 0.473267 -0.785754 0.522178 0.331542 -0.769256 0.56541 0.297584
-0.924872 -0.305423 -0.226558 0.725795 0.687257 -0.0299738 0.785491 0.618516 -0.0210092
--0.786373 0.615992 -0.0465999 0.851665 0.50546 -0.138482 0.884147 0.450915 -0.122307
--0.869551 0.480897 -0.112332 -0.87569 0.47276 -0.0983109 0.931887 -0.298993 0.2054
--0.774241 0.584113 0.243645 -0.309426 -0.618853 -0.721995 0.376057 0.924474 0.0626762
-0.143217 0.984764 0.0986342 -0.452387 0.891597 0.0200085 -0.542807 0.839708 0.0158348
-0.687566 0.726122 0 0.707008 0.707008 -0.0166846 -0.762011 0.646569 -0.0358951
--0.725795 0.687257 -0.0299738 0.794815 0.590631 -0.13937 0.806362 0.57469 -0.139682
--0.878117 0.462348 -0.123063 0.818428 -0.574589 0.00482848 -0.889982 0.389367 0.237329
--0.942235 0.240827 0.232799 0.949207 0.244655 -0.197863 0.743874 0.66668 -0.0467846
--0.70665 0.698237 -0.114503 0.632487 0.773272 0.0448425 0.666306 0.745471 0.0175922
--0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846 0.799405 0.586597 -0.129831
--0.850808 0.513854 -0.109911 -0.824838 0.555611 -0.104586 0.793489 -0.607421 -0.0376137
-0.702593 -0.711259 -0.0217755 -0.953977 -0.0681412 0.292034 0.968046 -0.154887 -0.197223
--0.70948 0.695059 -0.116324 -0.750326 0.641609 -0.159214 0.780173 0.619123 0.0895342
-0.649066 0.758225 0.0617139 -0.706805 0.706805 -0.0291896 -0.706805 0.706805 -0.0291896
-0.836657 0.530563 -0.136042 0.811074 0.570608 -0.128706 -0.733792 0.668275 -0.122299
-0.567254 -0.815787 0.11276 -0.496535 -0.722233 0.481489 0.915373 -0.377906 -0.138846
-0.909728 -0.394216 -0.130341 -0.77009 0.621238 -0.145001 -0.809467 0.575253 -0.117678
-0.794994 0.605489 0.0369765 0.819705 0.568624 0.0689241 -0.706805 0.706805 -0.0291896
--0.706805 0.706805 -0.0291896 0.789101 0.598476 -0.138368 0.806362 0.57469 -0.139682
--0.702247 0.702247 -0.117041 0.381865 0.816705 0.432633 0.468256 0.784886 0.405822
-0.374228 0.83328 0.406938 0.15149 0.908938 0.388435 0.976021 -0.206743 -0.0681131
--0.837875 0.54286 -0.0571733 -0.825293 0.564318 -0.0209006 0.699576 0.714556 -0.00188929
-0.726079 0.687511 0.011738 -0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846
-0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662 0.972209 0.0920126 0.215275
--0.431596 0.868096 0.245225 0.0797681 0.765773 0.638144 -0.566086 0.804585 0.179415
--0.589585 0.787992 0.177364 0.973088 0.221881 -0.0621977 -0.458034 0.883862 0.0948273
-0.0732056 0.995596 0.0585645 0.532326 0.846239 -0.022555 -0.687257 0.725795 -0.0299738
--0.64644 0.761859 -0.0410583 0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662
-0.959724 0.0239931 0.279919 0.982839 -0.150106 0.107219 0.432905 0.132964 0.891579
--0.388253 0.745925 0.541161 -0.619265 0.76639 0.170755 -0.615557 0.769446 0.170418
-0.510862 0.849929 -0.128996 0.719484 0.682962 -0.126123 -0.631207 0.773877 -0.05188
--0.62591 0.777172 -0.0651199 0.702247 0.702247 -0.117041 -0.598023 0.788504 -0.143633
--0.57469 0.806362 -0.139682 0.805703 -0.523707 0.276721 0.81319 -0.521513 0.258352
-0.547421 0.646952 0.530833 -0.510677 0.805299 0.301169 -0.276292 0.621658 0.732942
--0.797498 0.531665 0.285184 0.834017 0.476581 -0.278006 -0.433011 0.899851 -0.0526229
--0.42302 0.905901 -0.0199538 0.968 -0.23474 0.0887333 0.915018 -0.223407 0.335903
-0.963438 -0.255693 0.0800511 -0.675917 0.724073 0.137311 -0.672087 0.729168 0.128893
-0.952642 0.156456 -0.26076 0.458781 0.873746 -0.161518 0.00928327 0.99994 0.00574678
--0.0698733 0.996454 -0.0468715 0.215983 0.970446 -0.107639 -0.625859 0.77732 -0.0638284
--0.597383 0.801148 -0.0360066 -0.580015 0.813834 -0.0354454 0.702247 0.702247 -0.117041
--0.525649 0.839674 -0.136532 -0.570557 0.811923 -0.123471 0.806603 -0.531971 0.257679
-0.7963 -0.482163 0.365275 0.754212 -0.612311 0.237149 -0.828484 0.49962 0.252972
--0.778659 0.562949 0.27709 -0.803751 0.547575 0.232693 0.972897 0.201475 -0.113487
--0.440032 0.897903 -0.0118928 0.0335315 0.997962 -0.0542891 0.309552 0.950768 0.0147406
--0.0730282 0.994077 0.08048 -0.472144 0.872894 0.123031 -0.445174 0.890348 0.0953944
-0.918071 0.367722 0.148076 -0.607681 0.791702 0.0627037 -0.542928 0.837084 0.0672356
-0.96818 0.142503 -0.205721 -0.504826 0.862411 -0.0373945 -0.512535 0.858496 -0.0170845
-0.629993 0.760337 0.158102 0.146781 0.974779 0.168109 -0.405681 0.901513 0.150658
--0.420219 0.89516 0.148677 0.722843 0.687674 0.0678445 0.702802 0.708286 0.0663365
--0.13555 0.988715 -0.0637881 -0.511905 0.856869 -0.0610642 0.702247 0.702247 -0.117041
--0.593961 0.795024 -0.123073 -0.702247 0.702247 -0.117041 0.831794 -0.521423 0.190361
-0.814657 0.569062 0.111816 0.96461 -0.208999 0.160768 -0.468793 0.882546 0.0366937
--0.254913 0.96691 0.0102551 0.324573 0.933702 -0.151171 -0.396089 0.902252 0.170454
--0.36321 0.928204 0.0807134 0.41152 0.909894 -0.0523878 0.74245 0.669215 -0.0303041
--0.431545 0.896854 0.0970712 -0.647366 0.745287 0.159575 -0.754312 0.641948 0.137538
-0.965728 0.181539 -0.185507 -0.547652 0.836428 -0.0215729 -0.509393 0.860512 -0.00614652
-0.893389 -0.447659 0.0381625 -0.683946 0.72111 0.110537 -0.640153 0.766706 0.0486504
-0.888531 0.45377 0.0678611 -0.708849 0.702835 -0.0596345 -0.974618 0.223189 0.017505
-0.702247 0.702247 -0.117041 -0.702247 0.702247 -0.117041 0.996896 0.0750352 0.0238207
--0.238509 0.971074 0.0113576 0.0596535 0.997654 -0.033598 0.243225 0.957762 -0.153403
-0.0867785 0.995858 -0.0271308 -0.789815 0.600173 0.126428 0.871693 0.460363 -0.167982
--0.500058 0.865992 0 -0.468148 0.88365 0 -0.449818 0.893022 0.01323
-0.678991 -0.734044 -0.0122341 0.542535 -0.837459 -0.065714 -0.5071 0.86187 0.00534493
--0.438332 0.895684 0.0749286 -0.42997 0.899028 0.0829143 0.322186 0.946591 0.0127059
-0.307146 0.950664 -0.0435743 -0.181453 0.967752 -0.174733 -0.14762 0.984136 -0.0984136
-0.673835 0.737049 0.0520059 -0.858604 -0.512637 -0.00168354 0.702247 0.702247 -0.117041
--0.665916 0.731202 -0.147981 0.982715 0.181589 -0.0360245 -0.0643781 -0.981086 -0.182556
--0.1195 -0.979236 -0.163759 0.113419 -0.975399 -0.189031 -0.793613 0.595728 0.123635
--0.709686 0.695789 0.11056 0.563008 0.811297 -0.157541 0.528451 0.835585 -0.150126
-0.814319 0.555351 -0.168733 -0.457502 0.888747 0.0286436 -0.550553 0.834103 0.0340962
--0.574767 0.817704 0.0316554 0.534635 -0.840508 -0.0878206 0.649105 -0.740743 -0.173095
-0.737686 -0.658186 -0.150372 -0.363244 0.915201 0.174532 -0.412962 0.880654 0.232187
--0.105526 0.972834 0.206056 0.169772 0.969818 0.175016 0.204462 0.965997 0.158256
-0.15206 0.975996 0.155917 0.173893 0.978574 0.110246 0.292003 0.955725 0.0363921
--0.856901 -0.512676 -0.0537089 -0.812914 -0.577504 -0.0752371 0.479499 0.871225 -0.10511
-0.562478 0.818834 -0.114587 -0.616715 0.771145 -0.158106 -0.535488 0.82647 -0.173781
-0.670118 0.713468 -0.204708 -0.473457 -0.880601 0.0195039 -0.495026 -0.867695 0.0453174
--0.321311 -0.943506 -0.0809718 0.993584 0.111048 -0.0214302 -0.695781 0.712525 0.0905384
--0.599816 0.800085 -0.00925335 0.682727 0.717103 -0.14017 0.673821 0.719973 -0.166148
--0.626889 0.778445 0.0321482 -0.537073 0.843487 0.00904544 0.858828 -0.496212 -0.127234
--0.915686 -0.391304 -0.0916567 0.624353 0.77943 -0.0516923 0.441226 0.896205 -0.0462237
-0.312499 0.946568 -0.0797052 -0.158298 0.966672 -0.201214 0.624981 0.752234 -0.208669
--0.385295 -0.917935 0.0945696 -0.920835 -0.381253 -0.0819083 0.188245 -0.982101 0.00645411
-0.925438 -0.37178 -0.0731078 0.944088 -0.322686 -0.0676105 -0.653123 -0.748006 0.117973
--0.576251 -0.81473 0.0644219 0.99542 0.0704722 0.0645995 -0.58365 0.811376 -0.0319472
--0.227703 0.961412 -0.154397 0.478233 0.861316 -0.171546 -0.497727 0.867334 0
--0.392374 0.919676 0.0154814 -0.397157 0.917569 0.0182601 0.772741 -0.624267 -0.11473
--0.860065 -0.500567 0.0985965 -0.945583 -0.301323 0.12279 0.36121 -0.916403 0.17243
-0.454101 -0.876765 0.158353 -0.887808 -0.448053 -0.105099 -0.717029 -0.691722 -0.0859632
-0.74326 0.66433 -0.0789303 0.727248 0.684071 -0.0561823 -0.679343 0.71428 -0.168218
-0.160269 0.910797 -0.380476 0.884122 0.424657 -0.194924 -0.856608 -0.48949 0.163163
--0.681658 -0.718998 0.13559 0.989926 0 0.141587 -0.478352 0.878168 0
--0.397157 0.917569 -0.0182601 0.75075 -0.637123 -0.174499 0.685822 0.636443 -0.35297
-0.99177 -0.0627702 -0.111592 0.979575 -0.171037 -0.105732 0.986894 -0.119791 -0.108119
--0.917159 0.374499 0.136269 0.443643 -0.887287 0.126107 -0.12786 -0.991428 -0.0268939
-0.64434 0.759385 -0.090338 0.704894 0.704894 -0.0790535 -0.42833 0.888728 -0.163391
--0.0259677 0.969837 -0.242365 0.850593 0.47778 -0.219586 -0.962319 0.271423 0.0164499
-0.909347 0.199221 0.365238 0.965527 0.200753 0.165701 0.992061 0.0646997 0.107833
--0.321976 0.946552 -0.0192389 -0.326273 0.945081 -0.0192006 -0.175995 0.982641 -0.0586652
-0.0976805 0.993085 -0.0651203 0.183147 0.976783 -0.11114 0.0580726 0.97562 -0.211643
-0.265251 0.89973 -0.346594 0.990571 -0.0466412 -0.128819 -0.910502 0.391643 0.132668
--0.784732 0.617641 0.0521165 0.499462 0.85805 -0.119529 0.615386 0.781235 -0.104747
--0.493157 0.867277 -0.0680217 0.662902 0.745765 0.0662903 -0.800862 0.597836 -0.0348297
--0.82467 0.555207 -0.108002 0.394016 0.910313 -0.12681 0.47473 0.87152 -0.122816
--0.207983 0.974714 -0.0817076 0 0.99922 -0.0394837 0.217662 0.976024 0
--0.78792 0.597133 -0.150381 -0.738577 0.656931 -0.151476 0.335756 0.93732 -0.0932657
-0.325028 0.941474 -0.0893519 0.319809 0.940182 -0.117386 -0.312036 0.934975 -0.168689
-0.0745504 0.984242 -0.160342 0.158075 0.973779 -0.163606 0.0663259 0.99153 -0.111663
-0 0.995211 -0.0977514 0.0882513 0.992617 -0.0832084 0.254057 0.962565 -0.0944677
-
diff --git a/Modules/ImageExtraction/Testing/Data/testNrrd.ascii b/Modules/ImageExtraction/Testing/Data/testNrrd.ascii
deleted file mode 100644
index f78381e84b..0000000000
--- a/Modules/ImageExtraction/Testing/Data/testNrrd.ascii
+++ /dev/null
@@ -1,8 +0,0 @@
-2 2
-2 2
-2 2
-2 2
-1 1
-1 1
-1 1
-1 1
\ No newline at end of file
diff --git a/Modules/ImageExtraction/Testing/Data/testNrrd.nhdr b/Modules/ImageExtraction/Testing/Data/testNrrd.nhdr
deleted file mode 100644
index d62bdcaba6..0000000000
--- a/Modules/ImageExtraction/Testing/Data/testNrrd.nhdr
+++ /dev/null
@@ -1,20 +0,0 @@
-NRRD0005
-content: SomeIDNumber42
-type: short
-dimension: 4
-space: right-anterior-superior
-sizes: 2 2 2 2
-thicknesses: NaN NaN 2.5 NaN
-space directions: (2,0,0) (0,2.5,0) (0,0,2) none
-centerings: cell cell cell none
-kinds: space space space list
-endian: little
-encoding: ascii
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-data file: testNrrd.ascii
-measurement frame: (1,0,0) (0,0,1) (0,1,0)
-modality:=DWMRI
-DWMRI_b-value:=1000
-DWMRI_gradient_0000:= 0 0 0
-DWMRI_gradient_0001:= 1 0 1
\ No newline at end of file
diff --git a/Modules/ImageExtraction/Testing/Data/testimage.dcm b/Modules/ImageExtraction/Testing/Data/testimage.dcm
deleted file mode 100644
index ecf7b12d33..0000000000
Binary files a/Modules/ImageExtraction/Testing/Data/testimage.dcm and /dev/null differ
diff --git a/Modules/ImageExtraction/Testing/Data/vtkUnstructuredGrid.vtk b/Modules/ImageExtraction/Testing/Data/vtkUnstructuredGrid.vtk
deleted file mode 100644
index 392ef94c61..0000000000
Binary files a/Modules/ImageExtraction/Testing/Data/vtkUnstructuredGrid.vtk and /dev/null differ
diff --git a/Modules/ImageStatistics/Testing/Data/img.nrrd b/Modules/ImageStatistics/Testing/Data/img.nrrd
deleted file mode 100644
index 04a51b53cb..0000000000
--- a/Modules/ImageStatistics/Testing/Data/img.nrrd
+++ /dev/null
@@ -1,17 +0,0 @@
-NRRD0004
-# Complete NRRD file format specification at:
-# http://teem.sourceforge.net/nrrd/format.html
-content: SomeIDNumber42
-type: short
-dimension: 3
-space: right-anterior-superior
-sizes: 3 3 1
-thicknesses: 1 1 1
-space directions: (1,0,0) (0,1,0) (0,0,1)
-centerings: cell cell cell
-kinds: space space space
-encoding: ASCII
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-
-1 2 3 4 5 6 7 8 9
diff --git a/Modules/ImageStatistics/Testing/Data/lungs.vtk b/Modules/ImageStatistics/Testing/Data/lungs.vtk
deleted file mode 100644
index 5b0f7f17ac..0000000000
--- a/Modules/ImageStatistics/Testing/Data/lungs.vtk
+++ /dev/null
@@ -1,18985 +0,0 @@
-# vtk DataFile Version 3.0
-vtk output
-ASCII
-DATASET POLYDATA
-POINTS 7860 float
-59 174 77.8 95 170 80.2059 55 171 80.2222
-56 171 79.2353 56 172 78.5806 57 172 78.1765
-58 173 78.2 59 173 78.6923 61 173 79.6452
-87 173 80.4194 88 173 79.8 89 173 79.4571
-91 173 80.4706 58 174 78.5172 60 174 78.1765
-89 174 80.4706 91 174 80.8235 59 175 78.5172
-60 175 78.0909 63 175 79.4571 88 175 80.5588
-64 176 80.1429 63 177 80.2059 65 177 80.2059
-67 177 80.1429 81 177 80.4706 82 177 79.8
-84 177 79.8 62 177.087 81 64 177.5 81
-68 178 80.2059 80 178 80.2059 82 178 80.2059
-69 179 79.8529 77 179 80.2059 79 179 79.8
-80 179 80.2059 81 179 80.8235 70 180 80.5455
-74 180 80.4706 114 150 83.4706 113 151 83.4706
-112.739 151 84 114 152 82.8529 39 155 83.8
-38.6667 155 84 113 155 82.8 114 155 82.8
-39 156 83.1429 38.3333 156 84 40 156 83.4706
-114 156 83.1429 40 157 83.1429 40 158 83.8
-40.6667 158 84 42 158.833 84 41.3333 159 84
-109 159 83.4706 112 159 81.1765 113 159 81.4545
-43 160 83.2059 108 160 83.4706 109 160 82.8
-111 160 81.5294 112 160 81.1765 113 160 82.3
-110 161 82.2 111 161 81.5143 112 161 81.8182
-44 162 82.8 45 162 82.8 107 162 83.0323
-109 162 83.0323 110 162 82.2 111 162 82.2
-112 162 83.4828 46 163 83.4194 110 163 83.2059
-46.25 164 84 47 164 83.4194 106 164 82.2
-109 164 83.4706 104 165 83.4 105 165 82.4545
-106 165 82.2 108 165 83.4706 49 166 82.8
-50 166 82.8 51.1667 166 84 103 166 83.9
-51.4 167 84 99 167 83.2174 101 167 81.9
-96 168 83.4828 97 168 82.7 98 168 82.8182
-101 168 81.8824 95 169 81.8824 96 169 81.9677
-97 169 82.5556 93 170 82.3636 93 169.333 84
-96 170 81.2222 54 171 82.6552 93 171 81.6667
-94 171 81.1936 91 172 81.6207 92 172 81.9677
-93 172 81.6 94 172 81.8824 95 172 81.5294
-97 172 83.8846 68 173 83.3333 76 173 83.4706
-85 173 83.6842 86 173 81.7826 93 173 82.2
-71 174 82.6452 76 174 82.4571 84 174 83.6842
-85 174 83.8333 92 174 81.5294 57 174.727 84
-75 175 82.6452 80 175 82.4571 82 175 82.0714
-86 175 81.6 69 176 82.6452 71 176 82.8529
-72 176 83.8064 74 176 83.4194 80 176 82.2
-87 176 81.4545 60.2609 177 84 75 177 82.4571
-87 177 81.5294 89 177 82.8529 81 181.25 84
-115 146.357 87 36 149 86.4194 114 149 84.1765
-36 150 86.4194 37 150 86.8 36.0909 151 87
-37 151 86.0323 37 152 85.5556 37 153 86.0526
-38 153 86.6842 111 153 86.9091 37 154 86.1667
-38 154 84.7826 39 154 85.8261 38 155 84.6667
-38 156 85.0714 37.6538 156 87 41 157 84.6818
-41 158 84.1364 40 159 85.8571 41 159 84.1364
-44 158.278 87 108 159 84.5294 41 160 85.2273
-45.5 160 87 41.2 161 87 47 163 84.2727
-46 164 84.2308 52 165 85.3548 100 165 86.5455
-102 165 84.5294 53 166 86.0323 52 167 84.2647
-106 167 84.5294 51 168 84.9677 53 168 84.4545
-95 167.63 87 53 169 84.2647 92 168.75 87
-105 169 86.2059 67 169.75 87 89 170 84.8824
-98 170 85.56 98 171 85.7727 72 172 85
-74 172 85.5556 82 172 84.5294 84 172 84.6923
-98 172 85.3043 99 172 85.2 73 173 85.8261
-74 173 85.8261 84 173 84.8333 73 174 85.1538
-99 174 86.8235 73 175 85 74 175 84.5172
-184.833 178 87 186 178 85.8462 186 179 85
-188 179 84.9677 189 179 85.3 191 179 85.1818
-193 179 84.375 195 179 85.6552 196 179 86.069
-198 179 85.4545 198 178.261 87 201 179 86.4706
-202 179 86.2059 186 180 86.8235 189 180 85.3548
-190 180 84.6 191 180 84.6 193 180 84.4286
-196 180 86.1 198 180 85.5 200 180 86.2059
-201 179.75 87 193 181 86.8966 68 181.706 87
-82 182 84.5294 84 183.087 87 117 143 89.8
-118 143 89.4706 118 142.25 90 117 144 88.5
-118 144 89.4706 115 145 89.2174 116 145 87.9677
-117 145 88.2 34 146 89.6087 115 146 87.6818
-116 146 87.5769 117 146 89 35 147 87.9677
-116 147 87.2308 35 148 87.5769 36 148 87.4545
-35 149 87.5455 35.7727 152 90 39 153 89.7273
-151 155 88.8 42.6429 157 90 152 157 88.8
-153 157 89.1429 43 157.278 90 44 157.105 90
-45.4545 158 90 152 158 89.8 153 158 89.8
-45.8947 159 90 153 159 89.9 47.2857 161 90
-52 162 89.55 48 162.286 90 55 164 88.3043
-56 164 89.2174 98 164 88.8529 55 165 87.6923
-56 165 89.2174 96 165 89.2059 95.1818 165 90
-99 165 87.9677 45 165.346 90 56 166 88
-63 167 87.375 64.6 167 90 92.7692 167 90
-95 167 89.3182 94.375 167 90 64.3 168 90
-68.3333 168 90 93 167.75 90 93 168 89.5714
-94 168 89 94 167.75 90 72 168.474 90
-73 168.333 90 66 169.4 90 50 170.105 90
-174 175 89.4 175 175 88.8 176 175 89.4194
-176 176 89.0323 177 176 88.6452 178.6 176 90
-181 176 89.4231 181 177 89.3077 181 178 89.04
-182 178 88.7586 183 178 89.3182 184 178 89
-202 178 87.5172 204 178 88.5 182 179 89.4194
-183 179 89.7391 184 179 88.875 204 179 88.1538
-181 180 89.8235 183 180 89.4194 202 180 88
-119 140 92.7778 120 140 91.6452 118 141 91.9615
-119 141 90.8571 120 141 91.2 118 142 90.2
-119 142 90.1765 120 142 91.5 120.654 142 93
-119 143 90.5294 150 145 92.8 149.714 145 93
-150 146 91.8 150 147 91.5 151 147 91.8529
-117.895 148 93 150 148 91.8529 151 148 91.5
-151 149 90.5294 151 150 90.1765 36.5909 153 93
-39 154.5 93 39.1053 155 93 39.1667 156 93
-40 156.526 93 154 157 90.5294 156.105 159 93
-46 159.563 93 50.75 160 93 153 160 91.1471
-155 160 91.7 45.3333 161 93 51 161 91.0714
-52 161 91.2273 154 161 90.6 45.8667 162 93
-51 162 90.5 50.6875 162 93 154 162 91.7
-156 161.455 93 155 163 92.7391 155.25 163 93
-47 164 92.3077 46.25 164 93 159 164 91.5
-47 164.857 93 63 165 90.6667 92 165 90.8824
-159 165 90.8824 45 165.591 93 46.5455 166 93
-64 166 90.2609 66 166 92.6842 67 166 92.8636
-92 166 90.2 93 166 91.0385 158 166 91.5
-160 166 90.5806 161 166 92.3077 46.6 167 93
-65 166.684 93 69 166.4 93 70 166.227 93
-71 167 91.5556 72 167 92 75 167 90.6
-93 167 92.25 94 167 92.25 161 167 92.7391
-161.5 167 93 68.3333 168 93 72 168 91.5
-94 168 90.2143 160 168 92.4444 161 168 92.25
-162 168 91.5556 48.4 169 93 67 169 90.2727
-162 170 91.2353 51.2857 171 93 66 170.208 93
-167 171 92.8966 52.625 173 93 170 173 92.8235
-173 173 92.7778 174 174 90.2308 170 175 92.1429
-180 175 91.5 171 176 92.4194 172 175.091 93
-172 176 91.8889 174 176 90.2222 179 176 90.5455
-185 175.618 93 179 177 92.7 183 177 90.375
-177 178 91.2 178 178 92.7 178.333 178 93
-179 177.333 93 179.143 178 93 180 178 90.6
-176 178.833 93 177 178.818 93 177.286 179 93
-178 179 92.2105 179 179 91.5 204.833 179 93
-180 180 90.5294 204 180.172 93 121 139 93.2727
-123.105 139 96 33 140.857 96 34 141 94.8462
-34 142 93.9 35 143 93.6818 149 143 94.8889
-150 144 94.1818 149 145 93.7895 40 151 94.5
-40.0714 153 96 40 153.071 96 39.3529 156 96
-149.588 156 96 46 156.591 96 45 157.133 96
-48 158 94.8 47 159 93.8571 49 159 94.0714
-50.1818 159 96 45.6667 160 96 47 159.625 96
-52 159.895 96 45.5714 161 96 157 161 93.2308
-51 162 94.0714 52 161.722 96 52.8333 162 96
-54 161.5 96 156 162 95.25 158 162 93.2609
-159 162 93.6 41 163 94.8261 46 163 94.125
-51 162.692 96 52 163 95.4 52.75 163 96
-156 163 95.5714 46 164 93.3158 45.2273 164 96
-52 163.6 96 90 164 93.3214 155 164 93.6667
-43 165 94.1111 46 165 93.75 47 165 93.75
-156 165 93.2 45 166 94.5882 45.7273 166 96
-47 165.273 96 46.2727 166 96 54 166 94
-54.2 166 96 69.25 166 96 162 166 94.7727
-46 166.375 96 46 167 94.9286 54 166.667 96
-64.4615 167 96 69 166.5 96 155 166.474 96
-163 166.455 96 47 168 94.5 72 168 94.5
-94.55 168 96 164 168 94.1111 165 168 95.1
-46 169 95.8846 46.1667 169 96 47.5 169 96
-72 169 95.3182 164 169 94.1111 165 169 94.5556
-166 169 94.8 52 170 93.2 94 169.688 96
-166 170 93.4286 167 170 93.5455 51 170.625 96
-163 171 93.6 166 171 94.3636 168 171 94.375
-168 170.133 96 170 171 94.8 52 172 94
-52.1818 172 96 162 172 94.5 163 172 94.3
-164 172 95.7391 165 172 95.8636 167 172 94.3548
-168 172 94.3548 173 172 93.5172 52 172.5 96
-59 173 95.125 164 173 95.4194 165 173 95.0323
-171 173 93.1818 172 173 93.4545 216 173 95.8
-75 174 95 74.8421 174 96 76 173.533 96
-76 174 95 76.6364 174 96 167 174 95.1429
-172 174 93.8182 214 174 95.4706 168 175 94.5
-172 175 93.1765 183 174.941 96 170 177 94.5
-178 176.65 96 179 176.316 96 204.323 177 96
-176.85 178 96 178 178 93.2 179.591 178 96
-176 179 93.3158 177 179 93.8571 177 178.375 96
-178 178.609 96 177 180 94.1538 68 184.056 96
-124 138.071 99 33 139.357 99 34 140.056 99
-149 141 98.2174 150 140.5 99 149 142 96.2609
-115 143.111 99 41 153 98.6 40 154 98.0526
-41 154 98.7 42 154 98.6 43 154 97.9286
-43 153.773 99 44 155 97.5 44 156 98.1667
-44.7143 156 99 46 157 98.4545 42.8182 158 99
-45 158 97.4444 47 158 98.4706 48 158 98.25
-44 158.846 99 45 159 98.6 46 159 98
-46.75 159 99 47 158.75 99 46 160 97.6364
-46 159.375 99 47 160 97 49.1818 160 99
-51 160 97.5 46 161 97.2 47 161 97.5
-51 160.667 99 53 160.545 99 45.2778 162 99
-51 161.333 99 53 161.625 99 53 162 96.75
-161 162 97.8529 49.9333 163 99 52 162.2 99
-59 163 98.25 44.3158 164 99 60 163.667 99
-64 163.933 99 59 165 97 60 164.333 99
-60 165 97.6364 64.8182 165 99 66 165 97.125
-66.7143 165 99 68.75 165 99 47 166 97.8462
-47.3333 166 99 54 166 96.4 59 166 96
-58.2632 166 99 60 166 97.0909 65 166 98.7143
-64.8182 166 99 66 166 98.0526 66.75 166 99
-69 166 96.4286 70 165.833 99 224 166 98.8
-225 166 98.8 225 165.75 99 46 167 97.5
-47.8182 167 99 59 167 97.3636 58.25 167 99
-60 167 97.7143 67 166.286 99 69 167 96.75
-70 167 98.6 70 166.5 99 70.3333 167 99
-72 167 98.6 71.6667 167 99 72 166.5 99
-223 167 97.8529 224 167 97.6452 47 168 96.75
-46.4545 168 99 47.8571 168 99 56 168 98.7273
-55.8667 168 99 56 167.867 99 56.5 168 99
-61.8182 168 99 64.25 168 99 70 168 96.2609
-71 167.222 99 71 168 96.7895 73 168 97
-74 167.357 99 74 168 97.7727 222 168 97.8529
-223 168 97.3 224 168 98.7391 47 169 97.3636
-56 168.286 99 62 169 97.6552 62.9286 169 99
-64.25 169 99 69 169 96.9 71 169 97.35
-74.1 169 99 92.7 169 99 167 168.2 99
-221 169 97.7 222 169 97.3 223 169 98.7391
-46 170 97.5 52 169.462 99 54.2 170 99
-62 170 97.8182 62.6842 170 99 68 169.875 99
-69 170 98.25 68.5 170 99 70 170 97.1739
-71 170 97.25 72 170 97.5 72.9091 170 99
-74 169.056 99 77 170 97.5 76.4545 170 99
-77 169.571 99 170 170 96.4545 220 170 96.9
-221 170 97.0385 222 170 98.7391 61 171 98.7931
-60.7778 171 99 61.2857 171 99 69 170.5 99
-70 171 97.3333 71 171 97.25 72 171 98.625
-77 171 97.8 77.8571 171 99 94 170.294 99
-164 171 96.2727 165 171 96.4091 218 171 97.4
-219 171 96.6 220 171 96.2 221 171 98.2174
-49 172 96.3333 54 171.75 99 59 171.519 99
-60 172 98 69.1429 172 99 71 172 96.3
-72.4375 172 99 77 171.75 99 216 172 97.1818
-216 171.231 99 217 172 97.2414 218 172 96.5172
-219 172 97.5 220 172 98.7273 48 172.722 99
-50 173 97.875 51.5 173 99 58 173 96.5172
-57.1724 173 99 61 172.286 99 215 173 96.5294
-217 173 96.5294 218 173 97.3548 51 174 98.2174
-67 173.818 99 67.25 174 99 75.5 174 99
-78 174 98.7273 78.1053 174 99 180 173.097 99
-211 174 98.88 216 174 96.5294 58 174.737 99
-67 175 97.8462 66.0909 175 99 76 174.643 99
-77 175 98.4 77.75 175 99 78 174.667 99
-210 175 97.25 212 175 97.8261 213 175 96.6
-214 175 96.2 67 176 98.069 66.3571 176 99
-67.9 176 99 77 175.188 99 178 175.923 99
-178.25 176 99 209 176 96.4545 210 176 96.1154
-211 176 97.56 212 176 98.4444 213 176 98.1
-214 176 98.4231 67 176.5 99 179 176.75 99
-179.095 177 99 210 177 96.5806 212 176.833 99
-214 176.172 99 177 178.579 99 178 178.467 99
-63 183.375 99 66 183.818 99 67 184 98
-151 137 101.824 32 138 101.609 33 137.333 102
-150 138 100.696 33 139 99.5769 150 139 99.6667
-149 140 100.8 123 141 100.579 122 144 100.962
-120.8 145 102 107.773 150 102 41 152 99.5455
-34.5882 153 102 45 155 100.579 45.3913 155 102
-41 156 100.154 42 156 100.111 45 156 99.3158
-42 157 99.2727 43 157 100.111 46 157 99.6
-47 157 101.7 44 158 101.75 47 158 102
-48 158 100 43.8421 159 102 50 159 100.071
-51 160 99.4286 50 161 100.826 54 161 101.7
-55 161 101.5 158 161 101.667 157.25 161 102
-158 160.813 102 51 162 99.75 52 162 99.5455
-53 162 100.125 56 161.077 102 158 161.75 102
-227 162 101.1 228 162 101.739 46 162.444 102
-49 162.667 102 49 163 101.8 50 162.2 102
-60 162.944 102 226 163 100.5 227 163 99.9
-225 164 101.1 226 164 99.9 227 164 100.227
-47 165 101.167 59 165 101.727 65 165 99.8571
-66 165 101.5 80 164.567 102 225 165 99.5294
-226 165 100.111 46 166 101.824 60.875 166 102
-65 166 101 65.2 166 102 66 165.2 102
-66.8 166 102 226 165.944 102 46 167 99.9375
-47 167 101.077 60.75 167 102 61.1429 167 102
-62 166.455 102 64 167 100.5 65 167 100.364
-66 167 100.286 70 167 99.8571 72 166.563 102
-167 167 100.5 47 168 100.636 56 168 99.8571
-65 168 100.2 66 168 100.773 67 168 101.654
-74 167.105 102 94 168 101.786 95.375 168 102
-167 168 99.5455 62.6364 169 102 66 169 101.727
-67 169 101.8 68 169 101.8 75 168.571 102
-75 169 101.25 76 168.455 102 76 169 100.2
-95.9167 169 102 54 169.591 102 55 170 101.182
-56 169.167 102 56 170 100.5 61 170 99.8182
-64.4545 170 102 67 170 101.7 73.5455 170 102
-75 169.75 102 76 169.857 102 76.1429 170 102
-52 170.474 102 53 170.143 102 54.3333 171 102
-61 171 99.6 51 172 102 58 171.727 102
-60 172 101 73 171.667 102 72.9333 172 102
-78 171.917 102 60.25 173 102 72 173 101.182
-78 173 101.25 78 172.333 102 79.5 173 102
-180 172.316 102 67.3333 174 102 68 174 101.25
-68.6667 174 102 77 174 100.579 77.75 174 102
-79 174 102 187 174 101.419 188 174 101.8
-206.895 174 102 58 174.25 102 66 175 102
-68 175 102 77 175 99.6 78 174.75 102
-207 175 101 65.5625 176 102 68.1364 176 102
-173 176 100.688 173 175.632 102 176.565 176 102
-215 176 100.826 215.6 176 102 161 176.074 102
-212 177 99.1034 176.8 178 102 203.5 178 102
-212 178 100.556 203 178.867 102 210 179 100.355
-202.091 180 102 203 181 100.75 66 185 100.08
-200 184.172 102 232 99 104.8 232 98.7143 105
-232 99.5 105 235 111 104.824 235 112 104.824
-151 133 104.471 32 136 103.6 31.3 136 105
-33 135.867 105 150 137 102.167 153 141 103.2
-154 142 104.8 154.75 143 105 230 156 104.419
-49 157 104.318 229 157 104.8 45 158 103.313
-46 158 103.615 229 158 103.7 230 158 104.053
-44 159 103.125 45 159 102.75 46 159 103.8
-53 158.316 105 228 159 104.206 229 159 103.5
-37.1765 160 105 54 160 103.5 164 160 103.8
-229 160 103.5 157.533 161 105 158 160.417 105
-158.875 161 105 228 161 102.682 228.944 161 105
-49 162 102.273 50 162 102.316 59.8 162 105
-62 162 104.545 158 161.875 105 46 163 104
-48 163 102.375 225 163 103.111 45.1429 164 105
-46 163.455 105 47 164 103.05 45 165 103.286
-60 165 102.75 167 165 102.529 46 165.25 105
-60 166 103.105 63 166 105 65 166 102.429
-60 167 102.45 61.8571 167 105 62 166.333 105
-62.6667 167 105 64 167 104.5 63.5 167 105
-64.1 167 105 65 166.4 105 64 167.25 105
-68 168 102.261 69 168 103.962 71 168 103.556
-72 168 104.778 73 168 104.333 74 168 104.684
-96.7143 168 105 166 168 103.875 166.75 168 105
-62 169 103.05 69 169 103.304 71 169 103.304
-73 169 104.063 75 169 102.818 76 169 102.947
-97.5455 169 105 54 170 103.929 55 170 103.125
-56 170 104.143 62 170 103.235 65 170 103.636
-66 170 103.65 74 169.273 105 77 170 103
-52 171 103 53 171 102.692 54 171 103
-71 171 103.304 73 171 102.4 78 171 104.75
-178 170.261 105 179 171 103 181 171 104.419
-52 172 103.179 58 172 103.125 72 172 103.826
-77 171.286 105 182 172 104 184 172 102.882
-188 172 104.8 58 173 103.826 59 173 103.5
-70 173 103.125 72 173 103.8 78 173 103.5
-78.4 173 105 81 173 105 181 173 103.5
-182 173 103.909 188 173 102.783 207 173 104.333
-208.125 173 105 59 174 102.692 69.75 174 105
-80 173.857 105 198 174 102.667 206 174 104.217
-210 173.273 105 67 175 103.615 67.75 175 105
-68.2857 175 105 88 175 104 87.25 175 105
-88.75 175 105 176 175 104.308 176 174.455 105
-177 174.87 105 177 175 104.438 66 176 104.625
-67 176 104.625 68 176 103 88 175.75 105
-173.231 176 105 176 176 104.438 178.067 176 105
-204.091 178 105 203.25 179 105 200.571 180 105
-201 179.4 105 203 179.056 105 206 180 103.8
-201.75 181 105 205 181 104.333 206 181 103.8
-207 181 104.1 173 182 103.56 175.667 185 105
-230 94 107.4 230 93.1429 108 231 95 106.889
-231 96 106.355 231 97 106.182 232 97 106.636
-232 98 105.577 231 99 106.5 233 99 106.333
-233 98.1667 108 232 100 105.2 233.292 100 108
-233 101.5 108 233 102 107.684 233 103 106.111
-233 104 105.882 233 105 106.182 234 105 105.682
-234 106 105.222 235 105.75 108 234 107 105.2
-234 108 105.529 235 110 105.577 235.913 110 108
-234 111 105.529 236 111 106.421 236.292 114 108
-235 116 106.355 235 117 107.032 235 119 107.8
-235 120 107.8 236 120 107.739 236 121 106.696
-236 123 105.667 236 125 106.889 236 126 107.333
-235 127 107.824 236 128 106.355 236 130 107.1
-150 131 107.778 150 132 105.9 149.192 132 108
-151 132 105.818 235 132 107.8 31 135 106.8
-31 134.143 108 32 135 105.136 31 136 107
-33 135.133 108 235 136 107.471 120 139.435 108
-235 140 106.889 155 141 105.667 234 141 107.471
-235 141 107.217 234 142 107.143 235 141.857 108
-234 143 107.032 155 144 105.545 156 144 107.625
-234 144 107.333 233 145 107.824 162 151 107.471
-231 156 106.714 230.933 157 108 225.933 159 108
-57 160 107.684 168 160 107.471 57 161 106
-58 161 106.636 59 161 105.316 60 161 105.783
-158 161 106.05 58 162 108 59 162 106.2
-63 162 106 82 161.833 108 83 162 107.8
-83 161.833 108 84 162 106.759 160 162 106.714
-159.455 162 108 160 161.455 108 160.75 162 108
-46 164 105.6 64 166 106.286 65 166 106.636
-66 166 105.75 173 166 106.2 174 166 107.032
-176 166 107.778 62 167 105.333 64 167 105.231
-174 167 107.55 176 167 107.739 177 167 106.962
-216 167 107.1 168.13 168 108 174 168 105.75
-177 168 106.889 178 168 106.889 218 168 105.2
-74 169 105.333 166 168.25 108 167.2 169 108
-168 168.2 108 179 169 105.529 181 169 106.2
-183 170 105.529 192 169.333 108 195 170 107.471
-207 170 107.8 77 171 105.316 96 170.111 108
-197 171 106.645 198 171 106.457 208 171 106.457
-82 172 107.25 82 171.625 108 82.75 172 108
-197 172 106.5 198 172 106.826 203.5 172 108
-205.75 172 108 207 172 106.826 208 172 106.355
-80 173 106.2 82 172.375 108 175 173 107.087
-174.563 173 108 200 173 107.885 203 173 107.912
-205.455 173 108 209 173 106.105 210 173 105.474
-68 174 105.273 69 174 105.6 90 174 107.526
-89.75 174 108 90.75 174 108 175 174 106.895
-176 174 106.25 203 174 107.5 68 175 105.24
-88 175 105.818 90 174.75 108 177 174.895 108
-206 175 106.5 205.833 175 108 171 176 107.5
-171 175.333 108 172.231 176 108 176 175.933 108
-177.13 176 108 205 175.909 108 205 176 107.864
-206 176 106.636 205 178 105.882 204 179 105.29
-201 180 107.25 202 180 107.211 203 180 106.962
-202 181 106 203 181 107.348 169 182 106.235
-203 182 106.826 204 182 106.2 205 182 105.455
-171 183 105.176 173 183 105.778 204 183 107.1
-205 183 107.778 172 184 106.5 86 189.824 108
-227 88 110.4 226.5 88 111 228 89 109.444
-228 90 108.9 228 91 109.2 229 91 109.174
-229 92 108.667 230 91.8182 111 229 93 108.581
-230 93 108.2 233 101 109.5 232 102 108.24
-230.167 107 111 231 108 110.824 230.833 108 111
-232 109 109.182 236 119 108.545 236.64 125 111
-150 129.966 111 234.692 130 111 149 130.231 111
-148.63 131 111 235 131 109.227 236 131 108.273
-236 132 108.158 31 133 110.25 30.5882 135 111
-128 135 110.423 129 135 110.206 128 136 108.231
-129 136 110.1 129 136.818 111 157 138.643 111
-157 140 109.304 232.316 140 111 235.806 140 111
-156 141 108.136 156 142 109.08 157 142 109.4
-156 143 109.227 158 143 109.313 157 144 108.182
-232 145 109.2 234 145 108.682 234.567 145 111
-162 146 110.143 161 147 109.355 231 147 110.824
-233 147 110.864 164 148 110.471 232 148 110.909
-162 149 109.75 232 149 110.423 232.714 149 111
-231 150 110.423 232.929 150 111 231 151 109.696
-232 151 108.789 231 152 109.421 232 152 109
-231 153 110.053 230 154 108.692 170 157 109.457
-168 158 109.2 171 158 109.457 60 159 110.1
-168 159 108.529 172 159 109.457 223 158.875 111
-224 159 110.739 170 160 109.2 171 160 109.457
-172 160 109.8 174 160 110.143 82 161 108.909
-173 161 109.886 175 161 109.457 177 161 110.206
-177.818 161 111 105 162 110.25 106 162 109.2
-174 162 109.8 175 162 109.457 178 162 110.8
-220 162 110.25 220 161.417 111 106 163 109
-106.25 163 111 160 163 108.429 161 163 109.364
-161.2 163 111 175 163 108.882 161 164 109
-178 164 110.333 160 164.909 111 161.13 165 111
-179 165 108.968 184 165 109.457 183 166 109.457
-185 166 109.457 210 166 110.471 214 166 109.2
-215 166 108.882 66 167 109.6 65.125 167 111
-66 166.417 111 67 166.625 111 67.2727 167 111
-184 167 110.333 185 167 110.679 186 167 110.032
-187 167 109.457 194 167 110.8 193.5 167 111
-195 166.625 111 209 167 110.125 215 167 108.529
-66 168 109.5 65.25 168 111 67 168 110.308
-166.696 168 111 169 167.563 111 169 168 110.222
-170 168 110.735 171 168 110.735 172 167.87 111
-185 168 110.211 187 168 108.529 192 168 110.211
-192.714 168 111 193.25 168 111 195 168 109.645
-201 168 109.853 203 168 110.684 204 168 110.684
-207 167.5 111 210 168 109.826 213 168 110.864
-214 168 110.04 92.6842 169 111 167 168.875 111
-168 168.947 111 169 168.438 111 172 169 109.645
-173 169 109.429 192.818 169 111 194 169 109.5
-193.25 169 111 202 169 110.625 205 169 110.471
-207 169 108.75 93.25 170 111 173 170 109.35
-173.688 170 111 193 169.25 111 94 170.4 111
-95 170.625 111 173 171 111 82 172 108.818
-186 172 110.55 185.727 172 111 205 172 109.636
-205 171.375 111 92 173 110.55 91.25 173 111
-93 172.455 111 93 173 110.4 175 173 110.625
-186 172.375 111 195 173 110.471 195 172.571 111
-196 172.444 111 196 173 109.5 205 173 110.143
-90.5 174 111 91 173.2 111 91 174 108.6
-92 174 110.438 94 174 110.55 95 173.667 111
-95 174 109.875 175 174 109.75 176 174 109.313
-196 174 109.821 197 174 109.889 197.667 174 111
-204 174 108.947 205 173.4 111 205.75 174 111
-91 174.25 111 95 174.75 111 171 175 108.273
-176 175 109.909 195.563 175 111 197 175 110.217
-85 176 108 84.25 176 111 85 175.25 111
-85.1875 176 111 171.857 176 111 177 176 108.29
-196 176 111 197 176 110.143 205 175.333 111
-85 176.188 111 197 176.286 111 212 180.067 111
-207 67 113.333 208 68 112.645 209 68 112.889
-210 68.0667 114 210 70 112.457 213 71 112.313
-214 71 112.75 215 71 113.5 215 72 112.25
-216 73 111.261 217 73 111.273 213 74 112.8
-216 74 111.968 218 74 112.364 218.231 74 114
-218 75 111.783 218 76 112.313 219.091 76 114
-218 77 113.419 219 77 113.679 219.25 77 114
-219 78 113.778 220 78 113.419 220 79 113.143
-221 80 113.419 221.857 81 114 222 82 113.8
-222.167 84 114 223 84 113.143 224 85 113.333
-225 85 113.55 225 87 113.778 226 87 112.696
-226 88 111.783 227 87.2632 114 229 98 111.176
-231 110 111.529 230.04 113 114 231 114 111.529
-232 119 112.773 232 120 111.947 233 121 111.5
-233 128 111.581 234 129 112.227 31 130 113.793
-149 130 111.333 233.375 130 114 234 130 113.348
-31 131 112.636 32 131 112.5 234 131 112.364
-31 132 113.182 30.875 132 114 32 132 112.5
-232 132 112.2 233 132 111.455 131 133 112.962
-132 133 113.1 132 132.182 114 149 132.944 114
-129 134 112.111 130 134 111.581 131 134 111.9
-132 134 113.778 232 133.684 114 233 134 111.931
-130 135 111.2 131 135 112.7 126 135.067 114
-158 136 113.333 31.2857 137 114 232 137 111.581
-157 138 112.08 229.5 138 114 233 138 111.176
-229 142 113.824 230 142 113.143 108 143 113.545
-161 143 111.857 231 144 112.5 165 145 112.8
-164 146 112.313 229 146 113.8 231 146 111.091
-230 147 111.176 232.962 148 114 229 149 111.931
-226 151 113.143 227 152 113.545 229 152 113.909
-232.176 152 114 228 153 112.909 103 154 113.4
-104 154 113.455 101.818 155 114 103 155 111.429
-104 155 113 59 157 112.235 59 158 111.529
-222 157.565 114 177 159 113 220 160 112.545
-106 161.053 114 106.783 162 114 161 163 113.571
-189 163 113.206 106 163.13 114 159.677 164 114
-189 164 112.889 191 164 112.889 197.25 164 114
-208 164 112.457 161.667 165 114 191 165 113.684
-192 165 112.889 198 165 113.25 205 165 113.217
-67 166 112 66.4737 166 114 67 165.667 114
-68 166 112.241 68.8947 166 114 190 166 113.5
-191 166 113.25 192 166 111.947 197 166 113.885
-197 165.667 114 198 166 113.778 199 166 112.5
-203 166 111.75 66 166.75 114 68 167 111.923
-192 167 111.545 193 167 111.273 56 168 112.25
-56 167.125 114 56.5833 168 114 66.1429 168 114
-68 167.947 114 67.8571 168 114 90.625 168 114
-93 167.261 114 167.769 168 114 168 167.25 114
-172 167.391 114 193 168 111.6 56 169 111.75
-56.2 169 114 169 168.609 114 184 169 113.684
-184 168.333 114 185 168.75 114 185 169 113.308
-192.417 169 114 202.65 169 114 203 168.125 114
-204 168.455 114 173 169.857 114 185 170 113.308
-184.6 170 114 193 170 111.9 194 169.444 114
-194 170 112.125 95 170.261 114 185 171 112.263
-186 171 113.182 192.889 171 114 194 171 112
-195 171 112.696 93 171.684 114 185 172 113.182
-186.438 172 114 194 172 113 195 172 111.667
-196 172 112.714 204 171.875 114 205 172 112.875
-204.4 172 114 205.231 172 114 94 173 111.5
-185 172.111 114 205 173 112.5 204.867 173 114
-205.5 173 114 91.8667 174 114 94.6667 174 114
-195 173.722 114 197.429 174 114 206 173.25 114
-206 174 111.429 93 174.393 114 172 175 111.75
-172.125 175 114 196 174.667 114 205 175 113.571
-206.15 175 114 85 176 111.346 171 175.545 114
-176 186.853 114 181 187.808 114 201.75 67 117
-204 67 116.125 203 68 116.471 205 69 116.1
-208 73 116.217 209 73 116.125 208 74 116.333
-207.5 74 117 209 74 115.962 210 76 116.1
-211 76 116.217 215 77 115.2 214 78 115.8
-216 78 115.645 217 78 116.333 213 78.6667 117
-218 79 116.444 221.966 80 117 219 81 115.2
-222 81 114.136 221 82 114.176 221 83 114.857
-225 84.1111 117 223 86.8667 117 224 89 115.7
-225 89 115.227 225 90 115.5 224.697 92 117
-224 95 116.824 234.059 105 117 226 108 116.4
-227 110 116.778 228 111 116.824 228 112 116.206
-228 113 116.419 229 114 114.529 229 115 114.857
-229 118 115.8 230 119 116.885 231 119 115.759
-231 121 114.931 230 122 114.882 30 125 116.087
-31 126 115.5 228.5 126 117 146 127.966 117
-145.955 128 117 146 129 115.655 32 130 114.231
-134 130 116.5 135 130 116.471 230 130 116.778
-132 131 116.069 133 131 114.818 134 131 115.3
-135 131 116.778 132 132 114.182 133 132 114.091
-134 132 115.5 133 133 114.931 159 133 115.5
-229 133 116.143 230 133 115.147 149.433 134 117
-230 134 116.032 231 134 116.1 232 134 114.692
-159 135 114.2 161 135 116.217 228 135 116.8
-229 135 115.889 232 135 115.364 159 136 114.857
-160 136 115.56 161 136 116.739 163 136 116.333
-229 136 116.625 162 137 116.217 230 137 114.4
-164 138 116.739 164 139 115.889 226 142 116.824
-105.867 143 117 226 143 116.143 229 143 114.176
-167 144 115.2 228 144 115.853 229 144 115.235
-104 144.933 117 103.857 145 117 105 145 115.5
-168 145 116.625 229 145 115 168 146 116.885
-169 146 116.778 170 146 116.333 227 146 116.545
-170 148 115.8 172 149 115.457 222.125 149 117
-223 150 115.457 224 151 115.2 220 152 116.143
-221 152 115.853 222 152 115.8 224 152 115.853
-51 152.087 117 221 153 115.457 222 153 115.8
-223 153 116.471 102 154 116.143 104 154 115.5
-219 154 116.5 101.895 155 117 103.545 155 117
-182 154.75 117 216 155 116.471 217 155 116.032
-218 155 116.333 181 156 115.457 182 156 116.4
-216 156 115.8 217 156 116.333 217.75 156 117
-223 155.917 117 161 157 114.8 160.313 157 117
-161 156.083 117 162 157 116 162.333 157 117
-182 157 116.032 185 157 116.206 212 157 116.471
-214 157 116.559 216 157 115.457 217 157 116.333
-217.75 157 117 161 157.55 117 162 157.857 117
-176 158 114.207 183 158 115.853 212 158 115.457
-216 158 115.457 217 158 116.032 218 158 115.929
-185 159 115.457 205 158.833 117 208 159 116.419
-210 159 116.125 189 160 115.457 192 160 116.8
-207 160 116.032 208 160 115.645 209 160 116.217
-217 160 114.9 187 161 114.29 188 161 114.968
-204 161 115.8 205 161 115.645 207 161 116.419
-208 161 116.419 209.5 161 117 217 161 116.069
-103.083 162 117 206 162 116.1 210 162 114.667
-216 162 116.864 217 162 116.88 58 163 116.739
-57.8182 163 117 58.25 163 117 69 162.818 117
-103 163 116.087 103 162.125 117 211 163 114.931
-69 164 116.217 103 163.875 117 162.077 164 117
-68 165 116.25 68 164.813 117 159.933 165 117
-197 165 114.333 69 166 114.667 170 166 114.9
-190 166 114.75 190 165.455 117 191 166 115.2
-56 167 114.75 56 166 117 66 167 114.333
-67 167 116.348 67.3333 167 117 91 167 114.783
-191 167 115.765 192 167 116.455 56 168 117
-67 168 114.692 68 167.385 117 89.0909 168 117
-168.125 168 117 172 168 116.1 171.684 168 117
-184 168 114.6 184 167 117 184.333 168 117
-190.923 168 117 192 168 114.923 193 168 115.333
-193.333 168 117 201.067 168 117 202 167.067 117
-203 168 114.13 204.467 168 117 56 169 114.563
-89.25 169 117 91 169 115 94.6364 169 117
-171 169 115.579 172 169 115.7 184 168.8 117
-184 169 116 185 169 116.25 192 169 114.789
-202 169 116.6 201.923 169 117 204.609 169 117
-79 170 115.875 79 169.727 117 80 169.417 117
-80 170 115.385 185 170 116.571 192 169.737 117
-79 170.273 117 80 170.304 117 94 170.286 117
-185 171 115.737 186 171 114.474 195 171 116.727
-194.875 171 117 204 171 116.8 204 170.857 117
-94 171.455 117 186 172 114.778 194 172 115.286
-194 171.467 117 195 172 116.333 196 172 115
-205 172 114.474 92.2273 173 117 195 173 115.773
-196 173 116.1 205 173 114.6 93 174 116.75
-171 173.889 117 197 174 114.692 205 174 115.286
-206 174 115.636 206 175 114.818 172 175.933 117
-204 185 115.579 176.85 186 117 177 185.813 117
-178 185.417 117 184 186 116.735 184 187.385 117
-200.25 67 120 200.333 69 120 204 70 117.968
-202.125 71 120 204 71 118.313 204 74 119.143
-206 77 118.457 208 77 118.5 207 78 119.032
-210 78 118.25 217 79 117.273 210 79.5455 120
-214 80 119.5 216 80 117.261 217 80 117.103
-216 81 117.667 221 86 118.364 219 87 119.824
-220 87 119.8 220.5 87 120 220 88 119.559
-221 88 119.5 222 87.2857 120 222 89 119.1
-222 90.3333 120 223 90.7692 120 224 91.125 120
-222.545 93 120 224 93 118.56 33 105 119.8
-33 107 119.471 32 108 119.739 33 108 119.824
-223.867 108 120 32 109 118.556 33 109 119.824
-224.526 109 120 31 110 119.526 225 110 119.1
-32 111 118.5 224 111 119.419 224 112 118.457
-225 112 118.2 31 113 117.75 224 113 118.457
-225 113 118.645 226 113 118.3 226 114 119.864
-31 119 117.529 226 119 118.457 226 120 118.457
-227 120 118.258 230 120 117.391 225 121 119.471
-227 121 119.739 229 121 118.08 33 127 118.818
-29.4857 128 120 227.929 128 120 145.147 129 120
-228 129 119.864 226 130 119.143 162 131 118.8
-226 131 119.118 161 132 118.235 164 132 118.8
-227 132 118.457 34.4545 133 120 34 134 119.211
-226 135 118.457 230 135 117.517 231 135 117.409
-230 136 117.429 165 137 117.176 169 136.167 120
-169 137 119.143 168 138 118.457 224 138 118.8
-226 138 118.75 110 139 119.824 167 139 118.645
-225 139 119.032 226 139 119.333 227 139 118.556
-167 140 118 226 140 118.941 228 140 117.265
-224 141 118.8 106.133 142 120 221 142 118.8
-106 142.5 120 105.75 143 120 170 143 118.645
-173 143 118.8 103 144 119.769 105.857 144 120
-220 144 118.457 102 145 117.6 103 145 117.947
-104 144.667 120 105 144.857 120 221 145 118.457
-99 146 118.853 101 146 118.182 102 146 117.231
-219 146 118.457 221 146 118.8 222 146 119.206
-223 146 119.471 174 147 118.2 219 147 118.8
-221 147 119.559 222 147 119.273 223 147 118.909
-220.286 148 120 221 148 119.559 222 148 118.545
-221 149 119.1 179 150 118.457 220.346 150 120
-177 151 118.556 178 151 118.889 179 151 118.457
-213 152 118.8 218 152 117.857 181 153 119.1
-185 153 119.824 215 153 118.457 217 153 117.882
-102 153.85 120 103.438 154 120 210 154 118.457
-215 154 118.2 222 154 117.455 223 154 118.111
-224 154 117.45 104 155 119.143 209 155 118.457
-211 155 118.457 213 155 118.7 219 155 117.273
-221 155 118.759 222 155 119.172 223 155 118.435
-103 155.895 120 104 155.143 120 184 156 117.529
-189 156 118.457 211 156 117.882 213 156 117.968
-218.727 156 120 219 155.87 120 219.429 156 120
-220 156 119.294 222 156 119.04 161 157 118.737
-162 157 118.636 189 157 118.2 201 157 119.206
-219 156.75 120 219 157 119.5 198 158 119.419
-202 158 119.206 203 159 118.4 165 160 119.609
-164.727 160 120 165 159.75 120 202 160 117.182
-210 160 117.6 165 160.6 120 210 161 117.333
-211 161 119.786 211.25 161 120 212.75 161 120
-214 161 118.909 216 161 118.105 57 162 118.688
-57 161.125 120 58 161.083 120 58 162 118.565
-104 162 118.65 105 162 118.111 106 162 117.375
-188 162 119.684 57 163 118.688 67.5333 163 120
-68 162.417 120 101 163 119.308 100.143 163 120
-102 162.739 120 102 163 118.364 103 162.563 120
-104 163 119 188 163 119 57 164 119
-56.5556 164 120 57.8 164 120 101 164 119.217
-102 164 119.25 103 164 118 103.111 164 120
-181 164 119.308 188 164 119.308 189 164 118.889
-57 165 117.75 56.25 165 120 57.25 165 120
-68 165 118.125 68.3125 165 120 162 164.053 120
-162.667 165 120 169 164.5 120 180.739 165 120
-189 165 118.444 190 165 117.75 197 165 119.667
-198 165 119.55 57 165.25 120 68 166 118.826
-69 165.55 120 69 166 118.313 93.2 166 120
-161 165.947 120 182 166 118.364 183 166 117.375
-189.067 166 120 191 165.333 120 198 166 118.25
-199 166 118.95 56 167 117.75 68 167 118
-162 166.261 120 171.519 167 120 183 166.636 120
-190 166.737 120 198 166.35 120 200 167 119.182
-199.25 167 120 200 166.571 120 201 166.632 120
-201 167 117.375 184 168 117.75 193 168 118.579
-192.25 168 120 201 168 118 202 167.417 120
-192 169 119.211 192 168.375 120 203 169 119.87
-203 168.857 120 79 170 117.563 80 170 118.75
-193 170 119.684 203 170 117.391 204 170 117.6
-93 171 119 94 171 118 94.3704 171 120
-94.3704 172 120 94 172.667 120 170.192 175 120
-171 175.808 120 184 184.267 120 176.533 186 120
-180 186 117.25 181 186 117.6 181.8 186 120
-182.091 186 120 185 186 117.091 175 186.588 120
-181 187 120 184 187 117.652 183.053 187 120
-185 187 117.088 182 187.615 120 200.25 68 123
-200.333 69 123 205 80 122.625 207 80 121.556
-208 80 122.423 210 80 120.714 221 79.913 123
-205 80.75 123 207 81 121.889 214 81 120.12
-206 82 122.032 207 82 121.645 208 82 122.8
-213 82 120.333 214 82 120.231 211 83 121.645
-213 83 121.5 210.182 84 123 212 84 121.8
-213 84 122.125 213 84.875 123 214 85.5 123
-216 87 122.739 217 87 122.55 221 87 120.273
-222 87 120.333 218 88 121.2 220 89 121.038
-221 89 120.103 221 90 120.231 221 91 121.5
-223 91 122.25 220 92 122.129 221 92 121.7
-222 92 121.889 222.667 92 123 222 93 120.529
-34 102 121.962 34 101.182 123 33 103 121.895
-34 103 121.7 33 104 120.682 34 104 121.5
-31.8235 105 123 34 105 121.5 32 106 120.667
-222 107 120.529 220 109 122.778 224 109 121
-220 110 122.333 221 110 122.032 222 110 122.206
-223 110 121.909 221 111 122.806 222 111 121.909
-221 114 122.032 222 114 120.857 220 115 122.143
-225 115 120.273 226 115 120.692 223 116 121.25
-224 116 121.125 225 116 120.333 221 117 121.457
-224 117 121.2 222 118 122.333 223 118 122.739
-223 119 122.063 223 120 121.853 222 121 121.457
-224 121 120.529 221 122 121.457 223 122 121.457
-226 122 120.455 227 122 121.219 221 123 121.457
-224 123 121.5 225 123 121.853 226 123 121.909
-227 123 121.219 149 123.7 123 226 124 121.909
-227 124 120.094 34.4737 126 123 226 126 121.125
-161 126.5 123 165 127 122.824 225 127 122.1
-226 127 121.7 34.7391 128 123 134 127.833 123
-145.059 128 123 165 128 121.8 217.875 128 123
-219 128 121.8 223 128 121.8 227 128 122.167
-135 128.077 123 162 129 121.235 164 129 121.8
-167 129 121.8 226 129 120.115 227 129 120.316
-35 130 121.818 136.4 130 123 124 133 121.355
-219 133 121.457 168 134 121.5 220 135 121.8
-219 136 122.786 218 138 121.457 220 138 121.457
-221 138 121.645 222 138 121.304 174 139 121.457
-177 139 122.471 220 139 122.8 221 139 122.8
-222 139 122.217 223 139 120.5 104.6 140 123
-106 140 121.355 173 140 121.2 177 141 122.1
-178 141 122.032 179 141 122.471 221 141 120.818
-105 142 123 106 142 120.857 176 142 122.129
-215 142 122.25 102 143 120.29 103 143 120.261
-104 143 120.75 176 143 121.543 212 143 122.471
-104 144 120.857 116 144 121.714 117 143.818 123
-181 144 121.8 182 144 122.471 212 144 121.457
-214 144 121.886 104.417 145 123 106 145 122
-116 145 120.167 117 145 120.3 179 145 121.457
-215 145 121.8 105 145.438 123 106 145.261 123
-116 145.739 123 181 146 122.778 184 146 121.8
-210 146 122.806 214 146 121.645 216 146 121.457
-46 147 121.111 181 147 122.778 182 147 122.778
-184 147 121.457 205 147 122.471 205 146.5 123
-208 147 121.457 209 147 121.8 211 147 121.8
-91 147.5 123 181 148 121.7 205 148 121.457
-207 148 121.457 211 148 121.457 212 148 122.125
-214 148 122.125 90 149 122.419 188 149 121.8
-210 149 121.457 212.375 149 123 42 150 122.4
-41.625 150 123 42 149.625 123 42.2727 150 123
-89 150 120.882 203 150 121.853 204 150 121.457
-209 150 121.457 210 150 121.645 211 150 122.217
-211.75 150 123 220 150 121.08 52 151 120.692
-208 151 121.457 214 150.625 123 53 152 122.5
-54.75 152 123 62 151.5 123 84 152 120.529
-189 152 121.457 208 152 121.2 177 153 122.609
-176.4 153 123 177 152.727 123 177.75 153 123
-177 153.25 123 103 154.211 123 104 155 120.857
-200 155 121.457 101.313 156 123 103 156 120.375
-217 156 122.182 216.455 156 123 218 155.813 123
-218 156 122.182 219.429 156 123 102 156.846 123
-103 156.933 123 217 157 121.696 216.286 157 123
-218 157 122.182 219 157 120.75 217 157.5 123
-206 159 122.053 207 159 121.875 165 159.813 123
-207 160 121.355 208 159.083 123 209 159.727 123
-209 160 122.438 209.429 160 123 60 161 122.333
-165 160.75 123 166 161 121.091 186 161 122.71
-187 160.364 123 188 161 122.55 207 161 121.696
-208 161 122.053 209 160.333 123 212 161 121.125
-57 161.455 123 70 162 120.273 72 161.263 123
-72 162 121.645 167 162 122.125 166.125 162 123
-167 161.125 123 187 162 120.222 57 163 122.625
-71 163 121 98 163 122.526 98 162.625 123
-99 162.045 123 99 163 120.261 100 163 120.158
-102 163 121.636 101.667 163 123 103 163 120.875
-167 162.467 123 169 163 122.71 168.25 163 123
-181 163 122.55 180.87 163 123 181.75 163 123
-57 164 120.75 58 163.273 123 90.6957 164 123
-93 164 122.4 100 164 121.091 102 164 121.125
-103 164 120.333 161 164 121.2 168 164 122.739
-167.923 164 123 172 163.6 123 182 163.143 123
-57 165 120.375 161 164.6 123 163 164.391 123
-182 165 122.842 182 164.857 123 191.375 165 123
-195 164.333 123 196 164.217 123 198 164.923 123
-172.654 166 123 182 166 120.783 195.8 166 123
-210 166 122.609 209.75 166 123 85 167 122.222
-84.125 167 123 85 166.632 123 85.5833 167 123
-162 166.783 123 163 166.526 123 191 167 121.235
-191 166.167 123 200 167 121.125 201 167 121.235
-210 167 122.438 211 167 122.4 84 168 122.4
-83.25 168 123 169 167.609 123 192 168 120.375
-201 168 120.4 202 168 121.05 203 168 120.783
-211 168 120.2 211.875 168 123 84 168.2 123
-90.125 169 123 91 169.368 123 95.1875 170 123
-211 169.15 123 212 169.375 123 92.4615 171 123
-93 172 121.75 170 171.87 123 170 173 120.75
-171 172.727 123 193 174 122.6 193 173.333 123
-194 173.067 123 194 175 120 194.9 175 123
-171 175.316 123 159 180.31 123 183.4 184 123
-184.545 184 123 182.895 185 123 175.143 186 123
-177 185.4 123 177 186 121.615 180.417 186 123
-181 186 121.091 178 187 121.889 179 187 122.1
-180 187 121.5 183 186.333 123 178 187.909 123
-182 188.435 123 193 188.077 123 92 190.6 123
-203 70 125.71 202 71 124.5 202.37 71 126
-202.286 73 126 208 81 123.12 205 83 125.727
-208 83 123.682 207 84 124.826 206 85 125.778
-205.8 85 126 206.5 85 126 206 86 125.125
-205.364 86 126 206.875 86 126 209 86 125.125
-210.375 86 126 211 85.7727 126 207.4 87 126
-209 87 125.032 210 87 125.333 210.545 87 126
-214 87 124.304 212 87.25 126 211.143 88 126
-213 88 125.625 210.867 89 126 212 89 124.645
-213 90 125.333 216 91 125.7 223.909 91 126
-215 92 125.739 216 92 125.75 224 92 124.636
-214 93 125.778 217 93 124.889 216 94 124.645
-217 94 125.217 218 94 125.625 217 95 125.217
-218 95 125.211 219 95 125.786 36 96 125.8
-36 95.7143 126 216 96 124.645 217 96 124.889
-218 96 124.111 219 96 123.136 35 97 125.778
-36 97 125.471 36 98 125.824 34 99 125.609
-35 99 124.5 34 100 124.421 35 100 124.5
-215 100 124.457 35 101 124.818 216 105 124.457
-218 109 124.5 219 109 124 218 111 123.882
-219 111 123.517 216 112 125.471 221 112 123.176
-215 113 125.5 218 113 125.885 220 113 124
-219 114 125.864 214 116 125.824 215.75 117 126
-217 119 124.457 36 121 124.457 37 121 125.471
-152.6 121 126 155 121 124.457 157 121 124.8
-215 121 124.457 152 122 125.625 153 122 124.853
-166 121.833 126 153 123 123.882 155 123 124.457
-165 123 125.125 218 123 124.457 36 124 124.8
-146.923 124 126 165 124 125.217 170 123.833 126
-218 124 124.8 220 124 123.818 36 125 124.457
-160 125 124.313 165 125 125.125 170 125 124.8
-212 125 125.1 211.4 125 126 219.857 125 126
-221 125 125.25 223 125 125.545 224 125 125.206
-35 126 123.882 36 126 124.645 37 126 124.645
-145.8 126 126 160 126 123.783 170 126 124.457
-212 126 125.778 213 126 125.55 213.6 126 126
-219 126 125.885 223 126 125.545 224 126 124.909
-36 127 125.217 213.25 127 126 36 128 124.826
-37 128 124.889 174 127.25 126 217 127.739 126
-216.571 128 126 228 128 123.75 227.25 128 126
-37 129 124.645 38.5 129 126 174 129 124.645
-214 129 125.55 216 129 125.55 216 128.727 126
-228 128.75 126 38 130 125.471 174 130 124.889
-146.5 131 126 212 131 124.457 37 132 125.559
-176 132 124.645 216 132 124.889 177 133 125.143
-211 133 124.8 215 133 124.457 211 134 124.457
-217 135 124.3 216 136 124.147 217 136 124.5
-176 137 124.111 213 138 124.2 207.167 139 126
-209 139 124.457 217 139 124.125 224 139 125.455
-223.2 139 126 224 138.556 126 225 138.5 126
-225 139 125.143 102 140 124.2 104 140 124.227
-182 140 124.645 183 140 124.7 207.5 140 126
-216 140 124.8 217 140 124.545 43 141 125.824
-103 141 123.947 104.857 141 126 167 141 124.385
-166.364 141 126 167 140.417 126 182 141 124.889
-184 141 124.645 209 141 124.645 216 141 124.345
-218 141 123.818 42 142 124.235 43 142 125.559
-99 142 124.2 105 141.25 126 167 142 124
-183 142 124.645 186 142 124.7 186.722 142 126
-203 142 124.457 207.222 142 126 209 142 124.645
-213 142 124.5 46 142.5 126 168 143 123.13
-169 143 124.3 185 143 124.645 190 143 125.778
-191 143 124.457 192 143 124.645 205 143 124.8
-97 144 123.182 105 144 124.826 116 143.769 126
-168 144 124 169 144 123 184 144 123.882
-190 144 125.032 191 144 124.645 198 144 124.457
-202 144 124.457 105 145 124.105 106 145 124.2
-116.737 145 126 168 144.37 126 169 144.609 126
-188 145 125.1 189 144.125 126 193 145 125.55
-201 145 124.457 205 145 124.457 89 145.25 126
-115 145.857 126 115.25 146 126 194 146 124.457
-90 147 124.5 116 146.111 126 191 147 124.645
-202 147 124.457 196 148 124.8 43 149 124.364
-44 149 125.609 45 149 125.8 59 149 125.824
-191 149 124.457 194 149 123.529 197 149 124.556
-214 149 124.412 216 149 124.56 217 149 124.364
-42 150 123.818 43 149.857 126 44 149.273 126
-59.3333 150 126 60 150 125.75 61 150 125.333
-64 150 124.457 212.25 150 126 215 150 125.833
-216 150 125.864 217 150 124.909 54 151 123.316
-55 151 123.833 56 151 124.5 211.4 151 126
-214.75 151 126 54 152 124.286 59 151.375 126
-177 153 124.286 218 153 125.667 217.727 153 126
-176 154 125.308 102 155 125.8 174 155 125.55
-174 154.571 126 175 155 124.862 214 155 125.118
-215 155 124.5 217 155 124.875 217.4 155 126
-175 156 124.889 176 156 124.929 176.667 156 126
-214 155.909 126 216 156 123.938 217.368 156 126
-218 156 123.6 219 156 123.692 100 156.333 126
-102 157 123.75 103 156.273 126 204 157 125.4
-216 157 124.714 218 157 123.6 219 157 123.391
-100 157.909 126 205 158 123.8 206 158 124.091
-184 159 125.323 184 158.125 126 185 158.217 126
-185 159 124.258 205 159 123.517 208 158.923 126
-165 160 123.333 185 160 123.9 186 160 123.13
-208.654 160 126 209 160 123.75 61 161 123.3
-72 161 123.789 74 161 125.471 94 161 125.455
-94.5455 161 126 180 161 125.727 180 160.714 126
-181 160.444 126 185 161 125.684 57 162 124.2
-57.6 162 126 60 162 125.25 61 162 123.75
-70 162 124.579 73 162 123.556 92 162 124.7
-167 162 125.625 167.333 162 126 168 161.923 126
-168 162 125.143 181 162 123.188 180.063 162 126
-208 162 124.875 60 162.097 126 61 162.273 126
-69 163 124.5 71 163 125.727 71.25 163 126
-167.391 163 126 168 163 123.2 171 162.265 126
-181.25 163 126 207 162.2 126 208 163 126
-90 164 124.92 97.7273 164 126 163 164 125.25
-163 163.813 126 181 164 123.563 182 164 123.783
-190 163.773 126 87 165 125.4 86.6 165 126
-87.8571 165 126 192 165 124.111 194 165 123.1
-86 166 124.35 87 166 124.444 87.6364 166 126
-90.7391 166 126 164.435 166 126 191.857 166 126
-198 166 125.318 210 166 125.25 84.4737 167 126
-86 167 124.25 86.5833 167 126 162 166.6 126
-163 167 124.8 171.2 167 126 189 166.143 126
-210 167 124.125 211 167 123.75 84 168 123.818
-90 168 123.4 211 168 125.211 191 170 124.696
-190.333 170 126 192 169.889 126 192 170 125.25
-169 171 124.765 170 170.842 126 170 171 125.609
-191 170.909 126 192 171 124.263 191.083 171 126
-169 172 124.043 168.375 172 126 192 172 125.455
-193 172 124.875 171 173 124.636 170.737 173 126
-193 173 123.75 194 173 123.75 170 174 125.211
-171 174 125 195 175 124.2 195.13 175 126
-194 175.435 126 195 175.375 126 197 178 124.889
-197 179 124.821 197.733 179 126 197 179.917 126
-175 183 125.6 179 183 125.769 164 183.941 126
-184 184 124.2 175 185 124.889 176 185 125.308
-177 184.714 126 184 185 125.684 170 185.722 126
-170.714 186 126 173 185.714 126 176 185.375 126
-171 186.087 126 172 186.261 126 179 186.455 126
-180 186.333 126 192 186.818 126 182.5 188 126
-93 190 125 96 190.059 126 202.654 72 129
-207 72 128.806 209 72.6087 129 210 73.0909 129
-208 76 128 207.533 76 129 210 79 126.789
-210 78.2632 129 211 79 128.6 210 80 127.364
-210.857 80 129 211 79.6667 129 212 80 128.833
-211.5 80 129 212 79.9091 129 212 81 128.483
-211.5 81 129 212.5 81 129 212 81.4545 129
-207 85 126.857 205.1 86 129 207 86 126.5
-208 86 126.214 211 85.6667 129 212 86 126.5
-213 86 126.5 207 87 128 212 87 126.857
-213 87 127.071 205.833 88 129 207 87.0909 129
-210 88 126.4 211 87.75 129 211 88 127
-206 88.1667 129 210 89 127.773 205 90 128.684
-214 90 126.316 204 90.625 129 205 91 127.889
-211 90.625 129 212 90.4167 129 213 91 127.071
-215 91 126.882 223 91 128.143 204 92 128.125
-223 92 126.882 37 93 128.6 38 92.7143 129
-38.0909 93 129 203 93 128.684 205 93 127.457
-208 93 128.206 209 93 128.032 210 93 128.667
-37 94 128.053 203 94 128.333 209 94 128.333
-213.125 94 129 219 94 127.286 36 95 127
-202.739 95 129 209 95 128.125 34.9333 96 129
-203.5 96 129 209.583 96 129 213 96 128.625
-212.75 96 129 206 97 127.8 208 97 127.457
-210 96.7143 129 210 97 128.684 205 97.5 129
-209 98 127.889 211 98 127.889 212 99 127.889
-213 99 127.5 209 100 127.645 209 101 127.457
-212 102 127.457 208 103 127.8 208 104 127.457
-205 109 128.206 203 110 128.143 206 110 128.032
-207 110 127.457 214 110 127.457 212 111 127.457
-200 111.833 129 201 113 127.457 198.625 114 129
-204 114 127.853 218 114 126.818 199 115 127.8
-200 115 127.457 201 117 127.457 215 117 126.265
-223 117 127.895 222.632 117 129 223.875 117 129
-211 118 127.457 212 118 127.5 223 118 128
-222.143 118 129 223.261 118 129 202 119 128.8
-208 119 127.457 213 119 128.206 214 119 127.182
-202 120 128.419 203 120 128.5 209 120 127.457
-161 120.417 129 204 121 128.118 209 121 128.032
-152 121.818 129 166.6 122 129 205 122 127.457
-29.8235 123 129 167 122.25 129 168.6 123 129
-149 123.7 129 170.25 124 129 188 124 128.909
-187.833 124 129 208 124 127.889 196 125 128.143
-197 125 127.8 206 125 127.457 218 124.955 129
-218.1 125 129 39 126 127.182 189 126 128.824
-199 126 128.032 204 126 127.457 206 126 127.645
-210 126 128.308 133 126.824 129 172.75 127 129
-174 126.857 129 174.286 127 129 199 127 128.333
-205 127 127.457 206 127 127.889 210.455 127 129
-211 127 126.75 214 127 128.077 214.571 127 129
-216 126.25 129 218 127 126.3 217.25 127 129
-173 127.125 129 199 128 128.125 206 128 128.125
-215 128 126.964 228 128 126.818 179 128.182 129
-181 129 127.645 206.833 129 129 39 130 126.581
-146.273 130 129 179 130 127.8 183 130 127.457
-197 130 127.853 198 130 127.889 205 130 127.457
-207 130 128.25 209 129.417 129 39 131 126.529
-40 131 127.2 41.625 131 129 197 131 128.4
-198 131 128.55 201 131 128.125 209 131 127.457
-40 132 127.853 188 133 128.032 40 134 127.286
-180 134 127.543 187 134 127.889 188 134 128.217
-192 134 128.471 193 133.75 129 184 135 128.1
-188.286 135 129 192 135 127.457 43 136 127.8
-43.875 136 129 182 136 127.2 184 136 128.778
-185 136 128.778 186 136 128.125 206 136 127.457
-219 136 128.55 183 137 128.143 184 137 128.778
-185 137 128.778 196 137 128.55 203 137 127.8
-218 137 128.625 217.813 137 129 219 137 127.696
-220.375 137 129 102 138 126.29 184 138 127.75
-187 138 127.645 188 138 127.962 202 138 128.559
-219 137.667 129 220 137.375 129 222 138 128.4
-221.25 138 129 223 138 127.25 224 138 127.875
-224.375 138 129 186 139 128.1 187 139 127.889
-188 139 128.333 201 139 128.8 203 139 128.559
-205 139 128.032 206 139 127.444 223 139 126.429
-222.6 139 129 225 138.714 129 225.105 139 129
-186 140 126.563 187 140 127.111 188 140 127.853
-192 140 127.457 193 140 127.457 197 140 127.645
-200 140 127.457 204 140 128.423 204.714 140 129
-225 139.133 129 104 141 127.636 166.667 141 129
-167 140.143 129 188 141 128.4 189 141 128.909
-190 141 128.182 196 141 127.457 205.167 141 129
-213 141 127.154 214 141 127 105 142 126.818
-166.435 142 129 189 142 128.897 199 142 127.235
-200 142 126.882 201 142 126.176 207 142 128
-48 143 127.5 106 143 128.167 187.5 143 129
-189 143 128.833 188.857 143 129 194 143 127.345
-206 143 126.316 207 143 128 208 143 126.682
-50 143.188 129 207 144 127.615 208 144 127.7
-113.6 145 129 114 144.143 129 188 144.091 129
-114 146 128.217 115 147 128.769 114.714 147 129
-116 146.609 129 43 149 127.636 44 149 127.286
-44.4 149 129 45 148.455 129 46 148.727 129
-46 149 128.182 47 149 127.95 47.4667 149 129
-67 149 126.529 46 149.25 129 47 149.875 129
-59 150 126.094 211.455 150 129 214 150 126.75
-59 151 127 210 151 127.625 210 150.522 129
-211 151 126.3 213.667 151 129 208.813 152 129
-210 152 127.889 211 152 127.95 209 153 129
-211 152.304 129 216 153 128.786 214 153.565 129
-217 154 127.875 218 153.933 129 217.75 154 129
-174 154.5 129 176.895 155 129 205 155 128.71
-206 155 128.118 207 154.625 129 207 155 128.667
-101 156 128 102 156 127.826 174.074 156 129
-177 155.087 129 177 156 126.577 183 156 128.25
-182.125 156 129 204 156 127.147 206 156 128.308
-97 157 127.846 98 156.313 129 98 157 127.821
-100 156.067 129 101 156.625 129 101.25 157 129
-102 157 127.2 176 157 126.115 177 157 126.441
-183 157 127.8 184 156.632 129 184 157 128.125
-202 157 128.824 203 157 126.9 214 156.618 129
-217 157 127.5 178 158 128.71 183 158 128.222
-184 158 126.158 61 159 128.727 62 159 127.645
-95 159 128.4 183 158.778 129 183.1 159 129
-207.435 159 129 58.375 160 129 62 160 126.9
-71.9259 160 129 73 160 127.3 75 159.895 129
-94 160 126.75 95 160 127.038 95.7727 160 129
-179 160 128.8 180 159.045 129 180 160 126.577
-187 160 126.316 204 159.333 129 208 160 127.962
-62.4667 161 129 75 161 127.818 95 161 126.682
-95.5862 161 129 179.357 161 129 185 161 126.6
-186 161 128.348 186 160.545 129 208 161 127.304
-62 161.636 129 61.4286 162 129 71 162 128.625
-71.0769 162 129 92 161.056 129 168.769 162 129
-170 162 126.2 180 161.947 129 186 162 126.75
-187 162 128.217 207 162 126.692 207 161.167 129
-61 162.2 129 88.4545 163 129 89 162.455 129
-90 162.105 129 95 163 127.92 97.875 163 129
-167.833 163 129 181 162.231 129 187 162.75 129
-88 164 127.8 88 163.455 129 89 164 126.9
-95 164 127.714 97 164 128.286 96.6429 164 129
-100.176 164 129 163 163.571 129 163.857 164 129
-172.382 164 129 188 163.067 129 193 163.263 129
-86.5417 165 129 87 164.522 129 89 165 127.125
-90 165 127.5 97 165 128.769 98 165 128.217
-162.045 165 129 196 165 128.273 86 166 128.2
-86.3636 166 129 87.5833 166 129 91 165.261 129
-99 165.333 129 162 166 127.929 168.923 166 129
-194 166 126.818 195 166 128.294 195 165.6 129
-196 166 128.429 197 166 127.909 85 167 127.111
-86 167 127.05 92 167 127.5 93 167 128.5
-95.6667 167 129 165 167 126.857 189 167 127.125
-189.667 167 129 191 166.385 129 193 166.111 129
-166 168 128.1 166.857 168 129 189 168 127.696
-190 168 129 95.3704 169 129 164 168.333 129
-167.25 169 129 188.727 169 129 190 169 126.375
-95 169.909 129 168 170 127.75 169 170 126.783
-169.773 170 129 191 169.125 129 192 170 126.75
-168 171 128.25 167.87 171 129 169.944 171 129
-192 171 128.063 192 172 126.333 193 172 126.474
-193 173 126.45 194 173 126.45 194 174 127.222
-194 175 127.111 195 175 126.6 196 177 127.714
-196 176.75 129 197 177 127.333 197.833 177 129
-196 178 127.364 198.667 178 129 198 179.75 129
-207 180 128 92 181 128.667 92.375 181 129
-196 180.778 129 197 181 128.526 196.4 181 129
-202 181 127.174 204 181 127.765 207 181 127.393
-208 181 128.55 92 182 127.636 92.9091 182 129
-200.75 182 129 202 182 127.038 206 182 128.471
-207 182 128 208 182 127.444 209 182 126.9
-92 183 128.571 92.6667 183 129 174 183 126.273
-173.375 183 129 177 183 127.773 197 183 128.609
-198 183 128.71 207 183 128.333 208 183 126.261
-92 183.125 129 172 184 128.526 171.25 184 129
-171 185 128.455 172 185 127.8 173 185 126.682
-170 185.9 129 170.25 186 129 176 185.929 129
-175.68 187 129 179 187 127.565 178.45 187 129
-180 187 127.385 181 186.4 129 179 188 127
-178.5 188 129 180 188 126.5 181 188 127.5
-182 188 127.688 192.727 189 129 94 189.409 129
-95 190 127 193 189.194 129 86 191 126.5
-90.7368 191 129 87 191.8 129 90 191.452 129
-203 72 130.929 204 72 131.308 207 74 131.727
-208 74 130.962 211 74 130.765 208 75 130
-207.474 75 132 209 75 131.526 209 75.375 132
-208 76.5556 132 211 79 129.6 210 80 130.636
-212 80 129.231 212 81 129.882 213 82 130.5
-214 83 130.2 214.6 83 132 214 84 132
-206 85 130.2 214 85 129.429 213.5 85 132
-215 84.1 132 215 85 129.545 206.667 86 132
-210.727 86 132 215 85.5 132 42 87 131.909
-205.9 87 132 205.182 88 132 207 88 132
-41 89 131.824 205 89 130.846 205 88.2857 132
-206 89 129.882 207 89 130.857 208 89 130
-206 90 129.125 208 90 130.345 209 90 129.529
-210 90 129.261 39 91 131.739 211 91 129.391
-212 91 130.75 216 91 131.571 215.8 91 132
-216 90.7143 132 38 92 131.143 39 92 130.962
-39.6 92 132 203.37 92 132 212 92 130.364
-216 92 130.875 39 93 131 212 93 130.655
-216 92.75 132 211 95 132 212 95 132
-213 95 130.071 215 95 131.609 215 94.25 132
-216 95 132 202.533 96 132 215 95.3333 132
-211 97 129.094 34.5 98 132 203 98 131.129
-204 99 131.419 205 99 131.25 206 99 130.773
-37 100 129.529 201.727 100 132 207 100 130.304
-202 101 131.032 203 101 130.457 204 101 130.8
-202 102.25 132 202.857 103 132 203.167 104 132
-198.346 112 132 196 115.929 132 223 117 130.4
-194 118 131.739 193.889 118 132 223 118 130.636
-194 119 131.419 193.143 119 132 195 120 131.559
-212 120 129.882 153 121 129.667 155 121 130.543
-161 121 129.875 192 121 131.806 192 120.75 132
-192.5 121 132 195 121 131.471 212 121 130.154
-161 122 130.543 166 122 129.45 192.667 122 132
-193.75 122 132 40 123 131.1 152 123 129.857
-166 123 129.581 168 123 129.45 191 123 131.125
-193 122.75 132 193 123 131.909 202 123 129.545
-209 123 129.818 210 123 130.56 41 124 131.684
-159 124 130.543 167 124 130.147 187 124 130.364
-188 123.087 132 189 124 130.5 190 124 130.75
-195 124 129.857 210 124 129.409 218 124 131.625
-218 123.727 132 40 125 130.5 150 125 130.645
-157 125 130.543 165 125 129.529 170 125 130.355
-186 125 129.545 185.64 125 132 187 125 129.261
-191.75 125 132 192 124.5 132 194 125 131.182
-209 125 129.469 217 125 129.563 43 126 130.8
-157 126 130.543 158 126 129.581 160 126 129.2
-161 126 130.2 163 126 130.543 187 126 129.2
-190 126 130.235 201 126 129.094 208 126 129.714
-151 127 130.889 153 127 131.143 154 127 131.471
-155 127 131.118 156 127 131.471 159 127 129.5
-170 127 130.543 188 127 129.818 192 126.6 132
-192 127 131.824 210 127 130.667 133 127.5 132
-160 128 130.3 174 128 131.333 175 127.875 132
-176 127.625 132 180 127.435 132 185 128 131.885
-184.857 128 132 187 128 130.235 188 128 129.818
-191 128 131.206 200 128 129.844 201 128 130.545
-206.913 128 132 209.933 128 132 216 127.889 132
-44 129 130.645 161 129 131.824 164 128.909 132
-184 128.231 132 192 129 130.3 200 129 129.844
-201 129 130.182 207 128.286 132 42 130 130.111
-44 130 131.333 187 130 129.529 188 130 129.529
-189 130 130.08 190 130 129.882 191 130 130.5
-192 130 130.111 194 130 130.2 201 130 129.091
-44 131 131.333 188 131 129.265 189 131 130.773
-192 131 131.217 193 131 130.2 199 131 130.2
-46 132 131.333 192 132 131.333 194 132 130.5
-196 132 129.882 199 132 132 43 133 131.909
-47 133 131.032 106 133 129.882 110 132.265 132
-189.538 133 132 192 133 130 193 133 129.529
-195 133 130.235 197 133 131.217 197.462 133 132
-42 134 130.909 48 134 131.419 189 134 130.071
-190 133.545 132 191 134 130.8 194 134 129.682
-195 134 130.5 196 134 130.3 197.5 134 132
-198.857 134 132 45 134.857 132 103 135 129.265
-196 135 130 101 136 129.265 102 136 129.176
-189 136 129.517 196.571 136 132 218 136 129.167
-217.105 136 132 189 137 129.774 190 137 129.469
-196.696 137 132 201 137 129.9 221 136.875 132
-221 137 130.875 49 137.85 132 199.688 138 132
-217 138 131 220 138 129.682 223 138 130.615
-45 139 130.545 46 139 131.206 49 139 130.457
-52 139 130.457 199 139 129.882 199 138.478 132
-222 138.545 132 223 139 130.286 224 139 130.154
-50 141 130.457 87 141 131.206 131.294 141 132
-168 141 130.105 185 141 131.625 186 141 131.438
-186.188 141 132 204.75 141 132 205 140.813 132
-207.333 141 132 50 142 130.2 86 142 130.457
-106 142 131.143 167 142 130.182 186 142 132
-188 142 129.391 205.417 142 132 106 142.286 132
-187 143 131.25 186.333 143 132 187 142.857 132
-187.667 143 132 206 142.259 132 56 144 130.457
-75 144 130.457 80 144 130.457 85 144 129.265
-158 144 130.875 157.667 144 132 159 143.091 132
-159 144 130.421 159.667 144 132 171 144 129.789
-172 143.25 132 186.813 144 132 189 144 132
-74 145 130.457 81 145 129.529 82 145 130.235
-84 145 129.818 113.818 145 132 158 144.75 132
-159 145 131.308 158.143 145 132 159.545 145 132
-170 145 130.8 172 145 130.853 116.111 146 132
-159 145.4 132 172 146 131.118 73 147 129.176
-114 147 129.556 116 146.375 132 114 148 131
-115 147.947 132 45 149 129.783 46 149 129.6
-47 149 130.75 212 150 129.783 212 151 130.957
-208.8 152 132 210.545 152 132 63 153 131.077
-62.2 153 132 63 152.667 132 64 153 130.95
-208 153 129.75 210.133 153 132 216 153 129.273
-218 153 130.826 65 153.571 132 65 154 131.667
-66 153.667 132 66 154 131.419 207 154 130.875
-206.625 154 132 209 154 131.667 209.5 154 132
-216 154 130.667 217 154 129.474 64.8125 155 132
-66 155 131.118 181 155 130.3 182 155 129.1
-183 155 129.167 203.25 155 132 208 155 130.5
-209 155 131.8 210 155 131.471 211 154.421 132
-211 155 130.969 212 154.192 132 65.6 156 132
-67 155.125 132 67 156 131.323 68 156 131.667
-98.5455 156 132 175 155.818 132 176 155.65 132
-180.923 156 132 182 156 129.115 201 156 130.696
-202 155.419 132 208 156 131.8 209 155.5 132
-210.25 156 132 64 157 131.8 64.5 157 132
-66 157 131.769 68 157 131.118 69 157 131.118
-70.1875 157 132 99 156.357 132 99.4091 157 132
-175.1 157 132 184.077 157 132 200 157 130.543
-206.143 157 132 209 157 131.824 209.667 157 132
-212 156.292 132 214 156.519 132 61.2273 158 132
-65 158 131.654 70 157.75 132 93.6667 158 132
-94 157.474 132 185 158 129.947 184.188 158 132
-200 158 130.543 201 158 130.355 206 158 130.5
-206 157.071 132 61 158.278 132 71.4167 159 132
-72 158.533 132 74 158.824 132 75 159 130.889
-98 158.567 132 178 159 130.174 179 158.1 132
-179 159 129.158 183 158.188 132 184 159 131.348
-184 158.375 132 185 159 131.2 200 159 131.71
-204.25 159 132 207 159 130.579 206.25 159 132
-77 159.455 132 77.75 160 132 181 159.227 132
-185 160 130.742 186 160 129.783 206 160 131.885
-207 160 131.04 77 161 131.118 78 160.4 132
-78 161 131.743 89 161 131.053 92.6 161 132
-178 160.545 132 91 161.474 132 99 163 130.909
-181 162.375 132 186 162.474 132 96 163.571 132
-163 164 129.947 168.265 164 132 184 164 131.471
-183.25 164 132 189 163.45 132 193 164 131.625
-87 165 130.65 87.75 165 132 92 164.409 132
-96 165 129.158 98.9333 165 132 163 165 131.172
-164 165 131.333 183.333 165 132 185 165 130.147
-194 165 130.875 195 165 130.5 87 166 129.75
-97 166 131.684 163 166 131.5 166 165.903 132
-190 165.833 132 189.875 166 132 167 166.567 132
-93 168 129.316 163.769 168 132 167 168 129.091
-168 167.346 132 168 168 130.3 188 168 132
-95 168.273 132 166 169 130.227 167 169 129.1
-189 168.857 132 189 169 131.571 190 169 130.105
-62.75 170 132 63 169.8 132 64 169.143 132
-64 170 129.429 94 170 129.882 190 170 129.45
-191 170 129.778 63 171 131.571 62.75 171 132
-169 170.895 132 176 171 131.25 175.143 171 132
-197 170.625 132 175 172 131.667 176 172 130.5
-178 172 131.71 179 172 131.71 179.429 172 132
-198 172 130.444 199 172 131.4 176 173 131.308
-177 172.667 132 179 173 131.71 179.273 173 132
-175 174 131.4 198 173.909 132 198 175.4 132
-199 175.8 132 197 176.6 132 199 177 131.125
-180 179 131.71 196 178.4 132 201 179 130.444
-200.067 179 132 178 180 131.71 178 179.75 132
-178.75 180 132 92 181 132 178 181 130.895
-177 181 132 178.875 181 132 208.526 181 132
-92 182 131 179 181.091 132 196 181.455 132
-92 183 129.333 171 182.941 132 199 183 130.696
-201 183 130.364 206 183 130 172 183.684 132
-180.875 184 132 198 184 129.794 199 184 130.6
-200 184 130.625 202 184 130.821 203 184 131.471
-204 184 131.824 182 184.6 132 183 184.6 132
-184 184.625 132 199 185 131.4 200 185 130.5
-201 185 130.2 202 185 130.8 203 185 131.1
-204 185 130.962 168 185.045 132 171 186 129.45
-172 186 129.75 191 186 131.571 201 186 129.2
-175 187 131.217 176 188 129.783 178 189 130.579
-179 188.75 132 179 189 131.625 93 189.8 132
-179 189.167 132 193 189.323 132 85 191 131.727
-91 190.056 132 86 68 134.625 87 68 134.125
-85 69 134.206 87 69 134.419 91 69 134.824
-203 72.6538 135 207.278 75 135 208 75.6842 135
-215 77 133.444 49 78 134.8 214 78 134.769
-210 79 132.529 214 78.2857 135 216 78.1333 135
-213 79.8667 135 214 80 133.962 213 81 133.5
-212.375 81 135 211.714 82 135 207 82.375 135
-207 83 134.118 208 83 133.846 209 83 134.824
-209.333 83 135 211.714 83 135 43 84 133.696
-44 84 134.419 44 83.1429 135 206 84 132.125
-207 84 133.846 208 84 133.5 208.714 84 135
-209 83.3333 135 210 84 134.769 210.167 84 135
-213 84 134.143 214 83.5 135 213.667 84 135
-42 85 133 41.5652 85 135 43 85 132.581
-44 85 134.471 207 85 134.75 207.125 85 135
-208 84.4167 135 210 84.3333 135 213.75 85 135
-214 84.3333 135 215 84.625 135 215.25 85 135
-42 86 132.261 43 86 133.2 207 86 132.5
-211 86 133.8 41 87 132.316 43.5909 87 135
-206 87 132.143 41 88 132.1 42 88 132.882
-206 88 133.227 40 89 132.115 205 89 132.6
-206 89 133.714 207 89 133.412 39 90 133.8
-206 89.6 135 40 91 132.176 216 91 132.857
-215 94 132.75 214.4 94 135 215.6 94 135
-214 95 133.421 213.333 95 135 216 94.4 135
-214 96 133.444 215 96 132.9 215.737 96 135
-216 95.375 135 214 97 133.778 215 97 134.053
-214 97.9167 135 210 102 134.71 210 101.727 135
-202.278 103 135 230.5 103 135 40 115 132.581
-196 117.143 135 193.25 119 135 192 120.75 135
-192.667 121 135 43 122 133.355 44.25 122 135
-190.75 122 135 192.75 122 135 193.25 122 135
-193 122.167 135 40 124 132.176 188 123.833 135
-189 123.833 135 190 123.286 135 218 123.421 135
-192 125 132.75 193 125 132.316 218.806 125 135
-192 126 132.75 148 127 132.857 149 127 133.2
-150 127 132.176 209.375 127 135 133 128 133.444
-186.143 128 135 206.125 128 135 209.909 128 135
-216 128 133.2 148 129 133.543 149 129 133.543
-156 129 133.543 163 129 132.857 174 129 132.103
-206 129 134.182 207 129 133.25 216 128.75 135
-154 130 133.543 204 130 134.71 203.85 130 135
-205 130 134.25 206 130 134.684 207 129.368 135
-215 130 134.308 215 129.25 135 148 131 132.857
-163 131 133.543 174 131 134.286 189.353 131 135
-204 130.75 135 215 131 133 215.667 131 135
-151 132 134.118 160 132 133.5 162 132 133.8
-163 132 133.543 166 132 134.471 199 131.462 135
-215 132 133.688 214.125 132 135 150 133 134.143
-189 133 133.75 189 132.286 135 191 133 132.833
-44 134 132.29 45 134 132.529 51 134 134.143
-52 134 134.206 150 134 134.032 156 134 133.645
-157 134 133.889 163 134 133.125 164 134 133.147
-175 134 134.727 189 134 133.227 190 134 133.364
-190.5 134 135 46 135 132.882 47 135 132.882
-51 134.833 135 53 135 134.333 154 135 134.471
-155 135 134.143 164 135 133.455 187.643 135 135
-189 135 133.345 198.333 135 135 47 136 134.559
-47.625 136 135 165 136 134.531 190 136 133.966
-211 136 134.654 210.8 136 135 213 136 133.8
-214 136 134.032 215 136 134.333 46 137 133.182
-47 137 134.559 48 137 134.897 49 136.583 135
-57 137 134.8 57 136.75 135 189 136.455 135
-190 136.526 135 195.5 137 135 211 137 134.118
-210.091 137 135 212 137 134.118 214 137 133.8
-215 137 132.857 216 137 132.1 46 138 132.529
-47 138 133.182 56 138 134.217 56 137.143 135
-55.25 138 135 90 138 132.882 161 138 134.714
-55 139 132.429 55 138.1 135 215 138.609 135
-117 140 134.6 116.714 140 135 118 140 133.8
-119 139.455 135 119 140 134.053 119.316 140 135
-185 139.867 135 69 141 133.8 73 141 133.457
-76 141 134.824 76 140.6 135 79 141 133.457
-186 140.444 135 186.333 141 135 203 141 134.032
-204 141 133.35 207.455 141 135 77 142 132.909
-104.5 142 135 105.75 142 135 168 142 132.321
-169 142 133.179 170 142 133.32 185 142 132.13
-186.333 142 135 203 142 134.824 105 142.6 135
-186 143 132.429 186.545 143 135 187 143 132.857
-159 144 134 170 143.167 135 171 143.391 135
-172 143.105 135 186 143.429 135 187 144 134.25
-187.25 144 135 159 145 133.636 188 144.375 135
-113.5 146 135 115 146 134.7 161 146 133.95
-160 146 135 161 145.125 135 162 146 135
-113 147 132.789 113 146.125 135 161 147 134.125
-160.563 147 135 162 147 134.679 172 147 132.091
-113 148 133.3 112.37 148 135 161 147.467 135
-162 147.273 135 173 148 133.645 174 148 134.739
-178 148 133.6 178 147.417 135 50 149 133.714
-49.8125 149 135 51 149 133.6 112.818 149 135
-114 149 134.727 125 148.04 135 174 149 134
-175 149 133.846 177 149 133.355 178 149 133
-178.783 149 135 51 150 133 50.0909 150 135
-52 149.067 135 53 149.565 135 53.9091 150 135
-113 149.133 135 178 150 133.688 53 150.667 135
-177 151 134.71 178 151 133.8 210 151 132.692
-211 151 132.346 179 152 133.969 179.917 152 135
-210 152 133.125 63 153 133 63.7273 153 135
-178 152.188 135 180 153 133.258 181 153 134.55
-65 153.625 135 66 153.667 135 66.2727 154 135
-180 154 132.103 182 153.769 135 210 154 132.375
-211 153.6 135 179.409 155 135 182.955 155 135
-212 154.263 135 214 155 134.471 213.333 155 135
-65 156 133.688 64.5625 156 135 68 155.3 135
-175 156 132.4 177 156 132.875 183 156 134.885
-198 155.65 135 210 156 132.2 212 156 134.625
-213 156 133.4 214 156 133.826 65 157 132.261
-98.6774 157 135 165 157 134.16 164.364 157 135
-165 156.417 135 176 156.867 135 175.867 157 135
-181 156.077 135 182 157 133.2 183 157 134.333
-198 157 132.529 208 157 132.75 210 157 132.273
-61.1429 158 135 67 158 133.258 70 158 132.273
-71 157.625 135 71 158 132.75 195 158 134.471
-197 158 133.543 205 158 133.5 205 157.5 135
-204.333 158 135 208 158 134.609 209.917 158 135
-210 157.909 135 61 159 134.167 61.4545 159 135
-65.9333 159 135 71 158.375 135 72 158.727 135
-77 158.654 135 208 159 134.6 209 159 134.609
-60 160 132.875 61 160 134.2 62 160 134.9
-78 160 132.222 79 159.217 135 80 159.263 135
-80 160 133.765 200.435 160 135 208 159.143 135
-209 159.214 135 60 161 132.333 61 161 133
-62 161 132.692 79 161 132.771 81 161 133.8
-87.5 161 135 95.5 161 135 169 161 133.385
-182 161 134.143 200 160.909 135 77 162 132.577
-81 162 134.471 92 161.778 135 178 162 132.581
-179 162 132.222 182 162 133.421 186 161.931 135
-72 163 132.818 76 162.323 135 81 162.261 135
-93 162.182 135 178 163 133.846 177.333 163 135
-181 163 133.111 182 163 133.355 183 162.364 135
-183 163 133.645 98 163.769 135 182 164 132.794
-183 164 132.194 187.947 164 135 190 164 132.333
-191 164 132.333 88 164.25 135 88 165 133
-91 164.957 135 168.222 165 135 183 165 132.789
-189 165 133.853 190 165 132.882 195 165 134.25
-195 164.333 135 98.4 166 135 149.588 166 135
-165 166 133.962 166 166 133.125 169 166 133.5
-168.5 166 135 172 166 132.261 173 165.091 135
-182 165.292 135 186 165.955 135 187 166 134.842
-195 166 134.143 97 166.706 135 165 166.6 135
-166 166.192 135 168 166.125 135 168 167 133.174
-169 166.286 135 173 167 134.25 172.125 167 135
-173.875 167 135 195 167 134.053 94 167.091 135
-94 168 132.778 95 167.7 135 173 168 134.679
-174 168 134.032 189 168 132.6 195 168 134.419
-196 167.25 135 196 168 134.471 165.433 169 135
-174 169 133.5 196 169 133.625 63 170 135
-64 170 133.2 174 170 133.645 175 170 133.174
-195 169.545 135 196 170 133.688 197 169.75 135
-197 170 133.875 63 171 134 168 170.5 135
-176 170.067 135 196.417 171 135 86 172 133.543
-174.3 172 135 178 171.8 135 179.875 172 135
-219 171.739 135 83 173 134.778 84.7143 173 135
-87 173 133.543 173.926 173 135 174 172.75 135
-177 172.733 135 179.917 173 135 205 173 133.696
-205 172.091 135 206 173 133.565 206.647 173 135
-81 174 134.52 80.5556 174 135 82 174 134.333
-85 173.667 135 176 173.25 135 178 173.273 135
-179.182 174 135 198 173.857 135 205 173.667 135
-206 174 135 81 174.8 135 86 175 134.087
-174 175 134.143 175 175 132.429 175.316 175 135
-179 174.333 135 86 176 133.421 87 176 133.889
-198 175.364 135 199.261 176 135 207 176 134.053
-207 175.25 135 208 175.571 135 208 176 132.429
-86 177 134.182 85.8696 177 135 87 177 134.308
-176 177 134.609 177 177 134.667 207 177 134.069
-208 177 134.182 208.545 177 135 86 177.333 135
-87 177.545 135 176 178 134.609 177 178 134.625
-177.375 178 135 180 177.222 135 181 177.684 135
-199.929 178 135 200.091 178 135 201 177.565 135
-207 178 132.6 208 178 133.091 208.737 178 135
-176 178.6 135 177 179 134.55 178 178.417 135
-178 179 133.688 179 179 132.273 181 179 132.158
-196 179 133.227 198 178.933 135 199 178.684 135
-177 180 135 179 180 132.75 180 180 132.833
-181 180 132.167 182.065 180 135 197 179.429 135
-197 180 134.143 178 180.909 135 178 181 134.625
-180.375 181 135 182 181 133.364 196 181 133.071
-196.818 181 135 197 180.667 135 198 180.818 135
-177 181.5 135 178 181.333 135 181.125 182 135
-199 182 134.6 182 182.875 135 182 184 134.25
-166 184.045 135 184 184.1 135 174 186 134.318
-180 185.391 135 174 187 132.333 177 186.333 135
-190.4 187 135 90 188 134.609 89.625 188 135
-178 187.087 135 90 189 134.125 90.875 189 135
-174 189 134.1 193 188.591 135 91 189.143 135
-179 190 133.154 180 189.133 135 180 190 132.947
-181 190 134.684 88.4737 191 135 84 192 133.304
-93 191.391 135 80 192.5 135 92 68 135.3
-92.6429 68 138 82 69 136.773 83 69 135.273
-84 68.1923 138 66 70 136.5 66 69.4348 138
-69 70 137.419 72 70 137.824 75 70 136.645
-81 70 136 82 70 136.2 83 70 135.6
-84 70 135.75 86.875 70 138 87 69.9333 138
-89 69.875 138 89.1333 70 138 93 70 136.645
-94 69.1818 138 94 70 137.206 97 70 137.684
-65 71 137.739 66 71 136.962 67 71 137.333
-80 70.9444 138 83 71 137 90 71 137.684
-93 71 136.645 94 71 136.457 97 71 137.217
-97.8571 71 138 63 72 137.679 64 72 137.8
-64 71.3333 138 96 72 137.125 97 72 137.125
-97.875 72 138 62 73 137.778 97 72.875 138
-98 72.3333 138 97.3333 73 138 98 73 137.684
-98.5 73 138 99.25 73 138 101 73 136.889
-202 73 136.2 203 73 136.5 92 73.5 138
-101 74 137.419 202 74 136.636 203 73.5 138
-51 76 136.364 51 75.7778 138 52 76 136.364
-52.75 76 138 211 76 136.147 49 77 136.929
-50 77 135.316 51 77 135.261 52 77 137.053
-52.5 77 138 48 78 136.071 50 78 135.321
-51 78 136.556 47 79 137.455 48 79 135.261
-49 79 136 214 79 136.875 216 79 136.444
-47 80 135.5 48 80 136.5 213 80 135.333
-215 80 136.25 46 81 136.125 213 81 135.536
-214 80.2 138 214 81 136.286 45 82 135.714
-214 82 135.346 218.333 82 138 44 83 135.167
-45 83 135.2 46 83 136.5 207 83 136.071
-209 83 135.15 212 83 135.273 219 83 137.739
-218 83 138 45 84 135.529 207 84 136.5
-208 84 135.714 210 84 135.143 213 84 135.273
-218 84 137.52 217.5 84 138 219 83.3333 138
-207.2 85 138 214 85 135.333 215 85 135.45
-218 85 136.8 218.6 85 138 218 86 138
-40.5 87 138 215 94 135.391 215 95 137.25
-216 95 135.333 215 97 137.571 214 98 135.75
-213 98 138 41.375 99 138 204 99 136.889
-213 99 137.25 213.75 99 138 213 100 137.526
-202 101 135.968 212 101 137.667 211.25 101 138
-212 100.25 138 209.263 102 138 211 101.091 138
-211 102 136.696 210 103 135.938 209.421 103 138
-211.545 103 138 210 103.917 138 42 109 137.545
-42.6842 110 138 197 118 136.25 195 121 137.217
-195.316 121 138 45.5 122 138 192 122 135.783
-193 123 136.5 194.857 123 138 199 124 137.824
-188 125 136.2 189 125 136.2 191 125 135.667
-217 125 137.864 49 126 137.143 188 126 136.355
-190 126 137.032 192 126 136.8 186 127 135.222
-191 126.5 138 208 127 135.6 218 126.375 138
-207 128 136.826 208 128 137.143 99 128.5 138
-103 129 135.882 105 128.172 138 206 129 137.571
-208 129 135.818 97 130 137.471 99 130 136.457
-183 130 136.2 184 130 135.875 204 129.864 138
-205 129.533 138 206 129.333 138 98 131 136.889
-177 131 136.543 186 130.4 138 190 130.143 138
-190.4 131 138 204 131 135.6 203 131 138
-204.444 131 138 31 132 135.783 97 132 136.826
-173 132 135.667 182 132 136.543 184 132 136.25
-198 131.85 138 199 131.739 138 202 132 137.4
-202 131.842 138 203 132 136.25 203.583 132 138
-215 132 138 54 133 136.2 55 133 136.8
-56 132.5 138 89.6 133 138 93 133 136.8
-168 133 136.543 172 133 136.543 175 133 135.194
-177 133 136.2 184 133 136.889 184.909 133 138
-200 133 136.636 201 133 137.55 202 133 136.444
-203 133 137 56 134 137.143 92 134 137.032
-151 134 135.529 152 134 136.543 153 134 135.529
-174 134 135.176 176 134 135.455 180 133.273 138
-184 134 137.625 185 134 137.125 202 134 137.4
-51 135 135.2 54 135 135.6 57 135 136.556
-86 134.833 138 87 135 137.206 152 135 136.543
-160 135 136.355 175 135 135.441 185 135 137
-186 135 136.95 187 134.286 138 187 135 136.421
-201 134.182 138 213 134.727 138 48 136 135.391
-49 136 136.313 50 136 137.8 51 136 137.8
-53 136 135.4 55 136 136.2 57 136 136.125
-58 136 137.1 60 136 136.8 82 136 137.471
-89 136 135.968 152 136 135.968 158 136 136.2
-167 136 136.111 170 136 136.543 174 136 137.118
-176 136 135.577 192.818 136 138 210.6 136 138
-211 135.818 138 219 136 136.962 50 137 136.286
-52 136.533 138 53 136.65 138 55.3333 137 138
-56 137 135.429 153 137 135.857 159 137 136.111
-162 137 135.316 167 137 136.696 170 137 136.543
-177 137 137.55 195 137 137.053 209 137 137.625
-210 136.375 138 219 137 137.516 52 137.467 138
-55.5455 138 138 74 138 136.457 77 138 136.457
-79 138 137.217 80 138 137.217 158 138 137.4
-170 138 136.543 175 138 137.824 209 138 136.5
-210 138 135.794 220 138 137.318 221 138 137.143
-154 139 136.543 171 139 137.679 172 139 137.75
-196 139 136.5 208 139 136.75 209 139 135.875
-210 139 136 211 139 136.429 119 140 136
-155 140 137.471 184 139.625 138 184.2 140 138
-203 140 135.158 207 140 136.5 209 140 136.5
-182.684 141 138 202 140.056 138 208 140.75 138
-103.563 142 138 105.9 142 138 130.735 142 138
-156 142 137.4 185.7 142 138 201 142 136.457
-202 142 135.794 157 143 137.857 201 143 137.032
-202 143 136.645 203 143 137.217 205 142.69 138
-207 142.286 138 170 144 136.154 183 143.182 138
-185 143.261 138 188 144 135.29 155 145 137.182
-170.056 145 138 161.667 146 138 170 146 136.5
-162 146.25 138 169 147 137.471 168.143 147 138
-33.8235 148 138 175 148 137.053 50 149 135.333
-51 149 136.105 112 149 135.794 153 149 135.2
-51 150 137 53 149.522 138 54 150 135.6
-54.5 150 138 113 150 137.438 114 149.37 138
-163 150 137.609 163 149.625 138 179 149.5 138
-56.7273 151 138 58 150.125 138 58 151 137.222
-58.5833 151 138 112 150.933 138 163 151 137.71
-164 151 137.7 164.273 151 138 58 151.368 138
-173 151.333 138 176 151.5 138 64 153 135.333
-210 153 135.176 65 154 135.333 95 153.067 138
-182 154 135.783 210 154 138 121.176 155 138
-181 155 137.5 181 154.375 138 182 155 136.853
-67 155.222 138 98.5667 156 138 164.6 156 138
-182 156 136 211 156 135.692 166 157 135.667
-167 157 137.032 57 158 136.875 56.8 158 138
-58 158 135.375 59 158 135.375 63 158 137.739
-71 158 136.8 92.7368 158 138 165 157.875 138
-165.222 158 138 168 158 137.824 193 158 136.765
-207 157.467 138 208 158 137.25 208 157.947 138
-208.25 158 138 57 158.75 138 58 158.875 138
-59 158.467 138 62 159 135.667 72 159 135.375
-77 159 136.5 81 158.44 138 86 159 137.118
-90 159 136.6 168 159 137.471 170 159 137.735
-192 159 137.4 208 159 135.857 209 158.75 138
-209 159 137.25 73 160 136.2 74 160 136.457
-76 160 137.9 77 159.6 138 168 160 136.929
-171.37 160 138 194 160 136.543 73 161 136.2
-76 160.143 138 84 161 136.543 86 161 136.355
-91 161 136.5 106 161 136.714 105.25 161 138
-106.375 161 138 172.067 161 138 194 161 136.8
-193.263 161 138 195 161 137.25 195.467 161 138
-199 161 138 91 161.286 138 91 162 136.636
-91.625 162 138 106 162 136.875 105.25 162 138
-106.375 162 138 167.588 162 138 195 162 137.55
-200 161.75 138 76.9231 163 138 78 163 135.652
-89 163 136.826 91 162.333 138 176.935 163 138
-187.278 163 138 194 163 136.263 195 163 137.25
-77.75 164 138 194 164 137.143 195 164 135.75
-78 164.25 138 87 164.429 138 90.4348 165 138
-98.5 165 138 119.294 165 138 168 165 135.947
-91 166 136.889 167 165.565 138 168 166 135.222
-90 167 137.735 98 167 137.053 97.25 167 138
-99 166.417 138 99 167 136.688 165.567 167 138
-169 167 135.833 171.857 167 138 87 168 137.1
-86.6667 168 138 89 168 136.8 90 168 137.323
-91 167.857 138 93 167.261 138 99 168 136.565
-100 167.813 138 100 168 137.182 174 167.091 138
-196 167.25 138 63 169 136.875 62.625 169 138
-63 168 138 87 169 136.25 88 169 136.688
-89 169 136.543 90.15 169 138 98.8696 169 138
-100 169 135.273 201 169 137.71 63 169.429 138
-86 170 135.115 88 170 136.645 89 170 137.032
-196 170 136.313 196 169.25 138 197 170 135.45
-201 170 137.667 202 170 137.609 202.188 170 138
-89 171 137.684 100 170.133 138 174 170.636 138
-175 171 137.842 175 170.75 138 197 171 135.778
-201 170.188 138 202 170.75 138 83 172 136.421
-82.4444 172 138 176 172 136.688 177 172 136.138
-178 172 135.48 179 172 135.875 198 172 135.882
-84 173 136 173 172.867 138 174 172.455 138
-175 173 137 178 173 135.45 179 173 136.375
-198 173 135.581 205 173 137.727 206 173 137.75
-80.625 174 138 82.75 174 138 84 173.526 138
-85.0667 174 138 81 174.375 138 85.85 175 138
-175.368 175 138 205 175 137.684 205 174.5 138
-169 176 137.8 168.818 176 138 199 176 135.667
-202.286 176 138 203 175.474 138 204 176 137.323
-205 176 136.412 206 175.417 138 169 177 136.895
-168 177 138 175.75 177 138 176 176.571 138
-177 176.364 138 177.467 177 138 198 177 136.4
-199 177 136.4 202 177 137.55 201.813 177 138
-205 177 136.2 206 177 136 169 177.875 138
-177.333 178 138 179 178 137.143 179.4 178 138
-198 178 136.556 199 178 136.444 201.667 178 138
-203 178 135.375 204 178 135.9 208.526 178 138
-177 179 136.125 177 178.375 138 178 179 137.333
-179 179 137.5 179.167 179 138 197 179 135.45
-201 179 137.333 178 180 137.5 179 180 135.75
-181 180 137.318 182 180 135.333 201.684 180 138
-208.077 180 138 172 180.8 138 181 181 137
-181.714 181 138 198 181 137 201.087 181 138
-209 180.923 138 172 182 136.263 178 182 135.375
-183 182 136.364 197 181.333 138 198 181.045 138
-200 181.727 138 172 183 135.273 173 182.071 138
-173 183 135.4 182 183 135.75 183 183 135.923
-191 183 137.4 190.667 183 138 191 182.8 138
-191.273 183 138 184 183.591 138 187 184 136.645
-188 183.818 138 188.5 184 138 191 183.6 138
-167 184.071 138 189 184.667 138 189 185 137.864
-72 185.75 138 85 186 137.125 85 185.364 138
-89 186 135.577 88.3 186 138 196 186 135.462
-195.313 186 138 72 187 136.25 73 187 136.696
-84 187 136.969 85 187 137.032 90 187 135.857
-90.3226 187 138 174 186.091 138 177.944 187 138
-190.455 187 138 195 187 136.5 196 187 135.577
-198 187 135.231 73 188 137 89 188 135.652
-90.3333 188 138 191 187.75 138 73 188.158 138
-88.8 190 138 90.1053 190 138 180 189.125 138
-182.091 190 138 74 190.842 138 179 190.913 138
-180 190.875 138 181 190.929 138 182 190.286 138
-86 192.045 138 86 69 140.571 87 69 139.5
-89 69 140.625 89.1333 69 141 86.5333 70 141
-89 70 138.857 97 69.2 141 63 71 140
-64 71 138.136 71 71 138.529 72 71 138.882
-79 71 138.12 80 71 138.143 86 71 138.24
-87 70.3684 141 87 71 139 88 71 139.429
-89 71 139.08 98 70.5 141 98 71 138.5
-99 71 138.3 99.6429 71 141 62 72 138.214
-65 72 138.909 73 72 139.355 81 72 138.24
-87 72 139.345 98 72 139 100 72 138.857
-60 73 139.8 61 73 138.833 63 73 138.2
-74 73 139.8 76 73 139.889 80 73 140.217
-81 73 139.556 86 73 139.3 87 73 139.556
-89 73 138.931 97 73 138.167 99 73 139
-102 73 138.96 58 74 139.5 59 74 138.6
-60 74 138.6 61 74 139 62 74 139.4
-63 74 140.1 77 74 139.645 78 74 139.889
-80 74 139.889 89 74 140.1 95 73.5417 141
-98 74 139.5 56 75 138.75 58 75 138.25
-59 75 138.667 60 75 139.75 64 74.6 141
-77 75 140.471 79 74.8333 141 83 75 139.889
-87 75 140.806 90 75 139.457 97 75 140.769
-98 75 140.318 99 75 140.684 203 75 140.6
-204 74.1111 141 52 76 139.125 54 76 138.545
-53.25 76 141 55 76 138.316 57 76 138.818
-59 76 139.962 84 76 139.8 85 76 139.8
-86 76 140.206 100 76 139.7 101 76 139.7
-53 76.375 141 53 77 139.636 87 77 140.471
-99 77 140.679 102 77 140.824 54 77.75 141
-96 78 139.8 99 78 140.032 100 78 140.206
-47.3846 79 141 213.737 80 141 217 80 138.103
-53 80.25 141 216 80.9091 141 207 82.9444 141
-48 84 140.471 219 84 139.2 218 84.75 141
-219 84.4 141 215 96 138.29 214 97 139.5
-212.5 98 141 213 97.6842 141 214 98 139.8
-211.778 99 141 212 98.5 141 213.737 100 141
-211.167 101 141 210 104 139 211 104 139.696
-42 105 138.667 210 104.5 141 211 105 140.8
-210.5 105 141 229 105.25 141 42 107 138.783
-210 107 139.091 210 108 140.526 209.25 108 141
-43 109 138.968 43 111 138.529 45 112 140.471
-201 114 140.76 201 115 139.44 202.8 115 141
-204 115 140.76 203.5 115 141 204.286 115 141
-199 116 138.469 202 116 139.143 203 115.5 141
-203 116 140.647 203.5 116 141 201 117 140.118
-202 117 139.846 203 116.167 141 200 118 140.76
-200.167 118 141 201 117.333 141 48 119 139.8
-198 119 138.818 199 119.818 141 200 119.333 141
-197 122 140.143 198 122 140.8 200 121.25 141
-50 123 139.457 198 123 139.645 199 123 138.261
-200 123 138 197 124 139.543 200 124 138.8
-50 125 139.579 53 125 139.8 99 124.833 141
-103 125 140.824 196 125 138.667 198 125 139.625
-199 125 139.35 200 124.55 141 218 125 139
-100 126 140.143 193 126 138.1 196 126 139.6
-199 125.407 141 218 126 138.818 46 127 140.609
-45 127 141 100 127 139.853 102 127 140.545
-216 127 138.333 217 127 138.231 53 128 139.313
-192 128 139.5 216 128 138.321 54 129 139.645
-57 129 139.457 58 129 139.8 96 129 139.2
-189 129 138.6 131 130 138.103 188 130 138.517
-191 130 139.421 204 130 138.45 205 130 138.75
-206 130 138.2 221 130 139.8 222 129.474 141
-222 130 139.333 55 131 138.529 56 131 139.2
-130 131 140.182 132 131 138.6 188 131 139.636
-204 131 138.571 215 131 138.321 221 131 139.091
-220.125 131 141 222 131 139.2 60 132 139.457
-87 132 139.457 186 132 140.8 187 131.565 141
-188 131.909 141 188.071 132 141 190.5 132 141
-197.3 132 141 203 132 139.75 63 133 139.8
-88 133 138.882 185.923 133 141 201 132.75 141
-202 132.167 141 71 135 139.457 182 134.591 141
-112.87 136 141 115 135.955 141 178 136 140.531
-178.625 136 141 184 136 139.607 215 135.75 141
-52 137 139.75 55 136.462 141 173 137 138.455
-182.556 137 141 184 137 139.125 185 137 138.9
-190.286 137 141 194.667 137 141 199 136.25 141
-216 136.667 141 217 137 138.783 216.056 137 141
-129.308 138 141 183 138 139.781 184 138 139.031
-185 138 139.781 186 138 140.7 193.091 138 141
-207 137.727 141 173 139 139.091 174 139 138.094
-175 139 138.5 179 139 138.115 184 139 138.714
-184.889 139 141 192 138.091 141 193 139 139.889
-194 139 138.667 213 138.867 141 212.75 139 141
-105 139.87 141 109 140 139.765 110 140 140.25
-176 139.828 141 179 140 138.652 180 140 139.636
-191 140 140.118 192 140 139.455 194 140 138.857
-196 140 138.103 197 140 139.44 210 140 141
-103.63 141 141 106 141 139.846 108 141 140.735
-107.25 141 141 109 141 139.6 110.875 141 141
-169 140.818 141 171 141 139.645 173 140.261 141
-180 141 139.778 181 141 140 184.273 141 141
-193 141 139.455 194 141 139.147 195 141 139.412
-196 141 138.9 197 141 139.444 198 141 139.696
-199 141 140.438 106.4 142 141 170 142 140.8
-182 142 139.038 192 141.5 141 198 142 140.4
-199 142 139.385 157 144 138.316 181.87 144 141
-183 144 139 184 144 140.053 184.316 144 141
-201 144 138.9 207.857 144 141 170 145 139.5
-201 145 138.947 202 145 140.571 127.548 146 141
-161 146 138.5 168 145.222 141 201 146 139.875
-161 147 138.75 162 147 138.529 168 147 138.158
-167.053 147 141 211 147 140.667 210.818 147 141
-211 146.714 141 114 148 140.444 125 147.481 141
-212 148 140.76 211.833 148 141 212 147.5 141
-213 147.625 141 213 148 140.182 177.667 149 141
-213 149 139.846 214 149 139.385 220 149 139.364
-219 149 141 220 148.143 141 53 150 139.138
-64 150 140.71 164.933 150 141 214 149.875 141
-57.25 151 141 58 150 141 59 151 141
-62 151 140.118 63 151 140.118 64 151 140.471
-162.333 151 141 173 150.955 141 178 151 140.9
-179 153 138.375 180 153 138.75 180 154 138.75
-181 154 138.29 92 155 140.419 167 155 140.625
-169 155 139.8 170 155 139.8 207 155 140.211
-208 155 139.962 210 155 138.529 67 156 140.864
-68 155.565 141 69 155.222 141 71.5556 156 141
-99.0303 156 141 164.867 156 141 167 156 138.316
-168 156 139.147 169 156 139.2 170.773 156 141
-208 156 140.806 209 156 139.235 65 157 139.5
-90 157 138.783 92 157 139.355 168 157 138.794
-170 157 139.543 187 157 140.8 187 156.818 141
-188 157 139.645 191 156.192 141 191 157 138.9
-195 156.684 141 197 156.848 141 57 158 138.474
-58 158 139.105 59 158 139.05 66 158 140.9
-91 158 139.2 92 158 139.355 176 157.391 141
-187 158 140.625 188 158 139.111 191 158 138.194
-209 158 138.375 84 158.263 141 92 159 138.529
-189 159 139.125 190 159 139.25 200 159 138.857
-92 160 138.577 102 160 140.667 102.6 160 141
-166.63 160 141 188 159.13 141 199 160 140.1
-199 159.7 141 219 160 140.4 220 160 139.875
-76 161 138.529 77 161 139.8 78.5 161 141
-93 161 138.167 103 161 139.895 104 160.813 141
-104 161 138.75 106 161 138.391 181 160.333 141
-200 161 138.333 219 160.75 141 82.75 162 141
-89 162 139.2 90 162 138.231 90 161.077 141
-104 161.75 141 106 162 138.391 172 162 140.318
-193 161.909 141 193.083 162 141 195 162 139.125
-77.8125 163 141 85.8125 163 141 90 163 138.2
-91 163 139.304 185.375 163 141 194 163 140.063
-77.4167 164 141 79 163.909 141 91 163.813 141
-185.4 164 141 194 164 138.273 195 164 138.529
-77 165 138.938 78 165 140.077 178 164.778 141
-195 165 138.529 76 166 139.895 77 166 139.174
-172 166 140.739 184 165.52 141 195 166 138.529
-64 167 140.294 63 167 141 64 166 141
-76 167 139.565 75.45 167 141 77 167 140.55
-97 166.8 141 171 166.231 141 172 167 138.316
-173 167 138.677 200.125 167 141 76 168 140.125
-99 168 140.75 99 167.875 141 173 168 138.321
-174 168 138.968 196 168 138.29 63 169 138.818
-75 169 140.25 74.6316 169 141 100 169 139.304
-174 169 139.313 195 169 139.571 202 169 138.455
-203 169 139.853 205 169 140.667 75 170 140.667
-75.2 170 141 85.32 170 141 174 170 138.75
-175 170 138.29 203 170 140.167 201 170.783 141
-202 171 138.273 202.833 171 141 83 172 140.727
-83.125 172 141 82 173 138.778 83 173 140.318
-84 173 139.579 87 172.545 141 173 173 141
-174 173 139.286 81 174 138.29 82 174 138.265
-87 174 139.8 169 175 140.526 204.714 175 141
-205 174.895 141 168.545 176 141 170 176 139.421
-174 175.467 141 176 177 138.375 177 177 138.75
-202 177 139.125 202.172 177 141 170 177.4 141
-180 178 138.391 208.091 178 141 180 179 139
-51.5667 180 141 180 180 138.231 203.261 180 141
-172.286 181 141 182 181 138.545 183 182 139.636
-185 182 139.929 186 182 140.667 198 181.182 141
-171 183 140.5 175 182.517 141 182 183 138.75
-185 183 140.217 186 183 139.6 191 183 138.6
-167.143 184 141 182 184 139.5 183 183.429 141
-189 184 138.75 189.429 184 141 71 185 139.35
-71 184.267 141 90.5667 185 141 180 184.333 141
-86 185.684 141 86 186 139.714 87 185.933 141
-87 186 140.833 88 186 139.227 74 187 138.667
-75 186.455 141 83 187 138.136 86 187 139.333
-87 187 139.696 106 186.433 141 169 187 140.167
-169 186.688 141 178.625 187 141 192 187 139.125
-74 188 138.857 78 187.895 141 81 188 139.543
-83 188 138.091 84 188 138.103 86 188 140.727
-87 188 139.889 169 188 139.655 168.409 188 141
-170 187.182 141 170.75 188 141 193 187.033 141
-74 189 140.647 75 189 139.5 84 189 139.846
-172.467 189 141 73.9091 190 141 76 190 139.364
-82 190 139.543 83 190 139.543 84 190 140.419
-89 189.75 141 89 190 139.8 180 190 140.1
-180.75 190 141 182 189.889 141 80 191 139.2
-83 191 139.543 84 191 140.032 85 191 140.727
-89 191 139.235 179 190.091 141 182 190.182 141
-84 192 138.794 88 192 139 90 192 139.2
-89 193.13 141 68 68.8529 144 67.5455 69 144
-69 68.6571 144 70 68.4857 144 71 68.4857 144
-72 68.4857 144 73 68.4857 144 74 68.3529 144
-75 68.3429 144 76 68.3529 144 77 68.5862 144
-78 68.7391 144 79 68.9444 144 79.1667 69 144
-83 69 144 91 69 144 92 69 144
-93 69 144 94 69 144 65 69.8235 144
-64.5 70 144 66 69.3529 144 67 69.2143 144
-80 69.1515 144 81 69.1818 144 82 69.1818 144
-84 69.2609 144 85 69.9444 144 85.0833 70 144
-89.2273 70 144 90 69.2609 144 95 69.2727 144
-96 70 144 63 70.8235 144 62.7391 71 144
-64 70.2069 144 86 70.4783 144 87 70.7857 144
-88 70.7391 144 89 70.2941 144 97 70.6 144
-98 71 141.882 97.25 71 144 99 71 143.7
-62 71.7727 144 61.7727 72 144 98 72 141.316
-97 72 144 99 72 141.882 100 71.9167 144
-99.9231 72 144 101 71.7391 144 101.353 72 144
-60 72.8235 144 59.5 73 144 61 72.5 144
-97.3158 73 144 99 73 141.545 99.6207 73 144
-102 72.3793 144 102.529 73 144 57.5 74 144
-58 73.8235 144 59 73.1765 144 73 74 141.783
-87 74 141.316 94.6471 74 144 95 73.6667 144
-95.5 74 144 98 73.7222 144 99 74 142.364
-98.4545 74 144 99.2609 74 144 103 73.7273 144
-103.182 74 144 56 75 144 57 74.2609 144
-67.3333 75 144 68 74.75 144 69 74.5455 144
-70 74.3182 144 71 74.2857 144 72 74.2857 144
-73 74.7727 144 73.4167 75 144 94.0833 75 144
-95.6471 75 144 99 74.4615 144 103.364 75 144
-204 74.3929 144 203.393 75 144 205 74.1765 144
-206 74.7857 144 206.261 75 144 54 76 144
-55 75.4074 144 63.0909 76 144 64 75.6429 144
-65 75.4444 144 66 75.3182 144 67 75.1176 144
-74 75.25 144 75 75.697 144 76 75.8485 144
-76.4545 76 144 80 76 141.818 94 76 141.25
-95 75.4074 144 103.364 76 144 203.324 76 144
-207 75.5 144 207.739 76 144 50.7059 77 144
-51 76.8529 144 52 77 144 53.0833 77 144
-61 77 143.833 61.2 77 144 62 76.75 144
-63 76.0588 144 77 76.1765 144 78 76.2222 144
-79 76.5238 144 79.9091 77 144 103.036 77 144
-203.647 77 144 208 76.2069 144 209 76.8148 144
-209.227 77 144 49 78 144 50 77.4286 144
-53 77.0909 144 60.0909 78 144 61 77.0909 144
-80 77.0455 144 81 77.375 144 82 77.75 144
-82.3636 78 144 84 78 142.364 102.429 78 144
-103 77.0588 144 204 77.5217 144 204.324 78 144
-210 77.6071 144 210.688 78 144 48 78.8214 144
-47.8148 79 144 58.0909 79 144 59 78.5455 144
-60 78.0455 144 83 78.3182 144 84 78.4444 144
-85 78.4444 144 86 78.5455 144 86.9091 79 144
-89 79 141.75 101.389 79 144 102 78.5217 144
-204.647 79 144 211 78.1515 144 212 78.5 144
-212.739 79 144 47.4783 80 144 55 80 144
-56 79.7059 144 57 79.75 144 58 79.0588 144
-87 79.0455 144 88 79.4444 144 89 79.5455 144
-90 79.6429 144 91 79.8182 144 91.6667 80 144
-100.059 80 144 101 79.3043 144 205 79.7059 144
-205.147 80 144 213 79.1765 144 214 79.697 144
-214.455 80 144 46 81 144 47 80.5 144
-53 81 141.75 54.5833 81 144 92 80.1176 144
-93 80.1176 144 94 80.4118 144 95 80.75 144
-96 80.75 144 97 80.6 144 98 80.375 144
-99 80.4118 144 100 80.0455 144 205.5 81 144
-215 80.3529 144 216 80.697 144 216.455 81 144
-45 81.6071 144 44.6667 82 144 52 82 143.833
-52.0909 82 144 53 81.6429 144 54 81.3182 144
-205.971 82 144 217 81.5217 144 217.478 82 144
-44 83 144 51.0588 83 144 52 82.0588 144
-206 82.0435 144 206.647 83 144 218 82.9231 144
-218.056 83 144 43.3529 84 144 49.7059 84 144
-50 83.7826 144 51 83.0455 144 207 83.6667 144
-207.176 84 144 218 84 142 219 83.7391 144
-219.273 84 144 43 84.6667 144 42.7857 85 144
-48.6207 85 144 49 84.5217 144 207.647 85 144
-220 84.5926 144 220.478 85 144 42 86 144
-48.0357 86 144 207.824 86 144 221 85.6667 144
-221.176 86 144 41.2143 87 144 47.5294 87 144
-48 86.0588 144 207.971 87 144 221.824 87 144
-41 87.2727 144 40.5152 88 144 47.0357 88 144
-208 87.1667 144 208.179 88 144 222 87.5 144
-222.176 88 144 40 89 144 46.697 89 144
-47 88.0909 144 208.353 89 144 222.667 89 144
-39.5152 90 144 46.3636 90 144 208 90 144
-218 90 143.824 217.909 90 144 218 89.9412 144
-218.036 90 144 223 89.6471 144 223.261 90 144
-39 91 144 46.0357 91 144 207.586 91 144
-218 91 143.833 217.909 91 144 218.045 91 144
-223.793 91 144 38.5152 92 144 45.697 92 144
-46 91.0909 144 207.486 92 144 218 91.0625 144
-224 91.5 144 224.176 92 144 38.1765 93 144
-45.5455 93 144 207.343 93 144 224.485 93 144
-38 93.5 144 37.8235 94 144 45.3636 94 144
-207.176 94 144 224.824 94 144 37.5152 95 144
-45.0357 95 144 207 95 144 225 94.5 144
-225.176 95 144 37.1765 96 144 44.8529 96 144
-45 95.1667 144 206.824 96 144 225.485 96 144
-37 96.5 144 36.8235 97 144 44.6765 97 144
-206.515 97 144 225.824 97 144 36.6571 98 144
-44.6765 98 144 206.176 98 144 226 97.5 144
-226.176 98 144 36.3429 99 144 44.5143 99 144
-206 99 144 211.793 99 144 212 98.4545 144
-213 98.4 144 213.462 99 144 226.485 99 144
-36.1765 100 144 44.5 100 144 205.824 100 144
-211.75 100 144 213.333 100 144 226.824 100 144
-36 100.5 144 35.8235 101 144 44.3529 101 144
-205.821 101 144 211.522 101 144 213 101 144
-227 100.353 144 227.324 101 144 35.5152 102 144
-44.3636 102 144 205.393 102 144 210.667 102 144
-211 101.522 144 213.179 102 144 227.647 102 144
-35.1765 103 144 43 103 141.682 44 103 142.364
-44.3636 103 144 205.214 103 144 210.353 103 144
-213.185 103 144 228 103 144 35 103.5 144
-34.8235 104 144 44.5455 104 144 205 103.353 144
-204.676 104 144 210 104 141.462 210.379 104 144
-212.706 104 144 213 103.5 144 228 104 144
-34.5152 105 144 44.697 105 144 204.353 105 144
-210.478 105 144 212.538 105 144 228.324 105 144
-34.1765 106 144 44.8529 106 144 204 106 144
-209.944 106 144 210 105.917 144 213 105.5 144
-213.261 106 144 221 106 143.7 220 106 144
-221 105 144 221.091 106 144 228.647 106 144
-34 106.545 144 33.8529 107 144 45 106.833 144
-45.0294 107 144 203.676 107 144 209 107 144
-212 107 141.545 213 107 142.2 213.522 107 144
-219 107 143 218.739 107 144 219 106.647 144
-220 107 143 220.333 107 144 221 106.077 144
-229 107 144 33.5152 108 144 45.0294 108 144
-203.353 108 144 208.708 108 144 212 108 144
-213 107.667 144 219 108 142.2 218.333 108 144
-220 108 143.118 220.179 108 144 229.324 108 144
-33.1818 109 144 45.1818 109 144 203 108.706 144
-202.853 109 144 209 109 142.8 208.5 109 144
-210 108.923 144 209.857 109 144 211 108.179 144
-218 109 142.95 217.759 109 144 218 108.462 144
-219 109 142.2 219.667 109 144 220 108.455 144
-229.647 109 144 33 110 144 45.5294 110 144
-202.697 110 144 209 110 143.824 208 110 144
-209.053 110 144 218 110 143.824 217.941 110 144
-218.167 110 144 219 109.706 144 230 110 144
-32.8235 111 144 45.8529 111 144 202.429 111 144
-209 110.2 144 218 110.2 144 230 111 144
-32.6571 112 144 46 111.455 144 46.1818 112 144
-202.045 112 144 230.176 112 144 32.4857 113 144
-46.5294 113 144 202 112.059 144 201.429 113 144
-230.485 113 144 32.4857 114 144 47 113.941 144
-47.0357 114 144 201.045 114 144 208 114 143.842
-207.8 114 144 208 113.8 144 209 113.8 144
-209 114 143.842 210 113.417 144 210 114 142.95
-211 113.588 144 211 114 142.95 211.583 114 144
-230.824 114 144 32.4857 115 144 47.5294 115 144
-202 115 144 203.417 115 144 204 114.696 144
-205 114.588 144 205 115 142.25 206 114.417 144
-207 114.8 144 207 115 143.727 207.2 115 144
-208 114.2 144 209 114.091 144 210 114.412 144
-211 114.304 144 231 115 144 32.4857 116 144
-48 115.941 144 48.0357 116 144 201 115.6 144
-200.636 116 144 201.8 116 144 203 116 142
-202.2 116 144 203.8 116 144 204.2 116 144
-205 115.636 144 205.8 116 144 206.2 116 144
-207 115.2 144 231 116 144 32.4857 117 144
-48.5294 117 144 200.083 117 144 202 116.077 144
-204 116.043 144 206 116.063 144 231 117 144
-32.4857 118 144 49 117.727 144 49.2143 118 144
-200 117.2 144 199.818 118 144 231 118 144
-32.4857 119 144 49.8214 119 144 199.583 119 144
-231 119 144 32.4857 120 144 50 119.217 144
-50.6207 120 144 99 119.833 144 98.6667 120 144
-100 119.833 144 101 120 143.684 101 119.882 144
-101.167 120 144 199 119.636 144 198.818 120 144
-230.824 120 144 32.4857 121 144 51 120.478 144
-51.5217 121 144 97 121 143.684 97 120.833 144
-96.8333 121 144 98 121 143.684 98 120.667 144
-101.167 121 144 198 121 141.3 199 120.8 144
-199.083 121 144 230.657 121 144 32.4857 122 144
-44 122 141.938 43 122 144 44 121.353 144
-45 121.773 144 45.1786 122 144 52 121.478 144
-52.5217 122 144 97 122 143.684 96.6667 122 144
-100 122 143.684 101 122 143.684 101.333 122 144
-199.647 122 144 230.514 122 144 32.4857 123 144
-43.9565 123 144 45 123 142.263 45.5 123 144
-53 122.478 144 53.5217 123 144 96 122.667 144
-95.6667 123 144 98 123 143.684 100 123 143.684
-101 123 143 102 122.8 144 102.083 123 144
-200 122.5 144 200.353 123 144 230.343 123 144
-32.4857 124 144 44 123.056 144 45 124 143.824
-44.9444 124 144 45.2 124 144 54 123.478 144
-54.7059 124 144 95 124 143.684 95 123.667 144
-94.6667 124 144 96 124 143.684 97 124 143.684
-101 124 141.346 102 124 141.24 103 123.393 144
-103 124 141.783 104 123.966 144 104.059 124 144
-200.273 124 144 230.176 124 144 32.4857 125 144
-45 125 144 46 124.4 144 46.5455 125 144
-55 124.217 144 56 124.955 144 56.0588 125 144
-95 125 143.684 94.6667 125 144 96 125 143.684
-97 125 143 102 125 141.24 104 125 141.75
-105 124.727 144 105.222 125 144 200 124.353 144
-199.607 125 144 230 125 144 32.3429 126 144
-44.5 126 144 46 126 142.286 47 125.417 144
-47.6364 126 144 57 125.941 144 57.0588 126 144
-92 125.833 144 91.6667 126 144 93 125.667 144
-94 125.364 144 102 126 141.75 103 126 141.346
-105 126 141.75 105.643 126 144 197.455 126 144
-198 125.824 144 199 125.5 144 230 126 144
-32.3235 127 144 44.0556 127 144 48 126.8 144
-48.2 127 144 58 126.696 144 58.3889 127 144
-89 127 143.684 89 126.882 144 88.6667 127 144
-90 126.833 144 91 126.667 144 105.821 127 144
-195 126.824 144 194.647 127 144 196 126.485 144
-197 126.152 144 230 127 144 32.3429 128 144
-45 127.773 144 45.8333 128 144 46.1667 128 144
-47 127.706 144 48 127.059 144 59 127.478 144
-59.7059 128 144 88 128 143.684 88 127.667 144
-87.6667 128 144 89 128 143.684 90 128 143
-106 128 144 193.571 128 144 194 127.478 144
-230 128 144 32.4857 129 144 46 128.034 144
-60 129 141.75 60 128.217 144 61 128.955 144
-61.0909 129 144 85 129 143.684 85 128.882 144
-84.6667 129 144 86 128.833 144 87 128.667 144
-89 129 142.364 106.147 129 144 192 129 141.13
-193.227 129 144 230.147 129 144 32.4857 130 144
-62 129.588 144 62.6364 130 144 84 129.667 144
-83.6667 130 144 85 130 143 106.571 130 144
-192 130 142.286 193 130 143.053 193.545 130 144
-220.706 130 144 221 129.815 144 222 129.625 144
-222.353 130 144 230.303 130 144 32.4857 131 144
-63 130.25 144 64 130.588 144 65 130.882 144
-65.3333 131 144 81 130.882 144 80.6667 131 144
-82 130.833 144 83 130.364 144 106.727 131 144
-192 131 143.833 193 131 143.833 194 130.833 144
-194 131 143.824 195 130.917 144 195 131 143.833
-195.091 131 144 197.417 131 144 198 130.759 144
-199 130.708 144 199.412 131 144 220 131 141.25
-219 131 144 220 130.522 144 222 130.545 144
-221.545 131 144 230.303 131 144 32.4857 132 144
-66 131.25 144 67 131.588 144 67.6364 132 144
-75 131.882 144 74.6667 132 144 76 131.882 144
-77 131.882 144 78 131.682 144 79 131.588 144
-80 131.25 144 107 131.375 144 107.357 132 144
-129.167 132 144 130 131.821 144 131 132 142
-130.294 132 144 187 132 144 188 131.739 144
-188.545 132 144 193 132 143.842 194.2 132 144
-195 131.2 144 196.667 132 144 197 131.5 144
-200 131.476 144 200.393 132 144 218 132 142.263
-217.607 132 144 218 131.607 144 219 132 141
-220 132 141.176 221 131.5 144 220.727 132 144
-230.303 132 144 32.6571 133 144 68 132.182 144
-69 132.357 144 70 132.455 144 71 132.455 144
-72 133 141.75 72 132.455 144 73 132.357 144
-74 132.182 144 107.739 133 144 127 133 144
-128 132.5 144 129 132.034 144 130.778 133 144
-186 132.706 144 185.815 133 144 188.739 133 144
-192.2 133 144 193 132.2 144 194 132.091 144
-197 132.455 144 197.214 133 144 201 133 142
-200.739 133 144 202 133 142.364 203 133 141.24
-217 133 142.2 216.586 133 144 217 132.586 144
-218 133 141.571 219 133 143.118 219.294 133 144
-220 132.571 144 230.485 133 144 32.8235 134 144
-108 133.261 144 108.586 134 144 126 133.667 144
-125.353 134 144 130.824 134 144 185.593 134 144
-188 134 142 188.414 134 144 192.059 134 144
-197.176 134 144 201 133.375 144 201.588 134 144
-202 134 142.5 216 134 143.786 215.964 134 144
-216 133.944 144 217 134 141.652 218 134 143
-218.261 134 144 219 133.227 144 230.818 134 144
-33 135 144 108.957 135 144 123 135 144
-124 134.657 144 125 134.176 144 130.657 135 144
-180 135 142 181 135 142.364 186 134.733 144
-186.8 135 144 187.083 135 144 188 134.522 144
-192 135 144 196.667 135 144 197 134.353 144
-201.455 135 144 216 135 141.667 215.588 135 144
-217 135 142.25 217.304 135 144 218 134.273 144
-230.824 135 144 33 136 144 109 135.083 144
-110 135.353 144 111 135.227 144 112 135.478 144
-112.364 136 144 115.294 136 144 116 135.571 144
-117 135.667 144 118 135.971 144 119 135.824 144
-120 135.966 144 121 135.793 144 122 135.586 144
-129.875 136 144 130 135.852 144 180 136 143.727
-181 136 143.8 182 136 143.842 187 135.034 144
-191.455 136 144 195.815 136 144 196 135.815 144
-200.773 136 144 201 135.667 144 216 135.412 144
-217 135.25 144 230.657 136 144 33 137 144
-53 137 141.429 54.0833 137 144 55 136.621 144
-56 136.514 144 57 136.233 144 58 136.393 144
-59 136.739 144 59.375 137 144 113 136.656 144
-114 136.815 144 115 136.227 144 129.185 137 144
-181 137 143.8 182 137 142.765 190 136.733 144
-189.75 137 144 191 136.5 144 194.545 137 144
-195 136.815 144 200 137 143.167 200.227 137 144
-212 137 143.1 213 137 143.211 213.833 137 144
-214 136.917 144 214.091 137 144 215 137 142.421
-216 137 141.176 230.514 137 144 33 138 144
-54.0588 138 144 59 138 141.652 60 137.909 144
-60.0909 138 144 128.821 138 144 129 137.5 144
-180.636 138 144 181 137.2 144 181.364 138 144
-189 138 143.571 190 138 143.571 190 137.8 144
-191 138 141.75 191 137.455 144 192 137.353 144
-193 137.273 144 194 137.214 144 199 137.545 144
-198.545 138 144 200 137.185 144 205.5 138 144
-206 137.824 144 207 137.233 144 208 137.261 144
-209 137.412 144 209.833 138 144 210 138 143.684
-211 138 143.684 211.286 138 144 212 137.545 144
-212.5 138 144 213 138 143.167 214 137.083 144
-214 138 141.938 230.343 138 144 33 139 144
-55 138.727 144 55.5455 139 144 58.5455 139 144
-59 138.783 144 60 138.059 144 129 138.5 144
-129.179 139 144 180.688 139 144 181.833 139 144
-185 138.783 144 184.545 139 144 186 138.621 144
-187 138.5 144 188 138.214 144 189 138.091 144
-190 139 142.286 189.455 139 144 198.059 139 144
-203.739 139 144 204 138.824 144 205 138.176 144
-209.588 139 144 211 139 142.364 212 138.217 144
-212 139 141.75 230.176 139 144 33.3529 140 144
-56 139.152 144 57 139.176 144 58 139.176 144
-73 140 143.813 72.8571 140 144 73 139.941 144
-73.0833 140 144 104 140 144 105 139.227 144
-106 139.571 144 107 139.786 144 108 139.5 144
-109 139.214 144 110 139.353 144 110.478 140 144
-129.647 140 144 161 140 141.24 168 140 142.385
-177 140 144 181 139.313 144 181 140 141.938
-184 139.353 144 183.353 140 144 189.552 140 144
-198.706 140 144 202.393 140 144 203 139.5 144
-209.25 140 144 230 140 144 33.6765 141 144
-73 140.167 144 103.676 141 144 107 141 141.12
-110.739 141 144 129.818 141 144 165 141 143
-173 140.515 144 172.407 141 144 174 140.353 144
-175 140.353 144 176 140.176 144 178 140.313 144
-178.667 141 144 183.217 141 144 190 140.722 144
-190.833 141 144 199 140.294 144 200 141 144
-201 141 144 202 140.333 144 209 140.667 144
-208.882 141 144 230 141 144 34 142 144
-104 141.688 144 104.227 142 144 107 142 142.8
-108 142 144 109.545 142 144 110 141.773 144
-130 142 144 160.818 142 144 161 141.75 144
-162 141.059 144 163 141.304 144 164 141.412 144
-165 141.412 144 166 141.2 144 167 141.091 144
-168 141.091 144 168.909 142 144 171.75 142 144
-172 141.647 144 179 141.5 144 179.393 142 144
-183.964 142 144 191 141.036 144 192 141.773 144
-192.417 142 144 208.455 142 144 230 142 144
-34 143 144 105 142.607 144 106 142.353 144
-107 142.182 144 109 142.176 144 129.571 143 144
-160.304 143 144 169 142.091 144 169.625 143 144
-171.059 143 144 180 142.607 144 180.333 143 144
-184 142.077 144 184.522 143 144 193 142.412 144
-193.625 143 144 195 143 141.3 198 143 144
-208.179 143 144 230 143 144 34 144 144
-128.941 144 144 129 143.941 144 159.818 144 144
-160 143.636 144 170 143.353 144 171 143.091 144
-181 143.815 144 181.179 144 144 184.607 144 144
-194 143.222 144 195 143.643 144 196 143.515 144
-197 143.152 144 199 143.75 144 199.182 144 144
-204 143.848 144 203.545 144 144 205 143.852 144
-205.364 144 144 208 143.455 144 207.5 144 144
-229.824 144 144 34 145 144 127.727 145 144
-128 144.727 144 159 145 143 159.636 145 144
-166 145 144 167 144.727 144 168 144.571 144
-169 144.778 144 170 144.688 144 171 144.625 144
-172 144.588 144 172.304 145 144 182 145 144
-183.75 145 144 184 144.81 144 199.696 145 144
-202 145 144 203 144.261 144 206 144.292 144
-207 144.261 144 229.485 145 144 34 146 144
-64 146 143.824 63.5 146 144 64 145.833 144
-64.1429 146 144 127.5 146 144 160 145.8 144
-160 146 143.727 160.059 146 144 167 146 144
-173 146 144 183 145.5 144 200 145.636 144
-200.8 146 144 201.056 146 144 229.176 146 144
-34.3529 147 144 64 146.2 144 126.375 147 144
-127 146.63 144 158.091 147 144 159 146.091 144
-160 146.091 144 167.222 147 144 173.571 147 144
-201 146.059 144 211 147 141.857 229 147 144
-34.6765 148 144 63.8571 148 144 64 147.8 144
-64.1667 148 144 110 148 144 111 147.824 144
-112 147.848 144 112.455 148 144 124 148 144
-125 147.207 144 126 147.176 144 157.304 148 144
-158 147.059 144 168 147.778 144 168.214 148 144
-174 147.706 144 174.217 148 144 212 147.833 144
-211.909 148 144 213 147.333 144 214 147.657 144
-215 148 144 229 148 144 35 149 144
-64 149 141.682 63 149 144 65 148.455 144
-65.2609 149 144 108.227 149 144 109 148.5 144
-113 148.353 144 113.393 149 144 123.676 149 144
-156.5 149 144 157 148.389 144 169 149 144
-175 149 143 174.588 149 144 211.955 149 144
-216 149 144 220 149 144 228.824 149 144
-35.1765 150 144 59.1667 150 144 60 149.821 144
-61 149.667 144 62 149.5 144 65.7222 150 144
-108 150 141.652 107.357 150 144 108 149.217 144
-113 150 144 123.214 150 144 155.607 150 144
-156 149.5 144 163 150 144 164 149.414 144
-165 149.955 144 165.056 150 144 170 149.848 144
-170.185 150 144 175 150 143.625 174.667 150 144
-177 150 143.684 178 150 141.429 212 149.059 144
-212.941 150 144 215 150 144 228.485 150 144
-35.3429 151 144 58 151 141.6 59.0455 151 144
-66 150.833 144 66.0909 151 144 106.955 151 144
-107 150.909 144 112 150.667 144 111.353 151 144
-122.185 151 144 123 150.214 144 155 151 144
-162.214 151 144 165.214 151 144 171 151 144
-173.714 151 144 174 150.667 144 177 151 141.429
-213 150.036 144 214 150.364 144 228.176 151 144
-35.6571 152 144 60 152 144 62 152 141.682
-66 152 143.842 67 151.909 144 67 152 143.833
-67.2 152 144 94.2174 152 144 95 151.182 144
-96 151.217 144 97 151.696 144 98 151.941 144
-98 152 143.842 99 151.941 144 99 152 143.842
-99.2 152 144 107 151.091 144 108 151.706 144
-109 151.773 144 110 151.586 144 111 151.176 144
-121.571 152 144 122 151.294 144 154.657 152 144
-162.786 152 144 165 152 144 172 151.294 144
-173 151.294 144 187 152 143.769 186.909 152 144
-187 151.833 144 187.083 152 144 227.824 152 144
-228 151.5 144 36 153 144 61 152.343 144
-62 152.486 144 63 152.486 144 64 152.414 144
-65 152.304 144 66 152.059 144 67 152.2 144
-68 153 143.667 67.6667 153 144 68 152.667 144
-68.1667 153 144 73 153 143.769 72.9655 153 144
-73 152.857 144 74 152.417 144 74 153 142.6
-74.3043 153 144 93.1852 153 144 94 152.185 144
-99 153 143.842 99.2 153 144 121.179 153 144
-154.343 153 144 163 152.261 144 164 152.773 144
-168.625 153 144 169 152.778 144 170 152.571 144
-170 153 142.286 170.706 153 144 187 152.056 144
-227.485 153 144 36.3429 154 144 68 153.167 144
-73 154 143.833 72.9412 154 144 74 154 143.824
-74.0435 154 144 92 154 144 93 153.185 144
-99.4118 154 144 121.485 154 144 154.176 154 144
-164 154 143.824 163.944 154 144 164 153.833 144
-165 153.588 144 165 154 142.95 166 153.964 144
-167 153.786 144 168 153.357 144 171 153.417 144
-171.368 154 144 227.176 154 144 36.6571 155 144
-68.4545 155 144 69 154.625 144 70 154.778 144
-71 155 144 72 155 143.833 72 154.941 144
-72.2 155 144 73 154.2 144 74 154.059 144
-89.2 155 144 90 154.879 144 91 154.667 144
-99.25 155 144 121.029 155 144 154 154.5 144
-153.824 155 144 164 154.2 144 164.8 155 144
-166 155 141.429 171.586 155 144 203 155 141.571
-202 155 144 203 154.5 144 204 154.586 144
-204.923 155 144 226.647 155 144 227 154.333 144
-37 156 144 67.4783 156 144 68 155.294 144
-72.5652 156 144 87.5217 156 144 88 155.522 144
-89 155.043 144 99 156 144 120.824 156 144
-121 155.143 144 153.515 156 144 165 156 144
-171.486 156 144 185.955 156 144 186 155.938 144
-187 155.478 144 188 155.393 144 189 155 144
-190 155 144 191 155.393 144 191.773 156 144
-198.759 156 144 199 155.696 144 200 155.179 144
-201 155.176 144 205 155.091 144 206 156 143.625
-205.833 156 144 226.324 156 144 37.5152 157 144
-66.8214 157 144 67 156.688 144 72.1765 157 144
-86 157 144 87 156.522 144 98.3529 157 144
-120.514 157 144 153 157 144 165.485 157 144
-171.486 157 144 186 157 142.364 185.571 157 144
-192 156.185 144 193 156.545 144 193.833 157 144
-195 157 144 197.667 157 144 198 156.786 144
-205 156.909 144 204.917 157 144 225.824 157 144
-226 156.647 144 37.8235 158 144 67 157.294 144
-68 158 144 71.2143 158 144 72 157.214 144
-83.9412 158 144 84 157.957 144 85 157.727 144
-98 157.522 144 97.6071 158 144 120.176 158 144
-152.515 158 144 165.5 158 144 171.657 158 144
-174.5 158 144 175 157.333 144 176 157.414 144
-177 157.786 144 177.6 158 144 185.818 158 144
-194 157.091 144 196 157.353 144 197 157.414 144
-203.455 158 144 204 157.647 144 225.485 158 144
-38 158.5 144 38.1765 159 144 69 158.5 144
-70 158.657 144 71 158.207 144 83 159 144
-97.1818 159 144 101.917 159 144 102 158.955 144
-102.091 159 144 119.824 159 144 120 158.5 144
-152.176 159 144 165.853 159 144 171.5 159 144
-174.5 159 144 178 158.235 144 178.722 159 144
-186 158.273 144 186.696 159 144 200.091 159 144
-201 158.697 144 202 158.364 144 203 158.185 144
-225 159 144 38.5152 160 144 82 160 143
-82.6364 160 144 97 159.8 144 96.9412 160 144
-100.294 160 144 101 159.478 144 103 159.476 144
-103.478 160 144 119.514 160 144 152 159.353 144
-151.676 160 144 166 159.556 144 166.19 160 144
-171.393 160 144 174.966 160 144 179 159.238 144
-179.727 160 144 187 159.241 144 188 159.829 144
-188.5 160 144 195 159.588 144 194.364 160 144
-196 159.786 144 197 159.676 144 198 159.657 144
-199 159.353 144 200 159.034 144 217.647 160 144
-218 159.739 144 219 159 144 220 159.588 144
-220.304 160 144 224.485 160 144 39 161 144
-79 161 141.75 80 161 143 81 161 143.684
-83 160.667 144 83 161 143.684 84 160.667 144
-84.3333 161 144 90 161 144 91 160.824 144
-91.375 161 144 96.9545 161 144 99.5882 161 144
-100 160.417 144 101 161 141.12 104 161 144
-119.514 161 144 151.353 161 144 167 160.944 144
-167.059 161 144 171 160.917 144 170.941 161 144
-175 160.059 144 175.571 161 144 180 160.353 144
-180.917 161 144 181.2 161 144 182 160.81 144
-182.444 161 144 189 160.207 144 190 160.176 144
-191 160.607 144 192 161 144 195 161 142
-194.25 161 144 217 161 143.824 216.909 161 144
-217 160.917 144 218 161 142.714 219 161 141.25
-220 161 144 224 161 144 39.5152 162 144
-79 162 143 80 162 143 81 162 142.364
-85 161.25 144 86 161.941 144 86.0909 162 144
-89 161.586 144 88.2941 162 144 92 161.455 144
-92.3529 162 144 96.7778 162 144 100 161.304 144
-101 161.828 144 102 162 144 103 162 144
-119.514 162 144 151 161.522 144 150.676 162 144
-168 161.727 144 168.6 162 144 171 162 143.684
-170.667 162 144 176 162 144 181 161.045 144
-183 161.313 144 183.917 162 144 193 162 144
-194 162 143.75 194 161.8 144 216 162 143
-215.588 162 144 216 161.588 144 217 162 143.053
-218 162 144 219 161.478 144 223.485 162 144
-39.8235 163 144 78 163 141.6 79 163 142.765
-87 162.588 144 88 162.179 144 92.0345 163 144
-96.9643 163 144 119.514 163 144 150.353 163 144
-168.375 163 144 171 162.286 144 171.217 163 144
-176.485 163 144 184 162.059 144 184.727 163 144
-216 162.412 144 217 162.273 144 223 163 144
-40 163.5 144 40.1765 164 144 77.1667 164 144
-78 163.706 144 78.4545 164 144 91.1852 164 144
-92 163.043 144 97 163.045 144 97.6364 164 144
-119.514 164 144 150 163.667 144 149.824 164 144
-168.043 164 144 171.414 164 144 176.966 164 144
-185 163.5 144 185.375 164 144 222.393 164 144
-40.5152 165 144 64.6471 165 144 65 164.818 144
-66 164.75 144 67 164.909 144 67 165 143.833
-67.0588 165 144 76 165 144 77 164.043 144
-78.3929 165 144 90 165 144 91 164.185 144
-98 164.522 144 98.4783 165 144 119.514 165 144
-149.793 165 144 160 165 143.824 159.917 165 144
-160 164.917 144 161 164.941 144 161 165 143.833
-161.091 165 144 167.515 165 144 168 164.059 144
-171.4 165 144 177 164.059 144 177.727 165 144
-181 164.966 144 180.917 165 144 182 164.966 144
-182.083 165 144 185.478 165 144 199 165 143.842
-198.8 165 144 199 164.8 144 199.091 165 144
-210.966 165 144 211 164.941 144 212 164.909 144
-212 165 143.4 212.077 165 144 221.5 165 144
-222 164.5 144 41 166 144 63.4138 166 144
-64 165.393 144 65 166 141 66.5455 166 144
-67 165.091 144 75.5 166 144 78.1515 166 144
-89.1923 166 144 99 166 141.857 98.7059 166 144
-119.514 166 144 149.739 166 144 160 165.059 144
-161 165.091 144 166.522 166 144 167 165.607 144
-171 165.706 144 170.848 166 144 178 165.214 144
-179 165.176 144 180 165.324 144 183 165.333 144
-183.957 166 144 184.167 166 144 185 165.688 144
-199 166 143.833 198.941 166 144 200 165.588 144
-200 166 142.95 201 166 144 211 166 141.5
-210.773 166 144 212 166 144 221.179 166 144
-41.5152 167 144 63.0556 167 144 65 167 142.263
-65.6875 167 144 66 166.706 144 75.0345 167 144
-78 166.227 144 77.5 167 144 88 167 144
-89 166.227 144 96 166.667 144 95.5 167 144
-97 166.586 144 98 167 143.571 98 166.923 144
-99 167 142.615 119.514 167 144 149.739 167 144
-165.593 167 144 166 166.522 144 170.152 167 144
-184 166.056 144 199 166.167 144 199.217 167 144
-202 166.343 144 203 166.676 144 203.647 167 144
-211 166.455 144 220.824 167 144 221 166.455 144
-42 168 144 63 168 142 64 167.739 144
-65 167.324 144 74.5 168 144 75 167.056 144
-77 167.944 144 76.9655 168 144 87.2143 168 144
-91 168 143.571 91 167.957 144 90.9412 168 144
-92 167.818 144 93 167.966 144 93.1667 168 144
-94.2941 168 144 95 167.478 144 119.353 168 144
-149.786 168 144 165.034 168 144 170 167.455 144
-169.824 168 144 199.5 168 144 204 167.261 144
-205 167.621 144 206 167.739 144 207 167.455 144
-207 168 142.8 207.353 168 144 220.485 168 144
-42.6667 169 144 73.8485 169 144 74 168.773 144
-76.6471 169 144 86.7391 169 144 87 168.5 144
-90 168.727 144 89.7273 169 144 94 168.185 144
-119.029 169 144 149.971 169 144 164.545 169 144
-165 168.091 144 170 169 144 200 168.944 144
-200.029 169 144 204 169 141.125 206.944 169 144
-207 168.857 144 220 169 144 43 169.647 144
-43.1765 170 144 74 170 142.263 73.6071 170 144
-76.2333 170 144 85.8519 170 144 86 169.81 144
-89 169.941 144 88.9412 170 144 118.5 170 144
-119 169.056 144 150 169.083 144 150.324 170 144
-165 170 141.5 164.583 170 144 170.773 170 144
-200.414 170 144 205 170 141.682 206.333 170 144
-219.333 170 144 43.8235 171 144 74 171 143.118
-73.7059 171 144 75 171 143.167 75.2381 171 144
-76 170.304 144 85 171 142.105 85.75 171 144
-87 171 144 88 170.727 144 118.176 171 144
-150.647 171 144 165 170.417 144 166 170.478 144
-167 171 144 170 171 141.167 171 170.455 144
-171 171 143 171.273 171 144 201 171 144
-203 170.688 144 202.688 171 144 204 170.304 144
-205 170.515 144 206 170.353 144 218.647 171 144
-219 170.478 144 44 171.261 144 44.5 172 144
-74 171.294 144 75 171.185 144 84 172 141.875
-85 172 141.75 86 171.25 144 86 172 142.364
-117.853 172 144 118 171.545 144 150.824 172 144
-168 171.607 144 168.478 172 144 171 172 144
-202 171.647 144 218 172 144 45 172.586 144
-45.3529 173 144 117.5 173 144 151 172.353 144
-151.324 173 144 169 173 143.833 168.917 173 144
-169.167 173 144 170 172.545 144 217.333 173 144
-46 174 144 117.029 174 144 151.647 174 144
-168.294 174 144 170 173.833 144 170.056 174 144
-173 174 141.9 216.5 174 144 217 173.393 144
-46.6667 175 144 116.5 175 144 117 174.056 144
-152 174.522 144 152.324 175 144 168.261 175 144
-170.739 175 144 174 175 142.5 203.5 175 144
-204 174.955 144 205 174.815 144 205.179 175 144
-215.5 175 144 216 174.5 144 47 175.393 144
-47.5 176 144 115.848 176 144 116 175.773 144
-152.647 176 144 168.529 176 144 171 175.5 144
-171.261 176 144 202.81 176 144 203 175.2 144
-205.957 176 144 214.393 176 144 215 175.5 144
-48 176.5 144 48.5 177 144 115.176 177 144
-153 176.522 144 153.324 177 144 169 176.593 144
-169.393 177 144 171.333 177 144 202.643 177 144
-206 176.045 144 206.778 177 144 213.393 177 144
-214 176.393 144 49 177.5 144 49.5 178 144
-114.5 178 144 115 177.261 144 154 178 144
-170 177.944 144 171 178 144 203 177.909 144
-203.043 178 144 207 177.261 144 207.607 178 144
-212.667 178 144 213 177.5 144 50 178.5 144
-50.5 179 144 113.848 179 144 114 178.773 144
-155 179 144 183 179 143.824 182.941 179 144
-183 178.955 144 183.167 179 144 203.414 179 144
-208 178.647 144 208.176 179 144 211.697 179 144
-212 178.688 144 51 179.5 144 51.5 180 144
-113 180 144 156 180 144 182.964 180 144
-184 179.278 144 184 180 142.143 185 179.824 144
-185.214 180 144 203.515 180 144 209 179.824 144
-210 180 144 211 179.676 144 52 180.5 144
-52.6071 181 144 112 181 144 157 181 144
-183 181 142.5 182.783 181 144 184 181 141.571
-185 181 141.125 186 180.957 144 186.056 181 144
-202.706 181 144 203 180.773 144 53 181.333 144
-53.8148 182 144 111 182 144 158 181.848 144
-158.227 182 144 165 182 143.824 164.957 182 144
-165 181 144 166 181.333 144 166 182 142.2
-166.706 182 144 172 182 144 173 181.545 144
-173.455 182 144 183 181.455 144 184 182 141.938
-183.353 182 144 187 181.63 144 187.37 182 144
-198.353 182 144 199 181.476 144 200 181.179 144
-201 181.343 144 202 181.343 144 54 182.152 144
-55 182.848 144 55.2273 183 144 110 183 144
-159 182.5 144 159.773 183 144 165 182.043 144
-166 183 142.8 165.786 183 144 167 182.833 144
-167 183 143.667 167.077 183 144 171.739 183 144
-174 182.429 144 175 182.643 144 176 182.286 144
-177 182.214 144 178 182.393 144 179 183 144
-183.462 183 144 188 182.773 144 188.417 183 144
-198.515 183 144 56 183.5 144 57 184 144
-70.5882 184 144 71 183.72 144 72 183.966 144
-72.0588 184 144 87.9583 184 144 88 183.957 144
-89 183.5 144 89.7727 184 144 109 184 144
-160 183.152 144 161 184 144 166 183.5 144
-167 184 141.429 166.5 184 144 168 183.545 144
-168.625 184 144 171.167 184 144 180 183.478 144
-181 184 144 182.545 184 144 183 183.545 144
-189 183.318 144 190 183.706 144 190.217 184 144
-198.182 184 144 58 184.676 144 58.6471 185 144
-70.4138 185 144 73 184.593 144 73.5238 185 144
-87.4138 185 144 90 184.227 144 90.6071 185 144
-108 185 144 162 185 144 166.6 185 144
-169 184.182 144 170 184.176 144 171 184.042 144
-182 184.171 144 190.786 185 144 198.179 185 144
-59 185.176 144 60 185.824 144 60.5 186 144
-71 185.5 144 71.7727 186 144 74 185.455 144
-75 185.957 144 75.0909 186 144 83.3529 186 144
-84 185.676 144 85 185.667 144 86 186 144
-87 185.706 144 90.4286 186 144 107 186 144
-163 186 144 166.414 186 144 178 185.964 144
-177.857 186 144 178.2 186 144 191 185.214 144
-191.786 186 144 196.688 186 144 197 185.815 144
-198 185.192 144 61 186.176 144 62 186.824 144
-62.2609 187 144 72 186.179 144 73 186.667 144
-73.2727 187 144 76 186.303 144 77 186.75 144
-78 186.964 144 79 186.966 144 80 186.647 144
-81 186.514 144 82 186.343 144 83 186.176 144
-90 186.5 144 89.6471 187 144 105.706 187 144
-106 186.848 144 164 186.821 144 164.227 187 144
-166.077 187 144 176 186.767 144 175.611 187 144
-177 186.207 144 178.706 187 144 192 186.214 144
-192.815 187 144 195.522 187 144 196 186.5 144
-63 187.5 144 63.7391 188 144 74 188 144
-89.1471 188 144 103.478 188 144 104 187.586 144
-105 187.343 144 165 187.515 144 166 187.045 144
-169 187.217 144 168.217 188 144 170 187.217 144
-171 187.909 144 171.063 188 144 174.179 188 144
-175 187.324 144 178.5 188 144 193 187.152 144
-194 187.676 144 195 187.522 144 64 188.176 144
-65 188.657 144 66 189 144 74.625 189 144
-85 188.727 144 84.7931 189 144 86 188.407 144
-86.7273 189 144 89 188.5 144 88.7059 189 144
-102.5 189 144 103 188.393 144 168.455 189 144
-170 189 141.429 171.083 189 144 173 189 144
-174 188.227 144 178.485 189 144 67 189.5 144
-68 190 144 75 189.353 144 75 190 141.938
-76 190 143.571 76 189.941 144 76.0357 190 144
-84.9706 190 144 87 189.214 144 88 189.414 144
-101.393 190 144 102 189.5 144 169 189.353 144
-170 189.522 144 171 189.091 144 173 190 144
-179 190 141.167 178.5 190 144 182 190 143
-69 190.343 144 70 190.657 144 71 191 144
-72 191 144 73 190.778 144 74 190.714 144
-75 190.688 144 76 190.083 144 85 190.056 144
-85.6071 191 144 100 191 144 101 190.333 144
-174 191 144 178 191 144 86 191.478 144
-86.3529 192 144 98 192 144 99 191.5 144
-175 191.514 144 176 191.514 144 177 191.514 144
-87 192.815 144 87.1852 193 144 95 193 144
-96 192.657 144 97 192.343 144 88 193.786 144
-89 193.824 144 90 193.647 144 91 193.514 144
-92 193.514 144 93 193.514 144 94 193.343 144
-
-POLYGONS 13733 54932
-3 0 13 17
-3 14 0 17
-3 3 2 4
-3 5 3 4
-3 7 3 6
-3 6 3 5
-3 2 13 4
-3 5 4 13
-3 6 5 13
-3 9 10 11
-3 0 7 13
-3 7 6 13
-3 14 7 0
-3 14 8 7
-3 19 8 14
-3 10 9 20
-3 20 9 126
-3 11 10 15
-3 15 10 20
-3 12 11 16
-3 16 11 15
-3 16 121 12
-3 17 18 14
-3 19 14 22
-3 21 8 19
-3 28 17 13
-3 17 28 18
-3 14 18 22
-3 22 18 28
-3 132 20 126
-3 15 20 132
-3 21 19 29
-3 29 19 22
-3 23 21 29
-3 21 23 24
-3 24 127 21
-3 125 25 26
-3 27 125 26
-3 24 23 29
-3 127 24 30
-3 34 31 25
-3 26 25 32
-3 32 25 31
-3 27 26 32
-3 30 24 38
-3 127 30 33
-3 31 34 36
-3 36 34 35
-3 37 31 36
-3 37 32 31
-3 27 32 37
-3 38 33 30
-3 39 33 38
-3 35 34 39
-3 35 137 36
-3 37 36 137
-3 40 140 42
-3 42 41 40
-3 40 41 43
-3 43 41 42
-3 43 42 47
-3 47 42 46
-3 48 44 45
-3 49 48 45
-3 50 44 48
-3 51 46 58
-3 47 46 51
-3 51 2917 47
-3 50 48 52
-3 52 155 50
-3 48 53 52
-3 54 155 52
-3 53 54 52
-3 46 160 58
-3 160 57 58
-3 51 58 59
-3 65 51 59
-3 60 55 56
-3 61 160 71
-3 160 61 57
-3 57 61 62
-3 58 57 66
-3 66 57 62
-3 63 58 66
-3 64 58 63
-3 59 58 65
-3 65 58 64
-3 56 69 60
-3 70 60 69
-3 62 61 72
-3 66 62 72
-3 63 66 67
-3 64 63 68
-3 68 63 67
-3 65 64 75
-3 75 64 68
-3 75 2917 65
-3 76 60 70
-3 72 61 71
-3 66 72 73
-3 67 66 74
-3 74 66 73
-3 68 67 75
-3 75 67 74
-3 69 165 70
-3 76 70 165
-3 72 71 81
-3 73 72 77
-3 77 72 81
-3 77 74 73
-3 75 74 77
-3 164 78 79
-3 164 76 165
-3 164 79 86
-3 80 71 168
-3 81 71 80
-3 82 80 168
-3 89 82 168
-3 83 80 82
-3 84 80 83
-3 81 80 85
-3 85 80 84
-3 78 86 79
-3 88 86 87
-3 92 89 168
-3 84 83 171
-3 171 83 82
-3 171 85 84
-3 88 87 90
-3 90 87 86
-3 174 91 92
-3 89 92 96
-3 93 94 174
-3 101 93 174
-3 94 95 174
-3 174 95 91
-3 92 91 96
-3 96 91 95
-3 89 96 177
-3 101 97 93
-3 93 97 98
-3 94 93 99
-3 99 93 98
-3 180 95 94
-3 96 95 180
-3 103 173 175
-3 3 173 103
-3 3 7 173
-3 173 7 264
-3 101 100 1
-3 97 101 1
-3 102 97 1
-3 102 98 97
-3 99 98 111
-3 111 98 102
-3 111 94 99
-3 122 103 175
-3 3 103 2
-3 104 100 101
-3 107 104 101
-3 1 100 105
-3 105 100 104
-3 122 2 103
-3 112 264 7
-3 179 185 115
-3 11 179 115
-3 11 106 179
-3 179 106 107
-3 104 107 108
-3 105 104 109
-3 109 104 108
-3 105 110 1
-3 105 109 110
-3 1 110 102
-3 111 102 110
-3 122 13 2
-3 8 112 7
-3 115 185 114
-3 11 115 9
-3 106 11 12
-3 121 106 12
-3 121 107 106
-3 108 107 116
-3 116 107 121
-3 109 108 111
-3 111 108 116
-3 110 109 111
-3 112 8 21
-3 117 112 127
-3 113 123 118
-3 184 113 118
-3 125 184 118
-3 119 184 125
-3 114 119 120
-3 115 114 120
-3 9 115 126
-3 111 116 136
-3 136 116 121
-3 127 112 21
-3 117 127 128
-3 128 193 117
-3 194 123 113
-3 131 118 123
-3 125 118 124
-3 124 118 131
-3 126 119 125
-3 120 119 126
-3 115 120 126
-3 15 121 16
-3 28 13 122
-3 129 193 128
-3 129 130 194
-3 194 130 123
-3 123 130 134
-3 131 123 134
-3 25 124 131
-3 125 124 25
-3 126 125 27
-3 132 136 15
-3 121 15 136
-3 28 122 133
-3 128 127 33
-3 129 128 130
-3 34 131 134
-3 25 131 34
-3 135 126 27
-3 132 126 135
-3 136 132 135
-3 29 133 218
-3 29 22 133
-3 22 28 133
-3 130 128 33
-3 134 130 33
-3 27 219 135
-3 136 135 219
-3 29 38 24
-3 134 33 39
-3 34 134 39
-3 38 29 218
-3 27 37 219
-3 219 37 137
-3 218 39 38
-3 137 35 39
-3 140 234 138
-3 139 236 237
-3 140 138 42
-3 141 139 237
-3 142 139 141
-3 40 43 140
-3 43 234 140
-3 143 144 141
-3 141 144 142
-3 144 147 142
-3 148 42 138
-3 2917 234 43
-3 145 144 143
-3 147 144 145
-3 146 145 143
-3 147 145 146
-3 42 148 46
-3 47 2917 43
-3 154 149 146
-3 147 146 150
-3 150 146 149
-3 151 147 150
-3 154 152 149
-3 149 152 150
-3 44 152 45
-3 44 151 152
-3 151 150 152
-3 44 155 151
-3 46 148 760
-3 153 152 154
-3 45 153 49
-3 152 153 45
-3 44 50 155
-3 154 49 153
-3 154 157 49
-3 157 48 49
-3 48 157 53
-3 155 54 156
-3 244 155 55
-3 55 155 156
-3 46 760 160
-3 51 65 2917
-3 53 156 54
-3 53 157 156
-3 157 158 156
-3 55 158 56
-3 55 156 158
-3 55 60 245
-3 55 245 244
-3 245 60 159
-3 157 163 161
-3 157 161 158
-3 158 161 56
-3 60 162 159
-3 160 760 71
-3 56 161 163
-3 69 56 163
-3 76 162 60
-3 69 163 165
-3 76 164 162
-3 256 168 760
-3 71 760 168
-3 78 164 165
-3 86 252 164
-3 86 88 252
-3 81 75 77
-3 165 359 78
-3 252 88 166
-3 252 166 257
-3 256 167 168
-3 78 359 86
-3 257 166 169
-3 167 261 92
-3 168 167 92
-3 85 171 81
-3 171 75 81
-3 166 90 170
-3 88 90 166
-3 169 166 173
-3 173 166 170
-3 264 169 173
-3 261 259 174
-3 92 261 174
-3 86 359 172
-3 86 172 90
-3 90 172 170
-3 172 173 170
-3 89 177 82
-3 171 82 177
-3 2917 171 177
-3 173 172 175
-3 175 172 359
-3 178 264 112
-3 179 107 176
-3 176 101 174
-3 101 176 107
-3 94 111 180
-3 359 122 175
-3 183 178 182
-3 184 276 183
-3 111 181 180
-3 187 180 181
-3 180 187 96
-3 182 178 112
-3 179 184 185
-3 186 181 111
-3 187 181 186
-3 177 96 187
-3 182 112 117
-3 183 182 188
-3 189 183 188
-3 113 183 189
-3 184 183 113
-3 185 184 190
-3 185 190 114
-3 117 193 182
-3 188 182 191
-3 191 182 193
-3 189 188 194
-3 194 188 191
-3 113 189 194
-3 119 190 184
-3 114 190 119
-3 136 192 111
-3 186 111 192
-3 187 186 192
-3 194 191 193
-3 194 193 129
-3 133 122 218
-3 136 219 220
-3 196 195 197
-3 197 195 295
-3 198 196 197
-3 198 199 196
-3 201 202 200
-3 202 203 205
-3 200 202 205
-3 203 204 205
-3 205 204 206
-3 206 207 291
-3 295 208 197
-3 198 197 208
-3 199 198 209
-3 209 198 208
-3 210 199 209
-3 200 199 211
-3 211 199 210
-3 201 200 211
-3 212 201 211
-3 202 201 213
-3 213 201 212
-3 203 202 213
-3 204 203 214
-3 214 203 213
-3 215 204 214
-3 206 204 215
-3 215 216 206
-3 207 206 216
-3 211 210 217
-3 217 210 209
-3 212 211 217
-3 217 213 212
-3 214 213 217
-3 215 214 217
-3 220 137 39
-3 219 137 220
-3 221 222 223
-3 221 227 224
-3 222 221 225
-3 225 221 224
-3 225 315 222
-3 224 227 228
-3 315 225 228
-3 228 225 224
-3 226 540 230
-3 227 226 231
-3 231 226 230
-3 228 227 232
-3 232 227 231
-3 232 315 228
-3 230 540 138
-3 234 230 138
-3 234 231 230
-3 232 231 315
-3 315 231 234
-3 235 233 229
-3 238 235 229
-3 236 233 235
-3 761 233 236
-3 237 235 238
-3 236 235 237
-3 237 238 141
-3 139 142 236
-3 142 761 236
-3 143 141 238
-3 239 142 147
-3 239 419 142
-3 238 320 143
-3 320 146 143
-3 146 320 154
-3 147 151 239
-3 148 138 760
-3 155 239 151
-3 241 239 155
-3 320 762 154
-3 762 157 154
-3 155 244 241
-3 325 240 243
-3 243 240 242
-3 247 242 240
-3 243 242 248
-3 248 242 247
-3 248 325 243
-3 159 246 245
-3 159 249 246
-3 247 250 248
-3 762 163 157
-3 159 162 249
-3 251 162 164
-3 251 164 253
-3 252 253 164
-3 253 252 336
-3 165 163 262
-3 333 252 254
-3 254 252 257
-3 255 333 254
-3 165 262 359
-3 255 254 258
-3 258 254 257
-3 259 451 260
-3 256 451 261
-3 261 451 259
-3 167 256 261
-3 258 257 263
-3 263 257 169
-3 264 258 263
-3 255 258 264
-3 267 259 260
-3 75 171 2917
-3 263 169 264
-3 264 346 255
-3 351 346 265
-3 265 346 264
-3 259 267 174
-3 269 265 264
-3 178 363 270
-3 363 178 275
-3 271 266 354
-3 271 354 272
-3 272 273 274
-3 271 272 274
-3 268 274 273
-3 267 268 273
-3 267 273 174
-3 264 178 269
-3 269 178 360
-3 275 178 276
-3 184 365 276
-3 179 805 184
-3 354 179 176
-3 272 354 176
-3 174 272 176
-3 273 272 174
-3 178 277 360
-3 270 277 178
-3 276 178 183
-3 122 359 278
-3 187 192 177
-3 279 280 385
-3 385 280 281
-3 391 282 279
-3 279 282 280
-3 281 280 282
-3 283 281 282
-3 281 283 284
-3 122 382 218
-3 1226 192 136
-3 285 286 395
-3 401 287 286
-3 288 286 287
-3 395 286 289
-3 289 286 288
-3 289 290 395
-3 393 395 290
-3 196 290 195
-3 393 290 196
-3 196 199 393
-3 199 200 393
-3 393 200 205
-3 205 291 292
-3 287 401 293
-3 287 293 288
-3 289 288 294
-3 294 288 293
-3 290 289 295
-3 295 289 294
-3 290 295 195
-3 291 205 206
-3 207 296 291
-3 292 291 296
-3 293 297 298
-3 294 293 298
-3 295 294 298
-3 295 298 208
-3 216 215 299
-3 216 299 207
-3 207 299 296
-3 299 409 296
-3 215 409 299
-3 209 409 217
-3 208 409 209
-3 409 215 217
-3 300 301 410
-3 301 304 410
-3 300 302 303
-3 301 300 304
-3 304 300 303
-3 303 302 306
-3 306 302 305
-3 304 303 307
-3 307 303 306
-3 307 308 304
-3 223 302 221
-3 305 302 223
-3 222 305 223
-3 222 309 305
-3 309 306 305
-3 307 306 308
-3 308 306 309
-3 221 302 227
-3 222 315 309
-3 315 308 309
-3 233 415 229
-3 415 414 229
-3 302 226 227
-3 302 540 226
-3 312 310 311
-3 423 312 311
-3 312 314 310
-3 313 312 423
-3 314 312 313
-3 316 313 423
-3 314 313 317
-3 317 313 316
-3 317 914 314
-3 317 316 318
-3 914 317 318
-3 142 419 761
-3 540 760 138
-3 319 316 423
-3 318 316 319
-3 914 318 319
-3 2917 315 234
-3 229 320 238
-3 241 322 321
-3 239 241 321
-3 319 240 325
-3 324 322 241
-3 323 322 324
-3 319 423 240
-3 241 244 324
-3 245 425 244
-3 246 425 245
-3 240 423 247
-3 325 248 250
-3 330 325 250
-3 427 426 249
-3 249 426 246
-3 247 423 250
-3 249 430 327
-3 249 162 430
-3 427 249 327
-3 250 423 329
-3 330 250 329
-3 442 163 762
-3 251 331 162
-3 331 430 162
-3 337 332 328
-3 333 328 332
-3 330 329 334
-3 326 330 434
-3 434 330 334
-3 335 331 251
-3 336 332 337
-3 252 333 336
-3 333 332 336
-3 423 338 329
-3 329 338 334
-3 339 434 338
-3 338 434 334
-3 335 342 443
-3 335 251 342
-3 251 253 342
-3 337 253 336
-3 760 451 256
-3 341 339 338
-3 340 341 338
-3 440 344 441
-3 163 442 262
-3 343 443 342
-3 255 346 333
-3 573 441 344
-3 262 442 349
-3 342 345 343
-3 451 347 260
-3 344 440 348
-3 348 440 356
-3 573 344 357
-3 357 344 348
-3 262 349 454
-3 454 350 262
-3 352 346 351
-3 347 805 179
-3 354 347 179
-3 355 347 354
-3 260 347 355
-3 348 356 357
-3 358 573 357
-3 262 350 359
-3 360 351 265
-3 352 351 360
-3 361 363 362
-3 363 364 362
-3 362 364 365
-3 365 184 805
-3 266 366 354
-3 366 355 354
-3 367 355 366
-3 267 367 268
-3 267 260 367
-3 260 355 367
-3 358 357 368
-3 368 369 358
-3 265 269 360
-3 363 361 270
-3 270 361 370
-3 364 363 371
-3 371 363 275
-3 276 364 371
-3 365 364 276
-3 271 643 266
-3 366 266 832
-3 832 266 643
-3 367 366 474
-3 366 832 474
-3 372 271 274
-3 474 268 367
-3 274 268 372
-3 372 268 474
-3 356 373 357
-3 368 357 374
-3 374 357 373
-3 375 369 368
-3 375 368 374
-3 377 270 370
-3 276 371 275
-3 372 643 271
-3 375 374 378
-3 378 374 373
-3 278 359 376
-3 380 360 277
-3 277 270 377
-3 277 377 380
-3 379 122 278
-3 494 122 379
-3 122 494 382
-3 177 192 1226
-3 518 386 383
-3 507 383 386
-3 385 384 516
-3 387 384 385
-3 507 386 388
-3 388 389 507
-3 389 391 516
-3 385 391 279
-3 385 516 391
-3 281 387 385
-3 386 518 388
-3 389 388 390
-3 389 390 391
-3 387 281 284
-3 284 392 387
-3 285 387 392
-3 393 387 285
-3 285 395 393
-3 391 283 282
-3 391 390 283
-3 283 392 284
-3 283 394 392
-3 285 392 286
-3 392 394 286
-3 283 390 396
-3 396 397 283
-3 398 399 394
-3 398 394 397
-3 397 394 283
-3 399 400 401
-3 399 401 394
-3 394 401 286
-3 292 393 205
-3 382 707 218
-3 402 396 390
-3 403 396 402
-3 403 404 405
-3 403 405 396
-3 396 405 397
-3 400 398 397
-3 400 397 406
-3 406 397 405
-3 400 406 401
-3 292 296 407
-3 405 408 406
-3 401 406 408
-3 297 293 408
-3 293 401 408
-3 296 409 407
-3 297 408 298
-3 532 408 405
-3 298 408 532
-3 39 218 1226
-3 39 1226 220
-3 304 411 410
-3 413 412 414
-3 761 413 414
-3 761 414 415
-3 418 416 539
-3 423 418 539
-3 417 416 418
-3 417 914 416
-3 414 412 229
-3 310 418 311
-3 310 417 418
-3 310 914 417
-3 415 233 761
-3 418 423 311
-3 310 314 914
-3 319 573 914
-3 420 761 419
-3 229 762 320
-3 419 239 421
-3 421 420 419
-3 319 325 573
-3 239 542 421
-3 239 321 542
-3 542 321 322
-3 542 322 422
-3 322 323 422
-3 326 325 330
-3 324 422 323
-3 246 424 425
-3 324 244 422
-3 426 424 246
-3 426 554 424
-3 429 554 426
-3 429 426 428
-3 428 426 427
-3 327 430 557
-3 427 327 431
-3 431 327 557
-3 428 427 431
-3 429 428 431
-3 328 432 564
-3 573 326 440
-3 430 331 433
-3 328 564 337
-3 328 333 432
-3 438 432 333
-3 440 326 434
-3 331 335 433
-3 433 335 449
-3 570 435 337
-3 570 337 564
-3 435 436 437
-3 570 436 435
-3 339 439 434
-3 439 447 434
-3 440 434 447
-3 443 449 335
-3 337 444 253
-3 337 435 444
-3 444 435 445
-3 435 437 445
-3 445 437 446
-3 333 346 438
-3 346 576 438
-3 423 470 338
-3 439 341 447
-3 339 341 439
-3 441 573 440
-3 448 449 443
-3 443 343 448
-3 444 342 253
-3 445 450 444
-3 446 450 445
-3 346 579 576
-3 338 452 340
-3 340 447 341
-3 340 452 447
-3 452 456 447
-3 356 447 456
-3 447 356 440
-3 442 453 349
-3 454 449 448
-3 458 449 454
-3 343 345 455
-3 343 455 448
-3 448 455 454
-3 345 459 455
-3 342 459 345
-3 444 459 342
-3 579 346 352
-3 352 584 579
-3 584 352 586
-3 451 805 347
-3 452 338 470
-3 349 453 457
-3 454 349 458
-3 457 458 349
-3 459 454 455
-3 459 350 454
-3 459 460 350
-3 589 462 461
-3 586 352 353
-3 365 805 598
-3 456 452 470
-3 573 358 464
-3 464 471 573
-3 465 458 457
-3 465 457 466
-3 466 457 453
-3 466 460 465
-3 466 359 460
-3 359 350 460
-3 461 467 589
-3 462 467 461
-3 352 360 595
-3 360 468 595
-3 353 352 607
-3 352 595 607
-3 608 361 469
-3 463 362 598
-3 463 469 362
-3 469 361 362
-3 365 598 362
-3 456 470 356
-3 464 369 375
-3 358 369 464
-3 471 464 375
-3 453 477 466
-3 359 466 472
-3 466 477 472
-3 468 360 639
-3 608 626 370
-3 608 370 361
-3 470 893 356
-3 375 475 471
-3 476 471 475
-3 478 617 472
-3 478 472 477
-3 376 617 479
-3 376 472 617
-3 376 359 472
-3 370 653 377
-3 480 628 473
-3 480 473 629
-3 372 474 485
-3 373 356 893
-3 475 378 481
-3 375 378 475
-3 476 475 482
-3 482 475 481
-3 483 471 476
-3 483 476 482
-3 376 648 278
-3 479 648 376
-3 380 639 360
-3 485 643 372
-3 481 378 678
-3 482 481 679
-3 679 481 678
-3 483 482 486
-3 486 482 679
-3 487 483 486
-3 278 648 684
-3 379 488 484
-3 379 278 488
-3 650 685 484
-3 685 379 484
-3 380 377 987
-3 378 489 678
-3 679 490 486
-3 381 487 490
-3 487 486 490
-3 381 491 492
-3 381 492 487
-3 491 493 664
-3 492 491 664
-3 859 278 684
-3 488 278 859
-3 495 494 685
-3 494 379 685
-3 378 373 496
-3 373 893 496
-3 378 496 489
-3 496 497 489
-3 498 678 489
-3 498 489 497
-3 679 499 490
-3 381 490 500
-3 490 499 500
-3 381 500 491
-3 500 501 491
-3 493 491 501
-3 507 493 501
-3 502 493 507
-3 387 493 502
-3 503 700 382
-3 382 495 503
-3 494 495 382
-3 504 701 687
-3 893 505 496
-3 496 505 497
-3 498 497 505
-3 499 498 506
-3 506 498 505
-3 500 499 506
-3 501 500 506
-3 383 507 501
-3 502 507 508
-3 384 502 508
-3 502 384 387
-3 382 700 707
-3 510 512 513
-3 512 514 513
-3 515 505 893
-3 505 515 506
-3 501 506 515
-3 383 501 518
-3 516 508 507
-3 508 516 384
-3 513 511 510
-3 501 515 518
-3 516 389 519
-3 507 389 516
-3 516 519 389
-3 515 521 518
-3 388 518 521
-3 388 521 390
-3 524 393 292
-3 292 407 524
-3 521 1217 390
-3 522 403 525
-3 522 526 403
-3 399 398 526
-3 399 526 523
-3 523 526 522
-3 523 400 399
-3 523 527 400
-3 390 528 402
-3 529 525 528
-3 529 530 525
-3 528 525 402
-3 402 525 403
-3 530 404 531
-3 530 529 404
-3 531 404 526
-3 526 404 403
-3 398 531 526
-3 398 400 531
-3 400 527 531
-3 529 528 532
-3 532 528 390
-3 404 529 405
-3 529 532 405
-3 407 409 524
-3 218 707 533
-3 220 1226 136
-3 1052 298 532
-3 208 298 1052
-3 533 1226 218
-3 409 208 1052
-3 411 534 410
-3 534 411 1258
-3 535 412 536
-3 411 304 757
-3 1258 411 757
-3 412 413 536
-3 410 540 300
-3 538 537 914
-3 761 536 413
-3 540 302 300
-3 304 308 758
-3 758 757 304
-3 539 914 537
-3 762 412 535
-3 416 914 539
-3 759 758 308
-3 539 537 423
-3 308 315 759
-3 315 2917 759
-3 412 762 229
-3 541 761 420
-3 421 541 420
-3 421 542 541
-3 542 543 541
-3 546 541 544
-3 544 541 543
-3 544 545 546
-3 422 543 542
-3 546 545 547
-3 765 543 422
-3 548 545 544
-3 547 545 548
-3 548 549 547
-3 325 326 573
-3 422 768 765
-3 549 548 769
-3 424 550 425
-3 422 244 768
-3 551 768 244
-3 425 550 552
-3 424 553 550
-3 553 424 554
-3 425 555 244
-3 555 551 244
-3 555 425 556
-3 425 552 556
-3 550 557 552
-3 557 556 552
-3 558 553 559
-3 558 557 553
-3 557 550 553
-3 554 559 553
-3 429 776 554
-3 557 430 556
-3 560 561 430
-3 556 430 561
-3 557 558 431
-3 431 558 562
-3 561 560 558
-3 562 558 560
-3 431 562 429
-3 429 563 776
-3 562 563 429
-3 560 433 565
-3 430 433 560
-3 562 560 566
-3 566 560 565
-3 563 562 566
-3 432 567 564
-3 568 567 432
-3 568 432 438
-3 779 568 438
-3 565 433 569
-3 433 449 569
-3 564 567 570
-3 436 570 785
-3 437 571 572
-3 437 436 571
-3 436 785 571
-3 438 786 572
-3 438 572 779
-3 571 779 572
-3 576 786 438
-3 577 569 449
-3 444 450 575
-3 572 575 446
-3 572 446 437
-3 446 575 450
-3 786 575 572
-3 760 805 451
-3 579 578 576
-3 449 458 577
-3 459 444 588
-3 444 574 588
-3 580 581 582
-3 583 579 584
-3 585 584 586
-3 459 587 460
-3 459 588 587
-3 591 580 590
-3 582 592 580
-3 592 590 580
-3 592 582 581
-3 594 583 593
-3 584 595 583
-3 595 593 583
-3 596 584 585
-3 595 584 596
-3 353 597 586
-3 597 463 598
-3 597 598 586
-3 599 600 601
-3 601 600 814
-3 602 458 465
-3 602 815 458
-3 815 577 458
-3 465 460 587
-3 465 587 602
-3 603 587 588
-3 462 589 467
-3 604 591 590
-3 605 591 604
-3 592 606 590
-3 606 604 590
-3 606 592 581
-3 593 820 594
-3 593 468 820
-3 595 468 593
-3 595 596 607
-3 597 353 607
-3 608 463 609
-3 608 469 463
-3 609 463 610
-3 610 463 597
-3 610 611 609
-3 612 613 614
-3 644 573 471
-3 599 615 616
-3 616 600 599
-3 442 477 453
-3 815 617 618
-3 815 602 617
-3 602 587 617
-3 619 587 603
-3 617 587 619
-3 620 621 622
-3 622 623 620
-3 606 605 604
-3 625 820 468
-3 625 468 639
-3 626 608 609
-3 627 609 611
-3 627 628 609
-3 628 626 609
-3 613 628 627
-3 612 628 613
-3 612 473 628
-3 473 612 629
-3 629 630 631
-3 474 832 833
-3 599 632 615
-3 615 632 633
-3 616 615 634
-3 634 615 633
-3 634 600 616
-3 635 618 478
-3 617 478 618
-3 635 479 619
-3 617 619 479
-3 620 636 621
-3 623 636 620
-3 370 626 640
-3 628 641 626
-3 641 640 626
-3 628 480 641
-3 631 660 629
-3 660 631 642
-3 474 833 485
-3 471 483 644
-3 645 599 680
-3 599 645 632
-3 632 645 646
-3 633 632 647
-3 647 632 646
-3 647 634 633
-3 477 635 478
-3 477 648 635
-3 635 648 479
-3 484 859 649
-3 488 859 484
-3 484 649 650
-3 668 669 624
-3 624 637 668
-3 637 651 668
-3 652 637 638
-3 651 637 652
-3 370 654 653
-3 370 640 654
-3 655 653 654
-3 656 654 640
-3 641 657 640
-3 657 656 640
-3 480 658 641
-3 641 658 657
-3 480 659 658
-3 480 629 659
-3 660 659 629
-3 661 662 663
-3 483 487 644
-3 487 492 644
-3 664 644 492
-3 680 665 645
-3 645 665 666
-3 646 645 667
-3 667 645 666
-3 667 647 646
-3 670 668 651
-3 652 670 651
-3 987 377 653
-3 654 671 655
-3 671 654 672
-3 654 656 672
-3 657 673 656
-3 673 672 656
-3 658 674 657
-3 674 673 657
-3 674 658 659
-3 675 662 661
-3 691 662 675
-3 676 661 663
-3 675 661 676
-3 485 677 643
-3 387 664 493
-3 680 681 665
-3 665 681 682
-3 666 665 683
-3 683 665 682
-3 683 667 666
-3 648 698 684
-3 686 669 687
-3 669 668 687
-3 703 668 670
-3 687 668 703
-3 688 671 672
-3 673 689 672
-3 689 688 672
-3 674 690 673
-3 690 689 673
-3 676 691 675
-3 499 678 498
-3 679 678 499
-3 692 694 693
-3 693 694 680
-3 680 694 695
-3 681 680 696
-3 696 680 695
-3 682 681 697
-3 697 681 696
-3 697 683 682
-3 698 699 684
-3 859 684 699
-3 859 699 707
-3 685 503 495
-3 685 700 503
-3 702 686 701
-3 687 701 686
-3 703 504 687
-3 866 688 689
-3 690 866 689
-3 714 517 693
-3 693 517 704
-3 692 704 509
-3 692 693 704
-3 509 705 692
-3 705 694 692
-3 695 694 706
-3 706 694 705
-3 697 696 706
-3 706 696 695
-3 504 702 701
-3 716 702 504
-3 710 510 511
-3 710 512 510
-3 514 512 867
-3 512 710 867
-3 514 712 711
-3 867 712 514
-3 393 713 387
-3 517 715 704
-3 509 704 715
-3 509 715 705
-3 715 738 705
-3 738 697 706
-3 738 706 705
-3 703 716 504
-3 718 708 717
-3 717 708 709
-3 511 719 710
-3 511 513 719
-3 514 719 513
-3 514 720 719
-3 730 719 720
-3 721 711 722
-3 721 720 711
-3 720 514 711
-3 712 722 711
-3 2917 177 1226
-3 393 520 713
-3 520 1014 713
-3 714 885 723
-3 714 723 724
-3 517 714 725
-3 725 714 724
-3 517 725 726
-3 517 726 715
-3 726 738 715
-3 727 718 717
-3 728 718 727
-3 729 717 709
-3 727 717 729
-3 721 730 720
-3 520 393 877
-3 1021 877 393
-3 1021 393 524
-3 723 885 734
-3 734 885 733
-3 724 723 735
-3 735 723 734
-3 736 724 735
-3 725 724 737
-3 737 724 736
-3 726 725 738
-3 738 725 737
-3 727 739 728
-3 729 739 727
-3 893 521 515
-3 731 522 525
-3 731 732 740
-3 731 740 522
-3 522 740 523
-3 741 523 740
-3 734 733 742
-3 735 734 742
-3 894 743 736
-3 894 736 735
-3 737 736 743
-3 744 738 737
-3 893 1217 521
-3 746 527 741
-3 527 523 741
-3 735 742 894
-3 530 745 525
-3 531 746 530
-3 530 746 745
-3 746 531 527
-3 524 409 901
-3 390 1051 532
-3 707 747 533
-3 532 1051 1052
-3 747 748 533
-3 533 748 749
-3 749 748 902
-3 533 749 902
-3 902 1226 533
-3 913 753 750
-3 752 751 754
-3 1103 410 534
-3 755 753 913
-3 756 755 913
-3 750 753 914
-3 914 753 755
-3 535 754 751
-3 535 536 754
-3 755 756 538
-3 914 755 538
-3 538 756 537
-3 535 751 762
-3 761 764 536
-3 756 423 537
-3 541 546 761
-3 546 764 761
-3 547 763 764
-3 546 547 764
-3 544 543 766
-3 766 543 765
-3 544 766 548
-3 763 549 767
-3 547 549 763
-3 764 763 767
-3 768 766 765
-3 548 766 769
-3 766 768 769
-3 769 767 549
-3 769 770 767
-3 764 767 770
-3 771 764 770
-3 551 769 768
-3 772 769 551
-3 772 773 770
-3 772 770 769
-3 770 773 771
-3 774 771 773
-3 774 554 918
-3 555 775 551
-3 551 775 772
-3 559 773 558
-3 558 773 926
-3 554 773 559
-3 774 773 554
-3 554 776 918
-3 918 776 777
-3 762 930 442
-3 555 924 775
-3 556 924 555
-3 556 925 924
-3 561 926 556
-3 556 926 925
-3 926 561 558
-3 776 563 778
-3 777 776 778
-3 566 778 563
-3 567 777 778
-3 568 777 567
-3 568 779 931
-3 931 779 780
-3 760 1132 805
-3 781 782 783
-3 565 569 791
-3 565 791 566
-3 791 945 566
-3 939 778 945
-3 945 778 566
-3 940 778 939
-3 570 940 784
-3 570 778 940
-3 570 567 778
-3 784 785 570
-3 785 786 571
-3 571 786 779
-3 780 779 786
-3 780 786 787
-3 787 786 576
-3 781 788 782
-3 569 577 791
-3 793 574 792
-3 792 574 794
-3 940 444 784
-3 940 794 444
-3 794 574 444
-3 575 784 444
-3 785 784 575
-3 786 785 575
-3 576 578 787
-3 789 796 797
-3 797 790 789
-3 792 945 801
-3 793 792 801
-3 793 801 574
-3 795 578 803
-3 579 803 578
-3 789 946 798
-3 789 798 796
-3 796 798 799
-3 797 796 800
-3 800 796 799
-3 800 790 797
-3 801 588 574
-3 802 951 580
-3 951 581 580
-3 803 579 583
-3 803 804 1128
-3 804 585 586
-3 804 586 1128
-3 586 598 1128
-3 952 573 825
-3 798 946 806
-3 799 798 807
-3 807 798 806
-3 814 800 807
-3 807 800 799
-3 790 800 814
-3 577 808 953
-3 577 953 950
-3 801 953 808
-3 801 808 588
-3 802 591 954
-3 580 591 802
-3 951 809 581
-3 803 594 810
-3 583 594 803
-3 811 812 804
-3 811 804 810
-3 810 804 803
-3 812 585 804
-3 812 813 585
-3 813 596 585
-3 601 946 599
-3 806 946 601
-3 814 807 806
-3 601 814 806
-3 577 815 808
-3 588 808 816
-3 816 808 815
-3 588 816 603
-3 954 605 957
-3 591 605 954
-3 581 809 606
-3 809 817 606
-3 820 810 594
-3 820 821 810
-3 822 811 810
-3 822 810 821
-3 607 813 822
-3 607 596 813
-3 597 823 610
-3 610 823 611
-3 613 824 614
-3 824 612 614
-3 831 612 824
-3 573 644 825
-3 952 825 664
-3 618 826 815
-3 826 816 815
-3 603 826 619
-3 816 826 603
-3 622 621 827
-3 622 827 623
-3 605 606 957
-3 957 606 817
-3 637 818 819
-3 637 624 818
-3 819 960 637
-3 625 828 820
-3 828 821 820
-3 822 821 829
-3 829 821 828
-3 607 822 830
-3 830 822 829
-3 966 607 830
-3 597 607 966
-3 967 597 966
-3 823 597 967
-3 611 823 627
-3 627 823 968
-3 824 613 627
-3 968 824 627
-3 629 612 831
-3 630 629 831
-3 831 631 630
-3 839 631 831
-3 825 644 834
-3 664 825 834
-3 600 634 814
-3 477 442 648
-3 618 635 826
-3 619 826 635
-3 621 636 827
-3 623 827 636
-3 637 960 638
-3 960 835 638
-3 625 639 828
-3 829 828 836
-3 836 828 639
-3 830 829 837
-3 837 829 836
-3 976 966 830
-3 976 830 838
-3 838 830 837
-3 839 840 642
-3 839 642 631
-3 840 841 842
-3 839 841 840
-3 841 989 842
-3 833 843 485
-3 664 834 644
-3 599 1154 680
-3 647 814 634
-3 648 442 698
-3 649 859 855
-3 855 844 649
-3 844 650 649
-3 650 844 845
-3 845 846 847
-3 844 846 845
-3 624 669 848
-3 624 848 985
-3 638 835 652
-3 835 985 652
-3 639 380 849
-3 836 639 849
-3 836 850 837
-3 653 838 850
-3 838 837 850
-3 653 655 976
-3 653 976 838
-3 976 655 993
-3 851 659 988
-3 988 659 660
-3 840 660 642
-3 840 852 660
-3 852 988 660
-3 842 852 840
-3 853 852 842
-3 854 842 662
-3 854 853 842
-3 662 842 663
-3 663 842 989
-3 995 663 989
-3 677 485 843
-3 1154 693 680
-3 667 814 647
-3 859 990 855
-3 856 844 855
-3 845 857 650
-3 650 857 685
-3 848 669 858
-3 670 985 848
-3 670 848 858
-3 985 670 652
-3 380 987 849
-3 653 850 987
-3 671 993 655
-3 659 862 674
-3 994 659 851
-3 862 659 994
-3 662 691 854
-3 995 676 663
-3 996 387 997
-3 683 814 667
-3 991 685 992
-3 992 685 857
-3 686 861 669
-3 860 861 686
-3 669 861 858
-3 861 703 858
-3 858 703 670
-3 671 688 993
-3 862 863 674
-3 674 863 690
-3 676 864 691
-3 995 864 676
-3 387 870 997
-3 697 892 683
-3 892 814 683
-3 700 999 859
-3 700 859 707
-3 991 999 685
-3 999 700 685
-3 686 702 860
-3 860 702 1006
-3 865 861 860
-3 703 861 865
-3 993 688 1008
-3 688 866 1008
-3 690 1009 866
-3 690 863 1009
-3 868 869 867
-3 870 387 713
-3 870 713 1013
-3 693 1187 714
-3 699 698 707
-3 702 716 1006
-3 1006 716 880
-3 703 865 1018
-3 709 708 872
-3 872 708 871
-3 871 873 872
-3 1009 1008 866
-3 710 874 867
-3 867 875 868
-3 874 875 867
-3 876 867 869
-3 876 712 867
-3 713 1014 1013
-3 1004 1014 520
-3 1004 520 877
-3 1187 1023 714
-3 697 738 892
-3 716 1018 880
-3 1018 716 703
-3 871 708 881
-3 708 718 881
-3 872 882 709
-3 873 882 872
-3 730 710 719
-3 730 883 710
-3 883 874 710
-3 721 722 884
-3 721 884 874
-3 721 874 883
-3 875 874 884
-3 876 722 712
-3 884 722 876
-3 878 877 1021
-3 1046 885 879
-3 714 1023 885
-3 728 886 881
-3 728 881 718
-3 882 729 709
-3 882 887 729
-3 721 883 730
-3 890 1033 731
-3 1033 732 731
-3 892 738 891
-3 728 739 886
-3 739 887 886
-3 729 887 739
-3 525 895 890
-3 731 525 890
-3 741 740 732
-3 733 885 1046
-3 743 897 737
-3 894 897 743
-3 892 737 897
-3 892 744 737
-3 891 738 744
-3 891 744 892
-3 733 1046 742
-3 892 897 899
-3 525 745 895
-3 746 1040 745
-3 898 896 901
-3 901 896 524
-3 742 1046 899
-3 899 894 742
-3 897 894 899
-3 900 898 901
-3 903 1047 901
-3 901 409 903
-3 747 902 748
-3 903 409 1052
-3 904 905 906
-3 909 1093 750
-3 1095 909 750
-3 1095 750 914
-3 751 910 911
-3 912 910 752
-3 752 910 751
-3 750 1093 913
-3 912 754 536
-3 912 752 754
-3 913 1093 756
-3 912 536 764
-3 762 751 911
-3 1258 757 759
-3 1105 914 915
-3 540 410 1103
-3 915 914 916
-3 760 540 1103
-3 757 758 759
-3 916 914 573
-3 759 2917 4237
-3 771 918 764
-3 917 919 923
-3 773 772 920
-3 920 921 773
-3 771 774 918
-3 928 922 919
-3 923 919 922
-3 772 775 924
-3 772 924 920
-3 924 925 920
-3 921 920 926
-3 926 920 925
-3 921 926 773
-3 777 927 918
-3 777 568 927
-3 932 1115 573
-3 922 928 929
-3 938 923 929
-3 929 923 922
-3 931 927 568
-3 1121 927 931
-3 1301 1132 760
-3 929 928 933
-3 933 938 929
-3 780 787 1121
-3 780 1121 931
-3 1121 787 1126
-3 783 934 935
-3 782 934 783
-3 935 781 783
-3 936 781 935
-3 937 928 789
-3 938 933 937
-3 937 933 928
-3 782 943 934
-3 788 943 782
-3 936 788 781
-3 943 788 936
-3 937 789 790
-3 937 790 938
-3 944 945 791
-3 792 939 945
-3 794 939 792
-3 940 939 794
-3 787 578 1126
-3 941 578 795
-3 942 941 795
-3 795 803 1128
-3 795 1128 942
-3 791 577 947
-3 791 947 948
-3 791 948 944
-3 948 1137 949
-3 948 949 944
-3 944 949 945
-3 945 949 801
-3 952 932 573
-3 577 950 947
-3 950 953 947
-3 801 949 1137
-3 801 1137 953
-3 805 1128 598
-3 932 952 1141
-3 938 790 814
-3 802 954 951
-3 951 954 809
-3 956 812 811
-3 1140 813 812
-3 809 957 817
-3 954 957 809
-3 819 958 959
-3 818 958 819
-3 959 960 819
-3 962 955 961
-3 963 956 964
-3 963 961 956
-3 961 955 956
-3 811 964 956
-3 811 822 964
-3 822 1140 964
-3 1140 822 813
-3 824 969 831
-3 664 1141 952
-3 1144 958 624
-3 958 818 624
-3 961 965 962
-3 963 965 961
-3 967 968 823
-3 968 969 824
-3 831 969 970
-3 970 971 831
-3 831 971 839
-3 833 832 972
-3 832 1366 972
-3 930 698 442
-3 1144 624 975
-3 960 975 835
-3 1144 975 960
-3 976 967 966
-3 977 968 967
-3 969 968 977
-3 970 969 978
-3 978 969 977
-3 1155 971 978
-3 978 971 970
-3 979 971 1155
-3 839 971 979
-3 839 980 841
-3 979 980 839
-3 841 980 989
-3 643 1366 832
-3 972 981 833
-3 981 843 833
-3 982 983 844
-3 844 984 846
-3 983 984 844
-3 846 984 847
-3 624 985 975
-3 975 985 835
-3 849 987 836
-3 986 987 849
-3 836 987 850
-3 994 977 967
-3 978 977 994
-3 851 988 978
-3 851 978 994
-3 1155 978 988
-3 1155 852 979
-3 1155 988 852
-3 853 979 852
-3 980 979 853
-3 854 980 853
-3 854 989 980
-3 1382 1366 677
-3 1366 643 677
-3 1382 677 981
-3 843 981 677
-3 996 664 387
-3 693 1154 1365
-3 855 991 856
-3 990 991 855
-3 856 982 844
-3 856 991 982
-3 991 992 982
-3 845 992 857
-3 845 983 992
-3 983 982 992
-3 847 983 845
-3 984 983 847
-3 987 986 849
-3 993 967 976
-3 994 967 993
-3 989 854 1165
-3 854 691 1165
-3 995 989 1165
-3 997 998 1161
-3 996 997 1161
-3 698 930 707
-3 990 859 999
-3 991 990 999
-3 862 1001 863
-3 862 994 1001
-3 994 993 1001
-3 691 1002 1165
-3 995 1002 864
-3 1002 691 864
-3 998 997 870
-3 1161 998 1003
-3 1004 1161 1003
-3 1005 1161 1004
-3 693 1169 1187
-3 1365 1169 693
-3 860 1006 1000
-3 860 1000 1007
-3 1000 1006 1007
-3 1007 865 860
-3 1001 993 1009
-3 1009 993 1008
-3 1001 1009 863
-3 1011 868 1010
-3 1011 1179 868
-3 1179 869 868
-3 1179 1012 869
-3 1013 998 870
-3 1003 998 1014
-3 1014 998 1013
-3 1004 1003 1014
-3 1005 1004 877
-3 1015 1005 877
-3 878 1005 1015
-3 1162 1005 878
-3 1162 878 1163
-3 1163 878 1021
-3 1007 1006 1018
-3 1018 1006 880
-3 865 1007 1018
-3 873 871 1189
-3 871 1188 1189
-3 873 1189 1019
-3 1010 875 884
-3 868 875 1010
-3 876 1011 1010
-3 876 1010 884
-3 869 1020 876
-3 1020 1011 876
-3 1012 1020 869
-3 1015 877 878
-3 1016 1022 879
-3 885 1016 879
-3 1017 1016 885
-3 885 1023 1017
-3 871 881 1024
-3 871 1024 1025
-3 871 1025 1188
-3 873 1026 882
-3 873 1019 1026
-3 1028 1029 1027
-3 1030 1032 1033
-3 1031 1032 1030
-3 1022 1046 879
-3 881 886 1034
-3 881 1034 1024
-3 1034 1035 1024
-3 1024 1036 1025
-3 1024 1035 1036
-3 1036 1196 1025
-3 1036 1026 1196
-3 1036 887 1026
-3 882 1026 887
-3 1027 1037 1028
-3 1029 1037 1027
-3 888 1202 889
-3 1038 888 889
-3 1039 1031 1030
-3 1205 1031 1039
-3 1033 890 1039
-3 1033 1039 1030
-3 1033 1032 1040
-3 1033 1040 732
-3 887 1034 886
-3 1035 1034 887
-3 1036 1035 887
-3 888 1204 1202
-3 1204 888 1038
-3 1205 1039 890
-3 1205 890 895
-3 741 732 1040
-3 1041 524 896
-3 1427 895 745
-3 1040 1427 745
-3 741 1040 746
-3 1022 1210 1046
-3 902 747 707
-3 898 1045 1042
-3 896 898 1042
-3 896 1042 1041
-3 1043 1044 900
-3 1045 900 1044
-3 1045 898 900
-3 1050 899 1046
-3 1043 900 1047
-3 900 901 1047
-3 1049 1046 1048
-3 1050 1046 1049
-3 1433 899 1050
-3 1217 1051 390
-3 1049 1048 1220
-3 1225 1222 1051
-3 1051 1222 1052
-3 1047 903 1215
-3 903 1052 1223
-3 1055 1053 1056
-3 1056 1053 1060
-3 1058 1053 1055
-3 1056 1058 1055
-3 1060 1057 1056
-3 1058 1056 1057
-3 1058 1057 1059
-3 1059 1057 1060
-3 1059 1062 1058
-3 905 1059 1060
-3 904 1061 1062
-3 905 904 1062
-3 905 1062 1059
-3 905 1063 906
-3 905 1060 1063
-3 1060 1238 1063
-3 906 1061 904
-3 906 1063 1061
-3 1063 1064 1061
-3 1064 1062 1061
-3 1238 1064 1063
-3 1065 1237 1066
-3 1067 1066 1237
-3 1238 1067 1237
-3 1067 1238 1068
-3 1066 1067 1070
-3 1070 1067 1068
-3 1238 1239 1069
-3 1238 1069 1068
-3 1070 1068 1069
-3 1072 1066 1070
-3 1242 1069 1239
-3 1070 1069 1071
-3 1071 1069 1242
-3 1072 1070 1071
-3 1071 1242 1073
-3 1072 1071 1073
-3 1073 1242 1074
-3 1072 1073 1076
-3 1076 1073 1074
-3 1076 1074 1075
-3 1074 1242 1077
-3 907 1075 1077
-3 1075 1074 1077
-3 907 1078 1076
-3 907 1076 1075
-3 907 1081 908
-3 1077 1081 907
-3 907 908 1078
-3 908 1081 1080
-3 908 1080 1078
-3 1078 1080 1079
-3 1472 1082 1081
-3 1243 1079 1080
-3 1081 1243 1080
-3 1082 1243 1081
-3 1084 1082 1083
-3 1084 1083 1085
-3 1085 1083 1086
-3 1086 1084 1085
-3 1087 1084 1086
-3 1088 1084 1087
-3 1087 1089 1088
-3 1088 1089 1090
-3 1090 1091 1088
-3 1089 1091 1090
-3 1094 1093 1092
-3 1095 1092 1093
-3 909 1095 1093
-3 1098 1097 1099
-3 1102 1251 1096
-3 1100 1097 1098
-3 1504 1100 1098
-3 910 1100 911
-3 910 1099 1100
-3 1099 1097 1100
-3 1099 910 1101
-3 910 912 1101
-3 1504 911 1100
-3 534 1258 1256
-3 1095 914 1259
-3 1504 762 911
-3 1259 914 1105
-3 1101 912 764
-3 1263 1259 1105
-3 1102 1106 1104
-3 1104 1106 1107
-3 1258 759 4237
-3 1112 1263 1105
-3 1109 1107 1108
-3 1108 1107 1106
-3 915 916 1105
-3 916 1112 1105
-3 1110 1109 1108
-3 916 573 1111
-3 1112 916 1111
-3 1108 1114 1110
-3 1110 1114 1113
-3 573 1268 1111
-3 1268 1112 1111
-3 1114 1270 1113
-3 760 1511 2369
-3 1115 1268 573
-3 1288 917 1116
-3 1276 1115 1290
-3 919 917 1118
-3 917 1288 1118
-3 1116 917 1117
-3 1118 928 919
-3 917 923 1117
-3 1532 927 1119
-3 1290 1115 932
-3 1117 923 938
-3 1121 1119 927
-3 1120 1290 932
-3 1122 1119 1121
-3 1122 1123 1119
-3 1123 1124 1292
-3 1119 1123 1292
-3 1124 942 1292
-3 935 934 1125
-3 935 1125 936
-3 1297 1120 932
-3 928 1118 789
-3 1126 1122 1121
-3 1123 1122 1127
-3 1127 1122 1126
-3 941 1124 1127
-3 1124 1123 1127
-3 942 1124 941
-3 942 1128 1292
-3 1129 1130 1131
-3 1131 1130 1132
-3 934 943 1125
-3 936 1125 943
-3 1133 1134 1135
-3 1135 1136 1133
-3 1297 932 1141
-3 1118 1311 789
-3 1127 1126 578
-3 941 1127 578
-3 1129 805 1132
-3 1130 1129 1132
-3 1133 1315 1134
-3 1136 1315 1133
-3 948 947 1137
-3 1298 1141 1318
-3 1311 946 789
-3 947 953 1137
-3 423 893 470
-3 1142 1318 1141
-3 1143 1318 1142
-3 946 1311 599
-3 956 955 1138
-3 1138 1139 956
-3 956 1140 812
-3 1139 1140 956
-3 959 958 1144
-3 959 1144 960
-3 1138 962 1145
-3 955 962 1138
-3 964 1145 963
-3 964 1139 1145
-3 1139 1138 1145
-3 1140 1139 964
-3 1142 1141 1146
-3 1147 1142 1146
-3 1143 1142 1147
-3 1148 1143 1147
-3 1323 1148 1353
-3 962 965 1145
-3 963 1145 965
-3 974 973 1577
-3 1577 1150 974
-3 664 1151 1141
-3 1151 1146 1141
-3 1147 1146 1151
-3 1152 1147 1151
-3 1148 1147 1152
-3 1153 1148 1152
-3 1160 1148 1153
-3 1353 1148 1160
-3 1149 1343 1154
-3 974 1156 973
-3 974 1157 1156
-3 1157 1150 1158
-3 1157 974 1150
-3 1153 1152 1151
-3 1160 1153 1159
-3 1354 1353 1160
-3 1365 1154 1343
-3 1166 1382 981
-3 664 996 1151
-3 1153 1151 996
-3 1159 1153 996
-3 996 1160 1159
-3 1161 1160 996
-3 1354 1160 1161
-3 1354 1161 1162
-3 1005 1162 1161
-3 1373 1162 1163
-3 1168 1163 1167
-3 1359 1168 1175
-3 1377 1164 1169
-3 707 930 5643
-3 995 1165 1002
-3 1171 1172 1170
-3 1167 1163 1173
-3 1168 1167 1174
-3 1174 1167 1173
-3 1183 1168 1174
-3 1175 1168 1183
-3 1184 1175 1183
-3 1164 1176 1177
-3 1169 1164 1178
-3 1178 1164 1177
-3 1186 1169 1178
-3 1187 1169 1186
-3 1172 1180 1170
-3 1173 1163 1021
-3 1021 1174 1173
-3 1185 1016 1176
-3 1177 1176 1016
-3 1017 1177 1016
-3 1178 1177 1017
-3 1017 1186 1178
-3 1179 1011 1020
-3 1012 1179 1020
-3 1193 1182 1181
-3 1409 1194 1181
-3 1194 1193 1181
-3 1021 1183 1174
-3 1184 1183 1195
-3 1195 1183 1021
-3 1016 1185 1022
-3 1022 1185 1415
-3 1023 1186 1017
-3 1187 1186 1023
-3 1188 1025 1196
-3 1019 1196 1026
-3 1019 1189 1196
-3 1189 1188 1196
-3 1028 1197 1029
-3 1190 1198 1191
-3 1192 1198 1190
-3 1193 1205 1182
-3 1031 1205 1193
-3 1031 1193 1194
-3 1194 1409 1199
-3 1194 1199 1031
-3 1031 1199 1032
-3 524 1195 1021
-3 524 1413 1195
-3 1200 1022 1201
-3 1201 1022 1415
-3 1028 1037 1197
-3 1029 1197 1037
-3 1202 1203 889
-3 1038 1203 1204
-3 1038 889 1203
-3 1206 1040 1032
-3 1206 1032 1199
-3 524 1041 1413
-3 1207 1413 1208
-3 1208 1413 1041
-3 1201 1207 1208
-3 1201 1208 1200
-3 1200 1208 1209
-3 1200 1209 1022
-3 1205 895 1427
-3 1206 1427 1040
-3 1210 1208 1041
-3 1209 1208 1210
-3 1022 1209 1210
-3 1041 1042 1211
-3 1041 1211 1210
-3 1210 1211 1046
-3 1433 892 899
-3 1044 1043 1212
-3 1212 1213 1044
-3 1044 1214 1045
-3 1213 1214 1044
-3 1045 1211 1042
-3 1045 1214 1211
-3 1046 1211 1048
-3 1047 1212 1043
-3 1047 1215 1212
-3 1215 1213 1212
-3 1214 1213 1216
-3 1216 1213 1215
-3 1211 1214 1216
-3 1216 1215 1218
-3 1211 1216 1219
-3 1219 1216 1218
-3 1048 1211 1220
-3 1211 1219 1220
-3 1049 1433 1050
-3 1217 1221 1051
-3 1051 1221 1225
-3 1215 903 1223
-3 1218 1215 1223
-3 1219 1218 1223
-3 1220 1219 1224
-3 1224 1219 1223
-3 1893 1433 1049
-3 1893 1049 1224
-3 1224 1049 1220
-3 902 707 5643
-3 1217 1632 1221
-3 1221 1632 1225
-3 1893 1224 1223
-3 1632 1052 1225
-3 1225 1052 1222
-3 902 5643 1226
-3 1229 1227 1230
-3 1234 1229 1230
-3 1227 1231 1230
-3 1234 1230 1232
-3 1232 1230 1231
-3 1232 1231 1233
-3 1234 1232 1233
-3 1233 1231 1235
-3 1234 1233 1236
-3 1236 1233 1235
-3 1235 1231 1469
-3 1054 1469 1053
-3 1054 1236 1469
-3 1236 1235 1469
-3 1054 1053 1234
-3 1054 1234 1236
-3 1053 1469 1060
-3 1234 1053 1058
-3 1058 1062 1234
-3 1238 1060 1469
-3 1062 1064 1234
-3 1234 1064 1663
-3 1064 1237 1663
-3 1238 1237 1064
-3 1237 1065 1066
-3 1237 1066 1663
-3 1066 1072 1663
-3 1241 1240 1239
-3 1242 1239 1240
-3 1241 1242 1240
-3 1472 1242 1241
-3 1470 1472 1241
-3 1072 1076 1079
-3 1242 1472 1077
-3 1077 1472 1081
-3 1076 1078 1079
-3 1472 1473 1082
-3 1473 1083 1082
-3 1475 1083 1473
-3 1082 1084 1243
-3 1243 1084 1244
-3 1086 1083 1475
-3 1476 1086 1475
-3 1086 1476 1087
-3 1084 1088 1244
-3 1089 1087 1476
-3 1244 1088 1091
-3 1089 1476 1246
-3 1249 1089 1246
-3 1089 1249 1091
-3 1245 1247 1248
-3 1245 1248 1092
-3 1245 1092 1503
-3 1091 1249 1250
-3 1091 1250 1244
-3 1248 1094 1092
-3 1096 1246 1489
-3 1249 1246 1096
-3 1251 1249 1096
-3 1251 1250 1249
-3 1251 1244 1250
-3 1262 1244 1251
-3 1099 1252 1098
-3 1099 1487 1252
-3 1095 1503 1092
-3 1102 1096 1489
-3 1499 1102 1489
-3 1098 1252 1253
-3 1967 1487 1101
-3 1487 1099 1101
-3 1098 1253 1504
-3 1255 1254 1257
-3 1257 1254 1256
-3 1258 1500 1255
-3 1257 1258 1255
-3 1505 1102 1499
-3 1103 534 1502
-3 1256 1502 534
-3 1258 1257 1256
-3 1259 1503 1095
-3 1505 1508 1102
-3 1094 423 1093
-3 1251 1102 1262
-3 1967 1101 764
-3 1102 1104 1262
-3 1260 1259 1263
-3 1506 1259 1260
-3 1093 423 756
-3 1508 1261 1106
-3 1102 1508 1106
-3 1104 1107 1262
-3 1263 1112 1264
-3 1260 1263 1265
-3 1265 1263 1264
-3 1260 1512 1506
-3 1261 1108 1106
-3 1109 1262 1107
-3 1264 1112 1266
-3 1265 1264 1267
-3 1267 1264 1266
-3 1260 1265 1267
-3 1273 1260 1267
-3 1512 1260 1273
-3 1109 1110 1262
-3 1268 1266 1112
-3 1268 1267 1266
-3 1273 1267 1268
-3 1114 1108 1269
-3 1262 1110 1271
-3 1110 1113 1271
-3 1103 1511 760
-3 1272 1512 1273
-3 1270 1271 1113
-3 1114 1269 1275
-3 1114 1275 1271
-3 1114 1271 1270
-3 1274 1517 1518
-3 1517 1274 1269
-3 1275 1269 1274
-3 1272 1273 1278
-3 1276 1272 1278
-3 1277 1275 1274
-3 1279 1280 1277
-3 1115 1273 1268
-3 1115 1278 1273
-3 1284 1279 1281
-3 1282 1280 1279
-3 1284 1282 1279
-3 1115 1276 1278
-3 1284 1281 1283
-3 1286 1282 1284
-3 1285 1283 1281
-3 1284 1283 1286
-3 1286 1283 1285
-3 1287 1285 1281
-3 1287 1286 1285
-3 1289 1276 1290
-3 1525 1288 1287
-3 918 1740 764
-3 1287 1288 1116
-3 918 927 1740
-3 927 1531 1740
-3 1525 1533 1118
-3 1525 1118 1288
-3 1287 1116 1117
-3 1531 927 1532
-3 2369 1301 760
-3 1773 1289 1291
-3 1292 1532 1119
-3 1293 1290 1120
-3 1289 1290 1293
-3 1291 1289 1293
-3 1773 1291 1300
-3 1300 1291 1294
-3 1533 1296 1118
-3 1120 1297 1293
-3 1291 1293 1298
-3 1298 1293 1297
-3 1294 1291 1299
-3 1299 1291 1298
-3 1300 1294 1302
-3 1302 1294 1299
-3 1296 1295 1535
-3 1118 1296 1535
-3 1287 1117 814
-3 1303 1300 1302
-3 1304 1300 1303
-3 1300 1304 1305
-3 1118 1535 1311
-3 1129 1301 805
-3 1131 1301 1129
-3 1132 1301 1131
-3 1135 1134 1538
-3 1135 1538 1136
-3 1298 1297 1141
-3 1302 1299 1308
-3 1308 1299 1298
-3 1303 1302 1309
-3 1309 1302 1308
-3 1304 1303 1309
-3 1305 1304 1310
-3 1310 1304 1309
-3 1312 1311 1535
-3 938 814 1117
-3 1307 1313 1306
-3 1313 1307 1314
-3 1315 1541 1134
-3 1538 1134 1541
-3 1315 1136 1316
-3 1316 1136 1538
-3 1538 1317 1316
-3 1318 1308 1298
-3 1309 1308 1318
-3 1321 1541 1315
-3 1316 1319 1315
-3 1319 1316 1317
-3 1320 1309 1318
-3 1310 1309 1320
-3 1801 599 1311
-3 1321 1315 1322
-3 1315 1319 1322
-3 1322 1319 1317
-3 1318 1143 1320
-3 1310 1320 1323
-3 1323 1320 1143
-3 1324 1310 1323
-3 599 1801 1154
-3 1323 1143 1148
-3 1325 1324 1323
-3 1326 1324 1325
-3 1329 1801 1328
-3 1154 1801 1149
-3 1149 1801 1329
-3 1330 1331 1332
-3 1330 1333 1334
-3 1332 1333 1330
-3 1325 1323 1353
-3 1326 1325 1336
-3 1336 1325 1335
-3 1324 1326 1337
-3 1337 1326 1336
-3 1338 1324 1337
-3 1542 1324 1338
-3 1342 1327 1362
-3 1364 1327 1342
-3 1328 1327 1364
-3 1329 1328 1343
-3 1149 1329 1343
-3 1344 1331 1330
-3 1345 1331 1344
-3 1334 1346 1330
-3 1346 1344 1330
-3 1347 1577 973
-3 1150 1348 1349
-3 1150 1577 1348
-3 1348 1350 1349
-3 1335 1325 1353
-3 1336 1335 1353
-3 1337 1336 1354
-3 1354 1336 1353
-3 1338 1337 1354
-3 1355 1338 1354
-3 1566 1338 1355
-3 1566 1355 1356
-3 1357 1339 1340
-3 1341 1339 1358
-3 1358 1339 1357
-3 1341 1358 1561
-3 1563 1359 1360
-3 1342 1362 1363
-3 1364 1342 1363
-3 1328 1364 1365
-3 1343 1328 1365
-3 1346 1345 1344
-3 1156 1157 1367
-3 1156 1367 1347
-3 1156 1347 973
-3 1367 1157 1158
-3 1367 1158 1368
-3 1349 1158 1150
-3 1349 1369 1158
-3 1369 1368 1158
-3 1350 1369 1349
-3 1351 1369 1350
-3 1351 1352 1370
-3 1371 1370 1352
-3 1355 1354 1162
-3 1372 1356 1355
-3 1162 1372 1355
-3 1374 1373 1357
-3 1358 1357 1163
-3 1163 1357 1373
-3 1561 1358 1168
-3 1168 1358 1163
-3 1562 1561 1168
-3 1359 1562 1168
-3 1360 1359 1375
-3 1362 1361 1377
-3 1377 1361 1376
-3 1363 1362 1377
-3 1169 1363 1377
-3 1365 1363 1169
-3 1364 1363 1365
-3 1382 1378 1366
-3 981 1383 1166
-3 1384 1351 1370
-3 1371 1379 1370
-3 1379 1384 1370
-3 1379 1371 1380
-3 1162 1381 1372
-3 1162 1373 1381
-3 1374 1381 1373
-3 1359 1175 1375
-3 1377 1376 1164
-3 1166 1383 1382
-3 1380 1384 1379
-3 1171 1170 1385
-3 1171 1385 1172
-3 1175 1388 1389
-3 1609 1175 1389
-3 1164 1389 1388
-3 1176 1164 1388
-3 1170 1180 1385
-3 1172 1385 1180
-3 1390 1392 1393
-3 1392 1613 1393
-3 1181 1182 1394
-3 1386 1395 1387
-3 1396 1398 1399
-3 1397 1398 1396
-3 1175 1184 1413
-3 1388 1175 1400
-3 1400 1175 1413
-3 1176 1400 1185
-3 1388 1400 1176
-3 1401 1190 1191
-3 1401 1402 1190
-3 1192 1190 1403
-3 1403 1190 1402
-3 1391 1403 1402
-3 1391 1390 1403
-3 1390 1404 1403
-3 1404 1390 1393
-3 1613 1405 1393
-3 1405 1406 1407
-3 1613 1406 1405
-3 1394 1182 1408
-3 1181 1394 1409
-3 1394 1408 1409
-3 1396 1399 1410
-3 1411 1410 1399
-3 1411 1399 1412
-3 1184 1195 1413
-3 1414 1400 1413
-3 1414 1185 1400
-3 1414 1415 1185
-3 1191 1416 1401
-3 1191 1198 1416
-3 1403 1416 1192
-3 1192 1416 1198
-3 1404 1416 1403
-3 1417 1405 1407
-3 1182 1205 1408
-3 1205 1419 1408
-3 1419 1409 1408
-3 1409 1419 1199
-3 1420 1396 1410
-3 1411 1421 1410
-3 1421 1411 1412
-3 1414 1413 1430
-3 1415 1629 1201
-3 1422 1423 1424
-3 1424 1425 1422
-3 1203 1202 1418
-3 1202 1631 1418
-3 1418 1426 1203
-3 1418 1625 1426
-3 1203 1426 1204
-3 1205 1427 1419
-3 1427 1199 1419
-3 1199 1427 1206
-3 1410 1428 1420
-3 1428 1410 1429
-3 1410 1421 1429
-3 1429 1421 1432
-3 1207 1430 1413
-3 1201 1629 1207
-3 1629 1430 1207
-3 1433 814 892
-3 1422 1431 1423
-3 1425 1431 1422
-3 1426 1631 1202
-3 1204 1426 1202
-3 1429 1432 1428
-3 1632 1217 893
-3 1226 2516 2917
-3 1052 1632 1633
-3 1435 1436 1437
-3 1434 1435 1437
-3 1435 1434 1438
-3 1436 1435 1438
-3 1437 1436 1439
-3 1439 1436 1438
-3 1434 1638 1438
-3 1441 1437 1439
-3 1445 1438 1638
-3 1439 1438 1445
-3 1440 1441 1439
-3 1638 1639 1445
-3 1441 1440 1442
-3 1448 1441 1444
-3 1444 1441 1442
-3 1440 1439 1445
-3 1442 1440 1445
-3 1444 1442 1443
-3 1443 1442 1446
-3 1446 1442 1445
-3 1444 1443 1447
-3 1447 1443 1446
-3 1448 1444 1447
-3 1446 1445 1645
-3 1449 1447 1446
-3 1451 1448 1447
-3 1449 1451 1447
-3 1645 1647 1446
-3 1450 1446 1647
-3 1449 1446 1450
-3 1451 1449 1450
-3 1647 1452 1450
-3 1451 1450 1453
-3 1453 1450 1452
-3 1453 1454 1451
-3 1452 1648 1455
-3 1452 1455 1453
-3 1456 1454 1453
-3 1456 1453 1455
-3 1648 1457 1455
-3 1455 1457 1456
-3 1457 1458 1456
-3 1457 1654 1458
-3 1654 1459 1458
-3 1653 1654 1460
-3 1461 1460 1654
-3 1461 1462 1460
-3 1461 1463 1462
-3 1462 1463 1460
-3 1464 1460 1463
-3 1463 1466 1464
-3 1465 1466 1463
-3 1659 1467 1465
-3 1465 1467 1466
-3 1228 1227 1468
-3 1228 1468 1466
-3 1228 1466 1467
-3 1468 1227 1229
-3 1467 1659 1228
-3 1228 1659 1227
-3 1234 1468 1229
-3 1227 1659 1231
-3 1234 4051 1468
-3 1469 1231 1662
-3 1238 1469 1664
-3 1238 1664 1239
-3 1664 1666 1239
-3 1239 1666 1241
-3 1241 1666 1470
-3 1072 1079 1663
-3 1471 1470 1666
-3 1663 1079 1243
-3 1471 1670 1470
-3 1470 1670 1472
-3 1673 1472 1670
-3 1473 1472 1673
-3 1475 1473 1474
-3 1243 1244 1663
-3 1674 1474 1473
-3 1474 1674 1475
-3 1475 1674 1476
-3 1476 1477 1246
-3 1476 1480 1477
-3 1480 1481 1477
-3 1477 1481 1246
-3 1486 1482 1478
-3 1483 1478 1482
-3 1247 1493 1248
-3 1247 1479 1493
-3 1245 1479 1247
-3 1481 1480 1484
-3 1481 1484 1246
-3 1485 1482 1486
-3 1483 1482 1487
-3 1487 1482 1485
-3 1487 1967 1483
-3 1248 1493 1094
-3 1245 1503 1694
-3 1489 1480 1488
-3 1246 1484 1489
-3 1484 1480 1489
-3 1252 1485 1486
-3 1252 1486 1504
-3 1487 1485 1252
-3 1490 1491 1492
-3 1494 1490 1492
-3 1492 1491 1693
-3 1697 1094 1493
-3 1701 1694 1503
-3 1252 1504 1253
-3 1490 1494 1496
-3 1496 1494 1495
-3 1491 1490 1497
-3 1497 1490 1496
-3 1497 1693 1491
-3 1498 1499 1488
-3 1488 1499 1489
-3 1256 1254 1502
-3 1502 1255 1494
-3 1502 1254 1255
-3 1500 1494 1255
-3 1500 1495 1494
-3 1496 1495 1501
-3 1501 1495 1500
-3 1501 1497 1496
-3 1705 1499 1498
-3 1500 1258 1501
-3 2278 1497 1501
-3 1705 1712 1499
-3 1499 1712 1505
-3 1258 2278 1501
-3 1697 423 1094
-3 1503 1259 1506
-3 1258 4237 2278
-3 1712 1507 1261
-3 1505 1712 1261
-3 1508 1505 1261
-3 1512 1503 1506
-3 1719 1503 1512
-3 2686 1967 764
-3 1103 1978 1511
-3 1507 1509 1510
-3 1261 1507 1513
-3 1513 1507 1510
-3 1108 1261 1513
-3 1514 1512 1515
-3 1513 1510 1721
-3 1108 1513 1269
-3 1262 1271 1519
-3 1511 1724 2369
-3 1272 1515 1512
-3 1513 1721 1269
-3 1272 1276 1515
-3 1721 1516 1518
-3 1269 1721 1517
-3 1517 1721 1518
-3 1514 1515 1276
-3 1271 1275 1519
-3 1518 1277 1274
-3 1277 1519 1275
-3 1731 1514 1276
-3 1518 1516 1520
-3 1279 1518 1520
-3 1277 1518 1279
-3 1277 1280 1519
-3 1519 1280 1524
-3 2686 764 1740
-3 1279 1520 1281
-3 1280 1282 1524
-3 1289 1731 1276
-3 1520 1521 1522
-3 1281 1520 1523
-3 1282 1286 1524
-3 1521 1735 1522
-3 1523 1520 1522
-3 4845 930 762
-3 1523 1522 1525
-3 1281 1523 1287
-3 1287 1523 1525
-3 1287 1524 1286
-3 1773 2021 1289
-3 1526 1529 1528
-3 1527 1530 1526
-3 1530 1529 1526
-3 1522 2034 1525
-3 1530 1528 1529
-3 1533 1525 2034
-3 1292 1531 1532
-3 1128 1531 1292
-3 1753 1300 1534
-3 1533 1776 1535
-3 1296 1533 1295
-3 1301 1128 805
-3 1774 1534 1779
-3 1776 1788 1535
-3 1295 1533 1535
-3 1305 1534 1300
-3 1310 1534 1305
-3 1779 1534 1310
-3 1542 1779 1310
-3 1535 1788 1312
-3 1797 1536 1306
-3 1307 1306 1536
-3 1537 1307 1536
-3 1789 1542 1790
-3 1306 1313 1806
-3 1797 1306 1806
-3 1307 1537 1314
-3 1537 1540 1314
-3 1542 1310 1324
-3 1539 1790 1542
-3 1312 1801 1311
-3 1287 814 4422
-3 1313 1810 1806
-3 1313 1540 1810
-3 1314 1540 1313
-3 1538 1811 1317
-3 1783 1539 1542
-3 1543 1783 1542
-3 1545 1328 1808
-3 1799 1545 1808
-3 1317 1811 1322
-3 1811 1546 1322
-3 1543 1542 1547
-3 1548 1543 1547
-3 1560 1549 1544
-3 1562 1544 1549
-3 1563 1544 1562
-3 1550 1544 1563
-3 1545 1550 1327
-3 1328 1545 1327
-3 1551 1552 1553
-3 1551 1553 1554
-3 1553 1555 1554
-3 1322 1546 1321
-3 1547 1542 1556
-3 1557 1547 1556
-3 1548 1547 1558
-3 1558 1547 1557
-3 1339 1548 1558
-3 1815 1548 1339
-3 1341 1815 1339
-3 1341 1559 1560
-3 1815 1341 1560
-3 1560 1559 1549
-3 1549 1559 1561
-3 1562 1549 1561
-3 1327 1550 1563
-3 1332 1823 1564
-3 1331 1823 1332
-3 1552 1551 1333
-3 1552 1333 1564
-3 1564 1333 1332
-3 1334 1333 1551
-3 1334 1551 1565
-3 1565 1551 1554
-3 1565 1554 1555
-3 1348 1817 1351
-3 1817 1578 1351
-3 1556 1542 1338
-3 1566 1556 1338
-3 1557 1556 1566
-3 1566 1558 1557
-3 1339 1558 1567
-3 1567 1558 1566
-3 1339 1567 1340
-3 1559 1341 1561
-3 1359 1563 1562
-3 1327 1563 1362
-3 1569 1570 1568
-3 1571 1823 1345
-3 1823 1331 1345
-3 1565 1572 1573
-3 1565 1573 1334
-3 1334 1573 1346
-3 1555 1572 1565
-3 1574 1575 1366
-3 1366 1575 972
-3 1575 981 972
-3 1576 1577 1347
-3 1350 1348 1351
-3 1351 1578 1352
-3 1356 1579 1566
-3 1579 1567 1566
-3 1340 1579 1357
-3 1567 1579 1340
-3 1361 1563 1360
-3 1362 1563 1361
-3 1580 1569 1568
-3 1847 1569 1580
-3 1581 1568 1570
-3 1580 1568 1581
-3 1571 1345 1830
-3 1345 1346 1830
-3 1830 1346 1573
-3 1850 981 1575
-3 1347 1367 1576
-3 1367 1368 1576
-3 1369 1582 1368
-3 1368 1582 1576
-3 1582 1369 1351
-3 1352 1578 1834
-3 1371 1352 1834
-3 1583 1585 1586
-3 1584 1585 1583
-3 1579 1587 1841
-3 1579 1356 1587
-3 1356 1372 1587
-3 1841 1357 1579
-3 1841 1595 1357
-3 1595 1374 1357
-3 1360 1588 1589
-3 1375 1588 1360
-3 1361 1360 1590
-3 1360 1589 1590
-3 1590 1376 1361
-3 1581 1847 1580
-3 1383 1850 1597
-3 981 1850 1383
-3 1351 1384 1582
-3 1591 1380 1834
-3 1380 1371 1834
-3 1583 1592 1593
-3 1583 1586 1592
-3 1592 1586 1585
-3 1594 1372 1381
-3 1594 1587 1372
-3 1595 1594 1374
-3 1595 1596 1594
-3 1594 1381 1374
-3 1375 1175 1588
-3 1588 1175 1874
-3 1376 1590 1164
-3 1383 1597 1382
-3 1382 1597 1378
-3 1380 1591 1384
-3 1598 1593 1592
-3 1870 1599 1592
-3 1599 1598 1592
-3 1600 1587 1594
-3 1596 1601 1594
-3 1601 1600 1594
-3 1602 1596 1595
-3 1602 1601 1596
-3 1874 1175 1609
-3 1604 1593 1598
-3 1614 1593 1604
-3 1386 1387 1604
-3 1386 1604 1599
-3 1599 1604 1598
-3 1599 1870 1386
-3 1870 1605 1386
-3 1600 1601 1606
-3 1602 1607 1601
-3 1607 1606 1601
-3 1880 1608 1602
-3 1608 1607 1602
-3 1610 1611 1609
-3 1610 1609 1389
-3 1389 1612 1610
-3 1389 1164 1612
-3 1164 1590 1612
-3 1603 1392 1391
-3 1391 1392 1390
-3 1392 1619 1613
-3 1392 1603 1619
-3 1387 1614 1604
-3 1387 1395 1614
-3 1395 1876 1614
-3 1605 1395 1386
-3 1876 1395 1605
-3 1397 1606 1607
-3 1398 1397 1607
-3 1608 1398 1607
-3 1608 1880 1398
-3 1398 1880 1399
-3 1615 1611 1610
-3 1616 1611 1615
-3 1617 1610 1612
-3 1615 1610 1617
-3 1402 1401 1618
-3 1402 1618 1391
-3 1613 1619 1406
-3 1619 1407 1406
-3 1396 1620 1397
-3 1399 1880 1412
-3 1880 1621 1412
-3 1414 1616 1615
-3 1415 1622 1623
-3 1414 1622 1415
-3 1414 1617 1622
-3 1414 1615 1617
-3 1401 1624 1618
-3 1401 1416 1624
-3 1416 1404 1624
-3 1393 1624 1404
-3 1405 1624 1393
-3 1405 1886 1624
-3 1619 1417 1407
-3 1619 1886 1417
-3 1886 1405 1417
-3 1625 1418 1626
-3 1418 1887 1626
-3 1627 1620 1420
-3 1620 1396 1420
-3 1627 1621 1888
-3 1421 1412 1621
-3 1628 1616 1430
-3 1616 1414 1430
-3 1623 1629 1415
-3 1623 1622 1629
-3 1424 1423 1630
-3 1424 1630 1425
-3 1625 1892 1631
-3 1625 1631 1426
-3 1626 1892 1625
-3 1420 1428 1627
-3 1428 1432 1627
-3 1432 1621 1627
-3 1621 1432 1421
-3 1628 1430 1891
-3 1430 1629 1891
-3 1423 1431 1630
-3 1425 1630 1431
-3 814 1433 1893
-3 1634 1636 1635
-3 1434 1437 1635
-3 1636 1637 1635
-3 1434 1635 1637
-3 1637 1903 1434
-3 1441 1635 1437
-3 1434 1903 1641
-3 1434 1641 1638
-3 1448 1635 1441
-3 1640 1638 1641
-3 1639 1638 1642
-3 1642 1638 1640
-3 1641 1642 1640
-3 1639 1642 1643
-3 1445 1639 1643
-3 1445 1643 1645
-3 1645 1643 1644
-3 1644 1643 1908
-3 1908 1649 1644
-3 1644 1649 1645
-3 1651 1448 1454
-3 1448 1451 1454
-3 1646 1645 1649
-3 1647 1645 1646
-3 1647 1648 1452
-3 1454 1456 1651
-3 1647 1646 1649
-3 1912 1648 1647
-3 1648 1909 1650
-3 1651 1456 1458
-3 1912 1647 1649
-3 1913 1650 1909
-3 1648 1650 1652
-3 1648 1652 1457
-3 1913 1914 1650
-3 1650 1914 1652
-3 1653 1651 1459
-3 1651 1458 1459
-3 1457 1652 1654
-3 1654 1653 1459
-3 1653 1460 1656
-3 1654 1652 1655
-3 1654 1655 1461
-3 1655 1652 1914
-3 1464 1656 1460
-3 1461 1655 1463
-3 1466 1656 1464
-3 1657 1658 1655
-3 1655 1658 1463
-3 1463 1658 1465
-3 1466 1468 1656
-3 1922 1658 1657
-3 1465 1658 1659
-3 1658 1922 1660
-3 1658 1660 1659
-3 1231 1660 1661
-3 1660 1231 1659
-3 1662 1231 1661
-3 4051 1234 1663
-3 1666 1664 1665
-3 1666 1665 1667
-3 1667 1665 1668
-3 1669 1666 1667
-3 1471 1666 1669
-3 1669 1667 1668
-3 1471 1669 1670
-3 1669 1668 1670
-3 1670 1668 1671
-3 1670 1671 1673
-3 1673 1671 1672
-3 1672 1951 1673
-3 1673 1951 1674
-3 1673 1674 1473
-3 1676 1677 1947
-3 1951 1954 1675
-3 1674 1951 1675
-3 1675 1954 1476
-3 1675 1476 1674
-3 1476 1954 1678
-3 1677 1676 1956
-3 1677 1956 1478
-3 1681 1679 1680
-3 1245 1681 1479
-3 1476 1678 1480
-3 1480 1678 1685
-3 1682 1677 1478
-3 1682 1955 1677
-3 1956 1486 1478
-3 1478 1483 1682
-3 1483 1967 1955
-3 1483 1955 1682
-3 1686 1687 1683
-3 1683 1687 1688
-3 1684 1683 1689
-3 1689 1683 1688
-3 1479 1681 1493
-3 1245 1694 1963
-3 1685 1965 1488
-3 1480 1685 1488
-3 1687 1686 1691
-3 1691 1686 1690
-3 1688 1687 1692
-3 1692 1687 1691
-3 1692 1689 1688
-3 1486 1956 1504
-3 2279 1494 1686
-3 1492 1686 1494
-3 1690 1686 1492
-3 1693 1690 1492
-3 1693 1691 1690
-3 1689 1692 1693
-3 1693 1692 1691
-3 1493 1681 1697
-3 1703 1695 1965
-3 1488 1965 1696
-3 1696 1965 1695
-3 1488 1696 1498
-3 1494 2279 1502
-3 1693 1497 2278
-3 1689 1693 2278
-3 1696 1695 1698
-3 1698 1695 1704
-3 1498 1696 1699
-3 1699 1696 1698
-3 1498 1699 1700
-3 1956 3036 1504
-3 1707 1694 1701
-3 1702 1694 1707
-3 1709 1694 1702
-3 1704 1695 1703
-3 1969 1698 1704
-3 1699 1698 1969
-3 1970 1699 1969
-3 1970 1705 1699
-3 1699 1705 1700
-3 1700 1705 1498
-3 1701 1503 1706
-3 1707 1701 1706
-3 1702 1707 1708
-3 1709 1702 1711
-3 1711 1702 1708
-3 1703 1710 1704
-3 1710 1969 1704
-3 1705 1970 1971
-3 1708 1707 1711
-3 1711 1707 1706
-3 1972 1709 1711
-3 1705 1971 1712
-3 1503 1711 1706
-3 1972 1711 1713
-3 1968 1985 1710
-3 1712 1985 1507
-3 1712 1710 1985
-3 1719 1711 1503
-3 1714 1711 1719
-3 1713 1711 1714
-3 1972 1713 1714
-3 1983 1972 1714
-3 1504 3036 762
-3 3634 1978 1103
-3 1719 1512 1514
-3 1983 1714 1719
-3 1985 1509 1507
-3 1509 1985 1715
-3 1718 1715 1717
-3 1715 1718 1509
-3 1509 1718 1510
-3 4845 762 3036
-3 1724 1511 1716
-3 1983 1719 1725
-3 1715 2000 1717
-3 1718 1717 1720
-3 1721 1718 1720
-3 1718 1721 1510
-3 1722 1724 1716
-3 2000 1730 1717
-3 1720 1717 1730
-3 1721 1720 1726
-3 1722 1723 1724
-3 1719 1514 1727
-3 1725 1719 1727
-3 1728 1725 1727
-3 1516 1726 1720
-3 1721 1726 1516
-3 1729 1728 1731
-3 1731 1728 1727
-3 1516 1720 1521
-3 1720 1730 1521
-3 1514 1731 1727
-3 2008 1729 1731
-3 2008 1731 1732
-3 1733 1735 1730
-3 1521 1730 1735
-3 1516 1521 1520
-3 1733 1738 1734
-3 1735 1733 1734
-3 1289 1732 1731
-3 2021 1732 1289
-3 1738 1736 1737
-3 1734 1738 1739
-3 1735 1734 1739
-3 1735 1739 1522
-3 2023 1746 1736
-3 1741 1736 1746
-3 1737 1736 1741
-3 1738 1737 1742
-3 1742 1737 1741
-3 1739 1738 1743
-3 1743 1738 1742
-3 2034 1739 1743
-3 1522 1739 2034
-3 1744 2028 1526
-3 2028 1745 1526
-3 1527 1526 1745
-3 1749 2021 1753
-3 1751 1746 2023
-3 1746 2032 1742
-3 1746 1742 1741
-3 1743 1742 2032
-3 1528 2028 1744
-3 1528 1747 2028
-3 1526 1528 1744
-3 1748 1530 1745
-3 1745 1530 1527
-3 1746 1751 1752
-3 1530 1747 1528
-3 1748 1747 1530
-3 1753 2021 1773
-3 1749 1753 1754
-3 1750 2031 1755
-3 1751 1750 1756
-3 1756 1750 1755
-3 1757 1752 1756
-3 1756 1752 1751
-3 1531 1128 3731
-3 1759 1760 1761
-3 1759 1763 1762
-3 1761 1763 1759
-3 1753 1773 1300
-3 1754 1753 1764
-3 2045 1754 1765
-3 1765 1754 1764
-3 1755 2031 1768
-3 1768 2031 1767
-3 1756 1755 1769
-3 1769 1755 1768
-3 1770 1757 1756
-3 1769 1770 1756
-3 2034 1758 1533
-3 1301 3731 1128
-3 1759 1771 1760
-3 1762 1771 1759
-3 1772 1771 1762
-3 1763 1772 1762
-3 1764 1753 1774
-3 1765 1764 1774
-3 1779 1765 1774
-3 2025 1765 1779
-3 2046 2025 1779
-3 1766 1781 1775
-3 1788 1766 1775
-3 1767 1766 1788
-3 1768 1767 1776
-3 1776 1767 1788
-3 1769 1768 1777
-3 1777 1768 1776
-3 1770 1769 1778
-3 1778 1769 1777
-3 1533 1770 1778
-3 4845 5643 930
-3 1753 1534 1774
-3 1775 1781 1782
-3 1788 1775 1782
-3 1778 1777 1776
-3 1533 1778 1776
-3 2056 1779 1783
-3 1784 2056 1783
-3 2066 1785 1780
-3 1781 1780 1786
-3 1786 1780 1785
-3 1787 1781 1786
-3 2067 1782 1787
-3 1787 1782 1781
-3 1542 1789 1779
-3 1789 1783 1779
-3 1790 1783 1789
-3 2066 2060 1791
-3 1791 2060 1544
-3 1785 2066 1791
-3 1792 1785 1791
-3 1798 1785 1792
-3 1793 1785 1798
-3 1786 1785 1794
-3 1794 1785 1793
-3 1787 1786 1795
-3 1795 1786 1794
-3 1795 2067 1787
-3 2074 1796 1788
-3 1536 1797 2081
-3 2081 1537 1536
-3 1783 1790 1539
-3 1784 1783 1543
-3 1792 1791 1798
-3 1794 1793 1799
-3 1799 1793 1798
-3 1795 1794 1799
-3 1796 1800 1801
-3 1788 1796 1801
-3 1788 1801 1312
-3 1806 1807 1797
-3 2080 1540 2081
-3 1540 1537 2081
-3 1798 1791 1550
-3 1799 1798 1545
-3 1801 1800 1328
-3 1809 1805 2421
-3 2080 2091 1540
-3 2091 1810 1540
-3 1548 1784 1543
-3 1815 1784 1548
-3 1544 1784 1815
-3 1550 1791 1544
-3 1545 1798 1550
-3 1809 1812 1813
-3 1809 1816 1812
-3 1816 1809 2421
-3 1541 1321 1814
-3 1546 1811 2109
-3 1544 1815 1560
-3 1553 1552 1824
-3 1812 1553 1813
-3 1824 1813 1553
-3 1555 1553 1812
-3 1555 1812 1816
-3 1546 2121 1321
-3 1321 2121 1814
-3 2110 2446 1817
-3 2446 1835 1817
-3 1819 1820 1818
-3 1821 2128 1822
-3 1822 2128 1821
-3 1564 1824 1552
-3 1564 1823 1824
-3 1825 1813 1824
-3 1816 1831 1555
-3 1826 2120 1575
-3 1348 1833 2110
-3 1817 1348 2110
-3 1835 1578 1817
-3 1818 1820 1827
-3 1828 1827 1820
-3 1829 2128 1569
-3 1821 1569 2128
-3 1829 1570 2128
-3 1821 2128 1569
-3 1569 2128 1570
-3 1571 1830 1823
-3 1830 1824 1823
-3 1573 1572 1831
-3 1573 1831 1824
-3 1573 1824 1830
-3 1825 1824 1831
-3 1831 1572 1555
-3 1826 1574 1832
-3 1575 1574 1826
-3 1577 1576 1833
-3 1577 1833 1348
-3 1834 1578 1835
-3 1836 2140 1837
-3 1837 1838 1836
-3 1839 1818 1827
-3 1828 1840 1827
-3 1840 1839 1827
-3 1842 1841 1828
-3 1841 1840 1828
-3 1845 1843 1844
-3 1845 1846 1590
-3 1844 1846 1845
-3 1569 1847 1829
-3 1570 1847 1581
-3 1829 1847 1570
-3 1849 1832 1574
-3 1848 1832 1849
-3 1849 1574 1366
-3 1576 1582 1833
-3 1835 1851 1834
-3 1834 1851 1852
-3 1853 1583 1854
-3 1853 2140 1583
-3 1584 1583 1836
-3 1836 1583 2140
-3 1584 1838 1585
-3 1584 1836 1838
-3 1585 1838 1855
-3 1853 1854 1838
-3 1855 1838 1854
-3 1839 1856 1865
-3 1839 1840 1856
-3 1841 1587 1856
-3 1841 1856 1840
-3 1841 1842 1595
-3 1857 1843 1845
-3 1858 1843 1857
-3 1589 1588 1857
-3 1589 1857 1845
-3 1590 1589 1845
-3 1846 1859 1590
-3 1860 2149 1861
-3 1860 1862 1863
-3 1861 1862 1860
-3 1378 2485 1849
-3 1378 1849 1366
-3 1868 1597 1850
-3 1384 1851 1582
-3 1852 1851 1384
-3 1591 1852 1384
-3 1834 1852 1591
-3 1593 1854 1583
-3 1593 1864 1854
-3 1864 1855 1854
-3 1585 1864 1592
-3 1855 1864 1585
-3 1865 1856 1587
-3 1858 1857 1588
-3 1858 1588 2152
-3 2152 1588 1874
-3 1859 2153 1590
-3 1860 1866 2149
-3 1863 1866 1860
-3 1867 1866 1863
-3 1378 1868 2485
-3 1868 1378 1597
-3 1864 1593 1869
-3 1592 1864 1870
-3 1864 1869 1870
-3 1865 1587 1600
-3 1865 1600 1878
-3 1871 1602 1595
-3 1871 1595 1872
-3 1872 1595 1842
-3 1590 2153 1873
-3 1874 1873 2153
-3 1603 2154 1875
-3 1593 1614 1869
-3 1870 1869 1876
-3 1876 1869 1614
-3 1870 1876 1605
-3 1606 1877 1878
-3 1600 1606 1878
-3 1872 1878 1877
-3 1872 1877 1871
-3 1871 1877 1879
-3 1602 1871 1880
-3 1871 1879 1880
-3 1874 1609 1873
-3 1611 1873 1609
-3 1611 1881 1873
-3 1881 1590 1873
-3 1590 1881 1612
-3 1391 1882 1603
-3 1603 1882 2154
-3 1603 1875 1619
-3 1875 2157 1619
-3 1397 1877 1606
-3 1397 1883 1877
-3 1883 1879 1877
-3 1880 1879 1884
-3 1884 1879 1883
-3 1881 1616 1885
-3 1611 1616 1881
-3 1612 1885 1617
-3 1881 1885 1612
-3 1391 1618 1882
-3 1886 1882 1618
-3 1886 1619 2157
-3 1397 1620 1883
-3 1620 1888 1883
-3 1888 1884 1883
-3 1880 1884 1888
-3 1880 1888 1621
-3 1885 1616 1889
-3 1617 1890 1622
-3 1617 1885 1890
-3 1885 1889 1890
-3 1886 1618 1624
-3 1620 1627 1888
-3 1616 1628 1889
-3 1628 1891 1889
-3 1891 1890 1889
-3 1622 1891 1629
-3 1890 1891 1622
-3 1631 2160 1418
-3 1631 1892 2160
-3 893 2500 1632
-3 1895 1896 1894
-3 1896 1632 1894
-3 1633 1632 1896
-3 1633 1896 2163
-3 2163 2173 1633
-3 1893 1223 2515
-3 1633 2173 1898
-3 1052 1633 1898
-3 2172 1052 1898
-3 1635 1899 1634
-3 1634 1899 1636
-3 1899 1900 1636
-3 1900 1902 1636
-3 1637 1636 1901
-3 1902 1903 1636
-3 1901 1636 1903
-3 1637 1901 1903
-3 1902 1904 1903
-3 1906 1903 1904
-3 1641 1903 1906
-3 1635 1448 2180
-3 1906 1904 1905
-3 1642 1906 1643
-3 1641 1906 1642
-3 1643 1906 1910
-3 1910 1908 1643
-3 1651 2180 1448
-3 1906 1905 1907
-3 1910 1906 1907
-3 2189 1908 1910
-3 1649 1908 1911
-3 1911 1908 2189
-3 1911 1912 1649
-3 1912 1909 1648
-3 1912 1913 1909
-3 2183 1914 1911
-3 1911 1914 1912
-3 1913 1912 1914
-3 1653 2180 1651
-3 1656 2180 1653
-3 1914 1916 1915
-3 1914 1915 1655
-3 4051 2180 1656
-3 1915 1657 1655
-3 1918 2198 1915
-3 1918 1915 1917
-3 1917 1915 1916
-3 1657 1915 2198
-3 2199 1657 2198
-3 1916 1919 1917
-3 1918 1917 1920
-3 1920 1917 1919
-3 1918 1920 1921
-3 1920 2203 1922
-3 1920 1922 1921
-3 1657 1921 1922
-3 1923 1922 2203
-3 1924 1922 1923
-3 1924 1925 1922
-3 1922 1925 1660
-3 1660 1925 1661
-3 1927 1926 1662
-3 1927 1662 1661
-3 1468 4051 1656
-3 2557 2563 1926
-3 1926 2563 1662
-3 1469 1662 2563
-3 1664 1469 2220
-3 2219 1929 1928
-3 1930 1929 2219
-3 1929 1930 1931
-3 1664 2220 1932
-3 1936 1933 1930
-3 1931 1930 1934
-3 1934 1930 1933
-3 1932 1935 1937
-3 1932 1937 1664
-3 1933 1936 1938
-3 1934 1933 1938
-3 2226 1937 1935
-3 1664 1937 1665
-3 2226 1939 1937
-3 1937 1939 1941
-3 1665 1937 1941
-3 1939 1943 1940
-3 1941 1939 1940
-3 1665 1941 1668
-3 1938 1936 1942
-3 1941 1940 1944
-3 1944 1940 1943
-3 1668 1941 1945
-3 1945 1941 1944
-3 1944 1943 1946
-3 1945 1944 1946
-3 1668 1945 2233
-3 2233 1945 1946
-3 1936 3036 1942
-3 1942 3036 1947
-3 1938 1942 1947
-3 2234 2232 1946
-3 2234 1946 1943
-3 2233 2236 1671
-3 2233 1671 1668
-3 1671 2236 2238
-3 1671 2238 1948
-3 1947 3036 1676
-3 1948 2238 1949
-3 1949 2238 1952
-3 1671 1948 1950
-3 1950 1948 1949
-3 1672 1671 1951
-3 1671 1950 1951
-3 1950 1949 1953
-3 1954 1950 1953
-3 1951 1950 1954
-3 1949 1952 2247
-3 1953 1949 2247
-3 2606 1947 1677
-3 1953 1678 1954
-3 1244 1262 1663
-3 2256 1678 1953
-3 2606 1677 1955
-3 2254 1679 1245
-3 1679 1958 1680
-3 1245 1679 1681
-3 2258 1957 1678
-3 2254 1245 1963
-3 2272 2254 1963
-3 1678 1957 1959
-3 1684 2279 1683
-3 1680 1958 1681
-3 2272 1963 1961
-3 2275 1960 2276
-3 1959 2276 1960
-3 1959 1960 1685
-3 1678 1959 1685
-3 1967 1966 1955
-3 1966 2263 1955
-3 1683 2279 1686
-3 1684 1689 2278
-3 1962 1960 2275
-3 1965 1960 1962
-3 1685 1960 1965
-3 1964 1961 1963
-3 2272 1961 1964
-3 1958 1697 1681
-3 1964 1963 1694
-3 2279 1103 1502
-3 1975 2281 1964
-3 1965 1962 1703
-3 1709 1964 1694
-3 1962 2275 1968
-3 1968 2275 1976
-3 1703 1962 1968
-3 2281 1975 1973
-3 1968 1976 1977
-3 1703 1968 1710
-3 1969 1710 1971
-3 1970 1969 1971
-3 1972 1964 1709
-3 1975 1964 1972
-3 1974 1973 1975
-3 1710 1712 1971
-3 1968 1977 1985
-3 1979 1975 1972
-3 1974 1975 1991
-3 1973 1974 1991
-3 2288 1973 1991
-3 2287 2293 1976
-3 1977 1976 1980
-3 1981 1977 1980
-3 1982 1977 1981
-3 1977 1982 1985
-3 1983 1979 1972
-3 1975 1979 1983
-3 1991 1975 1983
-3 1976 2293 1986
-3 1980 1976 1984
-3 1984 1976 1986
-3 1981 1980 1984
-3 1982 1981 1984
-3 2296 2288 1991
-3 1982 1984 1985
-3 1987 1511 1978
-3 2304 1988 2300
-3 1986 2300 1988
-3 2000 1986 1988
-3 1715 1984 2000
-3 1984 1986 2000
-3 1985 1984 1715
-3 1511 1989 1990
-3 1716 1511 1990
-3 1987 1989 1511
-3 1992 2296 1991
-3 1988 2304 1995
-3 1990 1994 1716
-3 1983 1725 1991
-3 1992 1991 2008
-3 2330 2004 2304
-3 1995 2304 2004
-3 2305 2001 1996
-3 1993 2305 1997
-3 1997 2305 1996
-3 1723 1722 1998
-3 1723 1998 1993
-3 1723 1993 1997
-3 1716 1999 1722
-3 1722 1999 1998
-3 1999 1716 1994
-3 1991 1725 1728
-3 2008 1991 1728
-3 1988 1995 2000
-3 1996 2001 2002
-3 2003 1996 2002
-3 1724 2003 2369
-3 1724 1997 2003
-3 1997 1996 2003
-3 1723 1997 1724
-3 1729 2008 1728
-3 2000 1995 2005
-3 2005 1995 2004
-3 2006 2000 2005
-3 2007 2000 2006
-3 1730 2000 2007
-3 2002 2001 2369
-3 2003 2002 2369
-3 2321 1992 2008
-3 2004 2330 2009
-3 2013 2004 2009
-3 2005 2004 2010
-3 2010 2004 2013
-3 2006 2005 2011
-3 2011 2005 2010
-3 2007 2006 2012
-3 2012 2006 2011
-3 1730 2007 2012
-3 2331 2686 1740
-3 2013 2014 2010
-3 2011 2010 2015
-3 2015 2010 2014
-3 2012 2011 1733
-3 1733 2011 2015
-3 1730 2012 1733
-3 2016 2014 2013
-3 2015 2014 1733
-3 1733 2014 2016
-3 2706 2355 2001
-3 2321 2008 2019
-3 2019 2008 1732
-3 2017 2321 2019
-3 2018 1736 2016
-3 1733 1736 1738
-3 1733 2016 1736
-3 2363 2331 1740
-3 2017 2019 2020
-3 2021 2017 2020
-3 2366 2363 1740
-3 2001 2355 2369
-3 2021 2019 1732
-3 2020 2019 2021
-3 2017 2021 1749
-3 2341 2017 2024
-3 2024 2017 1749
-3 2022 2027 2018
-3 2360 2022 2018
-3 2027 2023 2018
-3 2018 2023 1736
-3 1740 2367 2366
-3 2022 2360 2030
-3 2027 2022 2026
-3 1531 2367 1740
-3 1745 2028 2377
-3 2029 1745 2377
-3 2025 2024 1749
-3 2030 2371 2036
-3 2022 2030 2031
-3 2031 2030 2038
-3 2026 2022 2031
-3 1750 2026 2031
-3 1751 2027 1750
-3 2027 2026 1750
-3 2023 2027 1751
-3 2032 2033 1743
-3 2033 2034 1743
-3 2035 1748 2029
-3 2029 1748 1745
-3 2045 2025 1749
-3 1781 2036 2371
-3 2038 2030 2037
-3 1746 1752 2039
-3 2039 2040 1746
-3 1746 2040 2032
-3 2040 2041 2032
-3 2033 2032 2042
-3 2042 2032 2041
-3 2034 2042 1758
-3 2034 2033 2042
-3 2035 1747 1748
-3 2035 2044 1747
-3 2044 2043 1747
-3 1754 2045 1749
-3 2025 2045 1765
-3 2037 2030 2047
-3 2047 2030 2036
-3 2038 2037 1766
-3 1766 2037 2047
-3 2048 2038 1766
-3 2031 2038 2048
-3 1752 1757 2049
-3 1752 2049 2050
-3 1752 2050 2039
-3 2050 2051 2052
-3 2050 2052 2039
-3 2039 2052 2040
-3 2041 2040 2053
-3 2053 2040 2052
-3 1758 2042 2053
-3 2042 2041 2053
-3 1761 1760 2054
-3 1761 2055 1763
-3 2054 2055 1761
-3 1784 2046 2056
-3 1781 2379 2061
-3 2061 2379 2057
-3 1766 2036 1781
-3 2047 2036 1766
-3 1767 2048 1766
-3 2031 2048 1767
-3 2058 2049 1757
-3 2058 1757 2059
-3 2059 1757 1770
-3 2051 2058 2059
-3 2052 2051 2059
-3 2052 2059 1533
-3 1758 2052 1533
-3 2053 2052 1758
-3 1760 1771 2054
-3 1772 2054 1771
-3 2055 2054 1772
-3 1763 2055 1772
-3 2056 2046 1779
-3 2046 1784 2060
-3 1533 2059 1770
-3 2057 2060 2066
-3 2061 2057 2062
-3 2062 2057 2066
-3 1781 2061 1780
-3 1780 2061 2062
-3 2063 2064 2065
-3 2060 1784 1544
-3 1780 2062 2066
-3 2067 2071 1782
-3 1782 2071 1788
-3 2071 2074 1788
-3 2063 2068 2064
-3 2067 1795 2069
-3 2071 2067 2070
-3 2070 2067 2069
-3 2411 2072 2071
-3 2073 2071 2072
-3 2074 2071 2073
-3 2075 2094 2076
-3 2075 2077 2078
-3 2076 2077 2075
-3 2077 2402 2078
-3 1797 2080 2081
-3 2079 2080 1797
-3 2082 2419 2407
-3 1795 1799 2069
-3 1808 2069 1799
-3 2070 2069 1808
-3 2070 1808 2071
-3 2072 2071 1328
-3 2071 1808 1328
-3 1800 2072 1328
-3 2073 2072 1800
-3 2074 2073 1800
-3 1796 2074 1800
-3 2083 2094 2075
-3 1802 1803 2083
-3 1802 2083 2078
-3 2078 2083 2075
-3 1802 2402 1804
-3 1802 2078 2402
-3 2084 2085 1805
-3 2086 2088 2089
-3 2089 1807 1806
-3 2089 2088 1807
-3 2088 2090 1807
-3 1797 1807 2090
-3 1797 2090 2091
-3 1797 2091 2079
-3 2429 2091 2090
-3 2080 2079 2091
-3 2092 2419 2082
-3 2092 2082 2407
-3 4422 1524 1287
-3 2093 2094 2083
-3 1803 2093 2083
-3 1803 2095 2093
-3 1804 1803 1802
-3 2084 1805 1809
-3 2096 2087 2086
-3 2089 2097 2086
-3 2097 2096 2086
-3 1806 1810 2098
-3 1806 2098 2089
-3 2089 2098 2097
-3 2091 2429 2099
-3 2091 2099 1810
-3 2098 1810 2099
-3 2443 1538 1541
-3 1811 2443 2108
-3 1811 1538 2443
-3 2101 2419 2092
-3 2124 2419 2101
-3 2102 2101 2092
-3 2103 2094 2093
-3 2104 2094 2103
-3 2105 2093 2095
-3 2103 2093 2105
-3 1813 2106 2107
-3 1813 2107 1809
-3 1809 2107 2084
-3 2099 2097 2098
-3 1814 2443 1541
-3 2108 2109 1811
-3 2447 2123 2100
-3 2123 2111 2100
-3 2124 2101 2112
-3 2101 2102 2112
-3 2113 2112 2102
-3 2102 2125 2113
-3 2103 2116 2104
-3 2105 2116 2103
-3 2106 1813 2117
-3 2118 2107 2106
-3 2118 2106 2119
-3 2119 2106 2117
-3 2119 1816 2118
-3 1816 2421 2118
-3 2819 1826 1832
-3 2120 1826 2819
-3 1546 2109 2130
-3 2446 2131 1835
-3 2111 2122 2458
-3 2111 2123 2122
-3 1819 1818 2124
-3 1819 2124 2112
-3 1819 2112 2113
-3 2113 2125 1819
-3 1819 2125 1820
-3 2114 2115 2126
-3 2127 2126 2115
-3 2117 1825 2129
-3 1813 1825 2117
-3 1816 2129 1831
-3 1816 2119 2129
-3 2119 2117 2129
-3 1546 2130 2121
-3 2123 2458 2122
-3 2132 2458 2123
-3 1818 2133 2124
-3 2142 1828 1820
-3 2142 1820 2125
-3 2127 2134 2126
-3 2134 2135 2136
-3 2134 2127 2135
-3 2137 2135 2127
-3 2135 2138 2139
-3 2137 2138 2135
-3 2138 2144 2139
-3 1825 1831 2129
-3 1850 1575 2120
-3 1837 2140 1838
-3 2133 1818 1839
-3 2133 1839 2146
-3 1842 2142 2141
-3 1842 1828 2142
-3 2136 2135 2143
-3 2135 2139 2143
-3 1843 2144 1844
-3 1843 2139 2144
-3 1843 2143 2139
-3 1844 2144 2480
-3 1846 1844 2480
-3 1832 1848 2484
-3 1582 2476 1833
-3 2476 1851 2131
-3 2476 1582 1851
-3 1835 2131 1851
-3 1838 2140 1853
-3 1865 2145 2146
-3 1839 1865 2146
-3 2142 2146 2145
-3 2142 2145 2141
-3 2141 2145 2151
-3 2141 2151 1842
-3 2143 1843 1858
-3 2143 1858 2479
-3 2148 2479 1858
-3 1846 2148 2147
-3 1846 2147 2153
-3 1846 2153 1859
-3 1861 2150 1862
-3 2149 2150 1861
-3 1862 2150 1863
-3 1849 2484 1848
-3 1849 2485 2484
-3 1850 2156 1868
-3 1865 2151 2145
-3 1842 2151 1872
-3 2152 2148 1858
-3 2152 2147 2148
-3 2153 2147 2152
-3 1867 2149 1866
-3 2150 2149 1867
-3 1863 2150 1867
-3 2154 2485 1868
-3 2154 1868 2155
-3 1868 2156 2155
-3 1878 2151 1865
-3 1878 1872 2151
-3 2153 2152 1874
-3 2155 1875 2154
-3 2155 2156 1875
-3 2156 2157 1875
-3 2490 2489 1882
-3 2489 2154 1882
-3 1882 1886 2490
-3 2158 2490 1886
-3 2157 2158 1886
-3 2492 2493 1887
-3 1887 2493 1626
-3 2159 1887 1418
-3 1418 2160 2159
-3 1892 2889 2160
-3 2889 1892 1626
-3 2500 2906 1632
-3 1894 2162 1895
-3 2162 1896 1895
-3 2163 1896 2507
-3 2163 2508 2164
-3 2507 2508 2163
-3 2508 2165 2164
-3 1897 2166 2161
-3 2167 1897 2161
-3 3403 1893 2515
-3 1894 1632 2504
-3 1632 2168 2504
-3 2504 2162 1894
-3 2169 2163 2164
-3 2169 2173 2163
-3 2165 2169 2164
-3 1897 2171 2166
-3 1897 2170 2171
-3 1897 2167 2170
-3 2170 2167 2172
-3 2161 2172 2167
-3 2172 2161 2515
-3 1898 2173 2915
-3 2171 2170 1898
-3 2171 1898 2915
-3 2172 1898 2170
-3 1052 2515 1223
-3 2172 2515 1052
-3 1635 2174 1899
-3 1899 2174 1900
-3 2174 2175 1900
-3 1902 1900 2175
-3 1902 1905 1904
-3 1905 2176 1907
-3 1907 2176 2177
-3 2178 1907 2177
-3 1910 1907 2179
-3 1907 2178 2179
-3 2181 2182 2176
-3 2176 2182 2177
-3 2521 2178 2182
-3 2182 2178 2177
-3 2178 2521 2179
-3 2191 2179 2521
-3 1910 2191 2189
-3 2179 2191 1910
-3 2184 2182 2181
-3 2185 2182 2184
-3 2521 2182 2186
-3 2186 2182 2185
-3 2521 2186 2191
-3 2189 2187 1911
-3 1911 2187 2183
-3 2187 2188 2183
-3 2183 2188 1914
-3 2184 2181 2525
-3 2185 2184 2525
-3 2523 2185 2525
-3 2186 2185 2523
-3 2187 2189 2190
-3 2188 2187 2190
-3 2188 2190 1914
-3 2191 2192 2189
-3 2190 2189 2193
-3 2193 2189 2192
-3 2196 2190 2193
-3 1914 2190 2196
-3 2192 2191 2194
-3 2194 2193 2192
-3 2194 2196 2193
-3 2196 2194 2195
-3 2196 2197 1914
-3 1914 2197 2200
-3 1914 2200 1916
-3 2196 2200 2197
-3 1916 2200 1919
-3 1921 2198 1918
-3 2199 2198 1921
-3 1657 2199 1921
-3 1919 2200 2201
-3 1919 2202 1920
-3 2201 2202 1919
-3 1920 2202 2203
-3 2201 2200 2204
-3 2202 2201 2203
-3 2201 2204 2203
-3 2203 2204 1923
-3 1923 2205 1924
-3 2962 1924 2205
-3 2962 2546 1924
-3 1925 1924 2546
-3 2204 2206 2207
-3 1923 2204 2208
-3 2208 2204 2207
-3 2209 2962 2205
-3 2209 2205 2208
-3 2208 2205 1923
-3 1925 2546 1661
-3 2546 2549 1661
-3 2208 2207 2210
-3 1926 2209 2208
-3 1926 2208 2210
-3 1927 2549 1926
-3 1926 2549 2209
-3 2549 1927 1661
-3 2210 2207 2557
-3 2210 2557 1926
-3 2574 2563 2562
-3 2563 2574 1469
-3 2213 2212 2217
-3 2212 2213 2211
-3 2211 2213 2214
-3 2214 2212 2211
-3 1469 2574 2220
-3 2215 2213 2217
-3 2214 2213 2216
-3 2216 2213 2215
-3 2216 2572 2214
-3 2215 2217 1928
-3 1928 2218 2215
-3 2218 2216 2215
-3 2218 2572 2216
-3 2217 2219 1928
-3 2218 1929 1931
-3 1928 1929 2218
-3 1931 2572 2218
-3 1930 2219 2217
-3 2220 2226 1932
-3 1930 2217 1936
-3 2220 2574 2221
-3 1932 2226 2222
-3 1932 2222 1935
-3 2220 2221 2224
-3 2224 2221 2223
-3 2226 2220 2225
-3 2225 2220 2224
-3 2222 2226 1935
-3 2224 2223 2227
-3 2225 2224 2228
-3 2228 2224 2227
-3 2226 2225 1939
-3 1939 2225 2228
-3 2227 2579 2230
-3 2227 2230 2228
-3 1943 1939 2230
-3 1939 2228 2230
-3 1934 1938 2587
-3 2582 2229 2579
-3 2230 2579 2229
-3 2582 2231 2229
-3 2229 2231 2234
-3 2230 2229 2234
-3 1943 2230 2234
-3 2232 2233 1946
-3 2587 1938 1947
-3 2234 2235 2232
-3 2235 2236 2232
-3 2233 2232 2236
-3 2234 2231 2237
-3 2234 2237 2240
-3 2235 2234 2238
-3 2238 2234 2240
-3 2236 2235 2238
-3 2240 2237 2239
-3 2237 2231 2245
-3 2245 2231 2586
-3 2239 2237 2245
-3 2240 2239 2241
-3 2238 2240 2244
-3 2244 2240 2241
-3 2239 2245 2242
-3 2241 2239 2242
-3 2244 2241 2242
-3 2238 2244 1952
-3 2242 2245 2243
-3 2246 2242 2243
-3 2244 2242 2246
-3 2587 1947 2606
-3 2245 2586 2249
-3 2244 2246 2250
-3 1952 2244 2247
-3 2244 2250 2247
-3 2247 2248 1953
-3 2243 2245 2249
-3 2246 2243 2250
-3 2250 2243 2249
-3 2247 2250 2251
-3 2252 2247 2251
-3 2248 2247 2253
-3 2253 2247 2252
-3 2248 2253 1953
-3 1676 3036 1956
-3 2250 2249 2605
-3 2615 2250 2605
-3 2251 2250 2615
-3 2251 2615 2255
-3 2251 2255 2252
-3 2253 2252 2256
-3 2256 2252 2255
-3 2253 2256 1953
-3 2258 2255 2615
-3 2256 2255 2258
-3 1955 2257 2606
-3 2254 2601 1679
-3 2256 2258 1678
-3 1679 2601 1958
-3 1958 2601 2265
-3 2615 2261 2258
-3 2258 2261 2262
-3 2257 1955 2263
-3 2259 2254 2272
-3 2272 2273 2260
-3 2260 2273 2266
-3 2274 2260 2266
-3 2267 2268 2269
-3 2262 2261 2269
-3 2258 2262 2270
-3 2258 2270 1957
-3 2264 2279 2271
-3 2279 1684 2271
-3 2278 2271 1684
-3 2266 2273 2274
-3 2262 2269 2275
-3 2270 2262 2276
-3 2276 2262 2275
-3 1957 2276 1959
-3 2270 2276 1957
-3 2274 2273 2272
-3 2269 2268 2280
-3 2263 1966 2277
-3 2272 1964 2274
-3 2268 2267 2280
-3 2275 2269 2280
-3 1966 2648 2277
-3 2280 2267 2653
-3 1958 2265 1697
-3 2281 2274 1964
-3 1967 2648 1966
-3 2288 2274 2281
-3 2275 2280 2282
-3 2279 3634 1103
-3 2282 2280 2283
-3 2275 2282 2287
-3 2275 2287 1976
-3 2288 2281 1973
-3 2288 2658 2274
-3 2282 2283 2285
-3 2285 2283 2284
-3 2287 2282 2286
-3 2286 2282 2285
-3 2290 2284 2662
-3 2284 2290 2285
-3 2286 2285 2291
-3 2291 2285 2290
-3 2287 2286 2292
-3 2292 2286 2291
-3 2287 2292 2293
-3 3634 2294 1978
-3 1978 2294 2295
-3 2289 2288 2297
-3 2299 2289 2297
-3 2293 2292 2291
-3 2295 2294 2301
-3 2288 2296 2303
-3 2297 2288 2303
-3 2299 2297 2298
-3 2291 2290 2300
-3 2293 2300 1986
-3 2291 2300 2293
-3 2688 2307 2668
-3 2668 2307 2676
-3 2295 2301 2302
-3 1978 2302 1987
-3 2295 2302 1978
-3 1992 2303 2296
-3 2298 2297 2313
-3 2299 2298 2313
-3 2691 2299 2313
-3 2300 2685 2304
-3 2307 2688 2305
-3 2305 2688 2706
-3 2306 2307 2305
-3 2302 2301 3172
-3 3172 1987 2302
-3 1989 1987 3172
-3 2297 2303 2308
-3 2313 2297 2321
-3 2321 2297 2308
-3 2305 2706 2001
-3 2306 2305 1993
-3 1998 2306 1993
-3 1998 2310 2306
-3 2310 2307 2306
-3 2310 2317 2307
-3 1990 1989 1994
-3 1994 1989 3172
-3 1992 2308 2303
-3 2321 2308 1992
-3 2691 2313 2314
-3 2328 2315 2309
-3 2316 2309 2315
-3 2304 2309 2316
-3 2310 1998 1999
-3 2310 1999 2317
-3 1999 1994 2318
-3 2324 1994 3172
-3 2318 1994 2324
-3 2312 2320 2311
-3 2320 2319 2311
-3 2339 2315 2328
-3 2304 2316 2330
-3 2330 2316 2322
-3 1999 2323 2317
-3 2318 2323 1999
-3 2324 2323 2318
-3 2320 2325 2319
-3 2313 2321 2326
-3 2314 2313 2333
-3 2333 2313 2326
-3 2334 2314 2333
-3 2327 2314 2334
-3 2315 2339 2345
-3 2316 2315 2345
-3 2329 2316 2345
-3 2322 2316 2330
-3 2330 2316 2329
-3 2326 2321 2017
-3 2333 2326 2332
-3 2721 2327 2334
-3 2336 2335 2328
-3 2335 2337 2328
-3 2337 2338 2328
-3 2339 2328 2338
-3 2329 2345 2346
-3 2009 2330 2329
-3 2332 2326 2341
-3 2341 2326 2017
-3 2333 2332 2341
-3 2334 2333 2341
-3 2715 2342 2336
-3 2336 2342 2335
-3 2337 2335 2343
-3 2343 2335 2342
-3 2339 2338 2344
-3 2345 2339 2344
-3 2346 2345 2350
-3 2009 2329 2346
-3 2346 2013 2009
-3 2706 2340 2355
-3 2355 2340 2347
-3 2344 2338 2349
-3 2345 2344 2361
-3 2361 2350 2345
-3 2013 2346 2742
-3 2744 2013 2742
-3 2362 2013 2744
-3 2013 2362 2016
-3 2351 2352 2353
-3 2353 2354 2351
-3 2369 2355 2730
-3 2347 2730 2355
-3 2739 2348 2370
-3 2740 2370 2356
-3 2342 2715 2357
-3 2357 2715 2356
-3 2337 2343 2364
-3 2338 2337 2358
-3 2358 2337 2364
-3 2349 2338 2359
-3 2359 2338 2358
-3 2344 2349 2360
-3 2360 2349 2359
-3 2360 2361 2344
-3 2362 2744 2755
-3 2016 2362 2018
-3 2331 2363 2738
-3 2756 2738 2363
-3 2343 2342 2371
-3 2364 2343 2371
-3 2359 2358 2030
-3 2360 2359 2030
-3 2361 2360 2365
-3 2365 2018 2755
-3 2362 2755 2018
-3 2366 2756 2363
-3 2348 2334 2341
-3 2370 2348 2341
-3 2357 2356 2371
-3 2342 2357 2371
-3 2358 2364 2030
-3 2030 2364 2371
-3 2018 2365 2360
-3 2761 2366 2367
-3 1531 2368 2367
-3 2372 2373 2374
-3 2374 2375 2372
-3 2025 2341 2024
-3 2372 2376 2373
-3 2375 2376 2372
-3 2046 2341 2025
-3 2370 2341 2046
-3 2356 2370 2046
-3 2028 1747 2767
-3 2377 2028 2767
-3 2035 2377 2378
-3 2035 2029 2377
-3 2371 2356 2046
-3 2379 2371 2046
-3 2381 2380 1747
-3 2380 2767 1747
-3 1747 2043 2381
-3 2378 2043 2044
-3 2381 2043 2378
-3 2035 2378 2044
-3 2379 2046 2057
-3 1781 2371 2379
-3 2382 2384 2385
-3 2385 2050 2049
-3 2385 2384 2050
-3 2384 2386 2050
-3 2386 2051 2050
-3 2381 2387 2380
-3 2388 2387 2381
-3 2378 2388 2381
-3 2389 2383 2382
-3 2390 2383 2389
-3 2385 2391 2382
-3 2391 2389 2382
-3 2049 2058 2392
-3 2049 2392 2385
-3 2385 2392 2391
-3 2058 2789 2392
-3 2058 2051 2789
-3 2051 2386 2789
-3 2057 2046 2060
-3 2389 2393 2390
-3 2391 2393 2389
-3 2789 2391 2392
-3 2394 2398 2395
-3 2065 2799 2396
-3 2064 2799 2065
-3 2396 2063 2065
-3 2395 2397 2394
-3 2398 2397 2395
-3 2397 2399 2400
-3 2398 2399 2397
-3 2399 2401 2400
-3 2077 2814 3259
-3 3259 2402 2077
-3 2064 2403 2799
-3 2068 2403 2064
-3 2396 2404 2063
-3 2063 2404 2068
-3 2068 2404 2403
-3 2396 2418 2404
-3 2801 2406 2405
-3 2394 2397 2408
-3 2409 2408 2397
-3 2409 2400 2410
-3 2409 2397 2400
-3 2401 2410 2400
-3 2076 2813 2412
-3 2094 2813 2076
-3 2814 2077 2412
-3 2412 2077 2076
-3 2804 2815 2402
-3 2413 2414 2415
-3 2817 2414 2413
-3 2404 2417 2403
-3 2417 2404 2416
-3 2418 2416 2404
-3 2405 2406 2419
-3 2407 2419 2406
-3 2072 2411 2071
-3 2420 2813 2094
-3 1804 2815 2827
-3 2402 2815 1804
-3 2084 2829 2085
-3 1805 2085 2817
-3 2085 2829 2817
-3 2817 2413 1805
-3 2421 1805 2413
-3 2421 2413 2415
-3 2118 2421 2415
-3 2422 2424 2425
-3 2423 2424 2422
-3 2425 2424 2426
-3 2426 2086 2087
-3 2426 2424 2086
-3 2424 2428 2086
-3 2427 2088 2428
-3 2088 2086 2428
-3 2088 2429 2090
-3 2427 2429 2088
-3 2416 2430 2417
-3 2433 2434 2824
-3 2824 2435 2433
-3 2844 2092 2407
-3 2420 2094 2436
-3 2095 1803 2437
-3 2095 2437 2420
-3 2095 2420 2436
-3 2827 2437 1804
-3 2437 1803 1804
-3 2422 2425 2440
-3 2426 2440 2425
-3 2087 2096 2440
-3 2426 2087 2440
-3 2441 2427 2428
-3 2429 2427 2442
-3 2442 2427 2441
-3 2429 2442 2099
-3 2444 2445 2833
-3 2432 2444 2833
-3 2432 2431 2444
-3 2431 2110 2444
-3 2446 2110 2431
-3 2100 2434 2433
-3 2100 2111 2434
-3 2433 2435 2447
-3 2433 2447 2100
-3 2864 2419 2124
-3 2102 2092 2844
-3 2436 2104 2448
-3 2094 2104 2436
-3 2095 2448 2105
-3 2436 2448 2095
-3 2829 2107 2118
-3 2829 2084 2107
-3 2853 2438 1832
-3 2819 1832 2438
-3 2096 2839 2440
-3 2441 2839 2097
-3 2839 2096 2097
-3 2099 2441 2097
-3 2442 2441 2099
-3 2443 1814 2449
-3 2108 2443 2449
-3 2109 2108 2450
-3 2450 2854 2109
-3 2110 1833 2445
-3 2110 2445 2444
-3 2131 2446 2457
-3 2111 2451 2452
-3 2123 2843 2451
-3 2123 2447 2843
-3 2452 2451 2843
-3 2102 2453 2125
-3 2102 2844 2453
-3 2849 2455 2114
-3 2454 2455 2849
-3 2115 2114 2456
-3 2114 2455 2456
-3 2104 2116 2448
-3 2105 2448 2116
-3 2819 2439 2120
-3 2109 2467 2130
-3 2467 2109 2854
-3 2458 2451 2111
-3 2123 2451 2132
-3 2132 2451 2458
-3 2849 2114 2459
-3 2114 2126 2459
-3 2115 2456 2470
-3 2127 2115 2470
-3 2462 2463 2464
-3 2464 2465 2462
-3 1832 2868 2853
-3 2130 2466 2121
-3 2467 2466 2130
-3 2133 2864 2124
-3 2133 2468 2469
-3 2133 2469 2864
-3 2468 2125 2469
-3 2468 2142 2125
-3 2134 2459 2126
-3 2134 2136 2470
-3 2137 2127 2470
-3 2137 2471 2138
-3 2470 2471 2137
-3 2138 2471 2144
-3 2472 2461 2460
-3 2473 2472 2460
-3 2474 2475 2463
-3 2483 2462 2465
-3 2483 2474 2462
-3 2463 2462 2474
-3 2439 1850 2120
-3 2476 2131 2457
-3 2146 2468 2133
-3 2146 2477 2468
-3 2142 2468 2477
-3 2143 2470 2136
-3 2143 2478 2470
-3 2478 2471 2470
-3 2144 2471 2479
-3 2471 2478 2479
-3 2479 2480 2144
-3 2473 2481 2472
-3 2481 2865 2472
-3 2481 2473 2482
-3 2474 2483 2475
-3 2868 1832 2484
-3 423 4373 893
-3 2142 2477 2146
-3 2479 2478 2143
-3 2480 2479 2148
-3 1846 2480 2148
-3 2865 2481 2487
-3 2482 2488 2481
-3 2488 2487 2481
-3 2439 2156 1850
-3 2489 2485 2154
-3 2489 2490 2158
-3 2156 2486 2157
-3 2486 2158 2157
-3 2881 2491 2492
-3 2493 2492 2491
-3 2492 1887 2881
-3 2493 2889 1626
-3 2494 2496 2497
-3 2495 2496 2494
-3 2496 2498 2497
-3 814 1893 4422
-3 2159 2881 1887
-3 2499 2881 2159
-3 2160 2499 2159
-3 2499 2160 2889
-3 2494 2497 2892
-3 2892 2497 2498
-3 893 4373 2500
-3 2900 2906 2500
-3 2161 2501 2901
-3 2901 2502 2161
-3 2899 2162 2904
-3 2899 1896 2162
-3 2507 1896 2899
-3 2501 2161 2503
-3 1632 2906 2910
-3 2910 2168 1632
-3 2505 2162 2506
-3 2505 2903 2162
-3 2904 2162 2903
-3 2161 2166 2503
-3 2166 2512 2503
-3 2161 2502 2515
-3 2515 2502 3945
-3 2506 2162 2504
-3 2506 2504 2513
-3 2513 2509 2506
-3 2510 2506 2509
-3 2510 2511 2507
-3 2508 2507 2511
-3 2508 2511 2169
-3 2165 2508 2169
-3 2171 2512 2166
-3 2510 2509 2513
-3 2514 2510 2513
-3 2511 2510 2514
-3 2169 2511 2514
-3 2173 2169 2514
-3 2512 2171 2915
-3 2915 2173 2514
-3 1635 2919 2174
-3 2175 2174 2518
-3 2919 2517 2174
-3 2517 2518 2174
-3 2175 2518 1902
-3 2519 2518 2517
-3 2518 2519 1902
-3 2519 2520 1902
-3 1902 2520 1905
-3 1905 2520 2176
-3 2520 2522 2176
-3 2181 2176 2522
-3 2181 2522 2525
-3 2186 2523 2191
-3 2523 2525 2524
-3 2191 2523 2531
-3 2523 2524 2531
-3 2526 2525 2522
-3 2527 2524 2525
-3 2191 2531 2194
-3 2528 2525 2526
-3 2529 2528 2526
-3 2530 2527 2525
-3 2528 2530 2525
-3 2532 2533 2194
-3 2532 2194 2531
-3 2943 2194 2533
-3 2195 2194 2943
-3 2531 2534 2535
-3 2532 2531 2536
-3 2536 2531 2535
-3 2536 2537 2532
-3 2538 2195 2943
-3 2946 2538 2943
-3 2196 2195 2538
-3 2948 2535 2534
-3 2536 2535 2948
-3 2949 2536 2948
-3 2537 2536 2949
-3 2946 2541 2538
-3 2538 2961 2196
-3 2540 2542 2539
-3 2539 2542 2543
-3 2541 2539 2543
-3 2541 2961 2538
-3 2961 2200 2196
-3 2544 2543 2542
-3 2955 2541 2544
-3 2544 2541 2543
-3 2961 2541 2955
-3 2545 2200 2961
-3 2200 2545 2204
-3 2545 2547 2548
-3 2551 2545 2548
-3 2204 2545 2551
-3 2206 2204 2551
-3 2209 2964 2962
-3 2546 2964 2549
-3 2548 2547 2551
-3 2551 2554 2206
-3 2554 2207 2206
-3 2964 2209 2549
-3 2551 2547 2552
-3 2553 2551 2552
-3 2554 2551 2553
-3 2977 2207 2554
-3 2550 2560 2547
-3 2552 2547 2560
-3 2553 2552 2555
-3 2554 2553 2556
-3 2556 2553 2555
-3 2557 2554 2556
-3 2977 2557 2207
-3 2555 2552 2561
-3 2561 2552 2560
-3 2556 2555 2562
-3 2562 2555 2561
-3 2557 2556 2563
-3 2563 2556 2562
-3 2558 2981 2564
-3 2558 2564 2565
-3 2568 2564 2981
-3 2565 2564 2566
-3 2566 2564 2568
-3 2561 2560 2571
-3 2562 2561 2571
-3 2981 3496 2567
-3 2981 2567 2568
-3 2994 2571 2560
-3 2569 2567 3496
-3 2568 2567 2570
-3 2570 2567 2569
-3 2572 2566 2568
-3 2570 2572 2568
-3 2212 2569 3496
-3 2570 2569 2572
-3 2572 2569 2212
-3 2574 2571 2573
-3 2571 2574 2562
-3 2212 3496 2217
-3 2212 2214 2572
-3 2997 2573 2571
-3 2217 3496 1936
-3 3004 2573 2997
-3 1262 4051 1663
-3 2572 1931 4052
-3 2574 2575 2221
-3 1931 1934 4052
-3 2575 2574 2223
-3 2575 2223 2221
-3 2576 2573 2578
-3 2574 2573 2576
-3 2223 2574 2577
-3 2577 2574 2576
-3 2223 2577 2227
-3 4052 1934 2587
-3 2582 2576 2578
-3 2577 2576 2582
-3 2577 2582 2227
-3 2580 2578 3004
-3 2582 2578 2581
-3 2581 2578 2580
-3 2579 2227 2582
-3 2581 2580 3010
-3 2582 2581 2583
-3 3010 2580 2585
-3 3010 2231 2583
-3 2582 2583 2231
-3 2580 2584 2585
-3 2585 2231 3010
-3 2586 2585 3014
-3 2231 2585 2586
-3 3026 2592 3014
-3 2586 3014 2592
-3 2589 2590 2591
-3 2588 2587 2600
-3 2589 2593 2594
-3 2590 2589 2594
-3 2591 2590 2597
-3 2599 2586 2592
-3 2586 2599 2249
-3 2600 2587 2606
-3 3533 2254 2593
-3 2594 2593 2596
-3 2596 2593 2254
-3 2590 2594 2597
-3 2597 2594 2596
-3 2595 2591 2598
-3 2610 2592 3527
-3 2592 2610 2604
-3 2599 2592 2604
-3 2601 2254 3533
-3 2254 2597 2596
-3 2591 2597 2607
-3 2598 2591 2608
-3 2602 2598 2608
-3 2608 2598 2602
-3 2603 2595 2598
-3 2249 2599 2605
-3 2599 2604 2605
-3 2588 2600 2618
-3 2618 2600 2606
-3 2607 2597 2254
-3 2591 2607 2608
-3 2603 2598 2609
-3 2609 2621 2603
-3 2604 2612 2613
-3 2604 2613 2605
-3 2614 2605 2613
-3 2615 2605 2614
-3 2606 2257 2617
-3 2617 2257 2616
-3 2618 2606 2617
-3 2620 2607 2254
-3 2608 2607 2259
-3 2259 2607 2620
-3 2609 2598 2608
-3 2622 2610 2611
-3 2604 2610 2623
-3 2623 2610 2622
-3 2624 2604 2623
-3 2612 2625 2613
-3 2613 2625 2626
-3 2614 2613 2626
-3 2615 2614 2627
-3 2627 2614 2626
-3 2617 2616 2628
-3 2618 2617 2631
-3 2631 2617 2628
-3 2644 2618 2631
-3 2601 2619 2265
-3 2259 2620 2254
-3 2272 2608 2259
-3 2260 2608 2272
-3 2621 2609 2608
-3 2629 2624 2623
-3 2267 2625 2633
-3 2626 2625 2269
-3 2269 2625 2267
-3 2261 2626 2269
-3 2627 2626 2261
-3 2615 2627 2261
-3 2257 2263 2616
-3 2628 2616 2630
-3 2630 2616 2263
-3 2631 2628 2630
-3 3055 2264 2271
-3 3587 3055 2271
-3 2260 2274 2608
-3 2640 2629 2623
-3 2635 2636 3073
-3 2637 2630 2263
-3 2631 2630 2637
-3 2644 2631 2637
-3 2264 3055 2279
-3 3587 2271 2278
-3 2639 2621 2608
-3 2632 2621 2639
-3 2645 2632 2639
-3 2623 2622 2640
-3 2634 2642 2641
-3 2634 2641 2633
-3 2633 2641 2267
-3 2635 2643 2636
-3 3073 2643 2635
-3 2263 2277 2637
-3 2645 2639 2608
-3 2637 2277 2648
-3 2644 2637 2648
-3 2646 2265 2619
-3 2645 2608 2658
-3 2645 2649 2651
-3 2647 2622 2652
-3 2640 2622 2647
-3 2641 2640 2650
-3 2267 2641 2650
-3 2658 2608 2274
-3 2650 2640 2653
-3 2267 2650 2653
-3 1697 2265 2646
-3 2649 2645 2658
-3 3110 2654 2652
-3 2640 2647 2652
-3 2659 2652 2654
-3 2640 2652 2659
-3 2653 2640 2659
-3 2653 2655 2280
-3 2651 2649 2658
-3 3110 2661 2654
-3 2655 2653 2659
-3 2280 2655 2283
-3 2655 2659 2656
-3 2657 2655 2656
-3 2283 2655 2657
-3 2648 1967 3095
-3 3106 2651 2658
-3 2660 2661 3110
-3 2284 2657 2656
-3 2283 2657 2284
-3 2675 3095 1967
-3 3634 2669 2294
-3 2288 2289 2658
-3 2654 2661 2659
-3 2284 2656 2659
-3 2668 2669 3121
-3 3106 2658 2289
-3 2670 3106 2289
-3 2659 2662 2284
-3 2659 2673 2662
-3 2663 2664 2665
-3 2663 2666 2667
-3 2665 2666 2663
-3 2681 2670 2289
-3 3144 2670 2671
-3 2672 2661 2660
-3 2683 2661 2672
-3 3162 2659 2661
-3 3163 2659 3162
-3 2659 3163 2673
-3 2674 2662 2673
-3 2685 2662 2674
-3 2290 2662 2685
-3 2686 2675 1967
-3 2668 3121 2688
-3 2676 3154 2669
-3 2676 2669 2668
-3 3154 2294 2669
-3 3154 2677 2294
-3 2677 2301 2294
-3 2678 2679 2680
-3 2671 2670 2691
-3 2691 2670 2681
-3 2682 2671 2691
-3 3144 2671 2682
-3 2692 3144 2682
-3 2673 3163 2684
-3 2674 2673 2684
-3 2685 2674 2684
-3 2300 2290 2685
-3 2675 2686 2687
-3 2698 2675 2687
-3 2689 2301 2677
-3 2690 2679 2678
-3 2680 2690 2678
-3 2299 2691 2289
-3 2691 2681 2289
-3 2692 2682 2701
-3 3169 2694 3137
-3 2705 3137 2694
-3 2683 2672 2696
-3 2696 2672 2695
-3 2697 2683 2696
-3 2683 2697 3162
-3 2697 2304 3162
-3 2684 3162 2304
-3 2685 2684 2304
-3 2698 2687 2686
-3 2307 3164 2676
-3 2689 3172 2301
-3 2719 2679 2690
-3 2699 2719 2690
-3 2680 2700 2690
-3 2700 2699 2690
-3 2682 2691 2711
-3 2701 2693 2692
-3 2703 3159 2702
-3 2694 3169 2715
-3 2705 2694 2725
-3 3179 2696 2695
-3 2309 2696 2328
-3 2697 2696 2309
-3 2304 2697 2309
-3 2331 2698 2686
-3 2706 2726 2340
-3 3164 2317 2707
-3 3164 2307 2317
-3 3164 2707 3172
-3 2312 2311 2708
-3 2719 2699 2709
-3 2700 2710 2699
-3 2710 2709 2699
-3 2710 2700 2720
-3 2314 2711 2691
-3 2701 2682 2711
-3 2712 2702 3159
-3 2722 2712 3159
-3 2703 2702 2713
-3 2713 2702 2712
-3 2704 2703 2713
-3 3167 3160 2714
-3 3167 2714 2724
-3 3169 3167 2724
-3 2715 3169 2724
-3 2328 2696 3179
-3 2707 2317 2716
-3 3172 2707 2717
-3 2717 2707 2716
-3 2717 2324 3172
-3 2319 3183 3184
-3 2319 3184 2708
-3 2319 2708 2311
-3 2718 2312 2708
-3 2312 2718 2320
-3 2710 2719 2709
-3 2720 2719 2710
-3 2314 2327 2711
-3 2701 2711 2327
-3 2693 2701 2721
-3 2722 2721 2712
-3 2712 2721 2732
-3 2713 2712 2732
-3 2723 2704 2713
-3 2723 2729 3176
-3 2714 3176 2729
-3 2694 2715 2725
-3 2340 2726 2730
-3 2317 2323 2716
-3 2324 2716 2323
-3 2717 2716 2324
-3 2319 2727 3183
-3 2731 2728 2727
-3 2325 2731 2727
-3 2325 2727 2319
-3 2718 2731 2325
-3 2718 2325 2320
-3 2721 2701 2327
-3 2714 2729 2734
-3 2715 2724 2733
-3 2336 2725 2715
-3 2328 2725 2336
-3 2723 2713 2732
-3 2729 2723 2732
-3 2724 2714 2733
-3 2732 2721 2334
-3 2334 2348 2732
-3 2740 2732 2739
-3 2729 2732 2740
-3 2734 2729 2740
-3 2714 2734 2733
-3 2715 2733 2356
-3 2735 3193 2736
-3 3193 2737 2736
-3 3171 2331 2738
-3 2340 2730 2347
-3 2739 2732 2348
-3 2741 2734 2740
-3 2356 2733 2734
-3 2350 2742 2346
-3 2743 2744 2742
-3 2353 2352 2745
-3 2354 2353 2745
-3 2736 2746 2735
-3 2747 2746 2736
-3 2737 2747 2736
-3 3201 2748 2749
-3 3201 2749 2738
-3 2750 2738 2749
-3 2751 2738 2750
-3 2369 3718 3731
-3 2730 3718 2369
-3 2740 2739 2370
-3 2356 2741 2740
-3 2734 2741 2356
-3 2350 2361 2752
-3 2350 2752 3203
-3 2350 3203 2742
-3 3203 2753 2742
-3 2743 2742 2754
-3 2754 2742 2753
-3 2744 2743 2755
-3 2755 2743 2754
-3 1524 4422 1519
-3 2352 2351 2745
-3 2354 2745 2351
-3 2757 2738 2756
-3 2758 2738 2757
-3 3201 2738 2758
-3 2750 2749 2748
-3 2751 2750 2368
-3 3198 2751 2368
-3 1531 3198 2368
-3 3731 3198 1531
-3 2369 3731 1301
-3 2752 2361 2759
-3 2361 2365 2759
-3 2753 2760 2365
-3 2759 2365 2760
-3 2754 2753 2365
-3 2755 2754 2365
-3 2756 2366 2761
-3 2367 2757 2761
-3 2757 2756 2761
-3 2758 2757 2367
-3 2368 2758 2367
-3 2758 2368 2762
-3 2748 2762 2368
-3 2750 2748 2368
-3 2374 2373 2763
-3 2374 2763 2375
-3 2373 2376 2763
-3 2375 2763 2376
-3 2767 3226 2377
-3 2377 3226 2378
-3 2768 2766 2770
-3 2769 2766 2768
-3 2771 2773 2772
-3 2380 2783 2767
-3 3226 2785 2378
-3 2768 2770 2775
-3 2766 2776 2770
-3 2776 2775 2770
-3 2776 2766 2777
-3 2778 2771 2772
-3 2382 2383 2779
-3 2382 2779 2773
-3 2773 2779 2772
-3 2773 2384 2382
-3 2773 2780 2384
-3 2773 2774 2780
-3 2780 2781 2384
-3 2384 2782 2386
-3 2781 2782 2384
-3 2783 2380 3236
-3 2380 2784 3236
-3 2380 2387 2784
-3 3240 2784 2387
-3 3240 2387 2785
-3 2785 2387 2388
-3 2785 2388 2378
-3 1697 4373 423
-3 3241 2775 2776
-3 2777 3241 2776
-3 2778 2787 3249
-3 2778 2772 2787
-3 2772 2779 2787
-3 2383 2390 2787
-3 2779 2383 2787
-3 2788 2781 2780
-3 3249 2788 2780
-3 2782 2781 2789
-3 2789 2781 2788
-3 2782 2789 2386
-3 2784 2790 3236
-3 3240 2790 2784
-3 2792 2791 2786
-3 2791 2797 2786
-3 2390 3249 2787
-3 2390 2393 3249
-3 3249 2391 2788
-3 3249 2393 2391
-3 2789 2788 2391
-3 2793 2795 2796
-3 2794 2795 2793
-3 2394 2797 2792
-3 2792 2797 2791
-3 2792 2798 2394
-3 2398 2394 2798
-3 2793 2796 2800
-3 2795 2801 2796
-3 2801 2800 2796
-3 2797 2836 3247
-3 2836 2797 2394
-3 2398 2802 2399
-3 2398 2798 2802
-3 2802 2803 2399
-3 2399 2803 2401
-3 2402 3259 2804
-3 2396 2799 2418
-3 2810 2811 2809
-3 2812 2793 2800
-3 2801 2405 2812
-3 2801 2812 2800
-3 2795 2406 2801
-3 2795 2407 2406
-3 2795 2844 2407
-3 2410 2803 2802
-3 2410 2802 2409
-3 2401 2803 2410
-3 2412 2813 2814
-3 2815 2804 2816
-3 2816 2804 2828
-3 2805 2414 2817
-3 2415 2414 2805
-3 2415 2805 2818
-3 2818 2805 2806
-3 2403 2417 2799
-3 2417 2820 2799
-3 2418 2799 2820
-3 2821 2418 2820
-3 2821 2822 2418
-3 2416 2418 2823
-3 2823 2418 2822
-3 2825 2809 2824
-3 2809 2811 2824
-3 2824 2811 2435
-3 2405 3290 2812
-3 2408 2836 2394
-3 2408 2409 2826
-3 2409 3281 2826
-3 2409 2802 3281
-3 2420 2437 2814
-3 2420 2814 2813
-3 2437 2827 2814
-3 2816 2827 2815
-3 2828 2827 2816
-3 2829 2830 2817
-3 2415 2831 2118
-3 2415 2818 2831
-3 2439 2819 2807
-3 3306 2439 2807
-3 3306 2807 2808
-3 2422 3299 2423
-3 2423 3299 2424
-3 2417 2430 2820
-3 2821 2430 2832
-3 2821 2820 2430
-3 2832 2430 2833
-3 2416 2823 2430
-3 2833 2430 2823
-3 2432 2822 2431
-3 2432 2823 2822
-3 2432 2833 2823
-3 2446 2431 3288
-3 2431 2822 3288
-3 3288 2834 2446
-3 2824 2434 2825
-3 3290 2405 2419
-3 2826 2836 2408
-3 2837 2836 2826
-3 3281 2837 2826
-3 2118 2830 2829
-3 2830 2118 2831
-3 2819 2438 2838
-3 2839 3299 2422
-3 2422 2440 2839
-3 2428 3309 2441
-3 2833 2445 2832
-3 3301 2111 2842
-3 3301 2434 2111
-3 2447 2842 2843
-3 2447 2835 2842
-3 2447 2435 2835
-3 3301 2842 2835
-3 2419 3302 3290
-3 3302 2419 2864
-3 2848 3314 2454
-3 3314 3322 2454
-3 2838 2853 3305
-3 2853 2838 2438
-3 2441 3309 2839
-3 3321 2449 1814
-3 3321 2450 2449
-3 2450 2108 2449
-3 2450 2840 2854
-3 2446 2834 2457
-3 2452 2842 2111
-3 2843 2842 2452
-3 2844 2848 2453
-3 2849 2848 2454
-3 2454 3322 2455
-3 2455 3322 2856
-3 2456 2455 2856
-3 2850 2464 2846
-3 2846 2845 2850
-3 2845 2851 2850
-3 2852 2845 2847
-3 2851 2845 2852
-3 1814 2121 3321
-3 3321 2121 2861
-3 2832 2445 3329
-3 3329 2445 1833
-3 2848 2855 2453
-3 2453 2855 2125
-3 2855 2848 3344
-3 2849 3344 2848
-3 2456 2856 2470
-3 2460 2461 2857
-3 2463 2858 2464
-3 2465 2850 2859
-3 2465 2464 2850
-3 2860 2859 2851
-3 2859 2850 2851
-3 2852 2860 2851
-3 2439 3306 2486
-3 2466 2861 2121
-3 2862 2861 2467
-3 2467 2861 2466
-3 2467 2854 2862
-3 2469 2855 2864
-3 2855 2469 2125
-3 2459 3330 2849
-3 2459 2856 3330
-3 2134 2856 2459
-3 2470 2856 2134
-3 2857 2472 2865
-3 2461 2472 2857
-3 2460 2866 2473
-3 2460 2857 2866
-3 2857 2865 2866
-3 2463 2475 2867
-3 2463 2867 2858
-3 2858 2867 3335
-3 2483 2465 2867
-3 3335 2867 2465
-3 2859 3335 2465
-3 2860 3335 2859
-3 2868 2485 2853
-3 1833 2476 3329
-3 2457 2863 2476
-3 2476 2863 3329
-3 2866 2865 2869
-3 2473 2869 2482
-3 2866 2869 2473
-3 2475 2483 2867
-3 2484 2485 2868
-3 2487 2869 2865
-3 2482 2869 2488
-3 2869 2487 2488
-3 2439 2486 2156
-3 2870 2872 2873
-3 2489 3889 2485
-3 2874 3360 3356
-3 2874 2875 2876
-3 3356 2875 2874
-3 2870 2877 2871
-3 2877 2878 2879
-3 2877 2870 2878
-3 2870 2873 2878
-3 3365 2873 2872
-3 2878 2873 3365
-3 2489 2158 3889
-3 2158 2486 3889
-3 2880 3360 2874
-3 2881 3360 2880
-3 2491 2880 2876
-3 2876 2880 2874
-3 2876 2885 2491
-3 2882 2879 2878
-3 3365 2883 2878
-3 2883 2882 2878
-3 2880 2491 2881
-3 2884 2493 2491
-3 2884 2491 2885
-3 2882 2886 3366
-3 2882 2883 2886
-3 2887 2886 2883
-3 2885 2888 2884
-3 2884 2888 2889
-3 2884 2889 2493
-3 2495 2494 2886
-3 2886 2494 3366
-3 2886 2887 2496
-3 2886 2496 2495
-3 2494 3369 3366
-3 2887 2498 2496
-3 2887 2883 2498
-3 2499 2888 2881
-3 2499 2889 2888
-3 2891 2890 2498
-3 2891 2498 2883
-3 2494 2892 3369
-3 2890 2893 2892
-3 2890 2892 2498
-3 2891 2893 2890
-3 3381 2894 2895
-3 2895 2894 2896
-3 2895 2897 3381
-3 2896 2897 2895
-3 3395 4422 1893
-3 1893 3404 3395
-3 2898 2902 3398
-3 2903 2898 3400
-3 2902 2898 2903
-3 3403 3404 1893
-3 2902 3410 3398
-3 2503 2901 2501
-3 2503 2905 2901
-3 2502 2901 2905
-3 2502 2905 3945
-3 2910 2906 2907
-3 2168 2910 2908
-3 3410 2168 2908
-3 2902 2168 3410
-3 2909 2902 2903
-3 2909 2504 2902
-3 2909 3414 2504
-3 2168 2902 2504
-3 2903 2505 2909
-3 2899 3418 2507
-3 2512 2905 2503
-3 2910 2911 2908
-3 2513 2504 3414
-3 2506 2912 2505
-3 2510 2912 2506
-3 2507 2913 2510
-3 2510 2913 2912
-3 2913 2507 3418
-3 2905 2512 2915
-3 3945 2914 2515
-3 2513 3421 2514
-3 3427 3403 2515
-3 3423 2514 3421
-3 3423 2915 2514
-3 2916 3426 2516
-3 2516 1226 3428
-3 2516 3426 2917
-3 2916 2516 3428
-3 2517 2918 2519
-3 2919 2918 2517
-3 2519 2918 2520
-3 2920 2919 2921
-3 2921 2919 1635
-3 2922 2923 3437
-3 2924 2925 2926
-3 2928 2926 2929
-3 2928 2927 2926
-3 2927 2924 2926
-3 2929 2930 2931
-3 2929 2926 2930
-3 2932 2930 2925
-3 2925 2930 2926
-3 2933 2931 2930
-3 2934 2931 2933
-3 2935 2930 2932
-3 2933 2930 2935
-3 2933 2936 2934
-3 2935 2936 2933
-3 2522 3450 2526
-3 2524 2527 2937
-3 2526 3450 2529
-3 3450 2938 2529
-3 2937 2530 2939
-3 2527 2530 2937
-3 2524 2940 2531
-3 2524 2937 2940
-3 2937 2939 2940
-3 2533 3456 2941
-3 2532 3456 2533
-3 2942 2533 2941
-3 2942 2943 2533
-3 2528 2529 2947
-3 2947 2529 2938
-3 2528 2939 2530
-3 2528 2944 2939
-3 2531 2944 2534
-3 2531 2940 2944
-3 2940 2939 2944
-3 2532 2537 3456
-3 3456 2537 2950
-3 2950 2945 2942
-3 2943 2942 2946
-3 2946 2942 2945
-3 2952 2528 2947
-3 2952 2948 2944
-3 2952 2944 2528
-3 2534 2944 2948
-3 2950 2537 2949
-3 2950 2949 2951
-3 2945 2950 2951
-3 2945 2951 2540
-3 2945 2540 2539
-3 2541 2945 2539
-3 2946 2945 2541
-3 3467 3470 2948
-3 2949 2948 2953
-3 2953 2948 3470
-3 2540 2953 2542
-3 2540 2951 2953
-3 2951 2949 2953
-3 3471 2953 3470
-3 2542 3471 2958
-3 2542 2953 3471
-3 2958 2544 2542
-3 2954 2956 2957
-3 3468 2954 2957
-3 2959 2544 2958
-3 2544 2959 2960
-3 2544 2960 2955
-3 2961 2955 2960
-3 2957 2956 2969
-3 2969 2956 2963
-3 3468 2957 2969
-3 2970 3468 2987
-3 2987 3468 2969
-3 2547 2961 2550
-3 2961 2960 2550
-3 2545 2961 2547
-3 2962 2964 2546
-3 3470 2970 2971
-3 2972 3470 2971
-3 2550 2960 2959
-3 2976 2550 2959
-3 3501 2967 2966
-3 3501 2966 2973
-3 2973 2966 2965
-3 2963 2968 2986
-3 2986 2968 2974
-3 2969 2963 2986
-3 2971 2970 2975
-3 2975 2972 2971
-3 2986 2974 2979
-3 2975 2970 2980
-3 2980 2970 2987
-3 2554 2557 2977
-3 2978 2973 2981
-3 2978 2981 2558
-3 2978 2558 2559
-3 2558 2978 2559
-3 2558 3501 2978
-3 3501 2973 2978
-3 2979 2982 2986
-3 2987 2969 2986
-3 2976 2985 2984
-3 2976 2984 2550
-3 2550 2984 2560
-3 2558 2565 3501
-3 2982 2990 2986
-3 2980 2987 2991
-3 2988 2983 2980
-3 2988 2980 2989
-3 2989 2980 2991
-3 2988 2989 3495
-3 2992 2985 3495
-3 2985 2992 2984
-3 2984 2992 2994
-3 2560 2984 2994
-3 2565 2566 3501
-3 2987 2986 2991
-3 2991 2986 2990
-3 3495 2989 2992
-3 2992 2989 2991
-3 2995 2991 2990
-3 2992 2991 3005
-3 3005 2991 2995
-3 2993 2992 3005
-3 2994 2992 2993
-3 2566 2572 3501
-3 2993 3005 2997
-3 2994 2993 2997
-3 2996 2995 3503
-3 3005 2995 2996
-3 2994 2997 2571
-3 2996 3503 2998
-3 3501 2572 4052
-3 3005 2996 2998
-3 2998 3503 2999
-3 3005 2998 2999
-3 2997 3005 3004
-3 3005 2999 3000
-3 3509 3001 3000
-3 3002 3000 3001
-3 3003 3000 3002
-3 3003 3002 3005
-3 3000 3003 3005
-3 3004 2578 2573
-3 3004 3005 2580
-3 3001 3006 3007
-3 3002 3001 3009
-3 3005 3002 3009
-3 3019 3005 3009
-3 2580 3005 3019
-3 2584 2580 3019
-3 2581 3010 2583
-3 3007 3008 3012
-3 3012 3008 3011
-3 3007 3012 3013
-3 3001 3007 3013
-3 3009 3001 3013
-3 2584 3019 3014
-3 2584 3014 2585
-3 3012 3011 3013
-3 3009 3013 3023
-3 3031 3009 3023
-3 3019 3009 3018
-3 3014 3019 3026
-3 3020 3016 3015
-3 3021 3016 3020
-3 3022 3015 3017
-3 3020 3015 3022
-3 2588 4052 2587
-3 3011 3008 3045
-3 3024 3009 3043
-3 3018 3009 3024
-3 3019 3018 3025
-3 3026 3019 3025
-3 3013 3011 3045
-3 3023 3013 3027
-3 3031 3023 3028
-3 3028 3023 3027
-3 3018 3024 3029
-3 3025 3018 3519
-3 2588 3532 4052
-3 2589 3521 3520
-3 2591 3521 2589
-3 2591 3030 3521
-3 3013 3045 3051
-3 3028 3027 3539
-3 3031 3028 3539
-3 3029 3024 3032
-3 3032 3024 3043
-3 3032 3018 3029
-3 3519 3018 3032
-3 3026 3025 2592
-3 3520 2593 2589
-3 3033 2593 3520
-3 2595 3030 2591
-3 2595 3529 3030
-3 3034 3529 2595
-3 3027 3013 3539
-3 3009 3031 3035
-3 3043 3009 3035
-3 3025 3527 2592
-3 3533 2593 3033
-3 2595 3037 3034
-3 2595 3535 3037
-3 3038 3535 2595
-3 3539 3013 3051
-3 3540 3032 3043
-3 2601 3533 3039
-3 2603 3038 2595
-3 2603 3040 3038
-3 3549 3044 3045
-3 3574 3539 3051
-3 3031 3539 3052
-3 3035 3031 3052
-3 3564 3540 3043
-3 3550 2611 3527
-3 3527 2611 2610
-3 2588 2618 3532
-3 3049 3532 2618
-3 2601 3039 2619
-3 2603 2621 3040
-3 3052 3539 3574
-3 3043 3035 3046
-3 2612 3047 3048
-3 2612 2604 3047
-3 3056 3040 2621
-3 3572 3050 3041
-3 3045 3044 3081
-3 3051 3045 3081
-3 3046 3035 3053
-3 3053 3035 3052
-3 3043 3046 3061
-3 3061 3046 3053
-3 3061 3564 3043
-3 3063 2611 3054
-3 2611 3063 2622
-3 2624 3066 2604
-3 3066 3047 2604
-3 2612 2633 2625
-3 2618 2644 3049
-3 3078 2619 3039
-3 3056 2621 2632
-3 3044 3549 3081
-3 3598 3574 3059
-3 3059 3574 3051
-3 3574 3599 3052
-3 3053 3052 3061
-3 3061 3052 3060
-3 3586 3062 3063
-3 3586 3063 3054
-3 2624 2629 3064
-3 3065 3066 3064
-3 3064 3066 2624
-3 3067 2612 3048
-3 3068 3067 3048
-3 2612 3067 2633
-3 3553 3049 3088
-3 2632 3069 3056
-3 3069 2632 3057
-3 2632 3058 3057
-3 2632 3074 3058
-3 3051 3081 3070
-3 3059 3051 3070
-3 3070 3598 3059
-3 3061 3060 3071
-3 3085 3063 3062
-3 2629 2640 3064
-3 3065 3064 3072
-3 3072 3064 2640
-3 3072 2634 3068
-3 3065 3072 3068
-3 2634 2633 3068
-3 3068 2633 3067
-3 2644 2638 3049
-3 3088 3049 2638
-3 2645 3074 2632
-3 3079 3074 2645
-3 3074 3079 3075
-3 3060 3052 3083
-3 3071 3060 3083
-3 3063 3085 2622
-3 3072 2640 2641
-3 2642 3072 2641
-3 2634 3072 2642
-3 2636 2643 3073
-3 2638 2644 3077
-3 3088 2638 3087
-3 3087 2638 3077
-3 3080 3075 3079
-3 3074 3075 3080
-3 3074 3080 3613
-3 3070 3081 3082
-3 3626 3070 3082
-3 3052 3609 3620
-3 3076 3071 3084
-3 3084 3071 3083
-3 3077 2648 3086
-3 2644 2648 3077
-3 3087 3077 3086
-3 2619 3078 2646
-3 3079 2645 2651
-3 3619 3630 3089
-3 3619 3089 3081
-3 3082 3081 3090
-3 3090 3081 3089
-3 3090 3626 3082
-3 3091 3620 3626
-3 3620 3091 3052
-3 3084 3083 3092
-3 3076 3084 3092
-3 3085 3076 3092
-3 2622 3092 2652
-3 3085 3092 2622
-3 3087 3086 3093
-3 3088 3087 3093
-3 3096 3079 2651
-3 3080 3079 3096
-3 3622 3080 3094
-3 3626 3090 3089
-3 3116 3091 3626
-3 2652 3092 3110
-3 3095 3086 2648
-3 3093 3086 3095
-3 3632 3088 3095
-3 3095 3088 3093
-3 4097 2646 3078
-3 3080 3096 3106
-3 3052 3091 3116
-3 3092 3083 3110
-3 3642 3632 3095
-3 1697 2646 4097
-3 3080 3101 3109
-3 3097 3080 3109
-3 3094 3080 3098
-3 3098 3080 3097
-3 3099 3647 3100
-3 3083 3052 3110
-3 3080 3106 3112
-3 3101 3080 3112
-3 3098 3097 3102
-3 3099 3646 3103
-3 3647 3099 3103
-3 3642 3095 3104
-3 3642 3104 3105
-3 2651 3106 3096
-3 3101 3112 3107
-3 3108 3101 3107
-3 3109 3101 3108
-3 3097 3109 3123
-3 3102 3097 3123
-3 3110 3052 3116
-3 2675 3104 3095
-3 3655 3121 3656
-3 3656 3121 3634
-3 2669 3634 3121
-3 3107 3112 3113
-3 3108 3107 3114
-3 3114 3107 3113
-3 3109 3108 3114
-3 3661 3657 3102
-3 3103 3646 3662
-3 3115 3654 3647
-3 3117 3118 3659
-3 3111 3117 3659
-3 3111 3119 3117
-3 3120 3119 3111
-3 2670 3122 3106
-3 3122 3112 3106
-3 3113 3112 3122
-3 3114 3113 3122
-3 3109 3114 3133
-3 3133 3114 3122
-3 3123 3109 3133
-3 3102 3123 3124
-3 3124 3661 3102
-3 3116 3664 3125
-3 3110 3116 3125
-3 2660 3110 3139
-3 3119 3118 3117
-3 3126 3118 3119
-3 3120 3126 3119
-3 3127 3126 3120
-3 3130 3132 3131
-3 3128 3132 3130
-3 3672 3104 2675
-3 2670 3144 3122
-3 3133 3122 3144
-3 3123 3133 3134
-3 3124 3123 3135
-3 3135 3123 3134
-3 3135 3661 3124
-3 3103 3662 3147
-3 3147 3662 3158
-3 3647 3103 3148
-3 3148 3103 3147
-3 3115 3647 3160
-3 3676 3115 3149
-3 3149 3115 3160
-3 3125 3136 3137
-3 3110 3125 3138
-3 3138 3125 3137
-3 3139 3110 3138
-3 3128 3140 3141
-3 3128 3130 3140
-3 2665 2664 3140
-3 2665 3140 3131
-3 3131 3140 3130
-3 3131 3132 3142
-3 3131 3142 2665
-3 2665 3142 2666
-3 3142 2667 2666
-3 3143 2667 3142
-3 3134 3133 3145
-3 3145 3133 3144
-3 3135 3134 3146
-3 3146 3134 3145
-3 3158 3661 3135
-3 3158 3135 3146
-3 3149 3150 3676
-3 3676 3150 3136
-3 3136 3150 3137
-3 3138 3137 3151
-3 3152 3138 3151
-3 3139 3690 2660
-3 2660 3690 2672
-3 2664 3141 3140
-3 2664 2663 3141
-3 2663 3153 3141
-3 2667 3153 2663
-3 3153 2667 3143
-3 3121 3682 2706
-3 2680 3155 3156
-3 2679 3155 2680
-3 2680 3156 3684
-3 2692 3157 3144
-3 3157 3145 3144
-3 3146 3145 3157
-3 3158 3146 3157
-3 3147 3158 3159
-3 3647 3148 3160
-3 3160 3148 3176
-3 3137 3150 3169
-3 2705 3151 3137
-3 3161 3152 3151
-3 3161 3151 2705
-3 3690 3170 2672
-3 3162 2661 2683
-3 2698 3672 2675
-3 3674 3672 3171
-3 3171 3672 2698
-3 3121 2706 2688
-3 2676 3164 3154
-3 2677 3154 2689
-3 2689 3154 3164
-3 3155 2679 3165
-3 2692 2693 3157
-3 3696 3157 2693
-3 3157 3166 3158
-3 3159 3158 3166
-3 2703 3147 3159
-3 2704 3147 2703
-3 2704 3148 3147
-3 3176 3148 2704
-3 3149 3160 3167
-3 3150 3149 3168
-3 3168 3149 3167
-3 3169 3150 3168
-3 2695 2672 3170
-3 2684 3163 3162
-3 3180 3681 3171
-3 2689 3164 3172
-3 2679 2719 3165
-3 2700 2680 3684
-3 3714 2700 3684
-3 3173 3696 2693
-3 3175 3174 3166
-3 3159 3166 3174
-3 3176 2704 2723
-3 3169 3168 3167
-3 3177 3161 2705
-3 3170 3177 3178
-3 2695 3170 3179
-3 3170 3178 3179
-3 2331 3171 2698
-3 3704 3180 3171
-3 2706 3682 2726
-3 2726 3682 3707
-3 3713 2720 3714
-3 2720 2700 3714
-3 3173 2693 3185
-3 2722 3174 3175
-3 3716 2722 3175
-3 3174 2722 3159
-3 2714 3160 3176
-3 2705 2725 3177
-3 3178 3177 3181
-3 3179 3178 3182
-3 3182 3178 3181
-3 3179 3182 2328
-3 2720 3726 2719
-3 3713 3726 2720
-3 2721 3185 2693
-3 3716 3185 2722
-3 3185 2721 2722
-3 3181 3177 2725
-3 3182 3181 2725
-3 2328 3182 2725
-3 2726 3707 3720
-3 3183 2727 3186
-3 2718 3189 2731
-3 2738 3704 3171
-3 3704 2738 3198
-3 2730 2726 3720
-3 3732 3187 3188
-3 3732 3186 3187
-3 3186 2727 3187
-3 2728 3187 2727
-3 2728 3189 3187
-3 2728 2731 3189
-3 3731 3717 3198
-3 3720 3718 2730
-3 1262 1519 4422
-3 2735 3191 3193
-3 3190 3191 2735
-3 3192 3193 3191
-3 2737 3194 3195
-3 2737 3193 3194
-3 3194 3196 3195
-3 3198 2738 2751
-3 2735 2746 3190
-3 2747 3190 2746
-3 3191 3190 2747
-3 3191 2747 3192
-3 2747 2737 3192
-3 3195 3199 2737
-3 3199 3192 2737
-3 3196 3199 3195
-3 3200 3199 3196
-3 3197 3200 3196
-3 2752 3202 3739
-3 2752 3739 3203
-3 2758 3204 3201
-3 3201 3204 2748
-3 3205 3202 3207
-3 3206 3202 3205
-3 2752 3207 3202
-3 2752 2759 3207
-3 2760 3203 3739
-3 3208 2760 3739
-3 3203 2760 2753
-3 2758 2762 3204
-3 2748 3204 2762
-3 3206 3205 3209
-3 3205 3210 3209
-3 3207 3211 3205
-3 3211 3210 3205
-3 2759 3211 3207
-3 2759 3213 3211
-3 2759 3208 3213
-3 3208 2759 2760
-3 3210 3212 3209
-3 3213 3212 3210
-3 3211 3213 3210
-3 3214 2764 2765
-3 3214 3750 2764
-3 3214 2773 3215
-3 3216 2773 3214
-3 2765 3216 3214
-3 2765 3217 3216
-3 2765 2764 3217
-3 3217 3218 3216
-3 3217 2764 3750
-3 2768 3219 2769
-3 2766 2769 3779
-3 2769 3219 3779
-3 3779 3220 2766
-3 3221 3223 3222
-3 3222 3223 3224
-3 2771 3771 3215
-3 2773 2771 3215
-3 3216 2774 2773
-3 3216 3218 2774
-3 2767 2783 3225
-3 3225 3226 2767
-3 2768 3227 3219
-3 3227 2768 2775
-3 3228 3229 2777
-3 3228 2777 3220
-3 3220 2777 2766
-3 3230 3231 3765
-3 3247 3221 3232
-3 3222 3233 3221
-3 3233 3232 3221
-3 3233 3222 3224
-3 2771 2778 3771
-3 2780 2774 3249
-3 3234 3235 3236
-3 3236 3235 2783
-3 3235 3237 2783
-3 3225 2783 3238
-3 3238 2783 3237
-3 3238 3239 3240
-3 3238 3240 3225
-3 3225 3240 3226
-3 2785 3226 3240
-3 3227 2775 3241
-3 3241 2777 3229
-3 3241 3229 3242
-3 3250 3242 3229
-3 3243 3231 3230
-3 3251 3231 3243
-3 3244 3245 3230
-3 3245 3243 3230
-3 2786 3247 3232
-3 2792 2786 3232
-3 2798 2792 3232
-3 2798 3232 3233
-3 2778 3249 3248
-3 3234 3819 3255
-3 3236 3819 3234
-3 3239 2790 3240
-3 3820 3227 3241
-3 3241 3242 3820
-3 3250 3820 3242
-3 3245 3252 3243
-3 3252 3251 3243
-3 3835 3245 3244
-3 3835 2795 3245
-3 2795 3252 3245
-3 3246 3247 3811
-3 2786 2797 3247
-3 3233 3812 2798
-3 2790 3819 3236
-3 2794 2793 3257
-3 2794 3257 3251
-3 2794 3251 3252
-3 3251 3257 3256
-3 2795 2794 3252
-3 3247 3271 3811
-3 2798 3812 3258
-3 2804 3259 3253
-3 3253 3260 2804
-3 3260 3253 3254
-3 3261 3263 3262
-3 3262 3263 3274
-3 3255 3265 3264
-3 3265 3255 3266
-3 3267 3268 3269
-3 3822 3268 3267
-3 3269 3833 2811
-3 3268 3833 3269
-3 2793 3834 3257
-3 2795 3835 3270
-3 2836 3271 3247
-3 3272 2798 3258
-3 2798 3272 2802
-3 2804 3260 3273
-3 2805 3285 3261
-3 2806 2805 3261
-3 3262 2806 3261
-3 2806 3262 3274
-3 3264 2807 3286
-3 2808 2807 3264
-3 2808 3264 3275
-3 3275 3264 3265
-3 3276 3265 3266
-3 3275 3265 3276
-3 2810 2809 3277
-3 2810 3277 3267
-3 2810 3267 3269
-3 2811 2810 3269
-3 3833 4338 2811
-3 3834 2812 3278
-3 3834 2793 2812
-3 3278 3279 3280
-3 3834 3278 3280
-3 3270 3280 3279
-3 2795 3270 2844
-3 2836 3293 3271
-3 3281 3272 3258
-3 3293 3281 3258
-3 3272 3281 2802
-3 2804 3282 3283
-3 2804 3283 2828
-3 3273 3282 2804
-3 2805 2817 3284
-3 2805 3284 3285
-3 2806 2831 2818
-3 2806 3274 2831
-3 3838 2831 3274
-3 3286 2807 2819
-3 3275 3298 2808
-3 3298 3275 3276
-3 3288 2822 3287
-3 2809 3289 3277
-3 2825 3289 2809
-3 2811 4338 2435
-3 4338 3301 2435
-3 3290 3278 2812
-3 3290 3279 3278
-3 3270 3279 3291
-3 3291 3279 3290
-3 3270 3291 2844
-3 2836 3292 3293
-3 3293 3292 3281
-3 2814 2827 3294
-3 2827 2828 3294
-3 3294 2828 3283
-3 2817 2830 3284
-3 3284 2830 2831
-3 3284 2831 3285
-3 3295 3297 2838
-3 3296 3297 3295
-3 2838 3297 2819
-3 2424 3299 3845
-3 3309 2428 3845
-3 2428 2424 3845
-3 2822 3300 3287
-3 2822 2821 3300
-3 2821 2832 3300
-3 3312 2834 3288
-3 3301 2825 2434
-3 2835 2435 3301
-3 3302 3291 3290
-3 3302 3313 3291
-3 3291 3313 2844
-3 2837 3292 2836
-3 3281 3292 2837
-3 3295 3303 3304
-3 3295 3305 3303
-3 2838 3305 3295
-3 3298 3306 2808
-3 3306 3298 3276
-3 3307 3308 3299
-3 3307 3299 2839
-3 2840 3310 2841
-3 3310 2840 2841
-3 3311 2840 3310
-3 2844 3313 3314
-3 2848 2844 3314
-3 2845 3315 3316
-3 2846 3315 2845
-3 2847 3316 3303
-3 2847 2845 3316
-3 3316 3304 3303
-3 3305 3317 3303
-3 3317 2847 3303
-3 3305 2853 3318
-3 3305 3318 3317
-3 3319 3308 3307
-3 3858 3308 3319
-3 2839 3320 3307
-3 3307 3320 3319
-3 3327 2839 3309
-3 2450 3321 2840
-3 2840 3321 3310
-3 2854 2840 3311
-3 2834 3312 2457
-3 2846 2464 3323
-3 2846 3323 3324
-3 2846 3324 3315
-3 2847 3856 3325
-3 2847 3325 2852
-3 3317 3856 2847
-3 3318 3856 3317
-3 3326 3856 3318
-3 3318 2853 3326
-3 3319 3867 3858
-3 3320 3867 3319
-3 3327 3320 2839
-3 3321 2861 3328
-3 2832 3329 3300
-3 3302 3347 3863
-3 3330 3864 3344
-3 3330 3331 3332
-3 3864 3330 3332
-3 3322 3332 3331
-3 3322 3331 3333
-3 2856 3322 3334
-3 3334 3322 3333
-3 2464 2858 3335
-3 2464 3335 3323
-3 3335 3336 3323
-3 2860 3866 3323
-3 2860 3323 3336
-3 3324 3323 3866
-3 3325 2860 2852
-3 3866 2860 3325
-3 2485 3326 2853
-3 2485 3337 3326
-3 3337 3857 3326
-3 3338 3857 3337
-3 3339 3306 3858
-3 2854 3340 2862
-3 3345 2854 3311
-3 3345 3340 2854
-3 2457 3312 2863
-3 2864 3341 3302
-3 3302 3341 3347
-3 3342 3341 2864
-3 2855 3343 2864
-3 2864 3343 3342
-3 2855 3344 3343
-3 3344 2849 3330
-3 2856 3331 3330
-3 3333 3331 2856
-3 3334 3333 2856
-3 2860 3336 3335
-3 3873 3338 3337
-3 2486 3306 3339
-3 3350 2861 2862
-3 2862 3340 3350
-3 3345 3350 3340
-3 3348 3341 3342
-3 3347 3341 3348
-3 2485 3873 3337
-3 3339 3349 2486
-3 3345 3880 3350
-3 3346 3880 3345
-3 3348 3353 3347
-3 3353 3352 3347
-3 3348 3358 3353
-3 3873 2485 3889
-3 3354 2486 3349
-3 3355 3351 3877
-3 3356 3355 3877
-3 2871 3358 2870
-3 2871 3353 3358
-3 3359 3358 3891
-3 3359 2872 3358
-3 2872 2870 3358
-3 2486 3354 3889
-3 3360 3351 3355
-3 3361 3351 3360
-3 3356 3360 3355
-3 3356 3362 2875
-3 3356 3357 3362
-3 2875 3362 2876
-3 2871 2877 3353
-3 2877 3891 3353
-3 2879 3363 3359
-3 2879 3359 3891
-3 2879 3891 2877
-3 2872 3363 3365
-3 3359 3363 2872
-3 2876 3362 2885
-3 3363 2882 3364
-3 2879 2882 3363
-3 3363 3364 3365
-3 3894 2881 2888
-3 3894 2888 3362
-3 3366 3364 2882
-3 3366 3365 3364
-3 3365 3367 2883
-3 3365 3366 3367
-3 2885 3362 2888
-3 3369 3368 3366
-3 3368 3367 3366
-3 3367 3368 2883
-3 2883 3370 2891
-3 2883 3368 3370
-3 3368 3369 3370
-3 2893 3369 2892
-3 3370 3369 2893
-3 2891 3370 2893
-3 3372 3373 3371
-3 3375 3372 3371
-3 2894 3375 3373
-3 3373 3375 3371
-3 2894 3374 3376
-3 2894 3373 3374
-3 2500 4373 3952
-3 3381 3372 3375
-3 3375 2894 3381
-3 3377 2894 3376
-3 2896 2894 3377
-3 2896 3377 2897
-3 3381 3382 3383
-3 3381 2897 3382
-3 3382 2897 3377
-3 3386 3385 3378
-3 3387 3386 3378
-3 3389 3379 3380
-3 3388 3379 3389
-3 3391 3390 3384
-3 3385 3391 3384
-3 3392 3391 3385
-3 3386 3393 3385
-3 3393 3392 3385
-3 3387 3394 3386
-3 3394 3393 3386
-3 3395 3394 3387
-3 3396 3379 3388
-3 3405 3379 3396
-3 3397 3388 3389
-3 3396 3388 3397
-3 2900 2500 3952
-3 3398 3399 2898
-3 3402 3401 3382
-3 3940 3390 3391
-3 3392 3393 3403
-3 3394 3404 3393
-3 3404 3403 3393
-3 3395 3404 3394
-3 3397 3405 3396
-3 3411 2900 3952
-3 3406 3399 3410
-3 3398 3410 3399
-3 2899 2904 3400
-3 2906 2900 3411
-3 3407 3406 3408
-3 3406 3409 3408
-3 3410 3409 3406
-3 3400 2904 2903
-3 3411 3408 2906
-3 2906 3408 2907
-3 2907 3408 3412
-3 3954 3408 3409
-3 2908 3954 3409
-3 2908 3409 3410
-3 3414 2909 3413
-3 2505 4514 2909
-3 2909 4514 3413
-3 3956 3951 3403
-3 3934 3403 3951
-3 2907 3412 3953
-3 2910 2907 3953
-3 2911 2910 3954
-3 2910 3953 3954
-3 3954 2908 2911
-3 2505 3416 4514
-3 2912 3415 3416
-3 2912 3416 2505
-3 2912 2913 3417
-3 3415 2912 3417
-3 3418 3422 3417
-3 3417 2913 3418
-3 3418 3943 3422
-3 2915 3945 2905
-3 3945 3955 2914
-3 3427 3956 3403
-3 3419 3416 3415
-3 3420 3416 3419
-3 3417 3421 3415
-3 3421 3419 3415
-3 3422 3421 3417
-3 3943 3423 3422
-3 3423 3943 3945
-3 3423 3945 2915
-3 3955 3424 2914
-3 3414 3959 2513
-3 3420 3419 2513
-3 3420 2513 3959
-3 3421 2513 3419
-3 3422 3423 3421
-3 3427 2515 2914
-3 3427 2914 3424
-3 2916 3962 3425
-3 3426 2916 3425
-3 4531 3965 1226
-3 3428 1226 3965
-3 3426 3425 2917
-3 1226 5643 4531
-3 3428 3965 3430
-3 3428 3430 3431
-3 3429 2916 3428
-3 3431 3429 3428
-3 3432 2918 3433
-3 3433 2918 2919
-3 3432 2520 2918
-3 2919 3435 3433
-3 3435 2919 2920
-3 3433 3434 3438
-3 3433 3435 3434
-3 2921 3436 2920
-3 2920 3436 3435
-3 2520 4582 2522
-3 3438 3434 3437
-3 3434 3435 3437
-3 3439 3437 3435
-3 3440 3439 3436
-3 3439 3435 3436
-3 3975 3436 2921
-3 1635 3975 2921
-3 3437 2923 3438
-3 3440 3437 3439
-3 3440 2922 3437
-3 1635 2180 3975
-3 2922 3441 2923
-3 3441 2922 3440
-3 2924 3978 2925
-3 3442 2925 3978
-3 3978 2927 3443
-3 3978 2924 2927
-3 3442 3978 3443
-3 3442 3443 2928
-3 3442 2928 2929
-3 2931 3442 2929
-3 2931 3444 3442
-3 2925 3442 2932
-3 2932 3442 3444
-3 2928 3443 2927
-3 3444 2934 3445
-3 2931 2934 3444
-3 2932 3445 2935
-3 3444 3445 2932
-3 2934 2936 3445
-3 2935 3445 2936
-3 2522 3995 3450
-3 4002 3446 3447
-3 3983 3447 3446
-3 3983 3448 3447
-3 3447 3449 4002
-3 3448 3449 3447
-3 3451 3452 3449
-3 3451 3453 3454
-3 3449 3453 3451
-3 3450 3459 2938
-3 3455 3450 3995
-3 3459 3450 3455
-3 2941 3456 4020
-3 4020 2942 2941
-3 3457 3451 3454
-3 2938 3459 2947
-3 4020 3456 2950
-3 2950 2942 4020
-3 3459 3460 2947
-3 2948 2952 3461
-3 3462 4024 4027
-3 3463 3464 4028
-3 2952 3463 3465
-3 2952 3460 3463
-3 2952 2947 3460
-3 3464 3463 3460
-3 2952 3465 3461
-3 3465 3466 3461
-3 2948 3461 3467
-3 3461 3466 3467
-3 3463 4028 3481
-3 3463 3481 2954
-3 3468 3463 2954
-3 3468 3465 3463
-3 3466 3465 3469
-3 3469 3465 3468
-3 3467 3466 3469
-3 3467 3469 3470
-3 2954 3481 2956
-3 2970 3469 3468
-3 3470 3469 2970
-3 3471 3473 2958
-3 2958 3474 2959
-3 3473 3474 2958
-3 3475 3476 3477
-3 3472 3496 3478
-3 3472 3478 3479
-3 3480 4033 3472
-3 3479 3480 3472
-3 2956 3481 2963
-3 3470 2972 3471
-3 2972 3473 3471
-3 3474 3473 3482
-3 3474 3482 2959
-3 3483 3476 3475
-3 3486 3476 3483
-3 3483 3475 3486
-3 3478 3496 2965
-3 3478 2965 2966
-3 2967 3478 2966
-3 2967 3484 3478
-3 3484 3479 3478
-3 4642 3480 3479
-3 3484 4642 3479
-3 3481 2968 2963
-3 3493 2968 3481
-3 3473 2972 3487
-3 3482 3473 3485
-3 3485 3473 3487
-3 2959 3485 2976
-3 3482 3485 2959
-3 2965 3496 2973
-3 2967 3501 3484
-3 3501 4642 3484
-3 2968 3493 2974
-3 2972 2975 3487
-3 3485 3487 3488
-3 3485 3488 2976
-3 2974 3493 2979
-3 2975 2980 2983
-3 3487 2975 2983
-3 2976 3488 3489
-3 3491 3492 3490
-3 2973 3496 2981
-3 2982 2979 3493
-3 3487 2983 3495
-3 3488 3487 2985
-3 2985 3487 3495
-3 3489 3488 2985
-3 2976 3489 2985
-3 3492 3494 3490
-3 3497 2982 3493
-3 2982 3497 2990
-3 3495 2983 2988
-3 3493 3502 3497
-3 2990 3497 3499
-3 3499 3497 3498
-3 2990 3499 3500
-3 3497 3502 3505
-3 3498 3497 3506
-3 3506 3497 3505
-3 3499 3498 3500
-3 3500 3498 3506
-3 2990 3500 3503
-3 2990 3503 2995
-3 3507 3504 3502
-3 3505 3502 3504
-3 3505 3504 3506
-3 3506 3504 3507
-3 3507 3508 3506
-3 3509 3506 3508
-3 3503 3500 2999
-3 3500 3506 2999
-3 3506 3509 3000
-3 2999 3506 3000
-3 3509 3510 3001
-3 3001 3510 3006
-3 3510 3007 3006
-3 1936 4702 3036
-3 3007 3510 3008
-3 3511 3518 3510
-3 3008 3510 3518
-3 3511 3513 3518
-3 3015 3016 3512
-3 3015 3512 3017
-3 3511 3514 3513
-3 3512 3021 3515
-3 3016 3021 3512
-3 3017 3515 3022
-3 3512 3515 3017
-3 3516 3513 3514
-3 3517 3516 3514
-3 3518 3513 3516
-3 3518 3045 3008
-3 3021 3020 3515
-3 3022 3515 3020
-3 3521 3030 3522
-3 3524 3523 3525
-3 3531 3516 3517
-3 3518 3516 3526
-3 3526 3516 3531
-3 3549 3518 3526
-3 3518 3549 3045
-3 3032 3527 3519
-3 3519 3527 3025
-3 3033 3520 3521
-3 3522 3543 3521
-3 3528 3543 3522
-3 3030 3528 3522
-3 3030 3529 3528
-3 3523 3524 3536
-3 3530 3525 3523
-3 3536 3530 3523
-3 3526 3531 3563
-3 3032 3540 3541
-3 3527 3032 3541
-3 3521 3577 3033
-3 3577 3533 3033
-3 3571 3528 3529
-3 3534 3571 3529
-3 3034 3037 3529
-3 3529 3037 3534
-3 3537 3530 3536
-3 3537 3536 3538
-3 3531 3537 3538
-3 3531 3538 3563
-3 3532 4063 3542
-3 3037 3544 3534
-3 3544 3556 3534
-3 3535 3544 3037
-3 3038 3544 3535
-3 3544 3038 3040
-3 3545 3042 3041
-3 3545 3041 3546
-3 3041 3547 3546
-3 3524 3548 3536
-3 3536 3548 3561
-3 3562 3536 3561
-3 3538 3536 3562
-3 3526 3563 3549
-3 3541 3540 3550
-3 3550 3540 3564
-3 3541 3550 3527
-3 4063 3049 3553
-3 4063 3532 3049
-3 4063 3553 3542
-3 3533 3554 3039
-3 3577 3554 3533
-3 3543 3555 3521
-3 3528 3570 3543
-3 3571 3570 3528
-3 3534 3556 3571
-3 3040 3557 3544
-3 3546 3559 3558
-3 3546 3558 3545
-3 3545 3558 3560
-3 3042 3560 3041
-3 3545 3560 3042
-3 3548 3547 3573
-3 3573 3547 3041
-3 3561 3548 3573
-3 3538 4069 3563
-3 2611 3550 3564
-3 3552 3565 5316
-3 3551 3565 3552
-3 3551 3047 3565
-3 3551 3048 3047
-3 3542 3553 3566
-3 3577 3576 3554
-3 3521 3579 3577
-3 3555 3567 3521
-3 3567 3579 3521
-3 3543 3568 3555
-3 3568 3567 3555
-3 3569 3568 3543
-3 3570 3569 3543
-3 3557 3556 3544
-3 3040 3056 3557
-3 3557 3056 3582
-3 3560 3558 3572
-3 3560 3572 3041
-3 3050 3573 3041
-3 3549 3563 3585
-3 3564 3061 3575
-3 2611 3575 3054
-3 3564 3575 2611
-3 3565 3066 5316
-3 3047 3066 3565
-3 3048 3551 3068
-3 3039 4081 3078
-3 4081 3039 4072
-3 3554 4074 3039
-3 4074 3554 3576
-3 3579 3578 3577
-3 3567 3580 3579
-3 3568 3580 3567
-3 3569 3581 3568
-3 3556 3582 3571
-3 3557 3582 3556
-3 3057 3589 3069
-3 3057 3058 3589
-3 3593 3558 3559
-3 3572 3558 3593
-3 3572 3583 3050
-3 3050 3583 3573
-3 3583 3561 3573
-3 3584 3561 3585
-3 3563 3584 3585
-3 3549 3585 3081
-3 3598 3599 3574
-3 3586 3054 3575
-3 5316 3066 3065
-3 3611 3566 3553
-3 3577 4074 3576
-3 4089 4074 3577
-3 3578 4089 3577
-3 3579 4089 3578
-3 3580 4089 3579
-3 3580 3568 4083
-3 3581 3588 3568
-3 3588 4083 3568
-3 3569 3588 3581
-3 3570 3588 3569
-3 3571 3604 3570
-3 3604 3588 3570
-3 3582 3604 3571
-3 3056 3589 3582
-3 3056 3069 3589
-3 3058 3590 3589
-3 3058 3591 3590
-3 3074 3591 3058
-3 3591 3074 3592
-3 3559 3594 3593
-3 3572 3593 3595
-3 3583 3572 3596
-3 3596 3572 3595
-3 3585 3561 3597
-3 3599 3609 3052
-3 3061 3071 3600
-3 3575 3061 3600
-3 3062 3601 3085
-3 3586 3601 3062
-3 3065 3602 5316
-3 3068 3602 3065
-3 3566 3611 3603
-3 3566 3603 3612
-3 3587 2279 3055
-3 3604 4083 3588
-3 3605 3604 3582
-3 4085 3582 3589
-3 3590 4085 3589
-3 3074 3606 3592
-3 3594 3606 3593
-3 3583 3596 3615
-3 3561 3583 3615
-3 3597 3561 3615
-3 3585 3597 3607
-3 3081 3585 3619
-3 3598 3070 3608
-3 3599 3598 3609
-3 3609 3598 3608
-3 3610 3600 3076
-3 3600 3071 3076
-3 3601 3076 3085
-3 3553 3088 3611
-3 3603 3611 3612
-3 5338 3587 2278
-3 3613 3606 3074
-3 3613 3593 3606
-3 3595 3593 3613
-3 3596 3595 3614
-3 3614 3595 3613
-3 3615 3596 3614
-3 3597 3615 3617
-3 3617 3615 3616
-3 3607 3597 3618
-3 3618 3597 3617
-3 3585 3607 3625
-3 3625 3607 3618
-3 3619 3585 3625
-3 3626 3608 3070
-3 3609 3608 3620
-3 3620 3608 3626
-3 3612 3611 3621
-3 3621 3611 3088
-3 3078 4081 4097
-3 3622 3613 3080
-3 3622 3614 3613
-3 3615 3614 3623
-3 3623 3614 3622
-3 3623 4697 3616
-3 3623 3616 3615
-3 3617 3616 4697
-3 3624 3617 4697
-3 3617 3624 3618
-3 3625 3618 3624
-3 3627 3612 3621
-3 4672 3612 3627
-3 3094 3644 3622
-3 3644 3623 3622
-3 3644 3636 3623
-3 3625 3624 3628
-3 3619 3625 3629
-3 3639 3619 3629
-3 3630 3619 3639
-3 3089 3631 3626
-3 3621 3088 3632
-3 3632 4116 3621
-3 4116 4117 3621
-3 3627 3621 3633
-3 3633 3621 4117
-3 3643 4672 3627
-3 3643 3627 3633
-3 2279 3635 3634
-3 4115 3637 3628
-3 3625 3628 3638
-3 3638 3628 3637
-3 3629 3625 3639
-3 3639 3625 3638
-3 3630 3639 3649
-3 3089 3630 3640
-3 3640 3630 3649
-3 3641 3089 3640
-3 3631 3089 3641
-3 3116 3626 3631
-3 4117 3643 3633
-3 3094 3098 3644
-3 3645 3636 3644
-3 3645 3644 3646
-3 3645 3646 4115
-3 3637 4115 3646
-3 3637 3646 3099
-3 3100 3637 3099
-3 3638 3637 3100
-3 3647 3638 3100
-3 3647 3639 3638
-3 3648 3639 3647
-3 3649 3639 3648
-3 3640 3649 3650
-3 3650 3641 3640
-3 3651 3116 3631
-3 3632 3642 3105
-3 4116 3632 3652
-3 3652 3632 3105
-3 3098 3102 3644
-3 3649 3648 3654
-3 3654 3648 3647
-3 3654 3650 3649
-3 4694 4168 3655
-3 3634 4694 3655
-3 3653 3634 3655
-3 3656 3653 3655
-3 3634 3653 3656
-3 3102 3657 3644
-3 3646 3644 3662
-3 3662 3644 3657
-3 3658 3650 3654
-3 3664 3116 3651
-3 3659 3660 3111
-3 3104 3672 3105
-3 3672 3652 3105
-3 3662 3657 3661
-3 3654 3115 3658
-3 3658 3115 3663
-3 3118 4162 3660
-3 3659 3118 3660
-3 3120 3665 3666
-3 3120 3111 3665
-3 4163 3652 3672
-3 3655 4168 3121
-3 3663 3115 3676
-3 3663 3676 3677
-3 3664 3668 3125
-3 3669 4162 3118
-3 3669 3118 3126
-3 3126 3127 3670
-3 3127 3120 3666
-3 3127 3666 3670
-3 3670 3666 3129
-3 3129 3665 3128
-3 3129 3666 3665
-3 3671 3128 3665
-3 3671 3132 3128
-3 4163 3672 3673
-3 4163 3674 3667
-3 3675 3667 3674
-3 4170 3667 3675
-3 3662 3661 3158
-3 3668 3677 3676
-3 3668 3676 3136
-3 3125 3668 3136
-3 3126 3678 3669
-3 3670 3678 3126
-3 3129 3678 3670
-3 3129 3128 3678
-3 3141 3679 3671
-3 3141 3671 3678
-3 3141 3678 3128
-3 3132 3671 3680
-3 3680 3671 3679
-3 3132 3143 3142
-3 3132 3680 3143
-3 3673 3672 3674
-3 4163 3673 3674
-3 3675 3674 3681
-3 3153 3679 3141
-3 3680 3679 3153
-3 3143 3680 3153
-3 3171 3681 3674
-3 3704 4170 3675
-3 3121 4168 3682
-3 3161 3688 3152
-3 3138 3152 3689
-3 3689 3152 3688
-3 3689 4189 3139
-3 3689 3139 3138
-3 3690 3139 4189
-3 3675 3681 3691
-3 3682 3706 3692
-3 3156 3165 3694
-3 3155 3165 3156
-3 4193 3684 3694
-3 3694 3684 3156
-3 4195 3684 4193
-3 3686 4196 3685
-3 3695 4196 3686
-3 3687 3695 3686
-3 3157 3696 3166
-3 3688 3161 3697
-3 3177 3170 4833
-3 4833 3170 3690
-3 3180 3691 3681
-3 3704 3691 3180
-3 3675 3691 3704
-3 3717 4180 3704
-3 3692 3706 3720
-3 3165 2719 3694
-3 4193 3694 2719
-3 3684 4195 3714
-3 3699 3700 3701
-3 3173 3701 3696
-3 3173 3699 3701
-3 3702 3175 3701
-3 3696 3701 3175
-3 3696 3175 3166
-3 3161 3703 3697
-3 3177 3703 3161
-3 3703 3177 4833
-3 3717 3704 3198
-3 3705 4180 3717
-3 3692 3720 3707
-3 3682 3692 3707
-3 3708 3710 3711
-3 3709 3710 3708
-3 3710 3712 3711
-3 4841 4193 2719
-3 3714 3727 3713
-3 3715 3700 3699
-3 3173 3185 3715
-3 3173 3715 3699
-3 4190 3705 3718
-3 3706 4190 3718
-3 3719 3706 3718
-3 3720 3706 3719
-3 3183 3721 3184
-3 3184 3728 2708
-3 3721 3728 3184
-3 2708 3728 2718
-3 3708 3722 3709
-3 3722 3723 3724
-3 3722 3708 3723
-3 3708 3711 3723
-3 3725 3711 3712
-3 3723 3711 3725
-3 4841 2719 3726
-3 3185 4211 3715
-3 4211 3185 3716
-3 3705 3717 3731
-3 3718 3705 3731
-3 3720 3719 3718
-3 3183 3186 3721
-3 3728 3189 2718
-3 3723 3729 3724
-3 3725 3729 3723
-3 4841 3726 4223
-3 3726 3713 4223
-3 3727 3730 3713
-3 3730 4223 3713
-3 3187 3189 3733
-3 3733 3189 3728
-3 3734 3186 3732
-3 3188 3734 3732
-3 3188 3735 3734
-3 3188 3187 3735
-3 3735 3187 3733
-3 3193 3192 3736
-3 3193 3737 3194
-3 3736 3737 3193
-3 3194 3738 3196
-3 3737 3738 3194
-3 3196 3738 3197
-3 3199 3736 3192
-3 3737 3736 3199
-3 3200 3737 3199
-3 3738 3737 3200
-3 3197 3738 3200
-3 3202 3206 4254
-3 3206 4253 4254
-3 3202 4254 3740
-3 3202 3740 3739
-3 3739 3740 3208
-3 4253 3206 3209
-3 3741 4253 3209
-3 3740 4254 3742
-3 3740 3742 3213
-3 3208 3740 3213
-3 3743 3744 3745
-3 3745 3746 3743
-3 3212 3747 3741
-3 3212 3741 3209
-3 3212 3213 3748
-3 3742 3748 3213
-3 3749 3750 3214
-3 3743 3746 3761
-3 3751 3752 3746
-3 3752 3761 3746
-3 3752 3753 3754
-3 3751 3753 3752
-3 3741 3755 3756
-3 3741 3747 3755
-3 3212 3757 3747
-3 3758 3748 4268
-3 3758 3757 3748
-3 3757 3212 3748
-3 3215 3749 3214
-3 3215 3759 3749
-3 3750 3749 3760
-3 3760 3749 3759
-3 3217 3760 3218
-3 3217 3750 3760
-3 3754 3762 3752
-3 3762 3761 3752
-3 3774 3754 3753
-3 3762 3754 3774
-3 3219 3778 3779
-3 3763 4266 4262
-3 4267 3764 4262
-3 3764 3763 4262
-3 3765 3764 4267
-3 3223 3221 3766
-3 3756 3755 3223
-3 3756 3223 3766
-3 3224 3223 3755
-3 3224 3755 3767
-3 3767 3755 3747
-3 3757 3768 3747
-3 3768 3767 3747
-3 3758 3769 3757
-3 3769 3768 3757
-3 3769 3770 3771
-3 3758 3770 3769
-3 3770 3772 3771
-3 3771 3772 3215
-3 3759 3215 3772
-3 3760 3759 2774
-3 3760 2774 3218
-3 3761 3762 3773
-3 3774 3775 3762
-3 3775 3773 3762
-3 3775 4277 3776
-3 3774 4277 3775
-3 3234 3777 3235
-3 3778 3219 3227
-3 3778 3227 4278
-3 3220 3779 3228
-3 3228 3779 4279
-3 4279 3229 3228
-3 3780 4266 3763
-3 3764 3781 3763
-3 3781 3780 3763
-3 3765 3231 3781
-3 3765 3781 3764
-3 3765 3796 3230
-3 3782 3783 3246
-3 3246 3783 3247
-3 3783 3766 3247
-3 3766 3221 3247
-3 3224 3767 3233
-3 3784 3768 3785
-3 3784 3767 3768
-3 3769 3785 3768
-3 3786 3785 3769
-3 3769 3771 3786
-3 3801 3786 3771
-3 3771 2778 3801
-3 4285 3249 2774
-3 3775 3790 3773
-3 3790 3789 3773
-3 3776 3790 3775
-3 3791 3776 4277
-3 3791 3790 3776
-3 3234 3255 3807
-3 3235 3777 3793
-3 3794 3237 3793
-3 3237 3235 3793
-3 3237 3239 3238
-3 3794 3239 3237
-3 4278 3227 3795
-3 3229 4279 3821
-3 3250 3229 3821
-3 3780 3781 4294
-3 3231 3251 4294
-3 3781 3231 4294
-3 3244 3230 3796
-3 4296 3783 3797
-3 3783 3782 3797
-3 3246 3797 3782
-3 3767 4297 3798
-3 3767 3798 3233
-3 3233 3798 3812
-3 3784 4297 3767
-3 3802 3801 2778
-3 2778 3248 3802
-3 3248 3249 4285
-3 3248 4285 3802
-3 3254 3803 3787
-3 3787 3260 3254
-3 3804 3787 3788
-3 3804 3260 3787
-3 3805 3790 3791
-3 3792 3805 3791
-3 3807 3255 3806
-3 3794 3819 2790
-3 3239 3794 2790
-3 3795 3227 3820
-3 4294 3251 3823
-3 3808 3835 3244
-3 3808 3244 3809
-3 3809 3244 3796
-3 3810 4296 3797
-3 3811 3810 3797
-3 3246 3811 3797
-3 3812 3813 4306
-3 3812 3798 3813
-3 3803 3254 3814
-3 3814 3254 3253
-3 4314 3260 3804
-3 3817 3831 3818
-3 3255 3264 3806
-3 3821 3820 3250
-3 3821 3822 3820
-3 3822 3833 3268
-3 3821 3833 3822
-3 3256 3823 3251
-3 3257 3824 3825
-3 3257 3825 3256
-3 3256 3825 3823
-3 3809 3825 3824
-3 3809 3824 3808
-3 3808 3824 3826
-3 3808 3826 3835
-3 3827 3810 3811
-3 3811 3271 3827
-3 3812 4306 3830
-3 3258 3830 3829
-3 3258 3812 3830
-3 4320 3253 3259
-3 3260 4314 3273
-3 3261 3815 3816
-3 3263 3261 3816
-3 3817 3263 3816
-3 3818 3263 3817
-3 3274 3263 3818
-3 3274 3818 3831
-3 3264 3286 3806
-3 3255 3819 3266
-3 3795 3820 3843
-3 3822 3267 3843
-3 3822 3843 3820
-3 3257 3834 3824
-3 3834 3826 3824
-3 3826 3834 3835
-3 3271 3836 3828
-3 3830 3836 3829
-3 3829 3836 3837
-3 3829 3837 3258
-3 3259 2814 4330
-3 4330 4320 3259
-3 3273 4314 4332
-3 3261 3285 3815
-3 3831 3838 3274
-3 3839 3831 3832
-3 3839 3840 3831
-3 3840 3838 3831
-3 3286 3842 3806
-3 3267 3277 3843
-3 3835 3834 3280
-3 3270 3835 3280
-3 3293 3836 3271
-3 3293 3837 3836
-3 3837 3293 3258
-3 2814 3294 4331
-3 2814 4331 4330
-3 3294 3283 3282
-3 3294 3282 4331
-3 4331 3282 4332
-3 4332 3282 3273
-3 3815 3285 4347
-3 4348 3838 4340
-3 3840 4340 3838
-3 3841 3296 4335
-3 3844 3297 3841
-3 3297 3296 3841
-3 3844 3286 2819
-3 3844 4342 3286
-3 4342 3842 3286
-3 3266 4336 3276
-3 3288 3287 4913
-3 3287 4337 4913
-3 3312 3288 4913
-3 3277 3846 3843
-3 3289 3846 3277
-3 4338 4345 3301
-3 3285 2831 4347
-3 4348 4347 2831
-3 3838 4348 2831
-3 3296 3295 4335
-3 3844 2819 3297
-3 3287 3300 3850
-3 3287 3850 4337
-3 2825 3846 3289
-3 2825 3301 3846
-3 3846 3301 4345
-3 3863 3847 3302
-3 3847 3853 3302
-3 3853 3313 3302
-3 3304 3856 4335
-3 3295 3304 4335
-3 3848 3306 4336
-3 4336 3306 3276
-3 3299 3308 3848
-3 3845 3299 3848
-3 3309 3845 4357
-3 3310 3849 3311
-3 3851 3847 3863
-3 3314 3313 4361
-3 3313 3853 4361
-3 3314 4361 4362
-3 3854 3314 4362
-3 3316 3315 3855
-3 3316 3855 3856
-3 3316 3856 3304
-3 3306 3848 3858
-3 3848 3308 3858
-3 3309 4357 3859
-3 3309 3859 3327
-3 3849 3321 3860
-3 3310 3321 3849
-3 3311 3849 3861
-3 3849 3860 3861
-3 3862 3852 3851
-3 3863 3862 3851
-3 3314 3854 3864
-3 3314 3865 3322
-3 3864 3865 3314
-3 3855 3324 3866
-3 3315 3324 3855
-3 3325 3856 3855
-3 3325 3855 3866
-3 3326 4364 3856
-3 3857 4364 3326
-3 3327 3867 3320
-3 3860 3328 3868
-3 3321 3328 3860
-3 3868 4374 3861
-3 3868 3861 3860
-3 3311 3861 4374
-3 3311 4374 3869
-3 3850 3300 3329
-3 3347 3862 3863
-3 3871 3343 3870
-3 3864 3870 3343
-3 3344 3864 3343
-3 3865 3864 3332
-3 3322 3865 3332
-3 3858 3867 3339
-3 3328 2861 3868
-3 2861 3874 3868
-3 3311 3869 3345
-3 3345 3872 3877
-3 3345 3869 3872
-3 3872 3876 3877
-3 2863 4378 3329
-3 4378 2863 3312
-3 3347 3878 3862
-3 3343 3871 3342
-3 3338 3873 3857
-3 3867 3879 3339
-3 2861 3350 3874
-3 3877 3875 3346
-3 3345 3877 3346
-3 3342 4399 3348
-3 4395 3857 3873
-3 4395 3349 3879
-3 3349 3339 3879
-3 3880 3874 3350
-3 3880 3346 3875
-3 3880 3875 3881
-3 3877 3351 3881
-3 3877 3881 3875
-3 3877 3876 3356
-3 3882 3352 3883
-3 3882 3878 3352
-3 3878 3347 3352
-3 3348 3883 3884
-3 3348 4399 3883
-3 3882 3883 4399
-3 3348 3884 3358
-3 3885 3887 3888
-3 3886 3887 3885
-3 3887 4407 3888
-3 3889 4395 3873
-3 3354 3349 3889
-3 3349 4395 3889
-3 3874 3880 3361
-3 3880 3881 3361
-3 3881 3351 3361
-3 3356 3876 3357
-3 3876 3362 3357
-3 3353 3883 3352
-3 3353 3890 3883
-3 3890 3884 3883
-3 3358 3884 3891
-3 3884 3890 3891
-3 3893 3885 3892
-3 3892 3888 4407
-3 3892 3885 3888
-3 3891 3890 3353
-3 3361 3360 3894
-3 2881 3894 3360
-3 3896 3895 3898
-3 3895 3899 3898
-3 3900 3899 3895
-3 3904 3903 3897
-3 3903 3910 3897
-3 3899 3905 3898
-3 3906 3905 3899
-3 3900 3906 3899
-3 3906 3900 3907
-3 3900 3901 3907
-3 3908 3901 3902
-3 3907 3901 3908
-3 3909 3905 3906
-3 3909 3898 3905
-3 3904 3910 3903
-3 3913 3373 3372
-3 3374 3911 3376
-3 3374 3913 3911
-3 3374 3373 3913
-3 3912 3914 3911
-3 3914 3376 3911
-3 3916 3913 3372
-3 3376 3914 4473
-3 3372 3381 3916
-3 3376 4473 4486
-3 3376 4486 3377
-3 3920 3921 3919
-3 3916 3381 3929
-3 3377 4486 3382
-3 3384 3918 3917
-3 3385 3384 3917
-3 3917 5068 3385
-3 4476 3378 3385
-3 3378 3926 3387
-3 3378 4476 3926
-3 3379 3922 3380
-3 3923 3920 3919
-3 3924 3920 3923
-3 3925 3919 3921
-3 3923 3919 3925
-3 3922 3379 3927
-3 3380 3927 3389
-3 3922 3927 3380
-3 3923 2899 3924
-3 3923 3925 3928
-3 3923 3928 2899
-3 3929 3381 3383
-3 3929 3383 3401
-3 3401 3383 3382
-3 4506 3402 3382
-3 3384 3390 3918
-3 3387 3926 3395
-3 3927 3405 3930
-3 3379 3405 3927
-3 3389 3930 3397
-3 3927 3930 3389
-3 2898 3399 3924
-3 3399 3935 3924
-3 3400 2898 3924
-3 3924 2899 3400
-3 2899 3928 3936
-3 4506 3932 3402
-3 4506 3939 3932
-3 3933 3390 3940
-3 3940 3391 3942
-3 3391 3392 3934
-3 3942 3391 3934
-3 3392 3403 3934
-3 3397 3930 3405
-3 3407 3935 3406
-3 3931 3935 3407
-3 3399 3406 3935
-3 3401 3402 3937
-3 3402 3932 3937
-3 3937 3932 3938
-3 3939 3938 3932
-3 3940 3939 3933
-3 3942 3941 3940
-3 3934 3951 3942
-3 3931 3408 3952
-3 3407 3408 3931
-3 3943 3418 2899
-3 3943 2899 3936
-3 3937 5130 3401
-3 5130 3937 3946
-3 3937 3938 3946
-3 3939 3947 3938
-3 3947 3946 3938
-3 3948 3947 3939
-3 3940 3949 3939
-3 3949 3948 3939
-3 3941 3950 3940
-3 3950 3949 3940
-3 3942 3951 3941
-3 3951 3950 3941
-3 3408 3411 3952
-3 3408 3953 3412
-3 3953 3408 3954
-3 3413 4514 4511
-3 3944 3945 3943
-3 5130 3946 3956
-3 3946 3947 3956
-3 3948 3956 3947
-3 3949 3956 3948
-3 3951 3956 3949
-3 3950 3951 3949
-3 3957 4511 4513
-3 3957 3414 4511
-3 3414 3413 4511
-3 3427 5130 3956
-3 3414 3957 3958
-3 3957 4513 3958
-3 3414 3958 3959
-3 4514 3416 3960
-3 3960 3416 3420
-3 3960 3420 3959
-3 3960 3959 3961
-3 3960 3961 4525
-3 3427 3964 5130
-3 2917 3425 3962
-3 3963 3959 3958
-3 3961 3959 3963
-3 4525 3961 3963
-3 3427 3424 3964
-3 3966 2916 3429
-3 3430 3965 4529
-3 3431 3430 3966
-3 3429 3431 3966
-3 3967 3969 3970
-3 3968 3967 3970
-3 4532 3968 3970
-3 3971 4532 3970
-3 3970 3969 4545
-3 4548 3971 3970
-3 2520 3432 4578
-3 3432 3972 4578
-3 3433 3972 3432
-3 3433 3438 3972
-3 2520 4578 4582
-3 3438 3973 3972
-3 3440 3436 4588
-3 4588 3436 3975
-3 3974 3973 2923
-3 3973 3438 2923
-3 3974 3440 4588
-3 4588 3975 3977
-3 2923 3441 3974
-3 3440 3974 3441
-3 3980 3977 3975
-3 3975 2180 3980
-3 3980 3979 3977
-3 4601 3980 2180
-3 4582 3986 2522
-3 3984 3981 3983
-3 3982 3983 3981
-3 3983 3982 4605
-3 3983 3985 3984
-3 3983 3446 3985
-3 3986 3987 2522
-3 3987 3995 2522
-3 3987 3986 3988
-3 3988 3986 3989
-3 3986 3990 3989
-3 3446 4002 3991
-3 3446 3991 3985
-3 3983 4605 3448
-3 4605 4611 3448
-3 2180 4051 5237
-3 3992 3993 3994
-3 3994 3993 4621
-3 3987 3996 3995
-3 3988 3997 3987
-3 3997 3996 3987
-3 3998 3989 3999
-3 3998 3997 3989
-3 3997 3988 3989
-3 3999 4000 4012
-3 3999 3989 4000
-3 4001 4000 3990
-3 3990 4000 3989
-3 4002 3449 4003
-3 4003 4004 4002
-3 4611 3449 3448
-3 4003 3449 4611
-3 3994 4006 4005
-3 3994 4005 3992
-3 3992 4005 4007
-3 3993 3992 4008
-3 4008 3992 4007
-3 4022 4621 3993
-3 4008 4022 3993
-3 4009 3995 3996
-3 4010 3997 4011
-3 4010 4009 3997
-3 4009 3996 3997
-3 3998 4011 3997
-3 4001 4012 4000
-3 4013 4002 3452
-3 4013 3991 4002
-3 3452 4002 3449
-3 4004 4014 4002
-3 3449 4002 4014
-3 3453 3449 4015
-3 3449 4014 4015
-3 4015 3454 3453
-3 4016 3454 4015
-3 4017 4005 4006
-3 4007 4005 4018
-3 4018 4005 4017
-3 4022 4008 4018
-3 4018 4008 4007
-3 4009 4019 3455
-3 3995 4009 3455
-3 4019 4009 4010
-3 3451 4013 3452
-3 3457 4631 3451
-3 3451 4631 4013
-3 4016 3457 3454
-3 4631 3457 4016
-3 4021 4006 4031
-3 4017 4006 4021
-3 4017 4021 3458
-3 4017 4022 4018
-3 3459 3455 4019
-3 3459 4019 4023
-3 4023 4019 3461
-3 3461 4019 4010
-3 4021 4031 4024
-3 3458 4021 4025
-3 4021 4024 4025
-3 3458 4025 4017
-3 4022 4017 4025
-3 4023 4026 3460
-3 3459 4023 3460
-3 3461 4026 4023
-3 4024 4031 4027
-3 3462 4025 4024
-3 3464 3460 4026
-3 3464 4026 4028
-3 4028 4026 4029
-3 3461 4030 4026
-3 4030 4029 4026
-3 4030 3461 4010
-3 3481 4028 4032
-3 4032 4028 4029
-3 4030 4032 4029
-3 4033 4031 3472
-3 4033 4027 4031
-3 3462 4027 4033
-3 3477 3476 4034
-3 3477 4034 3475
-3 3472 4031 3496
-3 4033 3480 4642
-3 3462 4033 4642
-3 3476 3486 4034
-3 3475 4034 3486
-3 3493 3481 4032
-3 3493 4032 4647
-3 4647 4032 4629
-3 4035 4036 4636
-3 4636 4037 4035
-3 4038 4039 4036
-3 4035 4038 4036
-3 4035 3490 4038
-3 4035 3491 3490
-3 3491 4040 3492
-3 3491 4037 4040
-3 3491 4035 4037
-3 4040 4638 3492
-3 4041 4039 4038
-3 3490 3494 4042
-3 3490 4042 4038
-3 4038 4042 4041
-3 3494 4043 4042
-3 3492 4043 3494
-3 3492 4044 4043
-3 4638 4044 3492
-3 4045 4039 4041
-3 4042 4046 4041
-3 4046 4045 4041
-3 4046 4042 4043
-3 4045 4047 4039
-3 4046 4047 4045
-3 4647 3502 3493
-3 3502 4647 3507
-3 4642 3501 5261
-3 3507 4647 4050
-3 4050 3508 3507
-3 3509 3508 4050
-3 3496 4702 1936
-3 5261 3501 4052
-3 3510 3509 4050
-3 4050 5269 3510
-3 3510 4053 3511
-3 3510 5269 4053
-3 3511 4053 3514
-3 4052 3532 5285
-3 3514 4054 3517
-3 4053 4054 3514
-3 4055 3524 3525
-3 4056 4055 3525
-3 3517 4054 3531
-3 5285 3532 4057
-3 4058 5285 4057
-3 4059 3524 4055
-3 3525 3530 4056
-3 4056 3530 4060
-3 4054 4061 3531
-3 3532 3542 4057
-3 4059 4066 3524
-3 3530 4062 4060
-3 3537 4062 3530
-3 4061 3537 3531
-3 4062 3537 4061
-3 3542 3566 4057
-3 4058 4057 3566
-3 3547 4065 3546
-3 3546 4065 4064
-3 3548 4066 3547
-3 3547 4066 4065
-3 4066 3548 3524
-3 4067 3551 3552
-3 3546 4064 3559
-3 3562 3561 4068
-3 3562 4069 3538
-3 4068 4069 3562
-3 4067 3552 5316
-3 4672 4058 3566
-3 4676 3559 4064
-3 4068 3584 4071
-3 3561 3584 4068
-3 3563 4069 4071
-3 4069 4068 4071
-3 3551 4070 3068
-3 4072 3039 4073
-3 3039 4074 4073
-3 3563 4071 3584
-3 3586 3575 4678
-3 4075 3586 4678
-3 4073 4082 4072
-3 4074 4082 4073
-3 4089 3580 4083
-3 4077 3559 4676
-3 4077 3594 3559
-3 4678 3575 3600
-3 4078 4678 3600
-3 3586 4075 3601
-3 4075 4079 3601
-3 5316 3602 4080
-3 4080 3602 4070
-3 4070 3602 3068
-3 3612 4672 3566
-3 3587 4076 5326
-3 4076 3587 5338
-3 4082 4081 4072
-3 4084 3604 3605
-3 4085 3590 3592
-3 3591 3592 3590
-3 3592 3606 4690
-3 3606 3594 4690
-3 4690 3594 4077
-3 3610 4087 4086
-3 3610 4086 4078
-3 3610 4078 3600
-3 3610 3076 4087
-3 4079 3076 3601
-3 4686 3076 4079
-3 5326 2279 3587
-3 4082 4097 4081
-3 4083 3604 4122
-3 3582 4108 3605
-3 3592 4099 4085
-3 4099 3592 4695
-3 4090 4078 4092
-3 4091 4078 4090
-3 4078 4086 4092
-3 4086 4093 4092
-3 4093 4087 4094
-3 4093 4086 4087
-3 3076 4094 4087
-3 3076 4686 4094
-3 4683 3634 3635
-3 3604 4105 4122
-3 4107 4105 3604
-3 4084 4107 3604
-3 4098 4107 4084
-3 3605 4098 4084
-3 4108 4098 3605
-3 4720 4108 3582
-3 3582 4085 4720
-3 4099 4720 4085
-3 3623 4100 4697
-3 3628 3624 4697
-3 4090 4101 4091
-3 4092 4101 4090
-3 4093 4101 4092
-3 4111 4095 4102
-3 4103 4095 4096
-3 4102 4095 4103
-3 4082 4112 4097
-3 4074 4112 4082
-3 4089 4104 4074
-3 4083 4122 4089
-3 4122 4121 4089
-3 4107 4106 4105
-3 4124 4107 4098
-3 4108 4124 4098
-3 4720 4099 4704
-3 4721 4099 4695
-3 3623 3636 4100
-3 4100 3636 4114
-3 4110 4111 4102
-3 4110 4102 4103
-3 4672 3643 4118
-3 4672 4118 4714
-3 3634 4683 4694
-3 4104 4112 4074
-3 4104 4089 4733
-3 4105 4746 4122
-3 4106 4746 4105
-3 4107 4123 4106
-3 4124 4123 4107
-3 4108 4141 4124
-3 4099 4721 4704
-3 4113 4114 3636
-3 4128 4115 3628
-3 4109 3631 3641
-3 4109 4725 3631
-3 4714 4118 4119
-3 4714 4119 4132
-3 1697 4097 4120
-3 4120 4097 4112
-3 4120 4104 4731
-3 4120 4112 4104
-3 4121 4733 4089
-3 4125 4734 4721
-3 4126 4114 4113
-3 4136 4114 4126
-3 3636 3645 4127
-3 3636 4127 4113
-3 4113 4127 4126
-3 4115 4128 3645
-3 4127 3645 4128
-3 3641 3650 4109
-3 4109 3650 5374
-3 4725 3651 3631
-3 4138 3651 4725
-3 4117 4116 3652
-3 3652 4129 4117
-3 4117 4130 3643
-3 4117 4129 4130
-3 3643 4130 4118
-3 4131 4132 4118
-3 4118 4132 4119
-3 5338 2278 3683
-3 1697 4120 4731
-3 4121 4134 4733
-3 4134 4133 4733
-3 4766 4134 4122
-3 4134 4121 4122
-3 4746 4106 4782
-3 4123 4782 4106
-3 4124 4135 4123
-3 4141 4135 4124
-3 4136 4126 4137
-3 4127 4137 4126
-3 4142 4127 4128
-3 4129 3652 4148
-3 4130 4129 4139
-3 4139 4129 4148
-3 4140 4130 4139
-3 4118 4130 4140
-3 4755 4118 4140
-3 4131 4118 4755
-3 4741 4132 4758
-3 4135 4141 4123
-3 4141 4782 4123
-3 4136 4137 4154
-3 4127 4142 4137
-3 4142 4154 4137
-3 3658 5374 3650
-3 3651 4138 3664
-3 4143 4147 4145
-3 4144 4147 4143
-3 4146 4145 4147
-3 3111 3660 4774
-3 4845 3036 4702
-3 4139 4148 4149
-3 4150 4140 4139
-3 4150 4139 4149
-3 4152 4153 4166
-3 1697 4731 4780
-3 4155 4154 4142
-3 4156 5374 3658
-3 3658 3663 4156
-3 4157 4144 4143
-3 4158 4144 4157
-3 4145 4159 4143
-3 4159 4157 4143
-3 4160 4159 4145
-3 4146 4160 4145
-3 4147 4161 4146
-3 4161 4160 4146
-3 3660 4162 4147
-3 4162 4161 4147
-3 3111 4774 4802
-3 3665 3111 4802
-3 3652 4163 4148
-3 4149 4148 4164
-3 4164 4148 4163
-3 4150 4149 3667
-3 3667 4149 4164
-3 4151 4150 3667
-3 4151 3667 4775
-3 3667 4171 4775
-3 4165 4166 4167
-3 4166 4165 4152
-3 3663 4806 4786
-3 3663 4786 4156
-3 3663 3677 4806
-3 3664 4806 3668
-3 3664 4138 4806
-3 4157 4800 4158
-3 4159 4800 4157
-3 4160 4800 4159
-3 4172 4800 4160
-3 4161 4172 4160
-3 4162 3669 4161
-3 3665 4802 3671
-3 3667 4164 4163
-3 3667 4170 4171
-3 4167 4171 4170
-3 4167 4170 4165
-3 4165 4170 4152
-3 4763 3682 4168
-3 3668 4806 3677
-3 3669 4172 4161
-3 3678 4172 3669
-3 3678 4801 4172
-3 4802 4801 3678
-3 3671 4802 3678
-3 4170 3704 4152
-3 4762 4152 3704
-3 4763 4184 3682
-3 4173 4174 4175
-3 4175 4176 4177
-3 4174 4176 4175
-3 4176 4178 4177
-3 3704 4180 4762
-3 4181 4182 4183
-3 3706 3682 4184
-3 4175 4174 4173
-3 4177 4174 4175
-3 1697 4780 4838
-3 4179 4185 3685
-3 3685 4185 3686
-3 4185 3687 3686
-3 4186 3687 4185
-3 4187 4815 4188
-3 4188 3689 3688
-3 4188 4815 3689
-3 3689 4815 4189
-3 4190 4181 4180
-3 4182 4181 4190
-3 4183 4182 4190
-3 4184 4183 4190
-3 3706 4184 4190
-3 4192 3693 4191
-3 4193 4194 4195
-3 3685 4196 4835
-3 3695 3687 4197
-3 3687 4186 4197
-3 4188 4198 4187
-3 3688 4198 4188
-3 3688 3697 4198
-3 3690 4189 4833
-3 4190 4180 3705
-3 3693 4199 4191
-3 4192 3698 3693
-3 4192 4199 3698
-3 3693 3698 4199
-3 4204 4194 4193
-3 4195 4194 4204
-3 4835 4196 4200
-3 3695 4200 4196
-3 4201 3701 4197
-3 4201 4202 3701
-3 4197 3701 3695
-3 3700 4200 3701
-3 3695 3701 4200
-3 3701 4202 3702
-3 3697 4832 4198
-3 3697 3703 4832
-3 4833 4832 3703
-3 3709 4203 3710
-3 3710 4203 3712
-3 4193 4841 4204
-3 4205 4195 4204
-3 3714 4195 4205
-3 3714 4205 4206
-3 4202 4207 4208
-3 4202 4201 4207
-3 4208 4207 3715
-3 4200 3700 4207
-3 3715 4207 3700
-3 3702 4202 4208
-3 3702 4208 4837
-3 3702 4837 3175
-3 4837 4208 4209
-3 4837 3716 3175
-3 3683 2278 4237
-3 3683 4237 4823
-3 3724 3709 3722
-3 3724 4210 3709
-3 4210 4203 3709
-3 3712 4210 3725
-3 4203 4210 3712
-3 4206 4846 3727
-3 4206 3727 3714
-3 4208 4211 4209
-3 4208 3715 4211
-3 4837 4211 3716
-3 3721 4212 5455
-3 3721 3186 4212
-3 3721 5455 4213
-3 4213 3728 3721
-3 4850 1697 4838
-3 3724 3729 4210
-3 3725 4210 3729
-3 4214 4215 4216
-3 4216 4217 4214
-3 4846 4229 3730
-3 3727 4846 3730
-3 4218 4219 4212
-3 4218 4212 3186
-3 3733 3728 4213
-3 4220 4215 4214
-3 4221 4215 4220
-3 4217 4222 4214
-3 4222 4220 4214
-3 4223 3730 4229
-3 4224 4219 4218
-3 4225 4219 4224
-3 3186 3734 4224
-3 4218 3186 4224
-3 3735 3733 4236
-3 4220 4226 4221
-3 4222 4226 4220
-3 4227 4226 4222
-3 4229 4228 4223
-3 4232 4245 4234
-3 4233 4245 4232
-3 4248 4225 4224
-3 4235 4225 4248
-3 3734 4236 4224
-3 4224 4236 4248
-3 3735 4236 3734
-3 4229 4238 4228
-3 4239 4229 4846
-3 4239 4238 4229
-3 4239 4231 4240
-3 4231 4230 4240
-3 4230 4241 4240
-3 4242 4230 4231
-3 4241 4230 4242
-3 4232 4244 4233
-3 4244 4232 4243
-3 4232 4234 4243
-3 4245 4243 4234
-3 4243 4246 4247
-3 4245 4246 4243
-3 4869 4228 4238
-3 4869 4238 4239
-3 4249 4239 4240
-3 4241 4249 4240
-3 4249 4241 4242
-3 4243 4250 4244
-3 4247 4250 4243
-3 4870 4239 4251
-3 4239 4249 4251
-3 4252 4251 4249
-3 4256 4249 4242
-3 4256 4252 4249
-3 4870 4255 4260
-3 4870 4251 4255
-3 4251 4252 4255
-3 4256 4255 4252
-3 3741 4257 4253
-3 4254 4257 3742
-3 4254 4253 4257
-3 3745 3744 4258
-3 4259 3745 4258
-3 4259 4871 3745
-3 4871 3746 3745
-3 4871 3751 3746
-3 4260 4255 4261
-3 4256 4261 4255
-3 4256 4262 4261
-3 4872 4257 3741
-3 4872 3742 4257
-3 4872 3748 3742
-3 3744 3743 4258
-3 3743 3761 4276
-3 3743 4276 4259
-3 3743 4259 4258
-3 4263 3751 4871
-3 3753 3751 4264
-3 3751 4263 4264
-3 4265 3753 4264
-3 1697 4850 4373
-3 4270 4260 4261
-3 4266 4270 4261
-3 4262 4266 4261
-3 3741 3756 4872
-3 4269 4268 3748
-3 4269 4272 4268
-3 4277 3774 4265
-3 4265 3774 3753
-3 4271 3765 4267
-3 4872 3756 3766
-3 3770 3758 4268
-3 4272 3770 4268
-3 3770 4272 3772
-3 3772 4272 4274
-3 4273 3759 4274
-3 3759 3772 4274
-3 4273 2774 3759
-3 4275 4276 3761
-3 3761 3773 4275
-3 3777 3234 4874
-3 4882 3777 4874
-3 3778 4279 3779
-3 4278 4279 3778
-3 4266 4293 4270
-3 4293 4266 3780
-3 3765 4280 3796
-3 4271 4280 3765
-3 4296 4281 3783
-3 3783 4281 3766
-3 3785 3786 4282
-3 3784 3785 4282
-3 4283 4284 4274
-3 4274 4284 4273
-3 4273 4284 4285
-3 2774 4273 4285
-3 3787 4299 4276
-3 3788 4275 4286
-3 3788 4276 4275
-3 3788 3787 4276
-3 3773 3789 4286
-3 4275 3773 4286
-3 4277 4302 3791
-3 3791 4302 3792
-3 3234 3807 4874
-3 3794 3793 3777
-3 3794 3777 4287
-3 4287 3777 4882
-3 4288 4289 4290
-3 4290 4886 4288
-3 4291 4279 4278
-3 4291 4278 3795
-3 4291 3795 4292
-3 3821 4279 4291
-3 4294 4884 3780
-3 3780 4884 4293
-3 4280 4884 4294
-3 4280 4294 4295
-3 4280 4295 3796
-3 4304 4281 4305
-3 4281 4296 4305
-3 4297 4309 3798
-3 3799 4297 3784
-3 3800 3799 3784
-3 3800 3784 4298
-3 4298 3784 4282
-3 3786 4298 4282
-3 3786 4885 4298
-3 4885 4311 4298
-3 4283 4885 3801
-3 4885 3786 3801
-3 3802 4283 3801
-3 4284 4283 3802
-3 4285 4284 3802
-3 3803 4299 3787
-3 3788 4286 3804
-3 3789 3804 4286
-3 3789 3790 4300
-3 3804 3789 4300
-3 3790 3805 4300
-3 4300 3805 4301
-3 4302 4301 3792
-3 4302 4303 4301
-3 4301 3805 3792
-3 4302 4893 4303
-3 3807 3806 4350
-3 3819 3794 4287
-3 3823 4295 4294
-3 3796 4295 3825
-3 3825 4295 3823
-3 3796 3825 3809
-3 4306 4307 4308
-3 4306 3813 4307
-3 4309 3813 3798
-3 3799 4319 4297
-3 4297 4319 4309
-3 3799 4310 4319
-3 3800 4310 3799
-3 3800 4311 4310
-3 3800 4298 4311
-3 3814 3253 4312
-3 3814 4312 4313
-3 3814 4313 3803
-3 3803 4313 4299
-3 4300 4314 3804
-3 4315 4314 4300
-3 4301 4315 4300
-3 4303 4315 4301
-3 3815 4315 4303
-3 3815 4303 3816
-3 4893 4316 4303
-3 3816 4303 4316
-3 3817 3816 4316
-3 4919 4317 3817
-3 3831 3817 4317
-3 3827 4308 4327
-3 3271 4308 3827
-3 3828 4306 4308
-3 3828 4308 3271
-3 4306 3836 3830
-3 4306 3828 3836
-3 4328 4309 4318
-3 4319 4318 4309
-3 3253 4320 4312
-3 4320 4321 4312
-3 4322 4313 4312
-3 4322 4312 4321
-3 3817 4316 4919
-3 3832 4324 4323
-3 3831 4324 3832
-3 3831 4317 4324
-3 4323 4324 4333
-3 4333 4325 4326
-3 4324 4325 4333
-3 3266 3819 4336
-3 4339 4304 4305
-3 4305 4296 4339
-3 3810 4339 4296
-3 3810 3827 4339
-3 4319 4328 4318
-3 4329 4328 4319
-3 4310 4329 4319
-3 4321 4320 4331
-3 4331 4320 4330
-3 4322 4321 4332
-3 4332 4321 4331
-3 4314 4906 4332
-3 4906 4322 4332
-3 3832 4323 3839
-3 3840 3839 4323
-3 3840 4323 4333
-3 4325 4334 4326
-3 4334 4333 4326
-3 3841 4335 4910
-3 4910 4911 3841
-3 3841 4911 3844
-3 4342 3844 4911
-3 3806 3842 4350
-3 4922 4913 4337
-3 3843 4344 3795
-3 3821 4338 3833
-3 4327 4339 3827
-3 4925 3815 4347
-3 3840 4333 4340
-3 4334 4341 4333
-3 4349 4341 4334
-3 3842 4342 4350
-3 4343 3795 4344
-3 3843 3846 4344
-3 4345 4338 4355
-3 4347 4348 4925
-3 4949 4348 4340
-3 4333 4949 4340
-3 4349 4333 4341
-3 4335 3856 4363
-3 4933 3312 4913
-3 4351 3795 4343
-3 4352 3795 4351
-3 4344 4351 4343
-3 3846 4353 4344
-3 4344 4353 4351
-3 3846 4345 4353
-3 4353 4345 4354
-3 4355 4356 4345
-3 4356 4354 4345
-3 4356 4346 3847
-3 4355 4346 4356
-3 3847 4346 3853
-3 3845 3848 4357
-3 4964 4337 3850
-3 4933 4379 3312
-3 4351 4353 4352
-3 4354 4358 4353
-3 4356 4359 4354
-3 4359 4358 4354
-3 3851 3852 4359
-3 3851 4359 4356
-3 3847 3851 4356
-3 4360 3853 4346
-3 4360 4368 3853
-3 4368 4361 3853
-3 4363 3856 4364
-3 4363 4364 4950
-3 4950 4364 4365
-3 4364 3857 4365
-3 3859 4357 4962
-3 4964 3850 4366
-3 4353 4380 4352
-3 4353 4358 4380
-3 4359 4367 4358
-3 4367 4380 4358
-3 3852 3862 4367
-3 4359 3852 4367
-3 4360 4382 4368
-3 4361 4368 4369
-3 4362 4361 3864
-3 3864 4361 4369
-3 4362 3864 3854
-3 3327 4372 3867
-3 3327 3859 4372
-3 3859 4962 4372
-3 4374 4375 3869
-3 4376 4377 3850
-3 4377 4366 3850
-3 3850 3329 4376
-3 4379 4378 3312
-3 4381 4380 4367
-3 3862 4381 4367
-3 4368 4382 4399
-3 3870 4399 3871
-3 3870 4369 4399
-3 4369 4368 4399
-3 3864 4369 3870
-3 4383 4371 4370
-3 4383 4370 4371
-3 4372 4384 3867
-3 3868 3874 4374
-3 4403 4385 4374
-3 4375 4374 4385
-3 4386 4375 4385
-3 3869 4375 4386
-3 3869 4386 3872
-3 3872 4386 4973
-3 3876 4387 4388
-3 3876 3872 4387
-3 3872 4973 4387
-3 4974 4376 4389
-3 4974 4388 4376
-3 4377 4376 4387
-3 4387 4376 4388
-3 3329 4389 4376
-3 4378 4389 3329
-3 4378 4390 4391
-3 4392 4378 4379
-3 4390 4378 4392
-3 3862 3878 4381
-3 3878 4382 4381
-3 3871 4399 3342
-3 4393 4383 4401
-3 4394 3857 4395
-3 4394 4395 4396
-3 4396 3879 3867
-3 4396 3867 4384
-3 3874 4403 4374
-3 3876 4388 4974
-3 4397 4391 4390
-3 4392 4398 4390
-3 4398 4397 4390
-3 4392 4416 4398
-3 3878 4399 4382
-3 4401 4402 4393
-3 4402 4400 4393
-3 4396 4395 3879
-3 4397 4404 4419
-3 4397 4398 4404
-3 4416 4404 4398
-3 3878 3882 4399
-3 4402 4405 4400
-3 4405 4402 4412
-3 3886 3885 4406
-3 3886 4407 3887
-3 4406 4407 3886
-3 4403 3874 3361
-3 4415 3362 4974
-3 3362 3876 4974
-3 4408 4419 4404
-3 4416 4409 4404
-3 4409 4408 4404
-3 4410 4400 4411
-3 4400 4405 4411
-3 4412 4413 4405
-3 4413 4411 4405
-3 4412 5012 4413
-3 4406 3893 4414
-3 3885 3893 4406
-3 4407 4414 3892
-3 4407 4406 4414
-3 4998 4990 4418
-3 3894 4415 3361
-3 3361 4415 4403
-3 3362 4415 3894
-3 3896 4416 3895
-3 3896 4409 4416
-3 3896 4408 4409
-3 4416 3900 3895
-3 4420 3900 4416
-3 4411 4417 4410
-3 3897 4417 4411
-3 3897 4411 4413
-3 4413 3904 3897
-3 4413 5021 3904
-3 4413 5012 5021
-3 3893 3892 4414
-3 4990 4425 4418
-3 3898 4419 4408
-3 3896 3898 4408
-3 3901 3900 5020
-3 3900 4420 5020
-3 5020 3902 3901
-3 4421 3902 5020
-3 3897 3910 4417
-3 4425 4424 4418
-3 4426 4427 4419
-3 4426 4419 3898
-3 3906 4428 4438
-3 3906 4439 4428
-3 3902 4421 3908
-3 4421 4429 3908
-3 3904 5021 5028
-3 4430 4431 4432
-3 4431 4433 4432
-3 4434 4423 4436
-3 4437 4424 4425
-3 5634 4426 4446
-3 3898 3909 4446
-3 4426 3898 4446
-3 3909 3906 4438
-3 3907 4449 4439
-3 3907 4439 3906
-3 3907 4440 4449
-3 3907 3908 4440
-3 3908 4429 4440
-3 3910 4441 4417
-3 5028 3910 3904
-3 4441 3910 5028
-3 4432 4442 4430
-3 4443 4442 4432
-3 4433 4443 4432
-3 4434 4444 4435
-3 4436 4444 4434
-3 4445 4437 4425
-3 4451 4445 4425
-3 3909 4447 4446
-3 4447 3909 4448
-3 3909 4438 4448
-3 4451 4450 4445
-3 4467 4451 4425
-3 4447 5634 4446
-3 3912 3911 5042
-3 3911 4452 5042
-3 4453 3912 5042
-3 4454 4456 4457
-3 4455 4456 4454
-3 4458 4445 4450
-3 4459 4445 4458
-3 4451 4460 4450
-3 4460 4458 4450
-3 4460 4451 4467
-3 3913 5075 3911
-3 3911 5075 4452
-3 3912 4453 3914
-3 4453 4473 3914
-3 4463 4455 4454
-3 4457 4464 4454
-3 4464 4463 4454
-3 4464 4457 4465
-3 4458 4466 4459
-3 4460 4466 4458
-3 4467 4466 4460
-3 4479 4461 4468
-3 4462 4469 4461
-3 4469 4468 4461
-3 4469 4462 4470
-3 4471 4472 3915
-3 3913 3916 5075
-3 3917 4474 4475
-3 4463 4476 5068
-3 4464 4477 4463
-3 4477 4476 4463
-3 4478 4464 4465
-3 4477 4464 4478
-3 4479 4468 4480
-3 4468 4469 4480
-3 4481 4469 4470
-3 4481 4482 4469
-3 4482 4480 4469
-3 4471 4482 4481
-3 4471 4483 4482
-3 3915 4483 4471
-3 4484 3915 4472
-3 4484 4472 4492
-3 3916 4485 4493
-3 3916 4493 5075
-3 4486 4473 4487
-3 3917 3918 4474
-3 3917 5067 5068
-3 3917 4475 5067
-3 5068 4476 3385
-3 3926 4476 4477
-3 5069 4477 4478
-3 4480 4488 4479
-3 3920 4488 4480
-3 3920 4480 4482
-3 3921 3920 4482
-3 3921 4482 4489
-3 4489 4482 4483
-3 4483 3915 4490
-3 4483 4490 4489
-3 3915 4484 4490
-3 4490 4484 4491
-3 4492 4491 4484
-3 3916 3929 4485
-3 4493 4485 4494
-3 4486 4493 4494
-3 4486 4494 3382
-3 3926 5069 5082
-3 4477 5069 3926
-3 3395 5088 4422
-3 4495 3924 4496
-3 4495 4488 3924
-3 4488 3920 3924
-3 4489 4495 3925
-3 4489 3925 3921
-3 3925 4495 4496
-3 4497 4489 4490
-3 4497 4490 4498
-3 4490 4491 4498
-3 4492 4498 4491
-3 4485 3929 4499
-3 4500 4501 4494
-3 4500 4494 4499
-3 4499 4494 4485
-3 4494 4502 3382
-3 4494 4501 4502
-3 4506 3382 4502
-3 4496 3924 4504
-3 4504 3924 4503
-3 3928 4504 5090
-3 3928 4496 4504
-3 3928 3925 4496
-3 3928 5090 3936
-3 4498 4505 4497
-3 5091 4498 4492
-3 4499 3929 3401
-3 4499 3401 4500
-3 3918 3390 4474
-3 4474 3390 5087
-3 3395 3926 5088
-3 5083 5095 3931
-3 3924 3935 4503
-3 3936 5090 4512
-3 4498 4507 4505
-3 5091 4507 4498
-3 4506 5094 3939
-3 3939 5094 5087
-3 3939 5087 3933
-3 3933 5087 3390
-3 3935 3931 5095
-3 3935 5095 5097
-3 5097 4503 3935
-3 5098 3944 4508
-3 5117 4500 3401
-3 5677 4237 2917
-3 4508 3943 3936
-3 3944 3943 4508
-3 3944 5104 4510
-3 3944 4510 3945
-3 3955 3945 4510
-3 3955 4510 4515
-3 3401 5130 5117
-3 3955 4515 5134
-3 4516 4517 5123
-3 3960 4518 4514
-3 3964 5129 5130
-3 4519 4517 4516
-3 4519 4516 4520
-3 4513 4521 3958
-3 4518 3960 4525
-3 3955 5134 3424
-3 3424 5134 4522
-3 5129 3964 4522
-3 4523 4519 4520
-3 4523 3966 4519
-3 3966 4523 2916
-3 4530 2916 4523
-3 4530 3962 2916
-3 3958 4521 3963
-3 4521 4524 3963
-3 4525 4524 4526
-3 4524 4525 3963
-3 4525 4526 4527
-3 3424 4522 3964
-3 4531 5643 5140
-3 4519 3966 4528
-3 3962 4530 2917
-3 5677 2917 4530
-3 4527 4524 4521
-3 4526 4524 4527
-3 3430 4529 4528
-3 4528 3966 3430
-3 4529 3965 4531
-3 3968 4536 3967
-3 4532 4533 3968
-3 3968 4533 4536
-3 4535 3969 3967
-3 4535 3967 4534
-3 4534 3967 4536
-3 4533 4532 4552
-3 4552 4532 3971
-3 4533 4552 4551
-3 4538 4537 4539
-3 4540 4541 5727
-3 5727 4541 4534
-3 4542 4534 4541
-3 4543 4534 4542
-3 4535 4534 4544
-3 4544 4534 4543
-3 3969 4535 4545
-3 4535 4544 4545
-3 4546 3970 4545
-3 4546 4547 3970
-3 3970 4547 4548
-3 4548 4560 3971
-3 4552 3971 4550
-3 4550 3971 4560
-3 4538 4554 4537
-3 4537 4554 4555
-3 4556 4537 4555
-3 4539 4537 4556
-3 5179 4541 4540
-3 5157 4541 5179
-3 4557 4541 5157
-3 4541 4557 4542
-3 4543 4542 4558
-3 4558 4542 4557
-3 4544 4543 4558
-3 4545 4544 4558
-3 4558 5159 4545
-3 4546 4545 5159
-3 4559 4548 4549
-3 4560 4548 4559
-3 4552 4550 4561
-3 4561 4550 4560
-3 4551 4552 4561
-3 4553 4551 4562
-3 4562 4551 4561
-3 4562 4563 4553
-3 4564 4565 4566
-3 5154 4556 4554
-3 4555 4554 4556
-3 4558 4557 5171
-3 5172 4558 5171
-3 4560 4559 4561
-3 4562 4561 4567
-3 4568 4562 4567
-3 4569 4563 4562
-3 4568 4569 4562
-3 5168 5177 4564
-3 5168 4570 5177
-3 4565 4564 5177
-3 4561 4559 4580
-3 4580 4567 4561
-3 4571 4568 4567
-3 4572 4573 4574
-3 4569 4568 4571
-3 4572 4574 4575
-3 4577 5174 4576
-3 4578 3972 4579
-3 5177 4570 5192
-3 4577 4576 4581
-3 4581 5187 4577
-3 5213 4579 4583
-3 5213 4582 4579
-3 4582 4578 4579
-3 3972 4583 4579
-3 3972 3974 4583
-3 3973 3974 3972
-3 4584 4586 4587
-3 4585 4584 4587
-3 4589 4590 4585
-3 4585 4590 4584
-3 4584 4590 4591
-3 4586 4584 4592
-3 4592 4584 4591
-3 4593 4587 4586
-3 4592 4593 4586
-3 3977 4600 4588
-3 4589 4594 3976
-3 3976 4595 4589
-3 4595 4590 4589
-3 4591 4590 4596
-3 4596 4590 4595
-3 4596 4592 4591
-3 4593 4592 4596
-3 4589 5235 4597
-3 4589 4597 4594
-3 4594 4597 4598
-3 3976 4594 4599
-3 4594 4598 4599
-3 3976 4599 4595
-3 4599 5238 4595
-3 5238 4596 4595
-3 4582 5213 5240
-3 4600 3977 3979
-3 3979 3980 4600
-3 4600 3980 4601
-3 4602 4597 5235
-3 4598 4597 4603
-3 4603 4597 4602
-3 4599 4598 5238
-3 5238 4598 4603
-3 4582 5240 3986
-3 4600 3981 4604
-3 4600 3982 3981
-3 3982 4600 4605
-3 4605 4600 4601
-3 5237 4605 4601
-3 5237 4601 2180
-3 4606 5235 4635
-3 5235 4606 4602
-3 4606 4603 4602
-3 5238 4603 4606
-3 4604 3984 4607
-3 3981 3984 4604
-3 4608 4604 4609
-3 4609 4604 4607
-3 4605 4608 4609
-3 5237 4608 4605
-3 4635 4610 4606
-3 4606 4610 4615
-3 3985 4607 3984
-3 4609 4607 4611
-3 4609 4611 4605
-3 4619 4612 5237
-3 4635 4613 4610
-3 4610 4613 4614
-3 4615 4610 4614
-3 5241 4606 4615
-3 4616 3986 5240
-3 4616 4617 3986
-3 3986 4617 3990
-3 3985 3991 4618
-3 4607 3985 4618
-3 4611 4607 4618
-3 4620 4612 4619
-3 5237 4051 4619
-3 4635 3994 4613
-3 4621 4613 3994
-3 4621 4614 4613
-3 4615 4614 5241
-3 5241 4614 4621
-3 4622 4616 5240
-3 4623 4616 4622
-3 3999 4623 3998
-3 3999 4617 4623
-3 4617 4616 4623
-3 4012 4617 3999
-3 4012 4624 4617
-3 3990 4617 4001
-3 4001 4617 4624
-3 3991 4625 4618
-3 4003 4625 4004
-3 4003 4611 4625
-3 4611 4618 4625
-3 4626 4627 4620
-3 4626 4619 4628
-3 4620 4619 4626
-3 4051 4628 4619
-3 4635 4006 3994
-3 4622 5240 4629
-3 4011 4629 4010
-3 4011 4622 4629
-3 4011 4623 4622
-3 3998 4623 4011
-3 4001 4624 4012
-3 4013 4625 3991
-3 4013 4630 4625
-3 4004 4625 4014
-3 4014 4625 4630
-3 4014 4631 4015
-3 4630 4631 4014
-3 4015 4631 4016
-3 4632 4627 4626
-3 4632 4626 4633
-3 4022 4642 4621
-3 4642 5241 4621
-3 4631 4630 4013
-3 4632 4634 4627
-3 4633 4634 4632
-3 4031 4006 4635
-3 4642 4022 4025
-3 4010 4629 4030
-3 4629 4032 4030
-3 4025 3462 4642
-3 4031 4635 3496
-3 4643 4647 4629
-3 4036 4039 5246
-3 4036 5246 4636
-3 5246 4637 4636
-3 4037 4638 4040
-3 4037 4636 4638
-3 4636 4637 4638
-3 5245 4637 5246
-3 4044 5245 4043
-3 4044 4637 5245
-3 4044 4638 4637
-3 4639 4046 5245
-3 4046 4043 5245
-3 4640 4039 4047
-3 4640 4641 4039
-3 4641 5246 4039
-3 4639 5249 4047
-3 4639 4047 4046
-3 4640 4047 5249
-3 4645 4644 4640
-3 4641 4640 4644
-3 5249 4645 4640
-3 4650 4644 4646
-3 4646 4644 4645
-3 4648 4649 4650
-3 4650 4646 4648
-3 4048 4651 4049
-3 4048 4652 4653
-3 4048 4049 4652
-3 4649 4653 4652
-3 4649 4648 4653
-3 4648 4656 4653
-3 4050 4647 4643
-3 4654 4655 4048
-3 4655 4651 4048
-3 4048 4653 4654
-3 4654 4653 4656
-3 4654 4657 4655
-3 4656 4657 4654
-3 5261 5256 4642
-3 4658 5261 4052
-3 5269 4050 5268
-3 5266 4659 4658
-3 4052 5266 4658
-3 4053 5269 5274
-3 5274 4660 4053
-3 4053 4660 4661
-3 4054 4053 4661
-3 4662 4660 5274
-3 4662 4661 4660
-3 4661 4061 4054
-3 4663 5285 4058
-3 4663 5292 5285
-3 4059 4055 4664
-3 4056 4060 4664
-3 4055 4056 4664
-3 4661 4662 4061
-3 4664 4665 4059
-3 4060 4062 4665
-3 4060 4665 4664
-3 4062 4061 4665
-3 4665 4061 4666
-3 4666 4061 4662
-3 5292 4663 4058
-3 4668 4064 4065
-3 4065 4066 4669
-3 4066 4059 4669
-3 4665 4670 4059
-3 5308 4670 4665
-3 5308 4665 4666
-3 5292 4058 4672
-3 4065 4669 4668
-3 4059 4670 4669
-3 4067 4671 5306
-3 5306 3551 4067
-3 5306 4070 3551
-3 4668 4673 4064
-3 4673 4676 4064
-3 4669 4674 4668
-3 4674 4673 4668
-3 4670 4677 4669
-3 4677 4674 4669
-3 4675 4677 4670
-3 4675 4670 5308
-3 4067 5316 4671
-3 5306 4679 4070
-3 4674 4677 4673
-3 5319 4677 4675
-3 4070 4679 5317
-3 4673 4077 4676
-3 4077 4673 4677
-3 4078 4680 4678
-3 4680 4681 4678
-3 4079 4678 4681
-3 4678 4079 4075
-3 5316 4080 5320
-3 4070 5317 5320
-3 4080 4070 5320
-3 4682 4683 4684
-3 5314 4682 4684
-3 4677 5327 4077
-3 4078 4685 4680
-3 4685 4686 4680
-3 4681 4680 4686
-3 4079 4681 4686
-3 4088 5320 4080
-3 5320 4088 4080
-3 4682 5324 4687
-3 4682 4687 4688
-3 4683 4682 4688
-3 5326 4076 5338
-3 4695 3592 4689
-3 3592 4690 4689
-3 4077 4696 4690
-3 4696 4077 5327
-3 4100 5327 5325
-3 5325 4697 4100
-3 4078 4091 4692
-3 4091 4691 4692
-3 4685 4078 4693
-3 4693 4078 4692
-3 4094 5331 4093
-3 4094 4685 5331
-3 4094 4686 4685
-3 4685 4693 5331
-3 4096 4095 5341
-3 4688 4687 4694
-3 4683 4688 4694
-3 4684 4683 3635
-3 4689 4722 4695
-3 3628 4697 4698
-3 4699 4091 4101
-3 4699 4700 4091
-3 4700 4691 4091
-3 4701 4699 4101
-3 4701 4101 5331
-3 4093 5331 4101
-3 4095 4111 5341
-3 5341 4103 4096
-3 5318 5298 4715
-3 4715 5298 4672
-3 5318 4715 4716
-3 4687 5324 4703
-3 4694 4687 4703
-3 4722 4721 4695
-3 4689 4705 4722
-3 4690 4706 4689
-3 4706 4690 4696
-3 3628 4698 4128
-3 4707 4708 4109
-3 4709 4700 4711
-3 4710 4700 4709
-3 4712 4699 4701
-3 4712 4711 4699
-3 4700 4699 4711
-3 4713 5341 4111
-3 4713 4110 5341
-3 4110 4103 5341
-3 4715 4672 4714
-3 4694 4703 4168
-3 4104 4733 4732
-3 4720 4719 4108
-3 4736 4722 4705
-3 4689 4723 4705
-3 4723 4736 4705
-3 4706 4723 4689
-3 4723 4706 4724
-3 4708 4725 4109
-3 4708 4726 4725
-3 4710 4709 4726
-3 4709 4727 4726
-3 4711 4728 4709
-3 4728 4727 4709
-3 4728 4711 4712
-3 4111 4110 4713
-3 4132 4741 4714
-3 4715 4714 4741
-3 4716 4715 4729
-3 4716 4729 4742
-3 4718 4717 4730
-3 4703 4718 4168
-3 4731 4104 4732
-3 4719 4141 4108
-3 4721 4734 4704
-3 4125 4721 4735
-3 4735 4721 4722
-3 4736 4785 4722
-3 4724 4738 4723
-3 4738 4737 4723
-3 4724 4749 4738
-3 4136 4750 4100
-3 4136 4100 4114
-3 4109 5374 4707
-3 4726 4752 4725
-3 4727 4739 4726
-3 4739 4752 4726
-3 4739 4728 4712
-3 4739 4727 4728
-3 4715 4741 4759
-3 4729 4715 4742
-3 4742 4715 4759
-3 4742 4761 4762
-3 4764 4730 4717
-3 4718 4730 4764
-3 4168 4718 4764
-3 4732 4745 4731
-3 4733 4745 4732
-3 4766 4122 4746
-3 4768 4719 4720
-3 4704 4769 4720
-3 4769 4768 4720
-3 4734 4769 4704
-3 4734 4125 4747
-3 4734 4747 4769
-3 4125 4735 4747
-3 4737 4738 4748
-3 4749 4748 4738
-3 4749 4750 4751
-3 4136 4751 4750
-3 4128 4771 4142
-3 4725 4752 4138
-3 4754 4755 4140
-3 4755 4756 4131
-3 4131 4756 4740
-3 4756 4757 4740
-3 4131 4776 4132
-3 4131 4740 4776
-3 4740 4757 4776
-3 4776 4758 4132
-3 4758 4777 4741
-3 4759 4741 4777
-3 4760 4742 4759
-3 4761 4742 4760
-3 4743 4763 4764
-3 4744 4743 4764
-3 4717 4744 4764
-3 5379 5338 3683
-3 4780 4731 4765
-3 4765 4731 4745
-3 4733 4780 4745
-3 4780 4765 4745
-3 4733 4133 4780
-3 4746 4781 4766
-3 4782 4169 4746
-3 4719 4767 4141
-3 4747 4770 4769
-3 4735 4770 4747
-3 4722 4785 4735
-3 4785 4770 4735
-3 4748 5372 4737
-3 4749 5372 4748
-3 5372 4749 4154
-3 4749 4751 4154
-3 4136 4154 4751
-3 4144 4772 4773
-3 4147 4144 4773
-3 4773 4753 4147
-3 4774 3660 4753
-3 3660 4147 4753
-3 4140 4150 4754
-3 4151 4754 4150
-3 4755 4754 4151
-3 4775 4755 4151
-3 4775 4756 4755
-3 4775 4757 4756
-3 4777 4758 4776
-3 4759 4778 4779
-3 4153 4779 4166
-3 4153 4760 4779
-3 4760 4759 4779
-3 4152 4760 4153
-3 4152 4762 4760
-3 4762 4761 4760
-3 4168 4764 4763
-3 4133 4134 4780
-3 4746 4169 4781
-3 4767 4783 4141
-3 4719 4784 4767
-3 4784 4783 4767
-3 4768 4784 4719
-3 5369 4784 4768
-3 5369 4768 4769
-3 4770 4798 4769
-3 4155 4771 4154
-3 4142 4771 4155
-3 4786 5394 5374
-3 4786 5374 4156
-3 4787 4788 4158
-3 5385 4788 4787
-3 4158 4788 4772
-3 4158 4772 4144
-3 4753 4789 4774
-3 4790 4775 4171
-3 4166 4779 4778
-3 4166 4778 4167
-3 4167 4778 4791
-3 4792 5354 4180
-3 4794 5354 4792
-3 4793 4794 4792
-3 4763 4794 4795
-3 4134 4803 4780
-3 4796 4803 4134
-3 4766 4796 4134
-3 4781 4796 4766
-3 4169 4796 4781
-3 6695 4169 4782
-3 6695 4782 4141
-3 4783 6695 4141
-3 4783 4784 4797
-3 5369 4804 4784
-3 4804 4797 4784
-3 4805 4804 5369
-3 5388 4798 4770
-3 4785 5388 4770
-3 4799 5385 4787
-3 4158 4800 4787
-3 4800 4799 4787
-3 4774 4789 4801
-3 4802 4774 4801
-3 4791 4171 4167
-3 4181 4792 4180
-3 4794 4793 4184
-3 4795 4794 4184
-3 5379 3683 4823
-3 4812 4803 4796
-3 4797 4804 4783
-3 4786 4806 5394
-3 4807 4816 5385
-3 5385 4799 4807
-3 4799 4808 4807
-3 4800 4809 4799
-3 4809 4808 4799
-3 4810 4809 4800
-3 4810 4800 4172
-3 4801 4789 4172
-3 4181 4183 4792
-3 4183 4793 4792
-3 4184 4793 4183
-3 4763 4795 4184
-3 4174 4811 4176
-3 4176 4811 4178
-3 4838 4780 4803
-3 4812 4838 4803
-3 3685 4813 4179
-3 4814 4179 4813
-3 5406 5394 4806
-3 4808 4817 4807
-3 4817 4816 4807
-3 4820 4817 4809
-3 4817 4808 4809
-3 4810 4820 4809
-3 4811 4174 4177
-3 4178 4811 4177
-3 3685 4818 4813
-3 4179 4814 4825
-3 4185 4825 4186
-3 4185 4179 4825
-3 4815 4827 4819
-3 4815 4187 4827
-3 4816 4189 4815
-3 4820 4189 4816
-3 4817 4820 4816
-3 4822 4192 4191
-3 4812 4824 4838
-3 3685 4835 4818
-3 4819 4826 5433
-3 4827 4826 4819
-3 4187 4198 4827
-3 4189 4820 4833
-3 4191 4199 4821
-3 4822 4199 4192
-3 4835 5430 4818
-3 4207 4186 4825
-3 4836 4207 4825
-3 4197 4207 4201
-3 4186 4207 4197
-3 5433 4829 5439
-3 5433 4826 4829
-3 4827 4830 4826
-3 4830 4829 4826
-3 4198 4831 4827
-3 4827 4831 4830
-3 4832 4831 4198
-3 5434 4838 4824
-3 5434 4824 4828
-3 4204 4834 4205
-3 4834 4206 4205
-3 4200 5437 4835
-3 4200 4836 5437
-3 4836 4200 4207
-3 4830 5439 4829
-3 4831 5439 4830
-3 4832 5439 4831
-3 4834 4841 4839
-3 4204 4841 4834
-3 4839 4206 4834
-3 4209 4211 4837
-3 4422 6658 1262
-3 4215 5445 4216
-3 5445 4217 4216
-3 4840 4217 5445
-3 4219 4849 6840
-3 5455 4212 4219
-3 5455 4219 6840
-3 4213 5455 3733
-3 4215 4221 5445
-3 5445 4221 5448
-3 4217 4840 4842
-3 4842 4222 4217
-3 5449 4222 4842
-3 4225 4849 4219
-3 3733 5455 4236
-3 4226 5448 4221
-3 4227 5449 4226
-3 4226 5449 5448
-3 5449 4227 4222
-3 4843 4841 4869
-3 4841 4223 4869
-3 4846 5462 4231
-3 4233 4848 4245
-3 4847 4848 4233
-3 4225 4235 4849
-3 4236 5455 4856
-3 4231 4239 4846
-3 4231 5462 4242
-3 5462 4859 4242
-3 4233 4244 4847
-3 4244 4851 4847
-3 4851 4848 4847
-3 4245 4848 4851
-3 4246 4245 4852
-3 4247 5468 4853
-3 4247 4246 5468
-3 4246 4852 5468
-3 5468 4854 4853
-3 4864 6882 4849
-3 4235 4248 4855
-3 4235 4855 4849
-3 4855 4248 4856
-3 4856 4248 4236
-3 4223 4228 4869
-3 4859 4256 4242
-3 4244 4250 4851
-3 4250 5468 4851
-3 4853 4250 4247
-3 4853 4854 4250
-3 4854 5468 4250
-3 4860 4861 4862
-3 4861 4863 4862
-3 4855 4864 4849
-3 4865 4858 4857
-3 4867 4857 4858
-3 4867 4866 4857
-3 4866 4865 4857
-3 4869 4239 4870
-3 4859 5482 4256
-3 4868 4860 4862
-3 4863 4868 4862
-3 4867 4865 4866
-3 5481 4870 4260
-3 4262 4256 5482
-3 4259 4276 4871
-3 4276 4873 4871
-3 4263 4871 4873
-3 4263 4265 4264
-3 4873 4265 4263
-3 5481 4260 4270
-3 5481 4270 5483
-3 4262 5482 5484
-3 4267 5484 4875
-3 4267 4262 5484
-3 3748 4872 4269
-3 4872 4876 4269
-3 4265 4881 4277
-3 4265 4873 4881
-3 4270 4879 5483
-3 5484 4879 4878
-3 5484 4878 4875
-3 4875 4878 4880
-3 4267 4880 4271
-3 4875 4880 4267
-3 5489 4876 3766
-3 4876 4872 3766
-3 4876 5491 4269
-3 4272 4269 5491
-3 4272 5491 4274
-3 4873 4276 5504
-3 4277 4881 5493
-3 4302 4277 5495
-3 4277 5493 5495
-3 5506 4874 3807
-3 4290 4883 5497
-3 5497 5486 4290
-3 4270 4293 4879
-3 4293 4878 4879
-3 4880 4878 4884
-3 4884 4878 4293
-3 4271 4884 4280
-3 4880 4884 4271
-3 4281 4898 5489
-3 3766 4281 5489
-3 4283 5491 4885
-3 4274 5491 4283
-3 4276 4299 4892
-3 4892 5504 4276
-3 3807 4894 5506
-3 3807 4350 4894
-3 4290 4289 4883
-3 4886 4290 5486
-3 5498 4887 5486
-3 4887 4886 5486
-3 5498 5507 4887
-3 4281 4304 4898
-3 4885 5491 4311
-3 4888 5518 4890
-3 4889 5518 4888
-3 4890 5518 4891
-3 4893 5495 5519
-3 4302 5495 4893
-3 4287 4882 3819
-3 4288 4895 4289
-3 4886 4895 4288
-3 4896 4895 4886
-3 4887 4912 4886
-3 4897 4887 5507
-3 4897 4912 4887
-3 4291 4292 5522
-3 3821 4291 5522
-3 3813 4899 4307
-3 4307 4899 4308
-3 4309 4899 3813
-3 4309 4900 4901
-3 4309 4901 4899
-3 4901 4900 4902
-3 4311 5491 5503
-3 4311 5503 4310
-3 4310 5503 5526
-3 4888 4903 4889
-3 4890 4903 4888
-3 4904 4903 4890
-3 4891 4904 4890
-3 4905 4904 4891
-3 5518 4905 4891
-3 4299 4313 4906
-3 4892 4299 4906
-3 5519 4892 4906
-3 4315 5519 4314
-3 5519 4315 4893
-3 3815 4893 4315
-3 3815 4907 4893
-3 4316 4893 4907
-3 4325 4921 4909
-3 5505 4911 4910
-3 5528 4911 5505
-3 4894 4350 5544
-3 4963 4877 4237
-3 4896 4886 4912
-3 4897 4913 4912
-3 4355 3821 5522
-3 4898 4914 5525
-3 5531 4327 4308
-3 4900 4328 4915
-3 4309 4328 4900
-3 4916 4902 4900
-3 4916 4900 4917
-3 4917 4900 4915
-3 4917 5526 4916
-3 4917 4310 5526
-3 4313 4322 4906
-3 4906 4314 5519
-3 3815 4918 4907
-3 4918 4316 4907
-3 4316 4918 4919
-3 4908 4317 4920
-3 4920 4317 4919
-3 4926 4921 4908
-3 4926 4908 4920
-3 4317 4908 4921
-3 4317 4921 4324
-3 4921 4325 4324
-3 4927 4325 4909
-3 4909 4910 4927
-3 4928 4927 4910
-3 5528 5532 4911
-3 4882 4336 3819
-3 4913 4922 4912
-3 4914 4898 4935
-3 4304 4924 4898
-3 4924 4935 4898
-3 4936 4924 4304
-3 4936 4304 4339
-3 5531 5550 4327
-3 4329 4915 4328
-3 4917 4915 4329
-3 4310 4917 4329
-3 4918 3815 4925
-3 4919 4918 4925
-3 4925 4926 4920
-3 4925 4920 4919
-3 4325 4927 4334
-3 4910 4335 4928
-3 4342 4911 4929
-3 4929 4911 5532
-3 4930 4931 5548
-3 5548 4932 4930
-3 4913 4923 4933
-3 3795 4952 4292
-3 4338 3821 4355
-3 4935 4924 4934
-3 4936 4934 4924
-3 4339 4937 4936
-3 4339 4938 4937
-3 4339 4327 5550
-3 5541 4925 4348
-3 4334 4927 4349
-3 4335 4363 4928
-3 4939 5554 4940
-3 4929 5532 4342
-3 4940 4941 4939
-3 4342 5544 4350
-3 4342 5532 5544
-3 4962 4336 4882
-3 3848 4336 4962
-3 4942 4931 4930
-3 4943 4931 4942
-3 4944 4930 4932
-3 4942 4930 4944
-3 4945 4922 4337
-3 4954 4935 4934
-3 4936 4946 4934
-3 4946 4954 4934
-3 4946 4936 4937
-3 4339 4947 4938
-3 5550 4947 4339
-3 4348 4948 5541
-3 4948 4348 4949
-3 4949 4333 4349
-3 4950 5553 4960
-3 5553 4950 5564
-3 4940 5554 4951
-3 4941 4940 4951
-3 4942 4944 4943
-3 3795 4352 4952
-3 4946 4955 4954
-3 4955 4946 5573
-3 4948 4959 4956
-3 4948 4949 4959
-3 4349 4959 4949
-3 4928 4363 4960
-3 4960 4363 4950
-3 4961 5564 4950
-3 3848 4962 4357
-3 4964 4945 4337
-3 4360 4346 4953
-3 5572 4954 4957
-3 4955 4958 4954
-3 4958 4957 4954
-3 4958 4955 5573
-3 4961 4950 4365
-3 4966 4945 4964
-3 4933 5592 4379
-3 4380 4952 4352
-3 4360 4953 4382
-3 4371 5577 4957
-3 4371 4957 4958
-3 4957 5577 5572
-3 4958 5573 4371
-3 5573 5577 4371
-3 4965 4961 4365
-3 3857 4965 4365
-3 4962 4971 4372
-3 4966 4964 4973
-3 4964 4967 4973
-3 4366 4377 4967
-3 4964 4366 4967
-3 4381 4952 4380
-3 4382 4953 4381
-3 4371 4383 5577
-3 5577 4383 5582
-3 4371 5577 4383
-3 5577 5582 4383
-3 4981 4968 4965
-3 3857 4981 4965
-3 3857 4394 4981
-3 4969 4970 4384
-3 4969 4384 4372
-3 4971 4969 4372
-3 4971 4972 4969
-3 4973 4385 4403
-3 4973 4386 4385
-3 4967 4387 4973
-3 4377 4387 4967
-3 5590 4974 4389
-3 4389 4975 5590
-3 4378 4975 4389
-3 4379 5592 4392
-3 5592 4985 4392
-3 4383 4393 5582
-3 5582 4393 5605
-3 4383 5582 4401
-3 5582 4986 4401
-3 4968 4978 4976
-3 4979 4978 4968
-3 4993 4968 4980
-3 4993 4979 4968
-3 4981 4980 4968
-3 4394 4396 4981
-3 4969 4994 4970
-3 4994 4969 4982
-3 4969 4972 4982
-3 4983 4972 4971
-3 4983 4984 4972
-3 4984 4982 4972
-3 4975 4378 4391
-3 4975 4391 5597
-3 5597 4391 4397
-3 4985 4416 4392
-3 4393 4400 5605
-3 4986 4402 4401
-3 5599 4402 4986
-3 4987 4988 4989
-3 4989 5600 4987
-3 4990 4977 4976
-3 4991 4990 4976
-3 4978 4992 4976
-3 4992 4991 4976
-3 4979 4992 4978
-3 4984 4995 4982
-3 4995 4994 4982
-3 5603 4984 4983
-3 4995 4984 5603
-3 5597 4397 4419
-3 5009 5597 4419
-3 4402 5599 4412
-3 4987 4997 4988
-3 5600 4997 4987
-3 4977 4990 4998
-3 4991 4999 4990
-3 4992 5000 4991
-3 5000 4999 4991
-3 5007 4979 4993
-3 5007 5000 4979
-3 5000 4992 4979
-3 4994 4995 5008
-3 5008 4995 5603
-3 4974 5590 4415
-3 5613 4416 4985
-3 4410 5605 4400
-3 4410 5001 5002
-3 4410 5002 5605
-3 4412 5001 5003
-3 4412 5599 5001
-3 5002 5001 5599
-3 4412 5003 5012
-3 5006 4996 5606
-3 5006 5005 4996
-3 5005 5004 4996
-3 4998 4418 4977
-3 5000 5007 4999
-3 4415 7464 4403
-3 5009 5010 5011
-3 4416 5010 5017
-3 4416 5613 5010
-3 5011 5010 5613
-3 4416 5017 4420
-3 4410 4417 5001
-3 4417 5012 5001
-3 5012 5003 5001
-3 5005 5013 5004
-3 5014 5013 5005
-3 5006 5014 5005
-3 4977 5015 5016
-3 4977 4418 5015
-3 4999 5007 4425
-3 4990 4999 4425
-3 4419 5025 5009
-3 5025 5010 5009
-3 5017 5010 5025
-3 4420 5017 5018
-3 5018 5019 4420
-3 5019 5020 4420
-3 5012 4417 5021
-3 5015 4434 5016
-3 5015 4423 4434
-3 4423 5015 5022
-3 5022 5015 4418
-3 4418 4424 5022
-3 5023 4427 4426
-3 5023 5024 4427
-3 4419 4427 5024
-3 4419 5024 5025
-3 4428 5025 4438
-3 4428 5018 5025
-3 5018 5017 5025
-3 4439 5018 4428
-3 4439 5026 5018
-3 5026 5019 5018
-3 5020 5019 5027
-3 5027 5019 5026
-3 4421 5027 4429
-3 5020 5027 4421
-3 5028 5021 4417
-3 4431 4430 5029
-3 5029 5030 4431
-3 4431 5030 4433
-3 5016 4434 5031
-3 5031 4434 4435
-3 5022 4436 4423
-3 5022 5033 4436
-3 5033 5032 4436
-3 4424 5033 5022
-3 4424 4437 5033
-3 4437 5034 5033
-3 5007 5628 4425
-3 5023 4426 5634
-3 5025 5024 4448
-3 4438 5025 4448
-3 4449 5026 4439
-3 4449 5027 5026
-3 4429 5027 4440
-3 4417 4441 5028
-3 4430 4442 5029
-3 4443 5029 4442
-3 5030 5029 4443
-3 4433 5030 4443
-3 4435 5035 5031
-3 4444 5035 4435
-3 4436 5032 4444
-3 4444 5032 5035
-3 4437 4445 5034
-3 5034 4445 5036
-3 4440 5027 4449
-3 4467 4425 5628
-3 5037 4447 4448
-3 5634 4447 5037
-3 5038 5046 5045
-3 5047 5046 5038
-3 4456 4455 5047
-3 4445 4459 5036
-3 4467 5036 4459
-3 5048 5041 5040
-3 5049 5041 5048
-3 4461 5050 5051
-3 4462 4461 5052
-3 4461 5051 5052
-3 5053 4462 5052
-3 4452 5075 5054
-3 5042 4452 5055
-3 5055 4452 5054
-3 4453 5055 4473
-3 5042 5055 4453
-3 5043 5044 5056
-3 5044 5067 5056
-3 5045 5058 5044
-3 5058 5067 5044
-3 5046 5058 5045
-3 5047 5059 5046
-3 5059 5058 5046
-3 4455 4463 5059
-3 5047 4455 5059
-3 4456 5047 5641
-3 5641 4457 4456
-3 5641 4465 4457
-3 4467 4459 4466
-3 5048 5060 5049
-3 5050 4461 4479
-3 5050 4479 5071
-3 4462 5053 4470
-3 5053 5061 4470
-3 5063 4471 5062
-3 5063 5640 4471
-3 4472 4471 5640
-3 5075 5064 5054
-3 5055 5054 5065
-3 5065 5054 5064
-3 5055 5065 4473
-3 4475 4474 5066
-3 5056 5066 5057
-3 5056 4475 5066
-3 5067 4475 5056
-3 5058 5068 5067
-3 4463 5068 5059
-3 5059 5068 5058
-3 4465 5641 4478
-3 5641 5069 4478
-3 4479 5070 5071
-3 4481 5070 5072
-3 4481 5061 5070
-3 4481 4470 5061
-3 5071 5070 5061
-3 4481 5062 4471
-3 4481 5072 5062
-3 5072 5073 5062
-3 5074 5063 5062
-3 5073 5074 5062
-3 5642 4472 5640
-3 4472 5642 4492
-3 4486 5064 5075
-3 4487 5064 4486
-3 5065 5064 4487
-3 4473 5065 4487
-3 5066 4474 5076
-3 4479 4488 5070
-3 4488 5077 5070
-3 5077 5072 5070
-3 5073 5072 5078
-3 5078 5072 5077
-3 5644 5074 5073
-3 5078 5644 5073
-3 5644 5079 5642
-3 4492 5642 5080
-3 5642 5079 5080
-3 4486 5075 4493
-3 4488 4495 5077
-3 4489 5077 4495
-3 5078 5077 4489
-3 5078 4489 5644
-3 4489 4497 5644
-3 4497 5084 5079
-3 4497 5079 5644
-3 5085 5647 5080
-3 5085 5080 5084
-3 5084 5080 5079
-3 5647 4492 5080
-3 4501 5086 4502
-3 4500 5086 4501
-3 4502 5086 4506
-3 5076 4474 5087
-3 5087 5081 5076
-3 3926 5082 5088
-3 5083 3931 5109
-3 5089 5083 5096
-3 4503 5090 4504
-3 5096 5090 4503
-3 4497 4505 5084
-3 5084 4505 5085
-3 5086 4500 5092
-3 5093 5086 5092
-3 4506 5086 5093
-3 4506 5093 5094
-3 5083 5089 5095
-3 5096 5097 5089
-3 5097 5095 5089
-3 5097 5096 4503
-3 5666 5090 5096
-3 5090 5666 4512
-3 5098 4505 4507
-3 5098 5654 4505
-3 5654 5085 4505
-3 4507 5091 5098
-3 5098 5091 5099
-3 5099 5091 5104
-3 5100 5101 5102
-3 5102 5103 5100
-3 5092 4500 5118
-3 5098 4508 5654
-3 4508 5659 5654
-3 5099 3944 5098
-3 3944 5099 5104
-3 4510 5104 5105
-3 5100 5108 5101
-3 5103 5108 5100
-3 5118 4500 5117
-3 5109 3952 4509
-3 3931 3952 5109
-3 3936 5666 5659
-3 5659 4508 3936
-3 4515 4510 5105
-3 4515 5105 5106
-3 5110 5106 5107
-3 5110 5111 5106
-3 5111 4515 5106
-3 5125 4511 4514
-3 5666 3936 4512
-3 4515 5111 5127
-3 5120 5119 5112
-3 5112 5672 5120
-3 5121 5674 5114
-3 5114 5113 5121
-3 5113 5122 5121
-3 5122 5113 5114
-3 4511 5125 4513
-3 5125 4514 4518
-3 5126 5125 4518
-3 5128 5681 5118
-3 5118 5117 5128
-3 5117 5129 5128
-3 5130 5129 5117
-3 5119 5131 5135
-3 5119 5120 5131
-3 5682 5120 5672
-3 5131 5120 5682
-3 5121 5686 5674
-3 5122 5686 5121
-3 5116 5115 5132
-3 5123 4517 5132
-3 5123 5132 5115
-3 5123 5124 4516
-3 5124 5133 4516
-3 4513 5125 5697
-3 4518 5680 5126
-3 5127 5134 4515
-3 5681 5129 4522
-3 5681 5128 5129
-3 5682 5135 5131
-3 4517 4519 5136
-3 5132 4517 5136
-3 4516 5133 4520
-3 5133 5137 4520
-3 4513 5697 4521
-3 5680 4518 5138
-3 5138 4518 4525
-3 5681 4522 5134
-3 4519 4528 5136
-3 4523 4520 5137
-3 4527 5138 4525
-3 4527 5139 5138
-3 4528 5712 5136
-3 4530 4523 5137
-3 5712 4530 5137
-3 5141 4527 4521
-3 4527 5141 5142
-3 4527 5142 5143
-3 5139 4527 5144
-3 5144 4527 5143
-3 5699 4531 5140
-3 5699 5708 4531
-3 5708 5715 4531
-3 4529 5145 4528
-3 4528 5145 5716
-3 5716 5712 4528
-3 4529 4531 5715
-3 4529 5715 5145
-3 4536 5146 4534
-3 5147 5146 4536
-3 4533 5148 4536
-3 5148 5147 4536
-3 5149 5148 4533
-3 4551 5152 4533
-3 5727 4539 4540
-3 4547 4546 5150
-3 4547 5150 5146
-3 4547 5146 5147
-3 4548 4547 5147
-3 4548 5147 5148
-3 5149 5160 5151
-3 5151 4549 5149
-3 5148 5149 4548
-3 4548 5149 4549
-3 4553 5152 4551
-3 5164 5152 4553
-3 5153 5154 4538
-3 4554 4538 5154
-3 4539 5155 4540
-3 5155 5156 4540
-3 5157 5158 4557
-3 5160 5150 4546
-3 5160 4546 5159
-3 5160 5159 5161
-3 5161 5162 5160
-3 5160 5162 5151
-3 5151 5162 5163
-3 4549 5163 4559
-3 5151 5163 4549
-3 5164 4563 5165
-3 5164 4553 4563
-3 5165 5166 5167
-3 5164 5165 5167
-3 5153 5168 4564
-3 4566 5153 4564
-3 5154 5153 4566
-3 4565 5154 4566
-3 4565 5169 5154
-3 4556 5154 5169
-3 5169 5155 4556
-3 4556 5155 4539
-3 5156 5155 5170
-3 4540 5156 5170
-3 5179 4540 5170
-3 4557 5158 5171
-3 5158 5157 5171
-3 4558 5172 5159
-3 5161 5159 5172
-3 5163 5162 5184
-3 5184 5162 5161
-3 5163 5184 4559
-3 5165 4569 5173
-3 4563 4569 5165
-3 5166 5165 5173
-3 5768 5167 5166
-3 5768 5166 5174
-3 5174 4577 5768
-3 5175 5176 5153
-3 5168 5153 5176
-3 5168 5176 4570
-3 4565 5177 5169
-3 5155 5169 5783
-3 5170 5155 5783
-3 5179 5170 5178
-3 5157 5179 5180
-3 5171 5157 5181
-3 5181 5157 5180
-3 5172 5171 5181
-3 5183 5172 5182
-3 5161 5172 5183
-3 5184 5161 5183
-3 4567 5185 4571
-3 4571 5173 4569
-3 4571 5185 5173
-3 4572 5173 4573
-3 4573 5173 5185
-3 4575 5173 4572
-3 4575 5186 5173
-3 5186 5166 5173
-3 5174 5186 4576
-3 5174 5166 5186
-3 4577 5187 5768
-3 5188 5189 5175
-3 5217 5188 5175
-3 5175 5189 5190
-3 5176 5175 5191
-3 5191 5175 5190
-3 4570 5176 5192
-3 5176 5191 5192
-3 5192 5193 5177
-3 5204 5177 5193
-3 5169 5177 5204
-3 5179 5178 5205
-3 5180 5179 5195
-3 5195 5179 5194
-3 5196 5180 5195
-3 5181 5180 5196
-3 5784 5183 5182
-3 5784 5197 5183
-3 5184 5183 5197
-3 4559 5184 5209
-3 5209 5184 5197
-3 4559 5209 4580
-3 4580 5198 4567
-3 5185 4567 5199
-3 5199 4567 5198
-3 4573 5199 4574
-3 4573 5185 5199
-3 4574 5186 4575
-3 4574 5199 5186
-3 5199 5212 5186
-3 4576 5186 4581
-3 5186 5212 4581
-3 5214 4583 3974
-3 5217 5200 5201
-3 5188 5217 5201
-3 5189 5188 5202
-3 5202 5188 5201
-3 5190 5189 5203
-3 5203 5189 5202
-3 5191 5190 5193
-3 5193 5190 5203
-3 5192 5191 5193
-3 5194 5179 5205
-3 5206 5195 5205
-3 5205 5195 5194
-3 5206 5824 5195
-3 5195 5824 5196
-3 5181 5196 5207
-3 5207 5196 5824
-3 5172 5181 5207
-3 5182 5172 5207
-3 5223 5182 5207
-3 5208 5784 5182
-3 5208 5182 5223
-3 4580 5209 5825
-3 5825 5198 4580
-3 5198 5210 5199
-3 5211 5199 5210
-3 5212 5199 5211
-3 4581 5212 5224
-3 4581 5224 5225
-3 5225 5187 4581
-3 5213 4583 5214
-3 4585 4587 5215
-3 5216 5218 5217
-3 5217 5218 5200
-3 5201 5200 5219
-3 5219 5200 5218
-3 5202 5201 5220
-3 5220 5201 5219
-3 5193 5203 5220
-3 5220 5203 5202
-3 5221 5207 5857
-3 5222 5207 5221
-3 5223 5207 5222
-3 5208 5223 5228
-3 5197 5208 5228
-3 5209 5197 5228
-3 5211 5210 5233
-3 5212 5211 5229
-3 5229 5211 5233
-3 5224 5212 5229
-3 5187 5225 5230
-3 5879 5214 3974
-3 5879 3974 4588
-3 5226 4589 4585
-3 5215 5226 4585
-3 5215 4587 4593
-3 5215 4593 5226
-3 5227 5226 4593
-3 5217 5226 5227
-3 5217 5227 5216
-3 5216 5227 5231
-3 5218 5216 5231
-3 5219 5218 5231
-3 5220 5219 5231
-3 5222 5221 5857
-3 5223 5222 5228
-3 5228 5222 5857
-3 5825 5209 5228
-3 5233 5210 5232
-3 5224 5229 5234
-3 5225 5224 5234
-3 5230 5225 5234
-3 5226 5235 4589
-3 4596 5227 4593
-3 5825 5228 5874
-3 5210 5825 5874
-3 5234 5229 5233
-3 4600 5879 4588
-3 5227 4596 5238
-3 5238 5231 5227
-3 5233 5232 5234
-3 5879 4600 5236
-3 5236 4600 4604
-3 4608 5236 4604
-3 4608 5239 5236
-3 5237 5239 4608
-3 5237 4612 5239
-3 5238 4606 5241
-3 4628 5242 4626
-3 5242 4628 4051
-3 5243 4620 4627
-3 5242 5244 5243
-3 5242 5243 4633
-3 5242 4633 4626
-3 4051 5244 5242
-3 4627 4634 5243
-3 4633 5243 4634
-3 5244 4051 5964
-3 4643 4629 6015
-3 4639 5245 5246
-3 4641 5247 5248
-3 4641 5248 5246
-3 6028 5249 5248
-3 5246 5248 5249
-3 5246 5249 4639
-3 5247 5250 5251
-3 4641 5250 5247
-3 4641 4644 5250
-3 4645 5249 6028
-3 5250 4644 4650
-3 4645 6028 5252
-3 4645 5252 4646
-3 4650 4649 5250
-3 4649 5253 5250
-3 4646 5252 4648
-3 4049 4651 5253
-3 5253 4652 4049
-3 5253 4649 4652
-3 4648 5252 4656
-3 5256 6052 4642
-3 4651 4655 5253
-3 5254 4655 4657
-3 5254 6064 4655
-3 6064 5253 4655
-3 4657 4656 5255
-3 5254 4657 5255
-3 4656 5258 5255
-3 4656 6066 5258
-3 5254 5257 6064
-3 5257 5258 5259
-3 5257 5254 5258
-3 5254 5255 5258
-3 6053 5256 5265
-3 5259 5258 5262
-3 5260 4051 1262
-3 5265 5256 5261
-3 5259 5262 5264
-3 5264 5262 5263
-3 4658 5265 5261
-3 4658 4659 5265
-3 5265 4659 5267
-3 5267 4659 5266
-3 5268 4050 6143
-3 4052 5267 5266
-3 5270 5275 5268
-3 5275 5269 5268
-3 5276 5275 5270
-3 5276 5277 5275
-3 5278 5271 5273
-3 5278 5277 5271
-3 5272 5271 5276
-3 5276 5271 5277
-3 5267 4052 5285
-3 5269 5279 5274
-3 5275 5280 5269
-3 5280 5279 5269
-3 5280 5277 5281
-3 5280 5275 5277
-3 5278 5281 5277
-3 5279 5282 5274
-3 5282 5287 5274
-3 5283 5279 5284
-3 5283 5282 5279
-3 5280 5284 5279
-3 5274 5286 4662
-3 5287 5286 5274
-3 5282 5288 5287
-3 5288 5282 5283
-3 4662 5286 6230
-3 6230 5286 5287
-3 6241 4662 6230
-3 6241 5289 4662
-3 5290 5289 6241
-3 5290 5291 5295
-3 4666 4662 5289
-3 4666 5289 5302
-3 5296 5302 5289
-3 5290 5293 5289
-3 5293 5296 5289
-3 5294 5293 5290
-3 5295 5294 5290
-3 6274 5295 5291
-3 5299 5285 5292
-3 4667 5296 5294
-3 5294 5296 5293
-3 4667 5294 5297
-3 5297 5294 5295
-3 5305 5295 6274
-3 5297 5295 5305
-3 4672 5298 5292
-3 5299 5292 5298
-3 5302 5308 4666
-3 4667 5304 5296
-3 5296 5304 5303
-3 4667 5305 5304
-3 4667 5297 5305
-3 5302 5309 5308
-3 5309 5302 5296
-3 5303 5309 5296
-3 5310 5309 5303
-3 5304 5310 5303
-3 5305 5310 5304
-3 4671 5316 5306
-3 5306 5311 4679
-3 5299 5298 5318
-3 5307 5300 5314
-3 5315 5307 5314
-3 6326 5315 4684
-3 5319 4675 5308
-3 5316 5317 5306
-3 4679 5311 5317
-3 5311 5306 5317
-3 5321 5299 5318
-3 5322 5299 5321
-3 4682 5300 5324
-3 5314 5300 4682
-3 4684 5315 5314
-3 5317 5316 5320
-3 6369 5322 5323
-3 5327 4677 5325
-3 5319 5325 4677
-3 5328 5325 5319
-3 6380 5328 5319
-3 5308 6380 5319
-3 5335 5321 5318
-3 5322 5321 5335
-3 5328 4697 5325
-3 4691 5330 4692
-3 5329 5330 4691
-3 4692 5331 4693
-3 5330 5331 4692
-3 5332 5333 5334
-3 5343 5333 5332
-3 5336 5322 5335
-3 5323 5322 5336
-3 6369 5323 5345
-3 5346 5324 6378
-3 5337 5326 6440
-3 5326 5338 6440
-3 4696 5327 5339
-3 5327 4100 5339
-3 4698 4697 5328
-3 4698 5328 6380
-3 5329 4700 5340
-3 4691 4700 5329
-3 5331 5340 4701
-3 5331 5330 5340
-3 5330 5329 5340
-3 5342 5343 5332
-3 5334 5344 5332
-3 5344 5342 5332
-3 4716 5335 5318
-3 4716 5336 5335
-3 5345 5354 6369
-3 4717 5324 5346
-3 4718 5324 4717
-3 4703 5324 4718
-3 5337 2279 5326
-3 4706 4696 5347
-3 5347 5339 5348
-3 5347 4696 5339
-3 5349 5348 5339
-3 5349 5339 4100
-3 5349 4100 5350
-3 4698 5351 4128
-3 4707 5352 6415
-3 4708 4707 6417
-3 4707 6415 6417
-3 4708 6417 5357
-3 4710 5353 4700
-3 5358 5353 4710
-3 4700 5353 5340
-3 4701 5340 4712
-3 4712 5340 5353
-3 5344 5343 5342
-3 5345 5323 5336
-3 5354 5345 5336
-3 6428 6369 5354
-3 4743 5346 6405
-3 4717 5346 5355
-3 5356 4724 5347
-3 4724 4706 5347
-3 5350 4100 6501
-3 4708 5357 4726
-3 5358 4710 4726
-3 5358 4726 5357
-3 6485 5353 5358
-3 6485 4712 5353
-3 4742 5336 4716
-3 4762 5336 4742
-3 5354 5336 4180
-3 6405 6465 4763
-3 4743 6405 4763
-3 5346 4743 4744
-3 5355 5346 4744
-3 4717 5355 4744
-3 5360 4736 4723
-3 4749 5356 4750
-3 4724 5356 4749
-3 6501 4100 4750
-3 4771 4128 5351
-3 5352 4707 5374
-3 4712 6485 4739
-3 4762 4180 5336
-3 4794 6465 5359
-3 4763 6465 4794
-3 3635 5361 4684
-3 4785 4736 5363
-3 5363 4736 5360
-3 5360 4723 5365
-3 4723 4737 5365
-3 5362 3635 2279
-3 6440 5338 5379
-3 4737 5372 5365
-3 5375 4138 4752
-3 4739 5375 4752
-3 4753 4773 5366
-3 4757 5367 4776
-3 4775 5367 4757
-3 6567 4776 5367
-3 4777 4776 5368
-3 4759 4777 5368
-3 4778 4759 5368
-3 5368 6598 4778
-3 4794 5359 5354
-3 4769 4798 5369
-3 5371 5370 5365
-3 5372 5371 5365
-3 4154 4771 5373
-3 4138 5375 6615
-3 4788 5385 6623
-3 4773 4772 4788
-3 4773 4788 6623
-3 5366 4773 6623
-3 4753 5366 5376
-3 5377 5376 5378
-3 5377 4753 5376
-3 4753 5377 4789
-3 5367 4775 4790
-3 4790 6567 5367
-3 6598 4791 4778
-3 5369 5386 4805
-3 5369 4798 5386
-3 4785 5363 5389
-3 5364 5389 5363
-3 5389 5364 6603
-3 5371 5381 5370
-3 5381 5380 5370
-3 5372 5382 5371
-3 5382 5381 5371
-3 5383 5382 5372
-3 5383 5372 4154
-3 5373 5383 4154
-3 5394 5384 5374
-3 4138 6615 4806
-3 5395 4172 5378
-3 5377 5378 4172
-3 5377 4172 4789
-3 4171 6660 4790
-3 4791 6660 4171
-3 6598 6660 4791
-3 4804 6695 4783
-3 4798 5387 5386
-3 5387 4798 5388
-3 5388 4785 5401
-3 4785 5389 5401
-3 6603 6680 5389
-3 5381 5390 5380
-3 5391 5390 5382
-3 5390 5381 5382
-3 5383 5391 5382
-3 6609 5392 5393
-3 5384 5393 5392
-3 5384 5394 5393
-3 4810 5395 5396
-3 4172 5395 4810
-3 5411 5399 5398
-3 4796 6676 4812
-3 4169 6676 4796
-3 6695 6676 4169
-3 6677 6695 4804
-3 4805 5386 5417
-3 5387 5417 5386
-3 5417 5388 5400
-3 5417 5387 5388
-3 5401 5400 5388
-3 6680 5402 5389
-3 5402 5401 5389
-3 5430 5370 5380
-3 4813 5380 5390
-3 5390 4814 4813
-3 5390 5391 4814
-3 5393 5404 6609
-3 5404 5403 6609
-3 5405 5404 5393
-3 5394 5405 5393
-3 5394 5406 5405
-3 5406 4806 5407
-3 5407 4806 6615
-3 4819 5385 4815
-3 5385 4816 4815
-3 4810 5396 4820
-3 4820 5396 5408
-3 4191 5409 6667
-3 5397 4191 6667
-3 5397 4822 4191
-3 5410 4822 5397
-3 5397 6692 5410
-3 5398 5413 5411
-3 5399 5413 5398
-3 5413 5399 5414
-3 5415 6677 5416
-3 6677 4804 5416
-3 4805 5416 4804
-3 5417 5416 4805
-3 5400 5401 5418
-3 5401 5402 5418
-3 6680 5419 5402
-3 5419 5418 5402
-3 6680 5430 5419
-3 5380 4818 5430
-3 4813 4818 5380
-3 4825 4814 5420
-3 5403 5404 5431
-3 5405 5421 5404
-3 5421 5431 5404
-3 5422 5421 5405
-3 5406 5423 5405
-3 5423 5422 5405
-3 5424 5423 5406
-3 5407 5425 5406
-3 5425 5424 5406
-3 5426 5425 5407
-3 5407 5427 5426
-3 5427 6707 4819
-3 5385 4819 6707
-3 4191 4821 5409
-3 5428 5410 6692
-3 4822 5410 5428
-3 5414 5411 5413
-3 4823 6720 5379
-3 4828 4824 4812
-3 6676 4828 4812
-3 5429 5415 5416
-3 5417 5429 5416
-3 5400 5418 5419
-3 5421 5422 5431
-3 5423 5431 5422
-3 5424 5432 5423
-3 5432 5431 5423
-3 5425 5432 5424
-3 5426 5432 5425
-3 5427 5433 5426
-3 5433 5432 5426
-3 4819 5433 5427
-3 4820 6739 4833
-3 5408 6739 4820
-3 4821 4199 5409
-3 4822 5428 4199
-3 4823 5444 6720
-3 5419 5435 5400
-3 5435 5419 5430
-3 4825 5438 4836
-3 5420 5438 4825
-3 5432 6757 5431
-3 5439 5432 5433
-3 4833 6739 6782
-3 4835 5436 5430
-3 5430 5436 5435
-3 5436 4835 5437
-3 5438 5437 4836
-3 5439 4832 5443
-3 6779 5443 4832
-3 6779 4832 5440
-3 4833 5440 4832
-3 5440 4833 6782
-3 5441 4206 4839
-3 5438 5436 5437
-3 5439 5442 6818
-3 5443 5442 5439
-3 4838 5434 4850
-3 5441 4839 4841
-3 5447 6818 5442
-3 5447 5442 5443
-3 5456 5444 4823
-3 4840 5449 4842
-3 4840 5445 5449
-3 5445 5448 5449
-3 5450 6815 5446
-3 5451 6815 5450
-3 4843 4844 5450
-3 4843 5450 5441
-3 5441 5450 5446
-3 4841 4843 5441
-3 6830 4846 4206
-3 5452 5453 5454
-3 6882 6840 4849
-3 4823 4237 5456
-3 4843 5451 5450
-3 4843 5450 4844
-3 5453 5457 5458
-3 5453 5452 5457
-3 5459 5457 5454
-3 5454 5457 5452
-3 5457 5460 5461
-3 5459 5460 5457
-3 4869 5451 4843
-3 5458 5463 5471
-3 5458 5457 5463
-3 5457 5461 5463
-3 5460 5464 5461
-3 5464 5463 5461
-3 5465 5466 5467
-3 4245 5468 4852
-3 4851 5468 4245
-3 4856 5455 4855
-3 4858 6890 4867
-3 4858 5478 6890
-3 6890 5470 4867
-3 4869 5479 5451
-3 5464 5471 5463
-3 5472 5473 4860
-3 5473 4861 4860
-3 5473 4863 4861
-3 5474 4863 5473
-3 5469 5477 5476
-3 5455 4864 4855
-3 4858 4865 5478
-3 5470 6949 4867
-3 4859 5480 5482
-3 5472 4860 6904
-3 4860 4868 6904
-3 5474 4868 4863
-3 6904 4868 5474
-3 5476 6926 5475
-3 5456 4237 6980
-3 6983 5478 4867
-3 4867 5478 4865
-3 4867 6949 6983
-3 4870 5479 4869
-3 5479 4870 6920
-3 4870 5482 5480
-3 4870 5480 6920
-3 4877 6980 4237
-3 5481 5482 4870
-3 6933 5496 4874
-3 4877 7000 6980
-3 5483 5482 5481
-3 5482 5483 5484
-3 4882 4874 5496
-3 5486 5488 5487
-3 5484 5483 4879
-3 5489 5490 4876
-3 5490 5491 4876
-3 4873 5504 5492
-3 4873 5492 4881
-3 5492 5493 4881
-3 5495 5493 5494
-3 5485 4874 5506
-3 5497 7032 5486
-3 5487 5499 5486
-3 5499 5498 5486
-3 5500 5499 5487
-3 5488 5508 5487
-3 5508 5500 5487
-3 5508 5488 5501
-3 5515 5489 4898
-3 5489 5515 7034
-3 5489 5502 5490
-3 5503 5490 5502
-3 5491 5490 5503
-3 4910 5485 5505
-3 5506 5505 5485
-3 4882 5496 4962
-3 5497 4883 4289
-3 5507 5498 5499
-3 5500 5507 5499
-3 5509 5512 5511
-3 5510 5512 5509
-3 5511 5512 5513
-3 5513 5514 5525
-3 5512 5514 5513
-3 4898 5514 5515
-3 4889 5517 5518
-3 5516 5517 4889
-3 5519 5504 4892
-3 4910 5527 5485
-3 5520 5505 5506
-3 5521 5520 5506
-3 5506 4894 5521
-3 4289 4895 5497
-3 5497 4895 4896
-3 5497 4896 5535
-3 4897 5507 5500
-3 5508 4913 5500
-3 4913 4897 5500
-3 5501 4913 5508
-3 5523 5510 5509
-3 5511 5524 5509
-3 5524 5523 5509
-3 5513 5530 5511
-3 5530 5524 5511
-3 5525 5530 5513
-3 5514 4898 5525
-3 5531 4308 4899
-3 7067 5531 4899
-3 4901 7067 4899
-3 5502 7067 4901
-3 4902 5502 4901
-3 4902 5526 5502
-3 5526 5503 5502
-3 4889 4903 5516
-3 4904 5516 4903
-3 5517 5516 4904
-3 4905 5517 4904
-3 5518 5517 4905
-3 4909 4921 5527
-3 4909 5527 4910
-3 5505 5520 5528
-3 5528 5520 5521
-3 4894 5544 5528
-3 5521 4894 5528
-3 5535 4896 4912
-3 5523 5524 5536
-3 5530 5529 5524
-3 5529 5536 5524
-3 5525 4914 5530
-3 4902 4916 5526
-3 4921 5543 7180
-3 4921 7180 5527
-3 5528 5544 5532
-3 7237 4373 4850
-3 4912 4922 5535
-3 4913 5501 4923
-3 5501 5558 4923
-3 4355 5522 5549
-3 5530 5536 5529
-3 4914 5536 5530
-3 5538 5537 5531
-3 5531 5537 5550
-3 4926 4925 5541
-3 4926 5541 4921
-3 5541 5542 4921
-3 5543 4921 5542
-3 7192 5533 5545
-3 5534 5545 5533
-3 5545 5546 5547
-3 5534 5546 5545
-3 7197 5535 4922
-3 4933 4923 5558
-3 4935 5559 4914
-3 4937 7169 7211
-3 4938 7169 4937
-3 5538 4938 5537
-3 5538 7169 4938
-3 4938 5550 5537
-3 5540 5551 5539
-3 4845 7220 5643
-3 5552 4927 5563
-3 5563 4927 4928
-3 5553 5554 5555
-3 4939 5555 5554
-3 5547 5556 5545
-3 5548 4943 5557
-3 4931 4943 5548
-3 4932 5557 4944
-3 5548 5557 4932
-3 4922 4945 7197
-3 4346 4355 5549
-3 5559 4935 5560
-3 5561 7211 7248
-3 5561 4946 7211
-3 4946 4937 7211
-3 4938 4947 5550
-3 5541 4948 5542
-3 5562 5542 4948
-3 4927 5552 4349
-3 4349 5552 7223
-3 5553 5555 4960
-3 5564 5554 5553
-3 5554 5565 4951
-3 5554 5564 5565
-3 4951 5565 5570
-3 4951 5570 4941
-3 4943 4944 5557
-3 4292 4952 5576
-3 5566 4953 4346
-3 7248 4954 5567
-3 7248 5560 4954
-3 5560 4935 4954
-3 7248 5567 5561
-3 5561 5567 5573
-3 5561 5573 4946
-3 4948 4956 5562
-3 5562 4956 5568
-3 5569 4349 7223
-3 5569 4959 4349
-3 5563 4928 4960
-3 5570 5565 5564
-3 5570 5564 4961
-3 4953 5566 5571
-3 4954 5572 5567
-3 5573 5567 5572
-3 5574 5587 5568
-3 4959 5575 5574
-3 4959 5574 5568
-3 4959 5568 4956
-3 4959 7302 5575
-3 4959 5569 7302
-3 5580 4933 5558
-3 5580 5592 4933
-3 5571 7361 4381
-3 4953 5571 4381
-3 5577 5573 5572
-3 5587 5574 5578
-3 5574 5579 5578
-3 7302 5579 5575
-3 5579 5574 5575
-3 4965 7344 4961
-3 7345 4971 4962
-3 4973 7464 4966
-3 7464 4945 4966
-3 4952 5581 5576
-3 4381 5581 4952
-3 7361 5581 4381
-3 5583 5584 5585
-3 5586 5587 5578
-3 5579 5588 5578
-3 5588 5586 5578
-3 5588 5579 7302
-3 7344 4965 4968
-3 7344 4968 4977
-3 5589 4384 4970
-3 7345 5596 4971
-3 4975 5591 5580
-3 4975 5580 5590
-3 5592 5580 5591
-3 4989 7402 5584
-3 5600 4989 5583
-3 5584 5583 4989
-3 5594 5587 5586
-3 5602 5587 5594
-3 5594 5586 5588
-3 4977 4968 4976
-3 7410 4993 4980
-3 7410 4980 5589
-3 5589 4980 4981
-3 4396 5589 4981
-3 5589 4396 4384
-3 4994 5589 4970
-3 4994 5595 5596
-3 4994 5596 5589
-3 4983 5596 5595
-3 4983 4971 5596
-3 4973 4403 7464
-3 5597 5591 4975
-3 5597 5592 5591
-3 4985 5592 5598
-3 5592 5597 5598
-3 4986 5582 5599
-3 5582 5605 5599
-3 5607 4996 5593
-3 7402 4988 5600
-3 4989 4988 7402
-3 5602 5594 5601
-3 4993 7410 5623
-3 4983 5595 5603
-3 5603 5595 4994
-3 5009 5604 5597
-3 5604 5598 5597
-3 5598 5604 4985
-3 5607 5606 4996
-3 4988 4997 5600
-3 5609 5602 5601
-3 5610 5601 5594
-3 5609 5601 5610
-3 5007 4993 5623
-3 5008 5603 4994
-3 7486 4415 5590
-3 5604 5009 5612
-3 4985 5604 5613
-3 5604 5612 5613
-3 5599 5605 5002
-3 4996 5004 5593
-3 5593 5004 5615
-3 5006 5606 5614
-3 5614 5606 5607
-3 5617 5607 7447
-3 5614 5607 5617
-3 4977 5619 7477
-3 5611 4977 7477
-3 5011 5612 5009
-3 5613 5612 5011
-3 5013 5615 5004
-3 5616 5615 5014
-3 5014 5615 5013
-3 5014 5617 5616
-3 5006 5617 5014
-3 5006 5614 5617
-3 5016 5618 5619
-3 4977 5016 5619
-3 5007 5623 5628
-3 5016 5620 5618
-3 5620 5621 5618
-3 5619 5618 5622
-3 5622 5618 5621
-3 5619 5622 7503
-3 4963 4237 5677
-3 5023 5625 5024
-3 5624 5625 5023
-3 5031 5620 5016
-3 5031 5626 5620
-3 5626 5627 5620
-3 5032 5621 5627
-3 5621 5620 5627
-3 5033 5621 5032
-3 5622 5621 5033
-3 5034 5622 5033
-3 5034 5628 5622
-3 5628 7503 5622
-3 5623 7503 5628
-3 5624 5023 7530
-3 5023 5634 7530
-3 7540 5625 5624
-3 4448 5625 7540
-3 4448 5024 5625
-3 5031 5035 5626
-3 5032 5626 5035
-3 5627 5626 5032
-3 5034 5036 5628
-3 5037 4448 7540
-3 5039 5630 5631
-3 5038 5630 5039
-3 5631 5038 5039
-3 5628 5036 4467
-3 5040 5041 5629
-3 5040 5629 5633
-3 5044 5043 7556
-3 5045 5044 5630
-3 5044 7556 5630
-3 5630 5038 5045
-3 5047 5038 5631
-3 7565 5049 5639
-3 7565 5632 5049
-3 5632 5041 5049
-3 5048 5040 5633
-3 5048 5633 5639
-3 5051 5050 5635
-3 5051 5636 5052
-3 5635 5636 5051
-3 5052 5636 5053
-3 5056 5057 5637
-3 5056 5637 5638
-3 5056 5638 5043
-3 5047 5631 5641
-3 5049 5060 5639
-3 5048 5639 5060
-3 5071 5635 5050
-3 5071 5636 5635
-3 5053 5071 5061
-3 5636 5071 5053
-3 5057 5066 5637
-3 5640 5074 5642
-3 5063 5074 5640
-3 5066 5076 5637
-3 5645 5638 5637
-3 5645 5637 5076
-3 5069 5641 5082
-3 5074 5644 5642
-3 5645 5076 5081
-3 5641 7610 5082
-3 4373 7616 3952
-3 5081 5087 5645
-3 5088 5082 7610
-3 3952 7616 4509
-3 5109 5652 5083
-3 5646 5096 5083
-3 5647 5085 5654
-3 4492 5648 5091
-3 4492 5647 5648
-3 5647 5654 5648
-3 5649 7640 7620
-3 7620 5650 5649
-3 5651 5093 5092
-3 5094 5093 5651
-3 5087 5094 5645
-3 5094 5651 5645
-3 5096 5646 5653
-3 7666 5096 5653
-3 5666 5096 7666
-3 5091 5648 5104
-3 5655 7640 5649
-3 5650 5656 5649
-3 5656 5655 5649
-3 5105 5656 5650
-3 5102 5101 5657
-3 5102 5657 5103
-3 5116 7680 5115
-3 5115 7680 5665
-3 5109 5658 5652
-3 5660 5648 5659
-3 5659 5648 5654
-3 5104 5648 5660
-3 5655 5104 5660
-3 5105 5104 5655
-3 5656 5105 5655
-3 5107 5662 5661
-3 5107 5106 5662
-3 5106 5105 5662
-3 5101 5108 5657
-3 5103 5657 5108
-3 5118 7671 5092
-3 5663 5664 5112
-3 5671 7680 5116
-3 5115 5665 5123
-3 7686 5109 4509
-3 7686 5658 5109
-3 5660 5659 5666
-3 5107 5661 5110
-3 5661 5111 5110
-3 5661 5662 5111
-3 5112 5673 5672
-3 5114 5667 5668
-3 5668 5669 5670
-3 5667 5669 5668
-3 5671 5670 5669
-3 7777 7761 4509
-3 7761 7686 4509
-3 5662 5127 5111
-3 5683 7724 5674
-3 5114 5674 7724
-3 5668 5675 5122
-3 5114 5668 5122
-3 5670 5676 5668
-3 5676 5675 5668
-3 5671 5116 5670
-3 5116 5676 5670
-3 5124 5123 5665
-3 5679 5678 5691
-3 5127 5693 5681
-3 5127 5662 5693
-3 5681 5693 5118
-3 5119 5135 5112
-3 5673 5695 5672
-3 5695 5682 5672
-3 5673 5683 5695
-3 5683 5674 5684
-3 5685 5684 5674
-3 5674 5686 5685
-3 5122 5675 5687
-3 5676 5688 5675
-3 5688 5687 5675
-3 5116 5132 5688
-3 5116 5688 5676
-3 5703 5137 5665
-3 5124 5137 5133
-3 5665 5137 5124
-3 5689 5678 5679
-3 5690 5689 5679
-3 5691 5678 5689
-3 5691 5689 5692
-3 5125 7784 5697
-3 5126 7784 5125
-3 5127 5681 5134
-3 5694 5135 5682
-3 5695 5694 5682
-3 5708 5695 5683
-3 5685 5700 5684
-3 5686 5696 5685
-3 5696 5686 5122
-3 5687 5696 5122
-3 5132 5136 5688
-3 7803 5689 5690
-3 5692 5689 7803
-3 5680 5138 7824
-3 5695 5699 5694
-3 5699 5698 5694
-3 5708 5699 5695
-3 5684 5708 5683
-3 5685 5701 5700
-3 5696 5702 5685
-3 5702 5701 5685
-3 5688 5136 5703
-3 5704 5703 5136
-3 5703 5704 5137
-3 5138 5705 7824
-3 5706 5705 5138
-3 5139 5707 5138
-3 5138 5707 5706
-3 7826 5707 5139
-3 5140 5643 5698
-3 5699 5140 5698
-3 5700 5708 5684
-3 5701 5709 5700
-3 5702 5710 5701
-3 5710 5709 5701
-3 5711 5710 5702
-3 5136 5712 5704
-3 5137 5704 5712
-3 5141 7840 5713
-3 7824 5705 5142
-3 7824 5142 5713
-3 5713 5142 5141
-3 5705 5706 5142
-3 5142 5706 5143
-3 5144 5143 5714
-3 5143 5706 5714
-3 7826 5139 5144
-3 5714 7826 5144
-3 5700 5715 5708
-3 5709 5715 5700
-3 5710 5715 5709
-3 5711 5145 5710
-3 5145 5715 5710
-3 5711 5716 5145
-3 5716 5717 5712
-3 5712 5717 4530
-3 5677 4530 5718
-3 5141 4521 7840
-3 5716 5718 5717
-3 4530 5717 5718
-3 4539 5719 5720
-3 4539 5721 5719
-3 4539 5722 5721
-3 4539 5723 5722
-3 4539 5724 5723
-3 4539 5725 5724
-3 5727 5726 4539
-3 4539 5726 5725
-3 5727 5729 5728
-3 5727 5730 5729
-3 5727 5731 5730
-3 4534 5732 5731
-3 4534 5731 5727
-3 5733 4534 5146
-3 5745 5733 5146
-3 5734 5749 5149
-3 5734 5149 4533
-3 4533 5735 5734
-3 5152 5736 4533
-3 4533 5736 5735
-3 5152 5737 5736
-3 4538 5738 5739
-3 4538 5740 5738
-3 4539 5741 4538
-3 4538 5741 5740
-3 5741 4539 5720
-3 4534 5742 5732
-3 5743 5742 4534
-3 5744 5743 4534
-3 5733 5744 4534
-3 5746 5745 5146
-3 5150 5747 5746
-3 5146 5150 5746
-3 5149 5748 5160
-3 5149 5749 5748
-3 5152 5750 5737
-3 5751 5750 5152
-3 5152 5759 5751
-3 5152 5164 5759
-3 5153 5752 5753
-3 4538 5754 5153
-3 5153 5754 5752
-3 5754 4538 5739
-3 5150 5755 5747
-3 5150 5160 5755
-3 5160 5756 5755
-3 5160 5757 5756
-3 5748 5758 5160
-3 5758 5757 5160
-3 5760 5761 5759
-3 5164 5760 5759
-3 5164 5167 5762
-3 5760 5164 5762
-3 5153 5763 5764
-3 5763 5153 5753
-3 5765 5761 5760
-3 5766 5761 5765
-3 5762 5767 5760
-3 5767 5765 5760
-3 5167 5767 5762
-3 5167 5768 5767
-3 5768 5769 5767
-3 5771 5770 5768
-3 5175 5772 5773
-3 5153 5774 5175
-3 5175 5774 5772
-3 5774 5153 5764
-3 5776 5766 5765
-3 5775 5766 5776
-3 5767 5776 5765
-3 5777 5767 5769
-3 5776 5767 5777
-3 5768 5778 5771
-3 5779 5778 5768
-3 5780 5217 5781
-3 5175 5782 5217
-3 5217 5782 5781
-3 5782 5175 5773
-3 5170 5783 5178
-3 5198 5785 5786
-3 5787 5198 5786
-3 5776 5788 5775
-3 5788 5789 5790
-3 5788 5776 5789
-3 5791 5776 5777
-3 5789 5776 5791
-3 5792 5779 5187
-3 5779 5768 5187
-3 5792 5187 5793
-3 5795 5794 5217
-3 5780 5795 5217
-3 5204 5817 5169
-3 5817 5818 5169
-3 5819 5169 5818
-3 5796 5797 5783
-3 5796 5783 5819
-3 5819 5783 5169
-3 5798 5783 5797
-3 5799 5783 5798
-3 5800 5783 5799
-3 5801 5783 5800
-3 5802 5783 5801
-3 5820 5802 5803
-3 5178 5802 5820
-3 5178 5783 5802
-3 5820 5205 5178
-3 5197 5784 5208
-3 5198 5825 5804
-3 5198 5804 5785
-3 5210 5198 5805
-3 5805 5198 5787
-3 5789 5806 5790
-3 5791 5806 5789
-3 5807 5793 5187
-3 5214 5808 5809
-3 5213 5214 5809
-3 5214 5810 5808
-3 5214 5811 5810
-3 5812 5811 5214
-3 5217 5814 5813
-3 5814 5217 5794
-3 5835 5838 5193
-3 5815 5816 5204
-3 5815 5204 5838
-3 5838 5204 5193
-3 5817 5204 5816
-3 5821 5205 5820
-3 5205 5821 5822
-3 5823 5205 5822
-3 5205 5823 5206
-3 5823 5840 5206
-3 5824 5206 5840
-3 5824 5857 5207
-3 5826 5804 5210
-3 5210 5804 5825
-3 5805 5826 5210
-3 5827 5807 5187
-3 5213 5809 5240
-3 5809 5828 5240
-3 5214 5829 5812
-3 5829 5214 5879
-3 5830 5829 5879
-3 5831 5226 5832
-3 5226 5833 5832
-3 5850 5833 5226
-3 5226 5834 5850
-3 5226 5217 5834
-3 5217 5813 5834
-3 5220 5868 5193
-3 5835 5193 5868
-3 5836 5837 5835
-3 5838 5835 5837
-3 5840 5823 5839
-3 5841 5824 5840
-3 5841 5842 5824
-3 5854 5824 5842
-3 5857 5824 5854
-3 5187 5230 5843
-3 5843 5827 5187
-3 5828 5844 5240
-3 5879 5845 5830
-3 5879 5846 5845
-3 5847 5846 5879
-3 5226 5849 5235
-3 5849 5848 5235
-3 5831 5849 5226
-3 5868 5220 5231
-3 5851 5852 5835
-3 5851 5835 5868
-3 5836 5835 5852
-3 5854 5842 5853
-3 5855 5857 5854
-3 5855 5856 5857
-3 5230 5234 5858
-3 5230 5858 5859
-3 5230 5859 5843
-3 5240 5844 5860
-3 5861 5240 5860
-3 5879 5862 5847
-3 5879 5863 5862
-3 5235 5864 5865
-3 5864 5235 5848
-3 5866 5867 5231
-3 5866 5231 5885
-3 5868 5231 5867
-3 5857 5856 5869
-3 5870 5857 5869
-3 5871 5857 5870
-3 5872 5857 5871
-3 5872 5873 5857
-3 5857 5873 5228
-3 5228 5873 5874
-3 5874 5232 5210
-3 5234 5893 5875
-3 5234 5875 5876
-3 5234 5876 5858
-3 5861 5877 5240
-3 5879 5878 5863
-3 5880 5879 5236
-3 5235 5865 5881
-3 5882 5883 5231
-3 5884 5231 5883
-3 5885 5231 5884
-3 5874 5873 5886
-3 5887 5874 5886
-3 5888 5874 5887
-3 5889 5874 5888
-3 5890 5874 5889
-3 5890 5891 5874
-3 5904 5874 5891
-3 5232 5874 5905
-3 5905 5874 5904
-3 5234 5232 5909
-3 5909 5232 5908
-3 5910 5234 5909
-3 5892 5234 5910
-3 5892 5893 5234
-3 5240 5877 5894
-3 5895 5240 5894
-3 5236 5896 5880
-3 5236 5897 5896
-3 5897 5236 5898
-3 5900 5899 5235
-3 5881 5900 5235
-3 5238 5901 5231
-3 5901 5902 5231
-3 5902 5882 5231
-3 5904 5891 5903
-3 5906 5232 5905
-3 5907 5232 5906
-3 5908 5232 5907
-3 5911 5892 5910
-3 5895 5912 5240
-3 5236 5913 5898
-3 5236 5239 5913
-3 5239 5914 5913
-3 5915 5914 5239
-3 5235 5916 5917
-3 5916 5235 5899
-3 5919 5920 5901
-3 5919 5901 5918
-3 5918 5901 5238
-3 5902 5901 5920
-3 5921 5902 5920
-3 5922 5240 5912
-3 5239 5923 5915
-3 4612 5923 5239
-3 5924 5923 4612
-3 5925 5235 5917
-3 5926 5927 5918
-3 5926 5918 5935
-3 5935 5918 5238
-3 5919 5918 5927
-3 5240 5928 5929
-3 5240 5922 5928
-3 5930 4620 5931
-3 5930 5924 4620
-3 5924 4612 4620
-3 5925 5932 5235
-3 5241 5944 5933
-3 5241 5933 5934
-3 5241 5934 5238
-3 5935 5238 5934
-3 5240 5929 5936
-3 5936 5937 5240
-3 5931 4620 5938
-3 5939 5931 5938
-3 5939 5938 5940
-3 5235 5941 5942
-3 5941 5235 5932
-3 5241 5943 5944
-3 5937 5945 5240
-3 4620 5243 5938
-3 5244 5938 5243
-3 5938 5946 5940
-3 5938 5244 5946
-3 5947 5946 5244
-3 5948 5235 5942
-3 5949 5943 5241
-3 5945 5950 5240
-3 5244 5951 5947
-3 5952 5951 5244
-3 5235 5953 4635
-3 5235 5948 5953
-3 5241 5954 5955
-3 5241 5955 5949
-3 5956 5240 5950
-3 5952 5244 5957
-3 4635 5958 5959
-3 4635 5959 3496
-3 5953 5958 4635
-3 5241 4642 5960
-3 5960 5954 5241
-3 5961 5240 5956
-3 5961 5962 5240
-3 5244 5963 5957
-3 5964 5963 5244
-3 5965 3496 5959
-3 4642 5966 5967
-3 4642 5967 5960
-3 5240 5962 4629
-3 5962 5968 4629
-3 5964 4051 5969
-3 5965 5970 3496
-3 5971 5966 4642
-3 5972 4629 5968
-3 5973 5974 5975
-3 5975 5976 5973
-3 4051 5977 5969
-3 5978 5977 4051
-3 5979 3496 5970
-3 5980 5971 4642
-3 5972 5981 4629
-3 5982 5974 5973
-3 5983 5974 5982
-3 5984 5973 5976
-3 5982 5973 5984
-3 5985 5978 4051
-3 5979 5986 3496
-3 4642 5987 5988
-3 4642 5988 5980
-3 4629 5981 5989
-3 5982 5990 5983
-3 5984 5990 5982
-3 5991 5985 4051
-3 5991 4051 5992
-3 5986 5993 3496
-3 5994 5987 4642
-3 4629 6000 6015
-3 5995 4629 5989
-3 6000 4629 5995
-3 5992 4051 5996
-3 3496 5997 5998
-3 5997 3496 5993
-3 5999 5994 4642
-3 6001 5996 4051
-3 5998 6002 3496
-3 6003 5999 4642
-3 6009 6003 4642
-3 6000 6004 6015
-3 6005 6001 4051
-3 6005 4051 6006
-3 6002 6007 3496
-3 6009 4642 6008
-3 6004 6010 6015
-3 6006 4051 6011
-3 3496 6012 6013
-3 6012 3496 6007
-3 4642 6014 6008
-3 6016 6011 4051
-3 6013 6017 3496
-3 6018 6014 4642
-3 6015 6019 4643
-3 5248 5247 6027
-3 5248 6027 6028
-3 6020 6016 4051
-3 6020 4051 6021
-3 6017 6022 3496
-3 6023 6018 4642
-3 6019 6024 4643
-3 5251 6025 6026
-3 5250 6025 5251
-3 6027 5247 5251
-3 6027 5251 6026
-3 6029 6021 4051
-3 3496 6022 6030
-3 6031 6023 4642
-3 6024 6032 4643
-3 6025 5250 6033
-3 5252 6028 6034
-3 6035 6029 4051
-3 3496 6036 6037
-3 6030 6036 3496
-3 4642 6052 6053
-3 6038 6031 4642
-3 6053 6038 4642
-3 6032 6039 4643
-3 5250 5253 6033
-3 6033 5253 6040
-3 6041 5252 6034
-3 6042 6035 4051
-3 6042 4051 6043
-3 6037 6044 3496
-3 6045 6038 6053
-3 4643 6039 6046
-3 5253 6047 6048
-3 6048 6040 5253
-3 6041 6049 5252
-3 6050 6043 4051
-3 4702 3496 6051
-3 3496 6044 6051
-3 6054 6045 6053
-3 6055 4643 6046
-3 6062 4643 6055
-3 5253 6056 6047
-3 6049 6057 4656
-3 5252 6049 4656
-3 4051 6058 6050
-3 4702 6059 6060
-3 6051 6059 4702
-3 6053 6052 5256
-3 6061 6054 6053
-3 6065 6056 5253
-3 6064 6065 5253
-3 4656 6067 6066
-3 4656 6057 6067
-3 6058 4051 6068
-3 6060 6069 4702
-3 6070 6061 6053
-3 6062 6063 4643
-3 6063 6071 4643
-3 6064 5257 5259
-3 6064 5259 6065
-3 6065 5259 6072
-3 6066 6073 5258
-3 6068 4051 6074
-3 4702 6075 6087
-3 4702 6069 6075
-3 6070 6053 6076
-3 4050 4643 6077
-3 6077 4643 6071
-3 5259 6078 6079
-3 6079 6072 5259
-3 6073 6093 5258
-3 6080 6094 6073
-3 6094 6093 6073
-3 6080 6081 6094
-3 6082 6083 6084
-3 6084 6085 6082
-3 5260 6086 4051
-3 6086 6074 4051
-3 6087 6088 4702
-3 6089 5265 6090
-3 6089 6076 5265
-3 6076 6053 5265
-3 6077 6091 4050
-3 5264 6092 5259
-3 5259 6092 6078
-3 5258 6093 5262
-3 6095 6094 6081
-3 6096 6097 6098
-3 6096 6083 6099
-3 6098 6083 6096
-3 6100 6082 6101
-3 6100 6099 6082
-3 6083 6082 6099
-3 6085 6101 6082
-3 5260 6102 6086
-3 6088 6103 4702
-3 6090 5265 6104
-3 6091 6105 4050
-3 6092 5264 6106
-3 5263 6107 6122
-3 5262 6107 5263
-3 5262 6093 6107
-3 6094 6107 6093
-3 6108 6107 6094
-3 6095 6108 6094
-3 6109 6097 6096
-3 6110 6097 6109
-3 6099 6111 6096
-3 6111 6109 6096
-3 6112 6099 6100
-3 6111 6099 6112
-3 6102 5260 6113
-3 4702 6103 6114
-3 6104 5265 6115
-3 4050 6116 6117
-3 6116 4050 6105
-3 6118 6106 5264
-3 6119 6106 6118
-3 5264 6120 6118
-3 5264 5263 6120
-3 6120 6121 6118
-3 6122 6120 5263
-3 6123 6124 6125
-3 6110 6123 6125
-3 6110 6109 6123
-3 6109 6126 6123
-3 6127 6111 6128
-3 6127 6126 6111
-3 6126 6109 6111
-3 6112 6128 6111
-3 6129 6113 5260
-3 6114 6130 4702
-3 5265 5267 6115
-3 5267 6131 6115
-3 4050 6117 6143
-3 6117 6132 6143
-3 6133 6119 6118
-3 6134 6119 6133
-3 6135 6118 6121
-3 6133 6118 6135
-3 6136 6124 6123
-3 6137 6124 6136
-3 6138 6126 6139
-3 6138 6136 6126
-3 6136 6123 6126
-3 6127 6139 6126
-3 5260 6140 6129
-3 6130 6141 4702
-3 6131 5267 6142
-3 6133 6144 6134
-3 6135 6144 6133
-3 6136 6145 6137
-3 6138 6145 6136
-3 6140 5260 6146
-3 6141 6147 4702
-3 6148 5267 6149
-3 6148 6142 5267
-3 6143 6154 5268
-3 6143 6150 6154
-3 6146 5260 6151
-3 6147 6152 4702
-3 5267 6153 6149
-3 6154 6155 5268
-3 6151 5260 6156
-3 6152 6157 4702
-3 5267 6159 6158
-3 5267 6158 6153
-3 6155 6160 5268
-3 6161 6162 6163
-3 6161 6164 6165
-3 6163 6164 6161
-3 6165 6166 6167
-3 6164 6166 6165
-3 6167 6168 6169
-3 6166 6168 6167
-3 6168 6170 6169
-3 6171 6156 5260
-3 6157 6172 4702
-3 5267 6173 6159
-3 6174 5270 5268
-3 6174 5268 6160
-3 5271 6175 6176
-3 5272 6175 5271
-3 5273 6177 6178
-3 5273 5271 6177
-3 5271 6176 6177
-3 6177 6179 6178
-3 6178 6180 6181
-3 6179 6180 6178
-3 6182 6161 6183
-3 6182 6181 6161
-3 6162 6161 6180
-3 6180 6161 6181
-3 6165 6183 6161
-3 6184 6183 6165
-3 6167 6184 6165
-3 6185 6184 6167
-3 6169 6185 6167
-3 6186 6185 6169
-3 6170 6186 6169
-3 5260 6187 6171
-3 6172 6188 4702
-3 6189 6173 5267
-3 6189 5267 6190
-3 5284 6191 6192
-3 6191 5284 6193
-3 6194 6174 6195
-3 5276 6174 6194
-3 5276 5270 6174
-3 5273 6197 5278
-3 5276 6194 5272
-3 5272 6194 6196
-3 5272 6196 6175
-3 5273 6198 6197
-3 5273 6178 6198
-3 6198 6208 6199
-3 6198 6178 6208
-3 6200 6181 6201
-3 6200 6208 6181
-3 6208 6178 6181
-3 6182 6201 6181
-3 6187 5260 6202
-3 6188 6203 4702
-3 5285 6190 5267
-3 5285 6204 6190
-3 6205 5284 6192
-3 6206 6193 5284
-3 6206 5284 5280
-3 6195 6206 5280
-3 6194 6195 5280
-3 6194 5280 5281
-3 6194 6207 6196
-3 6194 5281 6207
-3 6197 6207 5278
-3 5278 6207 5281
-3 6202 5260 6209
-3 6203 6210 4702
-3 5285 6212 6211
-3 5285 6211 6204
-3 5283 6213 6214
-3 6205 6213 5283
-3 5284 6205 5283
-3 6209 5260 6215
-3 6210 6216 4702
-3 5285 6217 6212
-3 5288 5283 6214
-3 6218 5288 6214
-3 6215 5260 6219
-3 6216 6220 4702
-3 5285 6221 6217
-3 6221 5285 6222
-3 6238 6223 6224
-3 6223 6238 6225
-3 6238 6226 6227
-3 6225 6238 6227
-3 6227 6226 6228
-3 5287 6229 6230
-3 6218 6229 5288
-3 6229 5287 5288
-3 5260 6231 6219
-3 6220 6232 4702
-3 5285 6233 6222
-3 6233 5285 6234
-3 6235 6236 6237
-3 6235 6238 6239
-3 6236 6235 6239
-3 6224 6239 6238
-3 6240 6228 6226
-3 6242 6241 6230
-3 6242 5291 6241
-3 6242 6243 5291
-3 5260 6244 6231
-3 6232 6245 4702
-3 6246 6247 6248
-3 6248 6249 6246
-3 5285 6251 6234
-3 6251 5285 6252
-3 6253 6235 6237
-3 6254 6253 6237
-3 6238 6235 6268
-3 6268 6235 6253
-3 6255 6238 6268
-3 6226 6238 6256
-3 6256 6238 6255
-3 6257 6240 6226
-3 6256 6257 6226
-3 5291 5290 6241
-3 5291 6243 6258
-3 6244 5260 6259
-3 6245 6260 4702
-3 6261 6247 6246
-3 6249 6262 6246
-3 6262 6261 6246
-3 6263 6249 6250
-3 6262 6249 6263
-3 5285 6264 6252
-3 6253 6266 6267
-3 6254 6266 6253
-3 6255 6268 6269
-3 6256 6255 6270
-3 6270 6255 6269
-3 6271 6257 6256
-3 6271 6256 6272
-3 6272 6256 6270
-3 6273 5291 6258
-3 6273 6274 5291
-3 6259 5260 6275
-3 6260 6276 4702
-3 6277 6278 6279
-3 6277 6261 6278
-3 6261 6262 6278
-3 6280 6262 6263
-3 6278 6262 6280
-3 5285 5299 6264
-3 5299 6281 6265
-3 5299 6265 6264
-3 6283 6284 6285
-3 6267 6284 6283
-3 6267 6283 6253
-3 6253 6283 6286
-3 6287 6253 6286
-3 6268 6253 6287
-3 6288 6268 6287
-3 6269 6268 6288
-3 6270 6269 6288
-3 6272 6270 6289
-3 6289 6270 6288
-3 6290 6272 6291
-3 6291 6272 6289
-3 6290 6291 6292
-3 6274 6294 5305
-3 6275 5260 6295
-3 6276 6296 4702
-3 6278 6297 6279
-3 6297 6278 6316
-3 6298 6316 6280
-3 6280 6316 6278
-3 6298 6299 6316
-3 5299 6300 6282
-3 5299 6282 6281
-3 6300 5299 6301
-3 6303 6283 6285
-3 6304 6303 6285
-3 6286 6283 6305
-3 6305 6283 6303
-3 6287 6286 6306
-3 6306 6286 6305
-3 5300 6287 6306
-3 6288 6287 5300
-3 5307 6288 5300
-3 5307 6307 6288
-3 6307 6289 6288
-3 5301 6291 6307
-3 6291 6289 6307
-3 5301 6308 6291
-3 6308 6292 6291
-3 6309 6293 6292
-3 6309 6292 6310
-3 6310 6292 6308
-3 5305 6311 6312
-3 6311 5305 6294
-3 6295 5260 6313
-3 6296 6314 4702
-3 6297 6316 6315
-3 6317 6316 6299
-3 5322 6301 5299
-3 6319 6302 6301
-3 6319 6301 5322
-3 6319 5322 6320
-3 6304 6324 6303
-3 6303 6324 5324
-3 6305 6303 5324
-3 6306 6305 5324
-3 5300 6306 5324
-3 6307 5307 6325
-3 5301 6307 6326
-3 6307 6325 6326
-3 5301 6326 6308
-3 6310 6308 6327
-3 6327 6308 6326
-3 6327 6328 6310
-3 6329 6348 5309
-3 6329 5309 6330
-3 6330 5309 5310
-3 5310 6331 6330
-3 6312 5310 5305
-3 6331 5310 6312
-3 6313 5260 6332
-3 6314 6333 4702
-3 6334 6315 5313
-3 5312 5313 6316
-3 6316 5313 6315
-3 5312 6316 6317
-3 6335 6317 6318
-3 6335 5312 6317
-3 6335 6336 5312
-3 6337 6320 5322
-3 6337 5322 6338
-3 6339 6340 6341
-3 6340 6339 6342
-3 6342 6362 6343
-3 6322 6343 6362
-3 6322 6362 6321
-3 6321 6362 5324
-3 6323 6321 5324
-3 6324 6323 5324
-3 5307 5315 6325
-3 6326 6325 5315
-3 6327 6326 4684
-3 6327 4684 6328
-3 6328 4684 6344
-3 5308 6345 6346
-3 5309 6347 5308
-3 5308 6347 6345
-3 6348 6347 5309
-3 6332 5260 6349
-3 6333 6350 4702
-3 5313 6351 6334
-3 6353 6352 6351
-3 5312 6353 6351
-3 5312 6351 5313
-3 5312 6354 6353
-3 6355 6354 5312
-3 6336 6355 5312
-3 5322 6356 6338
-3 6356 5322 6357
-3 6358 6359 6360
-3 6341 6359 6358
-3 6341 6358 6339
-3 6339 6358 6361
-3 6342 6339 6362
-3 6362 6339 6361
-3 5324 6362 6378
-3 6363 6344 4684
-3 6364 5308 6365
-3 6365 5308 6346
-3 6349 5260 6366
-3 6350 6367 4702
-3 6353 6368 6352
-3 6369 6370 6357
-3 6369 6357 5322
-3 6370 6369 6371
-3 6373 6374 6375
-3 6374 6373 6376
-3 6376 6378 6377
-3 6360 6377 6378
-3 6360 6378 6358
-3 6361 6358 6378
-3 6362 6361 6378
-3 6363 4684 6379
-3 6380 5308 6381
-3 6381 5308 6364
-3 6366 5260 6382
-3 6367 6383 4702
-3 6384 6372 6371
-3 6384 6371 6369
-3 6384 6369 6385
-3 6388 6386 6387
-3 6375 6386 6388
-3 6375 6388 6373
-3 6376 6373 6388
-3 6378 6376 5346
-3 5346 6376 6388
-3 6379 4684 6389
-3 6381 6391 6380
-3 6391 6390 6380
-3 6391 6381 6392
-3 5343 6393 6394
-3 5333 5343 6395
-3 5343 6394 6395
-3 6395 5334 5333
-3 6396 5334 6395
-3 6397 6382 5260
-3 6383 6398 4702
-3 6399 6385 6369
-3 6399 6369 6400
-3 6400 6402 6401
-3 6403 6404 6405
-3 6387 6406 6388
-3 6407 6389 4684
-3 6390 6408 4698
-3 6380 6390 4698
-3 6391 6409 6390
-3 6409 6408 6390
-3 6410 6391 6392
-3 6410 6411 6391
-3 6411 6409 6391
-3 6411 6412 6413
-3 6410 6412 6411
-3 6412 6414 6413
-3 6416 6417 6415
-3 6419 6420 6421
-3 6419 6421 6393
-3 6419 6393 5343
-3 6422 5344 6396
-3 5344 5334 6396
-3 1262 6397 5260
-3 6424 6397 1262
-3 6398 6425 4702
-3 6369 6428 6400
-3 6402 6400 6428
-3 6426 6402 6428
-3 6426 6428 6427
-3 6432 6465 6433
-3 6433 6465 6434
-3 6465 6404 6435
-3 6434 6465 6435
-3 6388 6406 6405
-3 5346 6388 6405
-3 4684 6436 6407
-3 6436 4684 6437
-3 6438 6472 2279
-3 6438 2279 6439
-3 6439 2279 5337
-3 6440 6441 6439
-3 6440 6439 5337
-3 5347 5348 6442
-3 5349 6443 5348
-3 5348 6443 6442
-3 6443 5349 5350
-3 6444 6443 5350
-3 4698 6408 5351
-3 6409 6445 6408
-3 6411 6445 6409
-3 6446 6413 6447
-3 6446 6445 6413
-3 6445 6411 6413
-3 6414 6447 6413
-3 6415 6448 6449
-3 6415 5352 6448
-3 6417 6418 6450
-3 6417 6450 5357
-3 6451 5357 6450
-3 6452 6453 6454
-3 6452 6420 6455
-3 6454 6420 6452
-3 6420 6419 6455
-3 6419 6456 6455
-3 5343 6456 6419
-3 5343 6457 6456
-3 6457 6458 6456
-3 6423 5344 6422
-3 6423 6457 5344
-3 6457 5343 5344
-3 6459 6424 1262
-3 6425 6460 4702
-3 6461 6428 5359
-3 5359 6428 5354
-3 6461 5359 6462
-3 6462 5359 6463
-3 6463 5359 6464
-3 5359 6465 6466
-3 6464 5359 6466
-3 6466 6465 6467
-3 6467 6465 6468
-3 6430 6468 6465
-3 6430 6465 6429
-3 6431 6429 6465
-3 6432 6431 6465
-3 6404 6465 6405
-3 6495 6469 4684
-3 6469 6437 4684
-3 2279 6471 6470
-3 6472 6471 2279
-3 6473 6441 6440
-3 5356 6474 6475
-3 6442 5356 5347
-3 6474 5356 6442
-3 5350 6501 6444
-3 6444 6501 6476
-3 6477 6445 6478
-3 6477 6408 6445
-3 6479 6478 6445
-3 6446 6479 6445
-3 6480 6448 5352
-3 6480 5352 6481
-3 6482 5357 6483
-3 6483 5357 6451
-3 5357 6484 5358
-3 6482 6484 5357
-3 6484 6485 5358
-3 6486 6487 6488
-3 6453 6486 6488
-3 6453 6452 6486
-3 6452 6489 6486
-3 6455 6490 6452
-3 6490 6489 6452
-3 6491 6456 6492
-3 6491 6490 6456
-3 6490 6455 6456
-3 6458 6492 6456
-3 6493 6459 1262
-3 6460 6494 4702
-3 6541 6496 6495
-3 4684 6541 6495
-3 4684 5361 6541
-3 2279 6497 6498
-3 6497 2279 6470
-3 6499 6473 6440
-3 4750 5356 6500
-3 6500 5356 6475
-3 6501 6502 6476
-3 4771 5351 6503
-3 6503 5351 6408
-3 6503 6408 6477
-3 5352 5374 6481
-3 6481 5374 6504
-3 6482 6483 6505
-3 6505 6506 6507
-3 6505 6507 6482
-3 6482 6507 6484
-3 6485 6507 4739
-3 6485 6484 6507
-3 6508 6509 6510
-3 6487 6508 6510
-3 6487 6486 6508
-3 6486 6511 6508
-3 6489 6512 6486
-3 6512 6511 6486
-3 6513 6490 6514
-3 6513 6512 6490
-3 6512 6489 6490
-3 6491 6514 6490
-3 6515 6493 1262
-3 6494 6516 4702
-3 6539 6496 6541
-3 6517 6496 6539
-3 6518 2279 6519
-3 2279 6520 6519
-3 6520 2279 6498
-3 6440 6521 6499
-3 5363 5360 6523
-3 6522 5363 6523
-3 4750 6500 6524
-3 6557 6524 6525
-3 4750 6524 6557
-3 4750 6557 6526
-3 4750 6526 6527
-3 4750 6527 6501
-3 6502 6501 6527
-3 6503 6528 4771
-3 5374 6529 6530
-3 6530 6504 5374
-3 4739 6507 6506
-3 4739 6506 6531
-3 6532 6509 6508
-3 6533 6509 6532
-3 6511 6534 6508
-3 6534 6532 6508
-3 6535 6512 6536
-3 6535 6534 6512
-3 6534 6511 6512
-3 6513 6536 6512
-3 6537 6515 1262
-3 1262 6595 6537
-3 4702 6516 4845
-3 6516 6538 4845
-3 6540 6539 6541
-3 6542 6541 5361
-3 6542 5361 6543
-3 6544 5362 6545
-3 5362 6546 6545
-3 5362 6547 6546
-3 6547 2279 6548
-3 6548 2279 6549
-3 6549 2279 6550
-3 2279 6551 6550
-3 6518 6551 2279
-3 6553 6521 5379
-3 5379 6521 6440
-3 5364 5363 6522
-3 5364 6522 6554
-3 6523 6555 6522
-3 6555 6554 6522
-3 5360 6556 6523
-3 6556 6555 6523
-3 5360 5365 6556
-3 6528 6558 4771
-3 5374 6559 6560
-3 6560 6529 5374
-3 6561 5375 6562
-3 6562 5375 4739
-3 6562 4739 6531
-3 6532 6563 6533
-3 6534 6563 6532
-3 6564 6563 6534
-3 6535 6564 6534
-3 6538 6566 4845
-3 4776 6568 5368
-3 6567 6568 4776
-3 6568 6569 5368
-3 5368 6569 6570
-3 6598 5368 6571
-3 5368 6570 6571
-3 6598 6571 6572
-3 6572 6573 6598
-3 5361 6575 6543
-3 3635 6576 5361
-3 5361 6576 6575
-3 5362 6577 3635
-3 6577 6576 3635
-3 6544 6577 5362
-3 5362 2279 6547
-3 5379 6552 6553
-3 5379 6578 6552
-3 5364 6554 6603
-3 6555 6579 6554
-3 6579 6603 6554
-3 6556 6580 6555
-3 6580 6579 6555
-3 5365 5370 6580
-3 6556 5365 6580
-3 5373 6581 6582
-3 6581 5373 6583
-3 6558 5373 4771
-3 6583 5373 6558
-3 5374 6584 6585
-3 6585 6559 5374
-3 5375 6586 6615
-3 6587 5375 6561
-3 6586 5375 6587
-3 6623 6588 5366
-3 6588 6589 5366
-3 6590 6591 5366
-3 6590 5366 6589
-3 6591 6592 6593
-3 6591 6593 5366
-3 5366 6594 5376
-3 5366 6593 6594
-3 5376 6594 5378
-3 6595 6565 6537
-3 6566 6596 4845
-3 4790 6597 6567
-3 6597 6568 6567
-3 6599 6573 6574
-3 6599 6598 6573
-3 6599 6600 6598
-3 5379 6601 6602
-3 5379 6602 6578
-3 6603 6579 6604
-3 6604 6580 6605
-3 6604 6579 6580
-3 5383 5373 6606
-3 6607 6606 5373
-3 5373 6582 6608
-3 6607 5373 6609
-3 6609 5373 6610
-3 6610 5373 6608
-3 6609 6611 5392
-3 6610 6611 6609
-3 6611 6612 5392
-3 5392 5374 5384
-3 5392 6612 5374
-3 6612 6613 5374
-3 6613 6584 5374
-3 6586 6614 6615
-3 6616 6614 6586
-3 6587 6616 6586
-3 6618 6619 5385
-3 5385 6619 6620
-3 6623 5385 6621
-3 6621 5385 6620
-3 6621 6622 6623
-3 6625 6626 6588
-3 6625 6588 6624
-3 6624 6588 6623
-3 6626 6627 6628
-3 6626 6628 6588
-3 6588 6628 6589
-3 6629 6590 6589
-3 6629 6589 6630
-3 6630 6589 6628
-3 6592 6629 6630
-3 6593 6592 6630
-3 6593 6630 5395
-3 5378 6593 5395
-3 6594 6593 5378
-3 6631 6595 1262
-3 6596 6632 4845
-3 6597 4790 6633
-3 4790 6660 6633
-3 6660 6634 6633
-3 6660 6598 6635
-3 6598 6636 6635
-3 6637 6636 6598
-3 6600 6637 6598
-3 5379 6638 6601
-3 6638 5379 6639
-3 6603 6640 6680
-3 6641 6605 6580
-3 6580 5370 6641
-3 5391 6642 6643
-3 5383 6644 5391
-3 5391 6644 6642
-3 6645 6644 5383
-3 6606 6645 5383
-3 6646 6645 6606
-3 6647 6646 6606
-3 6647 6648 6649
-3 6647 6606 6648
-3 6606 6607 6648
-3 6609 6648 6607
-3 5385 6651 6652
-3 6652 6653 5385
-3 6617 6618 5385
-3 6617 5385 6653
-3 6654 6623 6622
-3 6624 6623 6655
-3 6655 6623 6654
-3 6656 6625 6624
-3 6656 6624 6657
-3 6657 6624 6655
-3 6627 6656 6657
-3 6628 6627 6657
-3 6628 6657 5396
-3 6628 5396 5395
-3 6630 6628 5395
-3 1262 6658 6631
-3 6659 4845 6632
-3 6661 6660 6635
-3 6662 6661 6635
-3 6663 6664 6665
-3 6665 6666 6663
-3 5397 6667 6668
-3 5397 6668 6669
-3 6669 6670 5397
-3 6670 6671 5411
-3 6671 6672 5411
-3 5399 5411 6673
-3 5411 6672 6673
-3 6674 5399 6673
-3 6675 6639 5379
-3 5417 5400 6700
-3 6678 6700 5400
-3 6679 6680 6640
-3 6641 6680 6679
-3 6641 5430 6680
-3 6641 5370 5430
-3 4814 6681 6682
-3 4814 6643 6681
-3 4814 5391 6643
-3 6683 6649 6648
-3 6609 5403 6648
-3 6615 6650 5407
-3 5407 6650 6684
-3 6685 6686 5385
-3 6651 5385 6686
-3 5408 6654 6687
-3 6655 6654 5408
-3 5396 6655 5408
-3 6657 6655 5396
-3 6659 6689 4845
-3 6663 6690 6664
-3 6666 6690 6663
-3 5409 6691 6667
-3 6692 5397 6670
-3 5411 5412 6692
-3 5411 6692 6670
-3 5399 6674 5414
-3 6674 6693 5414
-3 6694 6675 5379
-3 6724 6723 6676
-3 6695 6724 6676
-3 6728 6727 6695
-3 6677 6729 6695
-3 6729 6728 6695
-3 6677 5415 6729
-3 5417 6696 6697
-3 5417 6698 6696
-3 6699 6698 5417
-3 6700 6699 5417
-3 5400 6701 6678
-3 5400 6702 6701
-3 5420 4814 6682
-3 6703 5420 6682
-3 6648 6704 6683
-3 5403 6705 6704
-3 5403 6704 6648
-3 5407 6684 6706
-3 5407 6706 5427
-3 6707 5427 6706
-3 5385 6707 6708
-3 5385 6708 6709
-3 6685 5385 6709
-3 5408 6710 6711
-3 6710 5408 6687
-3 6688 6658 6712
-3 6689 6713 4845
-3 6714 5409 6715
-3 6714 6691 5409
-3 6692 6716 5428
-3 5412 6716 6692
-3 5412 6717 6716
-3 5412 5411 6717
-3 6745 6717 5411
-3 6718 6745 5411
-3 6718 5411 6719
-3 6719 5411 5414
-3 6719 5414 6693
-3 5379 6720 6694
-3 6676 6722 6721
-3 6723 6722 6676
-3 6725 6724 6695
-3 6726 6725 6695
-3 6727 6726 6695
-3 6729 5415 6730
-3 5415 5429 6730
-3 6731 5429 6732
-3 6732 5429 5417
-3 6732 5417 6697
-3 5400 6733 6702
-3 5400 6734 6733
-3 6735 5420 6703
-3 5403 6736 6705
-3 5403 5431 6736
-3 5431 6737 6736
-3 5431 6738 6737
-3 5408 6711 6739
-3 6712 6658 6740
-3 6713 6741 4845
-3 6715 5409 6742
-3 5409 4199 6742
-3 5428 6743 4199
-3 4199 6743 6742
-3 6716 6744 5428
-3 6744 6743 5428
-3 6717 6744 6716
-3 5444 6746 6720
-3 6676 6747 4828
-3 6747 6676 6721
-3 6766 6749 6748
-3 5429 6766 6748
-3 5429 6748 6730
-3 6766 5429 6767
-3 6750 5429 6731
-3 6767 5429 6750
-3 5400 6751 6734
-3 5435 6752 6751
-3 5435 6751 5400
-3 6753 5420 6735
-3 6753 6754 5420
-3 5431 6755 6738
-3 6771 6756 6755
-3 5431 6771 6755
-3 6771 5431 6757
-3 6758 6774 5432
-3 5439 6758 5432
-3 6782 6739 6759
-3 6740 6658 6760
-3 6741 6761 4845
-3 6763 6746 5444
-3 4828 6765 6764
-3 4828 6747 6765
-3 5435 6768 6752
-3 6768 5435 6769
-3 5420 6754 5438
-3 6754 6770 5438
-3 6772 6771 6757
-3 5432 6772 6757
-3 6773 6772 5432
-3 6774 6773 5432
-3 5439 6775 6758
-3 6775 5439 6776
-3 5443 6777 6778
-3 5443 6779 6777
-3 6780 6779 5440
-3 6759 6781 6782
-3 6783 6760 4422
-3 4422 6760 6658
-3 6761 6784 4845
-3 5444 6785 6786
-3 6762 5444 6786
-3 6763 5444 6762
-3 5434 4828 6787
-3 6788 4828 6764
-3 6787 4828 6788
-3 6789 6791 5446
-3 6790 6791 6789
-3 5446 6792 5441
-3 6791 6792 5446
-3 6792 6793 5441
-3 4206 5441 6794
-3 5441 6793 6794
-3 4206 6794 6795
-3 6796 4206 6795
-3 5435 6797 6769
-3 5436 6797 5435
-3 6798 5436 6799
-3 6799 5436 5438
-3 6799 5438 6770
-3 6800 6776 5439
-3 6801 5443 6802
-3 6802 5443 6778
-3 5440 6803 6780
-3 5440 6804 6803
-3 6804 5440 6782
-3 4422 6805 6783
-3 6784 6806 4845
-3 6807 6808 6809
-3 6809 6810 6807
-3 5444 6811 6785
-3 6787 6827 5434
-3 6812 6787 6788
-3 6812 6813 6787
-3 6813 6827 6787
-3 6812 6814 6813
-3 5446 6815 6789
-3 6816 4206 6796
-3 5436 6817 6797
-3 6798 6817 5436
-3 5439 6818 6800
-3 6819 6818 5447
-3 5443 6801 5447
-3 5447 6801 6820
-3 6805 4422 6821
-3 6822 4845 6806
-3 6807 6823 6808
-3 6810 6823 6807
-3 5456 6824 6825
-3 6811 5444 5456
-3 6825 6811 5456
-3 6826 6846 6827
-3 6846 5434 6827
-3 6828 6827 6813
-3 6814 6828 6813
-3 6815 5451 6829
-3 6816 6830 4206
-3 5447 6831 6819
-3 6831 5447 6820
-3 5454 5453 6832
-3 6821 4422 6833
-3 6822 6834 4845
-3 6858 6835 6836
-3 6836 6837 6858
-3 6882 6838 6839
-3 6882 6839 6840
-3 6840 6841 5455
-3 5456 6842 6843
-3 5456 6843 6844
-3 6844 6824 5456
-3 5434 6846 6845
-3 5451 6847 6829
-3 6848 6847 5451
-3 6849 4846 6830
-3 6850 4846 6849
-3 5459 6832 6851
-3 5459 5454 6832
-3 6851 6832 6852
-3 5453 5458 6832
-3 6852 6832 5458
-3 5460 5459 6853
-3 5459 6851 6853
-3 5460 6853 6854
-3 6854 6855 5460
-3 6833 4422 6856
-3 6834 6857 4845
-3 6859 6835 6858
-3 6860 6858 6837
-3 6860 6861 6858
-3 6882 6862 6863
-3 6863 6838 6882
-3 6864 5455 6841
-3 6864 6865 5455
-3 5456 6866 6842
-3 5434 6868 6867
-3 5434 6845 6868
-3 5451 6869 6848
-3 6870 4846 6871
-3 6871 4846 6850
-3 6870 5462 4846
-3 6872 6852 5458
-3 5458 5471 6872
-3 5460 6855 5464
-3 6855 6873 5464
-3 5467 5466 6874
-3 5467 6874 5465
-3 6875 6856 4422
-3 6857 6876 4845
-3 6878 6879 5475
-3 6879 6880 5475
-3 6880 6859 5475
-3 6858 5475 6859
-3 6858 5476 5475
-3 6858 5469 5476
-3 5469 6858 6927
-3 6927 6858 6861
-3 6927 6861 6881
-3 6882 6883 6884
-3 6862 6882 6884
-3 6885 5455 6865
-3 6866 5456 6886
-3 5434 6887 4850
-3 5434 6888 6887
-3 6867 6888 5434
-3 6889 6890 5478
-3 5470 6891 6892
-3 5470 6890 6891
-3 5451 6893 6869
-3 6893 5451 5479
-3 6894 6893 5479
-3 6895 6870 6871
-3 6896 6895 6871
-3 6897 6870 6895
-3 5462 6870 6897
-3 5462 6898 4859
-3 5462 6897 6898
-3 5471 6900 6899
-3 5471 6899 6872
-3 5464 6901 5471
-3 6873 6901 5464
-3 5466 5465 6874
-3 4422 6902 6875
-3 6876 6903 4845
-3 5473 5472 6904
-3 5473 6904 5474
-3 5475 6877 6878
-3 5475 5474 6877
-3 5474 6905 6877
-3 5469 6927 5477
-3 6906 6927 6881
-3 6906 6907 6927
-3 6882 6908 6909
-3 6883 6882 6909
-3 4864 6910 6911
-3 6885 6910 4864
-3 6885 4864 5455
-3 5456 6912 6913
-3 6913 6886 5456
-3 6887 6914 4850
-3 6889 5478 6915
-3 6892 6949 5470
-3 6892 6916 6949
-3 5479 6917 6894
-3 6918 5479 6919
-3 6896 5479 6895
-3 6896 6919 5479
-3 5479 6920 6895
-3 6920 6897 6895
-3 5480 6898 6920
-3 6898 6897 6920
-3 4859 6898 5480
-3 5471 6921 6900
-3 6922 6921 5471
-3 6901 6922 5471
-3 6902 4422 6923
-3 6903 6924 4845
-3 5474 6925 6905
-3 5475 6925 5474
-3 6926 6925 5475
-3 5476 5477 6927
-3 6928 6927 6907
-3 6928 6929 6927
-3 6928 6930 6929
-3 4874 6931 6932
-3 6932 6933 4874
-3 6934 6935 6936
-3 6936 6937 6938
-3 6935 6937 6936
-3 6937 6939 6938
-3 6882 6940 6908
-3 6941 6940 6882
-3 6942 6941 6882
-3 6882 6943 6942
-3 4864 6944 6882
-3 6882 6944 6943
-3 6911 6944 4864
-3 6980 6945 6946
-3 6980 6946 6912
-3 6980 6912 5456
-3 6914 6947 4850
-3 6948 6915 5478
-3 5479 6950 6917
-3 6951 6950 5479
-3 6918 6951 5479
-3 6952 6953 6954
-3 6954 6955 6952
-3 4422 6956 6957
-3 4422 6957 6923
-3 6924 6958 4845
-3 6926 6959 6925
-3 6960 6959 6926
-3 5476 6960 6926
-3 6961 6960 5476
-3 6927 6961 5476
-3 6962 6961 6927
-3 6963 6962 6927
-3 6964 6963 6927
-3 6929 6964 6927
-3 6965 6964 6929
-3 6965 6966 6967
-3 6965 6929 6966
-3 6968 6966 6930
-3 6930 6966 6929
-3 6968 6969 6966
-3 6970 6971 6972
-3 6970 6973 6974
-3 6972 6973 6970
-3 6973 6975 6974
-3 5485 6976 6977
-3 6931 4874 6977
-3 6977 4874 5485
-3 6936 6933 6934
-3 6938 6978 6936
-3 6979 6938 6939
-3 6978 6938 6979
-3 4850 6947 6981
-3 5478 6982 6948
-3 6983 6982 5478
-3 6985 6986 6987
-3 6986 6988 6987
-3 6952 6989 6953
-3 6955 6989 6952
-3 4422 6990 6956
-3 6991 4845 6958
-3 6966 6992 6967
-3 6969 6992 6966
-3 6993 6971 6970
-3 6994 6971 6993
-3 6974 6995 6970
-3 6995 6993 6970
-3 6996 6974 6975
-3 6995 6974 6996
-3 5485 6997 6998
-3 5485 6998 6976
-3 6936 5496 6933
-3 5496 6936 6978
-3 6999 6978 6979
-3 5496 6978 6999
-3 7001 4850 6981
-3 7028 4850 7001
-3 7002 7003 7004
-3 7002 7005 7006
-3 7004 7005 7002
-3 7005 7007 7006
-3 7008 7009 5488
-3 6984 5488 7009
-3 6985 5488 6984
-3 6987 5488 6985
-3 5488 7010 7011
-3 5488 6988 7010
-3 5488 6987 6988
-3 6990 4422 7012
-3 6991 7013 4845
-3 5494 7014 7015
-3 7015 7016 5494
-3 7016 7017 5494
-3 7018 7017 7019
-3 7020 6993 7021
-3 7020 7018 6993
-3 6994 6993 7019
-3 7019 6993 7018
-3 6995 7021 6993
-3 7022 7021 6995
-3 6996 7022 6995
-3 7024 7025 5485
-3 7025 6997 5485
-3 7026 5496 6999
-3 7000 4877 7027
-3 7028 7029 4850
-3 7002 7030 7003
-3 7030 7002 7031
-3 7002 7006 7031
-3 7007 7032 7006
-3 7032 7031 7006
-3 5486 7032 7008
-3 7008 7032 7007
-3 5488 5486 7008
-3 5488 7011 5501
-3 5501 7011 7033
-3 7034 7035 7036
-3 7036 7037 7034
-3 7037 7038 7034
-3 7040 7012 4422
-3 7013 7041 4845
-3 5493 7042 7043
-3 5492 7042 5493
-3 7014 5494 7043
-3 7043 5494 5493
-3 5494 7017 5495
-3 5495 7017 7018
-3 7044 7018 7020
-3 5495 7018 7044
-3 5485 7045 7046
-3 7046 7047 5485
-3 7023 5485 7047
-3 7024 5485 7023
-3 7048 5496 7026
-3 4877 7049 7050
-3 7050 7027 4877
-3 4850 7029 7051
-3 7052 7031 5497
-3 7031 7032 5497
-3 7053 5501 7033
-3 7054 7056 7081
-3 7055 7056 7054
-3 7081 7057 5512
-3 7056 7057 7081
-3 7057 7058 5512
-3 7058 7059 5512
-3 7059 7060 5512
-3 7060 7061 5512
-3 5515 7062 7063
-3 5515 7063 7064
-3 5515 7064 7065
-3 5515 7065 7035
-3 7035 7034 5515
-3 7034 7038 7066
-3 7034 7066 5489
-3 7067 7066 7068
-3 7067 5489 7066
-3 5489 7067 5502
-3 7040 4422 7039
-3 4422 7069 7039
-3 7070 4845 7041
-3 7071 7072 5504
-3 7072 5492 5504
-3 7072 7042 5492
-3 5495 7073 5519
-3 7073 5495 7044
-3 5485 7074 7075
-3 7045 5485 7075
-3 5496 7048 4962
-3 4962 7048 7076
-3 7049 4877 7077
-3 7051 7078 4850
-3 7052 5497 7079
-3 7080 5501 7053
-3 7082 7054 7081
-3 5512 5510 7081
-3 5512 7061 7083
-3 5512 7083 5514
-3 5514 7083 7084
-3 5514 7084 7085
-3 5514 7114 5515
-3 7086 7114 5514
-3 7087 7088 5515
-3 7088 7062 5515
-3 7067 7068 7089
-3 7067 7089 5531
-3 7070 7093 4845
-3 5519 7094 7071
-3 5519 7071 5504
-3 7094 5519 7095
-3 5519 7096 7123
-3 5519 7097 7096
-3 5519 7073 7097
-3 7098 7100 5527
-3 7099 7100 7098
-3 5527 7100 5485
-3 7100 7074 5485
-3 4962 7101 7102
-3 7101 4962 7076
-3 7077 4877 7103
-3 7078 7104 4850
-3 5497 5535 7079
-3 7079 5535 7105
-3 7080 7106 5501
-3 5522 7107 7108
-3 4292 7107 5522
-3 5522 7108 7109
-3 5522 7109 7110
-3 7111 5522 7110
-3 5523 7082 7081
-3 7112 7082 5523
-3 7081 5510 5523
-3 5514 7085 7113
-3 7086 5514 7113
-3 7115 5515 7114
-3 7087 5515 7115
-3 7116 5531 7117
-3 7090 5531 7089
-3 7090 7117 5531
-3 4422 7091 7092
-3 4422 7118 7091
-3 7069 4422 7092
-3 7119 4845 7093
-3 7119 7120 4845
-3 7095 5519 7121
-3 5519 7122 7121
-3 7123 7122 5519
-3 7145 7124 5527
-3 7098 5527 7124
-3 7102 7125 4962
-3 4963 7129 7130
-3 7103 4877 4963
-3 7130 7103 4963
-3 4850 7131 7154
-3 4850 7104 7131
-3 7132 7105 5535
-3 5501 7106 5558
-3 7106 7133 5558
-3 7107 4292 7134
-3 5522 7111 7135
-3 5549 7135 7136
-3 5549 5522 7135
-3 5523 7137 7112
-3 7162 7138 7137
-3 5523 7162 7137
-3 5523 5536 7162
-3 7139 7171 5538
-3 7139 5538 7140
-3 7140 5538 5531
-3 5531 7141 7140
-3 7142 7141 5531
-3 7116 7142 5531
-3 7118 4422 7143
-3 7120 7144 4845
-3 7180 7145 5527
-3 7146 7124 7145
-3 4962 7147 7148
-3 7147 4962 7125
-3 7192 7149 7150
-3 7126 7192 7150
-3 7127 7192 7126
-3 7127 5533 7192
-3 5533 7151 5534
-3 5533 7128 7151
-3 5533 7127 7128
-3 7151 7152 5534
-3 7129 4963 7153
-3 7154 7155 4850
-3 5535 7156 7132
-3 7156 5535 7157
-3 7133 7158 5558
-3 7159 7134 4292
-3 5549 7136 7160
-3 5549 7160 7161
-3 5536 7163 7162
-3 7164 7163 5536
-3 7164 5536 4914
-3 7167 7169 7168
-3 7169 5538 7170
-3 7171 7170 5538
-3 5539 7172 7173
-3 7173 7174 5539
-3 5540 5539 7175
-3 5539 7174 7175
-3 7176 5540 7175
-3 4422 7177 7143
-3 7144 7178 4845
-3 5543 7179 7180
-3 7145 7180 7181
-3 7182 7146 7145
-3 7182 7145 7183
-3 7183 7145 7181
-3 7182 7183 7184
-3 7186 5555 4939
-3 7186 4939 7187
-3 7188 7187 4939
-3 7148 7189 4962
-3 7192 7190 7191
-3 7149 7192 7191
-3 5534 7193 5546
-3 5534 7152 7193
-3 5546 7193 5547
-3 7153 4963 7194
-3 4850 7195 7237
-3 4850 7155 7195
-3 5535 7196 7157
-3 7197 7196 5535
-3 7198 5558 7158
-3 7200 7159 4292
-3 7200 4292 7201
-3 5549 7202 7203
-3 5549 7161 7202
-3 7204 7205 5549
-3 7206 5549 7205
-3 7208 7207 7164
-3 4914 7208 7164
-3 7209 7208 4914
-3 4914 5559 7209
-3 5559 7210 7209
-3 7211 7165 7166
-3 7212 7211 7166
-3 7167 7165 7211
-3 7169 7167 7211
-3 7213 7214 7215
-3 7172 7213 7215
-3 7172 5539 7213
-3 5539 7216 7213
-3 5539 5551 7217
-3 5539 7217 7216
-3 7218 7217 5551
-3 7218 5551 5540
-3 7218 5540 7176
-3 7177 4422 7219
-3 7178 7220 4845
-3 7179 5542 7221
-3 5543 5542 7179
-3 7180 7179 7222
-3 7222 7179 7221
-3 7181 7180 7223
-3 7223 7180 7222
-3 5552 7181 7223
-3 7183 7181 5552
-3 5563 7183 5552
-3 7184 7183 5563
-3 5563 7224 7185
-3 5563 7185 7184
-3 5563 7226 7225
-3 7224 5563 7225
-3 5555 7227 7228
-3 7186 7227 5555
-3 7229 7188 4941
-3 7188 4939 4941
-3 7229 4941 7230
-3 7189 7231 4962
-3 7192 7232 7190
-3 7233 7232 7192
-3 7192 5545 7233
-3 5545 7234 7233
-3 5556 7235 5545
-3 5545 7235 7234
-3 7193 7235 5556
-3 5547 7193 5556
-3 7194 4963 7236
-3 7239 7197 4945
-3 7239 4945 7240
-3 7241 7198 7199
-3 7242 7241 7199
-3 7198 7241 5558
-3 4292 7243 7201
-3 5549 7203 7244
-3 7204 5549 7244
-3 5549 7206 7245
-3 7246 5549 7245
-3 5559 7247 7210
-3 5560 7248 7249
-3 5560 7249 5559
-3 5559 7249 7247
-3 7212 7249 7248
-3 7211 7212 7248
-3 7250 7251 7252
-3 7214 7250 7252
-3 7214 7213 7250
-3 7213 7253 7250
-3 7254 7253 7216
-3 7253 7213 7216
-3 7217 7254 7216
-3 7255 7254 7217
-3 7218 7255 7217
-3 4422 7256 7219
-3 7220 7257 5643
-3 5542 5562 7258
-3 5542 7258 7221
-3 7258 7259 7221
-3 7223 7259 5569
-3 7223 7222 7259
-3 7222 7221 7259
-3 7260 7226 4960
-3 4960 7226 5563
-3 7260 4960 7261
-3 7228 4960 5555
-3 7261 4960 7228
-3 4941 5570 7262
-3 7262 7230 4941
-3 7231 7263 4962
-3 7236 4963 7264
-3 7237 7238 4373
-3 7238 7265 4373
-3 7266 7240 4945
-3 7241 7242 7267
-3 7267 5558 7241
-3 7267 7268 5558
-3 4292 5576 7243
-3 7243 5576 7269
-3 4346 7270 7271
-3 4346 7246 7270
-3 4346 5549 7246
-3 7250 7272 7251
-3 7253 7272 7250
-3 7273 7272 7253
-3 7254 7273 7253
-3 7256 4422 7274
-3 5643 7257 7275
-3 7276 5643 7275
-3 7258 7277 7278
-3 7258 5562 7277
-3 5562 5568 7277
-3 5569 7258 7279
-3 5569 7259 7258
-3 7258 7278 7279
-3 5570 4961 7280
-3 5570 7280 7281
-3 5570 7281 7262
-3 4962 7263 7282
-3 7283 4962 7282
-3 7264 4963 7284
-3 4373 7285 7286
-3 7285 4373 7265
-3 7287 7266 4945
-3 7316 7287 4945
-3 7268 7288 5558
-3 7289 7269 5576
-3 4346 7271 7290
-3 7290 5566 4346
-3 7290 7291 5566
-3 7291 5571 5566
-3 4422 7292 7274
-3 7276 7293 5643
-3 7295 7297 7298
-3 7296 7297 7295
-3 7297 7299 7298
-3 5568 7300 7301
-3 5587 7300 5568
-3 7301 7277 5568
-3 5569 7279 7302
-3 4961 7303 7304
-3 7280 4961 7304
-3 4962 7283 7305
-3 7306 4962 7305
-3 7284 4963 7307
-3 7286 7308 4373
-3 7309 7310 7311
-3 7309 7312 7313
-3 7311 7312 7309
-3 7312 7314 7313
-3 7316 4945 7315
-3 5580 5558 7317
-3 7317 5558 7288
-3 5576 7319 7318
-3 5576 7318 7289
-3 7320 5581 7322
-3 7322 5581 7323
-3 7361 5571 7324
-3 5571 7291 7324
-3 7325 7326 7327
-3 7327 7328 7325
-3 7330 7331 7332
-3 7331 7333 7332
-3 4422 7334 7335
-3 7335 7292 4422
-3 7293 7336 5643
-3 5585 7337 7338
-3 7294 5585 7338
-3 7294 7295 5585
-3 7295 7339 5585
-3 7340 7298 7341
-3 7340 7339 7298
-3 7339 7295 7298
-3 7299 7341 7298
-3 5587 7342 7300
-3 7302 7343 7377
-3 4961 7344 7303
-3 7345 4962 7346
-3 7346 4962 7306
-3 7307 4963 7347
-3 7308 7348 4373
-3 7309 7349 7310
-3 7313 7349 7309
-3 7350 7349 7313
-3 7314 7350 7313
-3 7464 7351 7352
-3 7315 4945 7464
-3 7352 7315 7464
-3 5580 7317 7353
-3 5576 7355 7319
-3 5576 7356 7355
-3 5576 7357 7356
-3 7321 5581 7320
-3 7321 7357 5581
-3 7357 5576 5581
-3 5581 7358 7323
-3 5581 7359 7358
-3 7361 7360 5581
-3 7362 7326 7325
-3 7363 7326 7362
-3 7364 7325 7328
-3 7364 7365 7325
-3 7365 7362 7325
-3 7364 7366 7365
-3 7367 7329 7330
-3 7368 7329 7367
-3 7369 7367 7332
-3 7367 7330 7332
-3 7333 7369 7332
-3 7334 4422 7370
-3 7371 5643 7336
-3 5585 5584 7337
-3 5584 7372 7337
-3 5583 5585 7373
-3 7373 5585 7339
-3 7374 7339 7375
-3 7374 7373 7339
-3 7340 7375 7339
-3 7342 5587 7376
-3 7377 7378 7302
-3 7302 7378 5588
-3 7379 7380 4977
-3 7380 7344 4977
-3 5589 7381 7382
-3 5589 7383 7381
-3 5589 7384 7385
-3 5589 7385 7383
-3 7346 7385 7384
-3 7346 7384 7345
-3 7345 7384 7386
-3 7345 7386 5596
-3 7347 4963 7387
-3 7348 7388 4373
-3 7464 7389 7390
-3 7390 7351 7464
-3 5590 7353 7354
-3 5590 7354 7391
-3 5580 7353 5590
-3 5581 7392 7359
-3 7360 7392 5581
-3 7362 7393 7363
-3 7393 5593 7394
-3 7393 7362 5593
-3 7362 7365 5593
-3 5593 7365 7366
-3 5593 7366 7395
-3 5593 7396 5607
-3 5593 7395 7396
-3 7396 7397 5607
-3 7367 7398 7368
-3 7369 7398 7367
-3 4422 7399 7400
-3 7400 7370 4422
-3 7371 7401 5643
-3 5584 7402 7372
-3 7372 7402 7403
-3 5600 5583 7402
-3 7403 7402 5583
-3 7373 7404 5583
-3 7404 7403 5583
-3 7374 7404 7373
-3 5602 7405 7406
-3 5602 7406 7376
-3 5602 7376 5587
-3 5588 7407 7408
-3 5594 5588 7408
-3 7407 5588 7378
-3 4977 7409 7379
-3 7410 7411 7412
-3 7410 5589 7411
-3 7411 5589 7413
-3 5589 7414 7413
-3 5589 7415 7414
-3 7416 5589 7417
-3 7417 5589 7382
-3 5596 7384 5589
-3 7386 7384 5596
-3 7387 4963 7418
-3 7388 7419 4373
-3 7389 7464 7420
-3 5590 7421 7422
-3 7421 5590 7391
-3 5593 7423 7394
-3 5607 7424 7447
-3 5607 7397 7424
-3 7424 7425 7447
-3 7425 7426 7428
-3 7426 7427 7428
-3 7427 7429 7428
-3 7399 4422 7430
-3 7431 5643 7401
-3 5602 7433 7405
-3 5594 7408 7434
-3 7409 7435 7436
-3 7409 4977 7435
-3 4977 5611 7435
-3 7410 7437 7438
-3 7412 7437 7410
-3 5589 7439 7415
-3 7416 7439 5589
-3 4963 7461 7440
-3 4963 7440 7418
-3 7441 4373 7419
-3 7464 7442 7443
-3 7464 7443 7420
-3 5590 7422 7486
-3 7422 7444 7486
-3 5593 7445 7423
-3 7446 7445 5593
-3 5608 7447 7425
-3 5608 7425 7428
-3 7448 7428 7449
-3 7448 5608 7428
-3 7429 7449 7428
-3 4422 7450 7430
-3 5643 7431 7451
-3 7452 5643 7451
-3 7453 7432 7433
-3 7454 7432 7453
-3 5602 5609 7453
-3 7433 5602 7453
-3 5594 7455 5610
-3 7455 5594 7434
-3 5611 7456 7457
-3 7457 7435 5611
-3 7410 7458 7459
-3 7438 7458 7410
-3 7461 4963 7460
-3 7462 4373 7441
-3 7462 7463 4373
-3 7465 7442 7464
-3 7466 7486 7444
-3 5593 5615 7446
-3 7446 5615 7467
-3 7447 7493 5617
-3 7447 5608 7468
-3 7447 7468 7493
-3 7468 5608 7469
-3 7469 5608 7448
-3 7450 4422 7470
-3 7452 7471 5643
-3 7472 7454 7453
-3 7473 7454 7472
-3 5609 7474 7453
-3 7453 7474 7472
-3 5609 7475 7474
-3 5610 7475 5609
-3 5610 7476 7475
-3 5610 7455 7476
-3 7477 7478 5611
-3 5611 7478 7456
-3 7410 7459 7480
-3 7410 7480 5623
-3 4963 7507 7481
-3 4963 7481 7460
-3 7463 7482 4373
-3 7464 7483 7465
-3 7464 7484 7483
-3 4415 7485 7464
-3 7464 7485 7484
-3 7487 7486 7466
-3 7487 7488 7486
-3 7487 7489 7488
-3 5615 7490 7467
-3 5617 7491 7492
-3 7493 7491 5617
-3 7494 7493 7468
-3 7469 7494 7468
-3 7495 7494 7469
-3 4422 7496 7497
-3 7497 7470 4422
-3 5643 7471 7498
-3 7499 5643 7498
-3 7472 7500 7473
-3 7474 7500 7472
-3 7501 7500 7474
-3 7475 7501 7474
-3 5619 7502 7477
-3 7502 7503 7477
-3 7504 7478 7477
-3 7504 7477 7505
-3 7505 7477 7503
-3 7479 7504 7505
-3 7479 7505 5623
-3 7480 7479 5623
-3 7507 4963 7506
-3 4963 5677 7506
-3 7508 4373 7482
-3 4415 7509 7485
-3 4415 7510 7509
-3 4415 7486 7522
-3 7511 7522 7488
-3 7522 7486 7488
-3 7489 7511 7488
-3 5615 7512 7490
-3 5616 7512 5615
-3 7492 5616 5617
-3 7512 5616 7492
-3 7496 4422 7513
-3 5643 7499 7514
-3 7515 5643 7514
-3 7503 7502 5619
-3 5623 7505 7503
-3 7506 5677 7516
-3 4373 7508 7517
-3 7517 7518 4373
-3 7519 7510 4415
-3 7520 7510 7519
-3 7521 7519 7522
-3 7519 4415 7522
-3 4422 7523 7513
-3 5088 7523 4422
-3 7524 5643 7515
-3 5677 7525 7516
-3 7526 4373 7518
-3 7527 7520 7519
-3 7528 7519 7521
-3 7528 7529 7519
-3 7530 7540 5624
-3 5088 7531 7532
-3 7532 7523 5088
-3 7524 7533 5643
-3 5677 7534 7535
-3 5677 7535 7525
-3 4373 7526 7536
-3 7536 7537 4373
-3 5629 7527 7519
-3 5629 5041 7527
-3 5041 7538 7527
-3 5629 7519 7529
-3 5629 7529 7539
-3 5634 7540 7530
-3 7542 5631 5630
-3 7542 7543 5631
-3 7544 5631 7543
-3 5088 7545 7546
-3 7546 7531 5088
-3 5643 7533 7547
-3 7548 5643 7547
-3 5677 7549 7550
-3 7534 5677 7550
-3 7551 4373 7537
-3 5041 5632 7538
-3 7538 5632 7552
-3 5633 7553 7567
-3 5629 7553 5633
-3 5629 7539 7553
-3 7553 7554 7567
-3 5037 7540 5634
-3 5043 7555 7556
-3 7541 7542 5630
-3 7541 5630 7556
-3 7557 5631 7544
-3 5088 7558 7559
-3 7559 7545 5088
-3 5643 7548 7560
-3 7561 5643 7560
-3 5677 7562 7549
-3 4373 7551 7563
-3 7563 7564 4373
-3 5632 7565 7552
-3 7566 7565 5639
-3 5633 7567 5639
-3 5043 5638 7555
-3 7555 5638 7568
-3 5641 7569 7570
-3 5641 7557 7569
-3 5641 5631 7557
-3 5088 7571 7572
-3 7572 7558 5088
-3 5643 7561 7573
-3 7574 5643 7573
-3 5677 7575 7576
-3 5677 7576 7562
-3 7577 4373 7564
-3 5639 7578 7566
-3 7567 7579 5639
-3 7579 7578 5639
-3 7580 5638 7581
-3 7580 7568 5638
-3 5641 7582 7583
-3 5641 7570 7582
-3 5088 7584 7585
-3 7585 7571 5088
-3 5643 7574 7586
-3 7587 5643 7586
-3 5677 7588 7589
-3 7575 5677 7589
-3 4373 7577 7590
-3 7591 7592 7593
-3 7593 7594 7591
-3 5638 5645 7581
-3 7581 5645 7595
-3 5641 7583 7596
-3 7596 7597 5641
-3 5088 7598 7599
-3 7599 7584 5088
-3 5643 7587 7600
-3 7601 5643 7600
-3 5677 7602 7588
-3 4373 7590 7603
-3 7604 7592 7591
-3 7605 7591 7594
-3 7605 7606 7591
-3 7606 7604 7591
-3 7605 7607 7606
-3 7595 5645 7609
-3 7597 7610 5641
-3 5088 7611 7612
-3 7610 7611 5088
-3 7612 7598 5088
-3 5643 7601 7613
-3 7614 5643 7613
-3 5677 7615 7602
-3 4373 7603 7616
-3 7618 7604 7617
-3 7606 7619 7604
-3 7619 7617 7604
-3 7607 7620 7606
-3 7620 7619 7606
-3 7621 7607 7608
-3 7621 7620 7607
-3 7623 7624 5645
-3 7624 7609 5645
-3 5643 7614 7625
-3 5643 7625 7626
-3 5677 7627 7615
-3 7616 7628 7629
-3 7630 7631 7632
-3 7630 7633 7634
-3 7632 7633 7630
-3 7633 7635 7634
-3 5083 5652 7636
-3 5646 5083 7636
-3 5646 7636 7637
-3 7638 5646 7637
-3 7617 7639 7618
-3 7639 7640 7641
-3 7639 7617 7640
-3 7617 7619 7640
-3 7620 7640 7619
-3 7621 5650 7620
-3 5650 7622 7642
-3 5650 7621 7622
-3 7642 7643 5650
-3 5651 5092 7644
-3 7644 7645 5651
-3 5651 7645 7646
-3 5645 5651 7647
-3 5651 7646 7647
-3 7648 5645 7647
-3 7623 5645 7648
-3 5643 7626 7649
-3 5643 7649 7650
-3 7651 5643 7650
-3 5677 7652 7627
-3 7616 7629 7653
-3 7616 7653 7654
-3 7630 7655 7631
-3 7655 7656 7657
-3 7655 7630 7656
-3 7630 7634 7656
-3 7658 7634 7635
-3 7658 7659 7634
-3 7659 7656 7634
-3 7658 7660 7659
-3 7636 5652 7661
-3 5646 7638 7662
-3 5653 5646 7663
-3 5646 7662 7663
-3 7666 5653 7664
-3 5653 7663 7664
-3 7666 7664 7665
-3 7668 7641 7640
-3 7640 5655 7668
-3 5650 7669 5105
-3 5650 7643 7669
-3 7669 7670 5105
-3 5092 7671 7644
-3 5643 7651 7672
-3 7673 5643 7672
-3 5664 7674 7675
-3 5664 7676 7677
-3 7675 7676 5664
-3 7678 7679 7680
-3 5665 7680 7681
-3 5677 7682 7652
-3 4509 7683 7684
-3 4509 7654 7683
-3 4509 7616 7654
-3 7656 7685 7657
-3 7685 7686 7687
-3 7685 7656 7686
-3 7656 7659 7686
-3 5658 7659 7688
-3 5658 7686 7659
-3 7660 7688 7659
-3 7689 5658 7688
-3 5652 5658 7712
-3 5652 7712 7690
-3 5652 7690 7661
-3 5666 7666 7667
-3 5666 7667 7691
-3 7691 7692 5666
-3 5660 7693 7694
-3 7668 5660 7694
-3 5655 5660 7668
-3 5105 7670 7695
-3 5105 7695 5662
-3 5662 7696 7697
-3 5662 7695 7696
-3 7671 5118 7698
-3 5643 7673 7699
-3 7700 5643 7699
-3 5664 5663 7674
-3 5663 7701 7674
-3 7677 7702 5664
-3 5664 7702 5112
-3 7703 5112 7702
-3 5671 7704 7678
-3 7680 5671 7678
-3 5665 7681 7705
-3 7705 7706 5665
-3 5677 7707 7682
-3 4509 7684 7708
-3 7686 7709 7687
-3 5658 7689 7710
-3 5658 7710 7711
-3 7712 5658 7711
-3 5660 5666 7713
-3 5666 7692 7713
-3 7713 7693 5660
-3 5662 7697 7714
-3 7698 5118 7715
-3 5643 7700 7716
-3 5643 7716 7717
-3 7718 5643 7717
-3 5663 7719 7701
-3 5112 7719 5663
-3 7720 7719 5112
-3 5112 7703 7721
-3 5673 5112 7722
-3 5112 7721 7722
-3 5114 7724 7726
-3 7724 7725 7726
-3 7727 5667 7726
-3 5667 5114 7726
-3 7727 7728 5667
-3 7728 5669 5667
-3 7704 5671 5669
-3 7728 7704 5669
-3 7706 7729 5665
-3 5677 7730 7707
-3 4509 7708 7731
-3 4509 7731 7777
-3 7686 7761 7709
-3 7709 7761 7732
-3 5662 7714 7736
-3 7736 7737 5662
-3 7738 7739 5118
-3 7715 5118 7740
-3 7740 5118 7739
-3 5643 7718 7741
-3 5643 7741 7742
-3 7743 5643 7742
-3 5112 7744 7720
-3 5112 7746 7745
-3 5112 7745 7744
-3 5673 7723 7747
-3 5673 7722 7723
-3 7747 7748 5673
-3 7750 7751 5683
-3 7751 7752 5683
-3 7752 7753 5683
-3 7724 5683 7754
-3 5683 7753 7754
-3 5665 7755 7756
-3 7755 5665 7729
-3 5677 7757 7758
-3 7730 5677 7758
-3 7777 7731 7759
-3 7777 7759 7760
-3 7777 7778 7761
-3 5679 5691 7779
-3 5126 7762 7763
-3 5126 7764 7762
-3 7734 5126 7733
-3 7734 7764 5126
-3 7733 5126 5680
-3 7733 5680 7735
-3 7735 5680 7765
-3 5662 7737 7766
-3 5662 7766 5693
-3 7767 5693 7766
-3 5118 7768 7769
-3 7738 5118 7769
-3 5643 7743 7770
-3 5698 5643 7770
-3 7771 5698 7770
-3 5112 5135 7746
-3 5135 5694 7772
-3 5135 7772 7746
-3 5683 5673 7748
-3 7749 5683 7748
-3 7750 5683 7749
-3 5665 7756 5703
-3 7756 7773 5703
-3 5677 7774 7775
-3 5677 7775 7776
-3 7776 7757 5677
-3 7779 7780 5679
-3 5679 7780 5690
-3 5691 7781 7779
-3 5692 7783 7782
-3 5692 7782 5691
-3 5691 7782 7781
-3 7785 7784 5126
-3 7785 5126 7763
-3 7765 5680 7786
-3 5693 7767 7787
-3 5693 7787 7788
-3 5118 5693 7789
-3 7789 5693 7788
-3 7768 5118 7789
-3 5698 7771 7790
-3 5698 7790 7791
-3 7792 5698 7791
-3 7772 5694 5698
-3 5698 7793 7772
-3 5696 7794 7795
-3 5687 7796 5696
-3 5696 7796 7794
-3 7797 7796 5688
-3 5688 7796 5687
-3 5688 5703 7797
-3 7798 5703 7773
-3 5677 7800 7801
-3 7801 7774 5677
-3 7802 5690 7780
-3 7803 7783 5692
-3 7803 7804 7783
-3 7784 7806 5697
-3 7806 7805 5697
-3 7786 5680 7807
-3 5698 7792 7808
-3 7809 5698 7808
-3 7810 7793 5698
-3 7810 5698 7811
-3 7811 7812 7813
-3 7810 7811 7813
-3 7813 7812 7814
-3 5696 7795 5702
-3 7795 7815 5702
-3 5703 7816 7797
-3 5703 7817 7816
-3 7799 5703 7798
-3 7799 7817 5703
-3 7818 7819 5677
-3 7819 7800 5677
-3 5690 7802 7820
-3 7803 5690 7820
-3 7821 7803 7820
-3 7804 7803 7821
-3 7822 7804 7821
-3 7805 7823 5697
-3 7824 7825 5680
-3 7825 7807 5680
-3 5706 5707 7826
-3 5698 7809 7827
-3 5698 7827 7828
-3 7829 5698 7828
-3 7829 7830 5698
-3 7830 7831 5698
-3 7832 5698 7831
-3 7811 5698 7832
-3 7833 7811 7832
-3 7812 7811 7833
-3 7834 7812 7833
-3 7814 7812 7834
-3 5702 7815 7835
-3 5711 5702 7835
-3 7836 5711 7835
-3 5677 7837 7838
-3 7818 5677 7838
-3 7839 4521 7823
-3 4521 5697 7823
-3 5713 7825 7824
-3 5713 7840 7825
-3 7826 5714 5706
-3 5711 7836 7841
-3 5716 7841 7842
-3 5716 5711 7841
-3 5718 7843 5677
-3 7843 7844 5677
-3 7837 5677 7844
-3 4521 7839 7845
-3 4521 7845 7846
-3 4521 7846 7847
-3 4521 7847 7840
-3 5716 7842 7848
-3 5716 7848 7849
-3 7850 7851 5718
-3 7852 5718 7851
-3 7843 5718 7852
-3 5716 7849 7853
-3 5716 7853 5718
-3 5718 7853 7854
-3 7855 5718 7854
-3 5718 7855 7856
-3 5718 7856 7857
-3 5718 7857 7858
-3 5718 7858 7859
-3 7850 5718 7859
-
-CELL_DATA 13733
-POINT_DATA 7860
-NORMALS normals float
--0.133614 -0.057263 -0.989378 -0.0307275 -0.537162 -0.842919 -0.864861 -0.161839 -0.47521
--0.0591288 -0.790848 -0.60915 -0.72247 0.175378 -0.66879 0.236808 -0.629513 -0.740024
-0.197983 -0.368125 -0.908453 0.355323 -0.801092 -0.48166 0.285198 -0.791312 -0.540821
--0.618792 -0.400138 -0.676007 -0.398669 -0.360336 -0.843339 0 -0.0860472 -0.996291
-0.65077 -0.224068 -0.72546 -0.616992 0.576954 -0.535205 0.303636 -0.510558 -0.804448
-0.0991771 0.682572 -0.724058 0.372129 0.614105 -0.695985 -0.490425 0.764772 -0.41786
-0.0313472 0.583987 -0.811158 0.399766 -0.323516 -0.857627 0.216481 0.546615 -0.808918
-0.390625 0.179303 -0.902919 -0.088772 0.773204 -0.627914 -0.161114 0.301929 -0.939618
-0.336389 -0.421911 -0.841922 -0.529158 -0.497371 -0.687469 -0.448965 -0.270927 -0.851486
-0.456537 0.204655 -0.865847 -0.370621 0.853657 -0.365937 -0.188935 0.739997 -0.645529
-0.0329652 -0.212296 -0.976649 -0.149265 -0.468952 -0.870519 0.135512 0.597534 -0.79031
--0.431091 0.395359 -0.811081 -0.313014 -0.35348 -0.881518 0.208532 0.181332 -0.961058
-0.440965 0.440965 -0.781728 0.381019 0.634407 -0.672571 -0.260464 0.83826 -0.479039
-0 0.637398 -0.770535 0.253912 -0.463967 -0.848683 -0.745225 -0.1198 -0.655963
--0.819732 -0.123691 -0.559232 0.351087 -0.152592 -0.923826 0.299891 -0.766145 -0.568407
--0.0578228 -0.708329 -0.70351 -0.298115 -0.407947 -0.862964 0.626218 0.27526 -0.72944
--0.428964 0 -0.903322 -0.840707 0.309226 -0.444512 0.612134 -0.612134 -0.500582
-0.778143 0.124987 -0.615526 0.298546 0.138859 -0.94424 -0.483754 0.68549 -0.544138
-0.150583 0.282344 -0.947421 0.318835 -0.670203 -0.670203 -0.447214 0 -0.894427
--0.557993 -0.557993 -0.614238 -0.350425 -0.313294 -0.882638 0.678742 0.132751 -0.722279
-0.184754 -0.606401 -0.773398 -0.555685 -0.412346 -0.721932 -0.54253 -0.19323 -0.817511
--0.454534 -0.307546 -0.835951 0.309976 0.302415 -0.901366 0.791268 0.485184 -0.372145
--0.601158 0 -0.79913 -0.195297 0.328291 -0.924167 0.561633 0.64151 -0.522527
--0.430992 0.549168 -0.716003 0.450158 -0.054019 -0.891313 -0.0141727 -0.37479 -0.927001
--0.483179 0.180464 -0.856721 -0.327193 0.433721 -0.839542 0.334286 0.754839 -0.564332
-0.671316 0.671909 -0.312846 0.344796 0.158164 -0.925257 0.22389 0.743178 -0.630524
--0.553661 0.562312 -0.614218 -0.166154 -0.166154 -0.972001 -0.0172758 -0.302326 -0.953048
-0.591926 0.484469 -0.644137 -0.687459 0.261533 -0.677496 -0.505059 0.325209 -0.799471
-0.166733 0.45256 -0.876008 0.588363 0.588363 -0.55467 -0.406719 0.382316 -0.829707
-0.473568 -0.163299 -0.865486 0.720113 -0.256824 -0.644577 0.236649 -0.191878 -0.95246
-0.413754 0.227159 -0.881593 -0.417457 -0.790013 -0.449009 0.124878 -0.405854 -0.905366
--0.39225 -0.851721 -0.347435 -0.239402 -0.729666 -0.640527 -0.0931752 -0.0931752 -0.99128
-0.123225 0.432494 -0.893177 -0.249097 -0.886882 -0.389089 0.217978 -0.743821 -0.631836
-0.732431 0.259049 -0.629634 -0.737644 -0.569222 -0.363137 -0.669417 -0.68991 -0.275509
-0.821447 -0.111914 -0.559196 -0.924616 0.233679 -0.300798 -0.731344 -0.200835 -0.651768
--0.487093 0.295284 -0.821917 0.119911 -0.875437 -0.468222 -0.0338245 -0.717313 -0.69593
--0.0261782 0.279234 -0.959866 -0.0250979 0.633721 -0.773154 0.119187 0.815737 -0.566011
-0.879941 0.148971 -0.451122 0.201057 -0.61231 -0.764626 -0.220722 -0.715565 -0.662758
--0.919569 -0.0491032 -0.389849 -0.835811 -0.311849 -0.451853 0.523791 0.363162 -0.770555
-0.492487 -0.363645 -0.790708 -0.236316 -0.379469 -0.894516 0.285703 -0.82894 -0.480866
--0.603185 -0.603185 -0.521857 0.582435 0.465226 -0.666584 -0.634173 0.76534 -0.109907
--0.584343 -0.235207 -0.776673 -0.0678275 -0.131887 -0.988941 -0.269185 -0.72255 -0.636757
--0.634909 -0.317455 -0.704353 0.0535556 -0.444923 -0.893966 0.512611 -0.367788 -0.775862
-0.341278 -0.713496 -0.611925 -0.487268 -0.603938 -0.630736 -0.378509 -0.485634 -0.787966
-0.0320423 0.339926 -0.939906 -0.550019 0.821907 -0.148148 0.0585813 -0.422704 -0.904372
-0.382161 0.543608 -0.747291 0.500733 0.646371 -0.575734 0.0850264 0.786494 -0.611717
--0.159823 -0.820268 -0.549196 0.365676 -0.424613 -0.828242 0.0242708 -0.651266 -0.758462
--0.507728 0.237573 -0.828113 0.60161 -0.6034 -0.523425 -0.809091 0.35261 -0.470147
-0.216092 -0.520584 -0.826012 -0.357151 -0.0957722 -0.929124 -0.846672 0.235721 -0.477055
-0.660332 -0.623161 -0.419085 -0.68403 -0.523612 -0.507872 -0.923242 0.314121 -0.22125
--0.0158154 -0.661987 -0.749348 0.647451 -0.716615 -0.259365 -0.887292 0.0362983 -0.459778
--0.880705 0.414627 -0.229004 -0.880691 0.463666 -0.09694 0.854087 -0.349399 -0.385299
-0.591791 -0.197264 -0.781582 -0.69874 0.685205 -0.205562 -0.644528 0.34271 -0.683472
-0.519893 -0.777214 -0.354472 -0.588419 -0.588419 -0.55455 -0.814164 0.524526 -0.249018
-0.666706 -0.72418 -0.176256 -0.767549 0.610615 -0.194978 0.596127 -0.675259 -0.434347
--0.568865 0.667022 -0.481118 0.468899 -0.549215 -0.691735 -0.673848 -0.595175 -0.43783
--0.37961 -0.541691 -0.749978 0.649603 -0.356158 -0.67169 0.467638 -0.171231 -0.867176
-0.197129 0.824751 -0.530025 -0.315227 0.736623 -0.598347 -0.189691 -0.331959 -0.924024
--0.432596 -0.884943 -0.172444 -0.653129 0.0762328 -0.753399 -0.196901 -0.798542 -0.568824
-0.595899 0.595899 -0.538339 -0.0833766 -0.90672 -0.413409 0.244745 -0.840249 -0.483819
--0.0411872 0.720775 -0.691944 -0.346388 -0.148984 -0.926185 0.262214 -0.510627 -0.818843
--0.32034 -0.0488322 -0.946043 0.0269138 -0.558461 -0.829094 -0.231713 -0.311614 -0.921524
-0.415067 -0.105914 -0.903605 0.113699 0.437303 -0.892098 0.687616 -0.181196 -0.703102
--0.730426 -0.191407 -0.655623 -0.0673477 -0.43776 -0.896566 0.587931 -0.355209 -0.726749
-0.407993 0.710211 -0.573709 0.0627344 -0.643028 -0.763269 -0.716044 -0.492216 -0.494979
--0.625571 -0.657112 -0.420552 -0.125133 -0.871118 -0.474864 -0.513312 0.500792 -0.696935
-0.205739 -0.154691 -0.966303 0.139194 -0.63921 -0.756331 -0.183705 -0.7983 -0.573558
-0.129194 -0.79939 -0.586758 0.395605 -0.699374 -0.595292 0 -0.714057 -0.700088
-0.0821513 -0.670499 -0.737348 0 -0.947723 -0.319096 0 -0.424893 -0.905244
-0.232035 0.261205 -0.93698 -0.26748 0.823524 -0.500263 -0.505771 0.579733 -0.638831
--0.302437 0.55059 -0.778064 -0.0322538 0.628948 -0.776778 0.216548 0.804992 -0.552353
--0.0276135 0.796846 -0.603551 0.0606424 0.818673 -0.571049 0.42076 0.688839 -0.590307
-0.442564 0.636671 -0.631495 0.0703097 0.953021 -0.294631 -0.393632 0.883207 -0.254949
-0 0.842439 -0.538792 0.247275 0.851023 -0.463265 -0.53666 -0.712685 -0.451749
-0.330773 -0.301587 -0.894223 -0.311853 -0.648992 -0.693943 -0.0186271 -0.614693 -0.788546
-0.778019 0.198507 -0.596055 -0.721324 -0.65162 -0.234698 -0.244691 -0.700758 -0.670123
-0.722534 0.148377 -0.675225 -0.94044 -0.111906 -0.321012 -0.414019 -0.785113 -0.460636
-0.578245 -0.302339 -0.757776 0.804844 0.371467 -0.462859 -0.215747 -0.449986 -0.866583
-0.873669 0 -0.486522 -0.796789 -0.150159 -0.585304 0.577632 -0.654494 -0.48783
--0.919215 0.189644 -0.345078 -0.815376 0.574037 -0.0751172 0.94216 -0.314825 -0.114973
--0.526794 0.237428 -0.816159 0.367513 -0.929476 0.0317603 -0.438774 0.371842 -0.818053
-0.647808 -0.0398651 -0.76076 0.204368 -0.978894 -0.000987286 0.26964 -0.955995 -0.115618
-0.631516 -0.66722 -0.394976 -0.501994 0.643066 -0.578332 0.464369 0.337251 -0.818916
-0.953793 -0.124408 -0.2735 -0.151531 0.567922 -0.809013 0.764898 -0.642514 0.0458939
-0.2831 -0.886154 -0.366858 0.607346 -0.764806 0.214946 0.270611 -0.704715 -0.655855
-0.401862 -0.438789 -0.803723 -0.434244 -0.672652 -0.599143 0.726992 -0.275329 -0.629028
-0.592987 -0.393762 -0.702366 -0.474079 -0.574123 -0.667557 -0.503787 -0.440437 -0.743111
--0.457974 -0.673915 -0.57974 -0.588721 0.792639 -0.158528 0.0695623 -0.890398 -0.449836
-0.457902 -0.737537 -0.496352 0.970729 0.0507571 -0.234752 0.707754 -0.540756 -0.454606
--0.697492 -0.656992 -0.286122 -0.725648 -0.563773 -0.394455 0.985733 -0.147733 -0.0806586
--0.550024 -0.829022 -0.100971 0.512143 -0.857839 -0.0426786 0.322015 -0.946725 -0.00429354
--0.522973 -0.852252 0.0129129 -0.649531 -0.759452 0.0366402 0.14246 -0.939007 -0.313002
--0.280881 -0.853879 -0.438175 -0.0711379 -0.995931 0.0553295 -0.548838 0.804265 -0.227891
--0.74702 0 -0.664801 0.0171827 -0.326472 -0.945051 0.410419 -0.679111 -0.608575
--0.364289 0.167455 -0.916107 0.246603 -0.332377 -0.910336 0.451961 -0.335743 -0.826443
-0.144032 -0.882629 -0.44746 -0.38057 -0.225126 -0.896931 -0.575825 0.465475 -0.67213
-0.112 0.0263529 -0.993359 0.281641 -0.345346 -0.895217 -0.652357 -0.588712 -0.477334
--0.0965727 -0.915831 -0.389778 0.660328 -0.660328 -0.357678 -0.279956 0.36428 -0.888214
--0.100151 -0.0166918 -0.994832 -0.887081 -0.100325 -0.450581 0.76069 0.544434 -0.353471
--0.402301 0.504888 -0.763702 -0.349163 0.311494 -0.883774 0.441792 0.834495 -0.329298
--0.559507 -0.808386 -0.182932 -0.138395 -0.827316 -0.544421 -0.631133 -0.746974 -0.209046
--0.173925 -0.780433 -0.600562 0.767655 -0.0383828 -0.639713 -0.453607 -0.685278 -0.569767
-0.551526 -0.14722 -0.821063 0.826474 0.363649 -0.429767 0.8577 0.388891 -0.336325
-0.823711 0.279248 -0.493478 0.333318 -0.754251 -0.565689 0.0406417 -0.746792 -0.663815
-0.015947 -0.534225 -0.845192 -0.520495 0.0208198 -0.853611 0.661244 -0.495308 -0.563406
-0.913519 0.321215 -0.249607 -0.747552 0.00807074 -0.664154 0.461353 -0.53233 -0.709773
-0.292762 -0.56131 -0.774094 0.190724 -0.486347 -0.852696 -0.888497 0.430483 -0.158928
-0.994314 -0.0509905 0.0934825 0.986835 -0.131761 0.0937882 0.90288 -0.379832 0.201332
-0.619007 -0.75584 0.213394 0.869212 -0.160118 -0.467796 0.824087 -0.222516 -0.52093
-0.60237 0.798086 -0.0144975 -0.0559393 -0.964954 -0.256389 -0.379812 0.634713 -0.672965
-0.648721 -0.131186 -0.749634 0.977478 -0.153099 0.145248 -0.681476 -0.526052 -0.508782
-0.253505 -0.869394 -0.424134 -0.295363 0.210974 -0.9318 0.771082 -0.571005 0.281756
--0.520388 -0.81452 -0.256423 -0.932492 -0.332476 0.141129 -0.387589 0.66745 -0.635834
-0.72924 0.447094 -0.517992 0.490614 0.598931 -0.632913 0.554927 0.541393 -0.631625
--0.0398377 -0.632976 0.773146 0.833643 0.0106877 0.5522 0.277725 -0.55545 -0.783801
--0.428552 -0.68747 0.586284 0.232916 -0.842788 -0.485241 -0.207499 -0.735837 -0.644584
--0.128406 -0.342416 -0.930733 -0.160642 0.973546 -0.162488 -0.986898 0.0986898 0.127639
-0.451855 -0.636122 -0.62544 0.64379 0.539243 -0.542911 0.593303 0.25522 -0.763449
-0.234245 -0.669273 -0.705126 0.35794 0.188615 -0.914496 -0.643042 0.270755 -0.716372
-0.521396 -0.109909 -0.846207 0.91988 -0.041365 -0.390013 -0.946342 0.288601 -0.145419
-0.72821 0.682613 -0.0612429 -0.346952 -0.919119 -0.186664 0.0326775 -0.980326 -0.19466
-0.297089 -0.871314 -0.390576 0 -0.849343 -0.527841 0.0658001 -0.870586 -0.487596
-0.74046 0.64113 -0.20167 -0.540906 0.801701 -0.254355 0.833497 -0.00766434 -0.552471
-0.72087 -0.493227 -0.486903 -0.912475 -0.382435 0.14537 0.254155 -0.914959 -0.313458
--0.66355 -0.737278 0.126976 -0.327662 0.703275 -0.630905 -0.471757 -0.36856 -0.801005
-0.245787 -0.825896 -0.50743 -0.79949 0.588196 -0.121827 -0.554541 -0.831811 0.0239616
--0.0360758 0.742401 -0.668984 -0.522275 0.838219 0.156897 0.317629 -0.923394 0.215534
-0.290532 0.576195 -0.763931 -0.77193 0.604489 -0.196766 -0.130676 -0.659232 -0.740498
--0.459006 -0.442006 -0.770677 -0.374676 -0.769072 -0.517827 -0.376284 0.430038 -0.820657
-0.222776 -0.879965 -0.419562 -0.48734 0.46584 -0.738575 -0.249152 -0.738395 -0.626654
--0.706638 0.0936891 -0.701345 -0.382983 0.718093 -0.581091 0.0830439 -0.110725 -0.990376
-0.260005 -0.913991 -0.311476 0 0.999101 0.0423861 0.444728 -0.690636 -0.570298
-0.0428856 0.950631 -0.307347 0.815639 0.577103 0.0410385 0.942857 0.171429 0.285714
--0.728315 0.662105 0.176561 -0.722965 -0.690103 -0.032862 -0.910416 0.0343553 -0.412264
--0.128238 0.881635 -0.454175 -0.186605 0.92473 -0.331742 -0.486271 0.75559 -0.43889
--0.746592 0.409132 -0.524605 -0.67561 -0.275249 -0.683951 0.959044 0.280696 0.0380109
--0.551393 0.600772 -0.578826 0.682383 0.720548 -0.123144 -0.129602 -0.931015 -0.341196
-0.899206 0.0372805 -0.435934 -0.865383 -0.397797 -0.304745 0.355155 -0.856956 -0.373486
--0.121418 -0.689481 -0.714054 0.723358 -0.632815 -0.276221 -0.226561 -0.696637 -0.680711
-0.511263 -0.723072 -0.464519 -0.911951 -0.130058 -0.38914 0.937919 -0.290078 -0.190162
-0.760164 0.550687 -0.344809 0.766852 0.546222 -0.337015 0.934208 -0.3242 -0.148829
--0.982977 0.174299 -0.0580998 0.177826 -0.98367 -0.0277619 -0.728453 -0.67903 0.0909671
-0.778298 -0.598196 -0.190822 0.504274 0.784427 -0.361085 0.313858 -0.859187 -0.404092
-0.818402 -0.572881 -0.0450121 0.902922 0.409137 -0.131676 -0.0824148 0.970663 -0.225878
-0.26844 -0.96313 -0.017896 0.954296 0.149554 -0.258752 0.698362 -0.101079 -0.708572
--0.990127 -0.0735905 0.119306 -0.519702 0.814759 0.257057 -0.661742 0.672771 0.330871
--0.106395 -0.984152 0.14186 0.586209 0.768585 -0.256195 -0.0510752 -0.752508 -0.6566
-0.534006 -0.738057 -0.412444 -0.746554 0.590949 -0.305673 0.951414 0.0126434 0.307655
--0.405861 -0.900274 0.157425 0.402726 -0.836431 0.371747 -0.48941 -0.870062 0.0589104
-0.786062 -0.550243 -0.281672 0.894147 0.108601 0.434404 0.931719 -0.0291162 0.362012
--0.46618 -0.884546 -0.0159378 -0.294639 -0.837308 -0.460547 -0.0271759 0.570694 -0.820713
--0.646277 0.656016 -0.389832 0.838007 0.164315 0.520331 -0.451493 -0.799787 0.395594
--0.694515 -0.0292427 -0.718884 0.0571292 0.956915 -0.284694 0.463583 -0.86278 0.201745
--0.527545 -0.83658 0.147754 -0.53086 -0.812675 0.240307 0.703842 0.703842 0.0959785
-0.14104 0.967135 -0.211561 -0.0949207 -0.976327 -0.194361 0.902432 -0.258894 -0.344371
--0.166339 -0.970311 0.17558 -0.960289 0.0561572 -0.273299 0.431889 -0.431889 -0.791797
-0.629445 0.769322 0.109279 -0.972387 -0.233373 0 -0.707308 0.579529 -0.404799
-0.575168 -0.692435 -0.435564 -0.722346 0.685303 -0.0926085 0.403399 0.576284 0.71075
--0.838388 0.540438 0.0709405 0.618425 -0.531767 -0.578597 0.666068 -0.609667 -0.429721
--0.591621 0.591621 -0.547694 -0.571101 0.598297 -0.562036 -0.522678 0.709348 -0.472899
-0.248187 -0.849265 0.465997 0.749401 0.343811 -0.565856 0.327269 0.139263 -0.934613
-0.470209 -0.798609 -0.37567 -0.448116 0.426572 0.785639 -0.355483 -0.891999 0.27923
--0.816525 -0.199965 -0.541573 0.626849 -0.690813 -0.360331 0.932835 0.339604 0.120366
-0.750775 0.459982 -0.474081 -0.84453 0.341834 -0.412211 0.573251 -0.473762 -0.66853
-0.278974 -0.852913 -0.441264 0.0873541 -0.762893 -0.640597 -0.983169 0.172055 0.0614481
--0.602585 -0.71815 0.348069 -0.297116 0.847331 -0.440172 0.303829 0.717405 -0.626911
-0.653544 -0.308205 -0.691296 -0.201612 -0.632644 -0.74774 -0.279857 0.612659 -0.739141
--0.068935 -0.0771416 -0.994634 0.33931 -0.819482 -0.461863 -0.883753 -0.45613 0.10453
--0.254414 0.166439 0.952666 -0.249208 0.320836 -0.913761 -0.207199 0.148716 -0.966929
-0.304056 -0.33407 -0.892159 -0.170821 0.134216 -0.976118 0 -0.311641 -0.9502
-0.694672 -0.709144 0.120603 0.859581 -0.509036 -0.0447504 -0.781435 0.407462 0.472582
--0.647169 -0.392224 0.653706 -0.886995 0.0490504 0.459166 -0.497468 0.297268 -0.814958
-0.0882852 0.0294284 -0.99566 -0.269897 -0.304247 -0.913559 -0.719314 0.401156 -0.567152
--0.133211 -0.793344 -0.594021 0.102573 -0.981767 -0.160036 -0.479456 0.76713 -0.426184
-0.53753 0.808457 0.239703 -0.402972 0.914818 0.0268648 0.917997 -0.396562 0.00452816
-0.980883 0.0779716 0.178295 0.883936 0.441968 0.152713 -0.716192 -0.695922 -0.0525508
--0.0555452 0.864653 -0.499289 -0.243071 0.729213 -0.63966 0.952863 -0.276809 0.124209
--0.211241 -0.977383 -0.00998402 -0.540551 0.390592 -0.745146 -0.458135 0.823741 -0.33401
-0.369622 -0.870401 -0.325241 -0.146564 -0.840301 -0.521931 0.72583 -0.672963 -0.142449
--0.29592 -0.883917 -0.362107 0.647963 -0.416547 -0.637678 -0.149366 -0.852922 -0.500214
--0.746148 -0.662663 -0.0643531 0.855179 -0.117505 -0.504838 0.794308 0.21938 -0.566522
-0.239602 0.339436 -0.909601 -0.318953 0.134296 -0.938208 0.472654 -0.759727 -0.446557
-0.496001 -0.807052 -0.320392 0.576018 -0.62402 -0.528017 -0.116539 0.773139 -0.623438
-0.71045 0.333298 -0.619817 -0.105028 -0.992996 0.0541056 0.693252 -0.683712 -0.227904
--0.66256 -0.603026 0.444267 -0.0633257 -0.909588 0.410658 0.278523 -0.960424 -0.00320141
-0.329474 -0.929344 0.166631 0.23583 -0.946032 0.222277 0.17609 0.440225 0.880451
--0.741536 -0.670913 0 -0.757684 -0.651961 0.0293676 0.915488 -0.0938963 -0.391234
-0.0657912 -0.997833 0 -0.0423798 0.720457 -0.692204 0.548646 0.759664 -0.349139
--0.393073 -0.917171 -0.0655122 0.721223 0.523468 -0.453672 0.517381 0.776071 -0.360599
--0.928473 -0.295423 -0.225084 0.710282 -0.701925 -0.0529229 0.698377 0.704904 -0.124011
--0.95902 -0.139857 -0.246415 0.898349 -0.431207 -0.0838459 -0.724146 0.599293 0.341264
-0.740475 -0.598136 -0.306481 -0.762629 -0.635902 -0.11843 0.104777 -0.681047 -0.724704
-0.638241 -0.769309 0.0284929 0.994249 -0.0887288 0.0599629 0.17609 -0.968496 0.17609
-0.513226 -0.856379 -0.0566906 0.296071 0.911897 0.284228 -0.735612 0.559065 0.382518
--0.730931 0.608526 0.308926 0.89569 -0.432749 0.102317 0.124686 -0.992063 -0.0162633
--0.417759 -0.908461 -0.0132622 0.323677 -0.921233 -0.215784 -0.965722 -0.259028 0.0168931
--0.982888 -0.182016 -0.0283136 0.299775 0.930552 -0.210259 0.301131 0 0.953583
-0.976112 0.208611 -0.0607151 -0.890387 0.0460545 0.452869 0.813767 0.48358 0.322387
-0.839341 0.453698 0.299441 0.0112225 0.864131 0.503141 -0.860695 0.43913 0.257623
-0.01133 -0.940393 -0.339901 0.361886 -0.882096 -0.301571 -0.283706 -0.831774 -0.477141
-0.753653 -0.0519761 -0.655214 0.558975 -0.264243 -0.785953 0.586881 -0.8031 -0.102962
--0.895676 0.422393 0.139101 0.200534 -0.968295 0.148968 0.755142 -0.655406 0.014248
--0.409691 -0.872821 0.265211 -0.722956 0.690464 -0.0243693 -0.790186 0.603615 0.10609
--0.369077 0.918116 0.144377 -0.19593 0.979651 -0.04354 -0.218537 0.967805 0.124878
--0.13994 0.965583 0.219239 -0.102463 0.973399 0.204926 -0.297193 0.934035 0.198129
--0.522716 -0.678668 -0.515924 0.578153 -0.140245 -0.803785 -0.691431 0.718024 0.0797805
-0.435884 -0.89158 -0.12284 -0.606334 -0.785479 -0.124023 0.730789 0.501956 0.462587
-0.829482 0.47399 0.295454 0.692996 0.679921 0.239716 0 0.462566 0.886585
-0.186443 0.865288 0.465312 0.908919 -0.398649 -0.122252 -0.651332 0.195812 0.733092
-0.0958325 0.972015 0.214482 0.576707 0.527885 0.623495 -0.783524 0.547223 0.29434
--0.713561 0.5622 0.418046 -0.813596 0.355572 0.460033 -0.637132 -0.58963 -0.496385
-0.252222 0.252222 -0.934221 0.71509 0.659113 -0.232844 0.250099 -0.701892 -0.666932
-0.830773 0.288001 0.47631 0.196129 0.442546 0.875035 -0.926488 0.188352 0.325798
-0.654477 -0.711388 -0.2561 -0.433262 -0.753876 0.493919 0.660852 -0.189307 0.726249
--0.48085 -0.824314 0.298814 0.983296 -0.150169 -0.102855 0.520532 -0.753605 -0.401405
--0.491369 -0.728328 -0.477592 0.358962 0.243277 -0.90109 0.689078 0.689078 -0.224374
--0.717496 0.573997 -0.394623 0.264013 0.940669 -0.213166 -0.529192 0.797988 0.288395
--0.261115 -0.821228 0.507349 -0.680331 -0.684186 0.262753 -0.218519 -0.963269 -0.156085
-0.652871 -0.748414 0.116774 0.203874 -0.974064 -0.0981614 0.205266 -0.173687 0.963171
--0.171388 0.0507816 0.983894 -0.350738 -0.85736 0.376719 -0.855798 -0.474442 0.206192
--0.475789 -0.836182 0.272809 -0.135139 0.844618 0.518032 0.84978 0.186952 0.492872
--0.486418 0.856759 0.171352 0.307937 -0.865918 -0.394159 -0.438607 -0.758597 -0.481824
-0.659006 0.110713 -0.743945 0.69225 0.686197 -0.223436 0.231633 -0.146029 0.96178
-0.539235 0.550958 0.636923 -0.383801 -0.733736 0.56065 0.893078 -0.435089 -0.114497
-0.506432 -0.350607 0.787783 -0.604419 0.36457 0.708354 -0.873243 -0.169356 0.456909
-0.688789 -0.439653 0.576433 -0.885817 0.117133 0.449009 0 -0.999061 0.0433356
-0.871587 0.0901642 -0.481878 -0.511752 -0.0261691 -0.858735 -0.53265 -0.764754 -0.362539
--0.489831 -0.473503 -0.732025 0.450223 0.452841 -0.769568 0.769039 0.607173 -0.199799
--0.378939 0.801186 -0.463148 -0.718397 -0.689075 0.0952976 0.184114 0.97763 0.101694
--0.382269 0.888214 0.254846 0.867466 -0.485462 -0.108765 -0.560007 -0.222072 0.798171
--0.913832 -0.290254 0.284012 0.560901 -0.780385 0.276386 -0.368434 -0.846421 -0.384483
--0.38097 -0.881165 -0.280018 -0.210366 -0.839178 -0.501525 0.0851775 -0.00967926 -0.996319
-0.52573 0.738864 -0.421531 0.541798 0.823036 -0.170489 -0.601124 0.743495 -0.293029
-0.0634667 0.335467 -0.939912 -0.164716 -0.973322 -0.159725 0.874235 0.298474 0.382919
-0.975442 0.177995 0.129729 -0.932739 -0.328536 0.148533 -0.310257 -0.810372 -0.497028
-0.620221 0.334651 -0.709461 0.587911 0.732468 -0.343294 -0.74274 0.275875 -0.610107
-0.239939 0.945067 0.221985 -0.192387 0.902738 0.384774 0.908868 -0.0873912 -0.407825
--0.9459 0.169696 0.276542 -0.940466 0.175983 0.290781 0.36958 -0.90952 -0.19022
--0.460918 -0.800411 -0.383272 0.572474 0.677593 -0.461672 0.223733 -0.968343 0.110701
--0.216985 0.278012 0.935749 0.791297 0.238404 0.563038 0.79788 -0.555363 -0.234433
-0.0708869 -0.992416 0.100423 -0.555622 -0.807224 0.199185 -0.868642 -0.414275 0.271729
-0.142525 -0.891428 -0.430166 -0.668659 0.260825 -0.696323 -0.486004 0.602064 -0.633497
-0.123554 0.809965 -0.573316 0.22312 -0.80881 0.5441 0.509371 -0.709386 0.487147
--0.85552 -0.392807 0.337326 0.128324 -0.991598 0.0163322 0.04847 0.981518 0.185129
--0.160852 0.97798 0.132971 -0.783356 -0.0257743 -0.621039 0.396049 -0.203525 -0.895389
-0.800749 -0.0250234 -0.598477 0.197399 0.540055 -0.818153 -0.0079445 0.897728 -0.440478
-0.373377 0.886251 -0.274134 0.141833 -0.921916 0.360493 -0.929152 0.349305 -0.121092
--0.978305 0.142402 -0.150472 0.148585 0.728276 -0.668982 0.644562 0.528742 -0.552242
-0.41021 0.876547 -0.251779 0.329187 -0.938472 -0.104435 -0.419297 -0.898714 -0.128461
--0.403814 0.779454 -0.478942 -0.155245 0.851859 -0.500235 -0.654974 0.664606 -0.359594
-0.623948 -0.263531 -0.73569 -0.91542 -0.191728 -0.353903 0.556984 -0.718688 -0.41624
--0.299696 -0.775301 -0.555958 0.0263015 -0.836387 -0.547509 0.329968 -0.532663 -0.779353
--0.871129 -0.454099 -0.186891 0.610586 0.732157 -0.301878 0.682646 0.626428 -0.376273
-0.656219 0.686047 -0.31419 -0.702782 -0.649801 -0.289579 0.909282 -0.357218 -0.213544
--0.956792 0.278167 -0.0846846 0.741177 -0.626202 -0.241926 0.680638 -0.686146 -0.25678
-0.558265 -0.197035 -0.805927 -0.586108 -0.0572744 -0.808206 0.867414 0 -0.497587
-0.522385 -0.700066 -0.486848 0.374142 0.363513 -0.853157 0.431889 -0.431889 -0.791797
-0.831385 -0.356979 -0.42587 0.766349 0.569701 -0.2969 -0.78086 -0.496911 -0.378599
--0.0498854 -0.997708 -0.0457283 0.898977 -0.433004 -0.0659396 0.886174 -0.43135 -0.169214
--0.19776 -0.939362 -0.280161 -0.457524 0.481138 -0.747782 0.475591 -0.744403 -0.468698
-0.0990088 -0.964033 -0.246653 -0.601644 0.595687 0.532147 0.683818 0.683818 0.254532
--0.524195 0.725137 0.446537 -0.752249 -0.451349 -0.480006 0.15757 -0.601632 -0.783077
-0.290014 -0.913545 -0.285181 0.220903 -0.965483 -0.138 -0.794953 -0.539432 0.277603
--0.326052 -0.846725 -0.420413 0.903413 -0.171776 -0.392858 0.338093 0.899623 -0.276355
--0.34795 -0.394343 -0.850544 -0.548044 -0.631898 -0.548044 -0.724555 -0.169577 -0.66803
--0.0188745 -0.968891 -0.246767 -0.64358 -0.64358 -0.414258 0.356294 -0.456056 -0.815517
--0.648772 -0.689441 -0.322127 -0.465801 -0.237753 -0.852351 0.741325 0.585257 -0.328499
--0.779814 -0.582047 -0.23046 0.928625 0.19967 -0.312711 0.874323 -0.483668 -0.0403057
--0.0607823 -0.850952 -0.521715 -0.118168 -0.948487 -0.293953 -0.308258 -0.703795 -0.640039
-0.753462 0.453637 -0.475929 0.0160721 -0.962033 -0.272461 -0.830418 0.553612 -0.0626109
-0.968504 -0.141732 0.204724 0.79849 -0.598867 0.0614223 0 -0.848336 -0.529458
--0.82896 -0.524195 -0.195049 0.844479 0.52011 -0.12783 0.767202 -0.627521 -0.132732
--0.353643 0.640381 -0.681798 0.25207 -0.930719 -0.264996 0.305425 -0.916274 -0.259148
--0.384486 0.90221 0.195415 0.822951 0.565779 -0.0514344 -0.152098 -0.221233 -0.963287
--0.354471 -0.16953 -0.91957 -0.196067 0.980334 -0.0224076 0.133009 0.975401 -0.17579
-0.542551 -0.613318 -0.574003 0.0839211 -0.917138 -0.389634 0.710839 0.690135 0.135727
-0.732502 -0.138581 -0.666511 0.629762 0.414389 -0.657025 0.528107 0.55369 -0.64384
--0.491848 0.86233 -0.1203 0.379547 0.919673 -0.100726 -0.167817 0.976388 0.136033
-0.431277 -0.782524 -0.449062 -0.662868 -0.224902 -0.714161 0.22194 0.887761 -0.403264
-0.0235352 0.0823732 -0.996324 0.420952 -0.762634 -0.491111 -0.752994 0.648856 -0.109478
--0.92798 0.107075 0.356915 -0.701876 0.694926 -0.156358 -0.392322 0.603572 0.694107
--0.618742 -0.563607 0.547271 0.184252 0.982043 -0.0405227 -0.792281 0.313923 0.523205
-0.519907 0.854133 -0.0123787 -0.790345 -0.451626 0.41399 0.994274 0.0994274 0.0391684
-0.758853 -0.649703 -0.0450461 -0.771996 -0.571631 -0.277958 -0.395817 -0.918132 0.0190427
-0.108157 -0.973417 0.201894 0.375903 -0.884477 -0.276399 0.468316 -0.81339 -0.345075
-0.460938 0.784575 -0.414704 0.570948 0.741135 -0.353183 -0.572372 -0.803757 -0.162375
-0.662022 -0.165505 0.730982 0.820325 -0.392329 -0.416107 0.185374 0.98164 -0.0449392
--0.345809 0.912937 -0.216707 -0.95324 -0.300571 -0.0314884 -0.947779 -0.31749 -0.0302372
--0.0734306 -0.996558 0.0384637 -0.888005 -0.186481 -0.420323 -0.38819 -0.916742 0.094306
-0.549025 0.695432 0.463622 0.676753 -0.728811 0.104116 -0.717518 0.391374 0.576189
-0.585463 -0.712237 -0.387236 0.335432 0.934417 -0.119797 -0.371232 0.877457 0.303735
--0.662085 0.0827606 0.744845 0.848308 0.0614716 -0.525923 0.905197 -0.201155 -0.374372
--0.596285 -0.745356 0.298142 0.286282 -0.866402 -0.409134 0.135725 -0.841956 -0.522197
--0.616898 -0.663344 -0.423571 0.533046 -0.78434 -0.31729 0.637231 0.756711 -0.146032
--0.991192 0.052168 0.121725 0.384619 -0.915758 -0.115996 0.311161 -0.889033 -0.335857
--0.926151 -0.139271 -0.350498 0.98582 -0.167403 0.0116252 -0.938026 -0.343943 -0.0425586
--0.748222 -0.407409 0.523625 -0.670201 0.736762 0.0895131 0.75071 0.619153 0.230399
-0.48915 0.850043 -0.195342 0.504961 0.844554 -0.178164 -0.536778 0.782554 -0.315402
-0.688318 0.51766 -0.508179 0.294609 -0.922464 -0.249532 0.864722 0.502097 -0.0123975
-0.605492 0.749313 -0.268159 0.839586 0.529429 0.121658 0.217879 0.917911 -0.331615
-0.757777 0.277496 0.590568 0.864994 0.445953 0.230024 -0.388816 0.772288 -0.502388
-0.65577 0.733198 -0.179964 -0.415453 -0.127365 -0.900654 -0.314221 -0.287478 -0.904777
--0.449256 0.256718 -0.855725 0.106878 -0.299781 -0.948002 -0.267316 0.169883 -0.948515
-0.305573 -0.672644 -0.673925 -0.328982 -0.769959 -0.546749 -0.948924 -0.141738 -0.281875
-0.817136 -0.548751 -0.176527 -0.677952 -0.623459 -0.389462 0.685388 -0.292848 -0.666696
-0.838632 -0.00618156 -0.544664 0.843287 -0.130996 -0.521255 -0.204589 -0.7573 -0.620193
-0.357737 -0.829122 -0.429628 -0.638917 -0.610451 -0.468118 0.469127 0.69267 -0.547839
--0.268075 0.842522 -0.467217 -0.550732 -0.483631 -0.680291 0.826703 0.40761 -0.387836
-0.907922 -0.344613 -0.238578 0.0448372 -0.941581 -0.333788 -0.486454 -0.758296 -0.433993
-0.394619 -0.841407 -0.369202 -0.664798 -0.47826 -0.573857 0.276694 -0.122975 -0.953057
--0.883592 0.465557 -0.0502072 0.462115 -0.777194 -0.427106 0.603159 -0.356707 -0.713414
-0.820164 0.340068 -0.460092 0.952035 0.0115749 -0.30577 -0.0800304 0.98323 -0.163872
--0.814202 0.576286 0.0704937 0.282028 -0.568795 -0.772614 0.903205 0.418662 -0.0945708
-0.376086 0.621111 -0.687591 -0.637916 0.0609773 -0.767688 -0.57735 -0.57735 -0.57735
-0.276421 -0.900183 -0.336545 0.35853 -0.90913 -0.211988 0.30702 0.846952 -0.434063
--0.452599 -0.243188 -0.857912 -0.765682 -0.566025 -0.305526 0.66924 0.547077 -0.502816
--0.0733032 0.704525 -0.705883 -0.897898 -0.242961 -0.367082 0.770579 -0.597782 -0.221055
--0.311776 0.770271 -0.556307 0.541317 -0.589939 -0.599123 -0.485384 -0.654705 -0.579451
-0.467348 -0.233674 -0.852632 0.344958 0.936315 -0.0657063 0.905647 -0.416108 0.0815898
-0.204546 -0.920458 -0.333043 0.828805 -0.214514 -0.516784 0.493847 0.823079 -0.280457
-0.417315 -0.602789 -0.680069 -0.715093 -0.666336 -0.211277 -0.486664 -0.811107 -0.324443
--0.668648 -0.728751 -0.147754 -0.98481 -0.171271 -0.0285452 -0.583193 -0.770648 -0.256883
-0.724062 0.395093 -0.565363 0.431021 0.636194 -0.639905 0.453626 0.583736 -0.673406
-0.38199 -0.273335 -0.88282 -0.114376 0.564731 -0.817311 -0.620628 0.639645 -0.453514
--0.457017 0.888877 0.0321449 0.87115 0.195564 0.450391 -0.912988 0.300749 0.275687
-0.633054 -0.296257 -0.715174 0.571811 -0.62993 -0.525567 0 0.0634628 -0.997984
-0.649847 -0.361026 -0.668849 -0.781651 0.586238 -0.21295 -0.783687 0.391844 -0.481968
--0.898908 -0.437864 0.015454 0.714292 0.479267 -0.509989 -0.399538 -0.762754 -0.508503
--0.814241 -0.425626 -0.394784 0.3771 -0.627326 -0.681365 0.646204 -0.427328 -0.632307
--0.779839 -0.241456 -0.577538 -0.0748111 -0.654597 -0.752267 -0.176038 0.909527 -0.376525
-0.331348 0.649953 -0.683937 -0.0898383 -0.235826 -0.967634 -0.468896 -0.805914 -0.36144
-0.5891 0.0632205 -0.805583 -0.956807 -0.264417 -0.12085 -0.651873 0.641186 -0.404897
-0.00783244 -0.871638 -0.490087 0.156549 -0.834926 -0.527627 0.416594 -0.505777 -0.755407
--0.199523 -0.737045 -0.645721 0.278518 0.875341 -0.39523 -0.415601 0.373479 -0.82933
-0.857881 0.0504636 -0.511364 -0.19959 -0.471758 -0.858841 -0.0649442 -0.828039 -0.556897
-0.140919 -0.79407 -0.591265 0.517987 -0.426577 -0.741432 -0.527934 0 -0.849285
-0.901637 0.324026 -0.286458 -0.339653 -0.915176 -0.217 0.984734 -0.0364716 -0.170201
-0.885734 -0.207594 -0.415188 -0.858898 0.458079 0.229039 0.803824 -0.506112 -0.312598
--0.27654 -0.72098 -0.635384 0.0623288 -0.849938 -0.523184 -0.166814 -0.925299 -0.34058
-0.292642 -0.899488 -0.324473 -0.318389 -0.833989 -0.450655 -0.978475 -0.070904 -0.193804
--0.0285972 -0.972306 -0.231955 0.117531 -0.919095 -0.3761 -0.957871 -0.133723 -0.254168
--0.823829 -0.457683 -0.334414 0.398265 0.792466 -0.461933 0.428799 -0.227011 -0.874413
--0.170514 -0.882662 -0.437987 -0.309645 0.945233 0.103215 0.299377 0.94349 -0.142128
--0.686641 0.672336 0.276564 0.79082 0.39394 0.468417 0.198386 0.839325 0.506139
--0.599515 0.792319 0.113188 -0.505675 0.852423 0.13292 0.686569 0.473733 -0.551544
--0.317313 -0.463766 -0.827184 -0.885988 -0.437782 -0.152876 -0.462528 -0.886512 -0.012848
--0.895062 0.401235 -0.194616 0.978544 -0.144845 0.146529 -0.920899 0.327367 -0.211603
-0.872236 0.208885 -0.442234 0.262363 0.910983 -0.318237 0.856852 -0.509602 0.078169
-0.452362 0.876452 0.164924 0.258517 0.939418 -0.225084 -0.577073 -0.146094 -0.803519
-0.907065 -0.420878 0.00967536 -0.680325 0.255122 -0.687074 -0.0663093 0.582048 -0.810446
-0.241924 0.836654 -0.491408 -0.214169 0.938494 -0.270853 -0.510582 0.807553 -0.295235
--0.504783 -0.261739 -0.82261 0.188695 -0.677906 -0.71052 0.477558 -0.586803 -0.653911
--0.263785 -0.338687 -0.903166 -0.75132 0.0655221 -0.656677 0.727267 -0.595036 -0.342074
-0.126841 -0.692484 -0.710196 -0.89961 0.188291 -0.394015 0.971484 -0.139854 -0.191466
-0.937898 -0.346129 -0.0232614 -0.411939 0.56794 -0.712566 0.98726 0.13226 -0.088458
-0.84923 -0.36028 -0.386014 0.289955 -0.849693 -0.440395 -0.275267 -0.572488 -0.772324
--0.634616 0.0475962 -0.771361 -0.768179 0.303905 -0.563509 0.409018 -0.553643 -0.725385
--0.332772 -0.181342 -0.925407 0.972512 -0.230689 -0.0316632 -0.461936 0.14838 -0.874413
--0.41959 0.13741 -0.897253 0.525532 -0.586224 -0.616569 0.917388 -0.391152 -0.0734801
--0.786912 0.208901 -0.580629 0.946439 -0.259633 -0.191951 0.975783 0.118072 -0.184137
--0.0359614 0.471647 -0.881054 0.00288181 0.370312 -0.928903 -0.282292 0.341722 -0.896402
--0.530768 0 -0.847517 0.714956 -0.492864 -0.495906 0.257836 -0.699282 -0.666727
--0.389729 0.167027 -0.905656 -0.259181 0.610927 -0.74806 0.184859 0.0591548 -0.980983
--0.792411 -0.113653 -0.599307 -0.0431343 -0.197422 -0.979369 -0.533551 0.568348 -0.626342
--0.166914 -0.926267 -0.337888 -0.555622 -0.65112 -0.517037 -0.967191 -0.0541803 -0.248204
-0.355469 -0.823079 -0.442925 -0.443465 -0.518587 -0.731031 -0.962629 -0.172669 -0.208642
--0.897661 -0.368472 -0.241728 0.111658 -0.899335 -0.422764 -0.985853 0.131067 -0.104474
-0.84965 -0.515126 -0.112876 -0.31059 0.148658 -0.938848 -0.546689 -0.81886 -0.17493
-0.0932093 -0.0955993 -0.991046 0.873465 -0.11493 -0.473127 -0.570436 -0.371767 -0.732388
-0.709737 0.415677 -0.568758 -0.392645 -0.208593 -0.895722 0.867856 0.3632 -0.338986
-0.142514 0.0729142 -0.987103 0.837133 -0.107522 -0.536328 0.486846 -0.699546 -0.523084
-0.571804 0.507796 -0.644347 -0.324074 0.544199 -0.773837 0.587523 -0.587523 -0.556447
-0.988308 -0.0515375 -0.143497 0.917428 0.397619 0.0150234 -0.835169 -0.378436 -0.399098
-0.756881 -0.47434 -0.449592 0.557993 -0.557993 -0.614238 0.645238 -0.737415 -0.199717
--0.536173 -0.632409 -0.559086 -0.0521256 -0.79926 -0.598721 0.334866 -0.837718 -0.431384
-0.79371 0.163781 -0.585833 -0.655386 -0.573462 -0.491539 -0.865591 -0.0748042 -0.495132
-0.43624 -0.833989 -0.337872 -0.0930372 -0.868347 -0.487153 -0.227076 -0.866197 -0.445129
--0.221386 -0.854474 -0.469961 -0.381018 -0.847195 -0.37025 -0.570541 0.0691565 0.818352
-0.98138 -0.160694 -0.105216 -0.247 0.968627 0.0274444 -0.885824 0.420198 0.19685
--0.531494 0.341675 -0.775095 0.421847 0.888099 -0.182554 -0.0482555 0.965109 -0.257362
--0.942078 0.285478 -0.176045 0.583927 -0.237896 -0.776166 0.419812 0.257826 -0.87022
-0.35965 -0.0384092 -0.932296 0.799879 -0.131939 -0.585479 -0.56129 -0.799013 -0.215712
-0.725606 -0.0846922 -0.682878 -0.315342 -0.386549 -0.866683 -0.271599 -0.364468 -0.890728
--0.537244 -0.672859 -0.508556 -0.911339 0.0233079 0.410996 0.499059 -0.767783 -0.401807
-0.0522273 -0.377777 -0.924422 -0.117719 -0.375663 -0.919249 -0.181005 -0.837847 -0.515024
--0.158557 -0.372608 -0.914343 0.980312 -0.121694 -0.155498 -0.219502 -0.969891 0.105497
--0.903913 -0.18403 0.386102 -0.136131 -0.658635 -0.740046 0.227687 -0.607165 -0.761256
-0.0231565 -0.708202 -0.70563 0.348935 -0.747719 -0.564943 -0.147009 -0.65104 -0.744671
--0.42495 -0.459539 -0.779898 0.594258 0.556527 -0.580633 -0.325345 -0.945592 0.0025368
--0.188083 -0.442548 -0.876799 0.0850369 -0.357863 -0.929894 -0.389308 -0.448572 -0.804501
-0.670611 0.63708 0.380013 0.909109 0.37532 0.18071 -0.646918 -0.752538 0.123223
-0.255233 -0.478561 -0.84014 0.411 -0.135232 -0.901549 0.375551 -0.187775 -0.90758
--0.656132 -0.549009 -0.517764 -0.3431 -0.740116 -0.578369 -0.168283 -0.501845 -0.848429
-0.232733 0.806808 -0.543044 -0.114145 -0.984498 -0.133169 0.0698558 0.878187 0.47319
-0.960232 0.0751202 0.268908 0.511673 -0.473514 -0.71692 0.132824 -0.136849 -0.981647
--0.887468 -0.320718 -0.33097 0.193703 -0.830886 -0.52164 -0.903527 -0.172972 -0.392071
-0.658512 0.70729 -0.257104 -0.180472 0.789563 -0.586532 0.285217 0.918699 0.273208
-0.58228 0.804605 0.116456 -0.738717 -0.110808 0.664845 0.939025 -0.222655 0.262024
--0.464892 0.858465 0.216597 0.317284 -0.784144 -0.533339 0.135133 -0.713777 -0.687213
-0.199732 0.965371 -0.16783 -0.591054 -0.797923 0.118211 -0.895819 0.422518 -0.137792
--0.976474 0.205573 -0.0650983 -0.985232 0.168897 -0.0281495 0.830002 -0.536817 0.15141
-0.881484 0.336567 0.331224 -0.934465 -0.271554 -0.230288 0.493791 -0.841532 -0.219076
--0.714548 -0.519671 -0.468363 0.429581 -0.801884 -0.415261 0.437341 -0.799514 -0.411716
--0.968303 -0.162936 -0.189316 -0.0718217 -0.655373 -0.751883 0.103111 0.523737 -0.845617
-0.719326 -0.31275 -0.620288 -0.118581 0.783188 -0.610372 -0.500901 0.712981 -0.490669
-0.928063 -0.326783 -0.178641 -0.574786 -0.0334178 -0.817621 -0.35944 0.86132 -0.359069
--0.252345 -0.400784 -0.880735 -0.499005 0.483651 -0.719079 -0.210502 0.834124 -0.50983
--0.40673 0.777216 -0.480111 -0.00439597 0.84073 -0.541437 0.291792 0.827992 -0.478839
-0.302693 0.91365 -0.27133 -0.130404 0.891094 -0.43468 0.0603017 0.983449 -0.170855
--0.186761 -0.832641 -0.521373 -0.679514 -0.434134 -0.591429 0.420585 -0.723185 -0.547825
--0.245572 -0.0731492 -0.966614 -0.661545 0.340598 -0.668095 0.629657 -0.553173 -0.545465
--0.358405 -0.248571 -0.899866 0.891806 -0.452011 -0.0191974 -0.754601 0.0855841 -0.650578
-0.356064 -0.715145 -0.601486 0.995831 -0.0142262 -0.090099 -0.58215 0.429977 -0.690087
--0.724248 0.347639 -0.595493 -0.801478 0.281976 -0.527373 -0.779075 0.302749 -0.548985
--0.898627 0.149771 -0.412357 0.914188 -0.148247 -0.377205 0.992642 -0.0428094 0.113266
-0.0517198 -0.947414 -0.315805 -0.927056 0.0902244 -0.363905 -0.559794 -0.737206 -0.378363
--0.958316 -0.180477 -0.221494 -0.714704 -0.565303 -0.411863 0.646173 0.396238 -0.652269
-0.892075 0.079219 -0.444889 -0.800266 -0.561011 -0.211754 -0.996918 0.0657309 -0.0428246
--0.189974 -0.93027 -0.313859 0.290537 -0.646816 -0.705136 0.490444 -0.759708 -0.426975
-0.901897 0.167689 -0.398073 0.890305 0.39509 -0.22641 0.724946 -0.54371 -0.422885
-0.793386 -0.288132 -0.536207 -0.776237 -0.292262 -0.558605 0.976611 0.213166 0.0281372
-0.842339 0.304002 -0.445025 0.814105 0.306631 -0.493164 0.305038 0.0938579 -0.947704
-0.710796 -0.527646 -0.465143 0.374728 -0.498793 -0.781527 0.242357 -0.73988 -0.627568
--0.867817 0.0565968 -0.49365 0.726207 0.6205 -0.295979 0.927935 0.371065 -0.0353137
-0.652765 -0.293271 -0.698491 0.696431 -0.115888 -0.708204 -0.302605 0.048315 -0.951891
-0.520128 0.779495 -0.349076 0.488382 -0.586761 -0.645906 0.327712 -0.0121375 -0.9447
-0.457791 -0.3689 -0.808913 -0.00402853 -0.739235 -0.673436 0.868894 -0.408891 -0.278983
--0.641868 -0.421128 -0.640825 0.986782 0.150123 -0.0610255 -0.779776 -0.320574 -0.537756
-0.651451 -0.138391 -0.745962 -0.869597 0.0763549 -0.487823 0.710504 0.617323 -0.337781
-0.220767 -0.0229966 -0.975055 -0.0934787 -0.933175 -0.347053 0.0896729 -0.174364 -0.98059
-0.501089 -0.418718 -0.757354 0.172447 -0.172447 -0.969806 0.171111 -0.841528 -0.512397
-0.556848 -0.556848 -0.616312 0.180093 0 -0.98365 -0.244977 -0.792573 -0.558404
--0.269363 -0.778844 -0.566432 0.378509 -0.485634 -0.787966 0.286378 -0.266507 -0.920305
-0.217689 0.0473238 -0.97487 0.200596 -0.351042 -0.914621 -0.101472 -0.854825 -0.508898
-0.178932 -0.178932 -0.967454 -0.0207192 -0.361976 -0.931957 0.498923 -0.507459 -0.702539
-0.483004 -0.509034 -0.712455 0.76903 0.587655 0.251507 -0.301348 0.919499 0.252411
--0.0384775 -0.577162 -0.815723 0.082675 -0.277205 -0.957247 0.238274 -0.201616 -0.95004
--0.765755 -0.402021 -0.501995 -0.69594 -0.510917 -0.504609 -0.13824 -0.984957 0.10368
--0.502977 -0.863808 0.0291581 0.545883 -0.745784 0.381862 -0.953289 0.223045 0.203694
--0.850018 0.525734 0.032756 0.409694 -0.594898 -0.691554 -0.674859 -0.503077 0.539887
--0.0078526 -0.753849 -0.657001 0.737376 -0.63715 0.224315 -0.474709 -0.833032 0.284092
-0.279673 -0.619451 -0.733528 0.172541 -0.366033 -0.914467 0.157571 -0.0555251 -0.985945
-0 0.320807 -0.947145 -0.113267 -0.550789 -0.826923 -0.258576 -0.430959 -0.86453
--0.347626 -0.61694 -0.706075 -0.394927 0.668337 0.630364 0.862274 0.485029 -0.145708
-0.210028 0.977087 0.0344973 -0.499032 0.738152 0.453981 -0.786821 0.236416 0.570106
-0.695176 0.283864 -0.660417 -0.176292 0.557082 -0.81153 -0.534678 -0.0379013 -0.844205
-0 -0.542159 -0.840276 -0.302755 -0.513602 -0.802841 -0.291386 -0.388514 -0.874157
-0.278614 -0.767009 -0.577989 -0.228 -0.182875 -0.956333 -0.754886 -0.310732 -0.577575
-0.269663 -0.910112 0.314607 0.833897 -0.551655 -0.0171056 -0.727183 -0.650326 0.219731
-0.930932 0.241584 -0.273865 -0.529984 0.711485 0.461417 -0.849591 0 0.527442
--0.230759 0 0.973011 0.0269059 0.666241 0.745251 -0.281486 0.910101 0.304109
--0.327088 -0.727603 -0.602998 -0.0227522 -0.712902 -0.700894 0.66698 -0.618231 -0.415847
-0.478994 -0.319329 -0.817676 -0.427317 -0.0899615 -0.899615 -0.0149172 -0.615334 -0.788125
-0.0405642 -0.699732 -0.713253 0.329685 0.576949 -0.747287 -0.29226 0.670479 -0.68194
--0.0274813 -0.659552 -0.751156 -0.135381 -0.631778 -0.763235 -0.185869 -0.430745 -0.883126
--0.888935 -0.146262 -0.434054 0.968516 0.0131871 0.248601 0.562413 -0.788051 -0.250335
--0.161129 -0.986917 -0.00559477 -0.547542 -0.752558 0.365861 0.74427 0.0636547 0.664838
--0.488658 0.730359 0.477273 0.614369 -0.78882 -0.0176979 -0.570599 -0.570599 -0.59062
--0.380847 -0.914032 -0.139644 0.861457 -0.267811 -0.431473 -0.909721 0.1077 -0.40101
--0.128373 -0.826398 -0.548258 0.714629 -0.691576 0.105017 -0.0867184 -0.552259 0.82915
--0.997986 0.0608753 0.0178322 0.459158 -0.880053 0.121167 0.313637 -0.947183 0.0669092
--0.357703 -0.933826 0.00422068 0.561474 -0.827436 -0.00985042 0.911792 -0.293076 -0.287649
-0.102258 0.2876 0.952276 0.641782 -0.187839 0.743527 -0.586427 -0.662095 -0.466619
--0.970237 -0.222192 -0.0962831 0.213508 0.781899 0.585703 0.713906 0.695119 0.0845415
--0.381851 0.575194 0.723423 -0.309021 0.0457809 0.949953 -0.393099 0.48295 -0.782453
-0.634537 -0.625066 0.454594 0.953295 -0.120956 0.276763 0.873406 0.291135 0.390386
--0.280131 0.931437 0.232276 0.204539 0.562482 0.801111 -0.097859 0.831801 -0.546379
-0.907674 0 -0.419677 0.819948 0.571479 -0.0331292 -0.720129 -0.49272 0.488509
--0.537713 -0.778958 0.322628 0.668143 -0.348287 0.657481 -0.687771 0.723042 0.0646623
--0.0484929 0.994104 0.0969857 0.808223 -0.528712 -0.259305 -0.791052 0.566536 -0.230811
-0.752408 -0.165439 0.637583 -0.824815 -0.045823 0.563543 -0.940138 -0.197126 0.277998
-0.772106 -0.292395 -0.564231 0.667928 0.742142 -0.0556606 -0.836563 0.497088 0.230358
-0.186484 -0.959063 -0.213125 0.0693341 -0.990487 -0.118858 0.472632 0.836734 0.276577
--0.0268747 -0.698743 -0.714868 0.924193 -0.370082 0.0943742 -0.969623 -0.102912 0.221904
-0.248282 -0.910366 0.331042 0.948932 -0.199775 -0.24417 -0.365232 0.896478 -0.250866
--0.738858 -0.577498 -0.347254 -0.693041 -0.713791 -0.100982 -0.624894 -0.621727 -0.472189
-0.695174 -0.695174 -0.18294 -0.991053 -0.125374 -0.0457715 0.58828 -0.788073 -0.181294
--0.595792 -0.746726 -0.295689 -0.759902 -0.597864 -0.255163 0.591665 0.792456 -0.148139
--0.137568 -0.792204 -0.594548 -0.176128 -0.401005 -0.898985 0.393653 -0.719251 -0.572465
-0.55508 -0.80699 -0.201625 -0.0898359 0.285728 -0.954091 0.0976536 -0.19194 -0.976536
-0.427482 -0.61799 -0.659809 0.578262 -0.813487 -0.0620733 -0.255468 -0.271109 -0.928028
--0.523024 0.156704 -0.837789 0.683384 -0.416816 -0.599375 -0.395116 0.531363 -0.749358
--0.301731 0.484682 -0.821001 0.845864 -0.510983 -0.153006 0.819229 -0.569405 0.0681339
-0.709237 0.164138 -0.685596 0.207528 0.6127 -0.762581 0.923431 -0.310708 -0.225245
--0.162754 0.787458 -0.594492 0.652019 0.0197582 -0.757945 0.768873 -0.253047 -0.587198
--0.621695 0.321359 -0.714299 0.591213 -0.564986 -0.57555 -0.160851 0.0419611 -0.986086
-0.628373 -0.265136 -0.731334 0.729737 -0.367285 -0.576702 0.112827 -0.126101 -0.98558
--0.664376 0.408847 -0.625659 -0.410122 0.31638 -0.855397 -0.337348 0.363297 -0.868454
-0.685398 -0.602109 -0.409504 -0.697605 0.379467 -0.607743 -0.0654955 -0.688832 -0.721956
--0.871567 -0.0234853 -0.489713 0.670593 -0.741681 -0.0146125 -0.865168 0.146297 -0.479668
--0.8769 0.10167 -0.469798 -0.847356 -0.194703 -0.494043 -0.829636 0.173678 -0.530603
--0.901618 -0.0424442 -0.430445 -0.886804 -0.0928051 -0.452732 -0.811178 -0.0201535 -0.584451
--0.85455 0.278911 -0.438125 -0.661704 0.676585 -0.323081 -0.429258 -0.520739 -0.737949
--0.422608 -0.808144 -0.410251 -0.777924 0.0138915 -0.628205 -0.868429 0.0315543 -0.494808
--0.761754 -0.364631 -0.535514 0.807114 -0.417473 -0.417473 -0.609969 -0.738179 -0.288149
--0.949876 -0.0166645 -0.312182 -0.959867 0.157535 -0.232029 0.883655 -0.294552 -0.363858
--0.758329 -0.262279 -0.59678 -0.711843 -0.4919 -0.501312 -0.153665 -0.881345 -0.446786
-0.652715 -0.141231 -0.744324 -0.298263 -0.742896 -0.599287 -0.894969 0.444145 -0.0420212
--0.424483 -0.849683 -0.312815 -0.0522991 -0.780217 -0.623319 0.73675 -0.0437674 -0.674747
-0.845535 0.431687 -0.314192 -0.801317 0.489281 -0.34423 -0.927278 0.161833 -0.337588
-0.754098 0.324301 -0.571109 0.756034 0.574219 -0.314142 -0.459049 -0.86686 -0.194495
-0.776158 -0.0757228 -0.625975 -0.960802 0.277236 0 -0.725056 -0.28665 -0.6262
-0.717335 -0.531622 -0.450343 -0.812963 -0.0150549 -0.582121 -0.792509 -0.074795 -0.605256
--0.644503 -0.245979 -0.723954 -0.565292 0.0699885 -0.821916 -0.480075 -0.801048 -0.357561
-0.508248 -0.512954 -0.691782 -0.871898 -0.272468 -0.406886 0.520541 -0.362801 -0.772924
-0.522675 -0.441918 -0.729053 -0.662861 -0.628622 -0.406755 -0.758493 -0.204926 -0.618623
--0.537976 -0.37459 -0.755158 0.932353 0.346853 -0.10203 -0.816905 -0.00464811 -0.576753
--0.383825 0.119945 -0.915583 -0.292393 -0.247722 -0.923656 -0.475811 -0.254623 -0.841885
-0.943693 0.321587 0.0776246 -0.0446794 -0.854494 -0.517537 0.238988 0.942297 0.234436
--0.780142 0.61709 0.102848 0.825891 -0.560899 0.0574149 0.0991213 0.429526 0.897598
--0.964809 -0.244802 0.0960009 0.411222 -0.712785 -0.568185 0.242342 -0.693802 -0.678167
--0.163558 -0.906226 -0.389877 0.260388 -0.698313 -0.666751 -0.564163 -0.57856 -0.589057
--0.00563318 0.9982 0.0597117 -0.996706 -0.0699794 -0.0409879 -0.368071 0.926019 -0.0837409
-0.21344 -0.649488 -0.729801 -0.420871 -0.899368 -0.118338 0.97701 0.212449 -0.0178101
-0.214514 -0.477185 -0.85222 0.0847024 -0.0889375 -0.992429 -0.450341 -0.378696 -0.808568
--0.172528 -0.73739 -0.653062 -0.80767 -0.560697 0.182449 -0.302778 0.43692 -0.847011
--0.29517 -0.361763 -0.884309 -0.716899 0.109357 -0.688547 -0.00174721 -0.676172 -0.736742
-0.111441 0.984393 0.136205 0.677331 0.727815 -0.107279 0.523706 0.851896 -0.00232758
--0.55464 0.741248 0.378054 -0.961 0.0864778 0.262681 0.572965 -0.791734 -0.211823
--0.625792 -0.727271 -0.281888 -0.366019 -0.524073 -0.76901 0.299987 -0.784325 -0.542994
-0.0899026 -0.70124 -0.707234 -0.726774 -0.34349 -0.594823 -0.540466 -0.493469 -0.681458
--0.100363 -0.451634 -0.886541 0.908532 0.345828 -0.23446 -0.889587 -0.167233 0.425051
-0.111754 -0.621633 -0.775295 -0.349217 -0.133035 -0.92755 0.236301 0.843931 0.481603
-0.512517 0.772843 0.374219 -0.999969 -0.00476176 0.00634901 0.567379 -0.756505 -0.32524
--0.532288 -0.846394 -0.0169279 -0.476215 -0.878352 -0.0414483 0.632215 0.12772 0.764193
--0.0429579 0.948003 0.31535 0.956566 -0.206483 -0.205781 0.873818 0.484142 -0.0452653
--0.636874 0.770953 0.00474862 -0.506477 0.569787 -0.647166 -0.0814436 -0.977323 0.195465
--0.141925 -0.978539 -0.149395 0.415453 -0.909612 0.00232467 0.9282 -0.330592 0.170745
-0.882775 0.396348 0.252222 -0.809829 0.583077 0.0647864 -0.910695 0.395136 0.120423
-0.862701 0.38634 0.326326 0.988963 -0.0830152 0.122718 0.381722 0.819996 0.426492
--0.702105 0.706334 0.0902303 -0.635553 -0.566701 -0.524331 0.188958 0.6771 0.711218
-0.93302 0.0222148 0.359139 0.675939 -0.692629 0.251739 -0.72403 0.686661 0.0653963
--0.915396 0.349515 0.199723 -0.48367 -0.860083 -0.162235 0.862666 0.342529 0.37213
--0.851916 0.523678 -0.000835212 0.808312 -0.5819 0.0895773 0.618689 -0.471382 0.628509
--0.749072 0.650357 0.1262 0.10313 0.980641 0.166456 0.682158 -0.731202 -0.00222927
--0.951088 -0.118595 -0.285249 0.77083 -0.632254 0.0779491 0.211129 0.889759 0.404664
--0.542737 0.839349 0.0305026 0.789355 -0.612946 -0.0348831 -0.802624 -0.526311 -0.280699
-0.696452 -0.712102 -0.0886867 -0.972939 -0.023615 -0.229853 -0.531443 0.77455 0.342988
-0.590401 -0.801961 -0.0910202 0.868927 0.463428 -0.173785 0.981048 -0.151578 -0.120701
--0.80975 0.563304 -0.164297 0.649936 -0.747776 -0.135695 -0.919676 -0.326727 -0.217818
-0.832367 -0.542793 -0.111985 -0.887132 -0.3314 -0.321203 -0.919632 0.386829 -0.0681209
--0.918796 0.350723 0.181125 0.186736 -0.982362 0.00968799 -0.859083 0.501132 0.104131
--0.961772 0.225352 0.1556 0.277818 -0.884901 -0.373854 0.662087 -0.735246 -0.145098
--0.650969 -0.754723 -0.0814409 -0.647192 -0.616373 -0.448583 0.804875 -0.593398 -0.00736487
-0.120998 0.992372 0.0236056 -0.193053 0.978683 0.0700657 -0.676753 0.104116 -0.728811
--0.239465 -0.810878 -0.533979 -0.580163 0.463296 -0.669901 -0.60503 0.537085 -0.587774
--0.518402 0.439682 -0.733443 -0.562085 0.436355 -0.702606 -0.608176 0.351391 -0.711791
--0.683912 0.254025 -0.683912 -0.479149 0.199326 -0.854801 -0.272635 0.576555 -0.77023
--0.215907 0.663423 -0.716418 -0.394579 0.506252 -0.766823 -0.406585 0.609878 -0.680248
-0.297571 0.732482 -0.612309 -0.0874499 0.911977 -0.400812 -0.522842 0.692766 -0.4967
--0.814067 0.323509 -0.482323 0.826154 -0.56344 0.00224542 -0.489245 0.462437 -0.739453
-0.77798 -0.430456 -0.457661 -0.566856 0.474453 -0.673475 -0.708262 0.397687 -0.583275
-0.806212 -0.58939 0.0514062 -0.817192 0.498769 -0.288835 -0.679102 0.469527 -0.564239
--0.773952 0.348278 -0.528867 -0.910986 0.0700759 -0.40644 -0.978773 -0.13328 -0.155691
--0.78692 0.041236 -0.615676 0.955127 -0.267503 0.127183 -0.70305 0.212241 -0.67873
--0.572229 0.171218 -0.802022 -0.407421 0 -0.913241 -0.531609 -0.182043 -0.827195
--0.770144 0.0738629 -0.633579 -0.823196 -0.00460744 -0.567739 -0.800541 0.198299 -0.56552
--0.464681 0.52922 -0.709929 -0.445637 0.728326 -0.520527 -0.844319 0.360537 -0.396407
--0.803115 -0.473484 -0.361689 -0.760715 -0.41624 -0.498053 -0.900008 0.133334 -0.414979
-0.525763 -0.126183 -0.84122 -0.747258 0.161173 -0.644693 -0.551081 -0.76919 -0.323507
--0.572163 -0.754913 -0.320525 -0.897505 -0.110123 -0.427034 0.742705 -0.553222 -0.377274
--0.167768 -0.894763 -0.413828 0.59585 -0.546195 -0.588756 -0.554865 -0.615994 -0.559175
--0.566758 -0.775831 -0.277257 -0.204349 -0.819952 -0.534714 0.666597 -0.367943 -0.64828
-0.812309 0.445752 -0.376111 -0.420328 -0.754858 -0.503501 0.492021 0.00531915 -0.870567
-0.852066 0.41589 -0.317834 0.792062 0.517678 -0.323493 0.593697 -0.521295 -0.613005
--0.705055 -0.236478 -0.668562 -0.620622 0.404258 -0.671866 -0.822447 0.568842 0
-0.11671 0.729157 -0.674322 -0.331979 0.799635 -0.500373 -0.803889 0.500019 -0.322092
-0.798379 -0.0523527 -0.599875 0.369866 0.156217 -0.915858 -0.619742 0.236812 -0.748225
-0.147107 0.249524 -0.95713 -0.94483 -0.181092 -0.272951 0.797186 -0.028269 -0.603072
-0.656777 -0.402486 -0.637691 0.314249 -0.196992 -0.928677 0.42417 -0.24661 -0.871357
--0.3767 0.219742 -0.899895 0.149819 -0.301842 -0.941512 -0.636536 -0.642656 -0.426397
-0.392456 -0.364706 -0.844374 0.453076 -0.372224 -0.810044 -0.601956 -0.566373 -0.562913
--0.769846 -0.60387 -0.206587 -0.648616 -0.253806 -0.717551 -0.482492 0.516685 -0.707275
-0.579276 -0.177645 -0.795539 -0.416049 0.462771 -0.782781 -0.664953 0.31518 -0.677125
--0.309773 -0.937782 -0.156861 -0.28769 -0.939543 -0.185724 -0.654088 -0.735849 -0.175202
-0.821154 0.186192 -0.539479 -0.743262 -0.408794 -0.529574 0.532575 -0.282284 -0.797922
--0.264237 -0.397348 -0.878802 0.0706018 -0.600115 -0.796792 -0.778534 -0.257697 -0.572256
--0.0263625 -0.254837 -0.966624 0.156417 -0.449142 -0.879662 -0.72083 -0.511382 -0.46786
--0.449142 -0.156417 -0.879662 -0.55333 0.166757 -0.816099 -0.372586 -0.62904 -0.682267
--0.165314 -0.521468 -0.837104 -0.0278004 -0.185336 -0.982282 -0.2608 0.587367 -0.766148
-0.411074 -0.88683 -0.211069 0 0.211055 -0.977474 0.40504 0.495825 -0.76818
-0.272106 0.705253 -0.654658 0.880827 0.463391 0.0970186 -0.901997 0.43139 -0.0174299
--0.100298 0.254602 -0.961831 0.712622 -0.698888 0.0610383 -0.762781 -0.642749 0.0709864
-0.542105 -0.496929 -0.677631 -0.506658 -0.608718 -0.610541 -0.1159 -0.321207 -0.93989
-0.477504 0.187591 -0.85837 0.384429 -0.242307 -0.890787 0.598357 -0.295391 -0.74479
--0.294199 -0.501868 -0.813373 0.663932 0.165983 -0.729139 0.814149 0.32566 -0.480736
--0.721139 -0.655581 -0.22399 0.247493 -0.489361 0.836226 0.87133 -0.483522 -0.0836124
--0.163022 0.984484 -0.0649265 -0.905469 0.347303 0.243939 -0.847847 0.520966 0.0987452
-0.292962 -0.404503 -0.866343 0.0265558 -0.68455 -0.728482 0 -0.73366 -0.679517
--0.26173 -0.628348 -0.732582 -0.00576413 -0.201744 -0.979421 0.782567 -0.146079 -0.605185
-0.677627 -0.511417 -0.528464 0.53679 -0.84314 -0.0311772 0.00518468 -0.995459 0.0950525
--0.18027 -0.755749 -0.62956 0.131033 -0.512738 -0.848487 0 -0.263428 -0.964679
-0.0960711 -0.148345 -0.984258 0.242487 -0.664796 -0.706573 -0.196046 -0.844506 -0.498373
-0.125768 -0.440786 -0.888758 -0.244309 -0.745455 -0.620169 -0.228088 -0.740599 -0.632051
--0.122469 0.35652 -0.926226 0.257634 -0.434757 -0.862908 0.00588786 -0.812524 -0.582898
--0.25625 -0.318246 -0.912719 0.02465 0 -0.999696 0.686449 0.171612 -0.706638
--0.77205 0.353728 -0.528029 0.409933 -0.625121 -0.664213 0.471881 -0.434815 -0.766984
--0.0935671 -0.340244 -0.935671 0.13288 0 -0.991132 0.225659 0.0569847 -0.972538
-0.166533 -0.313345 -0.934923 0.463903 -0.746279 -0.477349 -0.807694 0.472775 -0.352298
-0.616546 0.784695 0.0642236 0.0344266 -0.496727 -0.867224 0.226224 -0.690792 -0.686752
-0.00989547 -0.951202 -0.308409 -0.668022 -0.276926 -0.690694 0.255987 0.252662 0.933077
-0.455952 0.237345 0.857773 -0.265447 0.245028 0.932469 -0.0574943 0.767959 0.637913
-0.904957 -0.0530101 0.422187 0.654389 0.75029 0.0940213 0.150119 -0.850672 -0.503807
-0.34337 0.587598 0.732684 0.0545363 -0.96711 0.248443 -0.830342 0.556603 0.0269394
-0.674611 0.732767 0.0891727 0.819487 0.569374 0.0652255 0.891889 -0.445384 -0.0785311
--0.482966 -0.0817328 -0.871816 -0.975184 -0.0872116 0.203494 -0.0860946 0.941769 0.325051
-0.805688 -0.591934 0.0219235 0.343258 0.86368 0.369094 -0.966533 0.250162 0.0568549
-0.591278 0.743866 0.311534 0.743494 0.650557 0.154895 0.943002 0.189716 -0.273415
-0.874134 -0.277382 -0.398683 0.67779 -0.550704 -0.487161 0.33154 0.754817 0.565979
-0.626842 -0.676591 0.386386 -0.598319 0.800793 0.0272997 0 -0.871576 -0.490261
-0.0722282 -0.967055 -0.244105 -0.139767 -0.941485 -0.306711 0.828475 0.555684 -0.0696009
-0.903477 -0.424268 -0.0610457 -0.954305 0.183792 -0.235631 -0.946472 -0.165543 -0.277104
-0.62114 0.763484 0.176852 -0.669754 0.740255 0.0587504 -0.827886 0.454002 -0.329374
-0.854212 -0.51096 0.0961315 0.763126 0.457875 0.456058 -0.639139 0.768489 0.0304352
--0.726498 0.687076 -0.0112635 0.827618 -0.529078 0.187416 -0.0556839 0.997249 0.0489344
-0.238792 0.878661 0.413442 -0.898035 0.436249 -0.0567479 0.0794507 -0.979177 -0.186817
-0.477464 -0.878192 -0.0284204 0.248372 -0.931394 0.266113 -0.953889 -0.0260367 -0.299027
-0.065624 -0.976008 -0.20761 -0.4787 -0.656139 -0.583376 0.793964 -0.53758 -0.283952
-0.870715 -0.477104 -0.119276 -0.904923 0.3541 -0.236067 0.971278 -0.182912 0.152191
-0.823809 -0.566067 0.03011 0.796188 -0.60419 0.0322235 -0.974865 -0.162277 -0.152661
-0.970984 0.192592 0.141769 0.931307 0.347631 -0.108724 -0.205526 0.976251 0.0685088
--0.798314 -0.434083 0.417452 -0.417846 -0.473559 -0.775337 0.78154 -0.623635 -0.0165593
-0.828034 -0.520319 -0.208873 -0.473877 -0.880563 -0.00707279 -0.745437 -0.64853 0.154057
-0.550147 -0.696653 -0.460449 -0.926113 0.356864 -0.122326 -0.863385 0.400411 -0.306981
--0.864079 0.29614 -0.407023 0.347919 -0.748956 -0.56393 0.167435 -0.771399 -0.61393
--0.879002 0.355188 0.318115 -0.536021 -0.716349 -0.446684 0.645486 -0.761253 -0.0619761
-0.403714 -0.847329 -0.345034 -0.246641 -0.44043 -0.863243 -0.693521 0.709105 -0.127275
--0.825708 -0.324556 -0.461378 0.982818 0.0530375 -0.176792 0.746583 -0.584152 -0.318403
--0.510715 -0.2293 -0.828608 0.906152 0.247132 -0.34324 0.122792 -0.960899 -0.248184
-0.310242 0.916184 0.253688 -0.708175 -0.465174 -0.531132 0.978202 -0.145819 -0.147844
--0.945683 0.282989 -0.160002 -0.494376 -0.861905 -0.112752 -0.539 -0.842296 0.00404395
-0.449857 0.878736 -0.159535 0.528707 0.827357 0.189603 0.537905 0.815755 0.212607
-0.064815 0.914355 0.399693 0.0703927 0.240253 0.968155 0.493916 0.631321 0.597898
--0.61754 -0.782218 -0.0823387 -0.810859 0.548522 -0.20404 -0.36257 0.611997 -0.702854
--0.778382 0.555209 -0.293027 -0.353858 0.234048 -0.905542 -0.697202 0.312684 -0.645088
--0.3748 0.3748 -0.847968 0.0431331 0.539164 -0.841096 -0.116571 0.657874 -0.744052
--0.249592 0.660891 -0.707762 0.0597491 0.336768 -0.93969 -0.577712 0.659838 -0.480483
--0.60388 0.530683 -0.594731 -0.150688 0.539966 -0.828088 -0.369478 -0.383689 -0.846326
--0.707931 0.353966 -0.611181 -0.306082 0.83371 -0.459609 -0.465637 0.456639 -0.758066
-0.153931 0.262965 -0.952447 0.213066 0.319599 -0.923287 -0.309679 0.424909 -0.850618
--0.0362285 -0.00905712 -0.999303 -0.771425 0.115714 -0.625711 -0.810519 0.0457551 -0.583922
--0.451093 0.663373 -0.597035 -0.312808 0.904909 -0.288603 -0.799353 0.583714 -0.14252
--0.593688 -0.604582 -0.531051 -0.716216 -0.648564 -0.257681 0.389333 -0.449012 -0.804243
-0.574993 0.146991 -0.804846 -0.631734 -0.539535 -0.556609 0.696127 0.126568 -0.706674
--0.661887 0.625641 -0.412891 0.134114 -0.560673 -0.817104 0.833614 0 -0.552348
--0.890851 0.234503 -0.389092 -0.912051 -0.343773 -0.223569 -0.879735 -0.149288 -0.45142
-0.516374 0.344249 -0.784124 -0.539225 -0.644543 -0.542034 -0.555452 -0.336169 -0.760567
--0.551223 0.045306 -0.833127 0.344184 -0.251519 -0.904586 -0.379469 0.236316 -0.894516
--0.0505197 0.523332 -0.85063 -0.428999 0.712708 -0.554983 -0.423668 0.738436 -0.524612
-0.414105 -0.164673 -0.895209 -0.699193 0 -0.714933 -0.503052 0.220748 -0.835589
--0.193854 0.693313 -0.694073 -0.749304 -0.194264 -0.633092 -0.559887 0.352447 -0.749872
-0.121946 0.858652 -0.497842 -0.782248 -0.349631 -0.515603 0.913806 -0.214453 -0.344917
--0.997963 0 -0.0637986 -0.934474 0.254436 -0.249039 -0.970636 0.23386 -0.0563426
--0.615577 -0.685302 -0.389135 -0.560925 -0.362052 -0.744501 0.307347 -0.53607 -0.786236
--0.669301 0 -0.742992 0.401257 -0.517128 -0.756023 0.395116 -0.531363 -0.749358
--0.632136 -0.102429 -0.768058 0.805925 -0.0215323 -0.591627 0.519204 -0.705333 -0.482631
--0.672804 -0.067374 -0.736747 0.553892 0.568681 -0.608116 -0.71218 0.0727614 -0.698216
--0.363524 -0.813978 -0.453088 0.561699 -0.27675 -0.779682 0.404642 -0.617612 -0.674404
-0.542029 -0.496095 -0.678302 0.17444 -0.0847279 -0.981016 -0.570814 -0.32865 -0.752436
--0.303507 0.360772 -0.881888 -0.410297 -0.776689 -0.477923 0.407867 -0.210306 -0.888491
-0.372813 0.135367 -0.917979 -0.317082 0.018119 -0.948225 -0.831034 0.0494128 -0.554023
-0.55003 -0.523838 -0.650432 -0.305021 -0.570503 -0.762554 -0.833039 -0.183966 -0.521731
--0.421117 -0.197667 -0.885205 -0.902386 -0.374105 -0.213882 -0.347955 -0.665913 -0.659914
--0.960518 -0.274434 -0.0457389 -0.968183 -0.212205 0.132628 0.238512 -0.0226325 -0.970876
-0.422694 -0.422694 -0.801661 0.380996 -0.627881 -0.678681 -0.864546 -0.364306 0.346181
--0.330467 -0.165233 -0.929241 -0.290911 -0.661823 -0.690914 0.0875772 -0.860865 -0.50124
-0.683175 -0.704524 -0.192143 -0.564599 -0.793711 0.226385 0 0.175069 -0.984556
--0.37607 -0.75214 -0.541162 -0.455337 -0.610873 -0.64769 -0.578046 -0.611896 -0.539857
--0.454739 0 -0.890625 0.321236 0.470648 -0.821766 0.309639 0.379102 -0.872012
--0.174146 0.245853 -0.953535 0.270138 -0.433858 -0.85953 0.0202675 0.668827 -0.743141
-0.0359715 0.373359 -0.926989 -0.315727 -0.315727 -0.894781 -0.380819 -0.635748 -0.671417
--0.423972 0.527501 -0.7362 -0.641047 -0.166119 -0.749308 -0.54974 -0.66345 -0.507562
--0.87643 -0.316259 -0.363112 0.256253 -0.169224 -0.951682 -0.82949 -0.49722 -0.254398
-0.660376 -0.23983 -0.711607 -0.115367 -0.195076 -0.973979 0.00509622 -0.225508 -0.974228
--0.23051 -0.669224 -0.706403 -0.501724 -0.666412 -0.551514 0.495783 -0.452462 -0.741268
-0.156365 -0.721412 -0.674621 -0.133386 -0.306152 -0.942592 -0.356597 -0.662251 -0.658986
-0.735799 0.674674 -0.0584333 -0.63828 0.760538 -0.119082 -0.172447 -0.172447 -0.969806
--0.492528 -0.379489 -0.783201 0.325622 0.842744 -0.428664 0.107415 0.747668 -0.655328
--0.81243 -0.183011 -0.553593 -0.983947 -0.178461 0 -0.172447 -0.172447 -0.969806
-0.082675 -0.277205 -0.957247 -0.14805 -0.345451 -0.926685 0.536267 0.701781 -0.468958
-0.312591 0.842878 -0.437999 -0.0678658 0.729558 -0.680544 -0.83351 -0.176319 -0.523615
--0.0240081 -0.970826 0.23858 -0.976271 -0.21639 0.00838721 0.121592 -0.688336 -0.715128
-0.253107 -0.523776 -0.813385 -0.221956 -0.635875 -0.739188 -0.0115213 -0.724692 -0.688976
-0.386263 0.920088 -0.0651006 0.222209 0.96929 -0.105358 -0.0538851 0.948377 -0.312533
--0.515738 0.055012 -0.854979 -0.427164 -0.768895 -0.475743 0.872329 -0.187977 -0.45134
--0.696362 0.666457 -0.266298 0.378509 -0.485634 -0.787966 -0.135512 -0.597534 -0.79031
--0.12771 -0.989754 -0.0638551 -0.14718 -0.987332 -0.0592808 -0.18581 -0.854396 -0.485264
-0.170756 -0.282894 -0.943829 -0.260393 -0.791765 -0.552542 -0.388232 0.522619 0.759042
-0.638935 -0.0418974 0.768119 -0.537887 0.758559 0.367786 0.00162546 -0.831423 -0.555637
-0.697849 0.536807 -0.474179 0.509548 -0.774121 0.375629 0.502088 -0.793742 -0.343339
-0.761545 -0.598772 -0.248035 0.718602 -0.617745 -0.319378 -0.655845 -0.139119 -0.741966
--0.526761 -0.325527 -0.78521 -0.760006 0.313617 -0.569241 0.792057 0.243343 0.559848
-0.27298 0.961115 0.0417052 -0.135909 0.96431 0.227235 -0.455563 0.754413 0.472571
-0.0211604 0.921441 -0.387941 -0.545395 0.253523 -0.798918 -0.807688 -0.264334 -0.527037
--0.401322 0.825934 0.395947 0.974495 -0.0417342 0.220496 0.984002 -0.127601 0.124329
-0.689761 0.720147 0.074952 0.398757 0.806309 0.436873 0.399496 0.559294 0.726356
-0.105949 0.994286 -0.0130398 0.676602 0.67255 0.299811 -0.109824 0.93223 -0.344797
--0.850381 -0.390716 -0.35241 0.274537 0.137269 0.951728 0.747409 0 0.664364
-0.944553 0.280813 -0.17019 -0.691431 -0.718024 -0.0797805 0.412394 -0.830269 0.374945
-0.0349829 -0.988267 0.148677 -0.17372 -0.978318 0.112766 -0.550285 -0.822469 -0.143981
-0.597449 0.74922 0.285876 0.700209 -0.65902 0.274592 -0.284758 0.801629 0.525646
--0.542715 -0.50395 0.671933 0.934404 -0.0133486 -0.355964 -0.610997 -0.73741 -0.287941
-0.936698 0.342018 -0.0749769 0.852352 -0.437889 -0.285919 -0.499767 0.866067 -0.0126647
--0.971465 0.124172 0.202084 0.603574 0.720053 0.342378 0.888564 -0.458445 -0.0167852
-0.955239 -0.114 0.272988 -0.278246 0.924176 0.261684 0.348285 0.868507 0.352693
--0.375022 0.912919 0.16105 -0.6494 -0.684822 -0.330604 0.754167 -0.270397 -0.598429
--0.16011 -0.936841 -0.310957 -0.564127 -0.798593 -0.209785 -0.838848 0.522174 0.153845
-0.509181 -0.86066 -0.000343577 0.56089 -0.820125 0.113121 -0.749457 0.356538 0.557848
-0.757747 -0.652537 0.00394044 -0.855023 0.510462 0.0914577 0.317331 -0.769286 0.554527
--0.641643 0.641643 0.420224 0.706267 -0.462727 -0.535789 -0.0413064 -0.888088 -0.457813
--0.275058 -0.933038 0.231911 -0.854788 -0.518817 0.012922 0.153124 -0.922995 -0.353035
-0.577741 -0.812855 -0.0740391 0.396683 -0.895789 0.200509 0.70818 -0.682192 0.181918
-0.428481 -0.895219 0.122423 -0.476731 0.800909 0.362316 -0.473672 0.879163 -0.0520321
-0.258292 0.926072 0.275092 0.25796 -0.51592 -0.816874 -0.742338 0.652228 -0.153402
--0.631057 0.308815 -0.711618 0.759959 -0.643043 0.094647 -0.43105 0.826179 -0.3628
-0.781053 -0.574353 -0.245103 0.325906 -0.422797 -0.845593 -0.145221 -0.875773 -0.460361
--0.250892 -0.802855 -0.540812 0.972572 -0.0342254 -0.230071 0.25179 -0.795428 -0.551268
--0.129511 -0.647553 -0.750934 0.485874 -0.85679 -0.172735 -0.682432 -0.554476 -0.476281
-0.944536 0.277064 0.176313 -0.862268 0.22419 0.454128 -0.964739 0.0639285 0.255327
--0.931844 -0.362605 -0.013577 -0.594279 -0.772562 -0.223562 0.840345 -0.541131 0.0315954
-0.337175 -0.937691 -0.083952 -0.196653 0.947336 0.252749 0.567186 0.823586 0.00258989
--0.154528 0.881383 0.446415 -0.151051 0.868543 0.472034 0.219365 0.877462 -0.426544
-0.668805 0.622144 -0.406986 -0.600171 0.493881 0.629187 0.237233 0.964443 0.116487
--0.864581 0.432291 -0.256172 0.743713 0.131362 0.655465 0.987282 -0.0806346 0.137013
--0.110199 0.539397 0.834809 -0.184052 0.94071 -0.28494 -0.806674 -0.235797 0.541919
--0.824177 0.524476 0.213675 -0.79624 0.498977 -0.342088 0.18834 0.690065 -0.698813
--0.0866422 0.880174 -0.466676 -0.647615 0.674422 -0.354612 0.766549 -0.618904 0.171349
--0.874694 0.35783 -0.326906 0.500186 0.0218937 -0.865641 -0.428552 0.220262 -0.876258
--0.633891 0.465654 -0.617534 0.317038 0.462008 -0.828273 0.45888 0.209489 -0.863449
--0.172331 0.623042 -0.762969 -0.436479 0.421808 -0.79471 -0.436819 0.422177 -0.794327
--0.204932 0.63529 -0.744587 -0.551799 0.469195 -0.689474 -0.0814733 0.537724 -0.839175
-0.0705667 0.650782 -0.755978 0.0268041 0.830926 -0.555737 -0.403932 0.580653 -0.706881
--0.45241 0.407383 -0.793325 -0.706872 -0.115358 -0.697872 0.312871 0.368741 -0.875295
--0.781045 0.292892 -0.551528 -0.643803 0.366898 -0.671493 -0.55345 0.675872 -0.486713
--0.674034 0.26364 -0.690052 -0.620867 0.46565 -0.630629 -0.648835 0.511203 -0.563635
-0.414562 0.910015 -0.00337042 -0.370703 0 -0.928751 -0.160067 0.101506 -0.981873
-0.535569 -0.494819 -0.684339 0.619153 -0.755367 -0.21464 -0.649905 -0.400235 -0.646093
-0.720422 -0.432253 -0.542355 0.408888 -0.713695 -0.568726 -0.712135 -0.577994 -0.39848
-0.83064 -0.139465 -0.539061 -0.202699 -0.719788 -0.663942 0.873608 -0.0513887 -0.48391
--0.943873 -0.330306 -0.00130685 0.917684 0 -0.397311 -0.936431 -0.211366 -0.280038
--0.635925 0.236485 -0.734626 -0.786572 -0.0172602 -0.617258 -0.806092 0.307588 -0.505575
--0.625074 0 -0.780565 -0.0319201 0.516273 -0.855829 -0.0713707 0.0356854 -0.996811
--0.537102 -0.559349 -0.631387 -0.3801 0.471936 -0.795488 -0.749884 -0.326389 -0.575451
--0.735108 -0.385716 -0.557529 -0.736127 0.114607 -0.66707 -0.65306 -0.483595 -0.582794
-0.477285 0.369327 -0.797369 -0.747115 -0.0498077 -0.662826 -0.205603 0.699771 -0.68414
--0.364781 0.674051 -0.642331 -0.522794 -0.459039 -0.71831 0.185773 0 -0.982593
--0.882847 0.0509335 -0.46689 0.671071 0.0447381 -0.740042 -0.52554 -0.21146 -0.824071
--0.497897 -0.342304 -0.796823 -0.436782 -0.288301 -0.852117 0 -0.185408 -0.982662
--0.723993 -0.00559789 -0.689784 -0.454739 0 -0.890625 -0.297124 0 -0.954839
-0.22072 0.839394 -0.496689 -0.258042 0.642919 -0.721158 -0.402083 0.467097 -0.787496
-0.133029 0.768613 -0.62573 0.131468 0.821464 -0.5549 -0.278108 0.661446 -0.696523
--0.835613 -0.33955 -0.431807 -0.151789 -0.893317 -0.423019 -0.863961 -0.2239 -0.451044
--0.839578 -0.423524 -0.340199 0.867114 -0.00530345 -0.498082 -0.904054 0.138161 -0.404472
-0.180169 -0.750704 -0.635596 0.0305688 -0.730056 -0.682704 -0.423027 -0.687823 -0.58987
--0.492764 0.236527 -0.8374 0.822643 -0.364328 -0.43649 0.0683147 -0.959512 -0.273259
--0.997079 -0.0487461 0.0587908 0.0222418 -0.578286 -0.815531 -0.76425 -0.390849 -0.51299
--0.5314 -0.442833 -0.722159 -0.177164 -0.500682 -0.847308 0.547588 -0.305631 -0.778933
-0.474633 -0.870765 -0.128421 0.397145 -0.723829 -0.564223 -0.0380044 -0.547264 -0.836097
-0.395116 -0.531363 -0.749358 -0.11476 -0.774954 -0.621511 0.0101811 -0.897637 -0.440617
-0.883631 -0.239682 -0.402181 0.978105 -0.204513 0.0385314 -0.435043 -0.791438 -0.429375
--0.333969 0.0811067 -0.939088 0.428472 -0.265245 -0.863746 -0.508177 0.182626 -0.841668
--0.772113 -0.15745 -0.615672 -0.470757 0.262312 -0.842366 0.0920962 0.446937 -0.889812
--0.0210331 0.57922 -0.8149 -0.634238 0.27247 -0.723535 0 -0.180093 -0.98365
-0.621395 -0.517209 -0.588527 -0.127733 0.58088 -0.803905 -0.261064 0.124687 -0.957235
--0.713487 -0.249232 -0.654844 -0.919597 -0.038546 -0.390967 -0.826018 -0.0225278 -0.563194
--0.636143 -0.373933 -0.674904 0.519706 -0.377321 -0.766508 -0.0341066 0.0341066 -0.998836
-0.177046 -0.481884 -0.858162 0.488382 -0.586761 -0.645906 -0.387423 -0.819548 -0.422191
--0.628337 0.7181 -0.299208 -0.97997 -0.0544428 -0.191558 0.288155 -0.288155 -0.9132
--0.328004 -0.770429 -0.546674 -0.319041 -0.738927 -0.593464 0.0421692 -0.685708 -0.726655
-0.598082 -0.642938 -0.478465 0.354843 -0.593661 -0.722255 -0.11671 -0.786079 -0.607008
-0.925631 -0.0970419 -0.365773 0.492707 0.854026 0.166973 -0.557297 0.827398 -0.0695197
-0.46927 -0.210363 -0.857632 0.570595 -0.423409 -0.703666 -0.117946 -0.451565 -0.884408
-0 -0.179487 -0.98376 0.846403 -0.50626 -0.165238 -0.644232 -0.759273 0.0920331
-0.812889 -0.452536 0.366638 -0.509134 -0.83879 0.192909 0.218713 -0.132745 -0.966718
--0.200509 -0.200509 -0.958954 0.192226 -0.973665 -0.122579 -0.516551 -0.856214 0.00846805
--0.0354702 -0.986073 0.162488 0.409464 0.394299 -0.82272 0.13231 -0.573343 -0.808561
--0.490945 -0.499693 -0.713638 -0.106641 -0.00784122 -0.994267 -0.409572 -0.253756 -0.876276
-0.625638 -0.687389 -0.368882 0.494146 -0.484163 -0.722085 -0.3461 -0.359944 -0.866404
--0.172447 -0.172447 -0.969806 -0.318335 -0.695493 -0.644167 -0.224632 -0.703848 -0.673897
-0 -0.587764 -0.809032 0.153572 -0.661029 -0.734477 0.00854327 -0.341731 -0.939759
--0.575751 -0.589459 -0.566612 0.488449 -0.636069 -0.597355 -0.30195 -0.433514 -0.849054
-0 -0.175069 -0.984556 0.230173 -0.0886227 -0.969106 0.451094 0.263138 -0.852803
--0.256417 0.682522 -0.684408 -0.349964 -0.817377 -0.457625 0.509858 -0.509858 -0.692884
-0.0929787 0.0929787 -0.991317 0.735538 0.465457 -0.492274 -0.726582 -0.59617 0.341556
-0.785634 -0.583274 -0.206328 0.139874 0.963575 0.227943 -0.602536 -0.763212 0.233363
--0.279498 -0.792159 -0.542554 -0.210776 -0.321124 -0.923284 -0.19265 -0.17179 -0.966113
-0.0960711 -0.148345 -0.984258 0.349424 -0.255216 -0.901536 0.644899 -0.12441 -0.754074
-0.858479 -0.280656 -0.429239 -0.82493 -0.434405 -0.361638 0.731604 -0.491344 -0.472585
--0.141882 -0.141882 -0.979663 0.208143 -0.976118 -0.0622036 0.728672 -0.613151 -0.305094
--0.340743 -0.908647 -0.241359 -0.0150653 -0.858722 -0.51222 -0.184493 -0.798436 -0.573117
-0 -0.185408 -0.982662 -0.423191 -0.423191 -0.801136 0.423718 -0.501943 0.754
-0.914698 -0.0531801 0.400624 -0.0418217 0.888712 0.456554 -0.968621 0.0284889 0.246903
-0.0250435 -0.751305 0.659479 -0.358429 0.907385 -0.219503 -0.996783 0.0419208 -0.0683153
--0.119944 -0.420374 -0.899388 0.934608 -0.142688 0.325805 -0.0671048 -0.971254 0.228392
-0.502134 0.819272 0.276866 0.616506 0.616506 0.489735 -0.0298865 0.999538 0.00553454
-0.289798 0.955825 -0.049147 -0.747094 0.516174 -0.418825 0.275001 -0.910122 0.309922
--0.299544 -0.948843 0.0998479 0.710932 -0.640053 0.291389 0.798598 -0.466295 0.38054
--0.0722302 -0.996777 -0.0349113 -0.268286 -0.960636 -0.0721198 -0.0161611 -0.985825 0.166998
-0.622713 0.178399 0.761842 -0.271273 0.883079 0.38286 0.113325 0.869937 -0.479965
-0.531963 0.0115144 0.846689 -0.354269 0.919412 0.170808 -0.784283 0.61792 0.0554544
--0.976588 0.151139 0.153076 -0.972625 0.196841 -0.123508 -0.72475 0.102208 0.681389
-0.828698 -0.510537 -0.229372 -0.790963 -0.0903958 0.60515 0.894124 0.0286272 0.446903
--0.275851 0.927108 0.253727 -0.542035 0.832958 0.111265 0.729044 -0.557877 0.396572
--0.639486 -0.689102 0.340876 -0.924675 -0.377418 0.0503224 -0.219365 -0.731218 -0.645909
-0.891443 0.432647 -0.134707 -0.142372 0.968598 0.203833 -0.235422 0.881707 0.408864
--0.814427 0 0.580265 -0.470187 -0.606294 0.641352 0.645084 -0.763198 0.0373523
--0.763394 0.643827 0.0521193 0.716086 0.461247 0.5239 0.849921 -0.449344 -0.275179
--0.914794 -0.333429 0.227986 0.963175 -0.157253 0.218095 0.969073 0.199515 0.145225
--0.0623225 0.996256 0.0599139 0.674192 -0.244272 0.696991 0.371349 0.516538 0.771549
--0.569795 0.776663 -0.268566 -0.718254 0.64363 -0.264293 -0.718274 0.517692 -0.464841
-0.480531 -0.835574 0.266282 0 0.890064 0.455835 0.365912 0.643118 0.672687
-0.832113 0.421851 0.360041 0.954546 0.130835 0.267813 -0.72099 0.674474 0.158928
-0.476716 -0.762746 -0.43699 -0.21813 -0.916637 -0.334956 0.858905 0.394416 0.326678
--0.816859 0.315719 0.482766 0.417419 -0.849571 0.322477 -0.454239 -0.883701 -0.112871
--0.561202 -0.810967 -0.165483 0.394132 0.878868 -0.268795 0.964523 -0.0595029 0.257206
-0.964573 -0.123663 0.233036 -0.769838 0.620974 0.147446 -0.859744 0.510178 0.0236194
--0.424986 -0.786224 -0.448596 0.89496 0.356203 -0.268636 -0.693899 0.696463 0.182875
--0.0058703 -0.817929 -0.57529 -0.113789 -0.785143 -0.608771 -0.773993 0.456103 0.43921
-0.312699 0.799121 0.513445 -0.111902 0.973338 0.200228 -0.576003 0.805213 -0.1409
--0.982313 -0.133382 0.131417 0.395951 -0.905306 -0.153767 0.498366 -0.835842 0.230216
--0.220191 0.790099 0.572066 0.624134 0.271363 0.732679 -0.419525 0.483477 0.768277
-0.632047 0.765289 0.121854 0.196978 0.875974 0.440305 -0.79877 -0.26753 0.538883
-0.297715 -0.952687 0.0612688 -0.580683 -0.763926 0.281468 -0.0227317 -0.941743 -0.335564
--0.601703 -0.791714 -0.105562 0.100041 -0.969632 -0.223169 -0.721377 0.55087 -0.41971
-0.985732 0.0490414 0.161019 -0.556792 0.82601 0.0876998 -0.596851 -0.750327 0.284215
-0.878503 0.459525 -0.130649 0.059197 -0.980263 -0.188628 -0.371376 0.00884229 -0.92844
-0.57772 -0.804488 -0.137981 0.107465 -0.0179108 -0.994048 -0.686893 0.482398 -0.543572
--0.240862 0.51314 0.823816 -0.926045 0.37362 -0.0533743 -0.412635 -0.909913 0.0423215
-0.906899 -0.378443 -0.185244 0.48306 -0.852947 -0.197825 -0.943578 0.229741 0.238493
-0.536044 -0.838564 -0.0973017 -0.818782 -0.438633 -0.370401 0.867657 -0.495804 -0.0367262
-0.569369 -0.765426 -0.299904 -0.202798 0.916731 0.344205 0.446501 0.788353 0.423246
--0.736485 0.675257 0.0402355 0.984051 0.140318 0.109339 0.943237 0.210987 0.256494
--0.579521 0.788357 0.206516 -0.71773 0.239243 0.653932 -0.987262 -0.0239204 0.157295
-0.0166855 -0.920734 -0.389833 -0.751227 0.659395 0.0292666 0.516148 0.842823 -0.152449
--0.329945 0.942416 0.0546615 0.970761 0.142024 -0.193528 -0.0254645 0.96765 0.251007
-0.98907 0.121111 -0.0841046 0.723093 0.61011 -0.323886 -0.933481 -0.283745 -0.21932
--0.798414 0.562519 -0.214725 -0.441277 0.375903 -0.814845 -0.242647 -0.0808824 -0.966737
--0.853984 0.204956 -0.478231 0.989226 -0.0613474 -0.132919 -0.277813 0.909421 -0.309472
--0.0427886 0.996974 -0.064896 -0.568726 0.820137 -0.0626494 0.181231 0.9834 -0.00891299
--0.461182 -0.733552 0.499212 -0.987359 0.0658239 0.144186 -0.90507 -0.318266 0.282053
--0.993195 0.116088 -0.00931568 0.0815103 0.151376 -0.98511 -0.949476 0.291748 -0.115663
--0.0710296 0.756256 -0.650408 0.114096 0.932051 -0.343895 -0.480534 0.439512 -0.758891
--0.736143 0.313542 -0.59982 -0.234798 0.626128 -0.743527 -0.412541 0.164372 -0.895987
--0.925036 0.143975 -0.351538 0.66157 0.0374474 -0.748948 -0.185527 0.272833 -0.944003
-0.5317 0.745858 -0.401237 0.0477638 0.987686 -0.148977 -0.505042 0.603245 -0.617274
--0.0350279 0.612227 -0.789905 0.6321 0.330034 -0.70109 0.771794 0.00627475 -0.635841
--0.650412 0.459625 -0.604739 -0.0762216 -0.70505 -0.70505 -0.496523 -0.553814 -0.668397
--0.165255 -0.694072 -0.700682 -0.792172 0.433567 -0.429515 -0.423179 0.215207 -0.880117
-0.0894459 0.673826 -0.733456 -0.895594 0.0334801 -0.443612 -0.887991 0.426662 -0.171554
--0.144472 -0.764993 -0.627626 -0.664857 -0.441506 -0.602526 -0.766713 -0.606981 -0.209104
--0.857561 -0.0751252 -0.508867 -0.282113 0.408106 -0.868252 0.0240754 -0.214672 -0.976389
-0.542341 0.198275 -0.816427 0.629121 0.351881 -0.693099 0.361147 -0.208119 -0.908988
-0.157398 -0.724033 -0.671567 -0.371133 -0.871357 -0.320932 0.406464 -0.468768 -0.784247
-0.312422 -0.551724 -0.7733 -0.455835 -0.0267213 -0.889663 -0.228108 -0.409086 -0.883525
--0.497743 -0.617619 -0.608932 -0.409339 -0.7567 -0.509752 -0.729704 -0.508382 -0.457252
-0.656527 0.025579 -0.753869 0.760126 0.302839 -0.574889 -0.842957 -0.469264 -0.263088
-0.54045 -0.237798 -0.807072 -0.629224 -0.641809 -0.438359 0.827071 0.109236 -0.551381
--0.373767 -0.289837 -0.881075 0.893271 0.0915583 -0.440096 -0.311345 0.166368 -0.935621
--0.205981 -0.137321 -0.968873 -0.694872 0.0534517 -0.717144 -0.448149 0.0206045 -0.893722
--0.499994 0.314238 -0.807007 -0.392693 0.145716 -0.908052 -0.767328 -0.00537847 -0.641233
--0.138503 -0.246228 -0.959265 -0.100131 0.807082 -0.581887 -0.816115 0.0429534 -0.576292
--0.830445 -0.337487 -0.443241 -0.335017 0.00744482 -0.942183 -0.423305 -0.100787 -0.900364
--0.297061 -0.0206124 -0.954636 0.718451 0.0671799 -0.692326 0.797564 0.118416 -0.591498
--0.604608 -0.763446 -0.227155 -0.186032 -0.677774 -0.711347 0.324318 -0.746686 -0.580756
--0.450544 -0.0813013 -0.889044 -0.457855 -0.848157 -0.266456 -0.287508 -0.713168 -0.639321
-0.401061 -0.749153 -0.527181 0.178405 -0.766553 -0.616902 0.147486 -0.516902 -0.843244
-0.332688 -0.266844 -0.904496 -0.480452 0.182781 -0.857763 0.699503 -0.14626 -0.699503
--0.652521 -0.756581 0.0424404 0 0 -1 0.574039 -0.732031 -0.366893
-0.0215465 0.797221 -0.603303 -0.366363 0.838326 -0.403718 0.540566 -0.0766156 -0.837806
-0.293806 -0.321788 -0.900073 0 -0.805683 -0.592347 0.58472 -0.577319 -0.569917
--0.643565 0.213155 -0.735112 -0.759482 -0.165432 -0.629142 -0.483722 0.668977 -0.564342
--0.206678 0.792266 -0.574106 -0.0288845 0.788133 -0.614827 -0.55797 0.52973 -0.638792
-0.759035 0.185262 -0.624135 0.363141 0.276421 -0.889786 0.481804 0.0161499 -0.87613
--0.942707 -0.306703 0.13129 0.0975776 -0.780621 -0.617341 0.408642 -0.207282 -0.888845
--0.362616 0.442157 -0.82037 0.172079 0.465394 -0.868215 0.544485 0.69033 -0.476425
--0.365771 -0.802035 -0.472177 -0.13498 -0.781247 -0.609454 -0.589435 -0.63244 -0.502579
-0.365376 0.152051 -0.918358 0.857891 -0.0919169 -0.505543 0.483016 -0.438554 -0.75787
-0.479833 -0.125979 -0.868268 0.428564 -0.767844 -0.476182 -0.669657 -0.685368 -0.286061
--0.584652 -0.733349 -0.346961 -0.630364 0.775832 0.0269386 0.702414 0.702414 -0.115015
-0.587823 -0.182105 -0.788227 0.762597 -0.0649019 -0.64361 0.574273 -0.19292 -0.795608
-0.452318 -0.452318 -0.768646 -0.568191 -0.409674 -0.71367 -0.552606 -0.566003 -0.611774
--0.552647 -0.82897 -0.0859673 0.761816 0.128864 -0.634847 0.379944 0.293593 -0.877181
--0.825219 0.5639 0.0320919 -0.449142 -0.156417 -0.879662 0.72444 -0.10363 -0.681503
-0.324992 -0.181527 -0.928131 -0.540602 -0.422114 -0.727715 0.51775 -0.285291 -0.806563
--0.554546 -0.284383 -0.782052 -0.133974 -0.173529 -0.975673 -0.330467 -0.165233 -0.929241
--0.244907 0.379966 -0.89199 -0.024013 -0.515648 -0.856464 0.0603724 -0.603724 -0.794904
-0.561852 -0.494688 -0.663028 -0.432075 0.0652188 -0.899476 -0.757459 0.269319 -0.594746
--0.188802 0.0917038 -0.977724 -0.253825 0.779287 -0.572961 0.263356 -0.784216 0.561826
-0.60898 -0.750797 0.255827 0.276018 0.552036 0.78681 -0.513996 0.747631 0.420542
--0.532352 -0.760503 0.371801 -0.133219 -0.666095 -0.733873 -0.589831 0.518208 -0.619322
-0.124862 -0.264413 -0.956293 0.165416 -0.478328 -0.862461 -0.875574 0.149034 -0.459521
--0.543368 0.123027 -0.830431 -0.497284 0.0252588 -0.86722 0.764705 -0.0791655 -0.6395
-0.607932 -0.645026 -0.46299 -0.581591 0.803149 -0.129242 -0.424753 0.817144 0.389694
-0.83265 0.550926 0.0563447 -0.270036 0.938696 0.214314 0.149199 -0.0239454 -0.988517
-0.194734 -0.301523 -0.933361 -0.110504 0 -0.993876 -0.256578 -0.843645 -0.471625
--0.400846 -0.754534 -0.519616 0.786517 -0.32386 -0.525837 0.555913 -0.526654 -0.643115
--0.261925 -0.641027 -0.721443 -0.612827 0.779962 -0.126898 0.514418 -0.163678 0.841774
--0.0646994 -0.139931 -0.988045 0.646157 -0.332785 -0.68683 0.913205 -0.145859 -0.380502
-0.0755444 -0.522145 -0.849504 -0.806435 0.280012 -0.520823 -0.354884 0 -0.93491
--0.181037 -0.929324 -0.321844 0.445548 -0.661135 -0.603645 -0.208956 0.46676 0.859344
--0.704145 0.631129 0.325356 0.109766 -0.259888 -0.95938 -0.788177 -0.498977 -0.360276
--0.401809 -0.385644 -0.830559 0.568719 -0.290243 -0.769622 0.549939 -0.46946 -0.690778
--0.363265 -0.690573 -0.625418 0.910828 -0.27297 -0.309644 -0.142386 0.987209 -0.0717203
-0.699557 -0.679852 0.220049 -0.853627 0.284542 0.436298 0.324002 -0.616962 -0.717203
--0.582605 -0.543416 -0.604376 -0.0985291 0.239285 -0.965937 0.0603236 -0.475492 -0.877649
--0.25542 0 -0.96683 0.481442 -0.813153 -0.327104 -0.518022 -0.84937 -0.101115
--0.971218 -0.194552 -0.137422 0.461727 -0.887022 -0.000247841 -0.175985 -0.984321 -0.0119312
--0.151461 -0.731338 -0.664984 -0.408019 -0.848249 -0.337629 0.0300072 -0.49762 -0.866876
-0 -0.25542 -0.96683 0.232757 -0.411802 -0.881047 -0.362132 -0.641275 -0.676482
-0.606449 -0.741216 0.287783 0.293729 -0.917009 0.269849 -0.160886 -0.326504 -0.931403
--0.535961 -0.375173 -0.756301 -0.408275 -0.898718 0.160057 0.104298 -0.208596 -0.972425
--0.271329 -0.407547 -0.871944 0.235196 -0.0306778 -0.971464 -0.0768463 0.922156 0.379109
--0.694839 0.191197 0.693284 -0.629876 -0.404648 0.66296 0.171286 -0.236777 -0.956346
-0.16836 -0.274186 -0.946825 0 -0.724005 -0.689795 -0.0958648 -0.636026 -0.76569
--0.0688492 0.907334 -0.414734 0.0720212 0.916019 -0.394616 -0.300483 0.832339 -0.465749
-0.445947 -0.876246 -0.182551 0.0776202 -0.993539 -0.0827949 -0.548156 -0.754604 0.360691
-0.0170736 0.273177 -0.961812 -0.335984 -0.0912549 -0.937437 -0.441987 -0.338543 -0.830684
-0.126111 -0.693611 -0.709225 0.635762 0.771252 0.031267 -0.163299 0.701899 -0.693304
--0.387619 0.113702 -0.914781 -0.6267 -0.586958 -0.512569 0.636046 0.158279 -0.755244
-0.482455 0.0331458 -0.875293 0.714132 -0.0892666 -0.694296 0.779214 -0.25568 0.572235
--0.418474 -0.89534 -0.152467 0.292683 -0.097561 -0.951219 -0.206772 -0.935644 -0.286035
-0.134147 0.972568 -0.190042 0.0410159 0.750004 0.66016 0.200766 0.790517 0.578597
-0.325909 0.678978 0.657854 0.209063 0.928485 -0.306933 0.890858 -0.206446 0.404663
-0.839116 0.427626 0.336184 0.129066 0.530605 0.837735 0.801616 0.248904 0.543561
-0.290777 0.717249 0.633247 -0.555659 0.782755 0.280246 -0.981049 0.178373 0.0756732
-0.535912 -0.602901 0.591024 -0.613857 -0.371237 0.696679 -0.868085 -0.0190788 0.496049
-0.637757 -0.699839 0.3217 0.715899 0.166664 0.678021 -0.941787 -0.0425323 -0.333508
--0.390771 0.882853 -0.260514 -0.660552 0.590438 -0.46374 0.623763 0.733839 0.269074
-0.0144218 -0.973473 0.228346 -0.923465 -0.259298 -0.282802 0.602693 0.609244 0.515346
-0.646749 -0.729533 0.222482 -0.389103 -0.915112 -0.105682 -0.557366 -0.804395 -0.20565
-0.0460165 -0.966347 0.253091 0.473718 0.702629 0.530946 -0.36819 0.911494 0.183346
-0.920294 -0.0626903 0.386172 0.566078 0.649209 0.508019 -0.400389 0.883808 0.242017
-0.107032 0.791103 0.602246 0.851886 -0.387471 0.352357 -0.698937 0.712301 -0.0641472
-0.436605 0.703781 -0.560418 0.827097 -0.232813 0.511575 0.00514209 0.742175 0.670186
--0.97065 0.0500804 -0.235226 -0.994384 0.057813 -0.0886466 -0.805787 0.401439 0.435377
-0.0855229 0.958325 0.27258 -0.829449 0.32249 0.456086 -0.105929 0.658274 0.745288
--0.670837 0.213448 0.710223 0.937375 0.124064 0.325478 0.88404 0.276743 0.376678
--0.463262 0.8165 0.344551 0.76058 -0.645527 0.0693831 0.982153 -0.0637072 -0.176965
-0.710444 -0.647925 -0.274705 -0.120542 -0.98945 0.0803614 -0.340571 -0.84512 0.412048
-0.745192 0.628883 -0.2218 -0.892643 -0.241861 0.380384 0.497432 0.834363 0.237485
-0.792949 0.109914 -0.599292 0.509942 0.747914 -0.424951 -0.0398567 0.99841 -0.0398567
--0.185057 0.981606 0.0469347 0.215159 0.66063 0.719218 0.924525 -0.365326 0.108587
--0.919617 -0.391427 0.0330119 -0.0499747 -0.998357 0.0280161 -0.249731 -0.968003 0.0245767
-0.726701 -0.0641207 -0.683954 0.208396 -0.968932 -0.133201 0.171561 -0.981113 -0.0893546
-0.983822 -0.168166 -0.0617616 0.645454 0.368348 0.66911 -0.449547 0.877687 0.166053
--0.137044 -0.939732 -0.313244 0.663553 -0.744598 -0.0726025 -0.421637 -0.737865 -0.527046
-0.942883 0.0574669 0.328129 0.905207 -0.373301 0.203091 -0.257075 0.956559 0.137505
--0.129518 0.979908 0.151673 0.757905 -0.606733 -0.239697 -0.864204 -0.251266 -0.435909
--0.279377 0.95525 0.0971923 0.164566 0.919298 0.357505 0.416017 0.886297 0.203487
--0.505457 0.315911 0.80294 -0.466701 0.132768 0.874393 0.656575 -0.366616 0.659168
-0.272729 0.873174 0.403962 -0.829695 -0.140709 0.540191 -0.801073 -0.563995 0.200476
-0.857995 -0.472093 -0.202419 -0.908661 0.147067 0.390777 -0.0739412 -0.985882 0.15023
--0.906681 0.0546992 -0.418256 -0.676726 0.502087 -0.53847 0.909123 0.284535 -0.304198
--0.69733 -0.686764 0.205149 -0.554284 -0.832311 0.00531262 0.766618 -0.622362 -0.157995
--0.0734825 -0.981516 0.176708 -0.18421 -0.97222 -0.144412 0.578781 -0.720523 0.381916
-0.980987 -0.158048 -0.112632 -0.663863 0.743847 -0.0773174 0.00736467 -0.979502 -0.201301
-0.974387 0.111722 -0.19516 -0.563754 -0.317517 -0.762472 0.821896 -0.115656 0.557773
-0.840799 -0.450428 0.300285 -0.653473 0.756901 -0.00861895 -0.647625 0.761127 0.0356083
-0.422265 0.777187 0.466555 -0.721025 0.675819 0.152945 -0.692976 0.702392 0.162573
-0.722882 -0.684516 0.0942304 0.541656 -0.0492415 0.839157 0.713851 -0.695309 0.0834371
-0.879118 0.295715 0.37377 0.96499 -0.236752 0.112882 0.730211 -0.683181 -0.00742588
--0.870976 0.491082 0.0154428 -0.918998 0.370755 -0.134103 -0.95269 -0.0790501 -0.293485
-0.950151 0.160415 0.267358 -0.632724 0.764542 0.12303 0.371687 -0.877865 -0.301995
--0.746607 -0.411175 -0.522985 -0.996271 0.0379532 0.0774877 -0.973645 0.216366 -0.0721218
-0.496914 -0.819696 -0.284912 -0.945534 -0.280158 -0.16576 0.13028 0.70514 0.696997
-0.188894 -0.554088 0.810744 -0.868409 -0.169371 0.466026 0.190266 -0.874654 0.445846
--0.409669 0.718718 0.561797 -0.249379 0.892778 0.375177 -0.286159 0.950614 0.120193
-0.368298 0.909472 -0.192918 0.309305 0.565341 0.76467 -0.153646 -0.171722 0.97309
-0.920076 -0.26439 0.289066 0.866675 0.454878 -0.204843 -0.161646 0.971446 -0.173678
--0.313982 0.921559 -0.228351 0.540462 0.808422 0.23314 -0.935596 -0.165529 0.311865
--0.315534 0.919775 -0.23335 0.123151 0.985211 -0.119136 0.423102 -0.883142 0.202597
--0.814527 -0.550356 0.183452 -0.870338 0.490779 0.040604 0.635008 0.759741 0.139853
-0.346862 0.923006 0.166572 0.138148 0.989628 -0.0393882 -0.835204 -0.528989 0.150352
-0.256576 -0.837052 0.483231 0.41113 -0.828846 0.379456 0.339057 -0.856564 0.389023
-0.0881929 -0.264579 0.960323 0.89914 -0.167889 0.404178 0.0615907 0.588961 0.805811
--0.126984 0.991592 0.0248987 -0.87468 0.471182 0.113674 0.250648 -0.943617 0.216246
--0.214176 -0.942376 0.257012 -0.975106 0.0286796 0.219877 -0.713099 0.693524 0.102537
--0.907426 0.36297 0.211733 -0.70946 0.701444 0.0681402 0.0514998 -0.885796 0.461209
-0.477187 -0.827124 0.296916 -0.717137 0.358569 0.597614 0.403604 -0.861021 0.309429
--0.291659 0.556803 -0.777757 -0.986657 -0.130252 0.0976888 0.69208 0.0768978 -0.717713
--0.666319 -0.0888426 -0.740355 0 0.999989 0.00476185 -0.22439 0.940992 -0.253344
--0.717168 0.649934 -0.251507 -0.514956 0.836804 -0.185956 -0.407553 -0.584159 -0.701897
--0.847143 -0.331942 -0.414927 0.0431467 0.848553 -0.527349 -0.519903 0.852641 -0.0519903
--0.10897 0.796083 -0.595296 0.329238 -0.93284 -0.146328 -0.280591 -0.795009 -0.5378
-0.391983 0.744768 -0.540065 -0.525994 0.713849 -0.462332 -0.187814 -0.77597 -0.602159
-0.557839 0.424072 -0.713427 -0.844915 -0.455553 -0.28034 0.0729597 -0.496126 -0.86518
--0.00704243 0.640861 -0.767625 -0.481616 0.854254 -0.195693 -0.703482 0.572602 -0.420999
--0.484667 -0.274155 -0.830624 0.204732 0.584948 -0.784806 -0.816358 -0.19948 -0.542004
-0.313793 -0.926031 -0.209764 -0.685239 -0.711043 -0.157691 0.803183 -0.274421 -0.528762
-0.877625 0.0706135 -0.474119 -0.798958 -0.510612 -0.317714 0.00539076 0 -0.999985
--0.0771935 -0.439117 -0.895107 0.183726 -0.110869 -0.976705 0.668356 0.200917 -0.716193
-0.604408 -0.304476 -0.736196 -0.869006 -0.025559 -0.494141 0.623928 0.0605303 -0.779134
--0.941095 0.218178 -0.25834 -0.743661 0.40669 -0.530633 -0.294724 -0.854699 -0.427349
--0.873177 0.311768 -0.374649 0.782583 -0.0622195 -0.619429 -0.843976 -0.53427 0.047538
--0.628695 0.603547 -0.490382 0.762248 -0.31208 -0.567083 -0.861042 -0.315841 -0.398561
--0.778741 -0.507254 -0.369128 -0.42219 0.509539 -0.74975 0.172483 0.172483 -0.969793
-0.553028 -0.563979 -0.613259 0.420491 -0.591386 -0.688077 -0.59626 0.59626 -0.537538
-0 -0.143589 -0.989637 0 -0.432897 -0.901444 -0.042924 -0.126906 -0.990986
--0.556175 -0.498639 -0.664852 -0.586204 -0.103807 -0.803486 -0.5199 -0.0879433 -0.849688
--0.313539 0 -0.949575 -0.579962 -0.297416 -0.758411 -0.469937 -0.16366 -0.867396
--0.155191 -0.39592 -0.905076 -0.427715 -0.427715 -0.796316 -0.298438 -0.235307 -0.924968
--0.25542 0 -0.96683 -0.423431 0 -0.905928 -0.132191 0 -0.991224
--0.707368 -0.485599 -0.513638 -0.330467 -0.165233 -0.929241 -0.674422 -0.513411 -0.530626
-0 0.230805 -0.973 -0.0597167 0.17915 -0.982008 -0.586297 -0.377836 -0.716586
--0.172447 -0.172447 -0.969806 0.175069 0 -0.984556 -0.133423 0.222371 -0.965789
-0.643257 0.757345 0.112469 0.665527 0.744119 0.0579688 -0.947659 -0.299019 -0.11194
-0.0212536 0.17503 -0.984334 -0.0969803 0.562486 -0.8211 -0.455376 -0.885453 0.0927618
-0.982315 -0.0605536 0.177175 -0.61987 -0.783887 0.0358197 0.626527 0 -0.7794
-0 -0.195557 -0.980692 -0.498237 0.486937 -0.717393 -0.845802 -0.127289 -0.518089
-0.501584 0 -0.865109 0 -0.0480727 -0.998844 0.247475 0.247475 -0.936756
-0.171035 -0.95851 0.228047 -0.544173 -0.229125 -0.80708 0.521558 0.462619 -0.716911
--0.675914 -0.667248 0.312923 0.52245 -0.8127 0.258 -0.195557 0 -0.980692
--0.984739 -0.0599483 0.163388 0.472562 -0.836072 0.278691 0.411622 -0.886571 0.211088
--0.218638 -0.881923 0.417624 0.694576 -0.694576 0.187425 0.232311 -0.546207 -0.804791
-0.111943 -0.567709 -0.815583 0.655627 0.109967 -0.747034 -0.561904 -0.275844 -0.779855
--0.149572 0.202363 -0.967821 0.0857304 0.0857304 -0.992623 -0.296679 0.941633 0.159089
--0.446721 0.887487 0.113169 0.856361 -0.324379 -0.401775 0.576977 0.0940259 -0.81133
-0.0688846 0.251578 -0.965382 -0.172447 0.172447 -0.969806 0.300108 0.200072 -0.932688
--0.738603 0.281173 -0.612705 0.0425635 -0.998883 0.0205271 0.229846 -0.919382 0.31923
-0.126139 -0.986587 0.103614 0.124193 -0.989536 0.0734473 0.452953 0.0654266 -0.88913
--0.00508037 0 -0.999987 0.538409 0.198361 -0.819004 -0.865946 0.382366 -0.322387
--0.789659 0.0535362 -0.611205 0.93286 -0.237879 -0.270529 0.620645 -0.746713 -0.239207
-0.599293 0.724146 -0.341264 -0.732201 -0.666237 -0.141456 -0.430444 -0.901882 -0.0364397
-0.0901019 -0.95508 0.282319 0.682593 0.0374693 -0.729837 0.815201 0 -0.579178
-0.0259785 -0.929042 -0.36906 -0.71174 0.652429 -0.260312 -0.231655 -0.817109 -0.527892
-0.0174929 -0.552483 -0.833341 0.74628 -0.564577 -0.35259 0.726239 -0.0264488 -0.686933
--0.927635 0.334059 0.167029 -0.0436685 -0.375549 -0.925773 0.219376 -0.383615 -0.897058
--0.425108 0.242417 -0.872076 0.329003 0.310726 -0.891743 0.109489 0 -0.993988
-0.397227 -0.687096 -0.608366 -0.546354 -0.714462 -0.437083 0.583549 0.12799 -0.801928
-0.655027 0.154953 -0.739547 0.817504 0.099876 -0.567197 -0.278014 0.636506 -0.719422
-0.424149 0.678248 -0.600064 -0.635402 -0.394892 -0.66357 -0.390559 -0.386314 -0.835599
-0.739463 0.225398 -0.634343 0.722494 -0.125552 -0.679882 0.804525 -0.496023 -0.326649
-0.545706 -0.36951 -0.752108 0 0.132589 -0.991171 0.605665 0.223876 -0.763577
--0.284537 -0.785047 -0.550218 0.294689 -0.678677 -0.672723 0.149357 0.460874 -0.874807
-0.687954 0 -0.725754 -0.299843 -0.465393 -0.832768 0.598635 -0.603424 -0.526798
-0.731639 -0.529377 -0.429494 0.602229 -0.356157 -0.714473 0.333962 0.305576 -0.89168
--0.242339 0.314525 -0.917794 -0.497679 -0.130162 -0.857539 -0.294744 -0.126319 -0.94719
--0.428243 0.817554 0.384986 0.622071 -0.429014 -0.654962 0.326843 -0.362795 -0.87267
--0.3676 -0.197415 -0.908789 0.822263 -0.369475 -0.432865 -0.35897 0.166963 -0.918294
-0.725959 -0.436415 0.531531 0.798561 -0.293901 0.525284 0 -0.676436 0.736502
--0.604206 0.609241 0.513575 -0.231295 -0.762899 -0.603728 0.449134 -0.691834 -0.56537
--0.0518748 0.10375 -0.99325 0.602678 0.0827511 -0.793682 -0.530196 0.151803 -0.834175
-0.165497 -0.803841 0.571358 -0.444921 -0.289552 0.847469 0.783503 0.383416 0.488995
-0.483077 -0.634039 0.603847 0.163302 0.969816 0.181077 -0.1954 0.98043 0.0239965
--0.389313 0.908397 -0.152481 0.299667 -0.466149 -0.832409 0.137031 -0.236868 -0.961829
-0.601839 -0.0947777 -0.792974 -0.161495 -0.77245 -0.614199 -0.183883 -0.348838 -0.918966
--0.280702 0.573879 -0.769331 -0.487241 0.648067 -0.585325 0.643089 -0.749384 0.157672
-0.565406 -0.824767 -0.00864536 -0.911609 0.104184 -0.397635 -0.891602 -0.253777 -0.375025
-0.517288 -0.660717 -0.543936 0.525293 -0.233464 -0.818267 0.676675 0.0424282 -0.735059
--0.306654 -0.403031 -0.862282 0 -0.278157 -0.960536 0.10493 -0.314791 -0.943343
--0.172439 -0.623969 -0.762186 0.668872 -0.536069 -0.515015 0.726475 0.152053 -0.670159
--0.84123 -0.387913 -0.376637 0.59115 0.698632 -0.403057 0.823398 0.385968 -0.415987
-0.106888 0.956368 -0.271909 0.47685 0.541508 -0.692375 -0.136187 -0.00567446 -0.990667
--0.661598 -0.497522 -0.561035 0 -0.285738 -0.958308 0.843392 -0.526448 -0.107438
-0.274146 -0.609214 -0.744112 -0.468236 -0.717962 -0.515059 0.751858 0.273403 -0.599967
-0.954202 -0.148505 -0.2597 -0.734667 -0.0192657 -0.678154 0.155893 -0.568552 -0.807741
--0.430524 -0.527604 -0.732314 -0.704419 -0.351344 -0.616727 -0.941018 -0.27882 -0.191689
-0.562007 -0.589422 -0.580284 0.556402 -0.525144 -0.643926 0.979045 -0.0559454 -0.195809
--0.916496 -0.212826 -0.338733 -0.910914 -0.179862 -0.371328 0.54976 -0.326371 -0.768925
-0.823957 -0.324067 -0.46484 0.0953891 -0.317964 -0.943292 -0.738019 0.546491 -0.395823
-0.329136 -0.738063 -0.58901 0.495584 -0.650275 -0.575794 -0.760372 -0.230097 -0.607363
-0.972335 -0.152681 0.176788 -0.247391 0.965624 -0.0798036 0.227384 -0.968006 0.106113
-0.901801 -0.332075 0.276552 -0.0711611 -0.947658 0.311257 0.140252 -0.918653 0.369331
--0.621543 -0.779547 0.0774018 0.91459 0.250573 -0.317392 0.804573 -0.378622 -0.457502
-0.671444 -0.400009 -0.623824 0.293508 0.905397 -0.306774 -0.14704 0.974141 -0.171547
--0.769258 -0.415815 0.485118 -0.813039 0.492103 0.31113 -0.745524 0.635176 0.201857
-0.0947376 -0.720748 -0.686692 0.334992 -0.937977 -0.0893311 -0.0170181 -0.991306 0.130472
-0.186891 0.409954 -0.892754 0.298121 0.95278 -0.0577442 -0.564954 0.695328 -0.444237
--0.285975 -0.222425 -0.932065 0.833103 0.484642 0.266575 0.559668 0.822328 0.102707
-0.82239 0.216711 0.526033 -0.859304 -0.394815 -0.325142 0.870448 0.387098 0.304099
-0.326204 -0.820714 0.469062 -0.272914 -0.94649 0.172265 -0.307926 -0.835799 0.454557
--0.377904 -0.920267 0.101474 0.379991 0.923864 0.0456229 0.27047 0.959923 0.0734368
--0.907951 0.36318 0.209104 -0.54294 -0.827151 -0.145045 -0.567032 -0.808855 -0.155656
-0.860864 0.479826 -0.16935 -0.656845 0.749181 -0.0853409 0.339534 0.881557 0.327985
-0.0530097 0.689127 0.722699 -0.67747 0.164435 0.716935 -0.790441 -0.234205 0.565995
-0.0322058 0.955438 -0.29343 -0.590012 0.590012 -0.551156 0.884118 -0.463081 -0.0623758
--0.67414 0.735736 -0.0650186 -0.91007 0.201826 0.361991 -0.414751 0.582894 0.698725
-0.775483 -0.178623 0.605574 0.1426 0.901463 0.408692 -0.895211 0.0354038 0.444234
-0.494864 0.345619 0.797281 0.151667 0.933473 0.325 0.494524 0.450187 0.743491
--0.11886 0.984361 -0.13002 -0.742923 0.309996 -0.593269 -0.826573 -0.275524 -0.490778
--0.713162 -0.665618 -0.219892 0.107999 -0.862893 0.493712 -0.668426 -0.42153 0.612796
-0.732081 0.0170251 0.681005 -0.761813 0.627981 0.158997 -0.60463 0.763136 0.228136
-0.814006 -0.0307172 0.580043 0.886447 0.0448204 0.460654 0.430911 -0.899216 0.0756766
--0.834017 -0.476581 -0.278006 -0.764471 -0.420901 0.488289 0.924827 -0.288031 0.248461
-0.450952 0.742645 0.495097 0.305142 0.933735 0.187154 -0.0974951 0.822038 0.561025
--0.171133 0.677401 0.715431 0.820962 -0.56521 0.0809879 0.790612 -0.611033 0.0396472
--0.853855 0.492772 -0.167656 0.646857 0.757603 -0.0872544 -0.877944 0.231183 0.419248
-0.781429 0.603208 0.159713 0.123034 0.954677 0.271024 -0.602238 0.663367 0.444132
-0.34682 0.829648 0.437492 -0.613503 0.560385 0.556402 -0.930951 -0.131847 0.340508
-0.912091 -0.165588 0.375061 -0.143247 0.962328 0.231093 0.527443 0.704356 0.475065
--0.73662 0.673403 -0.0626066 0.625738 -0.779689 0.0231755 -0.976936 0.0585186 -0.205357
--0.89319 -0.443772 0.0726446 -0.912663 -0.0641022 0.403654 -0.90457 -0.120245 0.409015
--0.965814 -0.207253 0.155725 0.858966 -0.460974 0.222893 0.701885 -0.712257 0.00691512
--0.0340011 -0.827361 -0.560641 -0.77167 -0.338782 -0.538287 -0.920225 -0.319336 -0.226298
--0.732257 -0.679953 -0.0382439 -0.334789 -0.932627 -0.134624 0.981843 0.0730674 -0.175057
-0.983404 0.0459665 -0.175508 0.718093 0.695021 0.0358886 0.456378 0.889457 0.0242122
--0.1093 0.976869 0.183793 0.556377 -0.828232 0.0669081 0.797056 -0.599337 -0.0741447
--0.275749 0.624835 -0.730441 0.548589 -0.822883 -0.148032 -0.300049 -0.862642 -0.40721
--0.0534147 -0.986391 -0.155496 0.823127 0.469235 0.319814 0.476461 0.682057 0.554783
-0.120242 0.901814 0.415057 -0.969943 -0.0365535 0.240573 0.530243 0.845 -0.0694078
-0.963615 0.235028 -0.127307 -0.222518 -0.971662 -0.0797357 0.242703 0.955643 -0.166858
-0.707656 0.647572 0.282617 0.86375 0.462908 0.199128 0.730136 0.380012 0.567884
--0.908267 0.17841 0.378445 0.897266 0.327638 0.295917 0.62797 0.65202 0.424882
--0.969913 -0.13204 -0.204533 0.309728 0.939509 -0.14626 -0.584816 0.811083 -0.0116035
--0.992025 0.114754 0.0521341 -0.201264 0.967781 -0.151305 -0.487205 0.867834 -0.097441
-0.836936 0.531264 -0.131514 0.742367 0.667217 -0.060933 -0.217208 -0.87413 0.434416
-0.306422 -0.94591 0.106581 0.252596 -0.8055 0.536064 0.24317 -0.940582 0.23701
-0.939034 0.195763 -0.282652 -0.749052 0.542011 -0.380979 0.921365 0.165175 -0.351857
-0.740634 -0.384329 -0.551138 -0.363888 -0.907528 -0.209711 0.17328 -0.958524 -0.226288
--0.30323 -0.952143 0.0384092 0.880712 -0.439715 -0.176057 0.661341 -0.740603 -0.118893
-0.101353 -0.994637 0.0206142 0.161383 -0.981749 -0.100616 -0.2495 -0.842061 -0.478208
--0.145196 -0.923357 -0.355428 -0.868831 -0.186722 -0.45855 0.810466 -0.25963 -0.525107
--0.265396 -0.940805 -0.210834 0.648096 -0.363566 -0.669172 0.960941 -0.0105021 -0.276555
--0.946306 -0.226291 0.230862 -0.652514 0.00526221 0.757758 -0.0437809 -0.718007 0.694657
--0.938791 -0.336283 0.0747297 -0.2118 -0.969823 -0.120763 -0.275402 -0.950996 -0.14057
--0.440281 -0.522193 0.730388 -0.718678 0.327717 0.613272 0.672565 -0.325607 0.664558
--0.907898 0.41903 -0.0116397 -0.970987 -0.18132 -0.15591 0.48366 -0.870587 0.0902831
-0.525126 -0.0145868 0.850899 0.749726 -0.646576 0.140888 0.598312 0.444461 0.666691
--0.655326 -0.6746 -0.339799 0.823216 0.128127 0.553081 -0.154807 0.877656 0.453601
--0.895835 0.440452 0.0590113 -0.84036 0.503562 -0.200553 -0.708394 0.702903 -0.0640667
-0.921436 -0.36737 0.126472 0.864675 -0.498321 0.063357 -0.975243 -0.019477 -0.220276
--0.503076 -0.416689 -0.757155 0.674162 -0.732531 -0.0943632 -0.904376 0.222616 -0.364069
-0.868548 -0.388027 -0.308316 -0.747161 0.633011 -0.202603 -0.053242 0.298155 -0.953031
-0.605262 -0.671463 -0.427545 -0.961025 0.187517 -0.203144 0.899104 0.422028 0.116211
-0.801056 0.585719 -0.12346 -0.403295 0.88985 0.213356 -0.565497 0.759382 0.321795
-0.987215 0.0881084 0.13283 -0.949529 0.170702 0.263165 -0.934238 -0.356579 0.00713159
--0.299684 0.789167 0.536101 0.361516 0.893748 0.265558 -0.195447 0.951177 0.23888
-0.833412 -0.507814 0.218061 -0.258731 -0.668066 0.697672 0.698858 -0.624862 0.348059
--0.148604 0.652564 0.743019 0.14157 -0.37752 0.915116 -0.37459 0 0.927191
--0.768366 0.555973 0.317029 0.919919 0.215046 0.327879 -0.990085 0.119177 -0.0743582
-0.950314 -0.266088 0.161553 -0.239335 -0.73077 0.639291 0.260221 -0.785937 0.560881
-0.491809 -0.412485 0.766799 0.378423 0.6775 0.630706 0.380476 0.88647 0.263457
-0.756507 -0.65393 0.0085481 -0.326836 -0.884379 -0.333244 0.708466 0.655496 0.261536
-0.492276 0.868449 0.0588254 0.345989 0.851543 0.393911 0.407102 -0.693581 0.594318
--0.576904 -0.457104 0.676932 0.847669 0.337882 0.409015 0.742929 0.611445 0.272381
-0.700824 -0.712007 -0.0434908 0.475483 0.832095 0.285541 0.658145 0.658145 0.365636
-0.832426 0.0582116 0.55107 0.788202 0.0297435 0.614698 0.651707 0.465797 0.59859
--0.0346193 0.979726 0.19733 -0.147418 0.967433 0.205771 -0.718491 -0.694857 0.030725
--0.938765 0.235545 -0.251475 0.691282 -0.628592 0.356372 0.780483 -0.537356 0.319523
--0.572271 -0.45088 0.684991 -0.841616 0.255035 0.476066 0.463893 0.884295 0.0531544
-0.771709 0.6288 0.0952727 -0.100257 0.989198 0.10694 -0.166482 0.965594 0.199778
-0.387115 0.883912 0.262378 -0.480241 0.865153 -0.144492 -0.626087 0.779017 -0.0338703
--0.202675 0.97863 -0.0347442 -0.282004 0.952066 -0.118506 -0.425091 0.902906 -0.0637087
-0.5488 0.832523 0.0756593 -0.222703 0.960615 -0.166196 0.404422 0.913358 0.0471237
--0.440282 -0.87416 0.204931 0.172043 -0.927122 0.332936 0.582501 -0.701441 0.410699
-0.338416 -0.0273719 0.940598 0.223578 -0.91511 0.33554 0.337478 0.826822 0.449971
-0.951425 -0.214495 0.220867 -0.720844 -0.503891 0.475897 -0.772683 -0.576238 0.266292
-0.157717 -0.97259 -0.17086 -0.847561 0.530647 -0.0073701 0.441633 -0.883266 -0.157482
--0.707635 0.70381 0.0624759 0.566219 -0.724761 0.392579 0.507093 0.169031 0.845154
--0.379071 0.324918 0.866449 -0.934703 0.354203 0.0295169 0.8 0.6 0
--0.968274 -0.0305771 0.248014 0.323587 -0.846305 0.423153 0.923508 -0.382918 0.0225246
--0.945638 0.3199 0.0585897 -0.92389 -0.148236 0.352779 -0.821489 0.410744 0.395532
-0.567814 0.786203 -0.243869 -0.797812 -0.602791 0.0118194 0.663011 0.279608 -0.694432
--0.630759 -0.608627 0.481369 -0.875577 -0.430516 0.219137 0.123613 -0.988903 0.0824086
-0.571771 0.177228 -0.801042 -0.77956 -0.625426 -0.0335932 -0.87093 -0.45754 0.17927
-0.354707 -0.36259 -0.861807 0.030052 -0.957909 -0.285494 -0.839178 0.342522 -0.422444
-0.566257 -0.452559 -0.688871 -0.369468 -0.385142 -0.845671 -0.461181 -0.0272888 -0.886886
--0.407831 0.480728 -0.776257 -0.387238 -0.741126 -0.548433 0.35976 0.299397 -0.883705
-0.0221855 0.192274 -0.98109 -0.167261 0.957948 0.233151 0.0790021 0.974359 0.210672
-0.0416105 0.970912 0.235793 -0.619476 -0.77877 -0.0988212 0.717143 -0.250568 -0.650325
-0.757263 -0.028576 -0.652485 -0.912356 -0.36374 0.187882 -0.0381181 0.0889423 -0.995307
--0.311458 -0.934374 -0.173032 0.817402 0.19659 -0.541486 -0.223864 0.466699 -0.855615
-0.809424 -0.57816 0.102784 0.748834 -0.157649 -0.643735 -0.487377 -0.433224 -0.758143
--0.9674 -0.107489 -0.22931 0.539375 -0.353275 0.764377 0.524331 0.635553 0.566701
--0.666895 -0.611321 0.426072 -0.990641 0.130815 -0.0389483 0.391348 -0.535529 0.748368
--0.157112 -0.843336 -0.513908 -0.912871 -0.365148 0.182574 -0.749074 -0.0995502 -0.654964
-0.322788 0.0370075 -0.945748 -0.263274 0.614305 -0.743852 -0.453511 0.717401 -0.528833
-0.839846 0.311148 -0.444798 -0.965111 -0.161247 -0.206301 -0.735422 0.0232851 -0.677209
--0.862863 0.21461 -0.457613 -0.0959334 0.419003 -0.902903 0.319076 -0.0299134 -0.947257
--0.730122 0.540831 -0.417642 -0.655516 0.460633 -0.598429 -0.76833 -0.18568 -0.61253
--0.851079 -0.499786 -0.160866 -0.676383 -0.697941 -0.235342 0.28543 0.924404 -0.252995
--0.865371 -0.397553 -0.305099 -0.85425 -0.470042 -0.222078 -0.643708 -0.743483 -0.181311
--0.320134 -0.147363 -0.935841 -0.795769 -0.51946 -0.311308 -0.632008 -0.0574552 -0.772829
--0.183694 0.671357 -0.718009 -0.592225 -0.744157 0.309032 -0.0817317 -0.687508 0.721563
-0.143158 -0.823156 0.549472 -0.133221 -0.717342 -0.683866 -0.336195 -0.770448 -0.541648
--0.0824786 -0.412393 -0.907265 -0.813482 -0.171921 -0.5556 -0.777154 -0.16239 -0.607997
-0.107518 -0.295676 0.949219 0.478444 -0.722357 0.499291 0.411476 -0.257172 -0.874386
--0.564649 -0.0996439 -0.819294 0.651038 0.421969 -0.630945 -0.645161 -0.415147 0.641421
--0.109675 -0.250687 0.961836 0.281709 -0.888291 0.362738 -0.155999 -0.189428 -0.969423
-0.293346 -0.258835 -0.9203 0.263598 -0.263598 -0.927918 0.0433038 0.158781 -0.986364
-0.810293 0.23402 -0.53727 -0.0708804 -0.432877 -0.898662 0.142177 -0.277062 -0.950275
-0 0.253012 0.967463 -0.379967 -0.287542 0.879173 -0.660942 -0.710266 -0.242236
--0.00861109 -0.999963 -0.000717591 0.461757 -0.799194 -0.384797 0.388164 -0.659411 -0.643822
--0.75955 -0.379775 -0.528068 -0.502656 -0.677047 -0.537535 0.175132 0.916075 0.360742
-0.283368 0.902466 0.324436 0.715145 -0.552612 -0.428004 0.236102 -0.681105 0.693074
-0.19549 0 0.980706 0 -0.706566 0.707647 0.618815 -0.374817 0.690348
--0.866634 -0.312135 -0.389251 -0.873185 -0.478844 0.0908622 -0.31719 -0.261072 -0.911719
-0.619827 0.216219 -0.754363 0.388103 0.388103 -0.835914 -0.85118 -0.275382 -0.446831
-0.133732 -0.105788 -0.985355 0.441379 0.891117 0.105329 0.533347 -0.478644 -0.697453
-0.399762 -0.261913 0.878403 0.647459 0.00130273 0.762099 -0.587672 0.402092 0.702114
--0.626249 0.0447321 0.778338 0 -0.501806 0.86498 -0.39884 0.16758 -0.901579
-0.835364 0.271903 -0.477741 0 0.423036 -0.906113 0.360268 0.838057 -0.409717
-0.40156 -0.558507 0.725824 -0.179132 -0.569009 0.802584 0.00613572 -0.654477 0.756057
-0 -0.652141 0.758097 0 -0.724005 0.689795 0.311837 -0.623673 0.716791
-0.39968 -0.325454 0.856934 0.150796 0.552918 -0.819477 -0.138478 -0.553913 -0.820978
--0.31691 -0.636168 -0.703462 -0.715076 0.667754 -0.206811 0.343255 -0.899886 0.269038
--0.058261 -0.802942 0.593203 -0.552275 -0.591443 0.587526 -0.359813 -0.768692 0.528817
--0.0479092 -0.910276 0.411221 0.0980957 -0.972334 0.212002 -0.500128 -0.823847 -0.266735
--0.434547 -0.880381 -0.189997 -0.73962 0.325635 -0.589003 -0.274968 0 -0.961453
--0.0337316 -0.464146 -0.885116 0.837203 0.141188 -0.528353 -0.00184239 0.182397 -0.983223
-0.963078 0.266531 0.0379815 -0.880658 -0.470216 -0.0577807 -0.345702 -0.888949 0.300432
-0.496918 0.175992 -0.849764 -0.263281 -0.623355 0.736282 0.405375 -0.585225 0.70227
--0.138413 -0.989816 -0.0332621 -0.156821 -0.374803 -0.913745 0.704014 -0.179153 -0.687218
--0.160456 -0.677765 -0.717558 0.996562 0.0683127 0.0468813 0.801537 -0.0716319 -0.593639
-0.379186 0.315167 -0.869993 -0.1138 -0.710198 -0.694744 0.218208 -0.293741 -0.930646
-0.394224 0.194032 -0.898298 0.167283 0.683469 -0.710553 0 0.760034 -0.649884
--0.0681252 0.346465 -0.935586 -0.30227 -0.0259089 -0.95287 -0.455913 -0.644806 -0.613489
-0.215119 0.225875 -0.950108 0.630857 -0.376284 -0.67855 0.929806 0.170964 -0.325932
--0.779166 0.35014 -0.519905 -0.35576 0 -0.934577 0.355314 0.87052 -0.34051
-0.220674 -0.299486 -0.92823 -0.799715 -0.336722 -0.497066 0.0233819 -0.140291 -0.989834
--0.243373 0.491565 -0.836142 -0.519122 0.849473 -0.0943858 0.491325 0.164189 -0.855361
-0.199089 -0.170648 -0.965009 -0.216983 -0.760268 -0.6123 0.334149 -0.942425 -0.0134376
-0.949603 -0.279794 -0.14131 -0.584431 -0.652191 -0.482791 -0.027351 -0.537903 -0.842563
-0.189589 0.108735 -0.975824 0.740397 0.498254 -0.451171 0.777968 0.563356 -0.278201
-0.597671 -0.605605 -0.525387 0.362821 0.571128 -0.736324 0.922932 -0.229862 -0.308805
-0.385831 -0.90522 -0.178076 -0.602383 -0.761838 -0.238197 0.582575 -0.588123 -0.560998
-0.266404 -0.133202 -0.954613 0.314997 -0.0633957 -0.946973 0.850919 0.33429 -0.4052
--0.987785 -0.104239 -0.115821 0.622746 -0.404558 -0.669717 -0.375952 -0.621059 -0.68771
-0.813313 -0.240297 -0.529886 -0.244476 -0.700173 -0.670812 -0.277144 -0.705624 -0.65214
-0.73243 0.0415295 -0.679574 0.986537 0.0544296 0.154217 0.615961 0.733768 0.286663
-0.616041 0.773443 0.149261 0.70385 -0.0454097 -0.708896 -0.587203 -0.268107 -0.763748
-0.843237 -0.527389 0.103983 -0.866153 0.278655 -0.414886 -0.767205 0.639724 0.0463568
--0.694629 0.7113 0.107436 -0.313249 -0.865523 -0.390827 -0.638247 -0.707328 -0.303856
-0.512049 -0.753581 0.412215 0.0742819 -0.909603 0.408784 -0.433559 0.872504 -0.225307
-0.736309 -0.412988 -0.535994 0.183294 -0.843305 -0.505213 -0.0189262 -0.480949 -0.876544
-0.1776 -0.350125 -0.919712 -0.0818006 -0.96252 -0.258581 -0.219074 -0.955087 -0.199537
--0.527875 -0.842354 -0.10857 0.247274 -0.931592 -0.266443 -0.542872 -0.67582 -0.498556
-0.294744 -0.126319 -0.94719 -0.234806 -0.712455 -0.661267 0.820648 0.562414 -0.101129
-0.191893 0.965237 -0.177465 0.796596 0.411286 0.443034 -0.642803 0.653822 0.39915
--0.732479 0.644874 0.218203 0.916885 0.216487 0.335342 0.678735 0.709587 0.189223
--0.923451 0.383319 0.0174236 0.490758 -0.457144 -0.741739 -0.236099 -0.607113 -0.75873
--0.399497 0.916087 0.0344394 0.949939 -0.0436419 -0.309373 -0.68483 -0.249029 0.68483
-0.352752 0.647048 -0.67594 0.478836 -0.85027 0.218534 -0.74563 0.664583 0.0486281
-0.563337 0.826227 0 0.720216 -0.330099 0.610183 -0.187108 0.982319 -0.00623695
--0.315064 0.933941 -0.168785 0.245169 -0.964484 0.0982987 0.119944 -0.420374 -0.899388
-0 -0.589777 -0.807566 0 -0.699193 -0.714933 -0.378538 -0.614196 -0.692439
-0.965134 0.23815 0.10863 0.971272 0.129503 -0.19965 -0.111979 0.993081 -0.0353619
--0.886187 -0.158973 0.435201 -0.937662 0.317595 0.141153 -0.866843 -0.298306 0.399496
--0.877954 0.45548 0.147426 0.90494 -0.397534 0.151822 -0.999671 0 -0.0256326
--0.271329 -0.407547 -0.871944 0.245978 -0.70176 -0.668601 0.155893 -0.568552 -0.807741
--0.557396 -0.405064 -0.72473 0.390873 0.870007 -0.30051 0.811941 -0.582687 -0.0350249
--0.298246 -0.898246 0.322807 0.649004 -0.7604 0.0242166 -0.68699 -0.610088 0.394763
-0.452039 -0.880077 0.145346 -0.802921 -0.00613586 0.596055 -0.964678 0.15152 -0.215495
-0.0744809 -0.9757 0.206064 -0.356966 -0.474504 0.804625 -0.188334 -0.867437 -0.460525
-0.719104 -0.563221 0.407028 -0.982481 -0.104459 -0.154336 0.242026 -0.892469 0.380686
--0.564821 -0.800404 0.200825 0.627277 -0.466811 -0.623387 0.637568 0 -0.770394
--0.142326 0.906669 -0.397107 0.159465 0.955366 -0.248689 -0.76274 -0.290672 -0.577701
-0.74587 0.617038 -0.250883 -0.81045 -0.479654 -0.336309 0.402746 -0.684668 0.607475
-0.658069 -0.731188 -0.17975 0.159197 0.987019 -0.0212262 -0.608463 0.571842 0.550245
-0.81123 0.504278 0.295989 -0.931872 -0.337191 0.133854 0.361893 0.932219 0.000763488
--0.760264 0.410953 -0.503107 -0.299494 0.861957 0.409064 0.258938 0.490132 0.832299
--0.601025 0.758216 0.252739 -0.60909 0.673264 0.419195 0.330928 0.931923 0.148347
-0.370937 0.928658 4.67317e-018 -0.737688 -0.436198 0.515313 -0.717518 -0.0326145 0.695776
--0.411705 0.799192 -0.437941 -0.832317 -0.392603 -0.391294 0.807314 -0.438668 0.394733
--0.167761 -0.0524254 0.984433 0.883076 0.0169618 0.468924 0.398877 0.656771 0.63996
--0.550062 0.741453 0.38429 0.269297 0.96283 -0.0209044 -0.780604 -0.483975 0.395506
--0.406482 -0.269789 0.872918 0.439425 -0.0298928 0.897782 0.20025 0.810206 0.550878
-0.71028 0.325003 0.6244 0.163913 0.980285 0.11034 0.706998 -0.255723 0.659363
--0.681199 0.618602 0.391536 -0.0740353 0.329794 0.941146 -0.43931 0.761009 0.47736
--0.435495 0.899894 0.0231236 0.805272 0.368949 -0.464127 -0.0156035 0.915408 -0.402225
-0.781356 -0.612276 0.120833 0.814023 -0.260067 0.519357 0.473539 0.796306 0.376374
-0.298136 0.951485 0.076104 -0.445801 -0.655864 0.609183 -0.273077 -0.109231 0.955771
-0.314567 -0.56075 0.765903 -0.202444 0.91642 0.345239 -0.145551 0.836917 0.527622
-0.345219 -0.455689 0.82047 0.109863 -0.576781 0.809477 -0.291199 0 0.956663
--0.689988 0.605675 0.396327 -0.779207 0.611971 -0.135381 -0.947068 0 -0.321033
-0.905529 -0.405661 -0.124326 -0.957779 0.191881 -0.214105 0.570971 0.401648 0.71601
--0.609188 -0.793025 -0.00120155 0.22393 -0.453529 0.862651 -0.298246 -0.561404 0.77193
--0.016947 -0.995634 0.091796 0.114627 -0.984316 -0.134102 0.76324 0.626272 0.158896
--0.780768 -0.0803318 0.619635 -0.0273474 -0.683685 0.729264 0.852852 0.497026 0.160027
-0.764328 0.60805 0.214659 -0.785482 0.607238 -0.119501 -0.798365 -0.10563 -0.592837
-0.424906 -0.465741 0.776235 0.275393 -0.768981 0.576912 -0.912551 0.323436 -0.250278
--0.691563 -0.720303 -0.053888 0.814957 0.568197 0.114 0.938593 -0.152877 0.309309
--0.0306653 0.967137 0.252399 0 0.999012 0.0444406 -0.122325 0.960364 0.250475
--0.575306 -0.815582 0.0620429 0.542611 -0.663519 0.515088 -0.614936 0.786501 0.0571884
-0.309303 0.662791 0.681938 0.453619 -0.857548 -0.242571 0.325035 -0.787823 -0.523152
--0.36419 -0.582704 -0.726513 -0.753345 0.120135 -0.646559 -0.0994293 -0.867548 0.487313
-0.192513 -0.941751 -0.275761 -0.768165 0.584621 -0.26104 -0.515661 0.515661 -0.684242
--0.632944 0.637947 0.438641 -0.568495 0.59692 0.566127 -0.648077 0.761306 0.0202524
-0.159836 -0.82674 -0.539402 -0.908765 0.024747 -0.416574 0.145153 -0.79507 -0.588892
--0.802954 -0.370481 -0.466914 -0.734038 -0.250939 0.631045 -0.621609 0.359879 0.695766
--0.632406 -0.213986 0.744494 0.182029 0.923914 0.336525 0.799461 0.572663 -0.181438
-0.862405 -0.311735 0.398847 -0.388229 0.915205 0.108064 -0.31451 0.904216 -0.288925
--0.371498 -0.894791 0.247665 0.204669 0.96003 0.190926 -0.483809 0.743171 0.462196
-0.469073 0.835769 -0.285415 0.993743 -0.106441 -0.0338403 0.553575 0.609784 0.567202
-0.544186 0.493953 0.678139 -0.369926 0.908427 -0.194719 -0.441629 0.612082 -0.655987
-0.949654 0.260179 -0.174537 0.626501 -0.750153 -0.211582 -0.0895616 -0.993198 -0.0744118
--0.689787 0.338757 0.639874 -0.765414 -0.634917 -0.104983 0.668823 0.412376 -0.618564
--0.238575 0.865341 -0.440758 0.758853 -0.457257 0.463743 0.778364 -0.333329 0.532016
--0.474954 -0.633272 -0.611052 -0.785467 0.499843 -0.364964 0.0092984 -0.920542 -0.390533
--0.527143 -0.811955 0.250699 0.858022 -0.269183 -0.437423 -0.486986 0.872854 0.031162
--0.660371 -0.609574 -0.438554 -0.678026 -0.620321 -0.394313 -0.5705 0.801753 0.178105
-0.977199 0.068692 -0.200906 0.903148 -0.401399 -0.152326 -0.701963 0.447823 0.553808
--0.567391 0.769922 0.292039 -0.532566 0.790644 0.302086 0.649099 -0.74896 -0.133149
--0.538312 -0.820533 -0.192213 0.472901 -0.858963 0.196334 0.599272 -0.414755 0.684727
--0.0792451 -0.871696 -0.483598 0.136622 -0.914773 -0.380165 -0.835916 0.0272952 -0.548179
-0.789339 0.592004 0.162715 0.638063 0.749724 0.175467 0.172341 0.982346 -0.0727664
--0.449201 -0.711235 0.540705 0.119806 -0.907281 -0.403097 0.505122 -0.842952 -0.185157
--0.675275 -0.369933 -0.638086 -0.253837 -0.930737 0.263239 0.313045 -0.922659 0.225173
--0.515346 -0.804469 -0.295377 -0.0862739 0.901083 0.424979 0.724233 0.485998 0.489175
-0.257861 0.759646 0.597031 0.932992 0.115541 0.340845 0.215433 -0.0615522 0.974577
--0.360523 0.733178 0.576605 -0.246761 0.856111 0.454074 -0.418989 0.80354 0.422815
-0.40057 0.35215 0.845893 -0.927404 0.345937 0.1423 -0.343669 -0.862136 0.372308
--0.351982 -0.854814 0.381314 -0.286761 -0.742204 0.605724 -0.469965 -0.724208 0.504634
--0.533947 -0.158207 0.830585 -0.0396385 -0.87771 0.47755 0.486597 0.71118 0.507392
--0.78616 0.54793 0.285876 0.749396 0.659043 -0.0637784 -0.843981 0.279303 0.457915
-0.0431624 0.156464 0.98674 0.917384 0.352563 -0.184676 0.0663639 0.859781 0.506332
-0.982786 -0.133659 0.127544 0.330211 0.749706 0.573499 0.407645 0.733761 0.543526
--0.325328 0.325328 0.887875 0.691598 0.296399 -0.658665 -0.0286735 0.93189 0.361605
-0.811029 0.575569 0.104649 -0.835007 0.544827 0.0769864 -0.605674 0.795532 -0.0169357
-0.526432 -0.723844 -0.446005 -0.858721 0.511499 0.0311131 0.95516 -0.294414 -0.0314641
-0.654318 -0.752291 -0.0769786 -0.184002 0.950676 0.249717 -0.766319 0.484996 0.421348
-0.814556 -0.30927 0.490766 0.747596 -0.142399 0.648708 0.150572 0.983936 0.0959089
--0.707383 0.697349 -0.115389 -0.0524396 -0.830294 0.554853 -0.422703 -0.329105 0.8444
--0.0389351 0.49591 0.867501 -0.367122 -0.453782 0.811975 -0.39595 -0.444575 0.803478
-0.325111 -0.0237886 0.945377 -0.222089 0.888354 0.401875 -0.013383 0.843126 0.537549
-0.059459 0.959272 0.276154 0.465452 -0.717806 0.517792 0.500189 -0.180068 0.846987
--0.137309 0.52635 0.839108 -0.337721 0.621407 0.706963 -0.0715918 0.8342 0.546795
-0.437739 0.835922 0.331087 -0.313847 0.936785 0.154704 -0.316154 0.839023 0.442818
-0.826227 0.338002 0.450669 -0.363858 0.909645 -0.200385 0.509167 0.737621 0.443468
--0.889945 -0.0778334 -0.449378 -0.639379 0.715837 -0.280664 0.0616832 0.953938 -0.293593
-0.916946 -0.16374 -0.363867 0.805817 0.351409 -0.476624 -0.421712 0.822072 -0.382566
-0.659112 0.483905 -0.57568 0.0866908 0.99413 0.0647366 -0.620591 0.663146 -0.418456
-0.596674 0.769434 0.227927 -0.306038 -0.889423 -0.339511 -0.198727 -0.817677 -0.540288
--0.16199 0.241365 -0.956819 -0.0259789 0.777923 -0.627823 0.128085 0.577638 -0.806182
-0.241196 -0.952135 0.187785 0.615898 -0.784377 0.0736399 0.490558 -0.865848 -0.0982902
-0.397915 -0.862814 0.311793 -0.076443 0.0955537 -0.992485 0.344402 -0.593367 0.727532
-0.304721 0.557874 -0.77196 0.34759 -0.385168 0.854884 0.350881 -0.818723 0.454504
-0.719072 0.694651 0.0198988 -0.409496 0.834609 0.368431 0.669983 0.736982 -0.0893311
-0.771905 0.500695 -0.391748 0.851906 0.377427 -0.363049 -0.718531 0.695165 -0.0214196
--0.673618 0.721355 0.16089 -0.340565 0.936554 -0.0829582 -0.703328 0.708697 -0.0554788
--0.62385 0.779813 0.0519875 0.904023 -0.420476 0.0770872 -0.274518 -0.877431 -0.39339
-0.664087 -0.193795 -0.722102 -0.277649 -0.771865 -0.571957 -0.855761 0.403953 0.323256
--0.980981 -0.161503 0.107669 -0.329698 -0.941995 -0.0627997 -0.318638 -0.88094 -0.349877
--0.913812 0 -0.406138 -0.843795 0.281265 -0.457056 -0.809858 -0.0449921 -0.584898
-0.642086 -0.713429 -0.280615 -0.677066 -0.112844 -0.727219 -0.479839 -0.221464 -0.848945
--0.593281 -0.741602 -0.313121 -0.810737 -0.585093 -0.0192656 0.700229 -0.0479288 -0.712308
-0.868324 0.183022 -0.460996 -0.990763 0.0176472 0.134455 -0.989301 -0.058887 0.133477
--0.596471 -0.796965 -0.0952348 0.0651251 -0.716376 -0.694668 0.432176 -0.85327 -0.291811
--0.16173 -0.549883 -0.819434 -0.808247 -0.153567 -0.568467 -0.739123 -0.558113 -0.377104
--0.00482716 -0.391 -0.920378 0.751728 0.381391 -0.538001 -0.782525 0.595786 0.180811
--0.0433646 0.520375 -0.852836 -0.72194 -0.469261 -0.508524 0.8223 0.441605 -0.358898
--0.558705 -0.649001 0.516379 -0.122262 -0.217176 -0.968445 0.771176 0.396563 -0.498021
--0.485481 -0.729729 0.48146 -0.739498 -0.372247 -0.560869 -0.753035 -0.637183 0.164123
--0.384129 -0.85523 0.34789 -0.408185 -0.910361 0.0680309 -0.890682 -0.435701 -0.129811
--0.417446 -0.834891 0.358742 0.569232 0.182244 -0.801724 0.0217289 0.999528 -0.0217289
-0.293995 0.930985 0.216413 0.428122 0.887267 -0.171662 -0.571268 0.736852 -0.361527
-0.899559 0.311847 0.30585 0.779239 0.618808 -0.0993148 -0.939353 0.139904 -0.313118
-0.797465 -0.194225 0.57125 -0.280294 -0.779216 0.560587 -0.90969 -0.414222 -0.0297458
--0.962264 -0.226415 -0.150943 0.418821 -0.732937 0.536091 -0.672912 -0.716482 0.183962
--0.159153 -0.925074 0.344831 -0.363915 0.166424 0.916444 -0.284834 0.575146 0.766861
--0.922282 0.372087 0.104631 0.922211 -0.269318 0.277479 0.807698 -0.0695976 -0.585474
--0.481251 -0.704689 0.521355 -0.756467 -0.550158 0.353673 -0.442581 -0.785225 0.433063
--0.539279 -0.41483 0.732867 0.747241 -0.314455 -0.585448 0.842745 -0.256488 -0.473281
--0.677798 -0.551429 0.48633 0.0859382 -0.880866 0.465499 -0.52058 -0.77123 0.366334
--0.0380571 -0.938742 0.342514 0.713643 -0.198685 -0.671743 -0.350684 -0.769412 0.533878
--0.138461 -0.860866 0.48963 -0.592205 -0.572016 0.56753 0.298066 0.938909 -0.172066
-0.292737 0.360292 -0.885717 -0.609509 -0.0156955 -0.792624 -0.975401 -0.220289 -0.00809461
-0.226415 -0.509434 -0.830189 -0.63785 -0.494817 0.590172 0.277409 -0.569419 0.773826
-0.681484 -0.453204 0.574618 -0.446719 0.824045 -0.348412 0.51393 -0.765361 0.387425
--0.84761 -0.081501 0.524323 0.783492 0.61996 0.042307 -0.827831 -0.477595 -0.294276
--0.441068 -0.866097 0.235236 -0.551845 0 0.833947 0.175069 0 0.984556
-0 -0.454739 0.890625 0.17378 -0.568735 0.803953 -0.493062 -0.571798 0.655696
-0.940981 0.209107 0.266136 0.451165 -0.892154 0.0226148 -0.892489 -0.435089 0.118999
-0 -0.195557 0.980692 0.751783 0.573536 0.325388 0.752332 0.596134 0.280393
-0.197539 0.395078 0.897157 -0.561401 -0.800219 0.210897 -0.246252 -0.969016 -0.0191884
-0.809813 0.524227 0.263417 0.910246 0.379269 0.166156 -0.759757 0.291306 0.5813
--0.172447 -0.172447 0.969806 -0.196671 -0.763545 0.615078 0.959401 0.266693 0.0917839
-0.4073 -0.492154 0.769345 0.80829 0.11547 0.57735 -0.990492 -0.137568 0
--0.281662 -0.537523 0.794818 -0.280577 -0.542448 0.79185 0.121636 -0.429782 0.894702
-0.132161 0.0213975 0.990997 -0.507118 -0.507118 0.696895 0.0118686 0.999929 0.00098905
--0.0506589 -0.905106 0.422158 0.932648 0.185624 0.309373 -0.673277 -0.0968744 0.733016
-0.945484 0.297152 0.133268 0.919568 0.33984 0.197241 -0.868611 -0.38537 -0.311456
-0.368731 -0.538557 -0.757624 -0.0650865 0.0735761 -0.995163 0.337086 0.204659 -0.91896
-0.314574 -0.340888 -0.885911 -0.876715 0.23123 0.421787 -0.0176222 -0.418527 0.908033
--0.135326 -0.582698 0.801342 0.540635 -0.138302 0.829811 -0.499233 0.0274447 0.866033
--0.159867 -0.188933 0.968889 0.947565 0.0485338 0.315855 -0.782687 -0.538732 0.311719
--0.904768 0.392635 0.165021 0.363733 0.544511 -0.755781 0.0826539 0.870818 -0.484608
--0.0118038 0.755442 -0.65511 0.385896 -0.0110256 -0.922476 0.569415 -0.251897 0.782505
-0.0355019 -0.443773 0.895436 -0.180905 -0.671932 0.718179 0.787789 -0.342626 0.511855
-0.656553 -0.632645 0.410729 -0.982679 -0.0289023 0.183048 0.56552 0.557749 -0.607538
-0.489065 0.619483 -0.614049 -0.449277 -0.587709 0.672866 -0.210012 -0.926893 0.31107
-0.562404 0.778392 0.278941 0.605463 0.762982 0.226433 -0.0221856 0.321691 0.946585
--0.27345 0.626657 0.729744 -0.143918 0.949248 0.279671 0.882628 -0.233014 -0.408256
-0.583178 -0.479771 -0.655532 -0.0129257 -0.843399 -0.537133 0.313224 -0.792495 -0.523299
-0.137234 -0.772338 -0.620211 0.129915 -0.75587 -0.641702 0.529696 -0.815144 0.23444
--0.376512 -0.909517 0.176119 0.867327 -0.412509 0.278532 0.433694 -0.501216 0.748794
-0.882248 0.0577171 0.467234 0 -0.689184 0.724587 0.620613 -0.297554 0.725466
-0.673255 0.290017 0.68016 0.684599 0.489865 0.539775 0.648062 -0.539542 -0.537504
-0.024134 -0.877121 -0.479664 -0.377302 -0.747617 -0.546545 -0.405857 -0.789166 -0.460973
--0.270585 -0.947047 -0.172874 -0.309803 -0.727292 -0.612428 -0.370652 -0.833377 0.409999
-0.449384 -0.755973 -0.475983 -0.0992201 -0.988232 -0.116418 0.163172 -0.979035 0.121923
-0.965393 0.0546449 0.25501 0.955532 -0.241761 0.168849 0.268769 0.761512 0.589799
--0.717536 0.694877 -0.0478357 -0.878072 -0.435326 0.1987 -0.918316 -0.395168 0.0232011
--0.201291 0.978272 0.0496517 0.217787 -0.745062 -0.630437 0.247182 -0.72645 -0.641226
--0.0932922 -0.713411 -0.694508 -0.124591 -0.662302 -0.738805 -0.126111 -0.693611 -0.709225
--0.819069 0.565132 -0.0987529 -0.93673 0.326121 -0.12721 0.80039 -0.0188981 0.599181
-0.773185 -0.036082 0.633153 -0.974482 -0.214048 0.0675941 -0.118932 -0.793781 -0.596462
-0.660087 0.660087 0.358566 -0.683426 0.729604 0.024628 0.825296 0.293417 -0.482486
-0.400152 0.639933 -0.656022 -0.330778 0.873827 -0.356389 0.728524 -0.414529 0.54536
--0.993146 0.0522708 -0.104542 0.42005 -0.725105 0.545692 0.53976 -0.725303 0.42731
-0.480591 -0.756341 0.443825 -0.920498 0.114466 -0.373605 -0.37285 0.915915 -0.1486
-0 0.80975 -0.586775 0.279475 0.784908 -0.553003 0.0700335 0.964906 -0.253084
--0.229426 0.964466 -0.131031 0.0737118 -0.986604 -0.145533 0.840993 -0.434513 -0.322381
-0.52657 -0.182274 -0.830361 0.312081 -0.92946 -0.196747 -0.334275 -0.315173 -0.888215
-0.27134 0.943793 -0.188759 -0.401074 0.860683 -0.313632 -0.378267 0.342242 0.860107
-0.976251 -0.205526 -0.0685088 -0.122878 0.988872 0.0838688 -0.872789 0.417421 0.252982
-0.976102 0.0377658 0.214006 0.651681 0.75762 -0.0363829 0.364101 -0.7756 0.51563
-0.742195 -0.656862 0.13296 -0.871366 -0.309023 0.381085 0.146872 -0.78273 0.604783
-0.877004 -0.372166 0.303901 0.957069 0.0118614 0.289617 0.558115 -0.796969 0.230971
--0.82509 -0.437877 0.357057 -0.399533 -0.528 0.749392 -0.730739 0.540921 0.416443
-0 0.845299 0.534293 0.134867 0.990863 0.000917466 0.606041 0.795429 0.00252517
-0.836213 0.470829 -0.28119 -0.445512 0.860086 0.248538 0.423396 -0.729626 0.537012
--0.305044 -0.934501 0.183457 0.806679 0.590989 0.000539224 0.342321 -0.222509 0.912856
-0.241416 0.64858 0.721846 0.200802 0.312538 0.928439 -0.535649 -0.204807 0.819228
--0.982708 0.1121 0.147371 -0.0159597 -0.877784 0.478791 0.67601 -0.720258 -0.155687
--0.49998 0.862466 0.0785683 -0.533904 0.782134 0.321267 -0.826654 0.296921 0.477997
-0.226547 -0.841459 0.490534 -0.495535 -0.31297 0.810244 -0.299892 -0.886638 0.352048
-0.54181 -0.725035 0.425165 0.245359 -0.500156 0.830447 0.363325 0.835104 -0.413033
--0.590006 0.548805 -0.592204 -0.116529 0.169081 0.978689 -0.706242 0.684456 0.180948
--0.309995 0.476063 -0.822962 0.95009 -0.19489 -0.243613 0.475945 0.655064 -0.586828
-0.728125 -0.630945 0.267849 -0.0407481 0.890951 0.452267 -0.582969 0.80907 0.0745233
--0.0549774 0.923621 -0.379344 -0.513722 0.834798 -0.197997 -0.557588 0.811228 -0.176081
-0.765321 0.26353 0.587227 -0.675956 0.731082 -0.0927525 -0.58211 0.40905 0.702727
--0.594237 0.801932 -0.0615391 0.723883 -0.685921 -0.0742002 -0.896904 0.294657 -0.329758
--0.638909 0.729387 -0.244521 -0.666179 0.460368 -0.586743 -0.678242 0.413304 -0.607592
-0.960313 0.122187 0.250738 0.913422 0.404416 0.0459035 -0.4968 0.867295 0.0314359
-0.876056 0.259828 -0.40622 -0.341332 0.898593 -0.275723 -0.872526 -0.119972 -0.473609
-0.584025 0.805516 0.100298 0.222134 -0.456384 0.861609 -0.311531 -0.914709 -0.2574
-0 -0.983582 -0.180463 -0.174272 -0.894402 -0.411915 0.0946618 0.636816 0.765183
--0.989303 -0.0594693 -0.133204 -0.20138 -0.47599 0.856084 0.892971 0.140995 0.427462
-0.222449 0.826241 0.517535 0.530197 0.745678 -0.403554 0.774297 0.526993 -0.350347
-0.494518 -0.85912 -0.131778 0.620653 -0.776792 -0.106695 -0.426685 -0.694779 -0.578983
-0.764098 0.363617 0.532858 0.361256 -0.794763 0.487695 -0.622033 -0.551448 0.55586
-0.959018 0 -0.283346 -0.194219 -0.920341 0.339488 0.208337 -0.876339 0.434311
--0.928985 0.364538 0.0640229 -0.707637 0.435469 0.556432 0.714521 0.136193 0.68623
-0.608432 -0.0612033 0.791242 -0.74959 -0.617309 -0.23884 -0.597472 -0.792565 -0.121933
--0.501535 -0.844691 -0.186976 0.84596 -0.484014 0.223791 -0.862354 -0.505442 -0.029558
--0.879617 -0.473284 -0.0477132 0.92322 0.0869844 -0.374296 0.78666 -0.248249 -0.565277
--0.44754 -0.888317 0.102961 -0.342413 -0.924516 -0.167402 -0.0276609 0.874084 -0.484987
--0.325084 0.945244 -0.0288963 0.774788 -0.615273 0.145408 -0.424469 -0.859505 0.28474
-0.873828 0.160835 -0.458865 0.630084 -0.422443 -0.651564 0.195384 -0.784541 -0.58849
--0.508922 0.675479 0.533597 -0.0545349 0.974688 0.216818 -0.177901 0.899011 0.400164
--0.476704 0.727146 0.493976 -0.908257 -0.416233 0.0426587 0.751682 -0.652623 0.0951742
--0.435742 -0.86247 0.257439 0.507963 -0.736138 -0.447297 0.0781703 -0.906776 -0.414303
--0.335164 -0.918402 -0.210247 -0.596191 -0.122268 0.793478 -0.649051 0.102482 0.75381
-0.888894 0.165376 0.427221 -0.918033 -0.393443 -0.0491803 0.527496 0.805815 0.269091
--0.929075 0.360048 0.0847665 -0.633245 -0.697642 0.335107 -0.17146 -0.925188 0.338568
--0.377802 -0.763377 0.523947 -0.278163 0.960533 0.00144877 0.636431 -0.383329 0.669338
-0.354603 -0.839506 0.411687 -0.952117 0.07129 0.297306 0.0171572 0.998693 0.0481355
-0 -0.974802 -0.22307 0.271945 -0.960733 -0.055124 -0.334501 -0.836773 0.433497
-0.599162 0.800444 -0.0171635 0.212221 -0.88361 0.417367 0.677376 -0.693698 0.244835
-0.0219415 -0.727446 0.685814 -0.269743 0.351839 0.896352 -0.34553 0.8828 0.318234
--0.0328036 0.880377 0.47314 -0.689033 0.714695 -0.120185 0.605622 -0.175543 0.776149
-0.535361 0.414935 0.735675 -0.885942 0.3648 -0.286406 -0.277827 0.845221 -0.456524
--0.169461 0.782128 -0.599632 0.584915 -0.779887 -0.222825 0.302739 -0.930641 -0.205563
-0.185381 -0.975458 0.118806 0.976954 -0.144377 0.157211 0.631576 -0.672323 0.386125
--0.86472 -0.0238269 -0.50169 -0.64589 -0.25329 -0.720188 -0.557171 0.78004 0.284777
--0.708727 0.590606 0.385863 -0.848634 -0.494632 0.187508 -0.969816 0.231324 -0.0771081
-0.194631 0.915417 -0.352322 -0.327382 0.944849 -0.00897883 0.605589 -0.789899 0.0965432
-0.629575 -0.198813 0.751072 -0.554213 -0.810811 0.188235 -0.943854 0.328847 0.0316199
-0.365393 -0.917264 0.158477 0.149393 -0.953978 -0.260014 -0.0996518 -0.866971 -0.488294
-0.950321 0.10182 0.294147 -0.357663 -0.925321 0.125933 0.733973 0.53509 -0.418286
-0.137962 0.984228 -0.110729 0.0876307 0.820962 0.564219 -0.561393 0.773908 0.293093
-0 -0.914429 0.404747 0 -0.62788 0.77831 0.495251 -0.839773 0.222504
--0.757878 0.611192 0.228178 0.891005 -0.18472 0.414716 0.665947 -0.745266 -0.0330495
-0.63056 -0.677268 -0.379081 -0.0272008 -0.994528 -0.100869 0.815211 -0.490259 0.308346
--0.553932 0.658963 0.50885 -0.667498 -0.451267 -0.592287 0.84932 -0.116523 0.514857
--0.91859 0.380106 0.108225 -0.871966 0.38644 0.300564 0.768589 -0.638718 0.0361996
-0.619813 0.215587 0.754555 -0.34832 0.34832 0.870257 0 0.863779 -0.503871
--0.889261 -0.370525 -0.26819 0.879936 -0.288775 0.377255 -0.163912 0.861059 0.481363
-0.802858 -0.539062 0.254621 0.810407 -0.476505 0.340858 -0.870374 0.486587 -0.0753867
--0.746696 0.662248 0.0622247 -0.460255 -0.887635 -0.0164377 -0.127855 -0.990877 -0.0426184
--0.76004 0.649094 -0.0318809 0.763761 -0.609075 -0.213767 0.33931 0.0657978 0.938371
-0.995588 -0.060645 0.0715948 -0.249263 0.926948 -0.280421 -0.60159 0.767546 -0.221275
-0.749145 0.649551 0.129868 -0.317376 0.372175 0.872214 0.563123 -0.412957 0.715792
--0.501663 0.0876942 0.860607 0.907507 0.380871 0.177113 0.947121 0.282254 0.152627
--0.154801 -0.942629 -0.295781 -0.95041 -0.256197 -0.176308 0.892504 -0.0263146 0.450272
--0.0551289 0.98707 0.150511 -0.670795 0.585071 0.455769 -0.92149 0.356335 0.154539
-0.67505 0.319615 0.664947 0.838591 0.268349 0.474083 -0.525761 -0.467343 0.710751
-0.819567 -0.402838 0.407469 -0.579188 -0.780295 -0.235966 0.778029 -0.602345 -0.178473
--0.389986 -0.91729 0.0805604 -0.365704 -0.683289 -0.631962 0.744031 -0.644087 0.177679
-0 -0.993263 0.115881 0.112211 -0.94756 0.29923 0.879996 0.118177 0.460046
-0.693532 -0.704541 0.150449 -0.725772 -0.652632 0.217544 -0.815089 -0.565128 0.127516
--0.168956 -0.92926 0.328526 0.816034 0.1515 0.557796 -0.935008 -0.189282 0.299887
-0.575748 0.663926 -0.477197 -0.710934 0.680731 -0.176572 0.946574 0.153445 0.28364
-0.446711 0.893423 0.0473785 -0.685454 0.697804 -0.2079 0.604175 -0.648929 0.462455
-0.847875 -0.529405 0.0289518 0.86957 -0.48236 -0.105723 -0.817904 -0.505664 0.274477
-0.655328 0.602811 0.455153 -0.665534 0.543604 0.511428 0.719596 0.474341 0.507131
--0.725722 0.302971 0.617686 -0.974869 0.141911 0.171733 0.815892 -0.565685 -0.119664
--0.642664 -0.731708 0.227126 0.92752 -0.209047 0.30985 -0.608522 0.0747307 0.790011
--0.394443 0.661272 0.63807 -0.295373 0.945194 0.139154 -0.78874 0.613802 0.0337069
--0.385115 0.135504 -0.912866 -0.221351 0.544863 -0.808782 -0.0461717 0.998767 0.0182257
-0.416136 0.808493 0.416136 -0.826732 0.300275 0.475761 -0.963011 -0.249362 0.10212
-0.886783 -0.446581 0.119088 0.854321 -0.0678032 0.515305 0.224021 0.950944 0.213353
-0.46955 0.812992 0.344336 0.641377 0.408994 0.649123 -0.8007 0.402122 0.444046
-0.902565 0.357773 -0.239532 -0.307914 -0.902323 -0.301667 -0.241942 -0.957545 -0.156751
-0.958194 -0.283909 -0.0354887 -0.498761 -0.546262 0.672931 0.166099 -0.861342 0.480105
--0.0416921 -0.481354 0.875534 -0.920533 0.38377 -0.0730684 0.612958 -0.290349 -0.734833
--0.343579 -0.343579 -0.874017 -0.511089 -0.584102 -0.630565 -0.609956 -0.43874 -0.659894
-0.603958 -0.795944 -0.0413304 -0.917812 -0.12132 0.378026 0.931316 -0.334376 -0.144373
-0.674781 0.687675 -0.267907 0.537652 0.752712 -0.379941 -0.560346 0.828218 -0.00820018
-0.586744 0.757878 -0.285223 -0.714804 -0.0238268 -0.698919 0.790435 -0.59912 0.127544
--0.562124 0.811274 0.160782 0.154868 -0.542037 0.825961 0.668151 0.70991 0.222717
--0.240452 0.951187 -0.193456 -0.429097 0.894287 0.126991 -0.335591 -0.929912 -0.150475
--0.210184 0.97459 -0.0774362 -0.760155 -0.305761 -0.573301 0.479909 -0.87477 0.0668227
--0.721273 0.656607 -0.220527 -0.357147 0.664399 0.656521 0.28204 0.378991 0.881374
-0.702879 -0.711184 -0.0133378 0.713275 0.394178 0.579536 -0.685865 0.727432 -0.0207838
--0.568874 0.733732 -0.37151 0.371274 0.85945 0.351429 -0.715244 0.694207 -0.0806402
--0.175969 0.907842 -0.380601 0.698151 -0.713006 -0.0648637 0.389244 0.758469 -0.522699
-0.953043 -0.0914082 -0.28871 0.636914 0.756475 0.148613 0.00965772 0.950078 -0.311864
--0.274688 0.864996 -0.419915 -0.161561 0.98637 0.0311784 0.659398 -0.67938 -0.321928
-0.535644 -0.84238 0.0590073 -0.347294 -0.88035 -0.323064 -0.607834 -0.487768 -0.626594
--0.154945 -0.985868 0.0636907 -0.615443 -0.553899 -0.560737 -0.464606 -0.872205 -0.152968
-0.359253 0.146086 -0.921735 0.0444477 0.112427 -0.992665 -0.355045 -0.0730133 -0.931994
-0.0674104 0.269642 -0.960598 -0.191121 0.210233 -0.958788 -0.228765 0.591634 -0.773069
-0.00978398 0.743583 -0.668572 0.437264 0.896952 -0.0654027 0.415123 0.909468 -0.0232384
--0.538665 0.819915 -0.193856 -0.551434 0.797567 -0.244556 0.595659 -0.0374086 -0.802366
-0.414913 -0.827079 -0.379192 0.30393 -0.649204 -0.697252 0.542147 -0.715456 -0.44068
--0.522983 0.298517 -0.798359 -0.0838339 0.854366 -0.512866 0.257119 0.817507 -0.515337
--0.301512 0.819938 -0.486612 0.115936 0.830872 -0.544253 -0.568658 0.434602 -0.69839
--0.129469 0 -0.991583 0 -0.286888 -0.957964 0.396823 -0.235874 -0.887071
-0.455331 -0.659765 -0.597816 -0.0958466 -0.443734 -0.891018 0.492498 0.357252 -0.79361
--0.245426 -0.47449 -0.845355 0.115963 0.552531 -0.825386 0.419206 0.375752 -0.826484
-0.693484 -0.1517 -0.70432 -0.116862 0.629659 -0.768032 -0.205244 0.840999 -0.500595
-0.576685 0.0678454 -0.814144 -0.199622 0.829201 -0.522089 0.0382157 0.636928 -0.769975
--0.132784 0.708183 -0.69343 -0.509512 0.445823 -0.735962 0.551977 -0.296608 -0.779324
--0.621821 -0.74489 0.241819 0.173984 -0.951112 0.255176 0.0641335 0.689436 -0.721502
-0.384586 0.590081 -0.709858 -0.977292 0.141508 0.157723 -0.254904 -0.892165 0.372915
--0.299088 -0.94711 -0.116312 -0.326407 -0.940819 0.0912019 0.633746 -0.660714 -0.402272
-0.768 -0.6 -0.224 0.26906 -0.858646 0.436272 -0.570063 -0.819726 -0.0554806
--0.399285 -0.613471 -0.681341 0.514472 0.35586 -0.780181 0.833419 0.44824 -0.323255
-0.84591 0.422955 -0.324878 -0.745351 -0.643481 -0.174311 0.507703 0.58509 -0.632382
-0.641742 0.647196 -0.411466 -0.846289 -0.531477 -0.0364195 -0.0377937 0.259517 -0.964999
-0.474143 0.720697 -0.505752 0.811386 -0.298932 0.502287 0.319102 -0.78366 0.532964
--0.326634 0.0130654 -0.945061 0.480956 0.775735 -0.408554 0.816645 0.576703 -0.0224507
--0.831019 -0.250951 0.496417 -0.490006 -0.601371 -0.631068 0.893498 0.0845509 -0.441036
-0.763268 -0.637292 -0.106215 -0.0642451 -0.936143 -0.3457 -0.431452 -0.748863 -0.503044
--0.796918 -0.446582 -0.4068 0.886277 -0.276366 0.371665 -0.426638 -0.781221 -0.455712
-0.607777 0.00542658 -0.794089 0.802224 0.36572 -0.471896 -0.869659 0.49359 0.00783477
--0.71059 0.688726 -0.14394 0.885195 -0.42083 -0.198322 0.587107 -0.569098 0.575701
-0.561558 0.505402 0.65515 0.815869 0.273909 -0.509247 -0.98744 0.143628 0.0658293
--0.773334 -0.559509 -0.298167 -0.643952 -0.13365 -0.753302 -0.0106825 -0.758459 -0.651634
--0.0861221 0.5844 0.806882 0.89086 0.222715 0.395938 0.414513 -0.612759 0.672834
--0.933702 0.322464 0.155617 0.403577 -0.828969 -0.387216 -0.589968 -0.543392 -0.597213
-0.0960738 0.288221 0.952732 -0.759953 -0.595639 0.260164 0.058722 -0.998274 0
--0.823847 -0.561068 0.0804908 -0.0323125 0.972067 -0.23247 -0.555582 0.694477 -0.457198
--0.971022 -0.0357431 -0.236302 -0.924955 -0.295986 -0.238433 -0.22434 -0.931012 0.287903
-0.933969 0.324859 0.148894 0.851205 0.206353 -0.482564 -0.753044 -0.331278 0.568489
-0.750727 -0.034124 0.65973 -0.625343 -0.606951 0.490465 -0.446065 -0.592582 0.670725
--0.923537 -0.0157474 0.383186 -0.341077 0.420397 0.840793 0.207583 0.928019 0.309339
-0.548625 0.648375 0.527844 0.970118 0.191682 -0.148761 0.246795 0.943394 0.221585
--0.805546 0.109847 0.582262 -0.0574128 -0.80059 0.596456 0.939336 -0.34205 -0.0254657
--0.611717 -0.694063 0.379578 0.00944936 -0.982733 0.184787 0.837139 -0.335124 -0.432309
-0.867052 -0.144121 -0.476917 -0.62838 -0.583709 0.51422 -0.814936 -0.382599 0.435313
--0.762198 -0.396171 0.51196 0.666667 -0.133333 -0.733333 0.0066872 -0.595161 0.803579
--0.264305 -0.816942 0.512591 -0.624136 -0.289599 0.725663 0.322258 -0.314065 0.893036
--0.396763 -0.523727 0.75385 0.0234246 -0.726164 0.687123 0.174694 -0.744069 0.644859
-0.699113 0.636239 -0.326253 0.710531 -0.4222 -0.562933 -0.492213 -0.118658 0.862349
--0.155189 -0.731085 0.664403 -0.310017 -0.75782 0.574106 -0.852302 -0.171869 0.494006
--0.0637487 -0.812796 0.57905 0.22359 0.941931 -0.250547 -0.644618 -0.738952 -0.196006
-0.506935 0.76695 -0.393452 -0.467142 0.27479 -0.840398 -0.200632 -0.72536 -0.658483
--0.191611 -0.8191 -0.540704 0.358312 -0.879151 -0.314177 0.143058 0.839276 -0.524548
--0.461237 -0.864036 -0.201748 -0.550213 -0.431616 -0.714824 -0.269224 -0.423066 -0.865179
-0.0698754 -0.635866 0.76863 0.172456 -0.426183 0.888047 0.66742 0.725401 -0.168358
-0.386712 0.858631 -0.336461 -0.576683 0.384455 -0.720854 -0.435259 -0.0423404 -0.899309
--0.155511 -0.459672 0.874367 -0.433461 -0.791066 0.431655 -0.604078 0.745775 0.280909
--0.996926 -0.0772811 -0.0128802 -0.060117 -0.865685 0.496967 0.6506 0.74819 -0.13012
--0.50084 -0.797035 -0.337483 -0.98064 0.0492949 0.189512 0.0126828 -0.674 -0.738622
-0.6305 -0.339879 0.697819 0 -0.472408 0.88138 -0.445054 -0.376861 0.812344
-0.573308 0.806359 0.145269 -0.317861 0.946014 0.063428 0.555598 0.811046 0.183071
-0.554127 0.829097 0.0744419 -0.390133 -0.23242 0.890942 -0.908379 -0.416506 -0.0370227
--0.768679 -0.361731 -0.527525 0.404002 -0.404002 -0.820709 0.513144 -0.372556 -0.77323
-0.542005 -0.527357 -0.654313 -0.347528 -0.538328 -0.767742 -0.286044 -0.618654 -0.731741
--0.156417 -0.449142 0.879662 0.284843 -0.0931216 0.95404 -0.397439 0.228527 0.888717
--0.152511 0.0538274 0.986835 -0.258021 -0.488103 0.833775 -0.840079 0.294433 0.455606
--0.931626 0.2465 0.267042 0.473692 0.68183 0.557426 0.225875 -0.309977 0.923523
--0.779569 -0.550896 0.297969 0.389904 -0.322095 -0.862687 -0.457239 -0.452489 -0.765628
--0.769422 -0.129357 0.625505 0 -0.454739 0.890625 0.712958 -0.235879 0.660343
-0.590895 -0.401198 0.699916 -0.692747 0.161911 0.70277 -0.347437 -0.820281 0.454341
-0.488719 -0.57264 0.658207 -0.153549 0.472832 0.867671 -0.243055 -0.884449 0.39834
--0.0845631 0.819611 -0.566645 0.735378 0.1329 -0.664498 0.241294 -0.487415 -0.839168
--0.343322 -0.672138 -0.656019 -0.365424 -0.637432 -0.67834 -0.0832131 0.254534 0.963477
-0.120501 -0.271127 0.954971 0.309647 -0.465699 0.829001 0.604564 -0.310033 0.733745
-0.325999 -0.10161 0.939894 0.338341 0.931664 0.132394 0.71773 -0.118145 0.686225
--0.242618 -0.679331 0.692565 0.516544 0.843397 -0.147862 0.484088 0.633273 -0.603842
-0.661233 0.418971 -0.622281 0.31461 0.750833 -0.58075 -0.206203 0.904889 -0.372366
-0.0224029 0.847576 -0.530201 -0.190866 0.438992 -0.877984 0.275766 -0.529172 -0.802453
-0.31833 -0.48339 -0.815475 0.0705311 -0.712364 -0.698257 -0.131773 -0.779013 -0.613004
--0.193575 -0.71323 -0.67367 -0.489911 0.553631 0.67341 -0.276104 -0.516582 0.810499
--0.285549 -0.095183 0.953626 -0.0892342 0 0.996011 0.539156 -0.589431 0.601566
--0.474298 -0.380462 0.793908 -0.986091 -0.152084 0.0670476 0.420109 0.904591 -0.0722769
-0.441151 0.893024 -0.0888429 -0.43675 0.780551 -0.447202 0.415877 -0.883738 -0.214603
--0.188738 0.924816 -0.330292 0.121147 0.987349 -0.102302 -0.779696 0.60643 0.155939
--0.48517 -0.749809 -0.449885 -0.381799 0 0.924245 0.494724 -0.169152 0.852429
--0.456887 -0.45452 0.764635 0.0189 -0.7686 0.63945 -0.305122 0 0.952313
--0.883178 -0.0334176 0.467846 0.975461 0.0248701 0.218765 0.696289 0.690828 0.194779
-0.443242 0.89612 -0.0224833 -0.369419 -0.181656 -0.911335 0.451936 -0.885795 -0.105452
--0.72774 -0.610632 0.312287 0 -0.61519 -0.788379 0.133662 -0.61917 -0.773798
-0.113717 -0.760903 -0.638824 -0.369801 -0.665642 -0.648204 -0.0342371 -0.725827 0.687025
--0.167154 -0.297295 0.94004 0.16328 -0.569211 0.805815 0.743706 0.424975 0.516041
-0.490768 -0.208642 0.84594 0.287294 -0.721474 -0.63003 -0.742765 -0.427652 -0.515184
--0.676961 0.132552 0.723985 -0.164613 -0.420322 0.892318 -0.572824 -0.329707 0.750444
-0.272078 -0.743681 0.610665 0.659524 0.544182 0.51855 0.339597 0.25412 0.905592
--0.245284 -0.531449 0.810801 -0.310388 -0.843483 0.438401 -0.955175 -0.212261 -0.206365
--0.783488 0 0.621407 -0.31772 0.926235 0.202838 -0.397139 0.917528 0.0205417
-0.400384 0.85243 0.336236 0.123878 0.916698 0.379893 -0.310369 -0.846462 0.432636
-0.845257 0.432523 0.313791 0.655033 0.74668 0.115764 -0.407329 -0.878302 0.250337
-0.991945 -0.101338 0.0760036 -0.997329 0 0.0730367 0.898404 0.431997 0.0790521
--0.727004 0.2812 0.626412 -0.975467 -0.00950748 -0.21994 0.728168 0.102717 0.677658
-0.59963 -0.237136 0.764337 -0.766545 0.178928 0.61676 0.568873 -0.644363 0.511057
--0.0122066 -0.772068 0.635422 -0.331944 -0.881242 0.336491 -0.0746191 -0.983867 0.162596
--0.859657 -0.459269 0.223746 0.799719 0.517609 -0.304188 0.646401 -0.609812 0.458579
--0.432498 -0.900382 -0.0475093 -0.364245 0.610786 -0.70304 -0.915037 -0.174293 0.36377
-0.824065 0.560746 -0.0804965 -0.489021 0.789957 -0.3699 0.975721 -0.136391 0.171363
--0.853388 0.426694 -0.299434 0.608354 -0.01767 0.793469 0.659089 0.0063374 0.752038
--0.948889 0.289914 0.124741 -0.314891 0.944674 0.0918433 0.831238 0.465312 -0.304185
-0.094667 0.9493 -0.299779 0.809295 -0.012302 0.587273 -0.845043 -0.423074 0.326971
-0.808137 -0.493278 -0.321855 -0.129371 0.954112 -0.270062 -0.873153 0.293771 0.388975
--0.916029 0.373197 -0.147017 -0.573422 -0.798089 0.185045 -0.728867 -0.684582 -0.0100463
-0.662043 0.367159 0.65337 0.0576586 0.897827 0.436558 -0.932517 0.345674 -0.104506
-0.773286 -0.594163 0.221355 -0.160785 0.920046 0.3573 -0.652284 -0.489828 0.578441
--0.719465 -0.527608 0.451664 -0.197394 -0.958769 0.204443 0.625048 -0.644351 0.440598
--0.450171 -0.467825 0.760583 -0.681206 -0.390797 0.619061 -0.269787 -0.926849 0.261084
-0.488812 -0.852821 0.183738 0.24203 -0.96812 0.0645413 0.152247 0.792952 -0.589956
--0.1013 0.964653 -0.243274 0.36482 0.781757 -0.505729 0.120654 0.890714 0.43826
--0.750137 0.641055 -0.162306 -0.300564 0.826551 -0.475893 0.889031 0.457648 0.0135305
-0.0175601 -0.807767 -0.589241 -0.627992 -0.250176 -0.736912 -0.832573 -0.0101197 -0.553822
--0.180239 0.959128 -0.218146 -0.975822 0.203105 0.0807432 0.446144 0.892288 0.0691209
--0.18645 -0.849383 -0.493747 -0.47971 -0.830184 -0.284029 -0.873968 -0.0771149 0.479826
--0.812278 0.330308 0.48073 0.642143 0.762545 0.0785956 0.685601 0.713303 -0.145431
-0.293974 0.551202 0.780869 -0.42041 -0.371525 0.827783 0.728482 0.0466762 -0.683473
--0.891428 -0.445714 -0.0818219 0.916834 -0.00274091 0.399259 0.532432 -0.846287 -0.0177477
-0.494079 -0.868381 0.0424209 -0.487983 0.486076 0.724985 0.620801 0.558721 0.549942
-0.311032 -0.948301 -0.0631279 0.699592 -0.699592 -0.145405 0.584159 -0.767357 -0.264427
-0.425544 -0.830331 -0.35981 0.464224 -0.858815 -0.216638 -0.188658 -0.981024 -0.044719
--0.659388 -0.746212 -0.0915165 0.771295 -0.290089 -0.566527 0.48177 0.404687 -0.777256
--0.194547 0.960578 -0.1986 -0.0345892 0.992606 0.116346 0.330335 0.739792 0.586163
--0.554409 0.671126 0.492159 0.104307 0.382459 0.918066 -0.464886 0.757472 0.458385
-0.696904 -0.420772 0.580754 0.82618 -0.563304 -0.0107296 -0.701191 -0.643716 -0.306531
--0.637416 -0.762623 -0.11003 0.58002 0.305686 -0.755071 0.385464 0.566682 -0.72821
-0.488593 0.576477 -0.654944 0.232487 0.854254 -0.464974 0.864582 0.27765 0.418818
--0.717908 0.683609 0.131478 0.481512 -0.502773 0.71789 0.654403 -0.364243 -0.662634
-0.566525 0.446772 -0.692419 -0.334364 -0.675893 0.656787 0.383583 -0.280166 0.879984
--0.82266 0.558234 0.107729 0.157532 0.984574 0.0761404 0.0894869 0.995541 0.029829
--0.456209 0.82688 -0.328851 -0.873372 0.487054 0 0.61682 0.106348 0.779887
-0.906605 -0.215459 0.362829 -0.735083 -0.479402 0.479402 -0.697206 -0.681626 0.222015
-0.337685 -0.92096 -0.194425 -0.78914 -0.39457 -0.470715 -0.451943 0.795246 -0.404142
-0.423041 0.867963 -0.260146 0.0770327 -0.99661 0.0288872 0.182021 -0.982915 0.0273032
--0.406562 -0.877078 -0.255814 0.998458 -0.0264492 0.0488051 -0.985628 -0.0467954 0.162321
--0.225258 -0.946086 -0.232767 0.908438 -0.417071 -0.0281424 0.19366 -0.937125 0.290332
-0.384013 -0.776411 -0.49972 0.370627 0.688307 -0.623594 0.881539 -0.467803 0.0636275
--0.935347 0.289678 -0.203008 0.930651 -0.101641 0.351509 -0.990077 0.12673 0.0607247
-0.505532 -0.767014 0.395129 0.780537 -0.617513 -0.0971554 -0.87798 0.432438 0.205299
-0.0433967 -0.902651 0.42818 0.291171 -0.934174 0.206246 0.979034 -0.19221 0.067442
--0.933366 0.35779 -0.0285195 0.978478 0.181628 -0.0979368 0.976701 0.111094 0.183614
-0.722059 -0.499788 0.478375 0.726421 0.682865 0.0775144 0.275503 0.771407 0.573611
-0.117289 0.640673 0.758803 0.217482 -0.931812 0.290565 0.109131 -0.992576 0.0536996
--0.850588 0.514502 0.108571 -0.755283 0.422272 0.501233 0.795559 0.595362 -0.112382
--0.965902 0.0616179 0.251468 0.393091 -0.91277 -0.111043 0.627833 0.623675 0.465677
-0.815527 0.547 0.188964 -0.129827 0.536618 0.833778 -0.629313 0.0646238 0.77446
--0.627186 -0.677179 0.384795 0.142175 -0.95994 0.241455 0.838717 -0.279572 0.467325
--0.828097 0.559978 -0.0260671 -0.793616 0.605257 0.0619489 -0.732389 0.642249 -0.226102
--0.919556 0.276615 -0.279107 -0.80546 0.577246 0.134243 0.85064 -0.515539 -0.103108
--0.529412 0.705882 0.470588 0.204655 0.708985 0.674875 -0.0936265 0.206624 0.973931
--0.430175 -0.0977054 0.897442 -0.87821 -0.40941 0.247247 0.817799 -0.572902 0.0546677
-0.274368 -0.00783907 0.961593 0.468355 0.212223 0.857674 -0.867086 -0.412898 -0.278706
-0.333247 0.773089 0.539704 -0.738222 0.0025812 0.674553 -0.729397 -0.388927 0.562775
--0.0345494 -0.958747 -0.282154 -0.759089 -0.498152 -0.41908 -0.883272 0.430186 -0.186469
-0.782948 -0.445471 0.434221 -0.702032 0.226257 0.675247 -0.818275 0.221564 0.53041
--0.759455 -0.607564 0.232583 0.038568 -0.994504 -0.0973383 0.741072 -0.553145 -0.380582
--0.402702 -0.434919 -0.805405 -0.591824 -0.313319 -0.742681 0.179559 -0.193371 -0.964555
-0.779622 -0.507457 0.366984 -0.0705151 -0.564121 0.822676 0.555662 0.789844 0.259586
-0.701905 0.712266 -0.00259006 -0.393066 -0.426583 -0.814571 -0.638362 -0.0640302 -0.767069
--0.156625 0.86731 -0.472485 -0.154957 0.923893 -0.349871 -0.566104 0.299702 -0.767923
--0.0540124 -0.900207 0.432099 0.717203 0.646973 0.258931 0.0387284 0.96821 -0.247124
--0.852252 0.233952 -0.467903 0.770828 -0.513885 -0.376492 -0.433293 0.0772538 -0.897936
--0.441542 -0.532343 -0.722254 0.586711 0.369167 -0.720754 -0.597891 -0.0128579 -0.801474
-0.817247 0.0674791 -0.572323 -0.284468 -0.924521 -0.253651 -0.0394122 -0.992603 -0.114831
-0.586584 -0.782685 -0.208143 0.210896 -0.723071 -0.657793 0.784555 -0.564991 -0.255458
--0.985826 0.125934 -0.110848 0.428532 0.836033 0.342651 0.544306 0.834603 0.0846699
--0.0273532 0.877789 0.478266 0.213399 0.87769 0.429093 -0.616112 0.724439 -0.309184
-0.725074 0.623471 0.292493 0.158607 0.929215 0.33377 0.241388 0.836883 0.491283
-0.277472 0.501692 0.819337 -0.586161 0.806416 0.0781548 -0.76939 0.377436 0.515346
-0.999076 0 -0.042971 0.901624 -0.276498 -0.332599 0.674453 0.551825 -0.490511
--0.302206 0.910816 -0.28122 -0.823832 0.322169 -0.466378 0.54395 0.390528 -0.742701
--0.786183 0.293769 -0.543706 0.923501 0.340491 0.17667 0.972855 0.221754 0.0661684
-0.249189 0.386672 0.887913 0.461058 0.675504 0.57543 -0.07817 -0.986144 -0.146318
--0.251057 -0.502114 -0.827558 0.781083 0.414068 -0.467395 0.162452 0.699794 -0.695628
-0.389264 -0.528137 -0.754682 -0.636464 -0.603463 -0.48036 0.922692 0.168944 -0.346551
--0.218208 0.877029 0.428024 0.0545856 0.846076 0.53026 -0.968434 -0.220467 -0.11632
-0.783573 -0.602749 -0.150687 0.166574 -0.760448 -0.627672 0.318941 0.528531 -0.786722
-0.707104 -0.335421 -0.622493 0.531772 -0.335856 -0.777444 0.705496 -0.264561 -0.657483
-0.90796 -0.0974804 -0.407561 0.141996 -0.812534 -0.565355 0.12281 -0.973037 -0.195237
--0.830287 -0.0919985 -0.549691 -0.907136 0.412125 -0.0851879 0.813701 0.28835 -0.504723
--0.980578 0.155423 0.119629 -0.21579 0.951074 0.221118 0.884389 -0.365954 -0.289714
-0.175323 0.91001 -0.375692 -0.294649 0.955378 -0.0208338 0.803538 0.583107 -0.119636
--0.0328396 0.97026 0.239828 -0.762362 0.39702 0.511057 -0.644103 0.644103 -0.412629
--0.861474 0.501651 0.0787934 0.757674 0.631395 -0.165134 -0.173715 0.98398 -0.0400881
-0.0590994 0.98105 0.184521 -0.485725 0.794409 0.364672 -0.601819 0.71081 0.364093
-0.0892751 0.982026 0.166297 0.755531 -0.458715 0.46771 -0.778652 0.593134 0.204679
-0.253929 0.948003 0.191858 0.253345 0.957082 0.140747 -0.01281 0.999179 0.03843
--0.784161 0.61138 -0.106327 -0.472775 0.8678 0.152994 -0.20039 0.901035 0.384682
--0.450055 0.725713 0.520376 -0.466501 0.641439 0.609043 -0.307698 -0.946762 -0.0946762
-0.606794 0.794186 0.0327193 -0.768634 0.409112 0.491761 -0.83657 0.375603 0.398841
-0.0107634 0.8826 0.470002 -0.305333 0.395137 0.866394 0.0352067 0.95058 0.308477
-0.69164 0.332688 0.641056 0.845559 0.383356 0.371575 0.673364 -0.424423 0.605348
-0.810594 0.583705 0.0471877 0.558877 0.0745169 0.825896 -0.753087 0.423041 0.503881
-0.457134 -0.0489787 0.888048 -0.556414 -0.529127 0.640647 -0.88778 0.333531 0.317181
--0.997911 0.0636821 -0.0108395 -0.0206386 -0.97591 0.217196 0.576738 -0.814743 -0.059724
--0.688388 0.697176 0.20017 0.46534 0.850908 0.24375 0.204143 0.74805 0.631464
-0.620335 0.592866 0.513512 -0.0176425 -0.970336 0.241114 0.792424 -0.255187 0.554025
--0.988113 -0.0306392 -0.150643 -0.291551 0.892875 0.34318 0.188902 -0.981878 0.0152229
-0.992506 0.0577038 0.107714 -0.903829 0.0703452 -0.422071 0.506059 -0.857637 0.0914458
-0.888234 -0.41419 -0.198715 0.0314464 0.993183 0.112246 0.0985576 0.995086 -0.00950994
-0.00309445 0.996412 0.0845815 0.0966845 0.995281 0.00821502 0.970079 -0.0928306 -0.22434
-0.0858495 0.985225 0.148193 0.459898 -0.813099 0.356881 0.420206 -0.452529 0.786539
--0.67743 -0.658185 0.328451 -0.603843 -0.738414 0.300196 0.538519 -0.817208 0.20535
--0.856362 0.486709 -0.172505 0.440858 -0.896412 0.0457186 -0.496167 -0.857016 -0.139077
--0.493412 -0.695837 -0.521878 0.121931 0.738758 -0.66285 0 0.69568 -0.718351
-0.117862 0.833876 -0.53922 -0.301478 0.836417 -0.457731 0.415422 0.671664 -0.613427
-0.431768 -0.895729 0.106048 0.732543 0.0261622 -0.680218 -0.0326107 -0.605627 -0.79508
--0.827311 -0.15551 -0.539791 0.779259 -0.610771 0.140407 0.529982 -0.714323 -0.457013
-0.54406 -0.746676 -0.382718 0.444184 -0.895533 -0.026866 -0.612625 -0.722253 -0.321001
-0.471829 0.688978 -0.55017 -0.223669 0.688465 -0.689919 -0.13129 0.774159 -0.619226
-0.0911533 0.299504 -0.949731 0.892607 -0.318788 -0.318788 0.0223457 -0.938521 -0.344497
--0.444963 -0.874583 -0.192647 -0.60169 -0.575867 -0.553486 0.342074 0.724872 -0.597951
--0.270215 0.628249 -0.72958 0.121069 0.407716 -0.905047 -0.23157 0.605852 -0.76113
--0.342352 0.569403 -0.747379 0.117507 0.568803 -0.814036 0.023847 0.7614 -0.647843
--0.526226 0.585519 -0.616648 -0.231181 0.854087 -0.46593 -0.784243 0.54556 -0.295512
-0.9009 -0.345628 -0.262526 -0.35482 -0.906762 -0.227786 -0.227612 -0.699695 -0.677215
-0.202606 0.162084 -0.965753 0.331769 0.539125 -0.774128 0.330417 0.788996 -0.517987
-0.22223 0.864528 -0.450783 -0.0817823 0.324208 -0.942444 0.112184 0.518025 -0.847977
--0.129178 0.172871 -0.976437 -0.715707 0.486015 -0.50155 0.0109128 0.979177 -0.202714
--0.10432 0.799788 -0.591148 -0.33193 -0.86539 -0.375397 0.188744 0.0330303 -0.981471
-0.475564 0.466758 -0.745638 0.464235 0.714406 -0.523554 0.182576 0.845068 -0.50252
-0.0765634 0.796955 -0.599166 -0.168661 0.748856 -0.640912 -0.0476265 0.483069 -0.874286
-0.356329 -0.344451 -0.868552 -0.390794 0.256037 -0.884152 -0.696654 0.171308 -0.696654
--0.126787 0.235461 -0.963578 -0.803303 0.087633 -0.589089 -0.98186 -0.11417 0.151381
--0.191918 -0.967673 0.163636 -0.00956072 -0.984755 0.173686 -0.389125 0.243203 -0.888501
--0.574119 -0.812714 0.0994146 0.00366827 0.201755 -0.979429 0.243627 0.705803 -0.665198
-0.427219 0.759135 -0.491119 -0.337822 0.445311 -0.829201 0.186444 0.445845 -0.875477
-0.329095 0.329095 -0.885095 -0.285756 0.417995 -0.862336 0.312529 0.659652 -0.683509
--0.428604 -0.898519 0.0946715 0.889324 0.0896797 -0.448398 -0.474634 0.443728 -0.76015
-0 -0.241626 -0.970369 0.664454 0.45961 -0.589287 0.0151411 0.847901 -0.529938
-0.101695 0.38983 -0.915254 0.0947333 0.271776 -0.957686 0.334016 0.513871 -0.79017
--0.798846 -0.589048 0.121934 0.652356 -0.753425 -0.0823527 0.478811 -0.806061 0.34786
-0.552936 0.535923 -0.638003 0.430075 -0.900803 0.0599109 -0.812626 0.58231 -0.0235386
-0.739027 0.451547 -0.499944 0.0858603 -0.932198 0.351618 0.592979 -0.662741 -0.45733
-0.229178 -0.965324 -0.125006 -0.865837 0.151789 -0.476745 -0.290488 0.544665 -0.786738
-0.566408 0.82264 0.0494483 0.238092 0.965783 -0.102838 -0.931211 0.271112 -0.243608
-0.913181 0.391363 0.11373 0.844132 0.522029 0.122177 -0.85241 -0.522741 -0.0118208
-0.773164 0.629435 -0.0776468 0.42169 -0.901543 0.0969401 -0.40193 -0.818801 0.409899
-0.877593 -0.00566189 -0.479373 0.996265 -0.0797012 -0.0332089 -0.630452 -0.302759 0.71475
-0.469776 -0.058722 0.88083 0.885716 -0.36621 0.285303 0.806559 -0.12566 -0.577644
--0.0478107 -0.273204 0.960767 -0.125909 -0.924588 0.359562 0.739254 -0.576042 0.348825
-0.810052 -0.236301 -0.536635 0.851356 -0.0949053 -0.515931 0.8308 -0.200538 -0.519187
--0.981549 0.0885608 0.169468 -0.779176 0.446306 0.440108 -0.266874 0.951168 0.155106
--0.220171 0.798397 0.560435 -0.198288 0.925346 0.323137 -0.313712 0.686775 0.655686
--0.669239 -0.540294 0.5101 -0.528226 0.136947 0.837988 -0.711376 0.643626 0.282292
--0.868 -0.432311 0.244301 -0.64222 -0.725087 0.248601 0.0137037 -0.986669 0.162161
--0.429028 -0.899734 0.0800853 -0.796435 -0.584053 0.156759 -0.930467 -0.266065 0.251875
--0.928756 -0.321726 0.184132 -0.459829 -0.887945 -0.0105708 0.65052 -0.359335 -0.669106
--0.595695 -0.689505 0.411983 -0.592954 -0.67838 0.433828 -0.932875 -0.201208 0.298764
--0.548243 0.146952 0.823307 -0.124359 0.683972 0.71883 -0.622472 0.77809 0.0842931
-0.294561 -0.13105 -0.946604 0.434018 0.648209 0.625663 0.560395 0.557255 0.612719
--0.768221 0 0.640184 -0.0907617 0.0819377 0.992496 -0.794135 -0.560566 0.234767
-0.744918 -0.157802 -0.648225 0.267261 -0.455916 -0.848947 -0.2543 -0.736411 -0.626921
-0.195894 -0.138278 -0.970827 -0.435293 -0.114005 0.893041 0.0790537 -0.837969 0.539961
--0.345503 -0.877873 0.331611 -0.773505 -0.630704 0.0624754 -0.194607 0.7914 -0.579495
-0.463032 -0.40981 -0.785912 -0.53091 -0.3492 0.772136 -0.48301 -0.802979 0.34918
--0.373332 -0.919782 0.120931 -0.691705 -0.620847 -0.368909 -0.378586 0.107728 0.919276
-0.772425 0 0.635105 0.311129 -0.677475 -0.666503 0 -0.913276 -0.407341
-0.69236 0.437533 -0.573761 -0.426071 -0.809534 -0.403879 0.51719 -0.292749 -0.804247
--0.275126 -0.776825 0.566435 -0.641663 -0.278551 -0.714617 0.420445 -0.544391 -0.725855
-0 -0.352946 -0.935644 0.399175 -0.536822 -0.743291 -0.378509 -0.485634 -0.787966
--0.564532 0.0903252 0.820454 0.00265338 -0.934652 0.355553 -0.0899031 -0.611341 0.786244
--0.8985 -0.252409 0.359149 0.673672 0.688717 -0.26802 -0.294485 -0.0631039 -0.95357
--0.830727 -0.420057 -0.365301 0.658488 0.719872 0.219496 -0.213353 0.963834 0.159703
--0.627803 0.700068 0.340248 0.546366 -0.561496 -0.621456 0.397347 -0.397347 -0.827182
--0.363614 -0.886822 0.285187 0.898894 -0.254554 0.356641 0.506943 -0.699884 0.50316
--0.573804 -0.538189 -0.617334 -0.483412 -0.0303714 -0.874866 0.598451 -0.619825 0.507615
-0.832499 0.445981 0.328705 -0.691032 -0.707291 0.149046 0.172447 -0.172447 -0.969806
--0.147857 -0.535454 -0.831521 -0.796696 -0.534456 0.282193 -0.197786 -0.928159 0.315279
-0.780603 -0.617143 0.0989653 0.820248 -0.568277 0.0652267 -0.973758 -0.0226455 0.226455
-0.919315 0.315586 0.235088 -0.600009 0.695182 -0.395868 0.307166 -0.557185 -0.771488
--0.357909 -0.586027 -0.726962 -0.991927 0.0148882 0.12593 -0.0436156 0.992255 -0.116308
-0.112852 0.94439 -0.308857 0 -0.699193 -0.714933 0.425581 -0.816792 0.389526
-0.554604 -0.805184 0.209984 -0.249555 -0.960203 0.125428 -0.907917 -0.0466872 0.416542
--0.819624 -0.015762 0.572686 0.897071 -0.135263 0.420675 -0.184387 0.964488 -0.189115
-0.785175 0.141838 -0.602812 -0.138233 0.990354 -0.00946802 -0.189037 -0.578924 0.793166
-0.80907 0.367141 0.458926 0.712364 0.274947 0.64571 -0.0772307 -0.724038 0.685423
--0.537326 -0.828757 0.156341 0.644661 0.764466 0.00190166 -0.633842 -0.741595 0.219732
--0.918632 -0.260508 -0.29707 -0.7758 -0.123306 -0.618813 -0.869091 -0.364103 -0.334829
-0.974566 -0.0251501 0.222683 0.856428 0.260562 0.445689 0 0.286582 0.958056
--0.622242 -0.656182 0.426896 -0.357277 -0.849524 0.388152 0.37847 0.879466 0.288617
-0.498339 0.839761 0.215544 -0.144164 -0.677962 0.720822 0.23215 -0.747922 0.621868
--0.0706076 -0.723728 0.686463 -0.717444 0.105168 0.688631 -0.689846 0.489349 0.533526
--0.731974 -0.671632 0.114562 0.0533486 0.906926 0.417897 0.494058 0.56507 0.660759
-0.729844 0.00793309 0.683568 -0.482697 -0.848026 -0.218757 -0.419436 -0.885477 -0.200009
--0.00301935 0.960153 0.279458 0.440196 0.752001 0.490635 -0.518201 0.782381 0.345467
--0.205353 -0.966659 0.152971 0.211218 -0.766884 0.606033 -0.834638 0.244123 0.493745
-0.799797 -0.307182 0.515716 0.527763 -0.0232623 0.849073 0.32594 -0.211257 0.921484
--0.274095 -0.713168 0.645185 -0.883103 -0.186223 0.43064 -0.551854 -0.827781 -0.101173
-0.968937 0.238534 0.0652922 -0.743488 0.529791 0.408102 0.545829 -0.433453 0.71707
--0.0797452 0 0.996815 0.391437 -0.669001 0.631834 -0.994407 -0.0678005 0.0809839
-0.652413 -0.609865 0.449913 -0.0276256 -0.910692 0.412161 -0.462232 -0.850126 0.252242
-0.270156 -0.689204 0.672319 -0.107629 0.522768 0.845654 -0.85372 0.357847 -0.378295
-0.362319 -0.687358 0.629495 0.0133976 -0.697707 0.716258 0.0683529 -0.772767 0.630998
-0.0312361 -0.777431 0.628192 -0.367265 -0.477998 0.797894 -0.38953 0.174335 0.904364
--0.158268 0.939195 0.304735 -0.657367 -0.734704 0.167564 0.338555 -0.63728 0.692283
-0.862128 0.00451376 0.50667 0.623929 -0.736236 0.26205 0.290356 -0.758885 0.582912
-0.778424 -0.346822 0.523231 -0.606172 -0.589621 0.533762 0.75355 -0.58685 0.29626
-0.246752 -0.809346 0.532984 -0.52009 -0.821074 0.235252 -0.709675 -0.68583 0.161238
-0.724845 -0.50997 0.463175 -0.916951 -0.395842 0.0501066 0.676329 0.736447 -0.0150295
-0.767536 -0.167899 0.618626 -0.726525 -0.676171 0.122286 0.807047 0.590411 -0.00949268
-0.536529 0.75552 -0.375935 0.189109 0.866118 0.462686 0.442605 -0.872192 0.208285
-0.762131 -0.568369 -0.31002 -0.913272 -0.258988 -0.31442 0.69705 -0.0279752 0.716477
-0.789299 -0.613216 0.0311944 0.605487 -0.630201 0.486037 0.760199 -0.612195 0.21752
--0.0822578 0.740321 0.667202 -0.856848 0.386508 -0.341209 0.413355 0.908883 0.0554045
-0.863375 -0.234283 0.446873 0.839448 -0.395966 0.372208 0.172774 0.777482 0.604708
--0.370247 0.887797 0.273373 -0.0265889 0.868572 0.49485 -0.703839 0.614933 -0.355624
-0.703157 -0.559768 0.438439 -0.295777 -0.371963 0.879863 -0.402732 -0.826118 0.394127
-0.751439 -0.644091 0.143131 -0.202927 0.96954 -0.137164 0.159409 0.299785 -0.940594
--0.345135 0.446563 0.825508 -0.755784 0.644915 0.113472 -0.0127457 -0.939996 0.340948
-0.554481 -0.73529 -0.389744 0.0383201 0.996322 -0.0766402 0 -0.993884 0.110432
-0.0623914 0.0594204 0.996281 -0.198595 -0.0379667 0.979346 -0.552502 -0.357105 0.753139
-0.95364 -0.283515 0.100948 0.0788381 -0.996887 -0.00103734 -0.623823 -0.516158 -0.586879
-0.619117 -0.711247 -0.332898 -0.587694 0.350116 -0.729407 0.425525 -0.633559 -0.646167
--0.792719 0.125052 -0.596623 0.549647 0.682485 0.48177 0.284613 0.868068 0.406759
-0.125081 0.646252 0.752803 -0.482884 0.46248 0.743596 0.0495907 0.963994 -0.261258
--0.220279 0.885436 -0.409244 -0.769262 -0.210159 -0.603382 0.463245 0.863706 -0.198534
-0.457551 0.889148 0.00801034 0.106283 0.978284 0.177943 -0.824598 0.385214 0.414305
--0.970146 -0.233118 0.0668742 0.99625 0.0510898 -0.0698227 -0.35326 0.855806 0.377895
--0.221715 0.565373 0.794478 -0.193881 0.320325 0.927255 -0.925243 0.0155069 0.379057
--0.843303 0.0018575 -0.537435 -0.894793 -0.13778 -0.424691 0.799902 0.47053 -0.372503
--0.316261 0.67903 0.662493 0.597121 0.11642 0.793658 -0.584023 0.460358 0.668572
--0.651687 0.267705 0.709675 0.730825 0.375507 0.56999 0.678212 0.452142 0.579306
-0.440507 0.652459 0.616645 -0.343026 0.883311 0.319524 0.00573542 0.81443 0.580234
--0.074976 0.995877 -0.0510706 0.256632 0.946919 -0.193609 0.713131 0.671647 -0.200836
-0.233665 0.826294 -0.512483 -0.883754 0.0489375 -0.465386 0.536882 -0.649454 -0.538486
--0.412153 0.527015 0.743226 0.47761 0.365454 0.798957 -0.198993 0.979813 0.0191922
-0.83459 -0.316449 0.45091 0.520414 0.122544 0.845075 0.585649 0.151293 0.79632
--0.742989 -0.398677 -0.53761 0.250072 0.953478 0.168357 -0.0907066 0.379318 0.920809
-0.0711989 -0.750327 0.657221 0.238656 -0.765445 0.59761 -0.858499 -0.505471 -0.086474
--0.148188 0.254037 0.955775 0.230954 0.798552 0.555855 -0.227606 0.878812 0.419385
-0.830754 -0.527494 0.177759 0.483491 -0.84246 0.237692 -0.547495 -0.79833 -0.250835
--0.596855 -0.778153 -0.195557 0.657571 0.553195 0.511444 -0.588348 0.784465 0.196116
-0.751382 -0.253756 -0.609125 0.69777 0.279108 -0.659709 0.569258 0.597721 -0.564514
-0.57905 0.539268 0.611466 0.355506 -0.0334594 0.934075 -0.695148 0.718065 0.0339511
-0.258622 0.862073 0.435826 -0.32263 0.897752 -0.299919 -0.594266 0.779492 -0.198089
--0.906621 -0.139084 -0.398364 0.426953 -0.760511 0.489218 -0.229504 -0.944247 -0.236062
--0.527683 -0.828512 -0.187401 -0.532891 -0.444664 -0.719932 -0.352344 -0.932926 -0.0741776
--0.257656 -0.96621 -0.00715711 -0.25711 -0.939012 -0.228365 -0.969541 0.153364 -0.19097
-0.799125 -0.599344 0.0467573 0.777426 -0.628471 0.025166 -0.966318 -0.256574 -0.0199928
-0.894109 0.296593 -0.335562 0.690268 -0.711399 -0.132067 0.686383 -0.11969 -0.717323
-0.713259 0.632277 -0.302469 -0.712278 0.651226 -0.261847 0.255656 -0.941177 -0.220965
-0.828486 0.555535 0.0706461 -0.666811 -0.742253 -0.0665188 0.837255 0.52587 -0.149886
--0.935068 -0.289133 -0.205059 0.703161 -0.689533 -0.173519 -0.949556 -0.0091597 -0.313465
-0.590602 0.309984 0.74505 -0.830706 -0.480177 0.281704 0.508962 -0.840972 0.18364
-0.259785 0 -0.965666 0.837165 0.429937 0.338096 -0.454403 -0.495712 0.740126
--0.77485 -0.478956 -0.412563 -0.0814985 -0.995301 0.0522949 0.714269 0.236299 -0.658774
--0.634238 -0.369972 0.678869 0.781088 0.618361 0.0867875 0.474481 0.800686 0.365746
-0.520859 -0.129625 0.843744 0.90976 0.304175 0.282514 -0.746589 -0.603824 0.279288
-0.126534 -0.989943 -0.063267 -0.503895 -0.852012 -0.142002 0.410782 -0.898505 -0.15475
--0.356862 -0.172444 -0.918103 0.655409 0.607867 0.448259 -0.46487 -0.542042 0.700061
-0.00422915 -0.90081 -0.434193 -0.191351 -0.867457 -0.459242 0.821086 -0.454422 -0.345425
--0.546042 0.58859 -0.596154 -0.93058 0.113535 -0.348038 -0.753609 -0.628008 -0.194111
-0.438023 0.109506 0.892269 0.777655 0.330412 0.534866 -0.889174 -0.0967962 -0.447213
-0.160625 -0.103259 -0.981599 -0.0679258 -0.666908 -0.742038 -0.728188 0.305994 0.613279
--0.833474 -0.0123217 0.552422 -0.107566 0.0759289 0.991294 -0.180939 -0.719548 0.670456
--0.350117 -0.73456 0.58124 0.775063 0.60803 -0.171976 0.547788 -0.620137 -0.561568
--0.852937 -0.0140401 -0.521824 -0.941919 -0.217366 0.256009 0.682862 -0.72604 0.0810265
-0.226125 -0.767773 0.599494 -0.77116 -0.632747 0.0703052 0.881302 0.375022 -0.287517
-0.886711 0.28195 -0.366398 0.880522 0.266924 -0.391705 0.329377 -0.838118 -0.434821
--0.0988595 -0.97384 -0.204605 -0.467157 -0.647056 -0.602564 0.463428 0.868927 -0.173785
--0.538635 0.817571 -0.203591 0.504489 -0.246379 -0.827519 -0.159358 -0.830206 -0.534194
--0.520467 -0.546931 -0.655729 0.395295 0.796767 0.45706 -0.168681 0.984547 0.0470471
--0.256167 0.966621 0.004627 0.989896 -0.134516 0.0448385 -0.826469 0.373294 0.421427
-0.343333 -0.924358 -0.166385 0.844812 -0.0808081 -0.528926 -0.666903 0.283434 -0.689134
-0.999991 -0.00306746 -0.00306746 0.970461 -0.206424 -0.124882 -0.19123 -0.956151 0.221827
--0.207602 0.851885 -0.480826 -0.936313 0.317231 -0.150605 0.106412 -0.127695 -0.986088
--0.680817 0.732192 -0.0195712 0.139002 -0.914116 -0.380882 0.911713 0.363804 -0.190858
--0.0763092 0.985661 -0.150499 -0.0643992 0.965988 -0.250441 -0.532559 0.817202 -0.220369
-0.0588725 0.408645 0.910793 -0.376454 0.792696 0.479494 0.564532 0.8054 -0.18065
-0.888415 0.376903 -0.262037 0.042241 0.995884 -0.0801862 0.978205 -0.0670004 -0.196534
-0.558875 0.62795 0.541607 0.362945 0.798117 0.480917 -0.342674 0.920935 -0.185615
-0.686221 0.721715 0.0907074 0.728373 0.681881 -0.067155 0.296334 0.931334 -0.211667
--0.560047 0.665716 0.493123 -0.728108 0.6721 0.134687 0.809224 0.325276 0.489237
-0.26383 0.906776 0.328863 -0.983703 0.14414 0.107479 -0.429642 0.839754 0.331996
--0.563812 0.82589 0.00459786 -0.812234 0.54149 0.216943 0.298822 0.914343 0.273281
-0.258055 0.918501 0.299606 0.892747 0.334366 0.301996 -0.85362 0.219279 0.472493
--0.700469 0.62234 0.349337 0.724669 0.537697 0.430972 -0.851145 -0.338675 0.401063
-0.452102 0.322536 0.83161 0.640457 0.751488 -0.158367 -0.418052 -0.8813 -0.220325
--0.341742 -0.93979 -0.00251281 0.932318 -0.334771 -0.136788 -0.147033 0.952039 0.268335
--0.43836 -0.769566 0.464337 0.170428 0.806892 0.565579 0.381367 0.560659 0.734998
-0.368843 -0.319411 0.872887 -0.24938 -0.798426 0.54802 -0.0984517 -0.950836 0.293628
-0.66899 -0.561804 0.48665 -0.573497 0.517834 -0.634783 -0.934294 0.219331 -0.281048
-0.566153 -0.781677 -0.261631 0.839666 -0.138027 -0.525271 -0.312362 0.94996 0.00261234
-0.910303 -0.40317 0.0938195 0.401091 -0.0668485 0.913596 -0.754771 -0.55993 0.341759
--0.994941 0.0826658 -0.0570787 0.725394 0.6883 0.00686926 0.265795 0.9093 0.320198
-0 -0.185408 0.982662 -0.368689 -0.345428 0.862988 -0.823699 -0.0296295 0.566252
--0.706004 -0.644612 -0.293316 -0.313848 -0.849235 -0.424617 0.157286 0.259059 0.952969
--0.568035 0.0908856 0.817971 0.897795 -0.439829 0.0226716 -0.304582 0.64458 0.701246
--0.241642 0.283963 0.927887 -0.393831 0.65717 0.64267 -0.384949 0.88418 0.264652
-0.501991 -0.00994041 -0.864816 0.892835 0.275335 0.356421 0.996713 0.0228604 0.0777253
-0.235249 0.88545 0.400794 0.0265536 0.862992 -0.504519 -0.461695 0.619809 -0.634567
-0.015591 0.930263 -0.366562 -0.279485 -0.960092 0.0105233 -0.274154 -0.961669 0.00568194
--0.201044 -0.979353 0.0211785 -0.0885584 -0.996071 0 0 -1 0
-0 -0.999816 -0.0191892 -0.0667311 -0.997587 -0.0191465 -0.0785018 -0.996512 -0.0283222
-0 -0.999901 -0.014081 0.111426 -0.993624 -0.0171897 0.182745 -0.983081 0.0124766
-0.14425 -0.988923 0.0349697 0.209281 -0.975923 0.061447 0.20126 -0.977087 0.0692509
-0 -0.995197 0.0978883 -0.10444 -0.974769 0.197275 0 -0.983175 0.182666
-0 -0.990057 0.140664 0.0975198 -0.991451 0.0866843 -0.446082 -0.894992 0
--0.465128 -0.885243 0 -0.308237 -0.951157 -0.0170229 -0.263313 -0.964684 0.00718127
-0.1499 -0.983638 0.0999335 0.0198833 -0.994163 0.106044 -0.0851522 -0.991866 0.0946136
-0.354005 -0.919619 0.170241 0.608501 -0.760931 0.22519 0.607536 -0.761714 0.225149
--0.682813 -0.716331 0.143649 -0.43741 -0.874004 0.211633 0.30826 -0.943021 0.12525
-0.695662 -0.664041 0.274049 -0.564745 -0.825265 0 -0.610299 -0.792104 0.0102787
--0.46671 -0.884401 -0.00408499 0.430166 -0.866834 0.252104 0.146086 -0.980865 0.128695
--0.235457 -0.963758 0.125423 -0.698113 -0.704852 0.125786 0.796187 -0.442326 0.412837
-0.73523 -0.487031 0.471421 0.825203 -0.255697 0.503645 0.0075539 -0.89136 0.453234
--0.712932 -0.697357 0.0736295 -0.669195 -0.738447 0.0829133 0.863017 -0.249821 0.439079
-0.924922 -0.0660658 0.374373 -0.725353 0.565463 0.392574 -0.532116 -0.821564 0.20466
--0.668001 -0.705112 0.237892 0.336973 -0.937546 0.0863569 0.399804 -0.914306 0.0648134
--0.328104 -0.944567 0.0118388 -0.388972 -0.92125 0 -0.437541 -0.898948 0.0212141
-0.842528 -0.454397 0.289257 -0.919454 -0.060292 0.388549 -0.916877 -0.297229 0.266443
-0.614886 -0.788568 0.0086409 0.769212 -0.638913 -0.0101843 -0.489603 -0.870405 0.0518098
--0.517831 -0.854646 0.0378242 -0.475235 -0.879761 -0.0131553 -0.454792 0.773371 -0.441658
-0.457439 0.470894 -0.754327 0.637711 0.755443 -0.150434 0.195588 0.97794 -0.0733455
--0.351294 0.91877 -0.180151 0.569061 -0.803759 0.173612 -0.73254 -0.656961 0.17829
-0.15325 -0.973776 0.168149 -0.661326 -0.726081 0.188294 0.883769 -0.459398 -0.0889158
-0.908735 -0.400459 -0.117617 -0.487417 -0.870388 0.0696311 -0.486002 -0.872009 0.05833
-0.30655 0.892601 -0.330593 0.287824 0.897735 -0.33351 0.198127 0.936202 -0.290295
-0.140983 0.94177 -0.305276 0.0184246 0.95071 -0.309534 -0.266425 0.916503 -0.298396
--0.439484 0.867163 -0.23427 -0.453132 0.863108 -0.22297 0.928792 -0.271056 -0.252733
--0.708115 -0.624926 -0.328695 -0.366922 -0.927089 0.0766459 0.975779 -0.110088 -0.18904
--0.515842 -0.851813 0.0912198 -0.894821 -0.434946 0.100591 0.168938 -0.985625 0.00180683
-0.610801 -0.790751 0.0404458 0.62596 -0.778972 0.0370939 -0.679775 -0.722261 0.127458
--0.474595 -0.877109 0.0737466 0.460456 0.850674 -0.253641 0.29013 0.924335 -0.24785
-0.180154 0.948812 -0.259422 0.165823 0.939665 -0.299219 0.282149 0.900644 -0.330502
--0.455763 0.862374 -0.220434 -0.311262 0.92517 -0.217201 -0.24785 0.95001 -0.189871
--0.214222 0.959033 -0.185375 -0.184099 0.796646 -0.575728 0.589037 -0.674199 -0.445523
--0.0897068 -0.937437 -0.336401 0.961929 0.166077 -0.217051 -0.987045 0.150574 0.0554062
-0.604209 -0.796135 0.0331723 0.544451 -0.83808 0.0345683 -0.28431 -0.948035 0.142823
--0.222907 -0.964731 0.140025 0.149932 -0.97456 0.166591 -0.448672 -0.88538 0.12164
-0.327741 0.853608 -0.404893 0.356679 0.857281 -0.37128 0.427049 0.847627 -0.314894
-0.479715 0.839502 -0.255168 -0.180057 0.964724 -0.19206 -0.17241 0.949471 -0.262258
--0.401497 0.867562 -0.293492 -0.390424 0.877381 -0.278874 0.879973 0.436878 -0.186507
--0.8848 0.465867 0.00985042 0.536194 -0.843495 0.0318177 0.605344 -0.794767 0.0436388
-0.616143 -0.78655 0.0413109 -0.609367 -0.781239 0.135415 -0.454729 -0.878828 0.144508
--0.333345 -0.935307 0.118666 0.596007 0.736388 -0.320169 0.359282 0.851087 -0.382842
--0.381715 0.880964 -0.279637 -0.388603 0.850528 -0.354387 -0.421969 0.843939 -0.331223
--0.430517 0.844565 -0.318378 -0.111816 0.901373 -0.418359 0.764673 0.614553 -0.193905
-0.875611 0.446136 -0.185119 -0.87505 0.483939 0.009489 -0.87991 0.475038 0.00987847
-0.583376 -0.811049 0.043256 0.455673 -0.888468 0.0546554 -0.784014 -0.607878 0.125727
--0.812292 -0.56948 0.125995 0.52514 0.8029 -0.2821 0.470129 0.831596 -0.295679
-0.588126 0.743735 -0.317752 -0.329969 0.889279 -0.316708 -0.0609368 0.962802 -0.263247
--0.0487821 0.963446 -0.263423 -0.26952 0.919791 -0.285207 -0.465079 0.84739 -0.256188
--0.106709 0.895169 -0.432764 0.619572 0.756938 -0.207787 0.687799 0.699214 -0.195019
--0.90749 0.418979 -0.0303091 0.398396 -0.915758 0.051644 0.452701 -0.891031 0.0335334
-0.526696 -0.849625 0.02701 -0.846911 -0.50641 0.162144 0.632236 0.632236 -0.447834
-0.0810448 0.921649 -0.379466 0.311677 0.885447 -0.344734 0.533229 0.797007 -0.283632
--0.467859 0.846086 -0.255435 -0.257223 0.932138 -0.254863 -0.105308 0.967076 -0.231677
--0.149137 0.955078 -0.256094 -0.234589 0.927496 -0.291064 -0.210937 0.922849 -0.322265
-0.462607 0.856168 -0.230153 0.607283 0.764151 -0.217441 -0.915423 0.401011 -0.0345132
--0.917805 0.394702 -0.0429383 0.545751 -0.837912 0.00765966 0.536292 -0.837903 -0.101538
-0.514291 -0.852072 -0.0973555 -0.438949 -0.893575 0.0940605 -0.643464 -0.747248 0.166055
-0.331179 0.804293 -0.49339 0.652385 0.671787 -0.350849 -0.167097 0.925588 -0.339655
--0.139846 0.929562 -0.341113 -0.277767 0.902352 -0.329555 -0.162397 0.924959 -0.343624
-0.042895 0.93654 -0.347926 0.197486 0.895271 -0.399361 0.0469726 0.935839 -0.349284
-0.206169 0.91721 -0.34091 0.452113 0.861337 -0.231715 -0.906546 0.412737 -0.0884435
-0.478404 -0.874821 -0.0762803 0.525524 -0.849231 -0.0512869 0.582049 -0.812504 -0.0325002
--0.674652 -0.73764 0.0270694 -0.745972 -0.665709 0.0188854 0.565346 0.785774 -0.250884
-0.545339 0.80327 -0.239507 0.336209 0.906564 -0.255159 0.504298 0.800663 -0.323452
--0.863022 0.501553 -0.0603085 0.674282 -0.738209 -0.019787 0.792273 -0.607985 -0.0515567
--0.83483 -0.548247 0.0498406 0.640116 0.735073 -0.223426 0.569923 0.786184 -0.238962
--0.860948 0.505315 -0.058522 -0.828601 0.553486 -0.0841081 0.847111 -0.511494 -0.144143
-0.838008 -0.525074 -0.148458 -0.845244 -0.528173 0.0812146 0.607048 0.767285 -0.2068
-0.56719 0.795933 -0.211626 0.637268 0.737754 -0.222729 -0.873019 0.481051 -0.0801752
--0.889695 0.44926 -0.0812946 0.720579 -0.633612 -0.281605 0.559646 -0.819889 -0.12074
-0.563916 -0.818588 -0.109145 -0.846393 -0.523492 0.097849 -0.838657 -0.535475 0.0996064
-0.778682 0.597046 -0.192849 0.722873 0.660975 -0.201412 -0.944739 0.320337 -0.0696634
-0.635403 -0.769735 -0.0614203 0.706902 -0.706216 -0.0393486 -0.747686 -0.657963 0.0897223
-0.84117 0.510537 -0.178283 -0.985739 0.165025 -0.0329462 0.82516 -0.564333 0.0252922
-0.842692 -0.537594 0.0293678 -0.766405 -0.637963 0.0750128 0.879043 0.439522 -0.184673
-0.843606 0.506872 -0.177228 -0.98623 0.1627 -0.029661 0.892631 -0.450742 -0.00643918
--0.787627 -0.611447 0.0759991 -0.844881 -0.529365 0.0771261 0.879973 0.436878 -0.186507
--0.987768 0.15465 -0.0199549 -0.985775 0.165093 0.0315033 0.901295 -0.433181 -0.00465786
-0.906341 -0.422545 -0.0011836 -0.894208 -0.440431 0.0800783 0.917305 0.346811 -0.195637
-0.882356 0.432583 -0.185256 -0.996776 -0.0190001 0.0779493 0.860584 -0.507798 0.0391984
--0.875593 -0.477047 0.0759135 0.914808 0.347158 -0.206418 -0.918262 -0.375653 0.125218
--0.647596 0.627359 0.432481 -0.574074 0.683601 0.450698 -0.628074 0.664893 0.404278
--0.658946 0.629894 0.411126 0.833918 -0.547733 0.0675979 0.840194 -0.537841 0.0692894
--0.895805 -0.441217 0.0534809 0.914241 0.355832 -0.19377 -0.958697 -0.265429 0.102213
--0.485848 -0.696872 0.527562 -0.374688 -0.745019 0.551866 -0.538516 -0.66768 0.514008
-0.915806 -0.384406 0.116326 -0.911935 -0.4079 0.0446234 0.946198 0.252955 -0.201799
-0.916367 0.351076 -0.192397 -0.980923 -0.115036 0.156704 -0.462568 -0.72496 0.510357
-0.938309 -0.327317 0.11153 0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338
-0.951038 0.208849 -0.227835 -0.973728 -0.156552 0.165366 0.935161 -0.334447 0.116703
--0.947121 -0.318063 0.0424084 -0.946323 -0.320875 0.0388939 0.939721 0.268262 -0.21204
--0.970249 -0.173227 0.169145 0.937562 -0.330556 0.108213 -0.940597 -0.336391 0.0460259
-0.938056 0.283766 -0.198817 -0.970969 -0.173905 0.164244 0.942445 -0.316493 0.107842
-0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338 0.965795 0.178257 -0.188318
-0.94359 0.267626 -0.194972 -0.958271 -0.238916 0.156961 0.932844 -0.333618 0.136021
--0.955365 -0.292313 0.0427776 -0.964187 -0.262245 0.0396281 0.977703 0.0987872 -0.185307
--0.927979 -0.331878 0.169444 0.934909 -0.329621 0.131511 -0.967903 -0.24577 0.0525545
-0.982451 0.085296 -0.165878 -0.9542 -0.24866 0.166347 0.939229 -0.315413 0.135511
-0.937489 -0.317879 0.141657 -0.968373 -0.243346 0.0550971 0.983436 0.0874351 -0.158771
--0.970969 -0.173905 0.164244 0.951928 0.306221 -0.00782675 0.744662 0.667362 0.0103067
--0.447367 0.858657 -0.250141 -0.920055 0.277962 -0.276109 0.930883 -0.332917 0.150409
--0.959368 -0.259522 0.11073 0.980586 0.0876947 -0.175389 -0.984588 -0.0919425 0.148774
-0.972924 0.205659 -0.105466 -0.939769 -0.284404 -0.189602 0.91166 -0.378968 0.158931
--0.95251 -0.284331 0.108994 -0.94166 -0.319294 0.106431 0.976638 0.0810446 -0.199021
--0.960915 -0.208065 0.182621 0.807409 0.585228 -0.0748237 -0.999142 -0.0344532 0.0229688
-0.907595 -0.389554 0.156585 0.898921 -0.414243 0.14263 -0.935161 -0.334447 0.116703
-0.968309 -0.00756491 -0.249642 -0.943049 -0.298862 0.146083 0.827908 0.551939 -0.0996556
-0.829409 0.553701 -0.0741315 -0.988999 0.0766979 0.126484 0.923209 -0.350874 0.156754
--0.938228 -0.330791 0.101521 0.81747 0 -0.575971 0.886783 -0.136041 -0.441712
-0.953334 -0.135022 -0.270043 -0.914936 -0.375234 0.148631 0.979671 0.163446 -0.116317
--0.963879 -0.205729 0.169155 0.970969 -0.173905 0.164244 -0.942445 -0.316493 0.107842
--0.94166 -0.319294 0.106431 0.940581 -0.229456 -0.250316 -0.915144 -0.379766 0.135234
--0.912054 -0.39573 0.107493 0.975988 -0.184472 -0.115832 0.994562 -0.07154 -0.0756873
--0.924056 -0.334353 0.185281 -0.96241 -0.212743 0.168844 0.973323 -0.159799 0.164642
--0.932844 -0.333618 0.136021 0.958965 -0.188685 -0.211623 -0.929024 -0.353084 0.110664
-0.981489 0.19151 0.00177324 -0.914695 0.195669 0.353619 0.927322 -0.339685 0.157127
--0.942986 -0.305259 0.132647 0.967742 -0.176726 -0.179562 -0.944318 -0.324169 0.0563772
-0.778301 0.622885 -0.0791354 0.799704 0.595128 -0.0793504 -0.8851 0.366684 0.286604
--0.827431 0.48322 0.286107 -0.5688 -0.724941 0.388494 0.558626 0.791388 0.248278
-0.034426 0.998353 0.0459013 -0.617527 -0.693453 0.371191 0.920138 -0.349707 0.176216
--0.936023 -0.320393 0.145633 -0.927877 -0.338893 0.155552 0.979754 -0.101184 -0.172753
-0.981068 -0.085914 -0.173564 -0.938781 -0.343883 0.0208414 0.886292 0.462413 -0.0256896
--0.678384 -0.345007 0.648664 -0.819457 -0.320657 0.475047 -0.940819 -0.210288 0.26578
-0.686347 0.630996 0.361624 0.751684 0.602857 0.267457 0.706789 0.660391 0.25364
--0.819705 0.102463 0.563547 -0.8922 -0.181026 0.413774 -0.627888 -0.689446 0.361138
-0.933945 -0.320608 0.157981 -0.918705 -0.372095 0.13239 0.981989 -0.0742681 -0.173727
--0.917171 -0.398376 0.00965761 0.947075 0.290642 0.136296 -0.226875 -0.948751 0.22
--0.557122 -0.793708 0.244218 0.587346 0.306441 0.749079 0.874185 0.417752 0.247557
--0.906806 -0.303399 0.292664 -0.913171 -0.31716 0.255985 0.927322 -0.339685 0.157127
--0.956602 -0.274784 0.0969827 0.94461 -0.272176 -0.183391 -0.933106 -0.359366 0.0130463
--0.943618 -0.330819 0.0119795 0.368099 -0.609268 0.70235 0.913666 0.201007 0.353284
--0.66647 -0.719787 0.194228 -0.65525 -0.721163 0.224879 -0.297492 -0.946762 0.12305
-0.898269 0.175236 0.402994 0.92303 0.26147 0.282221 0.910131 0.340691 0.23578
--0.414276 -0.659075 0.627691 -0.768872 -0.586989 0.253535 -0.867554 -0.438009 0.23558
-0.920138 -0.349707 0.176216 -0.982641 -0.175995 0.0586652 0.91092 -0.365516 -0.19137
--0.969412 -0.230631 0.0839648 -0.755723 -0.432203 0.49202 0.948314 0.0278916 0.316105
--0.785132 -0.42864 0.44703 0.556362 -0.568725 0.605816 0.656064 -0.498123 0.566969
-0.276547 -0.769146 0.576139 -0.543138 -0.78524 0.297319 0.970969 -0.173905 0.164244
--0.982995 -0.179131 0.0404011 0.929544 -0.325885 -0.172474 -0.928036 -0.356484 0.108025
--0.781546 -0.390773 0.486295 0.32972 -0.74187 0.583879 0.982172 -0.0879557 0.166139
--0.984305 -0.174911 0.0234358 0.925966 -0.337834 -0.168689 0.922301 -0.342488 -0.17906
--0.840928 -0.522527 0.140736 0.960749 -0.239534 0.139946 -0.995476 -0.0885055 0.0345593
-0.893041 -0.408998 -0.187614 -0.8376 -0.529841 0.133024 -0.899114 -0.436794 0.0283632
-0.935161 -0.334447 0.116703 -0.997618 0 0.0689857 0.843606 -0.506872 -0.177228
-0.84233 -0.508536 -0.178528 -0.994726 -0.101503 -0.014764 0.344364 0.0153051 0.938711
-0.384816 0.25161 0.888037 0.45747 0.0714796 0.886348 0.334283 -0.276146 0.90111
-0.388453 -0.371265 0.843367 -0.0610664 0.692086 0.719227 0.341072 -0.259577 0.903488
--0.531593 0.607067 0.590659 -0.487994 -0.350143 0.799538 -0.848697 -0.414609 0.328348
-0.963556 -0.255241 0.0800755 -0.994649 0 0.103311 0.886275 -0.419608 -0.196078
--0.437057 0.874115 -0.211907 0.405084 0.914226 0.00991031 0.488817 0.86761 0.091162
-0.210173 0.928038 0.307526 -0.469168 0.310748 0.82663 0.0414232 0.925119 0.377412
--0.66882 0.299209 0.680554 -0.802416 0.0272005 0.596145 -0.797353 -0.246454 0.550898
-0.144292 -0.272552 0.95126 0.319219 -0.520209 0.792137 0.0466797 -0.855794 0.515206
--0.598057 -0.628148 0.497754 0.994258 -0.089038 0.0593587 -0.994649 0 0.103311
-0.816194 -0.5454 -0.190699 0.813785 -0.548357 -0.192508 -0.67218 -0.640671 -0.371099
--0.557019 -0.768686 -0.314406 -0.0780157 -0.84517 -0.528773 -0.740772 -0.666695 0.082308
-0 -0.853639 -0.520865 0 -0.999504 0.0314805 0 -0.994853 0.101328
-0 -0.909398 0.415926 0 -0.934997 0.354654 -0.147687 -0.912182 0.382248
--0.837426 -0.233381 0.494218 0.995086 0 0.0990135 -0.994649 0 0.103311
-0.835057 -0.518216 -0.184747 -0.926832 -0.344868 -0.148485 -0.0234658 -0.863541 -0.503732
--0.00729327 -0.99772 0.0670981 0.0127155 -0.925688 0.378074 0.995086 0 0.0990135
--0.994649 0 0.103311 0.820178 -0.547229 -0.166876 0.811536 -0.559388 -0.168805
--0.956952 -0.264351 -0.119839 -0.982107 -0.175595 -0.0680601 0.995086 0 0.0990135
--0.994649 0 0.103311 0.803754 -0.56963 -0.17176 -0.932644 -0.351766 -0.0802274
-0.994258 0.089038 0.0593587 -0.994649 0 0.103311 0.797774 -0.57796 -0.171809
-0.754661 -0.632201 -0.175526 -0.297991 -0.736701 -0.60702 -0.39539 -0.691932 -0.604067
-0.0430287 -0.774517 -0.631088 0.48321 -0.683083 -0.547637 0.485352 -0.7371 -0.470232
-0.578083 -0.662522 -0.476323 -0.928843 -0.368139 -0.0415336 -0.975413 -0.220063 0.0118953
-0.98126 0.175193 0.0802233 -0.994649 0 0.103311 0.718864 -0.672108 -0.177497
-0.695091 -0.695091 -0.183567 -0.551784 -0.551784 -0.625355 -0.58159 -0.63064 -0.513855
--0.626391 -0.584163 -0.516128 0 -0.40364 -0.914918 -0.245541 -0.613852 -0.750264
-0.773549 -0.0521494 -0.631587 -0.627189 -0.137893 0.766564 -0.935451 0.350794 0.0433079
--0.898769 0.436471 0.0413227 0.982812 0.158012 0.0954571 -0.994649 0 0.103311
-0.185375 0.17796 0.96642 0.857402 -0.483663 0.175877 -0.338906 0.897994 0.280623
--0.712029 0.66542 0.224121 -0.780361 0.588177 0.212333 0.695091 -0.695091 -0.183567
-0.695091 -0.695091 -0.183567 -0.40364 0 -0.914918 -0.613852 -0.245541 -0.750264
-0 0 -1 0.382859 -0.316729 -0.867814 0.6379 -0.38274 -0.668276
--0.837997 0.535257 -0.106115 0.979643 0.159679 0.12166 -0.994649 0 0.103311
-0.738928 -0.627898 0.244395 -0.713958 -0.294895 0.63506 -0.909343 0.239301 0.340339
-0.695091 -0.695091 -0.183567 0.673365 -0.714803 -0.188773 -0.564888 -0.451911 -0.690419
--0.522083 -0.540085 -0.660104 0 -0.342852 -0.939389 -0.229748 -0.742263 -0.629493
-0.0276674 -0.774687 -0.631739 0.58132 -0.72818 -0.36307 0.529586 -0.781548 -0.329728
--0.912074 0.372537 -0.171281 -0.961153 0.247659 -0.121864 0.973547 0.173 0.149255
--0.994649 0 0.103311 0.748742 -0.614416 0.248752 0.635278 -0.541163 0.550967
-0.674978 -0.528131 0.51525 0.4346 -0.39114 0.811253 0.647272 -0.736992 -0.194632
-0.592917 -0.77952 -0.201986 -0.374299 -0.374299 -0.848411 -0.522083 -0.540085 -0.660104
--0.484928 -0.464723 -0.740863 0 0 -1 -0.32432 -0.32432 -0.888613
--0.15923 -0.641385 -0.750514 0.129084 -0.619922 -0.773973 0.547381 -0.800591 -0.243777
-0.437088 -0.782692 -0.443111 0.570316 -0.795567 -0.204483 0.571862 -0.794706 -0.20351
--0.940204 -0.335531 -0.0586132 0.971269 0.176995 0.15909 -0.991959 -0.073494 0.103032
-0.890045 0.193488 0.412774 -0.601734 0.657157 0.45394 -0.559559 0.742089 0.36905
-0.593383 -0.776323 -0.212648 0.690387 -0.682013 -0.241294 0.695867 -0.676604 -0.240784
--0.334529 -0.559575 -0.758265 -0.351027 -0.604546 -0.715055 -0.229748 -0.742263 -0.629493
--0.511382 -0.665985 -0.543095 0 0.208691 -0.977982 0.576997 -0.552269 -0.601726
-0.695706 -0.683943 -0.219579 0.765076 -0.601888 -0.228887 -0.88332 -0.466227 -0.04877
--0.696474 -0.717474 0.012444 0.982172 0.0879557 0.166139 -0.991745 -0.0846403 0.0963246
-0.80803 0.512788 0.290062 -0.0340272 0.782625 0.621563 -0.650659 0.679684 0.338633
--0.575574 0.698237 0.425652 0.573936 -0.783507 -0.238148 0.570736 -0.786242 -0.23682
--0.304518 -0.790296 -0.531697 -0.352924 -0.764669 -0.53919 -0.269052 -0.739894 -0.616578
--0.336836 -0.759934 -0.555916 0.22181 -0.208763 -0.95248 -0.201876 -0.232063 -0.951521
-0.689665 -0.515507 -0.508541 0.911446 -0.334489 -0.239547 -0.32526 -0.94218 0.0806431
--0.310025 -0.947492 0.0783771 -0.513201 -0.857889 0.0255324 0.985993 0 0.166785
--0.995816 0 0.0913839 0.922812 -0.350879 0.159065 -0.769477 -0.246993 0.588982
--0.680666 -0.490079 0.544533 0.607283 -0.764151 -0.217441 0.598502 -0.772542 -0.21207
--0.266017 -0.752103 -0.602972 -0.278994 -0.80958 -0.516471 -0.404761 -0.769046 -0.494708
--0.0803889 -0.840429 -0.535926 -0.334393 -0.759983 -0.557321 0.968851 -0.186702 -0.162698
--0.442193 -0.895896 0.0428444 -0.484923 -0.87324 0.0479871 -0.375434 -0.9257 0.0461502
--0.346325 -0.934029 0.0874559 0.985993 0 0.166785 -0.991745 0.0846403 0.0963246
-0.492928 -0.860757 0.126966 0.0776973 -0.99064 0.112229 -0.0571247 -0.991282 0.11873
--0.493055 -0.84793 0.19471 -0.653859 -0.553454 0.515904 0.590372 -0.780377 -0.20609
-0.572871 -0.793442 -0.205594 -0.324841 -0.593574 -0.736307 -0.45913 -0.688695 -0.561159
--0.404494 -0.674157 -0.617977 -0.281767 -0.569727 -0.772022 -0.350017 -0.725961 -0.592004
-0.985853 -0.159009 -0.0530029 -0.864813 -0.480157 0.146788 -0.692506 -0.714244 0.101443
-0.983335 -0.0733832 0.166335 -0.991959 0.073494 0.103032 0.00402836 -0.993661 0.112346
-0.587596 -0.69129 -0.420535 0.58271 -0.785392 -0.208824 0.56284 -0.791292 -0.238892
-0.562033 -0.79094 -0.241935 -0.226493 -0.82773 -0.513385 -0.241248 -0.861599 -0.446595
--0.365597 -0.8165 -0.446841 -0.0694331 -0.883694 -0.462887 -0.292104 -0.823202 -0.48684
--0.431539 -0.721202 -0.541887 0.961957 -0.269611 0.0441523 -0.73451 -0.576341 0.358227
--0.952994 -0.155379 0.260117 0.970003 -0.163404 0.179981 -0.994649 0 0.103311
-0.521358 -0.801554 -0.292741 0.471267 -0.826425 -0.308107 -0.517718 -0.711862 -0.474575
--0.457399 -0.73991 -0.493274 -0.350017 -0.725961 -0.592004 0.938158 -0.332209 0.097448
--0.711954 -0.561604 0.421571 -0.738749 -0.211071 0.640077 -0.776984 0.365639 0.512449
-0.526008 0.850448 0.00736319 0.561594 0.827147 -0.0209819 -0.398197 0.911999 -0.0984787
--0.996499 -0.0379831 -0.0744768 0.973268 -0.0957941 0.20874 -0.994649 0 0.103311
-0.432317 -0.845277 -0.314021 0.277767 -0.902352 -0.329555 0.29672 -0.896508 -0.328984
-0.30655 -0.892601 -0.330593 -0.211224 -0.895818 -0.391017 -0.246372 -0.893097 -0.376401
--0.19087 -0.90133 -0.388809 -0.380769 -0.826024 -0.415571 0.91681 -0.368812 0.153092
--0.574699 -0.549468 0.606471 0.00420699 -0.37863 0.925539 -0.202648 0.572181 0.794696
-0 0.447214 0.894427 -0.630304 0.467218 0.620019 -0.614424 0.384409 0.688995
--0.597018 0.447763 0.665641 0.345204 0.927614 0.14271 0.219501 0.969407 0.109858
--0.229929 0.965862 0.119341 -0.518612 0.842456 0.14598 0.761176 0.567208 0.314463
-0.480353 0.857773 0.182992 0.412654 0.903095 0.118895 -0.83391 -0.525598 -0.168348
--0.73334 -0.668785 -0.122223 0.977765 0 0.209704 -0.990783 0.0880882 0.102909
-0.318775 -0.888499 -0.330079 0.414728 -0.854726 -0.312161 0.393909 -0.871766 -0.291306
--0.167097 -0.925588 -0.339655 -0.210937 -0.922849 -0.322265 0 -0.938787 -0.344499
--0.123661 -0.931581 -0.341855 -0.122384 -0.945694 -0.301139 -0.20314 -0.91973 -0.335902
--0.28152 -0.89949 -0.334162 0.896953 -0.419203 0.140515 0.871755 -0.470252 0.137501
--0.268549 -0.960267 0.0759533 0.175164 -0.967724 0.181186 0.856429 -0.394109 0.333477
-0.445689 -0.869571 0.212622 -0.336085 -0.93357 0.124476 0.0232069 -0.999117 -0.0350139
-0.373427 -0.908543 -0.187355 0 -0.357789 0.933803 -0.323885 -0.689561 0.647769
--0.677957 0.0739589 0.731372 0.94085 -0.210308 0.265652 0.847716 0.493216 0.195232
--0.82378 0.554737 0.116848 -0.850412 0.525255 0.0301072 0.724963 0.626742 0.285698
-0.717732 0.67434 0.173569 0.683848 0.706168 0.183517 0.425656 0.243232 0.871582
--0.379604 -0.827626 0.413445 -0.799874 -0.599905 0.017775 -0.784501 -0.613566 0.0899658
-0.97202 -0.108245 0.208472 -0.980301 0.1742 0.0930774 0.342227 -0.896509 -0.28134
-0.149137 -0.955078 -0.256094 0.0528742 -0.971123 -0.232647 0 -0.972483 -0.232972
-0 -0.90031 -0.435249 -0.0528742 -0.971123 -0.232647 -0.149137 -0.955078 -0.256094
--0.234589 -0.927496 -0.291064 0.78306 -0.599178 0.166741 -0.502994 -0.864119 0.0171964
--0.441164 -0.896792 0.0337502 -0.327019 -0.94308 0.0604809 0.970338 -0.188498 0.15137
--0.82888 -0.559316 0.0110834 -0.893176 -0.448092 -0.0380928 0.963121 0.216896 -0.159229
--0.759243 -0.172095 0.627641 -0.150614 -0.506612 0.848917 -0.326814 -0.673139 0.663383
-0.987592 -0.127364 0.091869 0.984198 -0.176688 0.0116819 -0.391963 0.905571 -0.162192
--0.806214 0.586434 -0.0781912 -0.444323 0.654278 -0.611962 -0.927756 -0.0655707 -0.367382
-0.601259 0.720474 0.345551 0.73298 0.662853 0.152857 0.686924 0.703664 0.18164
--0.284726 -0.260999 0.922394 -0.571962 -0.784995 0.237995 -0.573067 -0.796486 0.192884
--0.621233 -0.762161 0.182152 0.938767 -0.287472 0.18994 -0.981345 0.178831 0.0705833
-0.803877 -0.572697 0.160625 0.832671 -0.512363 0.210101 -0.544894 -0.838298 0.0186288
--0.480725 -0.876849 0.00632533 0.994235 0.0699282 0.081284 -0.973598 0.122971 -0.192316
-0.738164 0.649585 -0.182081 0.860037 0.474696 -0.187086 -0.991592 -0.0517088 0.118626
-0.961565 0.272979 -0.0295963 -0.799181 0.592106 -0.103538 -0.967347 0.190745 -0.166901
--0.911891 -0.333191 -0.239664 0.860748 0.472624 0.189049 0.865778 0.469974 0.171908
-0.863642 0.474633 0.169839 0.114888 0.0774826 0.990352 -0.7072 -0.65397 0.268685
--0.693397 -0.690052 0.207434 -0.602114 -0.772772 0.200705 0.965312 -0.182386 0.186835
--0.994258 0.089038 0.0593587 0.750582 -0.592685 0.292147 -0.397157 -0.917569 -0.0182601
--0.388419 -0.921292 -0.0187255 -0.450752 -0.892649 0 0.929841 0.356706 0.0903121
--0.39972 -0.799439 0.448466 -0.0508834 -0.85371 0.518257 -0.692984 0.694726 -0.192689
-0.0248318 0.980858 -0.193137 0.162674 0.967991 -0.191129 0.662743 0.717365 -0.214845
--0.984132 -0.176639 0.0168228 0.856534 0.514883 -0.0352879 0.936277 0.349317 -0.0369269
--0.942913 -0.331188 0.035067 0.403378 0.541117 0.737887 0.994668 0.0219412 0.100767
--0.704075 -0.656962 0.26959 -0.603306 -0.784298 0.14456 -0.724981 -0.660808 0.194253
-0.981579 0.0849699 0.17112 -0.998223 0 0.0595954 0.727857 -0.618455 0.296204
-0.0147027 -0.940973 0.338162 0.0770382 -0.969719 0.231757 0.582397 -0.804078 0.119466
-0.66045 -0.737666 0.140195 -0.582227 -0.812493 0.0294295 -0.179542 -0.980125 -0.0843751
-0.229626 -0.971496 -0.0588786 0.08238 -0.99386 -0.073869 -0.01356 -0.997112 -0.0747306
--0.00279177 -0.997221 -0.0744473 -0.178722 -0.983813 -0.0130727 -0.416589 -0.909073 0.00627838
-0.765165 0.633543 0.114658 0.792715 0.598654 0.114961 -0.575386 -0.405201 0.710453
--0.0360068 -0.711135 0.702133 0.631299 -0.26971 0.72713 0.13398 0.973679 -0.184389
--0.786589 -0.587223 -0.190908 0.683335 0.729251 -0.0352922 0.72863 0.683751 -0.0397755
--0.798233 -0.578233 0.168732 -0.866879 -0.482376 0.125837 0.323581 -0.942908 0.0788656
--0.502939 -0.858277 0.102046 0.973728 0.156552 0.165366 -0.998223 0 0.0595954
-0.777952 0.529219 -0.3387 0.749279 0.613653 -0.249019 0.309423 0.948679 -0.0653135
-0.20013 0.979296 0.0304582 0.089334 0.982674 0.162392 -0.235125 0.953014 0.190998
--0.546514 0.805437 0.229332 -0.568801 0.78387 0.249027 0.485678 -0.857445 0.170016
--0.159158 -0.968464 0.191691 -0.636435 -0.766822 0.0832775 0.799041 0.585829 0.135416
--0.0232585 -0.424468 0.905144 0.756611 0.346981 0.554206 -0.707849 -0.671763 -0.218369
--0.847774 -0.51472 -0.127839 -0.656344 -0.725433 -0.207267 0.407615 0.912807 0.0251809
-0.530167 0.847803 -0.012388 -0.558937 -0.792326 0.24456 -0.621979 -0.753065 0.214559
-0.322649 0.875361 -0.360058 0.278898 0.756639 -0.591366 -0.26714 0.252299 -0.930044
--0.327934 0.213539 -0.92025 -0.509336 -0.0836223 -0.856495 -0.744883 -0.440047 -0.501506
--0.865884 -0.368839 -0.337938 0.974931 0.158911 0.155747 -0.998223 0 0.0595954
-0.886257 -0.418595 -0.198309 -0.819473 -0.281649 0.499138 -0.916385 -0.078894 0.392447
--0.898507 -0.211238 0.384791 0.989082 -0.0196767 0.146045 0.938853 0.309822 0.150217
--0.784379 -0.182088 0.592953 0 -0.471215 0.882018 0.604551 -0.453413 0.654931
--0.170221 -0.958912 0.226962 0.340323 0.850809 0.400381 0.0535363 0.963654 0.261733
-0.322316 0.799344 0.507111 0.240544 0.955847 0.168803 0.119379 0.967217 0.224141
-0.0841203 0.96101 0.263407 0.242414 0.965428 0.0958381 -0.667303 -0.696589 0.263574
--0.78311 -0.594693 0.181875 -0.583646 -0.781176 0.221631 0.418615 0.897032 0.141753
-0.409875 0.900101 0.147717 0.327479 0.936939 0.122079 -0.0806806 0.996095 0.035858
--0.478523 0.849237 -0.223185 -0.616534 0.561904 -0.551498 -0.560483 0.552552 -0.616884
-0.43921 0.380418 -0.813865 0.323313 0.0668923 -0.943925 0.281222 0.55646 -0.781836
--0.414636 -0.763803 -0.494653 -0.560148 -0.737139 -0.37797 -0.491984 -0.242527 -0.836141
--0.484683 -0.846938 -0.218583 0.972022 0.172729 0.159181 -0.982641 0.175995 0.0586652
-0.524648 -0.851137 -0.0176141 0.283137 -0.958311 0.0383739 -0.286332 -0.94321 0.16843
--0.486938 -0.844547 0.222782 -0.889608 -0.255526 0.378556 0.959574 -0.242135 0.143488
-0.882036 -0.450006 0.139671 -0.742364 0.593891 0.310143 0.918054 0.0612036 0.391703
--0.299391 -0.953943 -0.0189158 -0.408799 -0.907228 -0.0991028 -0.149332 -0.981512 0.119729
--0.188888 -0.969078 0.158775 -0.214925 -0.965081 0.149754 -0.06556 -0.971108 0.22946
-0.891861 0.0964174 0.441913 0.942344 -0.105825 0.317474 -0.98989 0.00856306 0.141576
-0.574859 0.817835 0.0261383 0.550082 0.833389 0.0536054 0.453329 0.880641 0.137707
--0.874919 -0.271263 -0.401164 -0.337804 -0.855989 -0.391372 -0.25232 -0.820983 -0.512173
--0.290521 -0.933019 -0.212304 0.972073 0.177141 0.153934 -0.929024 0.353084 0.110664
-0.180625 -0.981099 0.0694205 0.0125628 -0.995155 0.0975114 -0.158983 -0.977415 0.139228
--0.314324 0.679726 0.662701 0.0455877 0.747638 0.662541 -0.27552 0.74046 0.613032
--0.470453 0.623969 0.623969 0.852567 0.518954 0.0617802 0.078002 0.972492 0.219486
--0.282537 0.936832 0.206202 0.0781423 0.967762 0.239436 0.290705 0.935707 0.19986
-0.162957 0.972994 0.163484 -0.649065 0.740365 0.174855 -0.859571 0.508927 0.0461662
-0.938298 -0.295476 0.179694 -0.323151 -0.799539 0.506271 0.539562 -0.756329 0.369918
-0.0591047 -0.990004 0.12806 -0.447683 0.826491 0.34131 -0.372896 0.864362 0.337382
--0.623361 -0.749652 -0.222359 -0.841719 -0.497379 -0.210055 0.923711 -0.300417 0.237713
--0.747978 0.635781 0.190556 0.615968 0.782256 -0.0930588 0.645985 0.760378 -0.0672901
--0.924648 -0.344908 -0.161446 0.982172 0.0879557 0.166139 -0.93006 0.340688 0.137551
--0.468715 0.338517 0.815912 0.998236 -0.0576002 -0.0143583 -0.338731 0.193561 0.920758
--0.981036 -0.193008 -0.0177724 0.970405 -0.193783 0.144095 -0.191495 -0.833568 0.518164
--0.464684 -0.883052 0.0654866 -0.676968 -0.734808 0.0421014 -0.0893582 -0.994723 0.0504072
--0.0905864 -0.990233 0.10598 -0.180049 -0.978796 0.0976737 0.527412 -0.846036 0.0778419
-0.750225 -0.653257 0.102071 -0.877754 0.455368 -0.148952 0.615922 -0.74676 0.250977
-0.408844 -0.906834 0.102467 -0.738009 0.654412 0.164583 -0.228873 0.972709 -0.0381454
-0.337487 0.935758 -0.102269 0.581949 0.807511 -0.0962396 -0.913794 -0.406131 -0.0061535
--0.90515 -0.419733 0.0672855 0.985993 0 0.166785 -0.973323 0.159799 0.164642
-0.893689 -0.438371 -0.0956583 0.734908 -0.666249 -0.126582 -0.34802 -0.912492 0.215037
-0 -0.9837 0.179816 -0.256757 -0.960868 0.103963 -0.534985 -0.841855 0.0712107
-0.992076 0.0888426 0.0888426 -0.77454 -0.580905 0.250276 -0.731025 -0.629021 0.264453
--0.151516 -0.925564 0.346949 0.144294 -0.945232 0.292771 0.0801606 -0.921847 0.379173
--0.0369768 -0.90593 0.421809 -0.288508 -0.601059 0.745313 -0.0283629 -0.855615 0.516835
-0.630647 -0.667527 0.395845 0.752454 -0.620057 0.222132 -0.859289 -0.492892 0.136672
--0.858604 -0.506671 0.0779977 0.78356 -0.609436 0.12092 0.773686 -0.613753 0.157216
--0.83706 0.506832 -0.206039 0.397346 -0.914024 0.0817053 0.640441 -0.765318 0.0642225
-0.626561 -0.775742 0.0751431 -0.904265 -0.368404 0.215833 0.985993 0 0.166785
--0.985993 0 0.166785 0.127883 -0.989553 -0.0665629 -0.234956 -0.971224 0.0389789
--0.222632 -0.960744 0.165547 -0.0664783 -0.986728 0.148152 0.854386 0.515038 0.0689927
--0.883359 -0.419596 0.208844 0.746926 -0.630354 0.211557 0.391488 -0.897001 0.205246
--0.644467 -0.731907 0.221299 0.74956 -0.643764 0.154037 0.728101 -0.667812 0.154586
--0.84479 0.495855 -0.20114 -0.939313 0.337442 -0.0618315 0.577231 -0.812488 0.0816531
-0.54668 -0.829782 0.112265 0.0757077 -0.791146 0.606924 0.122598 -0.98078 0.151787
--0.935367 -0.344489 0.0801019 0.982172 0.0879557 0.166139 -0.991737 0 0.128284
-0.698525 0.709022 0.0966993 0.709161 0.698746 0.0940498 -0.921047 -0.292973 0.256591
--0.924892 -0.296325 0.238257 0.433101 -0.880099 0.194548 -0.605116 -0.759848 0.237625
-0.759829 -0.631018 0.156451 0.772156 -0.617008 0.151905 -0.968309 -0.239311 0.0714704
-0.526635 -0.840004 0.130571 0.163394 -0.972194 0.167751 -0.29119 -0.934755 0.203569
--0.25437 -0.951374 0.173732 0.796281 -0.566678 0.21169 0.828117 -0.516914 0.216846
--0.183889 -0.981474 0.0537944 -0.320398 -0.946777 0.0309718 0.2411 -0.966844 0.0841678
-0.233528 -0.969895 0.069054 -0.903472 -0.428388 0.0148887 -0.611621 -0.79001 -0.0424737
-0.95884 0.249869 0.134877 -0.995086 0 0.0990135 0.842244 0.527974 0.108947
-0.749169 0.654664 0.100806 -0.763318 -0.501609 0.407103 -0.924073 -0.100311 0.368819
-0.925196 0.201129 0.321807 0.380651 0.827094 0.413547 -0.0736462 0.97213 0.222575
--0.113333 0.988034 0.104615 0.125218 0.990362 0.059194 0.0616862 0.99647 -0.0569411
--0.604642 0.77921 -0.165047 -0.654665 0.737226 -0.167066 0.595467 -0.782614 0.181476
--0.473794 -0.85559 0.208531 -0.6647 -0.724096 0.184008 0.840159 -0.507061 0.192413
--0.64744 -0.761694 -0.0253898 -0.490858 -0.871197 0.00863829 0.167001 -0.983267 0.0727743
--0.236405 -0.971655 0 0.932844 0.333618 0.136021 -0.982641 0.175995 0.0586652
--0.39749 0.0709803 0.914857 0.80754 0.13459 0.574251 -0.39443 0.302396 0.867745
--0.663323 0.151617 0.732813 0.89597 0.443798 0.0167471 -0.912339 -0.180567 0.36747
--0.861592 -0.292516 0.414841 -0.899625 -0.282235 0.333194 0.886292 -0.462413 0.0256896
--0.841918 0.528263 -0.110055 -0.0856621 -0.980355 0.177669 0.73686 -0.653738 0.172233
--0.147438 -0.989063 0.0040955 -0.406043 -0.912823 -0.043394 0.960749 0.239534 0.139946
--0.929024 0.353084 0.110664 -0.320564 0.0674871 0.94482 0.39365 0.919182 -0.0119893
-0.726182 0.68718 -0.0210488 -0.724245 -0.654157 0.218052 -0.449876 -0.736161 0.505646
--0.84227 -0.409501 0.350558 0.746128 -0.664265 -0.0452199 -0.848602 0.516435 -0.114763
--0.352292 -0.935056 -0.0395094 0.922438 -0.359595 0.140711 0.987849 0.0884641 0.127781
--0.934583 0.342345 0.096723 0.257508 0.835331 0.485707 0.0494662 0.831032 0.554021
--0.217452 0.848061 0.483226 0.322634 0.939848 0.112221 0.0790893 0.996705 0.0179748
--0.180111 0.978306 -0.102358 -0.333222 0.928936 -0.161372 0.916886 0.387913 0.0940396
-0.161262 0.983526 0.0816756 0.238774 0.971075 0 -0.777287 -0.606089 0.168764
--0.74616 -0.633307 0.205349 0.776905 -0.629617 -0.00107903 0.762229 -0.64725 0.00859036
--0.872436 0.473766 -0.120006 -0.863423 0.485162 -0.13827 0.901675 0.430157 -0.0441187
-0.983641 0.178108 -0.026986 -0.213526 0.97368 0.0797165 -0.264783 0.957141 0.117354
--0.398744 0.886098 0.236293 0.992076 0.0888426 0.0888426 -0.964809 0.244802 0.0960009
-0.195266 0.78616 0.586365 0.747579 0.615653 0.249193 -0.883377 0.376598 0.278961
--0.841635 0.479792 0.247892 0.631517 0.758482 0.16091 0.509108 0.846123 0.157752
--0.73302 0.640187 -0.229873 -0.985746 0.0789435 -0.148572 0.94526 0.322741 0.0481914
--0.707235 -0.681672 0.18746 -0.749768 -0.638475 0.173774 0.745203 -0.66536 0.0443573
--0.561706 0.6366 -0.528419 -0.843485 0.316307 -0.434147 0.907987 -0.404496 0.109285
--0.869999 -0.39875 0.29 -0.80228 0.566315 -0.188772 0.965174 0.25152 0.0719457
--0.98126 0.175193 0.0802233 0.420999 0.90047 0.109148 0.214094 0.961517 0.172189
-0.177858 0.966364 0.185763 0.289185 0.937659 0.19279 -0.887417 0.371686 0.272656
-0.867886 0.286595 0.405756 0.879213 0.432113 0.200654 0.713733 0.678553 0.173641
--0.743582 -0.659084 -0.112664 0.796122 0.601769 0.0637452 -0.783658 -0.602979 0.149319
--0.730793 -0.660824 0.171037 0.560643 0.824475 -0.076951 0.0938288 0.995588 0.000955
--0.771634 0.635276 0.031711 -0.801444 0.59723 0.031681 0.727177 -0.677801 0.108628
-0.717909 -0.686696 0.11426 -0.403455 -0.14483 -0.903464 -0.754303 -0.258618 -0.603443
--0.739379 -0.285893 -0.609577 -0.902111 0.0674808 -0.426194 0.898344 -0.425962 0.107401
-0.530778 -0.836912 0.133612 -0.654043 -0.744256 0.135319 0.935161 0.334447 0.116703
--0.968373 0.243346 0.0550971 0.271817 -0.888631 -0.369392 0.905576 -0.424178 -0.00248785
--0.898645 0.246485 0.362881 -0.878041 0.269225 0.395679 0.942709 0.00771658 0.333528
-0.944479 0.0718895 0.320611 -0.532907 -0.836714 -0.126171 -0.418588 -0.906668 -0.0523235
-0.688407 0.716801 0.110871 0.762943 0.642586 0.0707184 -0.90686 -0.392522 0.153399
-0.998228 -0.0462258 0.0374804 -0.997735 -0.057916 0.0342231 0.491553 -0.849046 0.193642
--0.451911 -0.891608 0.0284989 -0.72445 -0.678208 -0.123311 -0.154193 -0.90974 -0.385483
-0.521877 -0.84215 0.135751 0.0316642 -0.987177 0.156458 0.94166 0.319294 0.106431
--0.945479 0.321611 0.051337 0.504367 -0.852206 0.139136 0.0773271 -0.947258 0.311004
--0.270119 -0.764532 0.585257 -0.393708 0.51711 0.759994 -0.337067 0.41068 0.847188
--0.511949 0.500043 0.698473 0.749796 0.644924 0.147914 0.372719 0.873962 0.311884
--0.27968 0.925729 0.254567 -0.387366 0.867965 0.31078 -0.209284 0.863295 0.459262
--0.221396 0.846047 0.484962 -0.225881 0.797226 0.55983 -0.22643 0.769375 0.597321
--0.370753 0.750334 0.547303 0.936041 -0.0744578 0.343924 0.22259 -0.926929 0.302087
--0.0853507 -0.971545 0.220943 -0.27938 -0.954058 0.108262 -0.394411 -0.91891 -0.00662875
-0.899368 0.412949 0.143561 0.751775 0.647856 0.122955 -0.938592 -0.319268 0.130814
-0.733675 -0.669384 0.116817 -0.938927 -0.333841 0.0834602 0.137194 -0.968931 0.205791
--0.146459 -0.97814 0.147622 -0.020719 -0.80804 0.588764 0.150539 -0.784057 0.602156
-0.0168332 -0.52183 0.852883 -0.249279 -0.807447 0.534686 0.937562 0.330556 0.108213
-0.942445 0.316493 0.107842 -0.93994 0.336695 0.0561158 0.236437 -0.956391 0.171506
-0.0787831 -0.982312 0.169871 -0.0329484 -0.98484 0.170308 -0.0917315 -0.974491 0.204825
--0.187575 -0.935656 0.298936 -0.22054 -0.803395 0.5531 -0.0340662 0.0170331 0.999274
--0.393818 -0.393818 0.830551 0.120903 -0.70527 0.698553 -0.70527 0.120903 0.698553
--0.671994 -0.186091 0.716794 0.954748 0.168736 0.244917 0.953272 0.197675 0.228465
-0.935294 0.277849 0.219148 -0.580904 0.783082 0.22211 -0.792735 0.0468434 0.607764
--0.94386 0.152858 0.292854 0.667641 0.731633 0.137727 0.784931 0.605469 0.131491
--0.600932 0.348833 0.719164 -0.714862 0.194962 0.671537 0.987926 0.0177048 0.153913
--0.960602 -0.241393 0.137742 0.729484 -0.66932 0.140939 0.173191 -0.899037 0.402166
-0.424978 0.882816 0.200076 0.39292 0.894521 0.21318 -0.103486 0.952782 0.285478
--0.21034 0.893083 0.397692 -0.539139 0.787489 0.298648 -0.0822085 -0.829234 0.552823
-0.935161 0.334447 0.116703 -0.944881 0.32297 0.0537605 -0.223261 -0.458925 0.859967
-0.784895 -0.242509 0.570201 0.829037 -0.138173 0.541854 -0.661083 -0.669713 0.338309
--0.687977 -0.651833 0.319062 0.573134 0.807597 0.138941 0.65065 0.744605 0.149055
--0.9574 -0.109048 0.267382 0.991783 0.117286 0.0510981 -0.951919 -0.257508 0.165949
-0.895763 0.0453551 0.442212 0.912843 0.0370907 0.406624 0.882829 -0.0764655 0.463428
--0.517766 0.534577 0.667941 -0.0185995 0.658955 0.751953 -0.034456 0.955934 0.291551
-0.343907 0.910341 0.230234 0.45066 0.870621 0.197292 -0.777171 0.564647 0.277809
--0.92431 0.299776 0.236187 0.915302 0.380062 0.133326 -0.945479 0.321611 0.051337
-0.61184 0.772478 0.170087 0.0868562 0.959366 0.268465 -0.18378 0.966933 0.176819
--0.0796151 0.987227 0.138 -0.133291 0.911708 0.388616 -0.0562991 0.925181 0.375327
--0.264587 0.841867 0.470376 0.609402 -0.370421 0.701012 -0.666254 -0.674645 0.317743
-0.299222 0.933099 0.199481 0.18655 0.967198 0.172417 0.474731 0.864116 0.167134
--0.969563 -0.217657 0.112126 0.949223 0.314029 0.019032 -0.946577 -0.28256 0.155408
--0.937489 -0.317879 0.141657 0.902487 -0.0638929 0.425952 0.83711 -0.413388 0.358269
-0.403713 0.858964 0.314954 -0.982239 0.010807 0.187322 0.170172 0.96184 0.214256
-0.322634 0.939848 0.112221 0.235282 0.957355 0.167672 -0.251342 0.952172 0.173767
--0.650482 0.757175 0.0596562 0.890888 0.428295 0.151266 0.907316 0.395497 0.142689
--0.916348 0.396628 0.0547073 0.79735 0.601228 -0.0525137 0.816542 0.569431 0.0949051
--0.936468 -0.248335 0.247703 0.622716 0.770025 0.138877 0.639269 0.757837 0.130452
-0.328412 0.921155 0.208854 -0.90309 -0.429338 -0.00986984 0.962071 0.272799 0
-0.952346 0.304588 0.0162447 -0.900467 -0.409868 0.145494 0.882518 -0.468838 -0.0367716
--0.984232 -0.0461571 0.170751 0.756585 0.596597 0.267678 0.734355 0.622262 0.271132
-0.230891 0.935931 0.265936 0.189247 0.96344 0.189657 0.189054 0.962454 0.194782
--0.189464 0.964546 0.183723 -0.487393 0.856514 0.169799 -0.391319 0.904234 0.170972
-0.734944 0.673608 -0.0781624 0.68022 0.730716 -0.0579226 0.216172 0.976324 0.00774349
-0.0927428 0.99513 0.0333874 -0.705545 0.70769 0.0371716 -0.849536 0.263464 -0.457029
--0.909507 0.196297 -0.36642 0.898921 0.414243 0.14263 -0.907331 0.412992 0.0786651
-0.972589 0.00495136 -0.232478 0.963906 0.19031 -0.18619 -0.849418 -0.501891 0.163079
-0.479853 0.870845 0.106634 0.620652 0.778636 0.0922828 -0.847093 -0.529328 -0.0473859
-0.936479 0.350724 0 -0.886935 -0.436849 0.150029 0.979753 -0.188784 -0.0666717
--0.98167 0.0994456 0.162586 0.905524 0.109557 0.409908 0.967228 0.00614113 0.253834
--0.430995 0.889658 0.150838 -0.4468 0.880649 0.157567 -0.423661 0.90028 -0.100031
--0.290129 0.928414 -0.232104 0.462084 0.873942 -0.15068 0.625276 0.769006 -0.132889
--0.676037 -0.730851 -0.0939666 -0.627252 -0.774974 -0.0772701 0.915704 0.380649 0.12881
-0.910762 0.390913 0.133042 -0.94485 0.320375 0.0679584 0.935441 -0.261671 -0.237653
-0.463751 -0.879528 -0.106609 -0.646283 -0.752002 0.129656 -0.833262 -0.528879 0.161124
-0.556124 0.826158 0.0904978 0.545323 0.831994 0.102023 0.496161 0.858403 0.130261
--0.84961 -0.52248 -0.0719597 -0.829593 -0.549583 -0.0986588 0.922822 0.385228 0
--0.904864 -0.404737 0.131941 0.979963 -0.199179 0 -0.988907 0.0111331 0.148118
-0.950273 0.291417 0.109809 0.32035 0.944621 0.0711888 -0.209442 0.977802 -0.00608843
--0.334132 0.942514 0.00479042 -0.417537 0.908529 0.0154643 0.876575 -0.443532 0.186803
--0.372264 0.908099 -0.191772 -0.0882881 0.975584 -0.201101 0.304687 0.935642 -0.178157
--0.435788 -0.896981 0.0742598 -0.528449 -0.84741 0.0513582 0.904864 0.404737 0.131941
--0.94561 0.317556 0.0705679 -0.940309 0.331525 0.0768753 0.328661 -0.943846 0.0337088
--0.130234 -0.985437 0.109332 -0.613055 -0.778677 0.133517 0.737178 0.641024 -0.213675
--0.941726 -0.325287 -0.0856723 0.0731249 0.967077 0.24375 0.0333514 0.9682 0.247945
--0.0491532 0.966679 0.251227 0.950925 0.309421 0 0.935084 0.354427 0
--0.915704 -0.380649 0.12881 0.957916 -0.280314 0.0618193 -0.986087 -0.143278 0.084281
-0.961897 -0.242722 0.125856 -0.567532 0.82305 0.0222562 -0.790305 0.609033 -0.0670562
-0.832218 -0.523935 0.181399 0.668505 -0.724698 0.167072 -0.336249 -0.939275 0.0685467
--0.373255 -0.914115 0.158351 -0.308917 -0.940954 0.13848 -0.346823 -0.931835 0.106756
-0.891109 0.438905 0.115268 -0.909999 0.407034 0.0788965 0.655354 0.472465 -0.589311
-0.715155 0.131873 -0.686413 -0.970202 -0.240965 0.0253648 -0.980567 -0.182926 0.0709014
-0.55495 0.793739 0.249016 0.564847 0.796469 0.215836 -0.74402 0.6392 0.194569
--0.795926 0.597597 0.0968449 0.987001 0.160715 0 -0.910762 -0.390913 0.133042
--0.898921 -0.414243 0.14263 0.9271 -0.356142 0.11683 0.855212 -0.493465 0.158443
--0.966198 -0.256732 -0.0234648 0.835548 -0.538439 0.109282 -0.752948 0.649358 -0.106788
--0.63996 0.734769 -0.224867 0.644276 -0.746059 0.168239 0.421389 -0.893143 0.157251
-0.302968 -0.939202 0.161583 -0.0432635 -0.822006 -0.567833 -0.730952 -0.472755 -0.49215
--0.00879051 -0.959924 -0.280124 -0.0714231 -0.975179 -0.209583 -0.187769 -0.964695 -0.18468
--0.312614 -0.94709 -0.0727582 -0.331391 -0.941849 0.0556724 0.69814 0.679073 0.226847
-0.704182 0.678293 0.209874 0.136649 0.976065 0.169185 -0.782013 0.616988 0.0882119
--0.962902 0.26848 0.0271878 0.87301 0.47564 0.1078 -0.894208 0.440431 0.0800783
-0.58504 0.645561 -0.490896 0.565425 0.565425 -0.60049 0.345295 0 -0.938494
-0.183808 -0.76865 -0.612692 0 -0.87317 -0.487416 0.256686 -0.81284 -0.52288
-0.369262 -0.812376 -0.45132 -0.324628 -0.945655 -0.018819 0.125901 -0.99192 -0.0155877
-0.279469 -0.958763 -0.051678 -0.979733 -0.139762 0.143489 0.842539 -0.401381 0.359194
-0.816503 0.468688 0.337126 0.656996 -0.399171 0.639546 -0.987105 0.151862 -0.0506207
-1 0 0 -0.872008 -0.466563 0.148061 0.62707 -0.777092 0.0539647
-0.618165 -0.784549 0.0485288 -0.925432 -0.311053 -0.216385 -0.912262 -0.334167 -0.236878
-0.834184 -0.540728 0.108402 0.871034 -0.478699 0.110216 -0.603543 0.766511 -0.219538
--0.219701 0.957567 -0.186539 -0.164018 0.973854 -0.157183 -0.109557 0.99348 -0.031539
--0.307155 0.950999 0.035441 0.17421 -0.968971 0.175348 0.166698 -0.972992 0.15968
-0.353095 -0.920885 0.165211 0.54846 -0.822689 0.14958 -0.77583 -0.573902 -0.262153
--0.890532 -0.287568 -0.352502 0.620804 0.64591 0.444301 0.626694 0.663362 0.408907
-0.618814 0.673415 0.404453 0.726395 -0.333287 0.601057 0.229135 -0.910085 0.345316
--0.682228 -0.730959 0.0162435 0.894208 0.440431 0.0800783 -0.907331 0.412992 0.0786651
-0.681032 0.376741 -0.627902 -0.241627 -0.638585 -0.730634 -0.366851 -0.791307 -0.489135
-0.567982 -0.743976 -0.351989 0.601696 -0.75212 -0.268843 0.561811 -0.783055 -0.266819
--0.544378 -0.838636 -0.0185274 -0.466562 -0.881284 -0.0752192 0.821962 -0.557699 -0.115544
-0.99236 -0.0870827 -0.0874017 -0.994794 0.0306877 0.0971778 0.779985 -0.548672 0.300969
-0.314976 -0.926439 0.206159 0.0796151 -0.987227 0.138 -0.118885 -0.990709 0.0660473
-1 0 0 -0.866056 -0.478626 0.144445 -0.876693 -0.463248 0.129658
-0.692094 -0.711521 -0.12142 0.673143 -0.641088 -0.368626 -0.840155 0.228775 -0.491734
--0.794007 0.174681 -0.582271 0.904379 -0.415125 0.0988393 -0.188828 0.964867 -0.182688
--0.540485 0.83688 0.0866467 -0.750966 0.659385 -0.0355224 0.472117 -0.881286 0.020983
--0.689591 -0.678858 -0.252224 -0.76161 -0.58942 -0.269323 0.690456 0.0470766 0.721841
-0.844057 0.19916 0.497899 0.776658 0.44287 0.44796 -0.227808 -0.672703 0.703971
--0.686188 -0.648067 0.330387 -0.470251 -0.853687 0.223791 0.865962 0.49676 0.0577907
--0.94485 0.320375 0.0679584 0.810314 0.450174 -0.375145 -0.385487 -0.416151 -0.82354
--0.124783 -0.945051 -0.302172 -0.435675 -0.89242 -0.117358 0.845825 0.506554 -0.167283
--0.90183 0.432091 -0.00038614 1 0 0 -0.89611 -0.430805 0.106743
-0.933381 0.285803 -0.217065 -0.863862 0.284682 -0.41557 -0.920171 0.288747 -0.264404
-0.909999 -0.407034 0.0788965 -0.76547 0.642157 -0.0411043 -0.682768 0.720467 -0.121474
-0.487663 -0.624719 0.609845 -0.232717 -0.867757 0.439137 0.87627 0.474048 0.0861905
--0.946459 0.317841 0.056505 -0.942007 0.332123 0.0481338 0.477676 0.877509 0.0424601
-0.0474296 0.986536 -0.156518 -0.909538 0.400197 -0.112176 0.665187 0.741896 -0.0843615
-0.837273 0.520343 -0.16798 -0.897915 0.440169 0.000488263 -0.814913 0.579494 0.0102154
-1 0 0 -0.946887 -0.315629 0.0615072 -0.964187 -0.262245 0.0396281
-0.913814 0.396829 -0.0864277 -0.982288 0.0762009 -0.171185 0.88096 -0.463637 0.0945998
--0.765014 0.639602 -0.0752473 -0.938451 0.345317 -0.00812512 0.802708 0.596364 -0.00310001
--0.911935 0.4079 0.0446234 0.405731 0.894223 0.189072 0.330252 0.920704 0.207937
-0.0132112 0.95121 0.308262 -0.855886 0.109428 0.505455 -0.880425 0 0.474186
--0.894675 -0.0378345 0.445112 0.784203 0.615061 0.0820082 0.523255 0.850394 0.0550795
--0.978238 -0.19341 0.0751261 0.748462 0.656814 0.0916485 0.683425 0.727721 -0.0579108
--0.84381 0.536501 -0.0122825 -0.875652 0.482762 -0.0132554 1 0 0
--0.998383 -0.0380227 0.0422474 0.68437 -0.28888 0.669467 0.756813 -0.24925 0.604242
-0.701308 -0.137098 0.699551 -0.622639 0.437793 0.648582 -0.623985 0.339192 0.703983
--0.666768 0.35864 0.653298 0.78887 0.613957 -0.0272198 0.909601 0.407789 -0.0795857
--0.964919 -0.225766 -0.134017 0.874059 -0.476451 0.0949511 0.466345 -0.875391 0.12733
--0.191218 -0.978682 -0.0749441 -0.18324 -0.980797 -0.0667926 0.185905 -0.979727 -0.0746564
-0.206426 -0.976194 -0.0665889 -0.91413 -0.36041 0.185666 -0.392605 0.326002 0.859991
--0.111041 0.142767 0.983508 -0.441563 0.454179 0.773786 -0.493862 0.409681 0.766982
-0.804592 0.572029 0.159418 0.789212 0.592309 0.162218 -0.696034 0.685325 0.214164
--0.671285 0.706616 0.223762 -0.817155 0.547715 0.179627 0.754161 0.651321 0.0837957
-0.77317 0.634173 0.00579153 -0.896946 0.441779 0.0178497 0.862379 0.493586 0.112583
-0.599199 0.783999 0.162192 -0.452839 0.251577 0.855363 -0.832275 -0.488101 0.262824
--0.89702 -0.0967048 0.431281 0.883359 0.462319 0.0770532 -0.887349 -0.450996 0.0959912
-0.627455 0.778103 0.029252 -0.944143 0.328398 -0.0273665 -0.993313 0.0180057 -0.114036
-0.999408 0 -0.0344137 -0.998955 -0.0284287 0.0357992 0.670098 -0.383875 0.635302
--0.640411 0.15137 0.752968 0.682656 0.730145 0.0294609 0.709228 0.704913 -0.00970806
--0.862109 -0.49602 -0.103594 -0.793538 -0.602136 -0.0879165 0.320821 -0.937495 0.13482
-0.0602766 -0.997713 0.0305881 -0.110478 -0.993817 0.0110316 0.467763 -0.883552 0.0230994
-0.402916 -0.895479 0.189144 0.238213 -0.944344 0.226869 -0.786527 -0.566171 0.246628
-0.857732 -0.219715 0.464781 0.859164 -0.271201 0.433921 -0.390518 0.836011 0.385462
--0.0214505 0.87782 0.478511 -0.315553 0.930052 0.188225 0.940861 0.0775968 0.329786
-0.966406 -0.211753 0.145674 -0.816968 -0.576683 0 0.934871 0.354583 0.0169167
--0.877317 0.477987 0.0429295 0.995081 0.0990068 -0.003342 -0.506055 -0.815438 0.281014
--0.580456 -0.792608 0.186665 -0.702755 -0.679441 0.210938 0.873762 0.479722 0.0800368
--0.879136 -0.467433 0.0928828 -0.839357 -0.533423 0.104593 0.792351 0.598665 -0.117385
-0.608994 0.793169 -0.00289584 -0.386139 -0.91992 -0.0681422 -0.501173 -0.864928 -0.0269448
-0.0353772 -0.995515 -0.0877355 0.225014 -0.964347 -0.139295 0.131541 -0.978663 -0.157849
--0.92299 -0.301215 -0.239498 0.994016 0.0808006 -0.0735061 -0.999674 0.0237077 -0.00948307
-0.786206 0.614147 0.0685787 0.745826 0.664091 0.0522191 -0.827312 -0.561551 0.0146811
-0.398312 -0.895884 0.196823 0.890365 -0.257455 0.375455 0.947689 -0.238664 0.211953
--0.311313 0.939372 0.143747 -0.421666 0.893895 0.152152 -0.474223 0.868607 0.143646
-0.783056 -0.613877 0.099896 0.955642 0.293845 0.0201067 0.948216 0.31657 0.0258831
--0.869706 0.493266 0.0173076 0.397071 -0.887569 -0.233571 -0.210322 -0.974072 0.0833535
--0.42977 -0.883827 0.184791 0.817617 0.557814 0.142637 0.870774 0.484908 0.0813462
--0.896909 -0.426012 0.118609 -0.899513 -0.419499 0.122055 0.838843 0.514054 -0.17914
--0.46401 -0.882192 -0.0801993 -0.427994 -0.899229 -0.0905994 -0.449055 -0.888681 -0.0927182
-0.0184781 -0.999355 0.0307968 0.203288 -0.969071 0.139911 0.141264 -0.979215 0.145544
--0.374923 -0.917243 0.134529 -0.648587 -0.760662 0.0269943 0.963864 0.247301 -0.0990371
--0.991303 0.122134 -0.0490118 0.903905 0.418992 0.086033 -0.941562 -0.336377 0.0176268
--0.999317 -0.03624 0.00724799 0.927754 -0.36205 0.0905126 -0.511409 0.843703 0.163175
--0.212154 0.960347 0.180896 -0.00765895 0.967216 0.253839 -0.178031 0.922856 0.341529
--0.812055 0.165164 0.559721 -0.928033 -0.164527 0.334195 0.912076 0.407963 -0.0410359
--0.83404 0.551393 0.0185342 0.893366 0.421589 0.155434 0.885165 0.440939 0.148513
--0.926284 -0.338503 0.165572 0.822803 0.530898 -0.202835 0.843827 0.497414 -0.201334
--0.687959 -0.713822 -0.13104 -0.695958 -0.70123 -0.154657 -0.211188 -0.96277 0.168743
-0.9139 0.395713 -0.0905412 -0.966118 0.249114 -0.0675129 0.943885 0.305949 0.124405
-0.911594 0.4008 0.0914105 -0.933941 0.352142 0.061242 0.919684 -0.392399 0.0143062
-0.916233 -0.400521 0.0100402 -0.471059 -0.203593 0.858285 -0.915223 -0.345325 0.207646
--0.919381 -0.326333 0.219647 0.869706 0.493266 -0.0173076 -0.856248 0.516528 0.00617672
--0.863412 0.5045 0 0.949901 0 0.312551 0.966694 0.133233 0.218522
--0.829007 -0.531972 0.172494 0.854524 0.481433 -0.194963 0.840974 0.507777 -0.186883
--0.696513 -0.697582 -0.168075 -0.691162 -0.703023 -0.167489 0.904852 0.419322 -0.0735652
-0.913292 0.397282 -0.089807 -0.965403 0.252157 -0.0664415 -0.943215 0.327134 -0.0577045
-0.881904 -0.386588 0.269806 0.893837 -0.441355 0.0791225 -0.844528 0.50902 0.166346
-0.886347 -0.463017 0.0020044 -0.0828959 -0.828959 0.553133 -0.804999 -0.542142 0.240952
-0.808104 0.58812 -0.0329227 -0.837432 0.546542 0 0.534473 -0.749104 0.391386
-0.728828 -0.596314 0.336482 -0.379356 -0.895194 0.233918 -0.453989 -0.868649 0.198353
--0.766829 -0.616239 0.179505 0.801561 0.389275 -0.453834 0.674657 -0.500177 -0.542827
--0.273896 -0.903855 -0.328675 -0.502434 -0.846655 -0.175317 0.943631 0.313417 -0.106444
--0.965631 0.253008 -0.0595312 0.480927 -0.874065 0.0687038 0.33854 -0.939856 0.0453944
-0.457787 -0.884002 0.0947145 -0.792912 -0.448754 0.412202 -0.873995 0.430419 0.225547
--0.914481 0.145486 0.37757 -0.924688 0.260226 0.277912 0.705414 -0.705414 0.0691582
--0.559827 -0.828604 -0.00296991 -0.535111 -0.844212 -0.0310209 0.0216605 -0.982702 0.183924
-0.0438133 -0.986753 0.156204 -0.478183 -0.847161 0.231646 0.792308 0.609598 0.0252596
-0.806769 0.590681 -0.014824 -0.821657 0.569983 0 -0.758782 0.651344 0
-0.419925 -0.835832 0.353621 -0.381501 -0.902954 0.197816 0.369933 -0.494845 -0.786307
-0.147043 -0.735215 -0.661693 0.364599 -0.798177 -0.479563 0.0134744 -0.881226 -0.472503
-0.937113 0.329655 -0.114662 0.942484 0.315008 -0.111777 -0.943881 0.312655 -0.106472
-0.708104 -0.689293 0.153176 0.666982 -0.698981 0.257993 -0.652166 -0.652166 0.386469
--0.195227 -0.980728 -0.00765596 0.810902 0.584913 0.0177246 -0.759496 0.650492 -0.00500152
--0.788524 0.61494 -0.00882193 0.902719 0.410994 -0.127212 -0.930072 0.35149 -0.106866
--0.899866 0.424305 -0.101025 0.436202 0.00411512 0.899839 0.534324 0.0360218 0.844512
-0.235431 -0.0692444 0.969421 -0.599185 -0.607869 0.52103 0.812685 0.582424 -0.0180597
--0.835147 0.548455 -0.0415496 0.88482 0.44965 -0.122098 -0.878117 0.462348 -0.123063
-0.806244 0.35495 0.473267 -0.785754 0.522178 0.331542 -0.769256 0.56541 0.297584
-0.924872 -0.305423 -0.226558 0.725795 0.687257 -0.0299738 0.785491 0.618516 -0.0210092
--0.786373 0.615992 -0.0465999 0.851665 0.50546 -0.138482 0.884147 0.450915 -0.122307
--0.869551 0.480897 -0.112332 -0.87569 0.47276 -0.0983109 0.931887 -0.298993 0.2054
--0.774241 0.584113 0.243645 -0.309426 -0.618853 -0.721995 0.376057 0.924474 0.0626762
-0.143217 0.984764 0.0986342 -0.452387 0.891597 0.0200085 -0.542807 0.839708 0.0158348
-0.687566 0.726122 0 0.707008 0.707008 -0.0166846 -0.762011 0.646569 -0.0358951
--0.725795 0.687257 -0.0299738 0.794815 0.590631 -0.13937 0.806362 0.57469 -0.139682
--0.878117 0.462348 -0.123063 0.818428 -0.574589 0.00482848 -0.889982 0.389367 0.237329
--0.942235 0.240827 0.232799 0.949207 0.244655 -0.197863 0.743874 0.66668 -0.0467846
--0.70665 0.698237 -0.114503 0.632487 0.773272 0.0448425 0.666306 0.745471 0.0175922
--0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846 0.799405 0.586597 -0.129831
--0.850808 0.513854 -0.109911 -0.824838 0.555611 -0.104586 0.793489 -0.607421 -0.0376137
-0.702593 -0.711259 -0.0217755 -0.953977 -0.0681412 0.292034 0.968046 -0.154887 -0.197223
--0.70948 0.695059 -0.116324 -0.750326 0.641609 -0.159214 0.780173 0.619123 0.0895342
-0.649066 0.758225 0.0617139 -0.706805 0.706805 -0.0291896 -0.706805 0.706805 -0.0291896
-0.836657 0.530563 -0.136042 0.811074 0.570608 -0.128706 -0.733792 0.668275 -0.122299
-0.567254 -0.815787 0.11276 -0.496535 -0.722233 0.481489 0.915373 -0.377906 -0.138846
-0.909728 -0.394216 -0.130341 -0.77009 0.621238 -0.145001 -0.809467 0.575253 -0.117678
-0.794994 0.605489 0.0369765 0.819705 0.568624 0.0689241 -0.706805 0.706805 -0.0291896
--0.706805 0.706805 -0.0291896 0.789101 0.598476 -0.138368 0.806362 0.57469 -0.139682
--0.702247 0.702247 -0.117041 0.381865 0.816705 0.432633 0.468256 0.784886 0.405822
-0.374228 0.83328 0.406938 0.15149 0.908938 0.388435 0.976021 -0.206743 -0.0681131
--0.837875 0.54286 -0.0571733 -0.825293 0.564318 -0.0209006 0.699576 0.714556 -0.00188929
-0.726079 0.687511 0.011738 -0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846
-0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662 0.972209 0.0920126 0.215275
--0.431596 0.868096 0.245225 0.0797681 0.765773 0.638144 -0.566086 0.804585 0.179415
--0.589585 0.787992 0.177364 0.973088 0.221881 -0.0621977 -0.458034 0.883862 0.0948273
-0.0732056 0.995596 0.0585645 0.532326 0.846239 -0.022555 -0.687257 0.725795 -0.0299738
--0.64644 0.761859 -0.0410583 0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662
-0.959724 0.0239931 0.279919 0.982839 -0.150106 0.107219 0.432905 0.132964 0.891579
--0.388253 0.745925 0.541161 -0.619265 0.76639 0.170755 -0.615557 0.769446 0.170418
-0.510862 0.849929 -0.128996 0.719484 0.682962 -0.126123 -0.631207 0.773877 -0.05188
--0.62591 0.777172 -0.0651199 0.702247 0.702247 -0.117041 -0.598023 0.788504 -0.143633
--0.57469 0.806362 -0.139682 0.805703 -0.523707 0.276721 0.81319 -0.521513 0.258352
-0.547421 0.646952 0.530833 -0.510677 0.805299 0.301169 -0.276292 0.621658 0.732942
--0.797498 0.531665 0.285184 0.834017 0.476581 -0.278006 -0.433011 0.899851 -0.0526229
--0.42302 0.905901 -0.0199538 0.968 -0.23474 0.0887333 0.915018 -0.223407 0.335903
-0.963438 -0.255693 0.0800511 -0.675917 0.724073 0.137311 -0.672087 0.729168 0.128893
-0.952642 0.156456 -0.26076 0.458781 0.873746 -0.161518 0.00928327 0.99994 0.00574678
--0.0698733 0.996454 -0.0468715 0.215983 0.970446 -0.107639 -0.625859 0.77732 -0.0638284
--0.597383 0.801148 -0.0360066 -0.580015 0.813834 -0.0354454 0.702247 0.702247 -0.117041
--0.525649 0.839674 -0.136532 -0.570557 0.811923 -0.123471 0.806603 -0.531971 0.257679
-0.7963 -0.482163 0.365275 0.754212 -0.612311 0.237149 -0.828484 0.49962 0.252972
--0.778659 0.562949 0.27709 -0.803751 0.547575 0.232693 0.972897 0.201475 -0.113487
--0.440032 0.897903 -0.0118928 0.0335315 0.997962 -0.0542891 0.309552 0.950768 0.0147406
--0.0730282 0.994077 0.08048 -0.472144 0.872894 0.123031 -0.445174 0.890348 0.0953944
-0.918071 0.367722 0.148076 -0.607681 0.791702 0.0627037 -0.542928 0.837084 0.0672356
-0.96818 0.142503 -0.205721 -0.504826 0.862411 -0.0373945 -0.512535 0.858496 -0.0170845
-0.629993 0.760337 0.158102 0.146781 0.974779 0.168109 -0.405681 0.901513 0.150658
--0.420219 0.89516 0.148677 0.722843 0.687674 0.0678445 0.702802 0.708286 0.0663365
--0.13555 0.988715 -0.0637881 -0.511905 0.856869 -0.0610642 0.702247 0.702247 -0.117041
--0.593961 0.795024 -0.123073 -0.702247 0.702247 -0.117041 0.831794 -0.521423 0.190361
-0.814657 0.569062 0.111816 0.96461 -0.208999 0.160768 -0.468793 0.882546 0.0366937
--0.254913 0.96691 0.0102551 0.324573 0.933702 -0.151171 -0.396089 0.902252 0.170454
--0.36321 0.928204 0.0807134 0.41152 0.909894 -0.0523878 0.74245 0.669215 -0.0303041
--0.431545 0.896854 0.0970712 -0.647366 0.745287 0.159575 -0.754312 0.641948 0.137538
-0.965728 0.181539 -0.185507 -0.547652 0.836428 -0.0215729 -0.509393 0.860512 -0.00614652
-0.893389 -0.447659 0.0381625 -0.683946 0.72111 0.110537 -0.640153 0.766706 0.0486504
-0.888531 0.45377 0.0678611 -0.708849 0.702835 -0.0596345 -0.974618 0.223189 0.017505
-0.702247 0.702247 -0.117041 -0.702247 0.702247 -0.117041 0.996896 0.0750352 0.0238207
--0.238509 0.971074 0.0113576 0.0596535 0.997654 -0.033598 0.243225 0.957762 -0.153403
-0.0867785 0.995858 -0.0271308 -0.789815 0.600173 0.126428 0.871693 0.460363 -0.167982
--0.500058 0.865992 0 -0.468148 0.88365 0 -0.449818 0.893022 0.01323
-0.678991 -0.734044 -0.0122341 0.542535 -0.837459 -0.065714 -0.5071 0.86187 0.00534493
--0.438332 0.895684 0.0749286 -0.42997 0.899028 0.0829143 0.322186 0.946591 0.0127059
-0.307146 0.950664 -0.0435743 -0.181453 0.967752 -0.174733 -0.14762 0.984136 -0.0984136
-0.673835 0.737049 0.0520059 -0.858604 -0.512637 -0.00168354 0.702247 0.702247 -0.117041
--0.665916 0.731202 -0.147981 0.982715 0.181589 -0.0360245 -0.0643781 -0.981086 -0.182556
--0.1195 -0.979236 -0.163759 0.113419 -0.975399 -0.189031 -0.793613 0.595728 0.123635
--0.709686 0.695789 0.11056 0.563008 0.811297 -0.157541 0.528451 0.835585 -0.150126
-0.814319 0.555351 -0.168733 -0.457502 0.888747 0.0286436 -0.550553 0.834103 0.0340962
--0.574767 0.817704 0.0316554 0.534635 -0.840508 -0.0878206 0.649105 -0.740743 -0.173095
-0.737686 -0.658186 -0.150372 -0.363244 0.915201 0.174532 -0.412962 0.880654 0.232187
--0.105526 0.972834 0.206056 0.169772 0.969818 0.175016 0.204462 0.965997 0.158256
-0.15206 0.975996 0.155917 0.173893 0.978574 0.110246 0.292003 0.955725 0.0363921
--0.856901 -0.512676 -0.0537089 -0.812914 -0.577504 -0.0752371 0.479499 0.871225 -0.10511
-0.562478 0.818834 -0.114587 -0.616715 0.771145 -0.158106 -0.535488 0.82647 -0.173781
-0.670118 0.713468 -0.204708 -0.473457 -0.880601 0.0195039 -0.495026 -0.867695 0.0453174
--0.321311 -0.943506 -0.0809718 0.993584 0.111048 -0.0214302 -0.695781 0.712525 0.0905384
--0.599816 0.800085 -0.00925335 0.682727 0.717103 -0.14017 0.673821 0.719973 -0.166148
--0.626889 0.778445 0.0321482 -0.537073 0.843487 0.00904544 0.858828 -0.496212 -0.127234
--0.915686 -0.391304 -0.0916567 0.624353 0.77943 -0.0516923 0.441226 0.896205 -0.0462237
-0.312499 0.946568 -0.0797052 -0.158298 0.966672 -0.201214 0.624981 0.752234 -0.208669
--0.385295 -0.917935 0.0945696 -0.920835 -0.381253 -0.0819083 0.188245 -0.982101 0.00645411
-0.925438 -0.37178 -0.0731078 0.944088 -0.322686 -0.0676105 -0.653123 -0.748006 0.117973
--0.576251 -0.81473 0.0644219 0.99542 0.0704722 0.0645995 -0.58365 0.811376 -0.0319472
--0.227703 0.961412 -0.154397 0.478233 0.861316 -0.171546 -0.497727 0.867334 0
--0.392374 0.919676 0.0154814 -0.397157 0.917569 0.0182601 0.772741 -0.624267 -0.11473
--0.860065 -0.500567 0.0985965 -0.945583 -0.301323 0.12279 0.36121 -0.916403 0.17243
-0.454101 -0.876765 0.158353 -0.887808 -0.448053 -0.105099 -0.717029 -0.691722 -0.0859632
-0.74326 0.66433 -0.0789303 0.727248 0.684071 -0.0561823 -0.679343 0.71428 -0.168218
-0.160269 0.910797 -0.380476 0.884122 0.424657 -0.194924 -0.856608 -0.48949 0.163163
--0.681658 -0.718998 0.13559 0.989926 0 0.141587 -0.478352 0.878168 0
--0.397157 0.917569 -0.0182601 0.75075 -0.637123 -0.174499 0.685822 0.636443 -0.35297
-0.99177 -0.0627702 -0.111592 0.979575 -0.171037 -0.105732 0.986894 -0.119791 -0.108119
--0.917159 0.374499 0.136269 0.443643 -0.887287 0.126107 -0.12786 -0.991428 -0.0268939
-0.64434 0.759385 -0.090338 0.704894 0.704894 -0.0790535 -0.42833 0.888728 -0.163391
--0.0259677 0.969837 -0.242365 0.850593 0.47778 -0.219586 -0.962319 0.271423 0.0164499
-0.909347 0.199221 0.365238 0.965527 0.200753 0.165701 0.992061 0.0646997 0.107833
--0.321976 0.946552 -0.0192389 -0.326273 0.945081 -0.0192006 -0.175995 0.982641 -0.0586652
-0.0976805 0.993085 -0.0651203 0.183147 0.976783 -0.11114 0.0580726 0.97562 -0.211643
-0.265251 0.89973 -0.346594 0.990571 -0.0466412 -0.128819 -0.910502 0.391643 0.132668
--0.784732 0.617641 0.0521165 0.499462 0.85805 -0.119529 0.615386 0.781235 -0.104747
--0.493157 0.867277 -0.0680217 0.662902 0.745765 0.0662903 -0.800862 0.597836 -0.0348297
--0.82467 0.555207 -0.108002 0.394016 0.910313 -0.12681 0.47473 0.87152 -0.122816
--0.207983 0.974714 -0.0817076 0 0.99922 -0.0394837 0.217662 0.976024 0
--0.78792 0.597133 -0.150381 -0.738577 0.656931 -0.151476 0.335756 0.93732 -0.0932657
-0.325028 0.941474 -0.0893519 0.319809 0.940182 -0.117386 -0.312036 0.934975 -0.168689
-0.0745504 0.984242 -0.160342 0.158075 0.973779 -0.163606 0.0663259 0.99153 -0.111663
-0 0.995211 -0.0977514 0.0882513 0.992617 -0.0832084 0.254057 0.962565 -0.0944677
-
diff --git a/Modules/ImageStatistics/Testing/Data/testNrrd.ascii b/Modules/ImageStatistics/Testing/Data/testNrrd.ascii
deleted file mode 100644
index f78381e84b..0000000000
--- a/Modules/ImageStatistics/Testing/Data/testNrrd.ascii
+++ /dev/null
@@ -1,8 +0,0 @@
-2 2
-2 2
-2 2
-2 2
-1 1
-1 1
-1 1
-1 1
\ No newline at end of file
diff --git a/Modules/ImageStatistics/Testing/Data/testNrrd.nhdr b/Modules/ImageStatistics/Testing/Data/testNrrd.nhdr
deleted file mode 100644
index d62bdcaba6..0000000000
--- a/Modules/ImageStatistics/Testing/Data/testNrrd.nhdr
+++ /dev/null
@@ -1,20 +0,0 @@
-NRRD0005
-content: SomeIDNumber42
-type: short
-dimension: 4
-space: right-anterior-superior
-sizes: 2 2 2 2
-thicknesses: NaN NaN 2.5 NaN
-space directions: (2,0,0) (0,2.5,0) (0,0,2) none
-centerings: cell cell cell none
-kinds: space space space list
-endian: little
-encoding: ascii
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-data file: testNrrd.ascii
-measurement frame: (1,0,0) (0,0,1) (0,1,0)
-modality:=DWMRI
-DWMRI_b-value:=1000
-DWMRI_gradient_0000:= 0 0 0
-DWMRI_gradient_0001:= 1 0 1
\ No newline at end of file
diff --git a/Modules/ImageStatistics/Testing/Data/testimage.dcm b/Modules/ImageStatistics/Testing/Data/testimage.dcm
deleted file mode 100644
index ecf7b12d33..0000000000
Binary files a/Modules/ImageStatistics/Testing/Data/testimage.dcm and /dev/null differ
diff --git a/Modules/ImageStatistics/Testing/Data/vtkUnstructuredGrid.vtk b/Modules/ImageStatistics/Testing/Data/vtkUnstructuredGrid.vtk
deleted file mode 100644
index 392ef94c61..0000000000
Binary files a/Modules/ImageStatistics/Testing/Data/vtkUnstructuredGrid.vtk and /dev/null differ
diff --git a/Modules/MapperExt/Internal/vtkPointSetSlicer.h b/Modules/MapperExt/Internal/vtkPointSetSlicer.h
index c72da5d871..bc3405662f 100644
--- a/Modules/MapperExt/Internal/vtkPointSetSlicer.h
+++ b/Modules/MapperExt/Internal/vtkPointSetSlicer.h
@@ -1,117 +1,116 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _VTKPOINTSETSLICER_H_
#define _VTKPOINTSETSLICER_H_
#include <iostream>
#include "vtkVersion.h"
class vtkCutter;
class vtkPlane;
class vtkPointLocator;
class vtkCell;
class vtkDataArray;
class vtkCellArray;
class vtkPointData;
class vtkCellData;
#include "mitkCommon.h"
-#include "MitkExtExports.h"
#include "vtkPolyDataAlgorithm.h"
class vtkPointSetSlicer : public vtkPolyDataAlgorithm
{
public:
vtkTypeMacro(vtkPointSetSlicer,vtkPolyDataAlgorithm);
void PrintSelf(std::ostream& os, vtkIndent indent);
// Description:
// Construct with user-specified implicit function; initial value of 0.0; and
// generating cut scalars turned off.
static vtkPointSetSlicer *New();
// Description:
// Override GetMTime because we delegate to vtkContourValues and refer to
// vtkImplicitFunction.
unsigned long GetMTime();
// Description
// Specify the implicit function to perform the cutting.
virtual void SetSlicePlane(vtkPlane*);
vtkGetObjectMacro(SlicePlane,vtkPlane);
// Description:
// If this flag is enabled, then the output scalar values will be
// interpolated from the implicit function values, and not the input scalar
// data.
vtkSetMacro(GenerateCutScalars,int);
vtkGetMacro(GenerateCutScalars,int);
vtkBooleanMacro(GenerateCutScalars,int);
// Description:
// Specify a spatial locator for merging points. By default,
// an instance of vtkMergePoints is used.
void SetLocator(vtkPointLocator *locator);
vtkGetObjectMacro(Locator,vtkPointLocator);
// Description:
// Create default locator. Used to create one when none is specified. The
// locator is used to merge coincident points.
void CreateDefaultLocator();
protected:
vtkPointSetSlicer(vtkPlane* cf = 0);
~vtkPointSetSlicer();
virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
virtual int FillInputPortInformation(int port, vtkInformation *info);
void UnstructuredGridCutter(vtkDataSet *input, vtkPolyData *output);
void ContourUnstructuredGridCell(vtkCell* cell,
vtkDataArray* cellScalars, vtkPointLocator* locator,
vtkCellArray* verts, vtkCellArray* lines,
vtkCellArray* polys, vtkPointData* inPd,
vtkPointData* outPd, vtkCellData* inCd,
vtkIdType cellId, vtkCellData* outCd);
vtkPlane *SlicePlane;
vtkCutter *Cutter;
vtkPointLocator *Locator;
int GenerateCutScalars;
private:
vtkPointSetSlicer(const vtkPointSetSlicer&); // Not implemented.
void operator=(const vtkPointSetSlicer&); // Not implemented.
static int edges[12][2];
typedef int EDGE_LIST;
typedef struct {
EDGE_LIST edges[8];
} POLY_CASES;
static POLY_CASES polyCases[256];
};
#endif /* _VTKPOINTSETSLICER_H_ */
diff --git a/Modules/OpenCL/Documentation/doxygen/MitkOpenCL.dox b/Modules/OpenCL/Documentation/doxygen/MitkOpenCL.dox
index e4f3b34e03..0ca4d070e5 100644
--- a/Modules/OpenCL/Documentation/doxygen/MitkOpenCL.dox
+++ b/Modules/OpenCL/Documentation/doxygen/MitkOpenCL.dox
@@ -1,49 +1,49 @@
/**
\page MitkOpenCL_Example Examples
This is a list of available examples:
- \subpage MitkOpenCL_BinaryThresholdFilter
*/
/**
\page MitkOpenCL_Overview The MITK OpenCL Module
The MITK OpenCL Module provides a basic class structure to allow usage of OpenCL-accelerated parallel computing.
<h1> Build Instructions </h1>
The MITK OpenCL module needs an OpenCL Device ( most likely a graphics card, but works also on some CPUs ) and the corresponding driver. Furthermore the OpenCL library and the headers are needed. A list of supported hardware is provided by <a href="http://www.khronos.org/conformance/adopters/conformant-products#topencl"> Khronos.org </a>. For the driver and the libraries please look at the support pages of the hardware manufacturer. Quick Links to the most likely of them:
- <a href="https://developer.nvidia.com/opencl"> NVIDIA OpenCL Page </a>
- <a href="http://www.amd.com/de/products/technologies/stream-technology/opencl/pages/opencl.aspx"> AMD/ATI OpenCL Page </a>
- <a href="http://software.intel.com/en-us/vcsource/tools/opencl-sdk"> Intel OpenCL SDK </a>
To activate the module, you have to activate the CMake option
\verbatim
MITK_USE_OpenCL
\endverbatim
The build system tries to find the OpenCL library and the include path automatically. If this attempt failes, you will be prompted to manually specify following variables:
\verbatim
-OpenCL_INCLUDE_DIR
-OpenCL_LIBRARY
+OPENCL_INCLUDE_DIRS
+OPENCL_LIBRARIES
\endverbatim
<h1> Detailed description </h1>
For own implementations, the OpenCL Module allows for building up a filtering pipeline in MITK Style ( see more in \ref PipelineingConceptPage ). The OpenCL filter can be simply connected also to an existing MITK image filtering pipeline since the mitk::OclImageToImageFilter provide a SetInput and GetOutput methods expecting an mitk::Image and returning it respectively.
<h1> Examples </h1>
Here is a list of \subpage MitkOpenCL_Example "examples":
- \ref MitkOpenCL_BinaryThresholdFilter
*/
diff --git a/Modules/Overlays/CMakeLists.txt b/Modules/Overlays/CMakeLists.txt
index 8e485ba7e4..9e84619f32 100644
--- a/Modules/Overlays/CMakeLists.txt
+++ b/Modules/Overlays/CMakeLists.txt
@@ -1,21 +1,8 @@
-# unused variable found in qt src related to bug-16780 on osx using the compiler: Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) Target: x86_64-apple-darwin12.4.0
-
-# In file included from /Users/Cordes/developing/src/MITK-Master/Modules/Overlays/QmitkScalarBar.cpp:20:
-# In file included from /Users/Cordes/dartclients/toolkits/qt-4.8.4-Build/include/QtGui/QPaintEvent:1:
-# In file included from /Users/Cordes/dartclients/toolkits/qt-4.8.4-Build/include/QtGui/qevent.h:52:
-# /Users/Cordes/dartclients/toolkits/qt-4.8.4-Build/include/QtGui/qmime.h:119:10: error: private field 'type' is not used [-Werror,-Wunused-private-field]
-# char type;
-# ^
-# 1 error generated.
-
-# start fix for the module Overlays
-
-if(APPLE)
- mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unused-private-field" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
-endif()
-
-# end fix
-
-MITK_CREATE_MODULE(DEPENDS MitkQtWidgets
+MITK_CREATE_MODULE(DEPENDS MitkCore
WARNINGS_AS_ERRORS
)
+
+# build tests?
+if(BUILD_TESTING)
+ add_subdirectory(Testing)
+ENDIF()
diff --git a/Core/Documentation/Doxygen/Concepts/Overlays.dox b/Modules/Overlays/Documentation/doxygen/OverlaysModule.dox
similarity index 54%
copy from Core/Documentation/Doxygen/Concepts/Overlays.dox
copy to Modules/Overlays/Documentation/doxygen/OverlaysModule.dox
index 0fb9ad3b1f..282f67eed5 100644
--- a/Core/Documentation/Doxygen/Concepts/Overlays.dox
+++ b/Modules/Overlays/Documentation/doxygen/OverlaysModule.dox
@@ -1,136 +1,82 @@
/**
-\page OverlaysPage Overlays and Annotations Concepts
+\page OverlaysModulePage Overlays and Annotations Module
\tableofcontents
-\section OverlaysPage_Introduction Overlays and Annotations
+\section OverlaysModulePage_Introduction Overlays and Annotations
The overlays in MITK are a simple way to display additional information on the render windows. A class, deriving from mitk::Overlay represents an arbitrary
2D or 3D object that can be rendered as an overlay. This can for example be used for the annotation of 3D points or to overlay despriptions in the window corners.
The mitk::OverlayManager is used to add the overlays to the renderwindows, updating them and manage the respective layout managers.
The following features are implemented in this framework.
<ol>
<li>Definition of graphical elements that can be displayed in the render windows.
<li>It is possible to manage multiple elements in each window.
<li>A single Overlay can be rendered on any number of available render windows.
<li>2D and 3D textelements are already defined in the Overlay module and are using VTK to create custom annotations.
<li>The mitk::BaseLayouter interface enables the implementation of layout managers, to handle the placement of the overlays.
</ol>
-\section OverlaysPage_ArchitectureSection General Architecture
-
-\dot
-digraph linker_deps {
- node [shape=record, fontname=Helvetica, fontsize=10];
- BR [ label="BaseRenderer" ];
- BL [ label="{BaseLayouter|+ArrangeOverlays()}" ];
- O [ label="{Overlay|-PropertyList|+RemoveOverlay(BaseRenderer*)\n+UpdateOverlay(BaseRenderer*)\n+RemoveOverlay(BaseRenderer*)}" ];
- OM [ label="{OverlayManager|+AddOverlay(Overlay*)\n+RemoveOverlay(Overlay*)}" ];
- TO [ label="TextOverlay" ];
- VTKO [ label="{vtkOverlay|#GetVtkActor()}" ];
- TO -> VTKO;
- VTKO -> O;
- OM -> O [style="dashed",label="manages"];
- OM -> BL [style="dashed"];
- OM -> BR [style="dashed"];
- BR -> OM [style="dashed"];
-}
-\enddot
-
-The mitk::Overlay can be implemented using a custom rendering framework like VTK. In this diagram, the vtkOverlay is shown as the superclass for all Overlays which use the vtk framework for rendering.
-The OverlayManager can be registered to several BaseRenderer instances in order to call the update method of each Overlay during the rendering phase of the renderer.
-It also manages the respective Layouters which are used to manage the placement of a group of Overlays.
-
-\subsection OverlaysPage_OverlaySubsection Overlay
-
-The mitk::Overlay is an abstract class that can manage property lists like the mitk::DataNode and provides the interfaces to thr three methods
-mitk::Overlay::AddOverlay, mitk::Overlay::UpdateOverlay and mitk::Overlay::RemoveOverlay. The subclasses of the mitk::Overlay have to implement these methods
-in order to provide the functionallity of an overlay. There are already a few implementations of mitk::Overlay which are using VTK as a rendering
-framework to display the Overlays. However the mitk::Overlay can also be implemented using OpenGL to draw the Overlay on the renderwindows.
-
-\subsection OverlaysPage_OverlayManagerSubsection OverlayManager
-
-The mitk::OverlayManager is the manager for a set of Overlays and the respective Layouters.
-Before the manager can be used, all mitk::BaseRenderer have to be registered to the mitk::OverlayManager instance like this:
-
-\snippet OverlayExample.cpp CreateOverlayManager
-
-The mitk::OverlayManager can then be used anywhere in the program by fetching it as follows:
-
-\snippet OverlayExample.cpp GetOverlayManagerInstance
-
-All mitk::Overlay instances can now be added to the OverlayManager by calling mitk::OverlayManager::AddOverlay.
-
-\subsection OverlaysPage_LayouterSubsection Layouter
-
-In order to use Layouters for the positioning
-of the Overlays, each Layouter object that has been created has to be added to an internal list in the OverlayManager:
-
-\snippet OverlayExample.cpp AddLayouter
-
-The mitk::OverlayManager::SetLayouter method can then be used to configure an Overlay to be positioned by a certain Layouter:
-
-\snippet OverlayExample.cpp SetLayouterToOverlay
-
-\section OverlaysPage_UsageSection Usage of Predefined Overlays
+\section OverlaysModulePage_ArchitectureSection General Architecture
+\section OverlaysModulePage_UsageSection Usage of Predefined Overlays
-\subsection OverlaysPage_TextWidget2DUsageSubsection mitkTextOverlay2D
+\subsection OverlaysModulePage_TextWidget2DUsageSubsection mitkTextOverlay2D
This exemplary overlay can render UTF-8 encoded text as a 2D Overlay. The Overlay2DLayouter can be used to automatically place a group of overlays to a
specific corner.
\snippet OverlayExample.cpp TextOverlay2D
\snippet OverlayExample.cpp SetLayouterToOverlay
-\subsection OverlaysPage_TextWidget3DUsageSubsection mitkTextOverlay3D
+\subsection OverlaysModulePage_TextWidget3DUsageSubsection mitkTextOverlay3D
This overlay displays labels in 3D coordinates. The labels always face the camera.
\snippet OverlayExample.cpp TextOverlay3D
-\subsection OverlaysPage_NotManagedSubsection Manually Managed Overlays
+\subsection OverlaysModulePage_NotManagedSubsection Manually Managed Overlays
In order to integrate an Overlay into an mitk::Mapper, it is advised not to use the OverlayManager but to manually manage the Overlay.
To do so, the update methods of the overlays have to be called manually before the start of each rendering procedure. It must only be called if the Properties have changed or if your custom overlay implements its own rendering mechanism.
-\section OverlaysPage_CustomOverlaySection Implement a Custom Overlay
+\section OverlaysModulePage_CustomOverlaySection Implement a Custom Overlay
A new custom Overlay should derive from mitkOverlay or one of the later mentioned subclasses VtkOverlay2D oder VtkOverlay3D. There should always be an implementation for the methods
AddOverlay, RemoveOverlay and Update Overlay.
UpdateOverlay is the procedure that is called in each rendering step. If the Overlay is rendered by VTK, this method only applies the properties to the representation.
If the custom Overlay requires additional properties, they should be made accessible by getters and setters for a better usability:
\code
void mitk::VtkOverlay3D::SetPosition3D(Point3D position3D, mitk::BaseRenderer *renderer)
{
mitk::Point3dProperty::Pointer position3dProperty = mitk::Point3dProperty::New(position3D);
SetProperty("Position3D", position3dProperty,renderer);
}
mitk::Point3D mitk::VtkOverlay3D::GetPosition3D(mitk::BaseRenderer *renderer)
{
mitk::Point3D position3D;
GetPropertyValue<mitk::Point3D>("Position3D", position3D, renderer);
return position3D;
}
\endcode
-\subsection OverlaysPage_CustomVTK2DOverlaySubsection VTK 2D Overlay
+\subsection OverlaysModulePage_CustomVTK2DOverlaySubsection VTK 2D Overlay
VTK based overlays which are meant to be displayed in 2D over the render window should derive from the mitk::VtkOverlay2D.
The mitk::VtkOverlay2D is a subclass of Vtk::Overlay, that uses VTK to render the overlay. This class creates the Overlay representation as a vtkActor2D, and is very easy to implement
because only UpdateVtkOverlay2D and GetVtkActor2D have to be implemented. The add, update and remove methods are implemented in the superclasses.
UpdateVtkOverlay2D only needs to apply the specific properties and GetVtkActor2D simply returns the created vtkActor.
-\subsection OverlaysPage_CustomVTK3DOverlaySubsection VTK 3D Overlay
+\subsection OverlaysModulePage_CustomVTK3DOverlaySubsection VTK 3D Overlay
The mitkVtkOverlay3D works just like mitkVtkOverlay2D, but it is designed for arbitrary 3D objects which derive from vtkProp,
-\section OverlaysPage_CustomLayouterSection Implement a Custom Layouter
+\section OverlaysModulePage_CustomLayouterSection Implement a Custom Layouter
A Layouter is used for an automatic positioning of a group of Overlays and is derived from mitkBaseLayouter. Every Layouter that manages a group of Layouts should have a unique identifier
which is used to register the Layouter in the OverlayManager. A Layouter is always uniquely defined by the identifier and one BaseRenderer. Before a Layouter can be used by the
OverlayManager it has to be added, using the AddLayouter Method. An Overlay can then be added to a Layout as follows:
\code
overlayManager->SetLayouter(textOverlay.GetPointer(),mitk::Overlay2DLayouter::STANDARD_2D_TOPLEFT,axialRenderer);
\endcode
A new Layouter has to implement PrepareLayout which should parse the internal Overlay list and set their position as required.
*/
diff --git a/Modules/Overlays/Testing/CMakeLists.txt b/Modules/Overlays/Testing/CMakeLists.txt
new file mode 100644
index 0000000000..30f873f17c
--- /dev/null
+++ b/Modules/Overlays/Testing/CMakeLists.txt
@@ -0,0 +1,36 @@
+MITK_CREATE_MODULE_TESTS()
+
+if(MITK_ENABLE_RENDERING_TESTING) ### since the rendering test's do not run in ubuntu, yet, we build them only for other systems or if the user explicitly sets the variable MITK_ENABLE_RENDERING_TESTING
+mitkAddCustomModuleTest(mitkLabelOverlay3DRendering2DTest mitkLabelOverlay3DRendering2DTest #OverlayTest
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkLabelOverlay3DRendering2DTest.png #corresponding reference screenshot
+)
+
+mitkAddCustomModuleTest(mitkLabelOverlay3DRendering3DTest mitkLabelOverlay3DRendering3DTest #OverlayTest
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkLabelOverlay3DRendering3DTest.png #corresponding reference screenshot
+)
+
+mitkAddCustomModuleTest(mitkTextOverlay2DRenderingTest_ball mitkTextOverlay2DRenderingTest #OverlayTest
+ ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay2DRenderingTest_ball.png #corresponding reference screenshot
+)
+
+#mitkAddCustomModuleTest(mitkTextOverlay2DLayouterRenderingTest_ball mitkTextOverlay2DLayouterRenderingTest #OverlayTest
+# ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
+# -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay2DLayouterRenderingTest_ball.png #corresponding reference screenshot
+#)
+
+mitkAddCustomModuleTest(mitkTextOverlay3DRendering2DTest_ball mitkTextOverlay3DRendering2DTest #OverlayTest
+ ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay3DRendering2DTest_ball.png #corresponding reference screenshot
+)
+
+mitkAddCustomModuleTest(mitkTextOverlay3DRendering3DTest_ball mitkTextOverlay3DRendering3DTest #OverlayTest
+ ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay3DRendering3DTest_ball.png #corresponding reference screenshot
+)
+
+mitkAddCustomModuleTest(mitkTextOverlay3DColorRenderingTest_ball mitkTextOverlay3DColorRenderingTest #OverlayTest
+ ${MITK_DATA_DIR}/ball.stl #input image to load in data storage
+ -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/mitkTextOverlay3DColorRenderingTest_ball.png #corresponding reference screenshot
+)
+endif()
diff --git a/Modules/Overlays/Testing/files.cmake b/Modules/Overlays/Testing/files.cmake
new file mode 100644
index 0000000000..1ed23e2999
--- /dev/null
+++ b/Modules/Overlays/Testing/files.cmake
@@ -0,0 +1,9 @@
+set(MODULE_CUSTOM_TESTS
+ mitkLabelOverlay3DRendering2DTest.cpp
+ mitkLabelOverlay3DRendering3DTest.cpp
+ mitkTextOverlay2DRenderingTest.cpp
+ mitkTextOverlay2DLayouterRenderingTest.cpp
+ mitkTextOverlay3DRendering2DTest.cpp
+ mitkTextOverlay3DRendering3DTest.cpp
+ mitkTextOverlay3DColorRenderingTest.cpp
+)
diff --git a/Core/Code/Testing/mitkLabelOverlay3DRendering2DTest.cpp b/Modules/Overlays/Testing/mitkLabelOverlay3DRendering2DTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkLabelOverlay3DRendering2DTest.cpp
rename to Modules/Overlays/Testing/mitkLabelOverlay3DRendering2DTest.cpp
diff --git a/Core/Code/Testing/mitkLabelOverlay3DRendering3DTest.cpp b/Modules/Overlays/Testing/mitkLabelOverlay3DRendering3DTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkLabelOverlay3DRendering3DTest.cpp
rename to Modules/Overlays/Testing/mitkLabelOverlay3DRendering3DTest.cpp
diff --git a/Core/Code/Testing/mitkTextOverlay2DLayouterRenderingTest.cpp b/Modules/Overlays/Testing/mitkTextOverlay2DLayouterRenderingTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkTextOverlay2DLayouterRenderingTest.cpp
rename to Modules/Overlays/Testing/mitkTextOverlay2DLayouterRenderingTest.cpp
diff --git a/Core/Code/Testing/mitkTextOverlay2DRenderingTest.cpp b/Modules/Overlays/Testing/mitkTextOverlay2DRenderingTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkTextOverlay2DRenderingTest.cpp
rename to Modules/Overlays/Testing/mitkTextOverlay2DRenderingTest.cpp
diff --git a/Core/Code/Testing/mitkTextOverlay2DSymbolsRenderingTest.cpp b/Modules/Overlays/Testing/mitkTextOverlay2DSymbolsRenderingTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkTextOverlay2DSymbolsRenderingTest.cpp
rename to Modules/Overlays/Testing/mitkTextOverlay2DSymbolsRenderingTest.cpp
diff --git a/Core/Code/Testing/mitkTextOverlay3DColorRenderingTest.cpp b/Modules/Overlays/Testing/mitkTextOverlay3DColorRenderingTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkTextOverlay3DColorRenderingTest.cpp
rename to Modules/Overlays/Testing/mitkTextOverlay3DColorRenderingTest.cpp
diff --git a/Core/Code/Testing/mitkTextOverlay3DRendering2DTest.cpp b/Modules/Overlays/Testing/mitkTextOverlay3DRendering2DTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkTextOverlay3DRendering2DTest.cpp
rename to Modules/Overlays/Testing/mitkTextOverlay3DRendering2DTest.cpp
diff --git a/Core/Code/Testing/mitkTextOverlay3DRendering3DTest.cpp b/Modules/Overlays/Testing/mitkTextOverlay3DRendering3DTest.cpp
similarity index 100%
rename from Core/Code/Testing/mitkTextOverlay3DRendering3DTest.cpp
rename to Modules/Overlays/Testing/mitkTextOverlay3DRendering3DTest.cpp
diff --git a/Modules/Overlays/files.cmake b/Modules/Overlays/files.cmake
index 920488e50e..4f128aa132 100644
--- a/Modules/Overlays/files.cmake
+++ b/Modules/Overlays/files.cmake
@@ -1,16 +1,13 @@
-SET(CPP_FILES
- QmitkCustomWidgetOverlay.cpp
- QmitkOverlay.cpp
- QmitkOverlayController.cpp
- QmitkScalarBar.cpp
- QmitkScalarBarOverlay.cpp
- QmitkTextOverlay.cpp
+set(H_FILES
)
-
-SET(MOC_H_FILES
- QmitkOverlay.h
- QmitkOverlayController.h
- QmitkScalarBar.h
- QmitkScalarBarOverlay.h
+set(CPP_FILES
+ mitkTextOverlay2D.cpp
+ mitkTextOverlay3D.cpp
+ mitkLabelOverlay3D.cpp
+ mitkOverlay2DLayouter.cpp
+ mitkScaleLegendOverlay.cpp
+ mitkLogoOverlay.cpp
+ mitkVtkLogoRepresentation.cxx
)
+
diff --git a/Core/Code/Rendering/mitkLabelOverlay3D.cpp b/Modules/Overlays/mitkLabelOverlay3D.cpp
similarity index 100%
rename from Core/Code/Rendering/mitkLabelOverlay3D.cpp
rename to Modules/Overlays/mitkLabelOverlay3D.cpp
diff --git a/Core/Code/Rendering/mitkLabelOverlay3D.h b/Modules/Overlays/mitkLabelOverlay3D.h
similarity index 97%
rename from Core/Code/Rendering/mitkLabelOverlay3D.h
rename to Modules/Overlays/mitkLabelOverlay3D.h
index 3cc10ce496..585a76a15f 100644
--- a/Core/Code/Rendering/mitkLabelOverlay3D.h
+++ b/Modules/Overlays/mitkLabelOverlay3D.h
@@ -1,116 +1,116 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef LabelOverlay3D_H
#define LabelOverlay3D_H
#include <mitkVtkOverlay3D.h>
#include <mitkLocalStorageHandler.h>
-#include "MitkCoreExports.h"
+#include "MitkOverlaysExports.h"
#include <vtkSmartPointer.h>
class vtkStringArray;
class vtkPolyDataMapper;
class vtkPolyData;
class vtkActor2D;
class vtkProperty2D;
class vtkPointSetToLabelHierarchy;
class vtkLabelPlacementMapper;
class vtkIntArray;
namespace mitk {
class PointSet;
/** \brief Can display a high amount of 3D labels to a PointSet */
-class MITK_CORE_EXPORT LabelOverlay3D : public mitk::VtkOverlay3D {
+class MitkOverlays_EXPORT LabelOverlay3D : public mitk::VtkOverlay3D {
public:
/** \brief Internal class holding the vtkActor, etc. for each of the render windows */
class LocalStorage : public mitk::Overlay::BaseLocalStorage
{
public:
vtkSmartPointer<vtkPolyData> m_Points;
vtkSmartPointer<vtkActor2D> m_LabelsActor;
vtkSmartPointer<vtkIntArray> m_Sizes;
vtkSmartPointer<vtkStringArray> m_Labels;
vtkSmartPointer<vtkLabelPlacementMapper> m_LabelMapper;
vtkSmartPointer<vtkPointSetToLabelHierarchy> m_PointSetToLabelHierarchyFilter;
/** \brief Timestamp of last update of stored data. */
itk::TimeStamp m_LastUpdateTime;
/** \brief Default constructor of the local storage. */
LocalStorage();
/** \brief Default deconstructor of the local storage. */
~LocalStorage();
};
mitkClassMacro(LabelOverlay3D, mitk::VtkOverlay3D);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Set the vector of labels that are shown to each corresponding point3D. The size has to be equal to the provided LabelCoordinates. */
void SetLabelVector(const std::vector<std::string>& LabelVector);
/** \brief Optional: Provide a vector of priorities. The labels with higher priorities will be visible in lower LOD */
void SetPriorityVector(const std::vector<int>& PriorityVector);
/** \brief Coordinates of the labels */
void SetLabelCoordinates(itk::SmartPointer<PointSet> LabelCoordinates);
void PointSetModified(const itk::Object *, const itk::EventObject &);
protected:
/** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */
mutable mitk::LocalStorageHandler<LocalStorage> m_LSH;
virtual vtkProp *GetVtkProp(BaseRenderer *renderer) const;
void UpdateVtkOverlay(mitk::BaseRenderer *renderer);
/** \brief explicit constructor which disallows implicit conversions */
explicit LabelOverlay3D();
/** \brief virtual destructor in order to derive from this class */
virtual ~LabelOverlay3D();
private:
/** \brief The char arrays in this vector are displayed at the corresponding coordinates.*/
std::vector<std::string> m_LabelVector;
/** \brief values in this array set a priority to each label. Higher priority labels are not covert by labels with lower priority.*/
std::vector<int> m_PriorityVector;
/** \brief The coordinates of the labels. Indices must match the labelVector and the priorityVector.*/
itk::SmartPointer<PointSet> m_LabelCoordinates;
unsigned long m_PointSetModifiedObserverTag;
/** \brief copy constructor */
LabelOverlay3D( const LabelOverlay3D &);
/** \brief assignment operator */
LabelOverlay3D &operator=(const LabelOverlay3D &);
};
} // namespace mitk
#endif // LabelOverlay3D_H
diff --git a/Modules/Overlays/mitkLogoOverlay.cpp b/Modules/Overlays/mitkLogoOverlay.cpp
new file mode 100644
index 0000000000..d015c5bc41
--- /dev/null
+++ b/Modules/Overlays/mitkLogoOverlay.cpp
@@ -0,0 +1,180 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkLogoOverlay.h"
+#include <vtkTextProperty.h>
+#include "vtkUnicodeString.h"
+#include <vtkImageMapper.h>
+#include <vtkTextRendererStringToImage.h>
+#include <vtkTextActor.h>
+#include <vtkImageData.h>
+#include <vtkImageMapper.h>
+#include <vtkTextRenderer.h>
+#include <vtkImageData.h>
+#include <vtkImageReader2Factory.h>
+#include <vtkImageReader2.h>
+
+#include <mitkVtkLogoRepresentation.h>
+#include <vtkLogoWidget.h>
+#include <vtkProperty2D.h>
+#include <vtkImageImport.h>
+#include <mbilogo.h>
+
+mitk::LogoOverlay::LogoOverlay()
+{
+ m_readerFactory = vtkSmartPointer<vtkImageReader2Factory>::New();
+ mitk::Point2D offset;
+ offset.Fill(0.03);
+ SetOffsetVector(offset);
+ SetRelativeSize(0.2);
+ SetCornerPosition(4);
+}
+
+
+mitk::LogoOverlay::~LogoOverlay()
+{
+}
+
+mitk::LogoOverlay::LocalStorage::~LocalStorage()
+{
+}
+
+mitk::LogoOverlay::LocalStorage::LocalStorage()
+{
+ vtkImageImport* VtkImageImport = vtkImageImport::New();
+ VtkImageImport->SetDataScalarTypeToUnsignedChar();
+ VtkImageImport->SetNumberOfScalarComponents(mbiLogo_NumberOfScalars);
+ VtkImageImport->SetWholeExtent(0,mbiLogo_Width-1,0,mbiLogo_Height-1,0,1-1);
+ VtkImageImport->SetDataExtentToWholeExtent();
+
+ char * ImageData;
+ // flip mbi logo around y axis and change color order
+ ImageData = new char[mbiLogo_Height*mbiLogo_Width*mbiLogo_NumberOfScalars];
+
+ unsigned int column, row;
+ char * dest = ImageData;
+ char * source = (char*) &mbiLogo_Data[0];;
+ char r, g, b, a;
+ for (column = 0; column < mbiLogo_Height; column++)
+ for (row = 0; row < mbiLogo_Width; row++)
+ { //change r with b
+ b = *source++;
+ g = *source++;
+ r = *source++;
+ a = *source++;
+
+ *dest++ = r;
+ *dest++ = g;
+ *dest++ = b;
+ *dest++ = a;
+ }
+
+ VtkImageImport->SetImportVoidPointer(ImageData);
+ VtkImageImport->Modified();
+ VtkImageImport->Update();
+ m_LogoImage = VtkImageImport->GetOutput();
+
+ m_LogoRep = vtkSmartPointer<mitkVtkLogoRepresentation>::New();
+ m_LogoWidget = vtkSmartPointer<vtkLogoWidget>::New();
+ m_LogoWidget->SetRepresentation(m_LogoRep);
+}
+
+void mitk::LogoOverlay::UpdateVtkOverlay(mitk::BaseRenderer *renderer)
+{
+ LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer);
+ if(ls->IsGenerateDataRequired(renderer,this))
+ {
+
+ ls->m_LogoRep->SetImage(ls->m_LogoImage);
+ ls->m_LogoRep->SetDragable(false);
+ ls->m_LogoRep->SetMoving(false);
+ ls->m_LogoRep->SetPickable(false);
+ ls->m_LogoRep->SetShowBorder(true);
+ ls->m_LogoRep->SetRenderer(renderer->GetVtkRenderer());
+ float size = GetRelativeSize(renderer);
+ ls->m_LogoRep->SetPosition2(size,size);
+ int corner = GetCornerPosition(renderer);
+ ls->m_LogoRep->SetCornerPosition(corner);
+ mitk::Point2D offset = GetOffsetVector(renderer);
+ ls->m_LogoRep->SetPosition(offset[0],offset[1]);
+ float opacity = 1.0;
+ GetOpacity(opacity,renderer);
+ ls->m_LogoRep->GetImageProperty()->SetOpacity(opacity);
+ ls->m_LogoRep->BuildRepresentation();
+ ls->UpdateGenerateDataTime();
+ }
+
+}
+
+void mitk::LogoOverlay::SetLogoImagePath(std::string path)
+{
+ SetStringProperty("Overlay.LogoImagePath", path.c_str());
+ Modified();
+}
+
+std::string mitk::LogoOverlay::GetLogoImagePath() const
+{
+ std::string path;
+ GetPropertyList()->GetStringProperty("Overlay.LogoImagePath", path);
+ return path;
+}
+
+void mitk::LogoOverlay::SetOffsetVector(const Point2D& OffsetVector, mitk::BaseRenderer *renderer)
+{
+ mitk::Point2dProperty::Pointer OffsetVectorProperty = mitk::Point2dProperty::New(OffsetVector);
+ SetProperty("Overlay.OffsetVector", OffsetVectorProperty.GetPointer(),renderer);
+ Modified();
+}
+
+mitk::Point2D mitk::LogoOverlay::GetOffsetVector(mitk::BaseRenderer *renderer) const
+{
+ mitk::Point2D OffsetVector;
+ OffsetVector.Fill(0);
+ GetPropertyValue<mitk::Point2D>("Overlay.OffsetVector", OffsetVector, renderer);
+ return OffsetVector;
+}
+
+void mitk::LogoOverlay::SetCornerPosition(const int &corner, mitk::BaseRenderer *renderer)
+{
+ SetIntProperty("Overlay.CornerPosition", corner, renderer);
+ Modified();
+}
+
+int mitk::LogoOverlay::GetCornerPosition(mitk::BaseRenderer *renderer) const
+{
+ int corner = 0;
+ GetIntProperty("Overlay.CornerPosition",corner,renderer);
+ return corner;
+}
+
+void mitk::LogoOverlay::SetRelativeSize(const float &size, mitk::BaseRenderer *renderer)
+{
+ SetFloatProperty("Overlay.RelativeSize", size, renderer);
+ Modified();
+}
+
+float mitk::LogoOverlay::GetRelativeSize(mitk::BaseRenderer *renderer) const
+{
+ float size = 0;
+ GetFloatProperty("Overlay.RelativeSize",size,renderer);
+ return size;
+}
+
+vtkProp* mitk::LogoOverlay::GetVtkProp(BaseRenderer *renderer) const
+{
+ LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer);
+ return ls->m_LogoRep;
+}
diff --git a/Modules/Overlays/mitkLogoOverlay.h b/Modules/Overlays/mitkLogoOverlay.h
new file mode 100644
index 0000000000..9a5f8e6f1a
--- /dev/null
+++ b/Modules/Overlays/mitkLogoOverlay.h
@@ -0,0 +1,103 @@
+/*===================================================================
+
+ The Medical Imaging Interaction Toolkit (MITK)
+
+ Copyright (c) German Cancer Research Center,
+ Division of Medical and Biological Informatics.
+ All rights reserved.
+
+ This software is distributed WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.
+
+ See LICENSE.txt or http://www.mitk.org for details.
+
+ ===================================================================*/
+
+#ifndef LOGOOVERLAY_H
+#define LOGOOVERLAY_H
+
+#include <mitkVtkOverlay.h>
+#include <mitkLocalStorageHandler.h>
+#include <vtkSmartPointer.h>
+#include "MitkOverlaysExports.h"
+
+class mitkVtkLogoRepresentation;
+class vtkLogoWidget;
+class vtkImageData;
+class vtkImageReader2Factory;
+
+namespace mitk {
+
+/** \brief Displays a logo on the renderwindow */
+class MitkOverlays_EXPORT LogoOverlay : public mitk::VtkOverlay {
+public:
+
+ class LocalStorage : public mitk::Overlay::BaseLocalStorage
+ {
+ public:
+ /** \brief Actor of a 2D render window. */
+ vtkSmartPointer<vtkImageData> m_LogoImage;
+ vtkSmartPointer<mitkVtkLogoRepresentation> m_LogoRep;
+ vtkSmartPointer<vtkLogoWidget> m_LogoWidget;
+
+ /** \brief Timestamp of last update of stored data. */
+ itk::TimeStamp m_LastUpdateTime;
+
+ /** \brief Default constructor of the local storage. */
+ LocalStorage();
+ /** \brief Default deconstructor of the local storage. */
+ ~LocalStorage();
+ };
+
+ mitkClassMacro(LogoOverlay, mitk::VtkOverlay);
+ itkFactorylessNewMacro(Self)
+ itkCloneMacro(Self)
+
+ vtkSmartPointer<vtkImageReader2Factory> m_readerFactory;
+
+ void SetLogoImagePath(std::string text);
+ std::string GetLogoImagePath() const;
+
+ /** \brief The relative offset to the corner position */
+ void SetOffsetVector(const Point2D& OffsetVector, BaseRenderer* renderer = NULL);
+ Point2D GetOffsetVector(mitk::BaseRenderer* renderer = NULL) const;
+
+ /** \brief The corner where the logo is displayed.
+ 0 = Bottom left
+ 1 = Bottom right
+ 2 = Top right
+ 3 = Top left*/
+ void SetCornerPosition(const int& corner, BaseRenderer* renderer = NULL);
+ int GetCornerPosition(mitk::BaseRenderer* renderer = NULL) const;
+
+ void SetRelativeSize(const float &size, BaseRenderer* renderer = NULL);
+ float GetRelativeSize(mitk::BaseRenderer* renderer = NULL) const;
+
+protected:
+
+ /** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */
+ mutable mitk::LocalStorageHandler<LocalStorage> m_LSH;
+
+ virtual vtkProp *GetVtkProp(BaseRenderer *renderer) const;
+ void UpdateVtkOverlay(mitk::BaseRenderer *renderer);
+
+ /** \brief explicit constructor which disallows implicit conversions */
+ explicit LogoOverlay();
+
+ /** \brief virtual destructor in order to derive from this class */
+ virtual ~LogoOverlay();
+
+private:
+
+ /** \brief copy constructor */
+ LogoOverlay( const LogoOverlay &);
+
+ /** \brief assignment operator */
+ LogoOverlay &operator=(const LogoOverlay &);
+
+};
+
+} // namespace mitk
+#endif // LOGOOVERLAY_H
+
diff --git a/Core/Code/Rendering/mitkOverlay2DLayouter.cpp b/Modules/Overlays/mitkOverlay2DLayouter.cpp
similarity index 100%
rename from Core/Code/Rendering/mitkOverlay2DLayouter.cpp
rename to Modules/Overlays/mitkOverlay2DLayouter.cpp
diff --git a/Core/Code/Rendering/mitkOverlay2DLayouter.h b/Modules/Overlays/mitkOverlay2DLayouter.h
similarity index 95%
rename from Core/Code/Rendering/mitkOverlay2DLayouter.h
rename to Modules/Overlays/mitkOverlay2DLayouter.h
index 81856eee5d..bbbfcab04a 100644
--- a/Core/Code/Rendering/mitkOverlay2DLayouter.h
+++ b/Modules/Overlays/mitkOverlay2DLayouter.h
@@ -1,74 +1,74 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKOVERLAY2DLAYOUTER_H
#define MITKOVERLAY2DLAYOUTER_H
-#include <MitkCoreExports.h>
+#include <MitkOverlaysExports.h>
#include <mitkAbstractOverlayLayouter.h>
namespace mitk {
/** @brief A simple implementation of a layouter for 2D Overlays
*/
-class MITK_CORE_EXPORT Overlay2DLayouter : public mitk::AbstractOverlayLayouter {
+class MitkOverlays_EXPORT Overlay2DLayouter : public mitk::AbstractOverlayLayouter {
public:
enum Alignment{TopLeft, Top, TopRight, BottomLeft, Bottom, BottomRight};
mitkClassMacro(Overlay2DLayouter, mitk::AbstractOverlayLayouter);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
static std::string STANDARD_2D_TOPLEFT();
static std::string STANDARD_2D_TOP();
static std::string STANDARD_2D_TOPRIGHT();
static std::string STANDARD_2D_BOTTOMLEFT();
static std::string STANDARD_2D_BOTTOM();
static std::string STANDARD_2D_BOTTOMRIGHT();
/** \brief Factory method for the different kinds of Layouters */
/** Create a Layouter that, depending on the identifier sorts the Overlays in one corner of the Renderwindow*/
static Overlay2DLayouter::Pointer CreateLayouter(Alignment alignment, BaseRenderer* renderer);
/** \brief Factory method for the different kinds of Layouters */
/** Create a Layouter that, depending on the identifier sorts the Overlays in one corner of the Renderwindow*/
static Overlay2DLayouter::Pointer CreateLayouter(const std::string& identifier, BaseRenderer* renderer);
void PrepareLayout();
protected:
/** \brief explicit constructor which disallows implicit conversions */
explicit Overlay2DLayouter();
/** \brief virtual destructor in order to derive from this class */
virtual ~Overlay2DLayouter();
Alignment m_Alignment;
double m_Margin;
private:
/** \brief copy constructor */
Overlay2DLayouter( const Overlay2DLayouter &);
/** \brief assignment operator */
Overlay2DLayouter &operator=(const Overlay2DLayouter &);
};
} // namespace mitk
#endif // MITKOVERLAY2DLAYOUTER_H
diff --git a/Core/Code/Rendering/mitkScaleLegendOverlay.cpp b/Modules/Overlays/mitkScaleLegendOverlay.cpp
similarity index 100%
rename from Core/Code/Rendering/mitkScaleLegendOverlay.cpp
rename to Modules/Overlays/mitkScaleLegendOverlay.cpp
diff --git a/Core/Code/Rendering/mitkScaleLegendOverlay.h b/Modules/Overlays/mitkScaleLegendOverlay.h
similarity index 96%
rename from Core/Code/Rendering/mitkScaleLegendOverlay.h
rename to Modules/Overlays/mitkScaleLegendOverlay.h
index 68f3619f51..22207afaf4 100644
--- a/Core/Code/Rendering/mitkScaleLegendOverlay.h
+++ b/Modules/Overlays/mitkScaleLegendOverlay.h
@@ -1,100 +1,100 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef SCALELEGENDOVERLAY_H
#define SCALELEGENDOVERLAY_H
#include <mitkVtkOverlay.h>
#include <mitkLocalStorageHandler.h>
#include <vtkSmartPointer.h>
-#include "MitkCoreExports.h"
+#include "MitkOverlaysExports.h"
class vtkLegendScaleActor;
namespace mitk {
/** \brief Displays configurable scales on the renderwindow. The scale is determined by the image spacing. */
-class MITK_CORE_EXPORT ScaleLegendOverlay : public mitk::VtkOverlay {
+class MitkOverlays_EXPORT ScaleLegendOverlay : public mitk::VtkOverlay {
public:
class LocalStorage : public mitk::Overlay::BaseLocalStorage
{
public:
/** \brief Actor of a 2D render window. */
vtkSmartPointer<vtkLegendScaleActor> m_legendScaleActor;
/** \brief Timestamp of last update of stored data. */
itk::TimeStamp m_LastUpdateTime;
/** \brief Default constructor of the local storage. */
LocalStorage();
/** \brief Default deconstructor of the local storage. */
~LocalStorage();
};
mitkClassMacro(ScaleLegendOverlay, mitk::VtkOverlay);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
void SetRightAxisVisibility(bool visibility);
bool GetRightAxisVisibility() const;
void SetLeftAxisVisibility(bool visibility);
bool GetLeftAxisVisibility() const;
void SetTopAxisVisibility(bool visibility);
bool GetTopAxisVisibility() const;
void SetBottomAxisVisibility(bool visibility);
bool GetBottomAxisVisibility() const;
void SetLegendVisibility(bool visibility);
bool GetLegendVisibility() const;
void SetRightBorderOffset(int offset);
int GetRightBorderOffset() const;
void SetCornerOffsetFactor(float offsetFactor);
float GetCornerOffsetFactor() const;
protected:
/** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */
mutable mitk::LocalStorageHandler<LocalStorage> m_LSH;
virtual vtkProp* GetVtkProp(BaseRenderer *renderer) const;
virtual void UpdateVtkOverlay(BaseRenderer *renderer);
/** \brief explicit constructor which disallows implicit conversions */
explicit ScaleLegendOverlay();
/** \brief virtual destructor in order to derive from this class */
virtual ~ScaleLegendOverlay();
private:
/** \brief copy constructor */
ScaleLegendOverlay( const ScaleLegendOverlay &);
/** \brief assignment operator */
ScaleLegendOverlay &operator=(const ScaleLegendOverlay &);
};
} // namespace mitk
#endif // SCALELEGENDOVERLAY_H
diff --git a/Core/Code/Rendering/mitkTextOverlay2D.cpp b/Modules/Overlays/mitkTextOverlay2D.cpp
similarity index 100%
rename from Core/Code/Rendering/mitkTextOverlay2D.cpp
rename to Modules/Overlays/mitkTextOverlay2D.cpp
diff --git a/Core/Code/Rendering/mitkTextOverlay2D.h b/Modules/Overlays/mitkTextOverlay2D.h
similarity index 95%
rename from Core/Code/Rendering/mitkTextOverlay2D.h
rename to Modules/Overlays/mitkTextOverlay2D.h
index a1e23233b9..7902853043 100644
--- a/Core/Code/Rendering/mitkTextOverlay2D.h
+++ b/Modules/Overlays/mitkTextOverlay2D.h
@@ -1,86 +1,86 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef TEXTOVERLAY2D_H
#define TEXTOVERLAY2D_H
#include <mitkVtkOverlay2D.h>
#include <mitkLocalStorageHandler.h>
#include <vtkSmartPointer.h>
-#include "MitkCoreExports.h"
+#include "MitkOverlaysExports.h"
class vtkTextActor;
class vtkImageMapper;
class vtkImageData;
namespace mitk {
/** \brief Displays text on the renderwindow */
-class MITK_CORE_EXPORT TextOverlay2D : public mitk::VtkOverlay2D {
+class MitkOverlays_EXPORT TextOverlay2D : public mitk::VtkOverlay2D {
public:
class LocalStorage : public mitk::Overlay::BaseLocalStorage
{
public:
/** \brief Actor of a 2D render window. */
vtkSmartPointer<vtkActor2D> m_textActor;
vtkSmartPointer<vtkImageData> m_textImage;
vtkSmartPointer<vtkImageMapper> m_imageMapper;
/** \brief Timestamp of last update of stored data. */
itk::TimeStamp m_LastUpdateTime;
/** \brief Default constructor of the local storage. */
LocalStorage();
/** \brief Default deconstructor of the local storage. */
~LocalStorage();
};
mitkClassMacro(TextOverlay2D, mitk::VtkOverlay2D);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
virtual Overlay::Bounds GetBoundsOnDisplay(BaseRenderer *renderer) const;
virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds& bounds);
protected:
/** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */
mutable mitk::LocalStorageHandler<LocalStorage> m_LSH;
virtual vtkActor2D* GetVtkActor2D(BaseRenderer *renderer) const;
void UpdateVtkOverlay2D(mitk::BaseRenderer *renderer);
/** \brief explicit constructor which disallows implicit conversions */
explicit TextOverlay2D();
/** \brief virtual destructor in order to derive from this class */
virtual ~TextOverlay2D();
private:
/** \brief copy constructor */
TextOverlay2D( const TextOverlay2D &);
/** \brief assignment operator */
TextOverlay2D &operator=(const TextOverlay2D &);
};
} // namespace mitk
#endif // TEXTOVERLAY2D_H
diff --git a/Core/Code/Rendering/mitkTextOverlay3D.cpp b/Modules/Overlays/mitkTextOverlay3D.cpp
similarity index 100%
rename from Core/Code/Rendering/mitkTextOverlay3D.cpp
rename to Modules/Overlays/mitkTextOverlay3D.cpp
diff --git a/Core/Code/Rendering/mitkTextOverlay3D.h b/Modules/Overlays/mitkTextOverlay3D.h
similarity index 96%
rename from Core/Code/Rendering/mitkTextOverlay3D.h
rename to Modules/Overlays/mitkTextOverlay3D.h
index 065d00b073..78b47ec0e1 100644
--- a/Core/Code/Rendering/mitkTextOverlay3D.h
+++ b/Modules/Overlays/mitkTextOverlay3D.h
@@ -1,90 +1,90 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef TextOverlay3D_H
#define TextOverlay3D_H
#include <mitkVtkOverlay3D.h>
#include <mitkLocalStorageHandler.h>
-#include "MitkCoreExports.h"
+#include "MitkOverlaysExports.h"
class vtkFollower;
class vtkVectorText;
class vtkTextActor3D;
namespace mitk {
/** \brief Displays at 3D position, always facing the camera */
-class MITK_CORE_EXPORT TextOverlay3D : public mitk::VtkOverlay3D {
+class MitkOverlays_EXPORT TextOverlay3D : public mitk::VtkOverlay3D {
public:
/** \brief Internal class holding the mapper, actor, etc. for each of the render windows */
/**
* To render the Overlay on transveral, coronal, and sagittal, the update method
* is called for each renderwindow. For performance reasons, the corresponding data
* for each view is saved in the internal helper class LocalStorage.
* This allows rendering n views with just 1 mitkOverlay using n vtkMapper.
* */
class LocalStorage : public mitk::Overlay::BaseLocalStorage
{
public:
/** \brief Actor of a 2D render window. */
vtkSmartPointer<vtkFollower> m_follower;
vtkSmartPointer<vtkVectorText> m_textSource;
/** \brief Timestamp of last update of stored data. */
itk::TimeStamp m_LastUpdateTime;
/** \brief Default constructor of the local storage. */
LocalStorage();
/** \brief Default deconstructor of the local storage. */
~LocalStorage();
};
mitkClassMacro(TextOverlay3D, mitk::VtkOverlay3D);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
protected:
/** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */
mutable mitk::LocalStorageHandler<LocalStorage> m_LSH;
virtual vtkProp* GetVtkProp(BaseRenderer *renderer) const;
void UpdateVtkOverlay(mitk::BaseRenderer *renderer);
/** \brief explicit constructor which disallows implicit conversions */
explicit TextOverlay3D();
/** \brief virtual destructor in order to derive from this class */
virtual ~TextOverlay3D();
private:
/** \brief copy constructor */
TextOverlay3D( const TextOverlay3D &);
/** \brief assignment operator */
TextOverlay3D &operator=(const TextOverlay3D &);
};
} // namespace mitk
#endif // TextOverlay3D_H
diff --git a/Modules/Overlays/mitkVtkLogoRepresentation.cxx b/Modules/Overlays/mitkVtkLogoRepresentation.cxx
new file mode 100644
index 0000000000..64676280c6
--- /dev/null
+++ b/Modules/Overlays/mitkVtkLogoRepresentation.cxx
@@ -0,0 +1,185 @@
+/*===================================================================
+
+ The Medical Imaging Interaction Toolkit (MITK)
+
+ Copyright (c) German Cancer Research Center,
+ Division of Medical and Biological Informatics.
+ All rights reserved.
+
+ This software is distributed WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.
+
+ See LICENSE.txt or http://www.mitk.org for details.
+
+ ===================================================================*/
+
+#include "mitkVtkLogoRepresentation.h"
+#include "vtkCallbackCommand.h"
+#include "vtkObjectFactory.h"
+#include "vtkPoints.h"
+#include "vtkCellArray.h"
+#include "vtkPolyData.h"
+#include "vtkPolyDataMapper2D.h"
+#include "vtkProperty2D.h"
+#include "vtkActor2D.h"
+#include "vtkPolyData.h"
+#include "vtkTexture.h"
+#include "vtkPolyDataMapper2D.h"
+#include "vtkFloatArray.h"
+#include "vtkPointData.h"
+#include "vtkImageData.h"
+#include "vtkPropCollection.h"
+#include "vtkRenderer.h"
+#include "vtkWindow.h"
+
+
+vtkStandardNewMacro(mitkVtkLogoRepresentation);
+
+//----------------------------------------------------------------------
+inline void mitkVtkLogoRepresentation::AdjustImageSize(double o[2],
+ double borderSize[2],
+ double imageSize[2])
+{
+ // Scale the image to fit with in the border.
+ // Also update the origin so the image is centered.
+ double r0 = borderSize[0]/imageSize[0];
+ double r1 = borderSize[1]/imageSize[1];
+ if ( r0 > r1 )
+ {
+ imageSize[0] *= r1;
+ imageSize[1] *= r1;
+ }
+ else
+ {
+ imageSize[0] *= r0;
+ imageSize[1] *= r0;
+ }
+}
+
+//-------------------------------------------------------------------------
+void mitkVtkLogoRepresentation::BuildRepresentation()
+{
+ if ( this->GetMTime() > this->BuildTime ||
+ (this->Renderer && this->Renderer->GetVTKWindow() &&
+ this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
+ {
+
+ // Determine and adjust the size of the image
+ if ( this->Image )
+ {
+ double imageSize[2], borderSize[2], o[2];
+ imageSize[0] = 0.0;
+ imageSize[1] = 0.0;
+ //this->Image->Update();
+ if ( this->Image->GetDataDimension() == 2 )
+ {
+ int dims[3];
+ this->Image->GetDimensions(dims);
+ imageSize[0] = static_cast<double>(dims[0]);
+ imageSize[1] = static_cast<double>(dims[1]);
+ }
+ int *p1 = this->PositionCoordinate->
+ GetComputedDisplayValue(this->Renderer);
+ int *p2 = this->Position2Coordinate->
+ GetComputedDisplayValue(this->Renderer);
+ borderSize[0] = p2[0];
+ borderSize[1] = p2[1];
+ o[0] = static_cast<double>(p1[0]);
+ o[1] = static_cast<double>(p1[1]);
+
+ // this preserves the image aspect ratio. The image is
+ // centered around the center of the bordered ragion.
+ this->AdjustImageSize(o,borderSize,imageSize);
+
+ // Update the points
+ this->Texture->SetInputData(this->Image);
+ int* size = this->Renderer->GetSize();
+
+ switch(this->cornerPosition)
+ {
+ case 0:
+ {
+ this->TexturePoints->SetPoint(0, o[0],o[1],0.0);
+ this->TexturePoints->SetPoint(1, o[0]+imageSize[0],o[1],0.0);
+ this->TexturePoints->SetPoint(2, o[0]+imageSize[0],o[1]+imageSize[1],0.0);
+ this->TexturePoints->SetPoint(3, o[0],o[1]+imageSize[1],0.0);
+ break;
+ }
+ case 1:
+ {
+ o[0] = size[0]-o[0];
+ this->TexturePoints->SetPoint(0, o[0]-imageSize[0],o[1],0.0);
+ this->TexturePoints->SetPoint(1, o[0],o[1],0.0);
+ this->TexturePoints->SetPoint(2, o[0],o[1]+imageSize[1],0.0);
+ this->TexturePoints->SetPoint(3, o[0]-imageSize[0],o[1]+imageSize[1],0.0);
+ break;
+ }
+ case 2:
+ {
+ o[0] = size[0]-o[0];
+ o[1] = size[1]-o[1];
+ this->TexturePoints->SetPoint(0, o[0]-imageSize[0],o[1]-imageSize[1],0.0);
+ this->TexturePoints->SetPoint(1, o[0],o[1]-imageSize[1],0.0);
+ this->TexturePoints->SetPoint(2, o[0],o[1],0.0);
+ this->TexturePoints->SetPoint(3, o[0]-imageSize[0],o[1],0.0);
+ break;
+ }
+ case 3:
+ {
+ o[1] = size[1]-o[1];
+ this->TexturePoints->SetPoint(0, o[0],o[1]-imageSize[1],0.0);
+ this->TexturePoints->SetPoint(1, o[0]+imageSize[0],o[1]-imageSize[1],0.0);
+ this->TexturePoints->SetPoint(2, o[0]+imageSize[0],o[1],0.0);
+ this->TexturePoints->SetPoint(3, o[0],o[1],0.0);
+ break;
+ }
+ default:
+ {
+ this->TexturePoints->SetPoint(0, o[0],o[1],0.0);
+ this->TexturePoints->SetPoint(1, o[0]+imageSize[0],o[1],0.0);
+ this->TexturePoints->SetPoint(2, o[0]+imageSize[0],o[1]+imageSize[1],0.0);
+ this->TexturePoints->SetPoint(3, o[0],o[1]+imageSize[1],0.0);
+ }
+ }
+
+
+ }
+ }
+}
+
+mitkVtkLogoRepresentation::mitkVtkLogoRepresentation() : cornerPosition(0)
+{
+
+}
+
+mitkVtkLogoRepresentation::~mitkVtkLogoRepresentation()
+{
+
+}
+
+//-------------------------------------------------------------------------
+void mitkVtkLogoRepresentation::PrintSelf(ostream& os, vtkIndent indent)
+{
+ this->Superclass::PrintSelf(os,indent);
+
+ if ( this->Image )
+ {
+ os << indent << "Image:\n";
+ this->Image->PrintSelf(os,indent.GetNextIndent());
+ }
+ else
+ {
+ os << indent << "Image: (none)\n";
+ }
+
+ if ( this->ImageProperty )
+ {
+ os << indent << "Image Property:\n";
+ this->ImageProperty->PrintSelf(os,indent.GetNextIndent());
+ }
+ else
+ {
+ os << indent << "Image Property: (none)\n";
+ }
+}
diff --git a/Modules/Overlays/mitkVtkLogoRepresentation.h b/Modules/Overlays/mitkVtkLogoRepresentation.h
new file mode 100644
index 0000000000..021be6c943
--- /dev/null
+++ b/Modules/Overlays/mitkVtkLogoRepresentation.h
@@ -0,0 +1,56 @@
+/*===================================================================
+
+ The Medical Imaging Interaction Toolkit (MITK)
+
+ Copyright (c) German Cancer Research Center,
+ Division of Medical and Biological Informatics.
+ All rights reserved.
+
+ This software is distributed WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.
+
+ See LICENSE.txt or http://www.mitk.org for details.
+
+ ===================================================================*/
+
+
+#ifndef __mitkVtkLogoRepresentation_h
+#define __mitkVtkLogoRepresentation_h
+
+#include "vtkLogoRepresentation.h"
+
+class mitkVtkLogoRepresentation : public vtkLogoRepresentation
+{
+public:
+
+ // Description:
+ // Instantiate this class.
+ static mitkVtkLogoRepresentation *New();
+
+ // Description:
+ // Standard VTK class methods.
+ vtkTypeMacro(mitkVtkLogoRepresentation,vtkLogoRepresentation);
+ void PrintSelf(ostream& os, vtkIndent indent);
+
+ // Description:
+ // Satisfy the superclasses' API.
+ virtual void BuildRepresentation();
+
+ void SetCornerPosition(int corner){cornerPosition = corner;}
+
+protected:
+ mitkVtkLogoRepresentation();
+ ~mitkVtkLogoRepresentation();
+
+ // Helper methods
+ void AdjustImageSize(double o[2], double borderSize[2], double imageSize[2]);
+
+ int cornerPosition;
+
+private:
+ mitkVtkLogoRepresentation(const mitkVtkLogoRepresentation&); //Not implemented
+ void operator=(const mitkVtkLogoRepresentation&); //Not implemented
+};
+
+#endif
diff --git a/Modules/Persistence/Testing/mitkPersistenceTest.cpp b/Modules/Persistence/Testing/mitkPersistenceTest.cpp
index 65c023e280..c07c3d17ec 100644
--- a/Modules/Persistence/Testing/mitkPersistenceTest.cpp
+++ b/Modules/Persistence/Testing/mitkPersistenceTest.cpp
@@ -1,169 +1,172 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkCommon.h>
#include <usModuleContext.h>
#include <usServiceReference.h>
#include <usGetModuleContext.h>
#include <mitkTestingMacros.h>
+#include <mitkTestFixture.h>
#include <mitkIPersistenceService.h>
#include <mitkPersistenceService.h>
#include <mitkSceneIO.h>
-#include <Poco/File.h>
+#include <mitkIOUtil.h>
+#include <itksys/SystemTools.hxx>
struct PersistenceTestClass
{
- PersistenceTestClass()
- : id(""), param1(1), param2(2), param3(false)
- {
- }
- std::string id;
- int param1;
- double param2;
- bool param3;
-
- PERSISTENCE_CREATE3(PersistenceTestClass, id, param1, param2, param3)
+ PersistenceTestClass()
+ : id(""), param1(1), param2(2), param3(false)
+ {
+ }
+ std::string id;
+ int param1;
+ double param2;
+ bool param3;
+
+ PERSISTENCE_CREATE3(PersistenceTestClass, id, param1, param2, param3)
};
struct TestPropertyListReplacedObserver: public mitk::PropertyListReplacedObserver
{
- TestPropertyListReplacedObserver(): counter(0) {}
- virtual void BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList )
- {
- if( id == m_Id )
- counter++;
- }
-
- virtual void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList )
- {
- if( id == m_Id )
- counter++;
- }
-
- int counter;
- std::string m_Id;
+ TestPropertyListReplacedObserver(): counter(0) {}
+ virtual void BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList )
+ {
+ if( id == m_Id )
+ counter++;
+ }
+
+ virtual void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList )
+ {
+ if( id == m_Id )
+ counter++;
+ }
+
+ int counter;
+ std::string m_Id;
};
-std::string testClassId = "testClass";
-int param1 = 100;
-double param2 = 201.56;
-bool param3 = true;
-
-void testParams( const PersistenceTestClass& testClass, const std::string& testClassName )
+class mitkPersistenceTestSuite : public mitk::TestFixture
{
- MITK_INFO << "Testing parameters of " << testClassName;
- MITK_TEST_CONDITION( testClass.id == testClassId, "testClass.id (" << testClass.id << ") != testClassId (" << testClassId << ")" );
- MITK_TEST_CONDITION( testClass.param1 == param1, "testClass.param1 (" << testClass.param1 << ") != param1 (" << param1 << ")" );
- MITK_TEST_CONDITION( testClass.param2 == param2, "testClass.param2 (" << testClass.param2 << ") != param2 (" << param2 << ")" );
- MITK_TEST_CONDITION( testClass.param3 == param3, "testClass.param3 (" << testClass.param3 << ") != param3 (" << param3 << ")" );
-}
-
-int mitkPersistenceTest(int /*argc*/, char* /*argv*/[])
-{
- MITK_TEST_BEGIN("PersistenceTest")
- // dummy load of SceneIO, otherwise PersistenceService won't be available
- //mitk::PersistenceService::LoadModule();
+ CPPUNIT_TEST_SUITE(mitkPersistenceTestSuite);
+ MITK_TEST(PersistenceTest);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ // private test members that are initialized by setUp()
+ std::string testClassId;
+ int param1;
+ double param2;
+ bool param3;
+
+public:
+
+ void setUp()
+ {
+ testClassId = "testClass";
+ param1 = 100;
+ param2 = 201.56;
+ param3 = true;
+ }
+
+ void PersistenceTest()
+ {
+ // dummy load of SceneIO, otherwise PersistenceService won't be available
+ //mitk::PersistenceService::LoadModule();
- MITK_INFO << "Testing availability of the PersistenceService.";
PERSISTENCE_GET_SERVICE_MACRO
- MITK_TEST_CONDITION_REQUIRED(persistenceService, "IPersistenceService available")
-
- MITK_INFO << "Initialize testable parameter values.";
+ CPPUNIT_ASSERT_MESSAGE("Testing availability of the PersistenceService.", persistenceService != NULL);
- Poco::File defaultPersistenceFile(persistenceService->GetDefaultPersistenceFile());
+ // Initialize testable parameter values
+ std::string defaultPersistenceFile = persistenceService->GetDefaultPersistenceFile();
PersistenceTestClass autoLoadTestClass;
autoLoadTestClass.id = testClassId;
- if( defaultPersistenceFile.exists() && persistenceService->GetAutoLoadAndSave() )
+ if( itksys::SystemTools::FileExists(defaultPersistenceFile.c_str(), true) && persistenceService->GetAutoLoadAndSave() )
{
- MITK_INFO << "Testing auto load/save of the PersistenceService.";
- defaultPersistenceFile.remove();
- autoLoadTestClass.FromPropertyList();
-
- testParams( autoLoadTestClass, "autoLoadTestClass" );
+ /// Test auto load/save of the PersistenceService.
+ itksys::SystemTools::RemoveFile(defaultPersistenceFile.c_str());
+ autoLoadTestClass.FromPropertyList();
+ testParams( autoLoadTestClass, "autoLoadTestClass" );
}
- MITK_INFO << "Removing left-over test files.";
- Poco::File testTempFile("PersistenceTestFile.mitk");
- if( testTempFile.exists() )
- testTempFile.remove(false);
-
- Poco::File testXmlTempFile("PersistenceTestFile.xml");
- if( testXmlTempFile.exists() )
- testXmlTempFile.remove(false);
+ std::string testTempFile = mitk::IOUtil::CreateTemporaryFile("XXXXXX.mitk");
+ std::string testXmlTempFile = mitk::IOUtil::CreateTemporaryFile("PersistenceTestFileXXXXXX.xml");
MITK_INFO << "Testing standard write to scene file/xml file.";
PersistenceTestClass testClass;
testClass.id = testClassId;
testClass.param1 = param1;
testClass.param2 = param2;
testClass.param3 = param3;
- MITK_TEST_CONDITION_REQUIRED( testClass.Save(testTempFile.path()), "testClass.Save(testTempFile.path())");
- MITK_TEST_CONDITION_REQUIRED( testClass.Save(testXmlTempFile.path()), "testClass.Save(testTempFile.path())");
+ CPPUNIT_ASSERT_MESSAGE( "Testing to save a scene file", testClass.Save(testTempFile));
+ CPPUNIT_ASSERT_MESSAGE( "testing to save an xml file", testClass.Save(testXmlTempFile));
- MITK_INFO << "Testing read from scene file.";
- MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)");
+ CPPUNIT_ASSERT_MESSAGE( "Testing read from scene file: persistenceService->RemovePropertyList(testClassId)", persistenceService->RemovePropertyList(testClassId));
PersistenceTestClass testClass2;
testClass2.id = testClassId;
- MITK_TEST_CONDITION_REQUIRED( testClass2.Load(testTempFile.path()), "testClass2.Load(testTempFile.path())");
+ CPPUNIT_ASSERT_MESSAGE( "Testing read from scene file: testClass2.Load(testTempFile.path())", testClass2.Load(testTempFile));
testParams( testClass2, "testClass2" );
- MITK_INFO << "Testing read from xml file.";
- MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)");
+ CPPUNIT_ASSERT_MESSAGE( "Testing read from xml file: persistenceService->RemovePropertyList(testClassId)", persistenceService->RemovePropertyList(testClassId));
PersistenceTestClass testClass3;
testClass3.id = testClassId;
- MITK_TEST_CONDITION_REQUIRED( testClass3.Load(testXmlTempFile.path()), "testClass3.Load(testXmlTempFile.path())");
+ CPPUNIT_ASSERT_MESSAGE( "Testing read from xml file: testClass3.Load(testXmlTempFile.path())", testClass3.Load(testXmlTempFile));
testParams( testClass3, "testClass3" );
- MITK_INFO << "Testing appendChanges functionality with scene load/write.";
- MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)");
- MITK_TEST_CONDITION_REQUIRED( persistenceService->Save(testTempFile.path(), true), "persistenceService->Save(testTempFile.path())");
- MITK_TEST_CONDITION_REQUIRED( persistenceService->Load(testTempFile.path()), "persistenceService->Load(testTempFile.path())");
+ CPPUNIT_ASSERT_MESSAGE( "Testing appendChanges functionality with scene load/write: persistenceService->RemovePropertyList(testClassId)", persistenceService->RemovePropertyList(testClassId));
+ CPPUNIT_ASSERT_MESSAGE( "Testing appendChanges functionality with scene load/write: persistenceService->Save(testTempFile.path())",persistenceService->Save(testTempFile, true));
+ CPPUNIT_ASSERT_MESSAGE( "Testing appendChanges functionality with scene load/write: persistenceService->Load(testTempFile.path())", persistenceService->Load(testTempFile));
PersistenceTestClass testClass4;
testClass4.id = testClassId;
testClass4.FromPropertyList();
testParams( testClass4, "testClass4" );
- MITK_INFO << "Testing appendChanges functionality with xml load/write.";
- MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)");
- MITK_TEST_CONDITION_REQUIRED( persistenceService->Save(testXmlTempFile.path(), true), "persistenceService->Save(testXmlTempFile.path())");
- MITK_TEST_CONDITION_REQUIRED( persistenceService->Load(testXmlTempFile.path()), "persistenceService->Load(testXmlTempFile.path())");
+ CPPUNIT_ASSERT_MESSAGE( "Testing appendChanges functionality with xml load/write: persistenceService->RemovePropertyList(testClassId)", persistenceService->RemovePropertyList(testClassId));
+ CPPUNIT_ASSERT_MESSAGE( "Testing appendChanges functionality with xml load/write: persistenceService->Save(testXmlTempFile.path())", persistenceService->Save(testXmlTempFile, true));
+ CPPUNIT_ASSERT_MESSAGE( "Testing appendChanges functionality with xml load/write: persistenceService->Load(testXmlTempFile.path())", persistenceService->Load(testXmlTempFile));
PersistenceTestClass testClass5;
testClass5.id = testClassId;
testClass5.FromPropertyList();
testParams( testClass5, "testClass5" );
- MITK_INFO << "Testing observer functionality.";
+ // Test Observer Functionality
TestPropertyListReplacedObserver testObserver;
testObserver.m_Id = testClassId;
persistenceService->AddPropertyListReplacedObserver( &testObserver );
- persistenceService->Load(testTempFile.path());
- MITK_TEST_CONDITION( testObserver.counter == 2, "testObserver.counter == 2, testObserver.counter is " << testObserver.counter );
-
- MITK_INFO << "Cleaning test files.";
- if( testXmlTempFile.exists() )
- testXmlTempFile.remove(false);
- if( testTempFile.exists() )
- testTempFile.remove(false);
+ persistenceService->Load(testTempFile);
+ CPPUNIT_ASSERT_MESSAGE( "Testing observer functionality: testObserver.counter == 2, testObserver.counter is " + testObserver.counter, testObserver.counter == 2 );
autoLoadTestClass.param1 = param1;
autoLoadTestClass.param2 = param2;
autoLoadTestClass.param3 = param3;
autoLoadTestClass.ToPropertyList();
- MITK_TEST_END()
-}
+ }
+
+ /**
+ * Helper Method that compares the returned class to its base values
+ */
+ void testParams( const PersistenceTestClass& testClass, const std::string& testClassName )
+ {
+ CPPUNIT_ASSERT_MESSAGE( "Parameter of TestClass not equal to reference value: testClass.id", testClass.id == testClassId );
+ CPPUNIT_ASSERT_MESSAGE( "Parameter of TestClass not equal to reference value: testClass.param1" , testClass.param1 == param1);
+ CPPUNIT_ASSERT_MESSAGE( "Parameter of TestClass not equal to reference value: testClass.param2" , testClass.param2 == param2);
+ CPPUNIT_ASSERT_MESSAGE( "Parameter of TestClass not equal to reference value: testClass.param3" , testClass.param3 == param3);
+ }
+};
+MITK_TEST_SUITE_REGISTRATION(mitkPersistence)
\ No newline at end of file
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.cpp
index 338f9b7023..f559a6ffd7 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.cpp
@@ -1,171 +1,184 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarAngle.h"
#include "mitkPlaneGeometry.h"
mitk::PlanarAngle::PlanarAngle()
: FEATURE_ID_ANGLE( this->AddFeature( "Angle", "deg" ) )
{
// Start with two control points
this->ResetNumberOfControlPoints( 2 );
this->SetNumberOfPolyLines(1);
this->SetNumberOfHelperPolyLines(1);
m_HelperPolyLinesToBePainted->InsertElement( 0, false );
}
mitk::PlanarAngle::~PlanarAngle()
{
}
void mitk::PlanarAngle::GeneratePolyLine()
{
this->ClearPolyLines();
for ( unsigned int i=0; i<this->GetNumberOfControlPoints(); i++ )
this->AppendPointToPolyLine(0, this->GetControlPoint(i));
}
void mitk::PlanarAngle::GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight)
{
// Generate helper-poly-line for angle
if ( this->GetNumberOfControlPoints() < 3)
{
m_HelperPolyLinesToBePainted->SetElement(0, false);
return; //We do not need to draw an angle as there are no two arms yet
}
this->ClearHelperPolyLines();
const Point2D centerPoint = this->GetControlPoint( 1 );
const Point2D boundaryPointOne = this->GetControlPoint( 0 );
const Point2D boundaryPointTwo = this->GetControlPoint( 2 );
double radius = centerPoint.EuclideanDistanceTo( boundaryPointOne );
if ( radius > centerPoint.EuclideanDistanceTo( boundaryPointTwo ) )
{
radius = centerPoint.EuclideanDistanceTo( boundaryPointTwo );
}
//Fixed size radius depending on screen size for the angle
double nonScalingRadius = displayHeight * mmPerDisplayUnit * 0.05;
if (nonScalingRadius > radius)
{
m_HelperPolyLinesToBePainted->SetElement(0, false);
return; //if the arc has a radius that is longer than the shortest arm it should not be painted
}
m_HelperPolyLinesToBePainted->SetElement(0, true);
radius = nonScalingRadius;
double angle = this->GetQuantity( FEATURE_ID_ANGLE );
//Determine from which arm the angle should be drawn
Vector2D v0 = boundaryPointOne - centerPoint;
Vector2D v1 = boundaryPointTwo - centerPoint;
Vector2D v2;
v2[0] = 1.0;
v2[1] = 0.0;
v0[0] = v0[0] * cos( 0.001 ) - v0[1] * sin( 0.001 ); //rotate one arm a bit
v0[1] = v0[0] * sin( 0.001 ) + v0[1] * cos( 0.001 );
v0.Normalize();
v1.Normalize();
double testAngle = acos( v0 * v1 );
//if the rotated arm is closer to the other arm than before it is the one from which we start drawing
//else we start drawing from the other arm (we want to draw in the mathematically positive direction)
if( angle > testAngle )
{
v1[0] = v0[0] * cos( -0.001 ) - v0[1] * sin( -0.001 );
v1[1] = v0[0] * sin( -0.001 ) + v0[1] * cos( -0.001 );
//We determine if the arm is mathematically forward or backward
//assuming we rotate between -pi and pi
if ( acos( v0 * v2 ) > acos ( v1 * v2 ))
{
testAngle = acos( v1 * v2 );
}
else
{
testAngle = -acos( v1 * v2 );
}
}
else
{
v0[0] = v1[0] * cos( -0.001 ) - v1[1] * sin( -0.001 );
v0[1] = v1[0] * sin( -0.001 ) + v1[1] * cos( -0.001 );
//We determine if the arm is mathematically forward or backward
//assuming we rotate between -pi and pi
if ( acos( v0 * v2 ) < acos ( v1 * v2 ))
{
testAngle = acos( v1 * v2 );
}
else
{
testAngle = -acos( v1 * v2 );
}
}
// Generate poly-line with 16 segments
for ( int t = 0; t < 16; ++t )
{
double alpha = (double) t * angle / 15.0 + testAngle;
Point2D polyLinePoint;
polyLinePoint[0] = centerPoint[0] + radius * cos( alpha );
polyLinePoint[1] = centerPoint[1] + radius * sin( alpha );
this->AppendPointToHelperPolyLine(0, polyLinePoint);
}
}
void mitk::PlanarAngle::EvaluateFeaturesInternal()
{
if ( this->GetNumberOfControlPoints() < 3 )
{
// Angle not yet complete.
return;
}
// Calculate angle between lines
const Point2D &p0 = this->GetControlPoint( 0 );
const Point2D &p1 = this->GetControlPoint( 1 );
const Point2D &p2 = this->GetControlPoint( 2 );
Vector2D v0 = p1 - p0;
Vector2D v1 = p1 - p2;
v0.Normalize();
v1.Normalize();
double angle = acos( v0 * v1 );
this->SetQuantity( FEATURE_ID_ANGLE, angle );
}
void mitk::PlanarAngle::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
+
+bool mitk::PlanarAngle::Equals(const PlanarFigure &other) const
+{
+ const mitk::PlanarAngle* otherAngle = dynamic_cast<const mitk::PlanarAngle*>(&other);
+ if ( otherAngle )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.h b/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.h
index 9ed5435fed..ab2a69c49c 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarAngle.h
@@ -1,88 +1,90 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_ANGLE_H_
#define _MITK_PLANAR_ANGLE_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure to display an angle
* through three control points
*/
class MitkPlanarFigure_EXPORT PlanarAngle : public PlanarFigure
{
public:
mitkClassMacro( PlanarAngle, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
public:
// Feature identifiers
const unsigned int FEATURE_ID_ANGLE;
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
/** \brief Angle has 3 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 3;
}
/** \brief Angle has 3 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 3;
}
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
+
protected:
PlanarAngle();
virtual ~PlanarAngle();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_ANGLE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp
index 2f8c2d0892..6185f0e685 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp
@@ -1,117 +1,132 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarArrow.h"
#include "mitkPlaneGeometry.h"
mitk::PlanarArrow::PlanarArrow()
: FEATURE_ID_LENGTH( this->AddFeature( "Length", "mm" ) )
{
// Directed arrow has two control points
this->ResetNumberOfControlPoints( 2 );
m_ArrowTipScaleFactor = -1.0;
this->SetNumberOfPolyLines( 1 );
this->SetNumberOfHelperPolyLines( 2 );
// Create helper polyline object (for drawing the orthogonal orientation line)
m_HelperPolyLinesToBePainted->InsertElement( 0, false );
m_HelperPolyLinesToBePainted->InsertElement( 1, false );
}
mitk::PlanarArrow::~PlanarArrow()
{
}
void mitk::PlanarArrow::GeneratePolyLine()
{
this->ClearPolyLines();
this->AppendPointToPolyLine(0, this->GetControlPoint(0));
this->AppendPointToPolyLine(0, this->GetControlPoint(1));
}
void mitk::PlanarArrow::GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight)
{
// Generate helper polyline (orientation line orthogonal to first line)
// if the third control point is currently being set
if ( this->GetNumberOfControlPoints() != 2 )
{
m_HelperPolyLinesToBePainted->SetElement( 0, false );
m_HelperPolyLinesToBePainted->SetElement( 1, false );
return;
}
this->ClearHelperPolyLines();
m_HelperPolyLinesToBePainted->SetElement( 0, true );
m_HelperPolyLinesToBePainted->SetElement( 1, true );
//Fixed size depending on screen size for the angle
float scaleFactor = 0.015;
if ( m_ArrowTipScaleFactor > 0.0 )
{
scaleFactor = m_ArrowTipScaleFactor;
}
double nonScalingLength = displayHeight * mmPerDisplayUnit * scaleFactor;
// Calculate arrow peak
const Point2D p1 = this->GetControlPoint( 0 );
const Point2D p2 = this->GetControlPoint( 1 );
Vector2D n1 = p1 - p2;
n1.Normalize();
double degrees = 100.0;
Vector2D temp;
temp[0] = n1[0] * cos(degrees) - n1[1] * sin(degrees);
temp[1] = n1[0] * sin(degrees) + n1[1] * cos(degrees);
Vector2D temp2;
temp2[0] = n1[0] * cos(-degrees) - n1[1] * sin(-degrees);
temp2[1] = n1[0] * sin(-degrees) + n1[1] * cos(-degrees);
this->AppendPointToHelperPolyLine(0, p1);
this->AppendPointToHelperPolyLine(0, Point2D(p1 - temp * nonScalingLength));
this->AppendPointToHelperPolyLine(1, p1);
this->AppendPointToHelperPolyLine(1, Point2D(p1 - temp2 * nonScalingLength));
}
void mitk::PlanarArrow::EvaluateFeaturesInternal()
{
// Calculate line length
const Point3D &p0 = this->GetWorldControlPoint( 0 );
const Point3D &p1 = this->GetWorldControlPoint( 1 );
double length = p0.EuclideanDistanceTo( p1 );
this->SetQuantity( FEATURE_ID_LENGTH, length );
}
-
void mitk::PlanarArrow::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
void mitk::PlanarArrow::SetArrowTipScaleFactor( float scale )
{
m_ArrowTipScaleFactor = scale;
}
+
+bool mitk::PlanarArrow::Equals(mitk::PlanarFigure& other)
+{
+ mitk::PlanarArrow* otherArrow = dynamic_cast<mitk::PlanarArrow*>(&other);
+ if ( otherArrow )
+ {
+ if ( std::abs(this->m_ArrowTipScaleFactor - otherArrow->m_ArrowTipScaleFactor) > mitk::eps)
+ return false;
+
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h
index c0a517da91..9375c529f7 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h
@@ -1,97 +1,99 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_ARROW_H_
#define _MITK_PLANAR_ARROW_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing an arrow
* through two control points
*/
class MitkPlanarFigure_EXPORT PlanarArrow : public PlanarFigure
{
public:
mitkClassMacro( PlanarArrow, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
/** \brief Line has 2 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 2;
}
/** \brief Line has 2 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 2;
}
void SetArrowTipScaleFactor( float scale );
+ virtual bool Equals(mitk::PlanarFigure& other);
+
protected:
PlanarArrow();
virtual ~PlanarArrow();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
// Feature identifiers
const unsigned int FEATURE_ID_LENGTH;
// ScaleFactor defining size of helper-lines in relation to display size
float m_ArrowTipScaleFactor;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_ARROW_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.cpp
index fe6e689199..cab3d12c23 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.cpp
@@ -1,120 +1,136 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarBezierCurve.h"
#include <mitkProperties.h>
#include <limits>
mitk::PlanarBezierCurve::PlanarBezierCurve()
: FEATURE_ID_LENGTH(Superclass::AddFeature("Length", "mm")),
m_NumberOfSegments(100)
{
this->ResetNumberOfControlPoints(2);
this->SetNumberOfPolyLines(1);
this->SetNumberOfHelperPolyLines(1);
}
mitk::PlanarBezierCurve::~PlanarBezierCurve()
{
}
void mitk::PlanarBezierCurve::EvaluateFeaturesInternal()
{
double length = 0.0;
for (unsigned int i = 0; i < m_NumberOfSegments; ++i)
length += static_cast<Point2D>(m_PolyLines[0][i]).EuclideanDistanceTo(static_cast<Point2D>(m_PolyLines[0][i + 1]));
this->SetQuantity(FEATURE_ID_LENGTH, length);
}
unsigned int mitk::PlanarBezierCurve::GetNumberOfSegments() const
{
return m_NumberOfSegments;
}
void mitk::PlanarBezierCurve::SetNumberOfSegments(unsigned int numSegments)
{
m_NumberOfSegments = std::max(1U, numSegments);
if (this->IsPlaced())
{
this->GeneratePolyLine();
this->Modified();
}
}
void mitk::PlanarBezierCurve::GenerateHelperPolyLine(double, unsigned int)
{
this->ClearHelperPolyLines();
unsigned int numHelperPolyLinePoints = m_ControlPoints.size();
for (unsigned int i = 0; i < numHelperPolyLinePoints; ++i)
this->AppendPointToHelperPolyLine(0, m_ControlPoints[i]);
}
void mitk::PlanarBezierCurve::GeneratePolyLine()
{
this->ClearPolyLines();
const unsigned int numPolyLinePoints = m_NumberOfSegments + 1;
for (unsigned int i = 0; i < numPolyLinePoints; ++i)
this->AppendPointToPolyLine(0, this->ComputeDeCasteljauPoint(i / static_cast<ScalarType>(m_NumberOfSegments)));
}
mitk::Point2D mitk::PlanarBezierCurve::ComputeDeCasteljauPoint(mitk::ScalarType t)
{
unsigned int n = m_ControlPoints.size() - 1;
if (m_DeCasteljauPoints.size() != n)
m_DeCasteljauPoints.resize(n);
for (unsigned int i = 0; i < n; ++i)
{
m_DeCasteljauPoints[i][0] = (1 - t) * m_ControlPoints[i][0] + t * m_ControlPoints[i + 1][0];
m_DeCasteljauPoints[i][1] = (1 - t) * m_ControlPoints[i][1] + t * m_ControlPoints[i + 1][1];
}
for (--n; n > 0; --n)
{
for (unsigned int i = 0; i < n; ++i)
{
m_DeCasteljauPoints[i][0] = (1 - t) * m_DeCasteljauPoints[i][0] + t * m_DeCasteljauPoints[i + 1][0];
m_DeCasteljauPoints[i][1] = (1 - t) * m_DeCasteljauPoints[i][1] + t * m_DeCasteljauPoints[i + 1][1];
}
}
return m_DeCasteljauPoints[0];
}
unsigned int mitk::PlanarBezierCurve::GetMaximumNumberOfControlPoints() const
{
return std::numeric_limits<unsigned int>::max();
}
unsigned int mitk::PlanarBezierCurve::GetMinimumNumberOfControlPoints() const
{
return 2;
}
bool mitk::PlanarBezierCurve::IsHelperToBePainted(unsigned int index)
{
return index == 0 && m_ControlPoints.size() > 2;
}
+bool mitk::PlanarBezierCurve::Equals(const PlanarFigure &other) const
+{
+ const mitk::PlanarBezierCurve* otherBezierCurve = dynamic_cast<const mitk::PlanarBezierCurve*>(&other);
+ if ( otherBezierCurve )
+ {
+ if( this->m_NumberOfSegments != otherBezierCurve->m_NumberOfSegments )
+ return false;
+ if( this->m_DeCasteljauPoints != otherBezierCurve->m_DeCasteljauPoints )
+ return false;
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.h b/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.h
index dd45e0f207..905c6fc1fe 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarBezierCurve.h
@@ -1,60 +1,62 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkPlanarBezierCurve_h
#define mitkPlanarBezierCurve_h
#include <mitkPlanarFigure.h>
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class MitkPlanarFigure_EXPORT PlanarBezierCurve : public PlanarFigure
{
public:
mitkClassMacro(PlanarBezierCurve, PlanarFigure)
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
unsigned int GetNumberOfSegments() const;
void SetNumberOfSegments(unsigned int numSegments);
virtual unsigned int GetMaximumNumberOfControlPoints() const;
virtual unsigned int GetMinimumNumberOfControlPoints() const;
virtual bool IsHelperToBePainted(unsigned int index);
const unsigned int FEATURE_ID_LENGTH;
+ virtual bool Equals(const mitk::PlanarFigure& other)const;
+
protected:
PlanarBezierCurve();
virtual ~PlanarBezierCurve();
mitkCloneMacro(Self)
virtual void EvaluateFeaturesInternal();
virtual void GenerateHelperPolyLine(double, unsigned int);
virtual void GeneratePolyLine();
private:
Point2D ComputeDeCasteljauPoint(ScalarType t);
std::vector<mitk::Point2D> m_DeCasteljauPoints;
unsigned int m_NumberOfSegments;
};
}
#endif
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.cpp
index 43b80d29e5..d6e248be95 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.cpp
@@ -1,175 +1,188 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarCircle.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
mitk::PlanarCircle::PlanarCircle()
: FEATURE_ID_RADIUS( this->AddFeature( "Radius", "mm" ) ),
FEATURE_ID_DIAMETER( this->AddFeature( "Diameter", "mm" ) ),
FEATURE_ID_AREA( this->AddFeature( "Area", "mm2" ) ),
m_MinRadius(0),
m_MaxRadius(100),
m_MinMaxRadiusContraintsActive(false)
{
// Circle has two control points
this->ResetNumberOfControlPoints( 2 );
this->SetNumberOfPolyLines( 1 );
this->SetProperty( "closed", mitk::BoolProperty::New(true) );
}
mitk::PlanarCircle::~PlanarCircle()
{
}
bool mitk::PlanarCircle::SetControlPoint( unsigned int index, const Point2D &point, bool /*createIfDoesNotExist*/ )
{
// moving center point
if(index == 0)
{
const Point2D &centerPoint = GetControlPoint( 0 );
Point2D boundaryPoint = GetControlPoint( 1 );
vnl_vector<ScalarType> vec = (point.GetVnlVector() - centerPoint.GetVnlVector());
boundaryPoint[0] += vec[0];
boundaryPoint[1] += vec[1];
PlanarFigure::SetControlPoint( 0, point );
PlanarFigure::SetControlPoint( 1, boundaryPoint );
return true;
}
else if ( index == 1 )
{
PlanarFigure::SetControlPoint( index, point );
return true;
}
return false;
}
mitk::Point2D mitk::PlanarCircle::ApplyControlPointConstraints(unsigned int index, const Point2D &point)
{
if ( this->GetPlaneGeometry() == NULL )
{
return point;
}
Point2D indexPoint;
this->GetPlaneGeometry()->WorldToIndex( point, indexPoint );
BoundingBox::BoundsArrayType bounds = this->GetPlaneGeometry()->GetBounds();
if ( indexPoint[0] < bounds[0] ) { indexPoint[0] = bounds[0]; }
if ( indexPoint[0] > bounds[1] ) { indexPoint[0] = bounds[1]; }
if ( indexPoint[1] < bounds[2] ) { indexPoint[1] = bounds[2]; }
if ( indexPoint[1] > bounds[3] ) { indexPoint[1] = bounds[3]; }
Point2D constrainedPoint;
this->GetPlaneGeometry()->IndexToWorld( indexPoint, constrainedPoint );
if(m_MinMaxRadiusContraintsActive)
{
if( index != 0)
{
const Point2D &centerPoint = this->GetControlPoint(0);
double euclideanDinstanceFromCenterToPoint1 = centerPoint.EuclideanDistanceTo(point);
Vector2D vectorProjectedPoint;
vectorProjectedPoint = point - centerPoint;
vectorProjectedPoint.Normalize();
if( euclideanDinstanceFromCenterToPoint1 > m_MaxRadius )
{
vectorProjectedPoint *= m_MaxRadius;
constrainedPoint = centerPoint;
constrainedPoint += vectorProjectedPoint;
}
else if( euclideanDinstanceFromCenterToPoint1 < m_MinRadius )
{
vectorProjectedPoint *= m_MinRadius;
constrainedPoint = centerPoint;
constrainedPoint += vectorProjectedPoint;
}
}
}
return constrainedPoint;
}
void mitk::PlanarCircle::GeneratePolyLine()
{
// TODO: start circle at specified boundary point...
// clear the PolyLine-Contrainer, it will be reconstructed soon enough...
this->ClearPolyLines();
const Point2D &centerPoint = GetControlPoint( 0 );
const Point2D &boundaryPoint = GetControlPoint( 1 );
double radius = centerPoint.EuclideanDistanceTo( boundaryPoint );
// Generate poly-line with 64 segments
for ( int t = 0; t < 64; ++t )
{
double alpha = (double) t * vnl_math::pi / 32.0;
// construct the new polyline point ...
Point2D polyLinePoint;
polyLinePoint[0] = centerPoint[0] + radius * cos( alpha );
polyLinePoint[1] = centerPoint[1] + radius * sin( alpha );
// ... and append it to the PolyLine.
// No extending supported here, so we can set the index of the PolyLineElement to '0'
this->AppendPointToPolyLine(0, polyLinePoint);
}
}
void mitk::PlanarCircle::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// A circle does not require a helper object
}
void mitk::PlanarCircle::EvaluateFeaturesInternal()
{
// Calculate circle radius and area
const Point3D &p0 = this->GetWorldControlPoint( 0 );
const Point3D &p1 = this->GetWorldControlPoint( 1 );
double radius = p0.EuclideanDistanceTo( p1 );
double area = vnl_math::pi * radius * radius;
this->SetQuantity( FEATURE_ID_RADIUS, radius );
this->SetQuantity( FEATURE_ID_DIAMETER, 2*radius );
this->SetQuantity( FEATURE_ID_AREA, area );
}
void mitk::PlanarCircle::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
bool mitk::PlanarCircle::SetCurrentControlPoint( const Point2D& point )
{
if ( m_SelectedControlPoint < 0 )
{
m_SelectedControlPoint = 1;
}
return this->SetControlPoint( m_SelectedControlPoint, point, false);
}
+
+ bool mitk::PlanarCircle::Equals(const PlanarFigure &other) const
+ {
+ const mitk::PlanarCircle* otherCircle = dynamic_cast<const mitk::PlanarCircle*>(&other);
+ if ( otherCircle )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.h b/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.h
index 2839b76f90..8e40da1975 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarCircle.h
@@ -1,138 +1,139 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_CIRCLE_H_
#define _MITK_PLANAR_CIRCLE_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a circle
* through two control points
*/
class MitkPlanarFigure_EXPORT PlanarCircle : public PlanarFigure
{
public:
mitkClassMacro( PlanarCircle, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
bool SetControlPoint( unsigned int index, const Point2D &point, bool createIfDoesNotExist = false );
/** \brief Circle has 2 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 2;
}
/** \brief Circle has 2 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 2;
}
/** \brief Sets the minimum radius
*/
void SetMinimumRadius( double radius )
{
m_MinRadius = radius;
}
/** \brief Gets the minimum radius
*/
double GetMinimumRadius()
{
return m_MinRadius;
}
/** \brief Sets the maximum radius
*/
void SetMaximumRadius( double radius )
{
m_MaxRadius = radius;
}
/** \brief Gets the minimum radius
*/
double GetMaximumRadius()
{
return m_MaxRadius;
}
void ActivateMinMaxRadiusContstraints( bool active )
{
m_MinMaxRadiusContraintsActive = active;
}
virtual bool SetCurrentControlPoint( const Point2D& point );
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarCircle();
virtual ~PlanarCircle();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Spatially constrain control points of second (orthogonal) line */
virtual Point2D ApplyControlPointConstraints( unsigned int index, const Point2D& point );
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
// Feature identifiers
const unsigned int FEATURE_ID_RADIUS;
const unsigned int FEATURE_ID_DIAMETER;
const unsigned int FEATURE_ID_AREA;
//Member variables:
double m_MinRadius;
double m_MaxRadius;
bool m_MinMaxRadiusContraintsActive;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_CIRCLE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarCross.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarCross.cpp
index be15c91a58..7ed28a6cc3 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarCross.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarCross.cpp
@@ -1,344 +1,356 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarCross.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
mitk::PlanarCross::PlanarCross()
: FEATURE_ID_LONGESTDIAMETER( this->AddFeature( "Longest Axis", "mm" ) ),
FEATURE_ID_SHORTAXISDIAMETER( this->AddFeature( "Short Axis", "mm" ) )
{
// Cross has two control points at the beginning
this->ResetNumberOfControlPoints( 2 );
// Create property for SingleLineMode (default: false)
this->SetProperty( "SingleLineMode", mitk::BoolProperty::New( false ) );
// Create helper polyline object (for drawing the orthogonal orientation line)
this->SetNumberOfHelperPolyLines( 1 );
m_HelperPolyLinesToBePainted->InsertElement( 0, false );
}
mitk::PlanarCross::~PlanarCross()
{
}
void mitk::PlanarCross::SetSingleLineMode( bool singleLineMode )
{
this->SetProperty( "SingleLineMode", mitk::BoolProperty::New( singleLineMode ) );
this->Modified();
}
bool mitk::PlanarCross::GetSingleLineMode() const
{
mitk::BoolProperty* singleLineMode = dynamic_cast< mitk::BoolProperty* >(
this->GetProperty( "SingleLineMode" ).GetPointer() );
if ( singleLineMode != NULL )
{
return singleLineMode->GetValue();
}
return false;
}
bool mitk::PlanarCross::ResetOnPointSelect()
{
if ( this->GetSingleLineMode() )
{
// In single line mode --> nothing to reset
return false;
}
switch ( m_SelectedControlPoint )
{
default:
// Nothing selected --> nothing to reset
return false;
case 0:
{
// Control point 0 selected: exchange points 0 and 1
Point2D tmpPoint = this->GetControlPoint( 0 );
this->SetControlPoint( 0, this->GetControlPoint( 1 ) );
this->SetControlPoint( 1, tmpPoint );
// FALLS THROUGH!
}
case 1:
{
// Control point 0 or 1 selected: reset number of control points to two
this->ResetNumberOfControlPoints( 2 );
this->SelectControlPoint( 1 );
return true;
}
case 2:
{
// Control point 2 selected: replace point 0 with point 3 and point 1 with point 2
this->SetControlPoint( 0, this->GetControlPoint( 3 ) );
this->SetControlPoint( 1, this->GetControlPoint( 2 ) );
// Adjust selected control point, reset number of control points to two
this->ResetNumberOfControlPoints( 2 );
this->SelectControlPoint( 1 );
return true;
}
case 3:
{
// Control point 3 selected: replace point 0 with point 2 and point 1 with point 3
this->SetControlPoint( 0, this->GetControlPoint( 2 ) );
this->SetControlPoint( 1, this->GetControlPoint( 3 ) );
// Adjust selected control point, reset number of control points to two
this->ResetNumberOfControlPoints( 2 );
this->SelectControlPoint( 1 );
return true;
}
}
}
unsigned int mitk::PlanarCross::GetNumberOfFeatures() const
{
if ( this->GetSingleLineMode() || (this->GetNumberOfControlPoints() < 4) )
{
return 1;
}
else
{
return 2;
}
}
mitk::Point2D mitk::PlanarCross::ApplyControlPointConstraints( unsigned int index, const Point2D& point )
{
// Apply spatial constraints from superclass and from this class until the resulting constrained
// point converges. Although not an optimal implementation, this iterative approach
// helps to respect both constraints from the superclass and from this class. Without this,
// situations may occur where control points are constrained by the superclass, but again
// moved out of the superclass bounds by the subclass, or vice versa.
unsigned int count = 0; // ensures stop of approach if point does not converge in reasonable time
Point2D confinedPoint = point;
Point2D superclassConfinedPoint;
do
{
superclassConfinedPoint = Superclass::ApplyControlPointConstraints( index, confinedPoint );
confinedPoint = this->InternalApplyControlPointConstraints( index, superclassConfinedPoint );
++count;
} while ( (confinedPoint.EuclideanDistanceTo( superclassConfinedPoint ) > mitk::eps)
&& (count < 32) );
return confinedPoint;
}
mitk::Point2D mitk::PlanarCross::InternalApplyControlPointConstraints( unsigned int index, const Point2D& point )
{
// Apply constraints depending on current interaction state
switch ( index )
{
case 2:
{
// Check if 3rd control point is outside of the range (2D area) defined by the first
// line (via the first two control points); if it is outside, clip it to the bounds
const Point2D p1 = this->GetControlPoint( 0 );
const Point2D p2 = this->GetControlPoint( 1 );
Vector2D n1 = p2 - p1;
n1.Normalize();
Vector2D v1 = point - p1;
double dotProduct = n1 * v1;
Point2D crossPoint = p1 + n1 * dotProduct;;
Vector2D crossVector = point - crossPoint;
if ( dotProduct < 0.0 )
{
// Out-of-bounds on the left: clip point to left boundary
return (p1 + crossVector);
}
else if ( dotProduct > p2.EuclideanDistanceTo( p1 ) )
{
// Out-of-bounds on the right: clip point to right boundary
return (p2 + crossVector);
}
else
{
// Pass back original point
return point;
}
}
case 3:
{
// Constrain 4th control point so that with the 3rd control point it forms
// a line orthogonal to the first line (constraint 1); the 4th control point
// must lie on the opposite side of the line defined by the first two control
// points than the 3rd control point (constraint 2)
const Point2D p1 = this->GetControlPoint( 0 );
const Point2D p2 = this->GetControlPoint( 1 );
const Point2D p3 = this->GetControlPoint( 2 );
// Calculate distance of original point from orthogonal line the corrected
// point should lie on to project the point onto this line
Vector2D n1 = p2 - p1;
n1.Normalize();
Vector2D v1 = point - p3;
double dotProduct1 = n1 * v1;
Point2D pointOnLine = point - n1 * dotProduct1;
// Project new point onto line [p1, p2]
Vector2D v2 = pointOnLine - p1;
double dotProduct2 = n1 * v2;
Point2D crossingPoint = p1 + n1 * dotProduct2;
// Determine whether the projected point on the line, or the crossing point should be
// used (according to the second constraint in the comment above)
if ( (pointOnLine.SquaredEuclideanDistanceTo( p3 ) > crossingPoint.SquaredEuclideanDistanceTo( p3 ))
&& (pointOnLine.SquaredEuclideanDistanceTo( p3 ) > pointOnLine.SquaredEuclideanDistanceTo( crossingPoint )) )
{
return pointOnLine;
}
else
{
return crossingPoint;
}
}
default:
return point;
}
}
void mitk::PlanarCross::GeneratePolyLine()
{
this->SetNumberOfPolyLines(1);
this->ClearPolyLines();
if (this->GetNumberOfControlPoints() > 2)
this->SetNumberOfPolyLines( 2 );
for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
{
if (i < 2)
this->AppendPointToPolyLine(0, this->GetControlPoint(i));
if (i > 1)
this->AppendPointToPolyLine(1, this->GetControlPoint(i));
}
}
void mitk::PlanarCross::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// Generate helper polyline (orientation line orthogonal to first line)
// if the third control point is currently being set
if ( this->GetNumberOfControlPoints() != 3 )
{
m_HelperPolyLinesToBePainted->SetElement( 0, false );
return;
}
m_HelperPolyLinesToBePainted->SetElement( 0, true );
this->ClearHelperPolyLines();
// Calculate cross point of first line (p1 to p2) and orthogonal line through
// the third control point (p3)
const Point2D p1 = this->GetControlPoint( 0 );
const Point2D p2 = this->GetControlPoint( 1 );
const Point2D p3 = this->GetControlPoint( 2 );
Vector2D n1 = p2 - p1;
n1.Normalize();
Vector2D v1 = p3 - p1;
Point2D crossPoint = p1 + n1 * (n1 * v1);
Vector2D v2 = crossPoint - p3;
if ( v2.GetNorm() < 1.0 )
{
// If third point is on the first line, draw orthogonal "infinite" line
// through cross point on line
Vector2D v0;
v0[0] = n1[1];
v0[1] = -n1[0];
this->AppendPointToHelperPolyLine(0, Point2D(p3 - v0 * 10000.0));
this->AppendPointToHelperPolyLine(0, Point2D(p3 + v0 * 10000.0));
}
else
{
// Else, draw orthogonal line starting from third point and crossing the
// first line, open-ended only on the other side
this->AppendPointToHelperPolyLine(0, p3);
this->AppendPointToHelperPolyLine(0, Point2D(p3 + v2 * 10000.0));
}
}
void mitk::PlanarCross::EvaluateFeaturesInternal()
{
// Calculate length of first line
const Point3D &p0 = this->GetWorldControlPoint( 0 );
const Point3D &p1 = this->GetWorldControlPoint( 1 );
double l1 = p0.EuclideanDistanceTo( p1 );
// Calculate length of second line
double l2 = 0.0;
if ( !this->GetSingleLineMode() && (this->GetNumberOfControlPoints() > 3) )
{
const Point3D &p2 = this->GetWorldControlPoint( 2 );
const Point3D &p3 = this->GetWorldControlPoint( 3 );
l2 = p2.EuclideanDistanceTo( p3 );
}
double longestDiameter;
double shortAxisDiameter;
if ( l1 > l2 )
{
longestDiameter = l1;
shortAxisDiameter = l2;
}
else
{
longestDiameter = l2;
shortAxisDiameter = l1;
}
this->SetQuantity( FEATURE_ID_LONGESTDIAMETER, longestDiameter );
this->SetQuantity( FEATURE_ID_SHORTAXISDIAMETER, shortAxisDiameter );
}
-
void mitk::PlanarCross::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
+
+ bool mitk::PlanarCross::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarCross* otherCross = dynamic_cast<const mitk::PlanarCross*>(&other);
+ if ( otherCross )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarCross.h b/Modules/PlanarFigure/DataManagement/mitkPlanarCross.h
index 217ed8c5ac..83a667e4df 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarCross.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarCross.h
@@ -1,132 +1,133 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_CROSS_H_
#define _MITK_PLANAR_CROSS_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure modeling a cross with two orthogonal lines
* on a plane.
*
* The cross consists of two two orthogonal lines, which are defined by four control points
* lying on a plane. The two control points of the first line are freely placable within
* the bounds of the underlying 2D geometry, while the two control points of the second line
* are ensured to meet the following constraints:
*
* 1.) The lines must be orthogonal to each other
* 2.) The second line must lie within the 2D area defined by the first line
* 3.) The two lines must intersect (at least with their boundaries)
*
* When placing the second line interactively, a graphical helper polyline is provided to the
* user to indicate the position and orthogonal orientation of the line if it would be placed
* at the current mouse position.
*
* When modifying one of the lines by interactively moving its control points, the respective
* other line is deleted and the user is prompted to draw it again.
*
* The class provide a special mode for drawing single lines (SingleLineModeOn/Off); in this
* case, interaction stops after the first line has been placed.
*
* The class provides the lengths of both lines via the "feature" interface, ordered by size.
*
* \sa PlanarFigureMapper2D
*/
class MitkPlanarFigure_EXPORT PlanarCross : public PlanarFigure
{
public:
mitkClassMacro( PlanarCross, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Indicates whether the PlanarFigure shall represent only a single line instead of an
* orthogonal cross. */
void SetSingleLineMode( bool singleLineMode );
/** \brief Indicates whether the PlanarFigure shall represent only a single line instead of an
* orthogonal cross. */
bool GetSingleLineMode() const;
/** \brief Indicates whether the PlanarFigure shall represent only a single line instead of an
* orthogonal cross. */
itkBooleanMacro( SingleLineMode ); // No need to reimplement; calls SetSingleLineMode()
/** \brief PlanarCross has either two or four control points, depending on the operation mode. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return this->GetSingleLineMode() ? 2 : 4;
}
/** \brief PlanarCross has either two or four control points, depending on the operation mode. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return this->GetSingleLineMode() ? 2 : 4;
}
/** \brief The cross shall be reset to a single line when a control point is selected. */
virtual bool ResetOnPointSelect();
/** \brief Returns the number of features available for this PlanarCross (1 or 2). */
virtual unsigned int GetNumberOfFeatures() const;
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarCross();
virtual ~PlanarCross();
mitkCloneMacro(Self);
/** \brief Spatially constrain control points of second (orthogonal) line */
virtual Point2D ApplyControlPointConstraints( unsigned int index, const Point2D& point );
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
// Feature identifiers
const unsigned int FEATURE_ID_LONGESTDIAMETER;
const unsigned int FEATURE_ID_SHORTAXISDIAMETER;
private:
/** Internal method for applying spatial constraints. */
virtual Point2D InternalApplyControlPointConstraints( unsigned int index, const Point2D& point );
};
} // namespace mitk
#endif //_MITK_PLANAR_CROSS_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.cpp
index 68dfab03db..5068f00549 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.cpp
@@ -1,251 +1,270 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarDoubleEllipse.h"
#include <mitkProperties.h>
#include <algorithm>
mitk::PlanarDoubleEllipse::PlanarDoubleEllipse()
: FEATURE_ID_MAJOR_AXIS(Superclass::AddFeature("Major Axis", "mm")),
FEATURE_ID_MINOR_AXIS(Superclass::AddFeature("Minor Axis", "mm")),
FEATURE_ID_THICKNESS(Superclass::AddFeature("Thickness", "mm")),
m_NumberOfSegments(64),
m_ConstrainCircle(true),
m_ConstrainThickness(true)
{
this->ResetNumberOfControlPoints(4);
this->SetNumberOfPolyLines(2);
this->SetProperty("closed", mitk::BoolProperty::New(true));
}
mitk::PlanarDoubleEllipse::~PlanarDoubleEllipse()
{
}
mitk::Point2D mitk::PlanarDoubleEllipse::ApplyControlPointConstraints(unsigned int index, const Point2D& point)
{
if (index == 2 && !m_ConstrainCircle)
{
Point2D centerPoint = this->GetControlPoint(0);
Vector2D outerMajorVector = this->GetControlPoint(1) - centerPoint;
Vector2D minorDirection;
minorDirection[0] = outerMajorVector[1];
minorDirection[1] = -outerMajorVector[0];
minorDirection.Normalize();
double outerMajorRadius = outerMajorVector.GetNorm();
double innerMajorRadius = (this->GetControlPoint(3) - centerPoint).GetNorm();
ScalarType radius = std::max(outerMajorRadius - innerMajorRadius, std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));
return centerPoint + minorDirection * radius;
}
else if (index == 3 && !m_ConstrainThickness)
{
Point2D centerPoint = this->GetControlPoint(0);
Vector2D outerMajorVector = this->GetControlPoint(1) - centerPoint;
double outerMajorRadius = outerMajorVector.GetNorm();
double outerMinorRadius = (this->GetControlPoint(2) - centerPoint).GetNorm();
ScalarType radius = std::max(outerMajorRadius - outerMinorRadius, std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));
outerMajorVector.Normalize();
return centerPoint - outerMajorVector * radius;
}
return point;
}
void mitk::PlanarDoubleEllipse::EvaluateFeaturesInternal()
{
Point2D centerPoint = this->GetControlPoint(0);
ScalarType outerMajorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(1));
this->SetQuantity(FEATURE_ID_MAJOR_AXIS, 2 * outerMajorRadius);
this->SetQuantity(FEATURE_ID_MINOR_AXIS, 2 * centerPoint.EuclideanDistanceTo(this->GetControlPoint(2)));
this->SetQuantity(FEATURE_ID_THICKNESS, outerMajorRadius - centerPoint.EuclideanDistanceTo(this->GetControlPoint(3)));
}
void mitk::PlanarDoubleEllipse::GenerateHelperPolyLine(double, unsigned int)
{
}
void mitk::PlanarDoubleEllipse::GeneratePolyLine()
{
this->ClearPolyLines();
Point2D centerPoint = this->GetControlPoint(0);
Point2D outerMajorPoint = this->GetControlPoint(1);
Vector2D direction = outerMajorPoint - centerPoint;
direction.Normalize();
const ScalarType deltaAngle = vnl_math::pi / (m_NumberOfSegments / 2);
int start = 0;
int end = m_NumberOfSegments;
if (direction[1] < 0.0)
{
direction[0] = -direction[0];
end = m_NumberOfSegments / 2;
start = -end;
}
vnl_matrix_fixed<mitk::ScalarType, 2, 2> rotation;
rotation[1][0] = std::sin(std::acos(direction[0]));
rotation[0][0] = direction[0];
rotation[1][1] = direction[0];
rotation[0][1] = -rotation[1][0];
ScalarType outerMajorRadius = centerPoint.EuclideanDistanceTo(outerMajorPoint);
ScalarType outerMinorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
ScalarType innerMajorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(3));
ScalarType innerMinorRadius = innerMajorRadius - (outerMajorRadius - outerMinorRadius);
ScalarType angle;
ScalarType cosAngle;
ScalarType sinAngle;
vnl_vector_fixed<mitk::ScalarType, 2> vector;
Point2D point;
for (int i = start; i < end; ++i)
{
angle = i * deltaAngle;
cosAngle = std::cos(angle);
sinAngle = std::sin(angle);
vector[0] = outerMajorRadius * cosAngle;
vector[1] = outerMinorRadius * sinAngle;
vector = rotation * vector;
point[0] = centerPoint[0] + vector[0];
point[1] = centerPoint[1] + vector[1];
this->AppendPointToPolyLine(0, point);
vector[0] = innerMajorRadius * cosAngle;
vector[1] = innerMinorRadius * sinAngle;
vector = rotation * vector;
point[0] = centerPoint[0] + vector[0];
point[1] = centerPoint[1] + vector[1];
this->AppendPointToPolyLine(1, point);
}
}
unsigned int mitk::PlanarDoubleEllipse::GetNumberOfSegments() const
{
return m_NumberOfSegments;
}
void mitk::PlanarDoubleEllipse::SetNumberOfSegments(unsigned int numSegments)
{
m_NumberOfSegments = std::max(4U, numSegments);
if (this->IsPlaced())
{
this->GeneratePolyLine();
this->Modified();
}
}
unsigned int mitk::PlanarDoubleEllipse::GetMaximumNumberOfControlPoints() const
{
return 4;
}
unsigned int mitk::PlanarDoubleEllipse::GetMinimumNumberOfControlPoints() const
{
return 4;
}
bool mitk::PlanarDoubleEllipse::SetControlPoint(unsigned int index, const Point2D& point, bool createIfDoesNotExist)
{
switch (index)
{
case 0:
{
Point2D centerPoint = this->GetControlPoint(0);
Vector2D vector = point - centerPoint;
Superclass::SetControlPoint(0, point, createIfDoesNotExist);
Superclass::SetControlPoint(1, this->GetControlPoint(1) + vector, createIfDoesNotExist);
Superclass::SetControlPoint(2, this->GetControlPoint(2) + vector, createIfDoesNotExist);
Superclass::SetControlPoint(3, this->GetControlPoint(3) + vector, createIfDoesNotExist);
break;
}
case 1:
{
Vector2D vector = point - this->GetControlPoint(1);
Superclass::SetControlPoint(1, point, createIfDoesNotExist);
Point2D centerPoint = this->GetControlPoint(0);
Vector2D outerMajorVector = point - centerPoint;
Vector2D outerMinorVector;
outerMinorVector[0] = outerMajorVector[1];
outerMinorVector[1] = -outerMajorVector[0];
if (!m_ConstrainCircle)
{
outerMinorVector.Normalize();
outerMinorVector *= centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
}
Superclass::SetControlPoint(2, centerPoint + outerMinorVector, createIfDoesNotExist);
Vector2D innerMajorVector = outerMajorVector;
if (!m_ConstrainThickness)
{
innerMajorVector.Normalize();
innerMajorVector *= centerPoint.EuclideanDistanceTo(this->GetControlPoint(3) - vector);
}
Superclass::SetControlPoint(3, centerPoint - innerMajorVector, createIfDoesNotExist);
break;
}
case 2:
{
m_ConstrainCircle = false;
Superclass::SetControlPoint(2, point, createIfDoesNotExist);
break;
}
case 3:
{
m_ConstrainThickness = false;
Superclass::SetControlPoint(3, point, createIfDoesNotExist);
break;
}
default:
return false;
}
return true;
}
+
+ bool mitk::PlanarDoubleEllipse::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarDoubleEllipse* otherDoubleEllipse = dynamic_cast<const mitk::PlanarDoubleEllipse*>(&other);
+ if ( otherDoubleEllipse )
+ {
+ if( this->m_ConstrainCircle != otherDoubleEllipse->m_ConstrainCircle)
+ return false;
+ if( this->m_ConstrainThickness != otherDoubleEllipse->m_ConstrainThickness)
+ return false;
+ if( this->m_NumberOfSegments != otherDoubleEllipse->m_NumberOfSegments)
+ return false;
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.h b/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.h
index ff67568439..7f42148beb 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarDoubleEllipse.h
@@ -1,61 +1,63 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkPlanarDoubleEllipse_h
#define mitkPlanarDoubleEllipse_h
#include <mitkPlanarFigure.h>
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class MitkPlanarFigure_EXPORT PlanarDoubleEllipse : public PlanarFigure
{
public:
mitkClassMacro(PlanarDoubleEllipse, PlanarFigure);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
unsigned int GetNumberOfSegments() const;
void SetNumberOfSegments(unsigned int numSegments);
virtual unsigned int GetMaximumNumberOfControlPoints() const;
virtual unsigned int GetMinimumNumberOfControlPoints() const;
virtual bool SetControlPoint(unsigned int index, const Point2D& point, bool createIfDoesNotExist = true);
const unsigned int FEATURE_ID_MAJOR_AXIS;
const unsigned int FEATURE_ID_MINOR_AXIS;
const unsigned int FEATURE_ID_THICKNESS;
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
+
protected:
PlanarDoubleEllipse();
virtual ~PlanarDoubleEllipse();
mitkCloneMacro(Self)
virtual mitk::Point2D ApplyControlPointConstraints(unsigned int index, const Point2D& point);
virtual void EvaluateFeaturesInternal();
virtual void GenerateHelperPolyLine(double, unsigned int);
virtual void GeneratePolyLine();
private:
unsigned int m_NumberOfSegments;
bool m_ConstrainCircle;
bool m_ConstrainThickness;
};
}
#endif
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.cpp
index 49ddb0f02d..443e89b7f7 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.cpp
@@ -1,280 +1,296 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <algorithm>
#include "mitkPlanarEllipse.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
#include <algorithm>
mitk::PlanarEllipse::PlanarEllipse()
: FEATURE_ID_MAJOR_AXIS(Superclass::AddFeature("Major Axis", "mm")),
FEATURE_ID_MINOR_AXIS(Superclass::AddFeature("Minor Axis", "mm")),
m_MinRadius(0),
m_MaxRadius(100),
m_MinMaxRadiusContraintsActive(false),
m_TreatAsCircle(true)
{
// Ellipse has three control points
this->ResetNumberOfControlPoints( 4 );
this->SetNumberOfPolyLines( 2 );
this->SetProperty( "closed", mitk::BoolProperty::New(true) );
}
mitk::PlanarEllipse::~PlanarEllipse()
{
}
bool mitk::PlanarEllipse::SetControlPoint( unsigned int index, const Point2D &point, bool createIfDoesNotExist )
{
if(index == 0) // moving center point and control points accordingly
{
const Point2D &centerPoint = GetControlPoint( 0 );
Point2D boundaryPoint1 = GetControlPoint( 1 );
Point2D boundaryPoint2 = GetControlPoint( 2 );
Point2D boundaryPoint3 = GetControlPoint( 3 );
vnl_vector<ScalarType> vec = (point.GetVnlVector() - centerPoint.GetVnlVector());
boundaryPoint1[0] += vec[0];
boundaryPoint1[1] += vec[1];
boundaryPoint2[0] += vec[0];
boundaryPoint2[1] += vec[1];
boundaryPoint3[0] += vec[0];
boundaryPoint3[1] += vec[1];
PlanarFigure::SetControlPoint( 0, point, createIfDoesNotExist );
PlanarFigure::SetControlPoint( 1, boundaryPoint1, createIfDoesNotExist );
PlanarFigure::SetControlPoint( 2, boundaryPoint2, createIfDoesNotExist );
PlanarFigure::SetControlPoint( 3, boundaryPoint3, createIfDoesNotExist );
return true;
}
else if (index < 3)
{
PlanarFigure::SetControlPoint( index, point, createIfDoesNotExist );
int otherIndex = index+1;
if (otherIndex > 2)
otherIndex = 1;
const Point2D &centerPoint = GetControlPoint( 0 );
Point2D otherPoint = GetControlPoint( otherIndex );
Point2D point3 = GetControlPoint( 3 );
Vector2D vec1 = point - centerPoint;
Vector2D vec2;
if (index == 1 && m_TreatAsCircle )
{
float x = vec1[0];
vec2[0] = vec1[1];
vec2[1] = x;
if (index==1)
vec2[0] *= -1;
else
vec2[1] *= -1;
otherPoint = centerPoint+vec2;
PlanarFigure::SetControlPoint( otherIndex, otherPoint, createIfDoesNotExist );
float r = centerPoint.EuclideanDistanceTo(otherPoint);
// adjust additional third control point
Point2D p3 = this->GetControlPoint(3);
Vector2D vec3;
vec3[0] = p3[0]-centerPoint[0];
vec3[1] = p3[1]-centerPoint[1];
if (vec3[0]!=0 || vec3[1]!=0)
{
vec3.Normalize();
vec3 *= r;
}
else
{
vec3[0] = r;
vec3[1] = 0;
}
point3 = centerPoint + vec3;
PlanarFigure::SetControlPoint( 3, point3, createIfDoesNotExist );
}
else if ( vec1.GetNorm() > 0 )
{
float r = centerPoint.EuclideanDistanceTo(otherPoint);
float x = vec1[0];
vec2[0] = vec1[1];
vec2[1] = x;
if (index==1)
vec2[0] *= -1;
else
vec2[1] *= -1;
vec2.Normalize(); vec2 *= r;
if ( vec2.GetNorm() > 0 )
{
otherPoint = centerPoint+vec2;
PlanarFigure::SetControlPoint( otherIndex, otherPoint, createIfDoesNotExist );
}
// adjust third control point
Vector2D vec3 = point3 - centerPoint; vec3.Normalize();
double r1 = centerPoint.EuclideanDistanceTo( GetControlPoint( 1 ) );
double r2 = centerPoint.EuclideanDistanceTo( GetControlPoint( 2 ) );
Point2D newPoint = centerPoint + vec3*std::max(r1, r2);
PlanarFigure::SetControlPoint( 3, newPoint, createIfDoesNotExist );
m_TreatAsCircle = false;
}
return true;
}
else if (index == 3)
{
Point2D centerPoint = GetControlPoint( 0 );
Vector2D vec3 = point - centerPoint; vec3.Normalize();
double r1 = centerPoint.EuclideanDistanceTo( GetControlPoint( 1 ) );
double r2 = centerPoint.EuclideanDistanceTo( GetControlPoint( 2 ) );
Point2D newPoint = centerPoint + vec3*std::max(r1, r2);
PlanarFigure::SetControlPoint( index, newPoint, createIfDoesNotExist );
m_TreatAsCircle = false;
return true;
}
return false;
}
void mitk::PlanarEllipse::PlaceFigure( const mitk::Point2D &point )
{
PlanarFigure::PlaceFigure( point );
m_SelectedControlPoint = 1;
}
mitk::Point2D mitk::PlanarEllipse::ApplyControlPointConstraints(unsigned int index, const Point2D &point)
{
return point;
Point2D indexPoint;
this->GetPlaneGeometry()->WorldToIndex( point, indexPoint );
BoundingBox::BoundsArrayType bounds = this->GetPlaneGeometry()->GetBounds();
if ( indexPoint[0] < bounds[0] ) { indexPoint[0] = bounds[0]; }
if ( indexPoint[0] > bounds[1] ) { indexPoint[0] = bounds[1]; }
if ( indexPoint[1] < bounds[2] ) { indexPoint[1] = bounds[2]; }
if ( indexPoint[1] > bounds[3] ) { indexPoint[1] = bounds[3]; }
Point2D constrainedPoint;
this->GetPlaneGeometry()->IndexToWorld( indexPoint, constrainedPoint );
if(m_MinMaxRadiusContraintsActive)
{
if( index != 0)
{
const Point2D &centerPoint = this->GetControlPoint(0);
double euclideanDinstanceFromCenterToPoint1 = centerPoint.EuclideanDistanceTo(point);
Vector2D vectorProjectedPoint;
vectorProjectedPoint = point - centerPoint;
vectorProjectedPoint.Normalize();
if( euclideanDinstanceFromCenterToPoint1 > m_MaxRadius )
{
vectorProjectedPoint *= m_MaxRadius;
constrainedPoint = centerPoint;
constrainedPoint += vectorProjectedPoint;
}
else if( euclideanDinstanceFromCenterToPoint1 < m_MinRadius )
{
vectorProjectedPoint *= m_MinRadius;
constrainedPoint = centerPoint;
constrainedPoint += vectorProjectedPoint;
}
}
}
return constrainedPoint;
}
void mitk::PlanarEllipse::GeneratePolyLine()
{
// clear the PolyLine-Contrainer, it will be reconstructed soon enough...
this->ClearPolyLines();
const Point2D &centerPoint = GetControlPoint( 0 );
const Point2D &boundaryPoint1 = GetControlPoint( 1 );
const Point2D &boundaryPoint2 = GetControlPoint( 2 );
Vector2D dir = boundaryPoint1 - centerPoint; dir.Normalize();
vnl_matrix_fixed<float, 2, 2> rot;
// differentiate between clockwise and counterclockwise rotation
int start = 0;
int end = 64;
if (dir[1]<0)
{
dir[0] = -dir[0];
start = -32;
end = 32;
}
// construct rotation matrix to align ellipse with control point vector
rot[0][0] = dir[0];
rot[1][1] = rot[0][0];
rot[1][0] = sin(acos(rot[0][0]));
rot[0][1] = -rot[1][0];
double radius1 = centerPoint.EuclideanDistanceTo( boundaryPoint1 );
double radius2 = centerPoint.EuclideanDistanceTo( boundaryPoint2 );
// Generate poly-line with 64 segments
for ( int t = start; t < end; ++t )
{
double alpha = (double) t * vnl_math::pi / 32.0;
// construct the new polyline point ...
vnl_vector_fixed< float, 2 > vec;
vec[0] = radius1 * cos( alpha );
vec[1] = radius2 * sin( alpha );
vec = rot*vec;
Point2D polyLinePoint;
polyLinePoint[0] = centerPoint[0] + vec[0];
polyLinePoint[1] = centerPoint[1] + vec[1];
// ... and append it to the PolyLine.
// No extending supported here, so we can set the index of the PolyLineElement to '0'
this->AppendPointToPolyLine(0, polyLinePoint);
}
this->AppendPointToPolyLine(1, centerPoint);
this->AppendPointToPolyLine(1, this->GetControlPoint(3));
}
void mitk::PlanarEllipse::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// A circle does not require a helper object
}
void mitk::PlanarEllipse::EvaluateFeaturesInternal()
{
Point2D centerPoint = this->GetControlPoint(0);
this->SetQuantity(FEATURE_ID_MAJOR_AXIS, 2 * centerPoint.EuclideanDistanceTo(this->GetControlPoint(1)));
this->SetQuantity(FEATURE_ID_MINOR_AXIS, 2 * centerPoint.EuclideanDistanceTo(this->GetControlPoint(2)));
}
void mitk::PlanarEllipse::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
+
+ bool mitk::PlanarEllipse::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarEllipse* otherEllipse = dynamic_cast<const mitk::PlanarEllipse*>(&other);
+ if ( otherEllipse )
+ {
+ if(this->m_TreatAsCircle != otherEllipse->m_TreatAsCircle)
+ return false;
+
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.h b/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.h
index ea900bf835..5654e737cb 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarEllipse.h
@@ -1,140 +1,142 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_ELLIPSE_H_
#define _MITK_PLANAR_ELLIPSE_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a circle
* through two control points
*/
class MitkPlanarFigure_EXPORT PlanarEllipse : public PlanarFigure
{
public:
mitkClassMacro( PlanarEllipse, PlanarFigure )
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
virtual void PlaceFigure( const Point2D &point );
bool SetControlPoint( unsigned int index, const Point2D &point, bool createIfDoesNotExist = true );
/** \brief Ellipse has 3 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 4;
}
/** \brief Ellipse has 3 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 4;
}
/** \brief Sets the minimum radius
*/
void SetMinimumRadius( double radius )
{
m_MinRadius = radius;
}
/** \brief Gets the minimum radius
*/
double GetMinimumRadius()
{
return m_MinRadius;
}
/** \brief Sets the maximum radius
*/
void SetMaximumRadius( double radius )
{
m_MaxRadius = radius;
}
/** \brief Gets the minimum radius
*/
double GetMaximumRadius()
{
return m_MaxRadius;
}
void ActivateMinMaxRadiusContstraints( bool active )
{
m_MinMaxRadiusContraintsActive = active;
}
/** \brief Treat ellipse as circle (equal radii)
*/
void SetTreatAsCircle( bool active )
{
m_TreatAsCircle = active;
}
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
+
const unsigned int FEATURE_ID_MAJOR_AXIS;
const unsigned int FEATURE_ID_MINOR_AXIS;
protected:
PlanarEllipse();
virtual ~PlanarEllipse();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Spatially constrain control points of second (orthogonal) line */
virtual Point2D ApplyControlPointConstraints( unsigned int index, const Point2D& point );
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
//Member variables:
double m_MinRadius;
double m_MaxRadius;
bool m_MinMaxRadiusContraintsActive;
bool m_TreatAsCircle;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_ELLIPSE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp
index 2b4fdbbbb0..5d69c365d6 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp
@@ -1,780 +1,895 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarFigure.h"
#include "mitkPlaneGeometry.h"
#include <mitkProperties.h>
#include <mitkProportionalTimeGeometry.h>
#include <algorithm>
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif __clang__
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif _MSC_VER
# pragma warning (push)
# pragma warning (disable: 4996)
#endif
mitk::PlanarFigure::PolyLineElement::PolyLineElement(Point2D point, int index)
: Point(point),
Index(index)
{
}
mitk::PlanarFigure::PolyLineElement::PolyLineElement(const Point2D& point)
: Point(point),
Index(-1)
{
}
mitk::PlanarFigure::PolyLineElement::PolyLineElement(const PolyLineElement &other)
: Point(other.Point),
Index(other.Index)
{
}
mitk::PlanarFigure::PolyLineElement& mitk::PlanarFigure::PolyLineElement::operator=(const PolyLineElement &other)
{
if (this != &other)
{
Point = other.Point;
Index = other.Index;
}
return *this;
}
mitk::PlanarFigure::PolyLineElement::operator mitk::Point2D&()
{
return Point;
}
mitk::PlanarFigure::PolyLineElement::operator const mitk::Point2D&() const
{
return Point;
}
mitk::PlanarFigure::PlanarFigure()
: m_SelectedControlPoint( -1 ),
m_PreviewControlPointVisible( false ),
m_FigurePlaced( false ),
m_PlaneGeometry( NULL ),
m_PolyLineUpToDate(false),
m_HelperLinesUpToDate(false),
m_FeaturesUpToDate(false),
m_FeaturesMTime( 0 )
{
m_HelperPolyLinesToBePainted = BoolContainerType::New();
m_DisplaySize.first = 0.0;
m_DisplaySize.second = 0;
this->SetProperty( "closed", mitk::BoolProperty::New( false ) );
// Currently only single-time-step geometries are supported
this->InitializeTimeGeometry( 1 );
}
mitk::PlanarFigure::~PlanarFigure()
{
}
mitk::PlanarFigure::PlanarFigure(const Self& other)
: BaseData(other),
m_ControlPoints(other.m_ControlPoints),
m_NumberOfControlPoints(other.m_NumberOfControlPoints),
m_SelectedControlPoint(other.m_SelectedControlPoint),
m_PolyLines(other.m_PolyLines),
m_HelperPolyLines(other.m_HelperPolyLines),
m_HelperPolyLinesToBePainted(other.m_HelperPolyLinesToBePainted->Clone()),
m_PreviewControlPoint(other.m_PreviewControlPoint),
m_PreviewControlPointVisible(other.m_PreviewControlPointVisible),
m_FigurePlaced(other.m_FigurePlaced),
m_PlaneGeometry(other.m_PlaneGeometry), // do not clone since SetPlaneGeometry() doesn't clone either
m_PolyLineUpToDate(other.m_PolyLineUpToDate),
m_HelperLinesUpToDate(other.m_HelperLinesUpToDate),
m_FeaturesUpToDate(other.m_FeaturesUpToDate),
m_Features(other.m_Features),
m_FeaturesMTime(other.m_FeaturesMTime),
m_DisplaySize(other.m_DisplaySize)
{
}
void mitk::PlanarFigure::SetPlaneGeometry( mitk::PlaneGeometry *geometry )
{
this->SetGeometry( geometry );
m_PlaneGeometry = dynamic_cast<PlaneGeometry *>(GetGeometry(0));//geometry;
}
const mitk::PlaneGeometry *mitk::PlanarFigure::GetPlaneGeometry() const
{
return m_PlaneGeometry;
}
bool mitk::PlanarFigure::IsClosed() const
{
mitk::BoolProperty* closed = dynamic_cast< mitk::BoolProperty* >( this->GetProperty( "closed" ).GetPointer() );
if ( closed != NULL )
{
return closed->GetValue();
}
return false;
}
void mitk::PlanarFigure::PlaceFigure( const mitk::Point2D& point )
{
for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
m_ControlPoints.push_back( this->ApplyControlPointConstraints( i, point ) );
}
m_FigurePlaced = true;
m_SelectedControlPoint = 1;
}
bool mitk::PlanarFigure::AddControlPoint( const mitk::Point2D& point, int position )
{
// if we already have the maximum number of control points, do nothing
if ( m_NumberOfControlPoints < this->GetMaximumNumberOfControlPoints() )
{
// if position has not been defined or position would be the last control point, just append the new one
// we also append a new point if we click onto the line between the first two control-points if the second control-point is selected
// -> special case for PlanarCross
if ( position == -1 || position > (int)m_NumberOfControlPoints-1 || (position == 1 && m_SelectedControlPoint == 2) )
{
if ( m_ControlPoints.size() > this->GetMaximumNumberOfControlPoints()-1 )
{
// get rid of deprecated control points in the list. This is necessary
// as ::ResetNumberOfControlPoints() only sets the member, does not resize the list!
m_ControlPoints.resize( this->GetNumberOfControlPoints() );
}
m_ControlPoints.push_back( this->ApplyControlPointConstraints( m_NumberOfControlPoints, point ) );
m_SelectedControlPoint = m_NumberOfControlPoints;
}
else
{
// insert the point at the given position and set it as selected point
ControlPointListType::iterator iter = m_ControlPoints.begin() + position;
m_ControlPoints.insert( iter, this->ApplyControlPointConstraints( position, point ) );
for( unsigned int i = 0; i < m_ControlPoints.size(); ++i )
{
if( point == m_ControlPoints.at(i) )
{
m_SelectedControlPoint = i;
}
}
}
// polylines & helperpolylines need to be repainted
m_PolyLineUpToDate = false;
m_HelperLinesUpToDate = false;
m_FeaturesUpToDate = false;
// one control point more
++m_NumberOfControlPoints;
return true;
}
else
{
return false;
}
}
bool mitk::PlanarFigure::SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist )
{
bool controlPointSetCorrectly = false;
if (createIfDoesNotExist)
{
if ( m_NumberOfControlPoints <= index )
{
m_ControlPoints.push_back( this->ApplyControlPointConstraints( index, point ) );
m_NumberOfControlPoints++;
}
else
{
m_ControlPoints.at( index ) = this->ApplyControlPointConstraints( index, point );
}
controlPointSetCorrectly = true;
}
else if ( index < m_NumberOfControlPoints )
{
m_ControlPoints.at( index ) = this->ApplyControlPointConstraints( index, point );
controlPointSetCorrectly = true;
}
else
{
return false;
}
if ( controlPointSetCorrectly )
{
m_PolyLineUpToDate = false;
m_HelperLinesUpToDate = false;
m_FeaturesUpToDate = false;
}
return controlPointSetCorrectly;
}
bool mitk::PlanarFigure::SetCurrentControlPoint( const Point2D& point )
{
if ( (m_SelectedControlPoint < 0) || (m_SelectedControlPoint >= (int)m_NumberOfControlPoints) )
{
return false;
}
return this->SetControlPoint(m_SelectedControlPoint, point, false);
}
unsigned int mitk::PlanarFigure::GetNumberOfControlPoints() const
{
return m_NumberOfControlPoints;
}
bool mitk::PlanarFigure::SelectControlPoint( unsigned int index )
{
if ( index < this->GetNumberOfControlPoints() )
{
m_SelectedControlPoint = index;
return true;
}
else
{
return false;
}
}
bool mitk::PlanarFigure::DeselectControlPoint()
{
bool wasSelected = ( m_SelectedControlPoint != -1);
m_SelectedControlPoint = -1;
return wasSelected;
}
void mitk::PlanarFigure::SetPreviewControlPoint( const Point2D& point )
{
m_PreviewControlPoint = point;
m_PreviewControlPointVisible = true;
}
void mitk::PlanarFigure::ResetPreviewContolPoint()
{
m_PreviewControlPointVisible = false;
}
mitk::Point2D mitk::PlanarFigure::GetPreviewControlPoint()
{
return m_PreviewControlPoint;
}
bool mitk::PlanarFigure::IsPreviewControlPointVisible()
{
return m_PreviewControlPointVisible;
}
mitk::Point2D mitk::PlanarFigure::GetControlPoint( unsigned int index ) const
{
if ( index < m_NumberOfControlPoints )
{
return m_ControlPoints.at( index );
}
itkExceptionMacro( << "GetControlPoint(): Invalid index!" );
}
mitk::Point3D mitk::PlanarFigure::GetWorldControlPoint( unsigned int index ) const
{
Point3D point3D;
if ( (m_PlaneGeometry != NULL) && (index < m_NumberOfControlPoints) )
{
m_PlaneGeometry->Map( m_ControlPoints.at( index ), point3D );
return point3D;
}
itkExceptionMacro( << "GetWorldControlPoint(): Invalid index!" );
}
const mitk::PlanarFigure::PolyLineType
mitk::PlanarFigure::GetPolyLine(unsigned int index)
{
mitk::PlanarFigure::PolyLineType polyLine;
if ( index > m_PolyLines.size() || !m_PolyLineUpToDate )
{
this->GeneratePolyLine();
m_PolyLineUpToDate = true;
}
return m_PolyLines.at( index );;
}
const mitk::PlanarFigure::PolyLineType
mitk::PlanarFigure::GetPolyLine(unsigned int index) const
{
return m_PolyLines.at( index );
}
void mitk::PlanarFigure::ClearPolyLines()
{
for ( std::vector<PolyLineType>::size_type i=0; i<m_PolyLines.size(); i++ )
{
m_PolyLines.at( i ).clear();
}
m_PolyLineUpToDate = false;
}
const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetHelperPolyLine( unsigned int index,
double mmPerDisplayUnit,
unsigned int displayHeight )
{
mitk::PlanarFigure::PolyLineType helperPolyLine;
if ( index < m_HelperPolyLines.size() )
{
// m_HelperLinesUpToDate does not cover changes in zoom-level, so we have to check previous values of the
// two parameters as well
if ( !m_HelperLinesUpToDate || m_DisplaySize.first != mmPerDisplayUnit || m_DisplaySize.second != displayHeight )
{
this->GenerateHelperPolyLine(mmPerDisplayUnit, displayHeight);
m_HelperLinesUpToDate = true;
// store these parameters to be able to check next time if somebody zoomed in or out
m_DisplaySize.first = mmPerDisplayUnit;
m_DisplaySize.second = displayHeight;
}
helperPolyLine = m_HelperPolyLines.at(index);
}
return helperPolyLine;
}
void mitk::PlanarFigure::ClearHelperPolyLines()
{
for ( std::vector<PolyLineType>::size_type i=0; i<m_HelperPolyLines.size(); i++ )
{
m_HelperPolyLines.at(i).clear();
}
m_HelperLinesUpToDate = false;
}
/** \brief Returns the number of features available for this PlanarFigure
* (such as, radius, area, ...). */
unsigned int mitk::PlanarFigure::GetNumberOfFeatures() const
{
return m_Features.size();
}
const char *mitk::PlanarFigure::GetFeatureName( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Name.c_str();
}
else
{
return NULL;
}
}
const char *mitk::PlanarFigure::GetFeatureUnit( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Unit.c_str();
}
else
{
return NULL;
}
}
double mitk::PlanarFigure::GetQuantity( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Quantity;
}
else
{
return 0.0;
}
}
bool mitk::PlanarFigure::IsFeatureActive( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Active;
}
else
{
return false;
}
}
bool mitk::PlanarFigure::IsFeatureVisible( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Visible;
}
else
{
return false;
}
}
void mitk::PlanarFigure::SetFeatureVisible( unsigned int index, bool visible )
{
if ( index < m_Features.size() )
{
m_Features[index].Visible = visible;
}
}
void mitk::PlanarFigure::EvaluateFeatures()
{
if ( !m_FeaturesUpToDate || !m_PolyLineUpToDate )
{
if ( !m_PolyLineUpToDate )
{
this->GeneratePolyLine();
}
this->EvaluateFeaturesInternal();
m_FeaturesUpToDate = true;
}
}
void mitk::PlanarFigure::UpdateOutputInformation()
{
// Bounds are NOT calculated here, since the PlaneGeometry defines a fixed
// frame (= bounds) for the planar figure.
Superclass::UpdateOutputInformation();
this->GetTimeGeometry()->Update();
}
void mitk::PlanarFigure::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::PlanarFigure::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::PlanarFigure::VerifyRequestedRegion()
{
return true;
}
void mitk::PlanarFigure::SetRequestedRegion(const itk::DataObject * /*data*/ )
{
}
void mitk::PlanarFigure::ResetNumberOfControlPoints( int numberOfControlPoints )
{
// DO NOT resize the list here, will cause crash!!
m_NumberOfControlPoints = numberOfControlPoints;
}
mitk::Point2D mitk::PlanarFigure::ApplyControlPointConstraints( unsigned int /*index*/, const Point2D& point )
{
if ( m_PlaneGeometry == NULL )
{
return point;
}
Point2D indexPoint;
m_PlaneGeometry->WorldToIndex( point, indexPoint );
BoundingBox::BoundsArrayType bounds = m_PlaneGeometry->GetBounds();
if ( indexPoint[0] < bounds[0] ) { indexPoint[0] = bounds[0]; }
if ( indexPoint[0] > bounds[1] ) { indexPoint[0] = bounds[1]; }
if ( indexPoint[1] < bounds[2] ) { indexPoint[1] = bounds[2]; }
if ( indexPoint[1] > bounds[3] ) { indexPoint[1] = bounds[3]; }
Point2D constrainedPoint;
m_PlaneGeometry->IndexToWorld( indexPoint, constrainedPoint );
return constrainedPoint;
}
unsigned int mitk::PlanarFigure::AddFeature( const char *featureName, const char *unitName )
{
unsigned int index = m_Features.size();
Feature newFeature( featureName, unitName );
m_Features.push_back( newFeature );
return index;
}
void mitk::PlanarFigure::SetFeatureName( unsigned int index, const char *featureName )
{
if ( index < m_Features.size() )
{
m_Features[index].Name = featureName;
}
}
void mitk::PlanarFigure::SetFeatureUnit( unsigned int index, const char *unitName )
{
if ( index < m_Features.size() )
{
m_Features[index].Unit = unitName;
}
}
void mitk::PlanarFigure::SetQuantity( unsigned int index, double quantity )
{
if ( index < m_Features.size() )
{
m_Features[index].Quantity = quantity;
}
}
void mitk::PlanarFigure::ActivateFeature( unsigned int index )
{
if ( index < m_Features.size() )
{
m_Features[index].Active = true;
}
}
void mitk::PlanarFigure::DeactivateFeature( unsigned int index )
{
if ( index < m_Features.size() )
{
m_Features[index].Active = false;
}
}
void mitk::PlanarFigure::InitializeTimeGeometry( unsigned int timeSteps )
{
mitk::PlaneGeometry::Pointer geometry2D = mitk::PlaneGeometry::New();
geometry2D->Initialize();
// The geometry is propagated automatically to all time steps,
// if EvenlyTimed is true...
ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
timeGeometry->Initialize(geometry2D, timeSteps);
SetTimeGeometry(timeGeometry);
}
void mitk::PlanarFigure::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
os << indent << this->GetNameOfClass() << ":\n";
if (this->IsClosed())
os << indent << "This figure is closed\n";
else
os << indent << "This figure is not closed\n";
os << indent << "Minimum number of control points: " << this->GetMinimumNumberOfControlPoints() << std::endl;
os << indent << "Maximum number of control points: " << this->GetMaximumNumberOfControlPoints() << std::endl;
os << indent << "Current number of control points: " << this->GetNumberOfControlPoints() << std::endl;
os << indent << "Control points:" << std::endl;
for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
//os << indent.GetNextIndent() << i << ": " << m_ControlPoints->ElementAt( i ) << std::endl;
os << indent.GetNextIndent() << i << ": " << m_ControlPoints.at( i ) << std::endl;
}
os << indent << "Geometry:\n";
this->GetPlaneGeometry()->Print(os, indent.GetNextIndent());
}
unsigned short mitk::PlanarFigure::GetPolyLinesSize()
{
if ( !m_PolyLineUpToDate )
{
this->GeneratePolyLine();
m_PolyLineUpToDate = true;
}
return m_PolyLines.size();
}
unsigned short mitk::PlanarFigure::GetHelperPolyLinesSize()
{
return m_HelperPolyLines.size();
}
bool mitk::PlanarFigure::IsHelperToBePainted(unsigned int index)
{
return m_HelperPolyLinesToBePainted->GetElement( index );
}
bool mitk::PlanarFigure::ResetOnPointSelect()
{
return false;
}
void mitk::PlanarFigure::RemoveControlPoint( unsigned int index )
{
if ( index > m_ControlPoints.size() )
return;
if ( (m_ControlPoints.size() -1) < this->GetMinimumNumberOfControlPoints() )
return;
ControlPointListType::iterator iter;
iter = m_ControlPoints.begin() + index;
m_ControlPoints.erase( iter );
m_PolyLineUpToDate = false;
m_HelperLinesUpToDate = false;
m_FeaturesUpToDate = false;
--m_NumberOfControlPoints;
}
void mitk::PlanarFigure::RemoveLastControlPoint()
{
RemoveControlPoint( m_ControlPoints.size()-1 );
}
void mitk::PlanarFigure::DeepCopy(Self::Pointer oldFigure)
{
//DeepCopy only same types of planar figures
//Notice to get typeid polymorph you have to use the *operator
if(typeid(*oldFigure) != typeid(*this))
{
itkExceptionMacro( << "DeepCopy(): Inconsistent type of source (" << typeid(*oldFigure).name() << ") and destination figure (" << typeid(*this).name() << ")!" );
return;
}
m_ControlPoints.clear();
this->ClearPolyLines();
this->ClearHelperPolyLines();
// clone base data members
SetPropertyList(oldFigure->GetPropertyList()->Clone());
/// deep copy members
m_FigurePlaced = oldFigure->m_FigurePlaced;
m_SelectedControlPoint = oldFigure->m_SelectedControlPoint;
m_FeaturesMTime = oldFigure->m_FeaturesMTime;
m_Features = oldFigure->m_Features;
m_NumberOfControlPoints = oldFigure->m_NumberOfControlPoints;
//copy geometry 2D of planar figure
PlaneGeometry::Pointer affineGeometry = oldFigure->m_PlaneGeometry->Clone();
SetPlaneGeometry(affineGeometry.GetPointer());
for(unsigned long index=0; index < oldFigure->GetNumberOfControlPoints(); index++)
{
m_ControlPoints.push_back( oldFigure->GetControlPoint( index ));
}
//After setting the control points we can generate the polylines
this->GeneratePolyLine();
}
void mitk::PlanarFigure::SetNumberOfPolyLines( unsigned int numberOfPolyLines )
{
m_PolyLines.resize(numberOfPolyLines);
}
void mitk::PlanarFigure::SetNumberOfHelperPolyLines( unsigned int numberOfHerlperPolyLines )
{
m_HelperPolyLines.resize(numberOfHerlperPolyLines);
}
void mitk::PlanarFigure::AppendPointToPolyLine( unsigned int index, PolyLineElement element )
{
if ( index < m_PolyLines.size() )
{
if(element.Index == -1)
element.Index = m_PolyLines[index].size();
m_PolyLines[index].push_back(element);
m_PolyLineUpToDate = false;
}
else
{
MITK_ERROR << "Tried to add point to PolyLine " << index+1 << ", although only " << m_PolyLines.size() << " exists";
}
}
void mitk::PlanarFigure::AppendPointToHelperPolyLine( unsigned int index, PolyLineElement element )
{
if ( index < m_HelperPolyLines.size() )
{
if(element.Index == -1)
element.Index = m_HelperPolyLines[index].size();
m_HelperPolyLines[index].push_back(element);
m_HelperLinesUpToDate = false;
}
else
{
MITK_ERROR << "Tried to add point to HelperPolyLine " << index+1 << ", although only " << m_HelperPolyLines.size() << " exists";
}
}
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wdeprecated-declarations"
#elif __clang__
# pragma clang diagnostic error "-Wdeprecated-declarations"
#elif _MSC_VER
# pragma warning (pop)
#endif
+
+bool mitk::PlanarFigure::Equals(const mitk::PlanarFigure& other) const
+{
+ //check geometries
+ if ( this->GetPlaneGeometry() && other.GetPlaneGeometry() )
+ {
+ if( !Equal(*(this->GetPlaneGeometry()), *(other.GetPlaneGeometry()), mitk::eps, true))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ MITK_ERROR << "Geometry is not equal";
+ return false;
+ }
+
+ //check isPlaced member
+ if ( this->m_FigurePlaced != other.m_FigurePlaced)
+ {
+ MITK_ERROR << "Is_Placed is not equal";
+ return false;
+ }
+
+ //check closed property
+ if (this->IsClosed() != other.IsClosed())
+ {
+ MITK_ERROR << "Is_closed is not equal";
+ return false;
+ }
+
+ //check poly lines
+ if (this->m_PolyLines.size() != other.m_PolyLines.size())
+ {
+ return false;
+ }
+ else
+ {
+ std::vector<PolyLineType>::const_iterator itThis = this->m_PolyLines.begin();
+ std::vector<PolyLineType>::const_iterator itEnd = this->m_PolyLines.end();
+ std::vector<PolyLineType>::const_iterator itOther = other.m_PolyLines.begin();
+
+ while( itThis != itEnd )
+ {
+ if(itThis->size() != itOther->size())
+ return false;
+ else
+ {
+ PolyLineType::const_iterator itLineThis = itThis->begin();
+ PolyLineType::const_iterator itLineEnd = itThis->end();
+ PolyLineType::const_iterator itLineOther = itOther->begin();
+
+ while(itLineThis != itLineEnd)
+ {
+ Point2D p1 = *itLineThis;
+ Point2D p2 = *itLineOther;
+ ScalarType delta = fabs(p1[0]-p2[0])+fabs(p1[1]-p2[1]);
+ if(delta > .001)
+ {
+ MITK_ERROR << "Poly line is not equal";
+ MITK_ERROR << p1 << "/" << p2;
+ return false;
+ }
+
+ ++itLineThis;
+ ++itLineOther;
+ }
+ }
+ ++itThis;
+ ++itOther;
+ }
+ }
+
+ //check features
+ if (this->GetNumberOfFeatures() != other.GetNumberOfFeatures())
+ {
+ MITK_ERROR << "Number of Features is Different";
+ return false;
+ }
+ else
+ {
+ std::vector<Feature>::const_iterator itThis = m_Features.begin();
+ std::vector<Feature>::const_iterator itEnd = m_Features.end();
+ std::vector<Feature>::const_iterator itOther = other.m_Features.begin();
+
+ while(itThis != itEnd)
+ {
+ if(( itThis->Quantity - itOther->Quantity) > .001 )
+ {
+ MITK_ERROR << "Quantity is Different" << itThis->Quantity << "/" << itOther->Quantity;
+ return false;
+ }
+ if( itThis->Unit.compare(itOther->Unit) != 0 )
+ {
+ MITK_ERROR << "Unit is Different" << itThis->Unit << "/" << itOther->Unit;
+ return false;
+ }
+ if( itThis->Name.compare(itOther->Name) != 0 )
+ {
+ MITK_ERROR << "Name of Measure is Different " << itThis->Name << "/ " << itOther->Name;;
+ return false;
+ }
+
+ ++itThis;
+ ++itOther;
+ }
+ }
+
+ return true;
+}
+
+bool mitk::Equal( const mitk::PlanarFigure& leftHandSide, const mitk::PlanarFigure& rightHandSide, ScalarType eps, bool verbose )
+{
+ return leftHandSide.Equals(rightHandSide);
+}
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h
index 210646a320..b781f8d13d 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h
@@ -1,434 +1,441 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_FIGURE_H_
#define _MITK_PLANAR_FIGURE_H_
#include <MitkPlanarFigureExports.h>
#include "mitkBaseData.h"
#include "mitkCommon.h"
#include <deque>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Base-class for geometric planar (2D) figures, such as
* lines, circles, rectangles, polygons, etc.
*
* \warning Currently does not support time-resolved data handling
*
* Behavior and appearance of PlanarFigures are controlled by various properties; for a detailed
* list of appearance properties see mitk::PlanarFigureMapper2D
*
* The following properties control general PlanarFigure behavior:
*
* <ul>
* <li>"selected": true if the planar figure is selected
* <li>"planarfigure.ishovering": true if the mouse "hovers" over the planar figure
* <li>"planarfigure.iseditable": true if the planar figure can be edited (otherwise,
* it can only be picked/selected, but its control points cannot be edited); default is true
* <li>"planarfigure.isextendable": true if new control points can be inserted into the list of control points;
* default is false
* </ul>
*
*
* TODO: Implement local 2D transform (including center of rotation...)
*
*/
class MitkPlanarFigure_EXPORT PlanarFigure : public BaseData
{
public:
mitkClassMacro( PlanarFigure, BaseData )
itkCloneMacro( Self )
/** \brief Treat as Point2D by implicitly using conversion operators.
*
* \deprecatedSince{2014_06} "struct PolyLineElement {...};" will be changed to "typedef Point2D PolyLineElement;".
*/
struct MitkPlanarFigure_EXPORT PolyLineElement
{
DEPRECATED(PolyLineElement(Point2D point, int index));
PolyLineElement(const Point2D& point);
PolyLineElement(const PolyLineElement &other);
PolyLineElement& operator=(const PolyLineElement &other);
operator Point2D&();
operator const Point2D&() const;
DEPRECATED(Point2D Point);
DEPRECATED(int Index);
};
typedef itk::VectorContainer< unsigned long, bool> BoolContainerType;
typedef std::deque< Point2D > ControlPointListType;
typedef std::vector< PolyLineElement > PolyLineType;
/** \brief Sets the 2D geometry on which this figure will be placed.
*
* In most cases, this is a Geometry already owned by another object, e.g.
* describing the slice of the image on which measurements will be
* performed.
*/
virtual void SetPlaneGeometry( mitk::PlaneGeometry *geometry );
/**
* \deprecatedSince{2014_06} Please use SetPlaneGeometry
*/
DEPRECATED(void SetGeometry2D(PlaneGeometry* geo)){SetPlaneGeometry(geo);};
/** \brief Returns (previously set) 2D geometry of this figure. */
virtual const PlaneGeometry *GetPlaneGeometry() const;
/**
* \deprecatedSince{2014_06} Please use GetPlaneGeometry
*/
DEPRECATED(const PlaneGeometry* GetGeometry2D()){return GetPlaneGeometry();};
/** \brief True if the planar figure is closed.
*
* Default is false. The "closed" boolean property must be set in sub-classes. */
virtual bool IsClosed() const;
/** \brief True if the planar figure has been placed (and can be
* displayed/interacted with). */
virtual bool IsPlaced() const { return m_FigurePlaced; };
/** \brief Place figure at the given point (in 2D index coordinates) onto
* the given 2D geometry.
*
* By default, the first two control points of the figure are set to the
* passed point. Further points can be set via AddControlPoint(), if the
* current number of control points is below the maximum number of control
* points.
*
* Can be re-implemented in sub-classes as needed.
*/
virtual void PlaceFigure( const Point2D& point );
/**
* \brief Adds / inserts new control-points
*
* This method adds a new control-point with the coordinates defined by point at the given index.
* If 'index' == -1 or index is greater than the number of control-points the new point is appended
* to the back of the list of control points.
* If a control-point already exists for 'index', an additional point is inserted at that position.
* It is not possible to add more points if the maximum number of control-points (GetMaximumNumberOfControlPoints())
* has been reached.
*/
virtual bool AddControlPoint( const Point2D& point, int index = -1 );
virtual bool SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist = false);
virtual bool SetCurrentControlPoint( const Point2D& point );
/** \brief Returns the current number of 2D control points defining this figure. */
unsigned int GetNumberOfControlPoints() const;
/** \brief Returns the minimum number of control points needed to represent
* this figure.
*
* Must be implemented in sub-classes.
*/
virtual unsigned int GetMinimumNumberOfControlPoints() const = 0;
/** \brief Returns the maximum number of control points allowed for
* this figure (e.g. 3 for triangles).
*
* Must be implemented in sub-classes.
*/
virtual unsigned int GetMaximumNumberOfControlPoints() const = 0;
/** \brief Selects currently active control points. */
virtual bool SelectControlPoint( unsigned int index );
/** \brief Deselect control point; no control point active. */
virtual bool DeselectControlPoint();
/** \brief Return currently selected control point. */
virtual int GetSelectedControlPoint() const { return m_SelectedControlPoint; }
/** \brief Returns specified control point in 2D world coordinates. */
Point2D GetControlPoint( unsigned int index ) const;
/** \brief Returns specified control point in world coordinates. */
Point3D GetWorldControlPoint( unsigned int index ) const;
/** \brief Returns the polyline representing the planar figure
* (for rendering, measurements, etc.). */
const PolyLineType GetPolyLine(unsigned int index);
/** \brief Returns the polyline representing the planar figure
* (for rendering, measurments, etc.). */
const PolyLineType GetPolyLine(unsigned int index) const;
/** \brief Returns the polyline that should be drawn the same size at every scale
* (for text, angles, etc.). */
const PolyLineType GetHelperPolyLine( unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight );
/** \brief Sets the position of the PreviewControlPoint. Automatically sets it visible.*/
void SetPreviewControlPoint( const Point2D& point );
/** \brief Marks the PreviewControlPoint as invisible.*/
void ResetPreviewContolPoint();
/** \brief Returns whether or not the PreviewControlPoint is visible.*/
bool IsPreviewControlPointVisible();
/** \brief Returns the coordinates of the PreviewControlPoint. */
Point2D GetPreviewControlPoint();
/** \brief Returns the number of features available for this PlanarFigure
* (such as, radius, area, ...). */
virtual unsigned int GetNumberOfFeatures() const;
/** \brief Returns the name (identifier) of the specified features. */
const char *GetFeatureName( unsigned int index ) const;
/** \brief Returns the physical unit of the specified features. */
const char *GetFeatureUnit( unsigned int index ) const;
/** Returns quantity of the specified feature (e.g., length, radius,
* area, ... ) */
double GetQuantity( unsigned int index ) const;
/** \brief Returns true if the feature with the specified index exists and
* is active (an inactive feature may e.g. be the area of a non-closed
* polygon. */
bool IsFeatureActive( unsigned int index ) const;
/** \brief Returns true if the feature with the specified index exists and is set visible */
bool IsFeatureVisible( unsigned int index ) const;
/** \brief Defines if the feature with the specified index will be shown as an
* overlay in the RenderWindow */
void SetFeatureVisible( unsigned int index, bool visible );
/** \brief Calculates quantities of all features of this planar figure. */
virtual void EvaluateFeatures();
/** \brief Intherited from parent */
virtual void UpdateOutputInformation();
/** \brief Intherited from parent */
virtual void SetRequestedRegionToLargestPossibleRegion();
/** \brief Intherited from parent */
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
/** \brief Intherited from parent */
virtual bool VerifyRequestedRegion();
/** \brief Intherited from parent */
virtual void SetRequestedRegion( const itk::DataObject *data);
/** \brief Returns the current number of polylines */
virtual unsigned short GetPolyLinesSize();
/** \brief Returns the current number of helperpolylines */
virtual unsigned short GetHelperPolyLinesSize();
/** \brief Returns whether a helper polyline should be painted or not */
virtual bool IsHelperToBePainted(unsigned int index);
/** \brief Returns true if the planar figure is reset to "add points" mode
* when a point is selected.
*
* Default return value is false. Subclasses can overwrite this method and
* execute any reset / initialization statements required. */
virtual bool ResetOnPointSelect();
/** \brief removes the point with the given index from the list of controlpoints. */
virtual void RemoveControlPoint( unsigned int index );
/** \brief Removes last control point */
virtual void RemoveLastControlPoint();
/** \brief Copies contents and state of a figre provided as parameter to the current object.
*
* Requires a matching type of both figures.
*
* \note Deprecated, use Clone() instead.
*/
DEPRECATED(void DeepCopy(Self::Pointer oldFigure));
/** \brief Allow sub-classes to apply constraints on control points.
*
* Sub-classes can define spatial constraints to certain control points by
* overwriting this method and returning a constrained point. By default,
* the points are constrained by the image bounds. */
virtual Point2D ApplyControlPointConstraints( unsigned int /*index*/, const Point2D& point );
+ /**
+ * \brief Compare two PlanarFigure objects
+ * Note: all subclasses have to implement the method on their own.
+ */
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarFigure();
virtual ~PlanarFigure();
PlanarFigure(const Self& other);
/** \brief Set the initial number of control points of the planar figure */
void ResetNumberOfControlPoints( int numberOfControlPoints );
/** Adds feature (e.g., circumference, radius, angle, ...) to feature vector
* of a planar figure object and returns integer ID for the feature element.
* Should be called in sub-class constructors. */
virtual unsigned int AddFeature( const char *featureName, const char *unitName );
/** Sets the name of the specified feature. INTERNAL METHOD. */
void SetFeatureName( unsigned int index, const char *featureName );
/** Sets the physical unit of the specified feature. INTERNAL METHOD. */
void SetFeatureUnit( unsigned int index, const char *unitName );
/** Sets quantity of the specified feature. INTERNAL METHOD. */
void SetQuantity( unsigned int index, double quantity );
/** Sets the specified feature as active. INTERAL METHOD. */
void ActivateFeature( unsigned int index );
/** Sets the specified feature as active. INTERAL METHOD. */
void DeactivateFeature( unsigned int index );
/** \brief Generates the poly-line representation of the planar figure.
* Must be implemented in sub-classes. */
virtual void GeneratePolyLine() = 0;
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.
* Must be implemented in sub-classes. */
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight) = 0;
/** \brief Calculates quantities of all features of this planar figure.
* Must be implemented in sub-classes. */
virtual void EvaluateFeaturesInternal() = 0;
/** \brief Initializes the TimeGeometry describing the (time-resolved)
* geometry of this figure. Note that each time step holds one PlaneGeometry.
*/
virtual void InitializeTimeGeometry( unsigned int timeSteps = 1 );
/** \brief defines the number of PolyLines that will be available */
void SetNumberOfPolyLines( unsigned int numberOfPolyLines );
/** \brief Append a point to the PolyLine # index */
void AppendPointToPolyLine( unsigned int index, PolyLineElement element );
/** \brief clears the list of PolyLines. Call before re-calculating a new Polyline. */
void ClearPolyLines();
/** \brief defines the number of HelperPolyLines that will be available */
void SetNumberOfHelperPolyLines( unsigned int numberOfHelperPolyLines );
/** \brief Append a point to the HelperPolyLine # index */
void AppendPointToHelperPolyLine( unsigned int index, PolyLineElement element );
/** \brief clears the list of HelperPolyLines. Call before re-calculating a new HelperPolyline. */
void ClearHelperPolyLines();
virtual void PrintSelf( std::ostream& os, itk::Indent indent ) const;
ControlPointListType m_ControlPoints;
unsigned int m_NumberOfControlPoints;
// Currently selected control point; -1 means no point selected
int m_SelectedControlPoint;
std::vector<PolyLineType> m_PolyLines;
std::vector<PolyLineType> m_HelperPolyLines;
BoolContainerType::Pointer m_HelperPolyLinesToBePainted;
// this point is used to store the coordiantes an additional 'ControlPoint' that is rendered
// when the mouse cursor is above the figure (and not a control-point) and when the
// property 'planarfigure.isextendable' is set to true
Point2D m_PreviewControlPoint;
bool m_PreviewControlPointVisible;
bool m_FigurePlaced;
private:
// not implemented to prevent PlanarFigure::New() calls which would create an itk::Object.
static Pointer New();
struct Feature
{
Feature( const char *name, const char *unit )
: Name( name ), Unit( unit ), Quantity( 0.0 ), Active( true ), Visible( true )
{
}
std::string Name;
std::string Unit;
double Quantity;
bool Active;
bool Visible;
};
virtual itk::LightObject::Pointer InternalClone() const = 0;
PlaneGeometry *m_PlaneGeometry;
bool m_PolyLineUpToDate;
bool m_HelperLinesUpToDate;
bool m_FeaturesUpToDate;
// Vector of features available for this geometric figure
typedef std::vector< Feature > FeatureVectorType;
FeatureVectorType m_Features;
unsigned long m_FeaturesMTime;
// this pair is used to store the mmInDisplayUnits (m_DisplaySize.first) and the displayHeight (m_DisplaySize.second)
// that the helperPolyLines have been calculated for.
// It's used to determine whether or not GetHelperPolyLine() needs to recalculate the HelperPolyLines.
std::pair<double, unsigned int> m_DisplaySize;
};
+MITK_CORE_EXPORT bool Equal( const mitk::PlanarFigure& leftHandSide, const mitk::PlanarFigure& rightHandSide, ScalarType eps, bool verbose );
+
} // namespace mitk
#endif //_MITK_PLANAR_FIGURE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.cpp
index ddd3d8c262..ca7c048a98 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.cpp
@@ -1,79 +1,92 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarFourPointAngle.h"
#include "mitkPlaneGeometry.h"
mitk::PlanarFourPointAngle::PlanarFourPointAngle()
: FEATURE_ID_ANGLE( this->AddFeature( "Angle", "deg" ) )
{
// Four point angle has two control points
this->ResetNumberOfControlPoints( 2 );
this->SetNumberOfPolyLines( 2 );
}
mitk::PlanarFourPointAngle::~PlanarFourPointAngle()
{
}
void mitk::PlanarFourPointAngle::GeneratePolyLine()
{
this->ClearPolyLines();
for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
this->AppendPointToPolyLine(i / 2, this->GetControlPoint(i));
}
void mitk::PlanarFourPointAngle::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// Generate helper-poly-line for an four point angle
// Need to discuss a sensible implementation
}
void mitk::PlanarFourPointAngle::EvaluateFeaturesInternal()
{
if ( this->GetNumberOfControlPoints() < 4 )
{
// Angle not yet complete.
return;
}
// Calculate angle between lines
const Point2D &p0 = this->GetControlPoint( 0 );
const Point2D &p1 = this->GetControlPoint( 1 );
const Point2D &p2 = this->GetControlPoint( 2 );
const Point2D &p3 = this->GetControlPoint( 3 );
Vector2D v0 = p1 - p0;
Vector2D v1 = p3 - p2;
v0.Normalize();
v1.Normalize();
double angle = acos( v0 * v1 );
this->SetQuantity( FEATURE_ID_ANGLE, angle );
}
void mitk::PlanarFourPointAngle::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
+
+ bool mitk::PlanarFourPointAngle::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarFourPointAngle* otherFourPtAngle = dynamic_cast<const mitk::PlanarFourPointAngle*>(&other);
+ if ( otherFourPtAngle )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.h b/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.h
index b485beb721..44189715de 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFourPointAngle.h
@@ -1,93 +1,94 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_FOURPOINTANGLE_H_
#define _MITK_PLANAR_FOURPOINTANGLE_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a four point
* angle, which is defined by two non-intersecting lines in 2D. Each of those lines
* is defined by two control points.
*/
class MitkPlanarFigure_EXPORT PlanarFourPointAngle : public PlanarFigure
{
public:
mitkClassMacro( PlanarFourPointAngle, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
public:
// Feature identifiers
const unsigned int FEATURE_ID_ANGLE;
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
/** \brief Four point angle has 4 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 4;
}
/** \brief Four point angle has 4 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 4;
}
+ virtual bool Equals(const mitk::PlanarFigure& other) const ;
protected:
PlanarFourPointAngle();
virtual ~PlanarFourPointAngle();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_FOURPOINTANGLE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarLine.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarLine.cpp
index a534089a6a..ffee0a38bd 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarLine.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarLine.cpp
@@ -1,65 +1,78 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarLine.h"
#include "mitkPlaneGeometry.h"
mitk::PlanarLine::PlanarLine()
: FEATURE_ID_LENGTH( this->AddFeature( "Length", "mm" ) )
{
// Line has two control points
this->ResetNumberOfControlPoints( 2 );
this->SetNumberOfPolyLines( 1 );
}
mitk::PlanarLine::~PlanarLine()
{
}
void mitk::PlanarLine::GeneratePolyLine()
{
this->ClearPolyLines();
this->AppendPointToPolyLine(0, this->GetControlPoint(0));
this->AppendPointToPolyLine(0, this->GetControlPoint(1));
}
void mitk::PlanarLine::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// A line does not require a helper object
}
void mitk::PlanarLine::EvaluateFeaturesInternal()
{
// Calculate line length
const Point3D &p0 = this->GetWorldControlPoint( 0 );
const Point3D &p1 = this->GetWorldControlPoint( 1 );
double length = p0.EuclideanDistanceTo( p1 );
this->SetQuantity( FEATURE_ID_LENGTH, length );
}
void mitk::PlanarLine::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
+
+ bool mitk::PlanarLine::Equals(const PlanarFigure &other) const
+ {
+ const mitk::PlanarLine* otherLine = dynamic_cast<const mitk::PlanarLine*>(&other);
+ if ( otherLine )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarLine.h b/Modules/PlanarFigure/DataManagement/mitkPlanarLine.h
index 09732fcef3..cdfd7bfd55 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarLine.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarLine.h
@@ -1,93 +1,94 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_LINE_H_
#define _MITK_PLANAR_LINE_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a line
* through two control points
*/
class MitkPlanarFigure_EXPORT PlanarLine : public PlanarFigure
{
public:
mitkClassMacro( PlanarLine, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
/** \brief Line has 2 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 2;
}
/** \brief Line has 2 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 2;
}
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarLine();
virtual ~PlanarLine();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
// Feature identifiers
const unsigned int FEATURE_ID_LENGTH;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_LINE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.cpp
index 669d952f3f..e47a71eebd 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.cpp
@@ -1,274 +1,287 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarPolygon.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
// stl related includes
#include <algorithm>
mitk::PlanarPolygon::PlanarPolygon()
: FEATURE_ID_CIRCUMFERENCE( this->AddFeature( "Circumference", "mm" ) ),
FEATURE_ID_AREA( this->AddFeature( "Area", "mm2" ) )
{
// Polygon has at least two control points
this->ResetNumberOfControlPoints( 2 );
this->SetNumberOfPolyLines( 1 );
// Polygon is closed by default
this->SetProperty( "closed", mitk::BoolProperty::New( true ) );
this->SetProperty( "subdivision", mitk::BoolProperty::New( false ) );
}
mitk::PlanarPolygon::~PlanarPolygon()
{
}
void mitk::PlanarPolygon::SetClosed( bool closed )
{
this->SetProperty( "closed", mitk::BoolProperty::New( closed ) );
if ( !closed )
{
// For non-closed polygons: use "Length" as feature name; disable area
this->SetFeatureName( FEATURE_ID_CIRCUMFERENCE, "Length" );
this->DeactivateFeature( FEATURE_ID_AREA );
}
else
{
// For closed polygons: use "Circumference" as feature name; enable area
this->SetFeatureName( FEATURE_ID_CIRCUMFERENCE, "Circumference" );
this->ActivateFeature( FEATURE_ID_AREA );
}
this->Modified();
}
void mitk::PlanarPolygon::GeneratePolyLine()
{
this->ClearPolyLines();
for (ControlPointListType::size_type i = 0; i < m_ControlPoints.size(); ++i)
this->AppendPointToPolyLine(0, this->GetControlPoint(i));
}
void mitk::PlanarPolygon::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// A polygon does not require helper objects
}
void mitk::PlanarPolygon::EvaluateFeaturesInternal()
{
// Calculate circumference
double circumference = 0.0;
unsigned int i,j;
PolyLineType polyLine = m_PolyLines[0];
if(polyLine.empty())
return;
for ( i = 0; i <(polyLine.size()-1); ++i )
{
circumference += static_cast<Point2D>(polyLine[i]).EuclideanDistanceTo(
static_cast<Point2D>(polyLine[i + 1]) );
}
if ( this->IsClosed() )
{
circumference += static_cast<Point2D>(polyLine[i]).EuclideanDistanceTo(
static_cast<Point2D>(polyLine.front()) );
}
this->SetQuantity( FEATURE_ID_CIRCUMFERENCE, circumference );
// Calculate polygon area (if closed)
double area = 0.0;
bool intersection = false;
if ( this->IsClosed() && (this->GetPlaneGeometry() != NULL) )
{
// does PlanarPolygon overlap/intersect itself?
unsigned int numberOfPoints = polyLine.size();
if( numberOfPoints >= 4)
{
for ( i = 0; i < (numberOfPoints - 1); ++i )
{
// line 1
Point2D p0 = polyLine[i];
Point2D p1 = polyLine[i + 1];
// check for intersection with all other lines
for (j = i+1; j < (numberOfPoints - 1); ++j )
{
Point2D p2 = polyLine[j];
Point2D p3 = polyLine[j + 1];
intersection = CheckForLineIntersection(p0,p1,p2,p3);
if (intersection) break;
}
if (intersection) break; // only because the inner loop might have changed "intersection"
// last line from p_x to p_0
Point2D p2 = polyLine.front();
Point2D p3 = polyLine.back();
intersection = CheckForLineIntersection(p0,p1,p2,p3);
if (intersection) break;
}
}
// calculate area
for ( i = 0; i < polyLine.size(); ++i )
{
Point2D p0 = polyLine[i];
Point2D p1 = polyLine[ (i + 1) % polyLine.size() ];
area += p0[0] * p1[1] - p1[0] * p0[1];
}
area /= 2.0;
}
// set area if appropiate (i.e. closed and not intersected)
if(this->IsClosed() && !intersection)
{
SetQuantity( FEATURE_ID_AREA, fabs( area ) );
this->ActivateFeature( FEATURE_ID_AREA );
}
else
{
SetQuantity( FEATURE_ID_AREA, 0 );
this->DeactivateFeature( FEATURE_ID_AREA );
}
}
void mitk::PlanarPolygon::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
if (this->IsClosed())
os << indent << "Polygon is closed\n";
else
os << indent << "Polygon is not closed\n";
}
// based on
// http://flassari.is/2008/11/line-line-intersection-in-cplusplus/
bool mitk::PlanarPolygon::CheckForLineIntersection( const mitk::Point2D& p1, const mitk::Point2D& p2, const mitk::Point2D& p3, const mitk::Point2D& p4, Point2D& intersection ) const
{
// do not check for intersections with control points
if(p1 == p2 || p1 == p3 || p1 == p4 ||
p2 == p3 || p2 == p4 ||
p3 == p4)
return false;
// Store the values for fast access and easy
// equations-to-code conversion
double x1 = p1[0], x2 = p2[0], x3 = p3[0], x4 = p4[0];
double y1 = p1[1], y2 = p2[1], y3 = p3[1], y4 = p4[1];
double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
// If d is zero, there is no intersection
//if (d < mitk::eps) return false;
if (d == 0) return false;
// Get the x and y
double pre = (x1*y2 - y1*x2);
double post = (x3*y4 - y3*x4);
double x = ( pre * (x3 - x4) - (x1 - x2) * post ) / d;
double y = ( pre * (y3 - y4) - (y1 - y2) * post ) / d;
double tolerance = 0.001;
// Check if the x coordinates are within both lines, including tolerance
if ( x < ( std::min(x1, x2) - tolerance )
|| x > ( std::max(x1, x2) + tolerance )
|| x < ( std::min(x3, x4) - tolerance )
|| x > ( std::max(x3, x4) + tolerance )
)
{
return false;
}
// Check if the y coordinates are within both lines, including tolerance
if ( y < ( std::min(y1, y2) - tolerance )
|| y > ( std::max(y1, y2) + tolerance )
|| y < ( std::min(y3, y4) - tolerance )
|| y > ( std::max(y3, y4) + tolerance )
)
{
return false;
}
// point of intersection
Point2D ret; ret[0] = x; ret[1] = y;
intersection = ret;
return true;
}
bool mitk::PlanarPolygon::CheckForLineIntersection( const mitk::Point2D& p1, const mitk::Point2D& p2, const mitk::Point2D& p3, const mitk::Point2D& p4 ) const
{
mitk::Point2D intersection;
return mitk::PlanarPolygon::CheckForLineIntersection( p1, p2, p3, p4, intersection );
}
std::vector<mitk::Point2D> mitk::PlanarPolygon::CheckForLineIntersection( const mitk::Point2D& p1, const mitk::Point2D& p2 ) const
{
std::vector<mitk::Point2D> intersectionList;
ControlPointListType polyLinePoints;
PolyLineType tempList = m_PolyLines[0];
PolyLineType::iterator iter;
for( iter = tempList.begin(); iter != tempList.end(); ++iter )
{
polyLinePoints.push_back(*iter);
}
for ( ControlPointListType::size_type i=0; i<polyLinePoints.size()-1; i++ )
{
mitk::Point2D pnt1 = polyLinePoints[i];
mitk::Point2D pnt2 = polyLinePoints[i+1];
mitk::Point2D intersection;
if ( mitk::PlanarPolygon::CheckForLineIntersection( p1, p2, pnt1, pnt2, intersection ) )
{
intersectionList.push_back( intersection );
}
}
if ( this->IsClosed() )
{
mitk::Point2D intersection, lastControlPoint, firstControlPoint;
lastControlPoint = polyLinePoints.back();
firstControlPoint = polyLinePoints.front();
if ( mitk::PlanarPolygon::CheckForLineIntersection( lastControlPoint,
firstControlPoint, p1, p2, intersection ) )
{
intersectionList.push_back( intersection );
}
}
return intersectionList;
}
+
+ bool mitk::PlanarPolygon::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarPolygon* otherPolygon = dynamic_cast<const mitk::PlanarPolygon*>(&other);
+ if ( otherPolygon )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.h b/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.h
index fa5c0c19b4..e37b70934b 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarPolygon.h
@@ -1,103 +1,104 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_POLYGON_H_
#define _MITK_PLANAR_POLYGON_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a polygon
* with two or more control points
*/
class MitkPlanarFigure_EXPORT PlanarPolygon : public PlanarFigure
{
public:
mitkClassMacro( PlanarPolygon, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Set whether the polygon should be closed between first and last control point or not. */
virtual void SetClosed( bool closed );
itkBooleanMacro( Closed ); // Calls SetClosed(); no need to re-implement
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
/** \brief Polygon has 3 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 3;
}
/** \brief Polygon maximum number of control points is principally not limited. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 1000;
}
std::vector<mitk::Point2D> CheckForLineIntersection( const Point2D& p1, const Point2D& p2 ) const;
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarPolygon();
virtual ~PlanarPolygon();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
bool CheckForLineIntersection(const mitk::Point2D& p1, const mitk::Point2D& p2, const mitk::Point2D& p3, const mitk::Point2D& p4, Point2D& intersection) const ;
bool CheckForLineIntersection( const mitk::Point2D& p1, const mitk::Point2D& p2, const mitk::Point2D& p3, const mitk::Point2D& p4 ) const;
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
const unsigned int FEATURE_ID_CIRCUMFERENCE;
const unsigned int FEATURE_ID_AREA;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_POLYGON_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.cpp
index cc7169ece3..d4fdeb80d6 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.cpp
@@ -1,146 +1,159 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkProperties.h"
#include "mitkPlanarRectangle.h"
#include "mitkPlaneGeometry.h"
mitk::PlanarRectangle::PlanarRectangle()
: FEATURE_ID_CIRCUMFERENCE( this->AddFeature( "Circumference", "mm" ) ),
FEATURE_ID_AREA( this->AddFeature( "Area", "mm2" ) )
{
// Rectangle has four control points
this->ResetNumberOfControlPoints( 4 );
this->SetProperty( "closed", mitk::BoolProperty::New(true) );
this->SetNumberOfPolyLines( 1 );
}
mitk::PlanarRectangle::~PlanarRectangle()
{
}
bool mitk::PlanarRectangle::SetControlPoint( unsigned int index, const Point2D &point, bool createIfDoesNotExist )
{
// heres the deal with the rectangle:
// when a point is moved all corresponding corner points are moved with him
// e.g. if the lower right point (index=3) is moved the upper right point (index=1)
// is moved in the same x direction
// and the lower left point (index=2) is moved in the same y direction
// the upper left point (index=0) is left untouched
bool set = PlanarFigure::SetControlPoint( index, point, createIfDoesNotExist );
if(set)
{
// can be made better ...
unsigned int horizontalCorrespondingPointIndex = 1;
unsigned int verticalCorrespondingPointIndex = 3;
if(index == 1)
{
horizontalCorrespondingPointIndex = 0;
verticalCorrespondingPointIndex = 2;
}
else if(index == 2)
{
horizontalCorrespondingPointIndex = 3;
verticalCorrespondingPointIndex = 1;
}
else if(index == 3)
{
horizontalCorrespondingPointIndex = 2;
verticalCorrespondingPointIndex = 0;
}
Point2D verticalCorrespondingPoint = GetControlPoint( verticalCorrespondingPointIndex );
verticalCorrespondingPoint[0] = point[0];
PlanarFigure::SetControlPoint( verticalCorrespondingPointIndex, verticalCorrespondingPoint );
Point2D horizontalCorrespondingPoint = GetControlPoint( horizontalCorrespondingPointIndex );
horizontalCorrespondingPoint[1] = point[1];
PlanarFigure::SetControlPoint( horizontalCorrespondingPointIndex, horizontalCorrespondingPoint );
}
return set;
}
void mitk::PlanarRectangle::PlaceFigure( const mitk::Point2D &point )
{
PlanarFigure::PlaceFigure( point );
m_SelectedControlPoint = 3;
}
void mitk::PlanarRectangle::GeneratePolyLine()
{
this->ClearPolyLines();
for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
this->AppendPointToPolyLine(0, this->GetControlPoint(i));
}
void mitk::PlanarRectangle::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
// A polygon does not require helper objects
}
void mitk::PlanarRectangle::EvaluateFeaturesInternal()
{
// Calculate circumference
double circumference = 0.0;
unsigned int i;
for ( i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
circumference += this->GetWorldControlPoint( i ).EuclideanDistanceTo(
this->GetWorldControlPoint( (i + 1) % this->GetNumberOfControlPoints() ) );
}
this->SetQuantity( FEATURE_ID_CIRCUMFERENCE, circumference );
// Calculate rectangle area (well, done a bit clumsy...)
double area = 0.0;
if ( this->GetPlaneGeometry() != NULL )
{
for ( i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
Point2D p0 = this->GetControlPoint( i );
Point2D p1 = this->GetControlPoint( (i + 1) % this->GetNumberOfControlPoints() );
area += p0[0] * p1[1] - p1[0] * p0[1];
}
area /= 2.0;
}
this->SetQuantity( FEATURE_ID_AREA, fabs(area) );
}
void mitk::PlanarRectangle::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
os << indent << "Number of control points: " << this->GetNumberOfControlPoints() << std::endl;
os << indent << "Control points:" << std::endl;
for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
os << indent << indent << i << ": " <<GetControlPoint( i ) << std::endl;
}
}
+
+ bool mitk::PlanarRectangle::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarRectangle* otherRectangle = dynamic_cast<const mitk::PlanarRectangle*>(&other);
+ if ( otherRectangle )
+ {
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.h b/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.h
index 2943a626c5..b4890c5ce8 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarRectangle.h
@@ -1,93 +1,94 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_RECTANGLE_H_
#define _MITK_PLANAR_RECTANGLE_H_
#include "mitkPlanarPolygon.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a polygon
* with two or more control points
*/
class MitkPlanarFigure_EXPORT PlanarRectangle : public PlanarFigure
{
public:
mitkClassMacro( PlanarRectangle, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
virtual void PlaceFigure( const Point2D &point );
/** \brief Polygon has 2 control points per definition. */
virtual unsigned int GetMinimumNumberOfControlPoints() const
{
return 4;
}
/** \brief Polygon maximum number of control points is principally not limited. */
virtual unsigned int GetMaximumNumberOfControlPoints() const
{
return 4;
}
virtual bool SetControlPoint( unsigned int index, const Point2D &point, bool createIfDoesNotExist = false);
protected:
PlanarRectangle();
virtual ~PlanarRectangle();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
const unsigned int FEATURE_ID_CIRCUMFERENCE;
const unsigned int FEATURE_ID_AREA;
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_POLYGON_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp
index db3ac6657b..2b63f2dffd 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp
@@ -1,132 +1,149 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarSubdivisionPolygon.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
// stl related includes
#include <algorithm>
mitk::PlanarSubdivisionPolygon::PlanarSubdivisionPolygon():
m_TensionParameter(0.0625),
m_SubdivisionRounds(5)
{
// Polygon is subdivision (in contrast to parent class PlanarPolygon
this->SetProperty( "closed", mitk::BoolProperty::New( true ) );
this->SetProperty( "subdivision", mitk::BoolProperty::New( true ) );
// Other properties are inherited / already initialized by parent class PlanarPolygon
}
mitk::PlanarSubdivisionPolygon::~PlanarSubdivisionPolygon()
{
}
void mitk::PlanarSubdivisionPolygon::GeneratePolyLine()
{
this->ClearPolyLines();
ControlPointListType subdivisionPoints;
ControlPointListType newSubdivisionPoints;
subdivisionPoints.clear();
subdivisionPoints = m_ControlPoints;
if( m_ControlPoints.size() >= GetMinimumNumberOfControlPoints() )
{
for( unsigned int i=0; i < GetSubdivisionRounds(); i++ )
{
// Indices
unsigned int index, indexPrev, indexNext, indexNextNext;
unsigned int numberOfPoints = subdivisionPoints.size();
Point2D newPoint;
// Keep cycling our array indices forward until they wrap around at the end
for ( index = 0; index < numberOfPoints; ++index )
{
// Create new subdivision point according to formula
// p_new = (0.5 + tension) * (p_here + p_next) - tension * (p_prev + p_nextnext)
indexPrev = (numberOfPoints + index - 1) % numberOfPoints;
indexNext = (index + 1) % numberOfPoints;
indexNextNext = (index + 2) % numberOfPoints;
newPoint[0] = (0.5 + GetTensionParameter()) * (double)( subdivisionPoints[index][0] + subdivisionPoints[indexNext][0] )
- GetTensionParameter() * (double)( subdivisionPoints[indexPrev][0] + subdivisionPoints[indexNextNext][0]);
newPoint[1] = (0.5 + GetTensionParameter()) * (double)( subdivisionPoints[index][1] + subdivisionPoints[indexNext][1] )
- GetTensionParameter() * (double)( subdivisionPoints[indexPrev][1] + subdivisionPoints[indexNextNext][1]);
newSubdivisionPoints.push_back( newPoint );
}
ControlPointListType mergedSubdivisionPoints;
ControlPointListType::iterator it, itNew;
for ( it = subdivisionPoints.begin() , itNew = newSubdivisionPoints.begin();
it != subdivisionPoints.end();
++it, ++itNew )
{
mergedSubdivisionPoints.push_back( *it );
mergedSubdivisionPoints.push_back( *itNew );
}
subdivisionPoints = mergedSubdivisionPoints;
newSubdivisionPoints.clear();
}
}
bool isInitiallyPlaced = this->GetProperty("initiallyplaced");
unsigned int i;
ControlPointListType::iterator it;
for ( it = subdivisionPoints.begin(), i = 0;
it != subdivisionPoints.end();
++it, ++i )
{
// Determine the index of the control point FOLLOWING this poly-line element
// (this is needed by PlanarFigureInteractor to insert new points at the correct position,
// namely BEFORE the next control point)
unsigned int nextIndex;
if ( i == 0 )
{
// For the FIRST polyline point, use the index of the LAST control point
// (it will used to check if the mouse is near the very last polyline element)
nextIndex = m_ControlPoints.size() - 1;
}
else
{
// For all other polyline points, use the index of the control point succeeding it
// (for polyline points lying on control points, the index of the previous control point
// is used)
nextIndex = (((i - 1) >> this->GetSubdivisionRounds()) + 1) % m_ControlPoints.size();
if(!isInitiallyPlaced && nextIndex > m_ControlPoints.size()-2)
{
PolyLineElement elem( m_ControlPoints[m_ControlPoints.size()-1], nextIndex );
this->AppendPointToPolyLine( 0, elem );
break;
}
}
PolyLineElement elem( *it, nextIndex );
this->AppendPointToPolyLine( 0, elem );
}
subdivisionPoints.clear();
}
+
+ bool mitk::PlanarSubdivisionPolygon::Equals(const mitk::PlanarFigure& other) const
+ {
+ const mitk::PlanarSubdivisionPolygon* otherSubDivPoly = dynamic_cast<const mitk::PlanarSubdivisionPolygon*>(&other);
+ if ( otherSubDivPoly )
+ {
+ if ( this->m_SubdivisionRounds != otherSubDivPoly->m_SubdivisionRounds)
+ return false;
+ if ( std::abs(this->m_TensionParameter - otherSubDivPoly->m_TensionParameter) > mitk::eps)
+ return false;
+ return Superclass::Equals(other);
+ }
+ else
+ {
+ return false;
+ }
+ }
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.h b/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.h
index 9d086cb88c..8f17c66805 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.h
@@ -1,107 +1,109 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_SUBDIVISION_POLYGON_H_
#define _MITK_PLANAR_SUBDIVISION_POLYGON_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
#include "mitkPlanarPolygon.h"
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing a polygon
* with two or more control points
*/
class MitkPlanarFigure_EXPORT PlanarSubdivisionPolygon : public PlanarPolygon
{
public:
mitkClassMacro( PlanarSubdivisionPolygon, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Subdivision Polygon has 3 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 3;
}
/** \brief Polygon maximum number of control points is principally not limited. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 1000;
}
/** \brief How many times should we generate a round of subdivisions? */
unsigned int GetSubdivisionRounds() const
{
return m_SubdivisionRounds;
}
void SetSubdivisionRounds( int subdivisionRounds )
{
m_SubdivisionRounds = subdivisionRounds;
}
/** \brief Parameter w_tension defines the tension.
* the higher w_tension, the lower the "tension" on points.
* Rule: 0 < w_tension < 0.1
* 0.0625 (1 / 16) seems to be a good value.
*/
float GetTensionParameter() const
{
return m_TensionParameter;
}
void SetTensionParameter(float tensionParameter )
{
m_TensionParameter = tensionParameter;
}
std::vector<mitk::Point2D> CheckForLineIntersection( const Point2D& p1, const Point2D& p2 ) const;
void IncreaseSubdivisions();
void DecreaseSubdivisions();
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
+
protected:
PlanarSubdivisionPolygon();
virtual ~PlanarSubdivisionPolygon();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
float m_TensionParameter;
int m_SubdivisionRounds;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_SUBDIVISION_POLYGON_H_
diff --git a/Modules/PlanarFigure/IO/mitkPlanarFigureReader.cpp b/Modules/PlanarFigure/IO/mitkPlanarFigureReader.cpp
index 8937d098e9..431e4cbbc2 100644
--- a/Modules/PlanarFigure/IO/mitkPlanarFigureReader.cpp
+++ b/Modules/PlanarFigure/IO/mitkPlanarFigureReader.cpp
@@ -1,469 +1,479 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPlanarFigureReader.h"
#include "mitkPlanarAngle.h"
#include "mitkPlanarCircle.h"
#include "mitkPlanarLine.h"
#include "mitkPlanarArrow.h"
#include "mitkPlanarCross.h"
#include "mitkPlanarFourPointAngle.h"
#include "mitkPlanarPolygon.h"
#include "mitkPlanarSubdivisionPolygon.h"
#include "mitkPlanarRectangle.h"
#include "mitkPlaneGeometry.h"
#include "mitkPlanarEllipse.h"
#include "mitkPlanarDoubleEllipse.h"
#include "mitkPlanarBezierCurve.h"
#include "mitkBasePropertySerializer.h"
#include <tinyxml.h>
#include <itksys/SystemTools.hxx>
mitk::PlanarFigureReader::PlanarFigureReader() : PlanarFigureSource(), FileReader(),
m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false)
{
this->SetNumberOfRequiredOutputs(1);
this->SetNumberOfIndexedOutputs(1);
this->SetNthOutput(0, this->MakeOutput(0));
m_CanReadFromMemory = true;
//this->Modified();
//this->GetOutput()->Modified();
//this->GetOutput()->ReleaseData();
}
mitk::PlanarFigureReader::~PlanarFigureReader()
{}
void mitk::PlanarFigureReader::GenerateData()
{
const std::string& locale = "C";
const std::string& currLocale = setlocale( LC_ALL, NULL );
if ( locale.compare(currLocale)!=0 )
{
try
{
setlocale(LC_ALL, locale.c_str());
}
catch(...)
{
MITK_INFO << "Could not set locale " << locale;
}
}
m_Success = false;
this->SetNumberOfIndexedOutputs(0); // reset all outputs, we add new ones depending on the file content
TiXmlDocument document;
if(m_ReadFromMemory)
{
if(m_MemoryBuffer == NULL || m_MemorySize == 0)
{
//check
itkWarningMacro( << "Sorry, memory buffer has not been set!" );
return;
}
if(m_MemoryBuffer[ m_MemorySize - 1 ] == '\0')
{
document.Parse(m_MemoryBuffer);
}
else
{
char * tmpArray = new char[(int)m_MemorySize+1];
tmpArray[m_MemorySize] = '\0';
memcpy(tmpArray,m_MemoryBuffer,m_MemorySize);
document.Parse(m_MemoryBuffer);
delete [] tmpArray;
}
}
else
{
if (m_FileName.empty())
{
itkWarningMacro( << "Sorry, filename has not been set!" );
return;
}
if (this->CanReadFile( m_FileName.c_str()) == false)
{
itkWarningMacro( << "Sorry, can't read file " << m_FileName << "!" );
return;
}
if (!document.LoadFile(m_FileName))
{
MITK_ERROR << "Could not open/read/parse " << m_FileName << ". TinyXML reports: '" << document.ErrorDesc() << "'. "
<< "The error occurred in row " << document.ErrorRow() << ", column " << document.ErrorCol() << ".";
return;
}
}
int fileVersion = 1;
TiXmlElement* versionObject = document.FirstChildElement("Version");
if (versionObject != NULL)
{
if ( versionObject->QueryIntAttribute( "FileVersion", &fileVersion ) != TIXML_SUCCESS )
{
MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
}
}
else
{
MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
}
if (fileVersion != 1) // add file version selection and version specific file parsing here, if newer file versions are created
{
MITK_WARN << "File version > 1 is not supported by this reader.";
return;
}
/* file version 1 reader code */
for( TiXmlElement* pfElement = document.FirstChildElement("PlanarFigure");
pfElement != NULL;
pfElement = pfElement->NextSiblingElement("PlanarFigure") )
{
if (pfElement == NULL)
continue;
std::string type = pfElement->Attribute("type");
mitk::PlanarFigure::Pointer planarFigure = NULL;
if (type == "PlanarAngle")
{
planarFigure = mitk::PlanarAngle::New();
}
else if (type == "PlanarCircle")
{
planarFigure = mitk::PlanarCircle::New();
}
else if (type == "PlanarEllipse")
{
planarFigure = mitk::PlanarEllipse::New();
}
else if (type == "PlanarCross")
{
planarFigure = mitk::PlanarCross::New();
}
else if (type == "PlanarFourPointAngle")
{
planarFigure = mitk::PlanarFourPointAngle::New();
}
else if (type == "PlanarLine")
{
planarFigure = mitk::PlanarLine::New();
}
else if (type == "PlanarPolygon")
{
planarFigure = mitk::PlanarPolygon::New();
}
else if (type == "PlanarSubdivisionPolygon")
{
planarFigure = mitk::PlanarSubdivisionPolygon::New();
}
else if (type == "PlanarRectangle")
{
planarFigure = mitk::PlanarRectangle::New();
}
else if (type == "PlanarArrow")
{
planarFigure = mitk::PlanarArrow::New();
}
else if (type == "PlanarDoubleEllipse")
{
planarFigure = mitk::PlanarDoubleEllipse::New();
}
else if (type == "PlanarBezierCurve")
{
planarFigure = mitk::PlanarBezierCurve::New();
}
else
{
// unknown type
MITK_WARN << "encountered unknown planar figure type '" << type << "'. Skipping this element.";
continue;
}
// Read properties of the planar figure
for( TiXmlElement* propertyElement = pfElement->FirstChildElement("property");
propertyElement != NULL;
propertyElement = propertyElement->NextSiblingElement("property") )
{
const char* keya = propertyElement->Attribute("key");
std::string key( keya ? keya : "");
const char* typea = propertyElement->Attribute("type");
std::string type( typea ? typea : "");
// hand propertyElement to specific reader
std::stringstream propertyDeserializerClassName;
propertyDeserializerClassName << type << "Serializer";
std::list<itk::LightObject::Pointer> readers =
itk::ObjectFactoryBase::CreateAllInstance(propertyDeserializerClassName.str().c_str());
if (readers.size() < 1)
{
MITK_ERROR << "No property reader found for " << type;
}
if (readers.size() > 1)
{
MITK_WARN << "Multiple property readers found for " << type << ". Using arbitrary first one.";
}
for ( std::list<itk::LightObject::Pointer>::iterator iter = readers.begin();
iter != readers.end();
++iter )
{
if (BasePropertySerializer* reader = dynamic_cast<BasePropertySerializer*>( iter->GetPointer() ) )
{
BaseProperty::Pointer property = reader->Deserialize( propertyElement->FirstChildElement() );
if (property.IsNotNull())
{
planarFigure->GetPropertyList()->ReplaceProperty(key, property);
}
else
{
MITK_ERROR << "There were errors while loading property '" << key << "' of type " << type << ". Your data may be corrupted";
}
break;
}
}
}
// If we load a planarFigure, it has definitely been placed correctly.
// If we do not set this property here, we cannot load old planarFigures
// without messing up the interaction (PF-Interactor needs this property.
planarFigure->GetPropertyList()->SetBoolProperty( "initiallyplaced", true );
+ // Which features (length or circumference etc) a figure has is decided by whether it is closed or not
+ // the function SetClosed has to be called in case of PlanarPolygons to ensure they hold the correct feature
+ PlanarPolygon* planarPolygon = dynamic_cast<PlanarPolygon*> (planarFigure.GetPointer());
+ if (planarPolygon != NULL)
+ {
+ bool isClosed = false;
+ planarFigure->GetPropertyList()->GetBoolProperty( "closed", isClosed);
+ planarPolygon->SetClosed(isClosed);
+ }
+
// Read geometry of containing plane
TiXmlElement* geoElement = pfElement->FirstChildElement("Geometry");
if (geoElement != NULL)
{
try
{
// Create plane geometry
mitk::PlaneGeometry::Pointer planeGeo = mitk::PlaneGeometry::New();
// Extract and set plane transform parameters
DoubleList transformList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "transformParam" ), "param", 12 );
typedef mitk::BaseGeometry::TransformType TransformType;
TransformType::ParametersType parameters;
parameters.SetSize( 12 );
unsigned int i;
DoubleList::iterator it;
for ( it = transformList.begin(), i = 0;
it != transformList.end();
++it, ++i )
{
parameters.SetElement( i, *it );
}
typedef mitk::BaseGeometry::TransformType TransformType;
TransformType::Pointer affineGeometry = TransformType::New();
affineGeometry->SetParameters( parameters );
planeGeo->SetIndexToWorldTransform( affineGeometry );
// Extract and set plane bounds
DoubleList boundsList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "boundsParam" ), "bound", 6 );
typedef mitk::BaseGeometry::BoundsArrayType BoundsArrayType;
BoundsArrayType bounds;
for ( it = boundsList.begin(), i = 0;
it != boundsList.end();
++it, ++i )
{
bounds[i] = *it;
}
planeGeo->SetBounds( bounds );
// Extract and set spacing and origin
Vector3D spacing = this->GetVectorFromXMLNode(geoElement->FirstChildElement("Spacing"));
planeGeo->SetSpacing( spacing );
Point3D origin = this->GetPointFromXMLNode(geoElement->FirstChildElement("Origin"));
planeGeo->SetOrigin( origin );
planarFigure->SetPlaneGeometry(planeGeo);
}
catch (...)
{
}
}
TiXmlElement* cpElement = pfElement->FirstChildElement("ControlPoints");
bool first = true;
if (cpElement != NULL)
for( TiXmlElement* vertElement = cpElement->FirstChildElement("Vertex"); vertElement != NULL; vertElement = vertElement->NextSiblingElement("Vertex"))
{
if (vertElement == NULL)
continue;
int id = 0;
mitk::Point2D::ValueType x = 0.0;
mitk::Point2D::ValueType y = 0.0;
if (vertElement->QueryIntAttribute("id", &id) == TIXML_WRONG_TYPE)
return; // TODO: can we do a better error handling?
if (vertElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
return; // TODO: can we do a better error handling?
if (vertElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE)
return; // TODO: can we do a better error handling?
Point2D p;
p.SetElement(0, x);
p.SetElement(1, y);
if (first == true) // needed to set m_FigurePlaced to true
{
planarFigure->PlaceFigure(p);
first = false;
}
planarFigure->SetControlPoint(id, p, true);
}
// Calculate feature quantities of this PlanarFigure
planarFigure->EvaluateFeatures();
// Make sure that no control point is currently selected
planarFigure->DeselectControlPoint();
// \TODO: what about m_FigurePlaced and m_SelectedControlPoint ??
this->SetNthOutput( this->GetNumberOfOutputs(), planarFigure ); // add planarFigure as new output of this filter
}
try
{
setlocale(LC_ALL, currLocale.c_str());
}
catch(...)
{
MITK_INFO << "Could not reset locale " << currLocale;
}
m_Success = true;
}
mitk::Point3D mitk::PlanarFigureReader::GetPointFromXMLNode(TiXmlElement* e)
{
if (e == NULL)
throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
mitk::Point3D point;
mitk::ScalarType p(-1.0);
if (e->QueryDoubleAttribute("x", &p) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
point.SetElement(0, p);
if (e->QueryDoubleAttribute("y", &p) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
point.SetElement(1, p);
if (e->QueryDoubleAttribute("z", &p) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
point.SetElement(2, p);
return point;
}
mitk::Vector3D mitk::PlanarFigureReader::GetVectorFromXMLNode(TiXmlElement* e)
{
if (e == NULL)
throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
mitk::Vector3D vector;
mitk::ScalarType p(-1.0);
if (e->QueryDoubleAttribute("x", &p) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
vector.SetElement(0, p);
if (e->QueryDoubleAttribute("y", &p) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
vector.SetElement(1, p);
if (e->QueryDoubleAttribute("z", &p) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
vector.SetElement(2, p);
return vector;
}
mitk::PlanarFigureReader::DoubleList
mitk::PlanarFigureReader::GetDoubleAttributeListFromXMLNode(TiXmlElement* e, const char *attributeNameBase, unsigned int count)
{
DoubleList list;
if (e == NULL)
throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
for ( unsigned int i = 0; i < count; ++i )
{
mitk::ScalarType p(-1.0);
std::stringstream attributeName;
attributeName << attributeNameBase << i;
if (e->QueryDoubleAttribute( attributeName.str().c_str(), &p ) == TIXML_WRONG_TYPE)
throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
list.push_back( p );
}
return list;
}
void mitk::PlanarFigureReader::GenerateOutputInformation()
{
}
int mitk::PlanarFigureReader::CanReadFile ( const char *name )
{
if (std::string(name).empty())
return false;
return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(name)) == ".pf"); //assume, we can read all .pf files
//TiXmlDocument document(name);
//if (document.LoadFile() == false)
// return false;
//return (document.FirstChildElement("PlanarFigure") != NULL);
}
bool mitk::PlanarFigureReader::CanReadFile(const std::string filename, const std::string, const std::string)
{
if (filename.empty())
return false;
return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(filename)) == ".pf"); //assume, we can read all .pf files
//TiXmlDocument document(filename);
//if (document.LoadFile() == false)
// return false;
//return (document.FirstChildElement("PlanarFigure") != NULL);
}
void mitk::PlanarFigureReader::ResizeOutputs( const unsigned int& num )
{
unsigned int prevNum = this->GetNumberOfOutputs();
this->SetNumberOfIndexedOutputs( num );
for ( unsigned int i = prevNum; i < num; ++i )
{
this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() );
}
}
diff --git a/Modules/PlanarFigure/Testing/files.cmake b/Modules/PlanarFigure/Testing/files.cmake
index 3e8d679a26..5c683c9c48 100644
--- a/Modules/PlanarFigure/Testing/files.cmake
+++ b/Modules/PlanarFigure/Testing/files.cmake
@@ -1,12 +1,19 @@
set(MODULE_TESTS
mitkPlanarCrossTest.cpp
mitkPlanarPolygonTest.cpp
mitkPlanarSubdivisionPolygonTest.cpp
mitkPlanarFigureIOTest.cpp
mitkPlanarFigureObjectFactoryTest.cpp
mitkPlanarArrowTest.cpp
)
set(MODULE_CUSTOM_TESTS
mitkViewportRenderingTest.cpp
)
+
+if(MITK_ENABLE_RENDERING_TESTING) #since mitkInteractionTestHelper is currently creating a vtkRenderWindow
+set(MODULE_TESTS
+ ${MODULE_TESTS}
+ mitkPlanarFigureInteractionTest.cpp
+)
+endif()
diff --git a/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp b/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp
new file mode 100644
index 0000000000..91a0276601
--- /dev/null
+++ b/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp
@@ -0,0 +1,193 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkTestingMacros.h"
+#include <mitkTestingConfig.h>
+#include <mitkTestFixture.h>
+
+#include <mitkIOUtil.h>
+#include <mitkInteractionTestHelper.h>
+#include <mitkPlanarFigureInteractor.h>
+#include <mitkPlanarFigureReader.h>
+#include <mitkPlanarFigureWriter.h>
+
+#include <mitkPlanarAngle.h>
+#include <mitkPlanarArrow.h>
+#include <mitkPlanarBezierCurve.h>
+#include <mitkPlanarCircle.h>
+#include <mitkPlanarDoubleEllipse.h>
+#include <mitkPlanarEllipse.h>
+#include <mitkPlanarFourPointAngle.h>
+#include <mitkPlanarSubdivisionPolygon.h>
+#include <mitkPlanarLine.h>
+#include <mitkPlanarPolygon.h>
+#include <mitkPlanarRectangle.h>
+
+#include <vtkDebugLeaks.h>
+
+#include "usModuleRegistry.h"
+
+class mitkPlanarFigureInteractionTestSuite : public mitk::TestFixture
+{
+
+ CPPUNIT_TEST_SUITE(mitkPlanarFigureInteractionTestSuite);
+ MITK_TEST(AngleInteractionCreate);
+ MITK_TEST(BezierCurveInteractionCreate);
+ MITK_TEST(CircleInteractionCreate);
+ MITK_TEST(DoubleEllipseInteractionCreate);
+ MITK_TEST(PlanarFourPointAngleInteractionCreate);
+ MITK_TEST(PlanarLineInteractionCreate);
+ MITK_TEST(PlanarPolygonInteractionCreate);
+ MITK_TEST(NonClosedPlanarPolygonInteractionCreate);
+ MITK_TEST(RectangleInteractionCreate);
+ MITK_TEST(PlanarSubdivisionInteractionCreate);
+
+ CPPUNIT_TEST_SUITE_END();
+
+
+public:
+
+ void setUp()
+ {
+ /// \todo Fix leaks of vtkObjects. Bug 18095.
+ vtkDebugLeaks::SetExitError(0);
+ }
+
+ void tearDown()
+ {
+ }
+
+ void RunTest(mitk::PlanarFigure::Pointer figure, std::string interactionXmlPath, std::string referenceFigurePath)
+ {
+ mitk::DataNode::Pointer node;
+ mitk::PlanarFigureInteractor::Pointer figureInteractor;
+
+ //Create DataNode as a container for our PlanarFigure
+ node = mitk::DataNode::New();
+ node->SetData(figure);
+
+ mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionXmlPath));
+
+
+ //Load a bounding image
+ mitk::Image::Pointer testImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("InteractionTestData/InputData/scaledSingleSlice.nrrd"));
+
+ mitk::DataNode::Pointer dn = mitk::DataNode::New();
+ dn->SetData(testImage);
+ interactionTestHelper.AddNodeToStorage(dn);
+ interactionTestHelper.GetDataStorage()->Add(node, dn);
+
+
+ node->SetName("PLANAR FIGURE");
+ // set as selected
+ node->SetSelected(true);
+ node->AddProperty("selected", mitk::BoolProperty::New(true));
+
+ //Load state machine
+ figureInteractor = mitk::PlanarFigureInteractor::New();
+ us::Module* planarFigureModule = us::ModuleRegistry::GetModule("MitkPlanarFigure");
+ figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
+ figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
+ figureInteractor->SetDataNode( node );
+
+
+ //Start Interaction
+ interactionTestHelper.PlaybackInteraction();
+
+ //Load reference PlanarFigure
+ mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New();
+ reader->SetFileName(GetTestDataFilePath(referenceFigurePath));
+ reader->Update();
+ mitk::PlanarFigure::Pointer reference = reader->GetOutput(0);
+
+ //Compare figures
+ MITK_ASSERT_EQUAL(figure, reference, "Compare figure with reference");
+ }
+
+ void AngleInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarAngle::New();
+ RunTest(figure, "InteractionTestData/Interactions/Angle.xml", "InteractionTestData/ReferenceData/Angle.pf");
+ }
+
+ void BezierCurveInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarBezierCurve::New();
+ RunTest(figure, "InteractionTestData/Interactions/Bezier.xml", "InteractionTestData/ReferenceData/Bezier.pf");
+ }
+
+ void CircleInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarCircle::New();
+ RunTest(figure, "InteractionTestData/Interactions/Circle.xml", "InteractionTestData/ReferenceData/Circle.pf");
+ }
+
+ void DoubleEllipseInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarDoubleEllipse::New();
+ RunTest(figure, "InteractionTestData/Interactions/DoubleEllipse.xml", "InteractionTestData/ReferenceData/DoubleEllipse.pf");
+ }
+
+ void PlanarSubdivisionInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarSubdivisionPolygon::New();
+ RunTest(figure, "InteractionTestData/Interactions/SubDivision.xml", "InteractionTestData/ReferenceData/SubDivision.pf");
+ }
+
+ void PlanarFourPointAngleInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarFourPointAngle::New();
+ RunTest(figure, "InteractionTestData/Interactions/Planar4PointAngle.xml", "InteractionTestData/ReferenceData/Planar4PointAngle.pf");
+ }
+
+ void PlanarLineInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarLine::New();
+ RunTest(figure, "InteractionTestData/Interactions/Line.xml", "InteractionTestData/ReferenceData/Line.pf");
+ }
+
+ void PlanarPolygonInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarPolygon::New();
+ RunTest(figure, "InteractionTestData/Interactions/Polygon.xml", "InteractionTestData/ReferenceData/Polygon.pf");
+ }
+
+ void NonClosedPlanarPolygonInteractionCreate()
+ {
+ mitk::PlanarPolygon::Pointer figure;
+ figure = mitk::PlanarPolygon::New();
+ figure->ClosedOff();
+ RunTest(figure.GetPointer(), "InteractionTestData/Interactions/Path.xml", "InteractionTestData/ReferenceData/Path.pf");
+ }
+
+ void RectangleInteractionCreate()
+ {
+ mitk::PlanarFigure::Pointer figure;
+ figure = mitk::PlanarRectangle::New();
+ RunTest(figure, "InteractionTestData/Interactions/Rectangle.xml", "InteractionTestData/ReferenceData/Rectangle.pf");
+ }
+
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkPlanarFigureInteraction)
diff --git a/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp b/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp
index de74b4938b..cabc312a40 100644
--- a/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp
+++ b/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp
@@ -1,153 +1,157 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// MITK
#include "mitkTestingMacros.h"
#include "mitkRenderingTestHelper.h"
#include "mitkNodePredicateDataType.h"
#include "mitkLevelWindowProperty.h"
#include "mitkColorProperty.h"
#include "mitkLevelWindowProperty.h"
#include "mitkPlanarFigure.h"
#include "mitkSurface.h"
#include "mitkImage.h"
// ITK
#include <itkVectorContainer.h>
// VTK
#include <vtkRegressionTestImage.h>
+#include <vtkDebugLeaks.h>
// stdlib
#include <stdlib.h>
int mitkViewportRenderingTest(int argc, char* argv[]) {
// load all arguments into a datastorage, take last argument as reference rendering
// setup a renderwindow of fixed size X*Y
// render the datastorage
// compare rendering to reference image
MITK_TEST_BEGIN("mitkViewportRenderingTest")
+ /// \todo Fix leaks of vtkObjects. Bug 18095.
+ vtkDebugLeaks::SetExitError(0);
+
// enough parameters?
if ( argc < 2 )
{
MITK_TEST_OUTPUT( << "Usage: " << std::string(*argv) << " [file1 file2 ...] outputfile" )
MITK_TEST_OUTPUT( << "Will render a central axial slice of all given files into outputfile" )
exit( EXIT_FAILURE );
}
double renderWindowWidth = atof(argv[1]);
double renderWindowHeight = atof(argv[2]);
double left = atof(argv[3]);
double bottom = atof(argv[4]);
double right = atof(argv[5]);
double top = atof(argv[6]);
std::string referenceFilename = argv[8+6];
argv += 6; // DO NOT attempt to read these as files, this just makes no sense
argc -= 6; // DO NOT attempt to read these as files, this just makes no sense
MITK_INFO << "Testing viewport "<<right-left<<"x"<<top-bottom<<" ("
<< left << ", "
<< bottom << ") to ("
<< right << ", "
<< top << ") "
<< "in render window of size "
<< renderWindowWidth << "x"
<< renderWindowHeight << "px";
mitk::RenderingTestHelper renderingHelper(renderWindowWidth, renderWindowHeight, argc, argv); // non-power-of-2
//for now this test renders Sagittal
//renderingHelper.SetViewDirection(mitk::SliceNavigationController::Axial);
renderingHelper.SetViewDirection(mitk::SliceNavigationController::Axial);
typedef mitk::DataStorage::SetOfObjects ObjectsSet;
ObjectsSet::ConstPointer figures = renderingHelper.GetDataStorage()->GetSubset( mitk::TNodePredicateDataType<mitk::PlanarFigure>::New());
for (ObjectsSet::const_iterator iterFigures = figures->begin();
iterFigures != figures->end();
++iterFigures)
{
(*iterFigures)->SetProperty("planarfigure.default.line.color", mitk::ColorProperty::New( 1.0, 0.0, 0.0 ) ); // red
(*iterFigures)->SetProperty("planarfigure.drawcontrolpoints", mitk::BoolProperty::New( false ) );
(*iterFigures)->SetProperty("planarfigure.drawname", mitk::BoolProperty::New( false ) );
(*iterFigures)->SetProperty("planarfigure.drawquantities", mitk::BoolProperty::New( true ) );
}
ObjectsSet::ConstPointer surfaces = renderingHelper.GetDataStorage()->GetSubset( mitk::TNodePredicateDataType<mitk::Surface>::New());
for (ObjectsSet::const_iterator iterSurfaces = surfaces->begin();
iterSurfaces != surfaces->end();
++iterSurfaces)
{
(*iterSurfaces)->SetProperty("color", mitk::ColorProperty::New( 0.0, 1.0, 0.0 ) ); // green
}
ObjectsSet::ConstPointer images = renderingHelper.GetDataStorage()->GetSubset( mitk::TNodePredicateDataType<mitk::Image>::New());
for (ObjectsSet::const_iterator iterImages = images->begin();
iterImages != images->end();
++iterImages)
{
(*iterImages)->SetProperty("levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(128.0, 256.0) ) ); // green
int imageWidth = dynamic_cast<mitk::Image*>((*iterImages)->GetData())->GetDimension(0);
int imageHeight = dynamic_cast<mitk::Image*>((*iterImages)->GetData())->GetDimension(1);
MITK_INFO << "Image dimension "<<imageWidth<<"x"<<imageHeight;
}
mitk::RenderingManager::GetInstance()->InitializeViews( renderingHelper.GetDataStorage()->ComputeBoundingGeometry3D( images ) );
double vLeft = left / renderWindowWidth;
double vBottom = bottom / renderWindowHeight;
double vRight = right / renderWindowWidth;
double vTop = top / renderWindowHeight;
// THIS HERE IS THE ACTUAL TEST PART, all the rest is setup and decoration
renderingHelper.GetVtkRenderer()->SetViewport( vLeft, vBottom, vRight, vTop );
renderingHelper.SetAutomaticallyCloseRenderWindow(true); // set to false for testing the test itself
renderingHelper.Render();
//use this to generate a reference screenshot or save the file:
bool generateReferenceScreenshot = false;
if(generateReferenceScreenshot)
{
std::string tmpFilename = referenceFilename;
std::string::size_type slashpos = referenceFilename.find_last_of('/');
tmpFilename = referenceFilename.substr(slashpos+1);
tmpFilename = std::string("/tmp/") + tmpFilename;
renderingHelper.SaveAsPNG( tmpFilename );
MITK_INFO << "*********************************";
MITK_INFO << "SAVE TO " << tmpFilename;
MITK_INFO << "*********************************";
}
//### Usage of vtkRegressionTestImage:
//vtkRegressionTestImage( vtkRenderWindow )
//Set a vtkRenderWindow containing the desired scene.
//vtkRegressionTestImage automatically searches in argc and argv[]
//for a path a valid image with -V. If the test failed with the
//first image (foo.png) check if there are images of the form
//foo_N.png (where N=1,2,3...) and compare against them.
int retVal = vtkRegressionTestImage( renderingHelper.GetVtkRenderWindow() );
//retVal meanings: (see VTK/Rendering/vtkTesting.h)
//0 = test failed
//1 = test passed
//2 = test not run
//3 = something with vtkInteraction
MITK_TEST_CONDITION( retVal == 1, "VTK rendering result matches expectation" );
MITK_TEST_END();
}
diff --git a/Modules/Python/CMakeLists.txt b/Modules/Python/CMakeLists.txt
index 475bb4d8bf..ec064837e1 100644
--- a/Modules/Python/CMakeLists.txt
+++ b/Modules/Python/CMakeLists.txt
@@ -1,12 +1,26 @@
if( MITK_USE_Python )
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ add_definitions( -DUSE_MITK_BUILTIN_PYTHON )
+ endif()
+
+ set(OpenCV_DEP )
+ if(MITK_USE_OpenCV)
+ set(OpenCV_DEP OpenCV)
+ endif()
+
+ # workaround until testing has a package depends
+ set(SimpleITK_DEP )
+ if(BUILD_TESTING AND NOT APPLE)
+ set(SimpleITK_DEP SimpleITK)
+ endif()
+
MITK_CREATE_MODULE(
- DEPENDS MitkCore
+ DEPENDS MitkCore MitkQtWidgets
EXPORT_DEFINE MITK_PYTHON_EXPORT
- PACKAGE_DEPENDS Qt4|QtGui CTK PythonLibs
+ PACKAGE_DEPENDS Qt4|QtGui CTK|CTKScriptingPythonCore+CTKScriptingPythonWidgets PythonLibs VTK|vtkPython+vtkWrappingPythonCore Numpy ${SimpleITK_DEP} ${OpenCV_DEP}
)
- configure_file(PythonPath.h.in
- "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY)
+ configure_file(PythonPath.h.in "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY)
add_subdirectory(Testing)
endif()
diff --git a/Modules/Python/PythonPath.h.in b/Modules/Python/PythonPath.h.in
index 6f5daf2961..d62c631f5a 100644
--- a/Modules/Python/PythonPath.h.in
+++ b/Modules/Python/PythonPath.h.in
@@ -1,21 +1,19 @@
#ifdef _DEBUG
#define PYTHON_PATH_BUILD_TYPE "/Debug"
#else
#define PYTHON_PATH_BUILD_TYPE "/Release"
#endif
#define PYTHONPATH_COMMAND "import sys\n"\
-"sys.path.append('@ITK_LIBRARY_DIRS@')\n"\
-"sys.path.append('@ITK_DIR@/Wrapping/WrapITK/Python')\n"\
-"sys.path.append('@ITK_LIBRARY_DIRS@" PYTHON_PATH_BUILD_TYPE "')\n"\
-"sys.path.append('@ITK_DIR@/Wrapping/WrapITK/Python" PYTHON_PATH_BUILD_TYPE "')\n"\
-"sys.path.append('@ITK_DIR@/Wrapping/Generators/Python')\n"\
-"sys.path.append('@ITK_DIR@/lib')\n"\
-"sys.path.append('@VTK_LIBRARY_DIRS@')\n"\
+"sys.path.append('@SimpleITK_DIR@/bin')\n"\
+"sys.path.append('@SimpleITK_DIR@/lib')\n"\
+"sys.path.append('@SimpleITK_DIR@/Wrapping')\n"\
"sys.path.append('@VTK_DIR@/Wrapping/Python')\n"\
+"sys.path.append('@VTK_DIR@/lib')\n"\
"sys.path.append('@VTK_DIR@/bin" PYTHON_PATH_BUILD_TYPE "')\n"\
-"sys.path.append('@VTK_DIR@/Wrapping/Python')\n"\
"sys.path.append('@OpenCV_DIR@/lib" PYTHON_PATH_BUILD_TYPE "')\n"\
"sys.path.append('@OpenCV_DIR@/lib')\n"\
"sys.path.append('@OpenCV_DIR@/bin')\n"\
"sys.path.append('@OpenCV_DIR@/bin" PYTHON_PATH_BUILD_TYPE "')"
+
+#define PYTHONHOME "@Python_DIR@"
diff --git a/Modules/Python/QmitkCtkPythonShell.cpp b/Modules/Python/QmitkCtkPythonShell.cpp
index f8c676dccb..c5f8a7aee0 100644
--- a/Modules/Python/QmitkCtkPythonShell.cpp
+++ b/Modules/Python/QmitkCtkPythonShell.cpp
@@ -1,91 +1,91 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkCtkPythonShell.h"
#include <ctkAbstractPythonManager.h>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QUrl>
#include "mitkPythonService.h"
#include <usModuleContext.h>
#include <usServiceReference.h>
#include <usGetModuleContext.h>
struct QmitkCtkPythonShellData
{
mitk::PythonService* m_PythonService;
us::ServiceReference<mitk::PythonService> m_PythonServiceRef;
};
QmitkCtkPythonShell::QmitkCtkPythonShell(QWidget* parent)
: ctkPythonConsole(parent), d( new QmitkCtkPythonShellData )
{
MITK_DEBUG("QmitkCtkPythonShell") << "retrieving IPythonService";
us::ModuleContext* context = us::GetModuleContext();
d->m_PythonServiceRef = context->GetServiceReference<mitk::IPythonService>();
d->m_PythonService = dynamic_cast<mitk::PythonService*> ( context->GetService<mitk::IPythonService>(d->m_PythonServiceRef) );
MITK_DEBUG("QmitkCtkPythonShell") << "checking IPythonService";
Q_ASSERT( d->m_PythonService );
MITK_DEBUG("QmitkCtkPythonShell") << "initialize m_PythonService";
this->initialize( d->m_PythonService->GetPythonManager() );
MITK_DEBUG("QmitkCtkPythonShell") << "m_PythonService initialized";
}
QmitkCtkPythonShell::~QmitkCtkPythonShell()
{
us::ModuleContext* context = us::GetModuleContext();
context->UngetService( d->m_PythonServiceRef );
delete d;
}
void QmitkCtkPythonShell::dragEnterEvent(QDragEnterEvent *event)
{
event->accept();
}
void QmitkCtkPythonShell::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
for(int i = 0; i < urls.size(); i++)
{
d->m_PythonService->Execute( urls[i].toString().toStdString(), mitk::IPythonService::SINGLE_LINE_COMMAND );
}
}
bool QmitkCtkPythonShell::canInsertFromMimeData( const QMimeData *source ) const
{
return true;
}
void QmitkCtkPythonShell::executeCommand(const QString& command)
{
MITK_DEBUG("QmitkCtkPythonShell") << "executing command " << command.toStdString();
- ctkPythonConsole::executeCommand(command);
+ d->m_PythonService->Execute(command.toStdString(),mitk::IPythonService::MULTI_LINE_COMMAND);
d->m_PythonService->NotifyObserver(command.toStdString());
}
void QmitkCtkPythonShell::Paste(const QString &command)
{
if( this->isVisible() )
{
this->exec( command );
//this->executeCommand( command );
}
}
diff --git a/Modules/Python/QmitkPythonSnippets.cpp b/Modules/Python/QmitkPythonSnippets.cpp
index 975944557c..b0947c81af 100644
--- a/Modules/Python/QmitkPythonSnippets.cpp
+++ b/Modules/Python/QmitkPythonSnippets.cpp
@@ -1,483 +1,483 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonSnippets.h"
#include "QmitkPythonScriptEditorHighlighter.h"
#include <QtGui>
#include <mitkCommon.h>
#include <memory>
struct QmitkPythonSnippetsData
{
QString m_AutoSaveFileName;
QString m_SaveFileName;
QAction* m_PasteSnippet;
QAction* m_RemoveSnippet;
QAction* m_RenameSnippet;
QAction* m_AddSnippet;
QAction* m_RestoreDefaultSnippets;
QAction* m_LoadSnippets;
QAction* m_SaveSnippets;
QToolBar* m_Toolbar;
QComboBox* m_Name;
QTextEdit* m_Content;
QGridLayout* m_Layout;
QmitkPythonSnippets::QStringMap m_Snippets;
};
const QString QmitkPythonSnippets::DEFAULT_SNIPPET_FILE( ":/mitkPython/PythonSnippets.xml" );
const QString QmitkPythonSnippets::SNIPPETS_ROOT_XML_ELEMENT_NAME( "PythonSnippets" );
const QString QmitkPythonSnippets::SNIPPETS_XML_ELEMENT_NAME( "PythonSnippet" );
QmitkPythonSnippets::QmitkPythonSnippets( const QString& _AutoSaveFileName, QWidget* parent )
: QWidget(parent), d(new QmitkPythonSnippetsData)
{
d->m_SaveFileName = QDir::currentPath();
d->m_AutoSaveFileName = _AutoSaveFileName;
- if( !this->LoadStringMap( d->m_AutoSaveFileName, d->m_Snippets ) )
+ if( !QmitkPythonSnippets::LoadStringMap( d->m_AutoSaveFileName, d->m_Snippets ) )
{
- this->LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
+ QmitkPythonSnippets::LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
}
d->m_PasteSnippet = new QAction(this);
d->m_PasteSnippet->setObjectName(QString::fromUtf8("PasteSnippet"));
QIcon icon;
icon.addFile(QString::fromUtf8(":/mitkPython/edit-paste.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_PasteSnippet->setIcon(icon);
d->m_PasteSnippet->setToolTip("Paste snippet!");
d->m_PasteSnippet->setEnabled(false);
d->m_RemoveSnippet = new QAction(this);
d->m_RemoveSnippet->setObjectName(QString::fromUtf8("RemoveSnippet"));
QIcon icon1;
icon1.addFile(QString::fromUtf8(":/mitkPython/edit-delete.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RemoveSnippet->setIcon(icon1);
d->m_RemoveSnippet->setToolTip("Remove snippet.");
d->m_RemoveSnippet->setEnabled(false);
d->m_RenameSnippet = new QAction(this);
d->m_RenameSnippet->setObjectName(QString::fromUtf8("RenameSnippet"));
QIcon icon2;
icon2.addFile(QString::fromUtf8(":/mitkPython/edit-find-replace.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RenameSnippet->setIcon(icon2);
d->m_RenameSnippet->setToolTip("Rename snippet.");
d->m_RenameSnippet->setEnabled(false);
d->m_AddSnippet = new QAction(this);
d->m_AddSnippet->setObjectName(QString::fromUtf8("AddSnippet"));
QIcon icon3;
icon3.addFile(QString::fromUtf8(":/mitkPython/document-new.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_AddSnippet->setIcon(icon3);
d->m_AddSnippet->setToolTip("Add snippet.");
d->m_RestoreDefaultSnippets = new QAction(this);
d->m_RestoreDefaultSnippets->setObjectName(QString::fromUtf8("RestoreDefaultSnippets"));
QIcon icon4;
icon4.addFile(QString::fromUtf8(":/mitkPython/edit-clear.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RestoreDefaultSnippets->setIcon(icon4);
d->m_RestoreDefaultSnippets->setToolTip("Restore default snippets");
d->m_LoadSnippets = new QAction(this);
d->m_LoadSnippets->setToolTip("Load Snippets from disk.");
d->m_LoadSnippets->setObjectName(QString::fromUtf8("LoadSnippets"));
QIcon icon5;
icon5.addFile(QString::fromUtf8(":/mitkPython/document-open.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_LoadSnippets->setIcon(icon5);
d->m_SaveSnippets = new QAction(this);
d->m_SaveSnippets->setToolTip("Save Snippets to disk.");
d->m_SaveSnippets->setObjectName(QString::fromUtf8("SaveSnippets"));
QIcon icon6;
icon6.addFile(QString::fromUtf8(":/mitkPython/document-save.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_SaveSnippets->setIcon(icon6);
d->m_SaveSnippets->setEnabled(false);
d->m_Toolbar = new QToolBar;
d->m_Toolbar->addAction( d->m_PasteSnippet );
d->m_Toolbar->addAction( d->m_AddSnippet );
d->m_Toolbar->addAction( d->m_RemoveSnippet );
d->m_Toolbar->addAction( d->m_RenameSnippet );
d->m_Toolbar->addAction( d->m_RestoreDefaultSnippets );
d->m_Toolbar->addAction( d->m_SaveSnippets );
d->m_Toolbar->addAction( d->m_LoadSnippets );
d->m_Name = new QComboBox;
d->m_Name->setObjectName(QString::fromUtf8("Name"));
d->m_Content = new QTextEdit(this);
d->m_Content->setObjectName(QString::fromUtf8("Content"));
d->m_Content->setEnabled(false);
QmitkPythonScriptEditorHighlighter* highlighter =
new QmitkPythonScriptEditorHighlighter( d->m_Content->document() );
d->m_Layout = new QGridLayout;
d->m_Layout->addWidget( d->m_Toolbar, 0, 0, 1, 1 );
d->m_Layout->addWidget( d->m_Name, 1, 0, 1, 1 );
d->m_Layout->addWidget( d->m_Content, 2, 0, 1, 1 );
d->m_Layout->setContentsMargins(2,2,2,2);
this->setLayout(d->m_Layout);
QMetaObject::connectSlotsByName(this);
this->Update();
}
QmitkPythonSnippets::~QmitkPythonSnippets()
{
delete d;
}
void QmitkPythonSnippets::on_PasteSnippet_triggered( bool )
{
emit PasteCommandRequested( d->m_Content->toPlainText() );
}
void QmitkPythonSnippets::on_RenameSnippet_triggered(bool)
{
QString oldname = d->m_Name->currentText();
QString name = oldname;
bool ok = false;
while( true )
{
name = QInputDialog::getText(this,
tr("Add new snippet"),
tr("Name of snippet:"),
QLineEdit::Normal,
name,
&ok);
if (ok)
{
if ( d->m_Snippets.contains(name) )
{
QMessageBox::warning(this,
tr("Duplicate name."),
tr("The entered name already exists. Enter another one or cancel the operation."),
QMessageBox::Ok,
QMessageBox::Ok );
}
else
{
QString tmpSnippet = d->m_Snippets[oldname];
d->m_Snippets.remove(oldname);
d->m_Snippets[name] = tmpSnippet;
this->Update(name);
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
break;
}
}
else
{
break;
}
}
}
void QmitkPythonSnippets::on_AddSnippet_triggered(bool)
{
bool ok;
QString name = QInputDialog::getText(this,
tr("Add new snippet"),
tr("Name of snippet:"),
QLineEdit::Normal,
"newSnippet",
&ok);
if (ok && !name.isEmpty())
{
MITK_DEBUG("QmitkPythonSnippets") << "creating unique name for " << name.toStdString();
name = this->CreateUniqueName(name);
MITK_DEBUG("QmitkPythonSnippets") << "creating snippet " << name.toStdString();
d->m_Snippets[name] = "";
this->Update(name);
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
QString QmitkPythonSnippets::CreateUniqueName( const QString& name ) const
{
QString newName = name;
size_t i = 2;
while( d->m_Snippets.contains(name) )
{
newName = name + QString("_%1").arg(i);
++i;
}
return newName;
}
void QmitkPythonSnippets::on_RemoveSnippet_triggered(bool)
{
QString name = d->m_Name->currentText();
QString question = QString("Really remove Snippet %1?").arg(name);
int remove = QMessageBox::question( this,
QString("Confirm removal"),
question,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
if( remove == QMessageBox::Yes || remove == QMessageBox::Ok )
{
d->m_Snippets.remove(name);
this->Update();
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
void QmitkPythonSnippets::on_RestoreDefaultSnippets_triggered(bool)
{
QString question = QString("Really restore default Snippets?");
int remove = QMessageBox::question( this,
QString("Confirm restoring"),
question,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
if( remove == QMessageBox::Yes || remove == QMessageBox::Ok )
{
- this->LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
+ QmitkPythonSnippets::LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
this->Update();
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
void QmitkPythonSnippets::on_Name_currentIndexChanged(int i)
{
bool validSelection = i >= 0 ;
d->m_PasteSnippet->setEnabled(validSelection);
d->m_RemoveSnippet->setEnabled(validSelection);
d->m_RenameSnippet->setEnabled(validSelection);
d->m_Content->setEnabled(validSelection);
d->m_SaveSnippets->setEnabled(validSelection);
if( validSelection )
{
QString name = d->m_Name->currentText();
MITK_DEBUG("QmitkPythonSnippets") << "selected snippet " << name.toStdString();
d->m_Content->setText( d->m_Snippets[name] );
MITK_DEBUG("QmitkPythonSnippets") << "selected snippet content " << d->m_Snippets[name].toStdString();
}
}
void QmitkPythonSnippets::SaveStringMap(const QString &filename, const QmitkPythonSnippets::QStringMap &map) const
{
MITK_DEBUG("QmitkPythonSnippets") << "saving to xml file " << filename.toStdString();
if( filename.isEmpty() )
{
MITK_WARN("QmitkPythonSnippets") << "empty auto save file path given. quit.";
return;
}
QFile file(filename);
file.open(QIODevice::WriteOnly);
if( !file.isOpen() )
{
MITK_WARN("QmitkPythonSnippets") << "could not open file " << filename.toStdString() << " for writing";
return;
}
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement(SNIPPETS_ROOT_XML_ELEMENT_NAME);
QStringMap::const_iterator it = d->m_Snippets.begin();
while( it != d->m_Snippets.end() )
{
{
MITK_DEBUG("QmitkPythonSnippets") << "SNIPPETS_XML_ELEMENT_NAME " << SNIPPETS_XML_ELEMENT_NAME.toStdString();
MITK_DEBUG("QmitkPythonSnippets") << "writing item " << it.key().toStdString();
}
xmlWriter.writeStartElement(SNIPPETS_XML_ELEMENT_NAME);
xmlWriter.writeAttribute( "key", it.key() );
xmlWriter.writeAttribute( "value", it.value() );
xmlWriter.writeEndElement();
++it;
}
xmlWriter.writeEndDocument();
if( file.isOpen() )
file.close();
{
MITK_DEBUG("QmitkPythonSnippets") << "SaveStringMap successful ";
}
}
-bool QmitkPythonSnippets::LoadStringMap( const QString& filename, QmitkPythonSnippets::QStringMap& oldMap ) const
+bool QmitkPythonSnippets::LoadStringMap( const QString& filename, QmitkPythonSnippets::QStringMap& oldMap )
{
MITK_DEBUG("QmitkPythonSnippets") << "loading from xml file " << filename.toStdString();
QStringMap map;
QXmlStreamReader xmlReader;
QFile file;
QByteArray data;
// resource file
if( filename.startsWith(":") )
{
QResource res( filename );
data = QByteArray( reinterpret_cast< const char* >( res.data() ), res.size() );
xmlReader.addData( data );
}
else
{
file.setFileName( filename );
if (!file.open(QFile::ReadOnly | QFile::Text))
{
MITK_ERROR << "Error: Cannot read file " << qPrintable(filename)
<< ": " << qPrintable(file.errorString());
return false;
}
xmlReader.setDevice(&file);
}
xmlReader.readNext();
while(!xmlReader.atEnd())
{
xmlReader.readNext();
if(xmlReader.name() == SNIPPETS_XML_ELEMENT_NAME)
{
QXmlStreamAttributes attributes = xmlReader.attributes();
QString key;
QString value;
if(attributes.hasAttribute("key"))
{
key = attributes.value("key").toString();
}
if(attributes.hasAttribute("value"))
{
value = attributes.value("value").toString();
}
if( !key.isEmpty() )
{
MITK_DEBUG("QmitkPythonSnippets") << "loaded snippet " << key.toStdString();
MITK_DEBUG("QmitkPythonSnippets") << "value " << value.toStdString();
map[key] = value;
}
}
}
if (xmlReader.hasError())
{
MITK_ERROR << "Error: Failed to parse file "
<< qPrintable(filename) << ": "
<< qPrintable(xmlReader.errorString());
return false;
}
else if (file.error() != QFile::NoError)
{
MITK_ERROR << "Error: Cannot read file " << qPrintable(filename)
<< ": " << qPrintable(file.errorString());
return false;
}
if( file.isOpen() )
file.close();
oldMap = map;
return true;
}
void QmitkPythonSnippets::Update(const QString &name)
{
d->m_Name->clear();
d->m_Content->clear();
MITK_DEBUG("QmitkPythonSnippets") << "size of snippets " << d->m_Snippets.size();
QStringMap::const_iterator it = d->m_Snippets.begin();
while( it != d->m_Snippets.end() )
{
MITK_DEBUG("QmitkPythonSnippets") << "adding item " << it.key().toStdString();
d->m_Name->addItem( it.key() );
++it;
}
int index = d->m_Name->findText( name );
if( index >= 0 )
{
MITK_DEBUG("QmitkPythonSnippets") << "selecting index " << index;
d->m_Name->setCurrentIndex(index);
}
}
void QmitkPythonSnippets::on_Content_textChanged()
{
if( d->m_Content->isEnabled() )
{
QString name = d->m_Name->currentText();
QString snippet = d->m_Content->toPlainText();
d->m_Snippets[name] = snippet;
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
MITK_DEBUG("QmitkPythonSnippets") << "SaveStringMap successful";
}
}
void QmitkPythonSnippets::on_SaveSnippets_triggered(bool)
{
QString fileName = QFileDialog::getSaveFileName(this, "Save snippets", d->m_SaveFileName, "XML files (*.xml)");
if( !fileName.isEmpty() )
{
d->m_SaveFileName = fileName;
this->SaveStringMap( d->m_SaveFileName, d->m_Snippets );
}
}
void QmitkPythonSnippets::on_LoadSnippets_triggered(bool)
{
QString fileName = QFileDialog::getOpenFileName(this, "Load snippets", d->m_SaveFileName, "XML files (*.xml)");
if( !fileName.isEmpty() )
{
d->m_SaveFileName = fileName;
QString question = QString("Your current snippets will be overwritten. Proceed?");
int overwrite = QMessageBox::warning(this,
QString("Confirm overwrite"),
question,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
if( overwrite == QMessageBox::Yes )
{
this->LoadStringMap( d->m_SaveFileName, d->m_Snippets );
this->Update( d->m_Name->currentText() );
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
}
diff --git a/Modules/Python/QmitkPythonSnippets.h b/Modules/Python/QmitkPythonSnippets.h
index 39c808a419..998e0a635b 100644
--- a/Modules/Python/QmitkPythonSnippets.h
+++ b/Modules/Python/QmitkPythonSnippets.h
@@ -1,104 +1,105 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _QmitkPythonSnippets_H
#define _QmitkPythonSnippets_H
#include <QWidget>
#include <QMap>
#include <MitkPythonExports.h>
struct QmitkPythonSnippetsData;
///
/// a widget that holds snippets and serializes the snippets to a certain places
class MITK_PYTHON_EXPORT QmitkPythonSnippets: public QWidget
{
Q_OBJECT
public:
static const QString DEFAULT_SNIPPET_FILE;
static const QString SNIPPETS_ROOT_XML_ELEMENT_NAME;
static const QString SNIPPETS_XML_ELEMENT_NAME;
///
/// typedef for string map
typedef QMap<QString, QString> QStringMap;
///
/// build ui here
/// the snippets will be loaded from _AutoSaveFileName if not empty and readable
/// otherwise the default snippets will be loaded
QmitkPythonSnippets( const QString& _AutoSaveFileName="", QWidget* parent=0 );
///
/// delete d pointer
virtual ~QmitkPythonSnippets();
+ ///
+ /// read string map from xml file
+ static bool LoadStringMap( const QString& filename, QStringMap& oldMap );
+
signals:
///
/// this class whishes to paste sth command
void PasteCommandRequested(const QString& command);
protected slots:
///
/// emits PasteCommandRequested signal
void on_PasteSnippet_triggered( bool checked = false );
///
/// ask for name as long as it exists, call update()
void on_RenameSnippet_triggered( bool checked = false );
///
/// ask for name, create snippet, call update()
void on_AddSnippet_triggered( bool checked = false );
///
/// remove the current snippet, call update()
void on_RemoveSnippet_triggered( bool checked = false );
///
/// call LoadStringMap with d->m_DefaultSnippetsAutoSaveFileName
void on_RestoreDefaultSnippets_triggered( bool checked = false );
///
/// update action state (enable/disable), update text box
void on_Name_currentIndexChanged( int i );
///
/// save changed snippet
void on_Content_textChanged();
///
/// ask for file, save snippets
void on_SaveSnippets_triggered( bool checked = false );
///
/// ask for file, load snippets (do not replace)
void on_LoadSnippets_triggered( bool checked = false );
protected:
///
/// write string map to xml file
void SaveStringMap( const QString& filename, const QStringMap& map ) const;
///
- /// read string map from xml file
- bool LoadStringMap( const QString& filename, QStringMap& oldMap ) const;
- ///
/// creates a name which does not exist in the list
QString CreateUniqueName(const QString &name) const;
///
/// update combo box
/// if name is passed, the according element will be selected
void Update(const QString &name = "");
private:
///
/// d pointer declaration (holds members)
QmitkPythonSnippetsData* d;
};
#endif // _QmitkPythonSnippets_H_INCLUDED
diff --git a/Modules/Python/QmitkPythonTextEditor.cpp b/Modules/Python/QmitkPythonTextEditor.cpp
index a5603af153..2789143341 100644
--- a/Modules/Python/QmitkPythonTextEditor.cpp
+++ b/Modules/Python/QmitkPythonTextEditor.cpp
@@ -1,184 +1,184 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonTextEditor.h"
#include <QList>
#include <QFileInfo>
#include <QUrl>
#include <QtGui>
#include <usModuleContext.h>
#include <usServiceReference.h>
#include <mitkDataNode.h>
#include <usGetModuleContext.h>
#include <mitkIPythonService.h>
#include "QmitkPythonScriptEditorHighlighter.h"
struct QmitkPythonTextEditorData
{
QString m_FilePath;
QAction* m_LoadScript;
QAction* m_SaveScript;
QAction* m_RunScript;
QToolBar* m_Toolbar;
QTextEdit* m_Content;
QGridLayout* m_Layout;
mitk::IPythonService* m_PythonService;
us::ServiceReference<mitk::IPythonService> m_PythonServiceRef;
QString m_FileName;
};
QmitkPythonTextEditor::QmitkPythonTextEditor(QWidget *parent)
:QWidget(parent), d(new QmitkPythonTextEditorData)
{
us::ModuleContext* context = us::GetModuleContext();
d->m_PythonServiceRef = context->GetServiceReference<mitk::IPythonService>();
d->m_PythonService = context->GetService<mitk::IPythonService>( d->m_PythonServiceRef );
d->m_LoadScript = new QAction(this);
d->m_LoadScript->setToolTip("Load script from disk.");
d->m_LoadScript->setObjectName(QString::fromUtf8("LoadScript"));
QIcon icon2;
icon2.addFile(QString::fromUtf8(":/mitkPython/document-open.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_LoadScript->setIcon(icon2);
d->m_SaveScript = new QAction(this);
d->m_SaveScript->setToolTip("Save script to disk.");
d->m_SaveScript->setObjectName(QString::fromUtf8("SaveScript"));
QIcon icon3;
icon3.addFile(QString::fromUtf8(":/mitkPython/document-save.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_SaveScript->setIcon(icon3);
d->m_RunScript = new QAction(this);
d->m_RunScript->setToolTip("Run the current script.");
d->m_RunScript->setObjectName(QString::fromUtf8("RunScript"));
QIcon icon4;
icon4.addFile(QString::fromUtf8(":/mitkPython/media-playback-start.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RunScript->setIcon(icon4);
d->m_Toolbar = new QToolBar;
d->m_Toolbar->addAction( d->m_LoadScript );
d->m_Toolbar->addAction( d->m_SaveScript );
d->m_Toolbar->addAction( d->m_RunScript );
d->m_Content = new QTextEdit(this);
d->m_Content->setObjectName(QString::fromUtf8("Content"));
QmitkPythonScriptEditorHighlighter* highlighter =
new QmitkPythonScriptEditorHighlighter( d->m_Content->document() );
d->m_Layout = new QGridLayout;
d->m_Layout->addWidget( d->m_Toolbar, 0, 0, 1, 1 );
d->m_Layout->addWidget( d->m_Content, 1, 0, 1, 1 );
d->m_Layout->setContentsMargins(2,2,2,2);
this->setLayout(d->m_Layout);
QMetaObject::connectSlotsByName(this);
}
QmitkPythonTextEditor::~QmitkPythonTextEditor()
{
us::ModuleContext* context = us::GetModuleContext();
context->UngetService( d->m_PythonServiceRef );
delete d;
}
void QmitkPythonTextEditor::dragEnterEvent(QDragEnterEvent *event)
{
event->accept();
}
void QmitkPythonTextEditor::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
for(int i = 0; i < urls.size(); i++)
{
this->Paste( urls[i].toString() );
}
}
/*
bool QmitkPythonTextEditor::canInsertFromMimeData( const QMimeData * ) const
{
return true;
}
*/
void QmitkPythonTextEditor::Paste(const QString &command)
{
if( this->isVisible() )
{
d->m_Content->insertPlainText(command + "\n");
}
}
QString QmitkPythonTextEditor::ReadFile(const QString& filename)
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
MITK_ERROR << "Could not open file " << filename.toStdString();
return NULL;
}
QByteArray total;
QByteArray line;
while (!file.atEnd())
{
line = file.read(1024);
total.append(line);
}
return QString(total);
}
void QmitkPythonTextEditor::on_SaveScript_triggered( bool )
{
d->m_FileName = QFileDialog::getSaveFileName(this,tr("Save File"), d->m_FileName,tr("*.py"));
if( d->m_FileName.compare("") != 0)
{
- ofstream myfile;
+ std::ofstream myfile;
myfile.open(d->m_FileName.toLocal8Bit().data());
myfile << d->m_Content->toPlainText().toLocal8Bit().data();
myfile.close();
}
}
void QmitkPythonTextEditor::on_LoadScript_triggered( bool )
{
d->m_FileName = QFileDialog::getOpenFileName( this, "Load Script", d->m_FileName, tr("*.py"));
if( !d->m_FileName.isEmpty() )
{
QString contents = this->ReadFile( d->m_FileName );
d->m_Content->setText(contents);
}
}
void QmitkPythonTextEditor::on_RunScript_triggered( bool )
{
if( !d->m_PythonService )
{
MITK_ERROR << "Python service not available.";
return;
}
d->m_PythonService->Execute( d->m_Content->toPlainText().toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
}
diff --git a/Modules/Python/QmitkPythonVariableStackTableModel.cpp b/Modules/Python/QmitkPythonVariableStackTableModel.cpp
index a06b9f9002..38ecedaf89 100755
--- a/Modules/Python/QmitkPythonVariableStackTableModel.cpp
+++ b/Modules/Python/QmitkPythonVariableStackTableModel.cpp
@@ -1,223 +1,225 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonVariableStackTableModel.h"
#include <QMimeData>
#include <usModuleContext.h>
#include <mitkDataNode.h>
#include <usGetModuleContext.h>
#include <QStringList>
#include <QMessageBox>
+#include "QmitkMimeTypes.h"
const QString QmitkPythonVariableStackTableModel::MITK_IMAGE_VAR_NAME = "mitkImage";
const QString QmitkPythonVariableStackTableModel::MITK_SURFACE_VAR_NAME = "mitkSurface";
QmitkPythonVariableStackTableModel::QmitkPythonVariableStackTableModel(QObject *parent)
:QAbstractTableModel(parent)
{
us::ModuleContext* context = us::GetModuleContext();
m_PythonServiceRef = context->GetServiceReference<mitk::IPythonService>();
m_PythonService = context->GetService<mitk::IPythonService>(m_PythonServiceRef);
m_PythonService->AddPythonCommandObserver( this );
}
QmitkPythonVariableStackTableModel::~QmitkPythonVariableStackTableModel()
{
us::ModuleContext* context = us::GetModuleContext();
context->UngetService( m_PythonServiceRef );
m_PythonService->RemovePythonCommandObserver( this );
}
bool QmitkPythonVariableStackTableModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
// Early exit, returning true, but not actually doing anything (ignoring data).
if (action == Qt::IgnoreAction)
return true;
// Note, we are returning true if we handled it, and false otherwise
bool returnValue = false;
- if(data->hasFormat("application/x-mitk-datanodes"))
+ if(data->hasFormat(QmitkMimeTypes::DataNodePtrs))
{
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "dropped MITK DataNode";
returnValue = true;
- QString arg = QString(data->data("application/x-mitk-datanodes").data());
- QStringList listOfDataNodeAddressPointers = arg.split(",");
-
- QStringList::iterator slIter;
int i = 0;
- int j = 0;
- for (slIter = listOfDataNodeAddressPointers.begin();
- slIter != listOfDataNodeAddressPointers.end();
- slIter++)
+ QList<mitk::DataNode*> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
+ mitk::DataNode* node = NULL;
+ foreach(node, dataNodeList)
{
- long val = (*slIter).toLong();
- mitk::DataNode* node = static_cast<mitk::DataNode *>((void*)val);
mitk::Image* mitkImage = dynamic_cast<mitk::Image*>(node->GetData());
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "mitkImage is not null " << (mitkImage != 0? "true": "false");
+ QRegExp rx("^\\d");
+ QString varName(node->GetName().c_str());
+ // regex replace every character that is not allowed in a python variable
+ varName = varName.replace(QRegExp("[.\\+\\-*\\s\\/\\n\\t\\r]"),QString("_"));
+
if( mitkImage )
{
- QString varName = MITK_IMAGE_VAR_NAME;
+ if ( varName.isEmpty() )
+ varName = MITK_IMAGE_VAR_NAME;
+ if ( rx.indexIn(varName) == 0)
+ varName.prepend("_").prepend(MITK_IMAGE_VAR_NAME);
+
if( i > 0 )
- varName = QString("%1%2").arg(MITK_IMAGE_VAR_NAME).arg(i);
+ varName = QString("%1%2").arg(varName).arg(i);
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString();
bool exportAsCvImage = mitkImage->GetDimension() == 2 && m_PythonService->IsOpenCvPythonWrappingAvailable();
if( exportAsCvImage )
{
int ret = QMessageBox::question(NULL, "Export option",
- "2D image detected. Export as OpenCV image to Python instead of an ITK image?",
+ "2D image detected. Export as OpenCV image to Python instead of an SimpleITK image?",
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
-
exportAsCvImage = ret == QMessageBox::Yes;
if(exportAsCvImage)
{
- m_PythonService->CopyToPythonAsCvImage( mitkImage, MITK_IMAGE_VAR_NAME.toStdString() );
+ varName = MITK_IMAGE_VAR_NAME;
+ m_PythonService->CopyToPythonAsCvImage( mitkImage, varName.toStdString() );
++i;
}
}
if( !exportAsCvImage )
{
- if( m_PythonService->IsItkPythonWrappingAvailable() )
+ if( m_PythonService->IsSimpleItkPythonWrappingAvailable() )
{
- m_PythonService->CopyToPythonAsItkImage( mitkImage, MITK_IMAGE_VAR_NAME.toStdString() );
+ m_PythonService->CopyToPythonAsSimpleItkImage( mitkImage, varName.toStdString() );
++i;
}
else
{
- MITK_ERROR << "ITK Python wrapping not available. Skipping export for image " << node->GetName();
+ MITK_ERROR << "SimpleITK Python wrapping not available. Skipping export for image " << node->GetName();
}
}
}
else
{
mitk::Surface* surface = dynamic_cast<mitk::Surface*>(node->GetData());
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "found surface";
if( surface )
{
- QString varName = MITK_SURFACE_VAR_NAME;
- MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString();
+ if (varName.isEmpty() )
+ varName = MITK_SURFACE_VAR_NAME;
+ if ( rx.indexIn(varName) == 0)
+ varName.prepend("_").prepend(MITK_SURFACE_VAR_NAME);
- if( j > 0 )
- varName = QString("%1%2").arg(MITK_SURFACE_VAR_NAME).arg(j);
- MITK_DEBUG("varName") << "varName" << varName.toStdString();
+ MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName;
if( m_PythonService->IsVtkPythonWrappingAvailable() )
{
- m_PythonService->CopyToPythonAsVtkPolyData( surface, MITK_SURFACE_VAR_NAME.toStdString() );
- ++j;
+ m_PythonService->CopyToPythonAsVtkPolyData( surface, varName.toStdString() );
}
else
{
MITK_ERROR << "VTK Python wrapping not available. Skipping export for surface " << node->GetName();
}
}
}
}
}
return returnValue;
}
QVariant QmitkPythonVariableStackTableModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
QVariant headerData;
// show only horizontal header
if ( role == Qt::DisplayRole )
{
if( orientation == Qt::Horizontal )
{
// first column: "Attribute"
if(section == 0)
headerData = "Attribute";
else if(section == 1)
headerData = "Type";
else if(section == 2)
headerData = "Value";
}
}
return headerData;
}
Qt::ItemFlags QmitkPythonVariableStackTableModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if(index.isValid())
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | flags;
else
return Qt::ItemIsDropEnabled | flags;
}
int QmitkPythonVariableStackTableModel::rowCount(const QModelIndex &) const
{
return m_VariableStack.size();
}
int QmitkPythonVariableStackTableModel::columnCount(const QModelIndex &) const
{
return 3;
}
QVariant QmitkPythonVariableStackTableModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && !m_VariableStack.empty())
{
if(role == Qt::DisplayRole)
{
mitk::PythonVariable item = m_VariableStack.at(index.row());
if(index.column() == 0)
return QString::fromStdString(item.m_Name);
if(index.column() == 1)
return QString::fromStdString(item.m_Type);
if(index.column() == 2)
return QString::fromStdString(item.m_Value);
}
}
return QVariant();
}
QStringList QmitkPythonVariableStackTableModel::mimeTypes() const
{
return QAbstractTableModel::mimeTypes();
QStringList types;
types << "application/x-mitk-datanodes";
types << "application/x-qabstractitemmodeldatalist";
return types;
}
Qt::DropActions QmitkPythonVariableStackTableModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
void QmitkPythonVariableStackTableModel::CommandExecuted(const std::string& pythonCommand)
{
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "command was executed " << pythonCommand;
m_VariableStack = m_PythonService->GetVariableStack();
QAbstractTableModel::reset();
}
std::vector<mitk::PythonVariable> QmitkPythonVariableStackTableModel::GetVariableStack() const
{
return m_VariableStack;
}
diff --git a/Modules/Python/QmitkPythonVariableStackTableView.cpp b/Modules/Python/QmitkPythonVariableStackTableView.cpp
index 4921eaec4f..a5a7425567 100755
--- a/Modules/Python/QmitkPythonVariableStackTableView.cpp
+++ b/Modules/Python/QmitkPythonVariableStackTableView.cpp
@@ -1,107 +1,116 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonVariableStackTableView.h"
#include <usModuleContext.h>
#include <usServiceReference.h>
#include <usGetModuleContext.h>
#include <mitkRenderingManager.h>
#include <mitkSurface.h>
+#include <vtkPolyData.h>
QmitkPythonVariableStackTableView::QmitkPythonVariableStackTableView(QWidget *parent)
:QTableView(parent)
{
m_TableModel = new QmitkPythonVariableStackTableModel(parent);
m_TableModel->CommandExecuted("");
this->setSelectionBehavior( QAbstractItemView::SelectRows );
this->setAlternatingRowColors(true);
this->setDropIndicatorShown(true);
this->setAcceptDrops(true);
this->setModel( m_TableModel );
us::ModuleContext* context = us::GetModuleContext();
us::ServiceReference<mitk::IPythonService> serviceRef = context->GetServiceReference<mitk::IPythonService>();
m_PythonService = context->GetService<mitk::IPythonService>(serviceRef);
connect( this, SIGNAL(doubleClicked ( const QModelIndex& )), this, SLOT( OnVariableStackDoubleClicked(const QModelIndex&) ) );
}
QmitkPythonVariableStackTableView::~QmitkPythonVariableStackTableView()
{
}
void QmitkPythonVariableStackTableView::SetDataStorage(mitk::DataStorage *_DataStorage)
{
m_DataStorage = _DataStorage;
}
void QmitkPythonVariableStackTableView::OnVariableStackDoubleClicked(const QModelIndex &index)
{
if( m_DataStorage.IsNull() || m_PythonService == 0 )
{
MITK_ERROR << "QmitkPythonVariableStackTableView not configured correctly. Quit";
return;
}
int row = index.row();
std::vector<mitk::PythonVariable> variableStack = m_TableModel->GetVariableStack();
{
MITK_DEBUG("QmitkPythonVariableStackTableView") << "row " << row;
MITK_DEBUG("QmitkPythonVariableStackTableView") << "variableStack.size(): " << variableStack.size();
}
QString varName = QString::fromStdString( variableStack.at(row).m_Name );
QString type = QString::fromStdString( variableStack.at(row).m_Type );
QString value = QString::fromStdString( variableStack.at(row).m_Value );
{
MITK_DEBUG("QmitkPythonVariableStackTableView") << "varName: " << varName.toStdString();
MITK_DEBUG("QmitkPythonVariableStackTableView") << "type: " << type.toStdString();
}
mitk::Image::Pointer mitkImage;
mitk::Surface::Pointer mitkSurface;
- if( type.startsWith("itkImage") )
+ if( type.startsWith("Image") )
{
- mitkImage = m_PythonService->CopyItkImageFromPython(varName.toStdString());
+ mitkImage = m_PythonService->CopySimpleItkImageFromPython(varName.toStdString());
}
else if( type.startsWith("numpy.ndarray") )
{
mitkImage = m_PythonService->CopyCvImageFromPython(varName.toStdString());
}
else if( value.startsWith("(vtkPolyData)") )
{
mitkSurface = m_PythonService->CopyVtkPolyDataFromPython(varName.toStdString());
}
std::string nodeName = varName.toStdString();
- mitk::DataNode::Pointer node = mitk::DataNode::New();
- node->SetName ( nodeName );
+ mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode(nodeName);
+
+ // only create data node if it does not exist
+ if ( node.IsNull() )
+ {
+ node = mitk::DataNode::New();
+ node->SetName ( nodeName );
+ m_DataStorage->Add(node);
+ }
if( mitkImage.IsNotNull() )
{
node->SetData( mitkImage );
}
else if( mitkSurface.IsNotNull() )
{
node->SetData( mitkSurface );
+ // init renderwindow geometry
+ mitk::RenderingManager::GetInstance()->InitializeViews(mitkSurface->GetGeometry());
}
- m_DataStorage->Add(node);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
diff --git a/Modules/Python/Testing/CMakeLists.txt b/Modules/Python/Testing/CMakeLists.txt
index c1470c885b..153cd81e2e 100644
--- a/Modules/Python/Testing/CMakeLists.txt
+++ b/Modules/Python/Testing/CMakeLists.txt
@@ -1,4 +1 @@
MITK_CREATE_MODULE_TESTS()
-
-mitkAddCustomModuleTest(mitkCopyToPythonAsItkImage_CopyPic3DToPythonAndBackToMitk_ImageIsEqual mitkCopyToPythonAsItkImageTest ${MITK_DATA_DIR}/Pic3D.nrrd)
-
diff --git a/Modules/Python/Testing/files.cmake b/Modules/Python/Testing/files.cmake
index c8e9fe00e2..fb6dc38d7e 100644
--- a/Modules/Python/Testing/files.cmake
+++ b/Modules/Python/Testing/files.cmake
@@ -1,7 +1,13 @@
set(MODULE_TESTS
mitkPythonTest.cpp
+ mitkVtkPythonTest.cpp
)
-set(MODULE_CUSTOM_TESTS
- mitkCopyToPythonAsItkImageTest.cpp
-)
+if(MITK_USE_OpenCV)
+ set(MODULE_TESTS ${MODULE_TESTS} mitkCvPythonTest.cpp)
+endif()
+
+if(MITK_USE_SimpleITK)
+ set(MODULE_TESTS ${MODULE_TESTS} mitkSimpleItkPythonTest.cpp)
+endif()
+
diff --git a/Modules/Python/Testing/mitkCommonPythonTest.h b/Modules/Python/Testing/mitkCommonPythonTest.h
new file mode 100644
index 0000000000..420e97bcb7
--- /dev/null
+++ b/Modules/Python/Testing/mitkCommonPythonTest.h
@@ -0,0 +1,72 @@
+
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+#include <mitkImage.h>
+#include <mitkSurface.h>
+#include <mitkIOUtil.h>
+#include <mitkTestingMacros.h>
+#include <mitkTestFixture.h>
+
+#include <usModuleContext.h>
+#include <usGetModuleContext.h>
+#include <usServiceReference.h>
+#include <usModuleRegistry.h>
+#include <usModule.h>
+#include <usServiceReference.h>
+#include <mitkPythonService.h>
+#include <mitkIPythonService.h>
+#include <QmitkPythonSnippets.h>
+
+namespace mitk
+{
+
+class CommonPythonTestSuite : public mitk::TestFixture
+{
+
+protected:
+ mitk::PythonService* m_PythonService;
+ mitk::Image::Pointer m_Image;
+ mitk::Image::Pointer m_Image2D;
+ mitk::Surface::Pointer m_Surface;
+ QMap<QString, QString> m_Snippets;
+
+public:
+
+ void setUp()
+ {
+ //get the context of the python module
+ us::Module* module = us::ModuleRegistry::GetModule("MitkPython");
+ us::ModuleContext* context = module->GetModuleContext();
+ //get the service which is generated in the PythonModuleActivator
+ us::ServiceReference<mitk::IPythonService> serviceRef = context->GetServiceReference<mitk::IPythonService>();
+ m_PythonService = dynamic_cast<mitk::PythonService*>( context->GetService(serviceRef) );
+
+ m_Image = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd"));
+ m_Image2D = mitk::IOUtil::LoadImage(GetTestDataFilePath("Png2D-bw.png"));
+ m_Surface = mitk::IOUtil::LoadSurface(GetTestDataFilePath("binary.stl"));
+
+ QmitkPythonSnippets::LoadStringMap(QmitkPythonSnippets::DEFAULT_SNIPPET_FILE,m_Snippets);
+ }
+
+ void tearDown()
+ {
+ m_Image = NULL;
+ m_Image2D = NULL;
+ m_Surface = NULL;
+ }
+};
+
+}
diff --git a/Modules/Python/Testing/mitkCopyToPythonAsItkImageTest.cpp b/Modules/Python/Testing/mitkCopyToPythonAsItkImageTest.cpp
deleted file mode 100644
index c9d0e5cd32..0000000000
--- a/Modules/Python/Testing/mitkCopyToPythonAsItkImageTest.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include <mitkCommon.h>
-#include <usModuleContext.h>
-#include <usGetModuleContext.h>
-#include <usServiceReference.h>
-#include <mitkTestingMacros.h>
-#include <mitkPythonService.h>
-#include <mitkIPythonService.h>
-#include <mitkIOUtil.h>
-
-#include <usModuleRegistry.h>
-#include <usModule.h>
-#include <usServiceReference.h>
-#include <mitkImagePixelReadAccessor.h>
-
-int mitkCopyToPythonAsItkImageTest(int /*argc*/, char* argv[])
-{
- MITK_TEST_BEGIN("mitkCopyToPythonAsItkImageTest")
-
- //get the context of the python module
- us::Module* module = us::ModuleRegistry::GetModule("MitkPython");
- us::ModuleContext* context = module->GetModuleContext();
- //get the service which is generated in the PythonModuleActivator
- us::ServiceReference<mitk::IPythonService> serviceRef = context->GetServiceReference<mitk::IPythonService>();
- mitk::PythonService* pythonService = dynamic_cast<mitk::PythonService*>( context->GetService(serviceRef) );
- MITK_TEST_CONDITION(pythonService->IsItkPythonWrappingAvailable() == true, "Is Python available?");
-
- mitk::Image::Pointer testImage = mitk::IOUtil::LoadImage(std::string(argv[1]));
-
- //give it a name in python
- std::string nameOfImageInPython("mitkImage");
-
- MITK_TEST_CONDITION( pythonService->CopyToPythonAsItkImage( testImage, nameOfImageInPython) == true, "Valid image copied to python import should return true.");
- mitk::Image::Pointer pythonImage = pythonService->CopyItkImageFromPython(nameOfImageInPython);
-
-
- itk::Index<3> index;
- index[0] = 128;
- index[1] = 128;
- index[2] = 24;
-
- try{
- // pic3D of type char
- mitk::ImagePixelReadAccessor<char,3> pythonImageAccesor(pythonImage);
-
- //TODO Use the assert comparison methods once we have them implemented and remove GetPixelValueByIndex
- MITK_TEST_CONDITION( pythonImageAccesor.GetDimension(0) == 256, "Is the 1st dimension of Pic3D still 256?");
- MITK_TEST_CONDITION( pythonImageAccesor.GetDimension(1) == 256, "Is the 2nd dimension of Pic3D still 256?");
- MITK_TEST_CONDITION( pythonImageAccesor.GetDimension(2) == 49, "Is the 3rd dimension of Pic3D still 49?");
-
- MITK_TEST_CONDITION( pythonImageAccesor.GetPixelByIndex(index) == 96, "Is the value of Pic3D at (128,128,24) still 96?");
- }catch(...)
- {
- MITK_TEST_CONDITION( false, "Image is not readable! ");
- }
-
- MITK_TEST_END()
-}
diff --git a/Modules/Python/Testing/mitkCvPythonTest.cpp b/Modules/Python/Testing/mitkCvPythonTest.cpp
new file mode 100644
index 0000000000..6f41448807
--- /dev/null
+++ b/Modules/Python/Testing/mitkCvPythonTest.cpp
@@ -0,0 +1,58 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkCommonPythonTest.h>
+
+class mitkCvPythonTestSuite : public mitk::CommonPythonTestSuite
+{
+ CPPUNIT_TEST_SUITE(mitkCvPythonTestSuite);
+ MITK_TEST(testCVImageTransfer);
+ MITK_TEST(testOpenCVMedianFilter);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void testCVImageTransfer()
+ {
+ std::string varName("mitkImage");
+ CPPUNIT_ASSERT_MESSAGE ( "Is OpenCV Python Wrapping available?",
+ m_PythonService->IsOpenCvPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.",
+ m_PythonService->CopyToPythonAsCvImage( m_Image2D, varName) == true );
+
+ mitk::Image::Pointer pythonImage = m_PythonService->CopyCvImageFromPython(varName);
+
+ // todo pixeltypes do not match, cv is changing it
+ //CPPUNIT_ASSERT_MESSAGE( "Compare if images are equal after transfer.",
+ // mitk::Equal(pythonImage,m_Image2D) );
+ }
+
+ //TODO opencv median filter, add cpp test code
+ void testOpenCVMedianFilter()
+ {
+ // simple itk median filter in python
+ CPPUNIT_ASSERT_MESSAGE ( "Is OpenCV Python Wrapping available?", m_PythonService->IsOpenCvPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.", m_PythonService->CopyToPythonAsCvImage(m_Image2D, "mitkImage") == true );
+
+ m_PythonService->Execute( m_Snippets["opencv median filter"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkCvPython)
diff --git a/Modules/Python/Testing/mitkSimpleItkPythonTest.cpp b/Modules/Python/Testing/mitkSimpleItkPythonTest.cpp
new file mode 100644
index 0000000000..e2d6cce2cb
--- /dev/null
+++ b/Modules/Python/Testing/mitkSimpleItkPythonTest.cpp
@@ -0,0 +1,201 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+#include <mitkImageReadAccessor.h>
+#include <mitkImageWriteAccessor.h>
+#include <mitkCommonPythonTest.h>
+
+#include "SimpleITK.h"
+
+namespace sitk = itk::simple;
+
+namespace mitk {
+ static mitk::Image::Pointer SimpleItkToMitkImage( sitk::Image& sitkImage );
+ static sitk::Image MitkToSimpleItkImage( mitk::Image* image );
+}
+
+sitk::Image mitk::MitkToSimpleItkImage( mitk::Image* image )
+{
+ const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
+ mitk::Point3D origin = image->GetGeometry()->GetOrigin();
+ mitk::PixelType pixelType = image->GetPixelType();
+ mitk::ImageReadAccessor ra(image);
+ void* buffer = (void*) ra.GetData();
+ sitk::ImportImageFilter importer;
+
+ std::vector<double> sitkSpacing;
+ sitkSpacing.push_back(spacing[0]);
+ sitkSpacing.push_back(spacing[1]);
+ sitkSpacing.push_back(spacing[2]);
+ std::vector<double> sitkOrigin;
+ sitkOrigin.push_back(origin[0]);
+ sitkOrigin.push_back(origin[1]);
+ sitkOrigin.push_back(origin[2]);
+ std::vector<unsigned int> sitkSize;
+
+ for ( unsigned int i = 0; i < image->GetDimension(); ++i )
+ sitkSize.push_back(image->GetDimensions()[i]);
+
+ importer.SetSpacing(sitkSpacing);
+ importer.SetSize(sitkSize);
+ importer.SetOrigin(sitkOrigin);
+
+ if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
+ importer.SetBufferAsDouble((double*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
+ importer.SetBufferAsFloat((float*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
+ importer.SetBufferAsInt16((int16_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
+ importer.SetBufferAsInt8((int8_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
+ importer.SetBufferAsInt32((int32_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
+ importer.SetBufferAsInt64((int64_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
+ importer.SetBufferAsUInt8((uint8_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
+ importer.SetBufferAsUInt32((uint32_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
+ importer.SetBufferAsUInt64((uint64_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
+ importer.SetBufferAsUInt16((uint16_t*) buffer);
+ }
+
+ return importer.Execute();
+}
+
+mitk::Image::Pointer mitk::SimpleItkToMitkImage( sitk::Image& sitkImage )
+{
+ mitk::Image::Pointer image = mitk::Image::New();
+ void* buffer = NULL;
+ mitk::PixelType pixelType = MakeScalarPixelType<short>();
+ std::vector<double> sitkSpacing = sitkImage.GetSpacing();
+ double spacing[3] = { sitkSpacing[0], sitkSpacing[1], sitkSpacing[2] };
+ std::vector<double> sitkOrigin = sitkImage.GetOrigin();
+ double origin[3] = { sitkOrigin[0], sitkOrigin[1], sitkOrigin[2] };
+ std::vector<unsigned int> sitkSize = sitkImage.GetSize();
+ unsigned int dimensions[4] = { 1,1,1,1};
+
+ for ( size_t i = 0; i < sitkSize.size(); ++i )
+ dimensions[i] = sitkSize[i];
+
+ size_t size = 0;
+ if ( sitkImage.GetPixelIDValue() == sitk::sitkInt8 ) {
+ pixelType = MakeScalarPixelType<char>();
+ buffer = (void*) sitkImage.GetBufferAsInt8();
+ size = sizeof(char);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkInt16 ) {
+ pixelType = MakeScalarPixelType<short>();
+ buffer = (void*) sitkImage.GetBufferAsInt16();
+ size = sizeof(short);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkInt32 ) {
+ pixelType = MakeScalarPixelType<int>();
+ buffer = (void*) sitkImage.GetBufferAsInt32();
+ size = sizeof(int);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkInt64 ) {
+ pixelType = MakeScalarPixelType<long>();
+ buffer = (void*) sitkImage.GetBufferAsInt64();
+ size = sizeof(long);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt8 ) {
+ pixelType = MakeScalarPixelType<unsigned char>();
+ buffer = (void*) sitkImage.GetBufferAsUInt8();
+ size = sizeof(unsigned char);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt16 ) {
+ pixelType = MakeScalarPixelType<unsigned short>();
+ buffer = (void*) sitkImage.GetBufferAsUInt16();
+ size = sizeof(unsigned short);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt32 ) {
+ pixelType = MakeScalarPixelType<unsigned int>();
+ buffer = (void*) sitkImage.GetBufferAsUInt32();
+ size = sizeof(unsigned int);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt64 ) {
+ pixelType = MakeScalarPixelType<unsigned long>();
+ buffer = (void*) sitkImage.GetBufferAsUInt64();
+ size = sizeof(unsigned long);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkFloat32 ) {
+ pixelType = MakeScalarPixelType<float>();
+ buffer = (void*) sitkImage.GetBufferAsFloat();
+ size = sizeof(float);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkFloat64 ) {
+ pixelType = MakeScalarPixelType<float>();
+ buffer = (void*) sitkImage.GetBufferAsDouble();
+ size = sizeof(double);
+ }
+
+ image->Initialize(pixelType,sitkImage.GetDimension(),dimensions);
+ image->SetSpacing(spacing);
+ image->SetOrigin(origin);
+
+ for(size_t i = 0; i < sitkSize.size(); ++i )
+ size *= sitkSize[i];
+
+ mitk::ImageWriteAccessor wa(image);
+
+ memcpy(wa.GetData(),buffer, size);
+
+ return image;
+}
+
+
+class mitkSimpleItkPythonTestSuite : public mitk::CommonPythonTestSuite
+{
+ CPPUNIT_TEST_SUITE(mitkSimpleItkPythonTestSuite);
+ MITK_TEST(testSimpleItkImageTransfer);
+ MITK_TEST(testSimpleITKMedianFilterSnippet);
+ CPPUNIT_TEST_SUITE_END();
+
+
+public:
+
+ void testSimpleItkImageTransfer()
+ {
+ std::string varName("mitkImage");
+ CPPUNIT_ASSERT_MESSAGE ( "Is SimpleITK Python Wrapping available?",
+ m_PythonService->IsSimpleItkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.",
+ m_PythonService->CopyToPythonAsSimpleItkImage( m_Image, varName) == true );
+
+ mitk::Image::Pointer pythonImage = m_PythonService->CopySimpleItkImageFromPython(varName);
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if images are equal after transfer.",
+ mitk::Equal(*pythonImage.GetPointer(),*m_Image.GetPointer(), mitk::eps,true) );
+ }
+
+
+ void testSimpleITKMedianFilterSnippet()
+ {
+ // simple itk median filter in cpp
+ sitk::MedianImageFilter medianFilter;
+ medianFilter.SetRadius(1);
+ sitk::Image sitkImage = medianFilter.Execute(mitk::MitkToSimpleItkImage(m_Image));
+ mitk::Image::Pointer mitkImage = mitk::SimpleItkToMitkImage(sitkImage);
+
+ // simple itk median filter in python
+ CPPUNIT_ASSERT_MESSAGE ( "Is SimpleItk Python Wrapping available?", m_PythonService->IsSimpleItkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.", m_PythonService->CopyToPythonAsSimpleItkImage(m_Image, "mitkImage") == true );
+
+ m_PythonService->Execute( m_Snippets["medianfilter"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+
+ mitk::Image::Pointer pythonImage = m_PythonService->CopySimpleItkImageFromPython("mitkImage_new");
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if images are equal.", mitk::Equal(*pythonImage.GetPointer(), *mitkImage.GetPointer(),mitk::eps,true) );
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkSimpleItkPython)
diff --git a/Modules/Python/Testing/mitkVtkPythonTest.cpp b/Modules/Python/Testing/mitkVtkPythonTest.cpp
new file mode 100644
index 0000000000..3fb2662006
--- /dev/null
+++ b/Modules/Python/Testing/mitkVtkPythonTest.cpp
@@ -0,0 +1,95 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+// vtk cone sample snippet
+#include <vtkConeSource.h>
+// vtk decimate pro snippet
+#include <vtkDecimatePro.h>
+
+#include <mitkCommonPythonTest.h>
+
+class mitkVtkPythonTestSuite : public mitk::CommonPythonTestSuite
+{
+ CPPUNIT_TEST_SUITE(mitkVtkPythonTestSuite);
+ MITK_TEST(testSurfaceTransfer);
+ MITK_TEST(testVtkCreateConePythonSnippet);
+ MITK_TEST(testVtkDecimateProPythonSnippet);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void testSurfaceTransfer()
+ {
+ std::string varName("mitkSurface");
+ CPPUNIT_ASSERT_MESSAGE ( "Is VTK Python Wrapping available?", m_PythonService->IsVtkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid surface copied to python import should return true.",
+ m_PythonService->CopyToPythonAsVtkPolyData( m_Surface, varName) == true );
+
+ mitk::Surface::Pointer pythonSurface = m_PythonService->CopyVtkPolyDataFromPython(varName);
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if surfaces are equal after transfer.", mitk::Equal(*pythonSurface.GetPointer(),*m_Surface.GetPointer(),mitk::eps,true) );
+ }
+
+ void testVtkCreateConePythonSnippet()
+ {
+ // cone in cpp
+ mitk::Surface::Pointer mitkSurface = mitk::Surface::New();
+ vtkSmartPointer<vtkConeSource> coneSrc = vtkSmartPointer<vtkConeSource>::New();
+ coneSrc->SetResolution(60);
+ coneSrc->SetCenter(-2,0,0);
+ coneSrc->Update();
+ mitkSurface->SetVtkPolyData(coneSrc->GetOutput());
+
+ // run python code
+ CPPUNIT_ASSERT_MESSAGE ( "Is VTK Python Wrapping available?", m_PythonService->IsVtkPythonWrappingAvailable() == true );
+
+ m_PythonService->Execute( m_Snippets["vtk: create cone"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+
+ mitk::Surface::Pointer pythonSurface = m_PythonService->CopyVtkPolyDataFromPython("cone");
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if cones are equal.", mitk::Equal(*pythonSurface.GetPointer(), *mitkSurface.GetPointer(), mitk::eps,true) );
+ }
+
+ void testVtkDecimateProPythonSnippet()
+ {
+ // decimate pro in cpp
+ mitk::Surface::Pointer mitkSurface = mitk::Surface::New();
+ vtkSmartPointer<vtkDecimatePro> deci = vtkSmartPointer<vtkDecimatePro>::New();
+ deci->SetInputData(m_Surface->GetVtkPolyData());
+ deci->SetTargetReduction(0.9);
+ deci->PreserveTopologyOn();
+ deci->Update();
+ mitkSurface->SetVtkPolyData(deci->GetOutput());
+
+ // decimate pro in python
+ CPPUNIT_ASSERT_MESSAGE ( "Is VTK Python Wrapping available?", m_PythonService->IsVtkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid surface copied to python import should return true.", m_PythonService->CopyToPythonAsVtkPolyData( m_Surface, "mitkSurface") == true );
+
+ m_PythonService->Execute( m_Snippets["vtk.vtkDecimatePro"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+
+ mitk::Surface::Pointer pythonSurface = m_PythonService->CopyVtkPolyDataFromPython("mitkSurface_new");
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if surfaces are equal.", mitk::Equal(*pythonSurface.GetPointer(), *mitkSurface.GetPointer(), mitk::eps,true) );
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkVtkPython)
diff --git a/Modules/Python/documentation/mitkPython.dox b/Modules/Python/documentation/mitkPython.dox
index dbfb3994e9..52f27b2c52 100644
--- a/Modules/Python/documentation/mitkPython.dox
+++ b/Modules/Python/documentation/mitkPython.dox
@@ -1,43 +1,49 @@
/**
\page mitkPython_Overview The MITK Python Module
-<h1>Brief description</h1>
-The MITK Python Module provides a service class for interactively run python code (passed as C++ strings) and evaluate the results. Furthermore the service class offers means to convert an MITK Image to an ITK/OpenCV image in their wrapped python environment. <strong>Thus, one can process MITK images with Python Code from the OpenCV and ITK wrapping system</strong>. Furthermore one can convert an mitk::Surface to a vtkPolyData in its Python environment.<br />
-Under the hood, the MITK build system takes care that the wrapping build process for ITK/VTK/OpenCV is correctly initiated and all paths are correctly set within MITK code.
-
-<h1>Build Instructions</h1>
-- Install Python <b>2.x</b>
-- Activate MITK_USE_Python in the superbuild process of MITK
-- Provide CMake with the correct Python paths (if not found automatically)
-- Build MITK: All wrapping will be setup by the MITK superbuild routine
-
-<h1>Known problems and workarounds</h1>
-
-<p>System: Linux/OSX/gcc<br />
-Problem: An error during the build process occurs:
-<pre>
-Linking CXX shared library libPythonQt.so
-/usr/bin/ld: error: /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/libpython2.7.a(abstract.o): requires dynamic R_X86_64_PC32 reloc against 'PyErr_Occurred' which may overflow at runtime; recompile with -fPIC
-</pre>
-<strong>Workaround</strong>: Try setting the CMake var PYTHON_LIBRARY to the shared object, e.g. /usr/lib/libpython2.7.so
-</p>
-<p>System: Linux/gcc (maybe Mac OS)<br />
-Problem: An error during the build process occurs:
-<pre>
-Scanning dependencies of target install_wrapitk_compatibility
-[ 40%] Built target install_wrapitk_compatibility
-[ 40%] Generating swigrun.xml
-gccxml_cc1plus: error: gccxml_builtins.h: No such file or directory
-make[5]: *** [Wrapping/WrapITK/SwigRuntime/swigrun.xml] Error 1
-make[4]: *** [Wrapping/WrapITK/SwigRuntime/CMakeFiles/SwigRuntimePython.dir/all] Error 2
-make[3]: *** [all] Error 2
-make[2]: *** [ITK-cmake/src/ITK-stamp/ITK-build] Error 2
-make[1]: *** [CMakeFiles/ITK.dir/all] Error 2
-make: *** [all] Error 2
-</pre>
-<strong>Workaround</strong>: Install CableSwig from the software repo and set the CMake var EXTERNAL_CableSwig_DIR to the directory containing CableSwigConfig.cmake, on linux usually /usr/lib/CableSwig
-</p>
+\section sec1 Brief description
+The MITK Python Module provides a service class for interactively run python code (passed as C++ strings) and
+evaluate the results. Furthermore the service class offers means to convert an MITK Image to an ITK/OpenCV image in their wrapped python environment.
+<strong>Thus, one can process MITK images with Python Code from the OpenCV and ITK wrapping system</strong>.
+Furthermore one can convert an mitk::Surface to a vtkPolyData in its Python environment.<br />
+Under the hood, the MITK build system takes care that the wrapping build process for SimpleITK/VTK/OpenCV is correctly initiated and all paths are correctly set within MITK code.
+To use the features of the different toolkits make sure they are enabled during the superbuild process.
+\section sec2 Build Instructions
+
+The following build options are available:
+<ul>
+ <li> MITK_USE_Python
+ <li> MITK_USE_SYSTEM_PYTHON
+</ul>
+
+\subsection ssec1 MITK_USE_Python
+MITK_USE_Python enables the python wrapping in MITK. When the option is activated
+the build of the additional dependency SimpleITK is also enabled. The default behaviour is to download and build
+Python 2.7.3 with numpy and embed it into MITK.To use an own custom runtime see MITK_USE_SYSTEM_PYTHON.
+
+\subsection ssec2 MITK_USE_SYSTEM_PYTHON
+This option is deactivated by default. If MITK_USE_SYSTEM_PYTHON is activated the python runtime from the system is used.
+The user can also specify it's own runtime by modifing the variables added by the
+FindPythonLib.cmake script. <strong>Note:</strong> A Python runtime with numpy is needed to use the MITK Python wrapping.
+
+\section sec3 Suported Data Types
+The following data types in MITK are supported in the MITK Python Wrapping:
+<ul>
+ <li> Image
+ <li> Surface
+</ul>
+
+\subsection ssec4 Image
+Mitk Images can be transferred to python. The images are copied in-memory and
+transferred as a numpy array to Python and vice versa. The MITK python wrapping creates a SimpleITK image
+using the numpy array with the properties of the MITK Image. Two dimensional images
+can also be transferred as an OpenCV image to python.
+
+\subsection ssec5 Surface
+Surfaces within mitk can be transferred as a vtkPolyData Object to Python.
+The surfaces are fully memory mapped. When changing a python wrapped surface
+the original object is also modified on the C++ side of MITK.
*/
diff --git a/Modules/Python/files.cmake b/Modules/Python/files.cmake
index 66fb3a3ce7..c4fe74b329 100644
--- a/Modules/Python/files.cmake
+++ b/Modules/Python/files.cmake
@@ -1,28 +1,34 @@
SET(CPP_FILES
mitkIPythonService.cpp
mitkPythonActivator.cpp
mitkPythonService.cpp
QmitkCtkPythonShell.cpp
QmitkPythonVariableStackTableModel.cpp
QmitkPythonVariableStackTableView.cpp
QmitkPythonScriptEditorHighlighter.cpp
QmitkPythonTextEditor.cpp
QmitkPythonSnippets.cpp
)
+if(BUILD_TESTING)
+ SET(H_FILES
+ Testing/mitkCommonPythonTest.h
+ )
+endif()
+
#SET(UI_FILES
# QmitkPythonSnippets.ui
#)
SET(MOC_H_FILES
QmitkCtkPythonShell.h
QmitkPythonVariableStackTableModel.h
QmitkPythonVariableStackTableView.h
QmitkPythonScriptEditorHighlighter.h
QmitkPythonTextEditor.h
QmitkPythonSnippets.h
)
set(QRC_FILES
resources/mitkPython.qrc
)
diff --git a/Modules/Python/mitkIPythonService.h b/Modules/Python/mitkIPythonService.h
index ddde271380..d9af572e60 100644
--- a/Modules/Python/mitkIPythonService.h
+++ b/Modules/Python/mitkIPythonService.h
@@ -1,141 +1,141 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkIPythonService_h
#define mitkIPythonService_h
// mitk
#include <MitkPythonExports.h>
#include "mitkImage.h"
//for microservices
#include <usServiceInterface.h>
#include "mitkSurface.h"
#include <vector>
namespace mitk
{
///
/// describes a python variable (data container)
/// \see IPythonService::GetVariableStack()
///
struct PythonVariable
{
std::string m_Name;
std::string m_Type;
std::string m_Value;
};
///
/// a PythonCommandObserver gets informed as soon as a python command was issued
/// \see IPythonService::AddPythonCommandObserver()
///
class PythonCommandObserver
{
public:
virtual void CommandExecuted(const std::string& pythonCommand) = 0;
};
///
/// The central service for issuing Python Code
/// The class also enables to transfer mitk images to python as itk::Image and vice versa
/// \see IPythonService::GetVariableStack()
///
class MITK_PYTHON_EXPORT IPythonService
{
public:
///
/// Constant representing a single line command
/// \see IPythonService::Execute()
static const int SINGLE_LINE_COMMAND = 0;
///
/// Constant representing a command in which the commands are seperated by new lines, i.e. "\\n"
/// \see IPythonService::Execute()
static const int MULTI_LINE_COMMAND = 1;
///
/// Constant representing a single line command x which is run as "eval(x)"
/// \see IPythonService::Execute()
static const int EVAL_COMMAND = 2;
///
/// Executes a python command.
/// \return A variant containing the return value as string of the python code (if any)
virtual std::string Execute( const std::string& pythonCommand, int commandType = SINGLE_LINE_COMMAND ) = 0;
///
/// Executes a python script.
virtual void ExecuteScript( const std::string& pathToPythonScript ) = 0;
///
/// \return true if the last call to Execute...() resulted in an error, false otherwise
virtual bool PythonErrorOccured() const = 0;
///
/// \return The list of variables in the __main__ namespace
virtual std::vector<PythonVariable> GetVariableStack() const = 0;
///
/// \return true if a variable with this name is defined in the __main__ namespace, false otherwise
virtual bool DoesVariableExist(const std::string& name) const = 0;
///
/// adds a command observer which is informed after a command was issued with "Execute"
virtual void AddPythonCommandObserver( PythonCommandObserver* observer ) = 0;
///
/// removes a specific command observer
virtual void RemovePythonCommandObserver( PythonCommandObserver* observer ) = 0;
///
/// notify all observer. this should only be used if it can be garantueed that the
/// current python interpreter instance got another command from anywhere else
/// the the Execute() method of this service, e.g. the shell widget uses this function
/// since it does not use Execute()
virtual void NotifyObserver( const std::string& command ) = 0;
///
/// \return true, if itk wrapping is available, false otherwise
- virtual bool IsItkPythonWrappingAvailable() = 0;
+ virtual bool IsSimpleItkPythonWrappingAvailable() = 0;
///
/// copies an mitk image as itk image into the python interpreter process
/// the image will be available as "varName" in python if everythin worked
/// \return true if image was copied, else false
- virtual bool CopyToPythonAsItkImage( mitk::Image* image, const std::string& varName ) = 0;
+ virtual bool CopyToPythonAsSimpleItkImage( mitk::Image* image, const std::string& varName ) = 0;
///
/// copies an itk image from the python process that is named "varName"
/// \return the image or 0 if copying was not possible
- virtual mitk::Image::Pointer CopyItkImageFromPython( const std::string& varName ) = 0;
+ virtual mitk::Image::Pointer CopySimpleItkImageFromPython( const std::string& varName ) = 0;
///
/// \return true, if OpenCv wrapping is available, false otherwise
virtual bool IsOpenCvPythonWrappingAvailable() = 0;
///
/// \see CopyToPythonAsItkImage()
virtual bool CopyToPythonAsCvImage( mitk::Image* image, const std::string& varName ) = 0;
///
/// \see CopyCvImageFromPython()
virtual mitk::Image::Pointer CopyCvImageFromPython( const std::string& varName ) = 0;
///
/// \return true, if vtk wrapping is available, false otherwise
virtual bool IsVtkPythonWrappingAvailable() = 0;
///
/// \see CopyToPythonAsItkImage()
virtual bool CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& varName ) = 0;
///
/// \see CopyCvImageFromPython()
virtual mitk::Surface::Pointer CopyVtkPolyDataFromPython( const std::string& varName ) = 0;
///
/// nothing to do here
virtual ~IPythonService(); // leer in mitkIPythonService.cpp implementieren
};
}
US_DECLARE_SERVICE_INTERFACE(mitk::IPythonService, "org.mitk.services.IPythonService")
#endif
diff --git a/Modules/Python/mitkPythonService.cpp b/Modules/Python/mitkPythonService.cpp
index df84c3fef3..da852eab10 100644
--- a/Modules/Python/mitkPythonService.cpp
+++ b/Modules/Python/mitkPythonService.cpp
@@ -1,529 +1,646 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPythonService.h"
#include <Python.h>
#include <mitkIOUtil.h>
#include <QFile>
#include <QDir>
#include <PythonQt.h>
#include "PythonPath.h"
+#include <vtkPolyData.h>
+#include <mitkRenderingManager.h>
+#include <mitkImageReadAccessor.h>
+#include <mitkImageWriteAccessor.h>
+#include <numpy/arrayobject.h>
+
+#ifndef WIN32
+ #include <dlfcn.h>
+#endif
const QString mitk::PythonService::m_TmpDataFileName("temp_mitk_data_file");
+#ifdef USE_MITK_BUILTIN_PYTHON
+ static char* pHome = NULL;
+#endif
mitk::PythonService::PythonService()
: m_ItkWrappingAvailable( true ), m_OpenCVWrappingAvailable( true ), m_VtkWrappingAvailable( true ), m_ErrorOccured( false )
{
{
MITK_DEBUG << "will init python if necessary";
}
bool pythonInitialized = static_cast<bool>( Py_IsInitialized() ); //m_PythonManager.isPythonInitialized() );
{
MITK_DEBUG << "pythonInitialized " << pythonInitialized;
MITK_DEBUG << "m_PythonManager.isPythonInitialized() " << m_PythonManager.isPythonInitialized();
}
// due to strange static var behaviour on windows Py_IsInitialized() returns correct value while
// m_PythonManager.isPythonInitialized() does not because it has been constructed and destructed again
if( !m_PythonManager.isPythonInitialized() )
{
try
{
+//TODO a better way to do this
+#ifndef WIN32
+#if defined (__APPLE__) || defined(MACOSX)
+ const char* library = "libpython2.7.dylib";
+#else
+ const char* library = "libpython2.7.so";
+#endif
+ dlerror();
+ if(dlopen(library, RTLD_NOW | RTLD_GLOBAL) == 0 )
+ {
+ mitkThrow() << "Python runtime could not be loaded: " << dlerror();
+ }
+#endif
+
+ std::string programPath = mitk::IOUtil::GetProgramPath();
+ QDir programmDir( QString( programPath.c_str() ).append("/Python") );
+ QString pythonCommand;
+ // Set the pythonpath variable depending if
+ // we have an installer or development environment
+ if ( programmDir.exists() ) {
+ // runtime directory used in installers
+ pythonCommand.append( QString("import site, sys\n") );
+ pythonCommand.append( QString("sys.path.append('')\n") );
+ pythonCommand.append( QString("sys.path.append('%1')\n").arg(programPath.c_str()) );
+ pythonCommand.append( QString("sys.path.append('%1/Python')").arg(programPath.c_str()) );
+#ifndef USE_MITK_BUILTIN_PYTHON
+ pythonCommand.append( QString("\nsite.addsitedir('%1/Python/SimpleITK')").arg(programPath.c_str()) );
+#endif
+ } else {
+ pythonCommand.append(PYTHONPATH_COMMAND);
+ }
+
if( pythonInitialized )
m_PythonManager.setInitializationFlags(PythonQt::RedirectStdOut|PythonQt::PythonAlreadyInitialized);
else
m_PythonManager.setInitializationFlags(PythonQt::RedirectStdOut);
- MITK_DEBUG("PythonService") << "initalizing python";
- m_PythonManager.initialize();
-
- MITK_DEBUG("PythonService") << "python initalized";
+// set python home if own runtime is used
+#ifdef USE_MITK_BUILTIN_PYTHON
+ QString pythonHome;
+ if ( programmDir.exists() )
+ pythonHome.append(QString("%1/Python").arg(programPath.c_str()));
+ else
+ pythonHome.append(PYTHONHOME);
- QString pythonCommand(PYTHONPATH_COMMAND);
- MITK_DEBUG("PythonService") << "registering python paths" << PYTHONPATH_COMMAND;
- m_PythonManager.executeString( pythonCommand, ctkAbstractPythonManager::FileInput );
+ if(pHome) delete[] pHome;
+ pHome = new char[pythonHome.toStdString().length() + 1];
- /*
- //system("export LD_LIBRARY_PATH=/local/muellerm/mitk/bugsquashing/bin-debug/VTK-build/bin:$LD_LIBRARY_PATH");
- //m_PythonManager.executeString( "print sys.path", ctkAbstractPythonManager::SingleInput );
- //MITK_DEBUG("mitk::PythonService") << "result of 'sys.path': " << result.toString().toStdString();
+ strcpy(pHome,pythonHome.toStdString().c_str());
+ Py_SetPythonHome(pHome);
+ MITK_DEBUG("PythonService") << "PythonHome: " << pHome;
+#endif
- //m_PythonManager.executeString( "sys.path.append('/usr/share/pyshared/numpy')", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeString( "import numpy", ctkAbstractPythonManager::SingleInput );
+ MITK_DEBUG("PythonService") << "initalizing python";
+ m_PythonManager.initialize();
- MITK_DEBUG("mitk::PythonService") << "Trying to import ITK";
- m_PythonManager.executeString( "import itk", ctkAbstractPythonManager::SingleInput );
- m_ItkWrappingAvailable = !m_PythonManager.pythonErrorOccured();
- MITK_DEBUG("mitk::PythonService") << "m_ItkWrappingAvailable: " << (m_ItkWrappingAvailable? "yes": "no");
- if( !m_ItkWrappingAvailable )
+#ifdef USE_MITK_BUILTIN_PYTHON
+ PyObject* dict = PyDict_New();
+ // Import builtin modules
+ if (PyDict_GetItemString(dict, "__builtins__") == NULL)
{
- MITK_WARN << "ITK Python wrapping not available. Please check build settings or PYTHONPATH settings.";
+ PyObject* builtinMod = PyImport_ImportModule("__builtin__");
+ if (builtinMod == NULL ||
+ PyDict_SetItemString(dict, "__builtins__", builtinMod) != 0)
+ {
+ Py_DECREF(dict);
+ Py_XDECREF(dict);
+ return;
+ }
+ Py_DECREF(builtinMod);
}
+#endif
- {
- MITK_DEBUG("mitk::PythonService") << "Trying to import OpenCv";
- PyRun_SimpleString("import cv2\n");
- if (PyErr_Occurred())
- {
- PyErr_Print();
- }
- else
- m_OpenCVWrappingAvailable = true;
-
- //m_PythonManager.executeString( "import cv2", ctkAbstractPythonManager::SingleInput );
- MITK_DEBUG("mitk::PythonService") << "Investigate if an error occured while importing cv2";
- //m_OpenCVWrappingAvailable = !m_PythonManager.pythonErrorOccured();
- MITK_DEBUG("mitk::PythonService") << "m_OpenCVWrappingAvailable: " << (m_OpenCVWrappingAvailable? "yes": "no");
- if( !m_OpenCVWrappingAvailable )
- {
- MITK_WARN << "OpenCV Python wrapping not available. Please check build settings or PYTHONPATH settings.";
- }
- }
+ MITK_DEBUG("PythonService")<< "Python Search paths: " << Py_GetPath();
+ MITK_DEBUG("PythonService") << "python initalized";
- MITK_DEBUG("mitk::PythonService") << "Trying to import VTK";
- m_PythonManager.executeString( "import vtk", ctkAbstractPythonManager::SingleInput );
- m_VtkWrappingAvailable = !m_PythonManager.pythonErrorOccured();
- MITK_DEBUG("mitk::PythonService") << "m_VtkWrappingAvailable: " << (m_VtkWrappingAvailable? "yes": "no");
- if( !m_VtkWrappingAvailable )
- {
- MITK_WARN << "VTK Python wrapping not available. Please check build settings or PYTHONPATH settings.";
- }
- */
+ MITK_DEBUG("PythonService") << "registering python paths" << PYTHONPATH_COMMAND;
+ m_PythonManager.executeString( pythonCommand, ctkAbstractPythonManager::FileInput );
}
catch (...)
{
MITK_DEBUG("PythonService") << "exception initalizing python";
}
-
}
-
- //m_PythonManager.executeString( "for path in sys.path:\n print path\n", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeString( "for k, v in os.environ.items():\n print \"%s=%s\" % (k, v)", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeFile("/local/muellerm/Dropbox/13-02-11-python-wrapping/interpreterInfo.py");
- //std::string result = m_PythonManager.executeString( "5+5", ctkAbstractPythonManager::EvalInput );
- //MITK_DEBUG("mitk::PythonService") << "result of '5+5': " << result.toString().toStdString();
}
mitk::PythonService::~PythonService()
{
- //QVariant result = m_PythonManager.executeString( "sys.getrefcount(cv2)", ctkAbstractPythonManager::EvalInput );
- //MITK_DEBUG("mitk::PythonService") << "sys.getrefcount(cv2): " << result.toString().toStdString();
-
- //m_PythonManager.executeString( "del sys.modules[\"cv2\"]", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeString( "del cv2", ctkAbstractPythonManager::SingleInput );
MITK_DEBUG("mitk::PythonService") << "destructing PythonService";
+
+#ifdef USE_MITK_BUILTIN_PYTHON
+ if(pHome)
+ delete[] pHome;
+#endif
}
std::string mitk::PythonService::Execute(const std::string &stdpythonCommand, int commandType)
{
QString pythonCommand = QString::fromStdString(stdpythonCommand);
+ {
+ MITK_DEBUG("mitk::PythonService") << "pythonCommand = " << pythonCommand.toStdString();
+ MITK_DEBUG("mitk::PythonService") << "commandType = " << commandType;
+ }
- {
- MITK_DEBUG("mitk::PythonService") << "pythonCommand = " << pythonCommand.toStdString();
- MITK_DEBUG("mitk::PythonService") << "commandType = " << commandType;
- }
-
- QVariant result;
- bool commandIssued = true;
+ QVariant result;
+ bool commandIssued = true;
- if(commandType == IPythonService::SINGLE_LINE_COMMAND )
- result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::SingleInput );
- else if(commandType == IPythonService::MULTI_LINE_COMMAND )
- result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::FileInput );
- else if(commandType == IPythonService::EVAL_COMMAND )
- result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::EvalInput );
- else
- commandIssued = false;
+ if(commandType == IPythonService::SINGLE_LINE_COMMAND )
+ result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::SingleInput );
+ else if(commandType == IPythonService::MULTI_LINE_COMMAND )
+ result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::FileInput );
+ else if(commandType == IPythonService::EVAL_COMMAND )
+ result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::EvalInput );
+ else
+ commandIssued = false;
- if(commandIssued)
- {
- this->NotifyObserver(pythonCommand.toStdString());
- m_ErrorOccured = PythonQt::self()->hadError();
- }
+ if(commandIssued)
+ {
+ this->NotifyObserver(pythonCommand.toStdString());
+ m_ErrorOccured = PythonQt::self()->hadError();
+ }
- return result.toString().toStdString();
+ return result.toString().toStdString();
}
void mitk::PythonService::ExecuteScript( const std::string& pythonScript )
{
m_PythonManager.executeFile(QString::fromStdString(pythonScript));
}
std::vector<mitk::PythonVariable> mitk::PythonService::GetVariableStack() const
{
- std::vector<mitk::PythonVariable> list;
+ std::vector<mitk::PythonVariable> list;
+
+ PyObject* dict = PyImport_GetModuleDict();
+ PyObject* object = PyDict_GetItemString(dict, "__main__");
+ PyObject* dirMain = PyObject_Dir(object);
+ PyObject* tempObject = 0;
+ PyObject* strTempObject = 0;
- PyObject* dict = PyImport_GetModuleDict();
- PyObject* object = PyDict_GetItemString(dict, "__main__");
- PyObject* dirMain = PyObject_Dir(object);
- PyObject* tempObject = 0;
- PyObject* strTempObject = 0;
+ if(dirMain)
+ {
+ std::string name, attrValue, attrType;
- if(dirMain)
+ for(int i = 0; i<PyList_Size(dirMain); i++)
{
- std::string name, attrValue, attrType;
+ tempObject = PyList_GetItem(dirMain, i);
+ name = PyString_AsString(tempObject);
+ tempObject = PyObject_GetAttrString( object, name.c_str() );
+ attrType = tempObject->ob_type->tp_name;
+
+ strTempObject = PyObject_Repr(tempObject);
+ if(strTempObject && ( PyUnicode_Check(strTempObject) || PyString_Check(strTempObject) ) )
+ attrValue = PyString_AsString(strTempObject);
+ else
+ attrValue = "";
- for(int i = 0; i<PyList_Size(dirMain); i++)
- {
- tempObject = PyList_GetItem(dirMain, i);
- name = PyString_AsString(tempObject);
- tempObject = PyObject_GetAttrString( object, name.c_str() );
- attrType = tempObject->ob_type->tp_name;
-
- strTempObject = PyObject_Repr(tempObject);
- if(strTempObject && ( PyUnicode_Check(strTempObject) || PyString_Check(strTempObject) ) )
- attrValue = PyString_AsString(strTempObject);
- else
- attrValue = "";
-
- mitk::PythonVariable var;
- var.m_Name = name;
- var.m_Value = attrValue;
- var.m_Type = attrType;
- list.push_back(var);
- }
+ mitk::PythonVariable var;
+ var.m_Name = name;
+ var.m_Value = attrValue;
+ var.m_Type = attrType;
+ list.push_back(var);
}
+ }
- return list;
+ return list;
}
bool mitk::PythonService::DoesVariableExist(const std::string& name) const
{
bool varExists = false;
std::vector<mitk::PythonVariable> allVars = this->GetVariableStack();
- for(int i = 0; i< allVars.size(); i++)
+ for(unsigned int i = 0; i< allVars.size(); i++)
{
if( allVars.at(i).m_Name == name )
{
varExists = true;
break;
}
}
return varExists;
}
void mitk::PythonService::AddPythonCommandObserver(mitk::PythonCommandObserver *observer)
{
if(!m_Observer.contains(observer))
m_Observer.append(observer);
}
void mitk::PythonService::RemovePythonCommandObserver(mitk::PythonCommandObserver *observer)
{
m_Observer.removeOne(observer);
}
void mitk::PythonService::NotifyObserver(const std::string &command)
{
MITK_DEBUG("mitk::PythonService") << "number of observer " << m_Observer.size();
- for( size_t i=0; i< m_Observer.size(); ++i )
+ for( int i=0; i< m_Observer.size(); ++i )
{
m_Observer.at(i)->CommandExecuted(command);
}
}
QString mitk::PythonService::GetTempDataFileName(const std::string& ext) const
{
QString tmpFolder = QDir::tempPath();
QString fileName = tmpFolder + QDir::separator() + m_TmpDataFileName + QString::fromStdString(ext);
return fileName;
}
-bool mitk::PythonService::CopyToPythonAsItkImage(mitk::Image *image, const std::string &stdvarName)
+bool mitk::PythonService::CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &stdvarName)
{
QString varName = QString::fromStdString( stdvarName );
- // save image
- QString fileName = this->GetTempDataFileName( mitk::IOUtil::DEFAULTIMAGEEXTENSION );
- fileName = QDir::fromNativeSeparators( fileName );
-
- MITK_DEBUG("PythonService") << "Saving temporary file " << fileName.toStdString();
- if( !mitk::IOUtil::SaveImage(image, fileName.toStdString()) )
- {
- MITK_ERROR << "Temporary file could not be created.";
- }
- else
+ QString command;
+ unsigned int* imgDim = image->GetDimensions();
+ int npy_nd = 1;
+ npy_intp* npy_dims = new npy_intp[1];
+ npy_dims[0] = imgDim[0] * imgDim[1] * imgDim[2];
+ // access python module
+ PyObject *pyMod = PyImport_AddModule((char*)"__main__");
+ // global dictionarry
+ PyObject *pyDict = PyModule_GetDict(pyMod);
+ const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
+ const mitk::Point3D origin = image->GetGeometry()->GetOrigin();
+ mitk::PixelType pixelType = image->GetPixelType();
+ itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
+ PyObject* npyArray = NULL;
+ mitk::ImageReadAccessor racc(image);
+ void* array = (void*) racc.GetData();
+
+ // default pixeltype: unsigned short
+ NPY_TYPES npy_type = NPY_USHORT;
+ std::string sitk_type = "sitkUInt8";
+ if( ioPixelType == itk::ImageIOBase::SCALAR )
{
- // TODO CORRECT TYPE SETUP, MAKE MITK_DEBUG("PythonService") MITK_DEBUG("PythonService")
- int dim = image->GetDimension();
- mitk::PixelType pixelType = image->GetPixelType();
- itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
-
- // default pixeltype: unsigned short
- QString type = "US";
- if( ioPixelType == itk::ImageIOBase::SCALAR )
- {
- if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE )
- type = "D";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT )
- type = "F";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT)
- type = "SS";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR )
- type = "SC";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::INT )
- type = "SI";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG )
- type = "SL";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR )
- type = "UC";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT )
- type = "UI";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG )
- type = "UL";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT )
- type = "US";
+ if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
+ npy_type = NPY_DOUBLE;
+ sitk_type = "sitkFloat64";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
+ npy_type = NPY_FLOAT;
+ sitk_type = "sitkFloat32";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
+ npy_type = NPY_SHORT;
+ sitk_type = "sitkInt16";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
+ npy_type = NPY_BYTE;
+ sitk_type = "sitkInt8";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
+ npy_type = NPY_INT;
+ sitk_type = "sitkInt32";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
+ npy_type = NPY_LONG;
+ sitk_type = "sitkInt64";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
+ npy_type = NPY_UBYTE;
+ sitk_type = "sitkUInt8";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
+ npy_type = NPY_UINT;
+ sitk_type = "sitkUInt32";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
+ npy_type = NPY_LONG;
+ sitk_type = "sitkUInt64";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
+ npy_type = NPY_USHORT;
+ sitk_type = "sitkUInt16";
}
+ } else {
+ MITK_WARN << "not a scalar pixeltype";
+ return false;
+ }
- MITK_DEBUG("PythonService") << "Got mitk image with type " << type.toStdString() << " and dim " << dim;
-
- QString command;
-
- command.append( QString("imageType = itk.Image[itk.%1, %2]\n") .arg( type ).arg( dim ) );
-
- command.append( QString("readerType = itk.ImageFileReader[imageType]\n") );
- command.append( QString("reader = readerType.New()\n") );
- command.append( QString("reader.SetFileName( \"%1\" )\n") .arg(fileName) );
- command.append( QString("reader.Update()\n") );
- command.append( QString("%1 = reader.GetOutput()\n").arg( varName ) );
+ // creating numpy array
+ import_array1 (true);
+ npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);
+
+ // add temp array it to the python dictionary to access it in python code
+ const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
+ .arg(varName).toStdString().c_str(),
+ npyArray );
+
+ // sanity check
+ if ( status != 0 )
+ return false;
+
+ command.append( QString("%1 = sitk.Image(%2,%3,%4,sitk.%5)\n").arg(varName)
+ .arg(QString::number(imgDim[0]))
+ .arg(QString::number(imgDim[1]))
+ .arg(QString::number(imgDim[2]))
+ .arg(QString(sitk_type.c_str())) );
+ command.append( QString("%1.SetSpacing([%2,%3,%4])\n").arg(varName)
+ .arg(QString::number(spacing[0]))
+ .arg(QString::number(spacing[1]))
+ .arg(QString::number(spacing[2])) );
+ command.append( QString("%1.SetOrigin([%2,%3,%4])\n").arg(varName)
+ .arg(QString::number(origin[0]))
+ .arg(QString::number(origin[1]))
+ .arg(QString::number(origin[2])) );
+ // directly access the cpp api from the lib
+ command.append( QString("_SimpleITK._SetImageFromArray(%1_numpy_array,%1)\n").arg(varName) );
+ command.append( QString("del %1_numpy_array").arg(varName) );
- MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
- MITK_INFO << this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- QFile file( fileName );
- MITK_DEBUG("PythonService") << "Removing file " << fileName.toStdString();
- file.remove();
- return true;
- }
- return false;
+ return true;
}
-mitk::Image::Pointer mitk::PythonService::CopyItkImageFromPython(const std::string &stdvarName)
+mitk::Image::Pointer mitk::PythonService::CopySimpleItkImageFromPython(const std::string &stdvarName)
{
+ double*ds = NULL;
+ // access python module
+ PyObject *pyMod = PyImport_AddModule((char*)"__main__");
+ // global dictionarry
+ PyObject *pyDict = PyModule_GetDict(pyMod);
+ mitk::Image::Pointer mitkImage = mitk::Image::New();
+ mitk::Vector3D spacing;
+ mitk::Point3D origin;
+ QString command;
QString varName = QString::fromStdString( stdvarName );
- mitk::Image::Pointer mitkImage;
- QString command;
- QString fileName = GetTempDataFileName( mitk::IOUtil::DEFAULTIMAGEEXTENSION );
- fileName = QDir::fromNativeSeparators( fileName );
- MITK_DEBUG("PythonService") << "Saving temporary file with python itk code " << fileName.toStdString();
+ command.append( QString("%1_numpy_array = sitk.GetArrayFromImage(%1)\n").arg(varName) );
+ command.append( QString("%1_spacing = numpy.asarray(%1.GetSpacing())\n").arg(varName) );
+ command.append( QString("%1_origin = numpy.asarray(%1.GetOrigin())\n").arg(varName) );
+ command.append( QString("%1_dtype = %1_numpy_array.dtype.name").arg(varName) );
- command.append( QString( "writer = itk.ImageFileWriter[ %1 ].New()\n").arg( varName ) );
- command.append( QString( "writer.SetFileName( \"%1\" )\n").arg(fileName) );
- command.append( QString( "writer.SetInput( %1 )\n").arg(varName) );
- command.append( QString( "writer.Update()\n" ) );
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
- this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
+ PyObject* py_dtype = PyDict_GetItemString(pyDict,QString("%1_dtype").arg(varName).toStdString().c_str() );
+ std::string dtype = PyString_AsString(py_dtype);
+ PyArrayObject* py_data = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_numpy_array").arg(varName).toStdString().c_str() );
+ PyArrayObject* py_spacing = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_spacing").arg(varName).toStdString().c_str() );
+ PyArrayObject* py_origin = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_origin").arg(varName).toStdString().c_str() );
+
+ size_t sz = sizeof(short);
+ mitk::PixelType pixelType = MakeScalarPixelType<short>();
+ if( dtype.compare("float64") == 0 ) {
+ pixelType = MakeScalarPixelType<double>();
+ sz = sizeof(double);
+ } else if( dtype.compare("float32") == 0 ) {
+ pixelType = MakeScalarPixelType<float>();
+ sz = sizeof(float);
+ } else if( dtype.compare("int16") == 0) {
+ pixelType = MakeScalarPixelType<short>();
+ sz = sizeof(short);
+ } else if( dtype.compare("int8") == 0 ) {
+ pixelType = MakeScalarPixelType<char>();
+ sz = sizeof(char);
+ } else if( dtype.compare("int32") == 0 ) {
+ pixelType = MakeScalarPixelType<int>();
+ sz = sizeof(int);
+ } else if( dtype.compare("int64") == 0 ) {
+ pixelType = MakeScalarPixelType<long>();
+ sz = sizeof(long);
+ } else if( dtype.compare("uint8") == 0 ) {
+ pixelType = MakeScalarPixelType<unsigned char>();
+ sz = sizeof(unsigned char);
+ } else if( dtype.compare("uint32") == 0 ) {
+ pixelType = MakeScalarPixelType<unsigned int>();
+ sz = sizeof(unsigned int);
+ } else if( dtype.compare("uint64") == 0 ) {
+ pixelType = MakeScalarPixelType<unsigned long>();
+ sz = sizeof(unsigned long);
+ } else if( dtype.compare("uint16") == 0 ) {
+ pixelType = MakeScalarPixelType<unsigned short>();
+ sz = sizeof(unsigned short);
+ }
- try
- {
- MITK_DEBUG("PythonService") << "Loading temporary file " << fileName.toStdString() << " as MITK image";
- mitkImage = mitk::IOUtil::LoadImage( fileName.toStdString() );
- }
- catch(std::exception& e)
- {
- MITK_ERROR << e.what();
- }
+ unsigned int* dimensions = new unsigned int[py_data->nd];
+ // fill backwards , nd data saves dimensions in opposite direction
+ for( int i = 0; i < py_data->nd; ++i )
+ {
+ dimensions[i] = py_data->dimensions[py_data->nd - 1 - i];
+ sz *= dimensions[i];
+ }
- QFile file(fileName);
- if( file.exists() )
- {
- MITK_DEBUG("PythonService") << "Removing temporary file " << fileName.toStdString();
- file.remove();
- }
+ mitkImage->Initialize(pixelType, py_data->nd, dimensions);
+ mitkImage->SetChannel(py_data->data);
+
+ ds = (double*)py_spacing->data;
+ spacing[0] = ds[0];
+ spacing[1] = ds[1];
+ spacing[2] = ds[2];
+ mitkImage->GetGeometry()->SetSpacing(spacing);
+
+ ds = (double*)py_origin->data;
+ origin[0] = ds[0];
+ origin[1] = ds[1];
+ origin[2] = ds[2];
+ mitkImage->GetGeometry()->SetOrigin(origin);
+
+ // cleanup
+ command.clear();
+ command.append( QString("del %1_numpy_array\n").arg(varName) );
+ command.append( QString("del %1_dtype\n").arg(varName) );
+ command.append( QString("del %1_spacing\n").arg(varName) );
+ command.append( QString("del %1_origin").arg(varName) );
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
+
+ delete[] dimensions;
- return mitkImage;
+ return mitkImage;
}
bool mitk::PythonService::CopyToPythonAsCvImage( mitk::Image* image, const std::string& stdvarName )
{
QString varName = QString::fromStdString( stdvarName );
bool convert = false;
if(image->GetDimension() != 2)
{
MITK_ERROR << "Only 2D images allowed for OpenCV images";
return convert;
}
// try to save mitk image
QString fileName = this->GetTempDataFileName( ".bmp" );
fileName = QDir::fromNativeSeparators( fileName );
MITK_DEBUG("PythonService") << "Saving temporary file " << fileName.toStdString();
if( !mitk::IOUtil::SaveImage(image, fileName.toStdString()) )
{
MITK_ERROR << "Temporary file " << fileName.toStdString() << " could not be created.";
return convert;
}
QString command;
command.append( QString("%1 = cv2.imread(\"%2\")\n") .arg( varName ).arg( fileName ) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
MITK_DEBUG("PythonService") << "Removing file " << fileName.toStdString();
QFile file(fileName);
file.remove();
convert = true;
return convert;
}
mitk::Image::Pointer mitk::PythonService::CopyCvImageFromPython( const std::string& stdvarName )
{
QString varName = QString::fromStdString( stdvarName );
mitk::Image::Pointer mitkImage;
QString command;
QString fileName = GetTempDataFileName( ".bmp" );
fileName = QDir::fromNativeSeparators( fileName );
MITK_DEBUG("PythonService") << "run python command to save image with opencv to " << fileName.toStdString();
command.append( QString( "cv2.imwrite(\"%1\", %2)\n").arg( fileName ).arg( varName ) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
try
{
MITK_DEBUG("PythonService") << "Loading temporary file " << fileName.toStdString() << " as MITK image";
mitkImage = mitk::IOUtil::LoadImage( fileName.toStdString() );
}
catch(std::exception& e)
{
MITK_ERROR << e.what();
}
QFile file(fileName);
if( file.exists() )
{
MITK_DEBUG("PythonService") << "Removing temporary file " << fileName.toStdString();
file.remove();
}
return mitkImage;
}
ctkAbstractPythonManager *mitk::PythonService::GetPythonManager()
{
return &m_PythonManager;
}
mitk::Surface::Pointer mitk::PythonService::CopyVtkPolyDataFromPython( const std::string& stdvarName )
{
- QString varName = QString::fromStdString( stdvarName );
- mitk::Surface::Pointer newSurface;
-
+ // access python module
+ PyObject *pyMod = PyImport_AddModule((char*)"__main__");
+ // global dictionarry
+ PyObject *pyDict = PyModule_GetDict(pyMod);
+ // python memory address
+ PyObject *pyAddr = NULL;
+ // cpp address
+ size_t addr = 0;
+ mitk::Surface::Pointer surface = mitk::Surface::New();
QString command;
- QString fileName = GetTempDataFileName( ".stl" );
- fileName = QDir::fromNativeSeparators( fileName );
+ QString varName = QString::fromStdString( stdvarName );
- MITK_DEBUG("PythonService") << "run python command to save polydata with vtk to " << fileName.toStdString();
- command = QString (
- "vtkStlWriter = vtk.vtkSTLWriter()\n"
- "vtkStlWriter.SetInput(%1)\n"
- "vtkStlWriter.SetFileName(\"%2\")\n"
- "vtkStlWriter.Write()\n").arg(varName).arg(fileName);
+ command.append( QString("%1_addr_str = %1.GetAddressAsString(\"vtkPolyData\")\n").arg(varName) );
+ // remove 0x from the address
+ command.append( QString("%1_addr = int(%1_addr_str[5:],16)").arg(varName) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- try
- {
- MITK_DEBUG("PythonService") << "Loading temporary file " << fileName.toStdString() << " as MITK Surface";
- newSurface = mitk::IOUtil::LoadSurface( fileName.toStdString() );
- }
- catch(std::exception& e)
- {
- MITK_ERROR << e.what();
- }
+ // get address of the object
+ pyAddr = PyDict_GetItemString(pyDict,QString("%1_addr").arg(varName).toStdString().c_str());
- QFile file(fileName);
- if( file.exists() )
- {
- MITK_DEBUG("PythonService") << "Removing temporary file " << fileName.toStdString();
- file.remove();
- }
+ // convert to long
+ addr = PyInt_AsLong(pyAddr);
+
+ MITK_DEBUG << "Python object address: " << addr;
+
+ // get the object
+ vtkPolyData* poly = (vtkPolyData*)((void*)addr);
+ surface->SetVtkPolyData(poly);
+
+ // delete helper variables from python stack
+ command = "";
+ command.append( QString("del %1_addr_str\n").arg(varName) );
+ command.append( QString("del %1_addr").arg(varName) );
+
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- return newSurface;
+ return surface;
}
bool mitk::PythonService::CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& stdvarName )
{
QString varName = QString::fromStdString( stdvarName );
- bool convert = false;
+ std::ostringstream oss;
+ std::string addr = "";
+ QString command;
+ QString address;
- // try to save mitk image
- QString fileName = this->GetTempDataFileName( ".stl" );
- fileName = QDir::fromNativeSeparators( fileName );
- MITK_DEBUG("PythonService") << "Saving temporary file " << fileName.toStdString();
- if( !mitk::IOUtil::SaveSurface( surface, fileName.toStdString() ) )
- {
- MITK_ERROR << "Temporary file " << fileName.toStdString() << " could not be created.";
- return convert;
- }
+ oss << (void*) ( surface->GetVtkPolyData() );
- QString command;
+ // get the address
+ addr = oss.str();
+
+ // remove "0x"
+ address = QString::fromStdString(addr.substr(2));
+
+ command.append( QString("%1 = vtk.vtkPolyData(\"%2\")\n").arg(varName).arg(address) );
- command.append( QString("vtkStlReader = vtk.vtkSTLReader()\n") );
- command.append( QString("vtkStlReader.SetFileName(\"%1\")\n").arg( fileName ) );
- command.append( QString("vtkStlReader.Update()\n") );
- command.append( QString("%1 = vtkStlReader.GetOutput()\n").arg( varName ) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- MITK_DEBUG("PythonService") << "Removing file " << fileName.toStdString();
- QFile file(fileName);
- file.remove();
- convert = true;
- return convert;
+ return true;
}
-bool mitk::PythonService::IsItkPythonWrappingAvailable()
+bool mitk::PythonService::IsSimpleItkPythonWrappingAvailable()
{
- this->Execute( "import itk\n", IPythonService::SINGLE_LINE_COMMAND );
- this->Execute( "print \"Using ITK version \" + itk.Version.GetITKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
+ this->Execute( "import SimpleITK as sitk\n", IPythonService::SINGLE_LINE_COMMAND );
+ // directly access cpp lib
+ this->Execute( "import _SimpleITK\n", IPythonService::SINGLE_LINE_COMMAND );
+ m_ItkWrappingAvailable = !this->PythonErrorOccured();
+
+ // check for numpy
+ this->Execute( "import numpy\n", IPythonService::SINGLE_LINE_COMMAND );
+
+ if ( this->PythonErrorOccured() )
+ MITK_ERROR << "Numpy not found.";
m_ItkWrappingAvailable = !this->PythonErrorOccured();
return m_ItkWrappingAvailable;
}
bool mitk::PythonService::IsOpenCvPythonWrappingAvailable()
{
this->Execute( "import cv2\n", IPythonService::SINGLE_LINE_COMMAND );
m_OpenCVWrappingAvailable = !this->PythonErrorOccured();
return m_OpenCVWrappingAvailable;
}
bool mitk::PythonService::IsVtkPythonWrappingAvailable()
{
this->Execute( "import vtk", IPythonService::SINGLE_LINE_COMMAND );
- this->Execute( "print \"Using VTK version \" + vtk.vtkVersion.GetVTKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
+ //this->Execute( "print \"Using VTK version \" + vtk.vtkVersion.GetVTKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
m_VtkWrappingAvailable = !this->PythonErrorOccured();
return m_VtkWrappingAvailable;
}
bool mitk::PythonService::PythonErrorOccured() const
{
return m_ErrorOccured;
}
diff --git a/Modules/Python/mitkPythonService.h b/Modules/Python/mitkPythonService.h
index a566b8214d..37f1b34d0d 100644
--- a/Modules/Python/mitkPythonService.h
+++ b/Modules/Python/mitkPythonService.h
@@ -1,105 +1,105 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkPythonService_h
#define mitkPythonService_h
#include "mitkIPythonService.h"
#include <itkLightObject.h>
#include <ctkAbstractPythonManager.h>
#include "mitkSurface.h"
#include <MitkPythonExports.h>
namespace mitk
{
///
/// implementation of the IPythonService using ctkabstractpythonmanager
/// \see IPythonService
class MITK_PYTHON_EXPORT PythonService: public itk::LightObject, public mitk::IPythonService
{
public:
///
/// instantiate python manager here
PythonService();
///
/// empty implementation...
~PythonService();
///
/// \see IPythonService::Execute()
std::string Execute( const std::string& pythonCommand, int commandType = SINGLE_LINE_COMMAND );
///
/// \see IPythonService::ExecuteScript()
void ExecuteScript(const std::string &pathToPythonScript);
///
/// \see IPythonService::PythonErrorOccured()
bool PythonErrorOccured() const;
///
/// \see IPythonService::GetVariableStack()
std::vector<PythonVariable> GetVariableStack() const;
///
/// \see IPythonService::DoesVariableExist()
bool DoesVariableExist(const std::string& name) const;
///
/// \see IPythonService::AddPythonCommandObserver()
void AddPythonCommandObserver( PythonCommandObserver* observer );
///
/// \see IPythonService::RemovePythonCommandObserver()
void RemovePythonCommandObserver( PythonCommandObserver* observer );
///
/// \see IPythonService::NotifyObserver()
void NotifyObserver( const std::string& command );
///
/// \see IPythonService::IsItkPythonWrappingAvailable()
- bool IsItkPythonWrappingAvailable();
+ bool IsSimpleItkPythonWrappingAvailable();
///
/// \see IPythonService::CopyToPythonAsItkImage()
- bool CopyToPythonAsItkImage( mitk::Image* image, const std::string& varName );
+ bool CopyToPythonAsSimpleItkImage( mitk::Image* image, const std::string& varName );
///
/// \see IPythonService::CopyItkImageFromPython()
- mitk::Image::Pointer CopyItkImageFromPython( const std::string& varName );
+ mitk::Image::Pointer CopySimpleItkImageFromPython( const std::string& varName );
///
/// \see IPythonService::IsOpenCvPythonWrappingAvailable()
bool IsOpenCvPythonWrappingAvailable();
///
/// \see IPythonService::CopyToPythonAsCvImage()
bool CopyToPythonAsCvImage( mitk::Image* image, const std::string& varName );
///
/// \see IPythonService::CopyCvImageFromPython()
mitk::Image::Pointer CopyCvImageFromPython( const std::string& varName );
///
/// \see IPythonService::IsVtkPythonWrappingAvailable()
bool IsVtkPythonWrappingAvailable();
///
/// \see IPythonService::CopyToPythonAsVtkPolyData()
bool CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& varName );
///
/// \see IPythonService::CopyVtkPolyDataFromPython()
mitk::Surface::Pointer CopyVtkPolyDataFromPython( const std::string& varName );
///
/// \return the ctk abstract python manager instance
ctkAbstractPythonManager* GetPythonManager();
protected:
QString GetTempDataFileName(const std::string &ext) const;
private:
QList<PythonCommandObserver*> m_Observer;
ctkAbstractPythonManager m_PythonManager;
static const QString m_TmpDataFileName;
bool m_ItkWrappingAvailable;
bool m_OpenCVWrappingAvailable;
bool m_VtkWrappingAvailable;
bool m_ErrorOccured;
};
}
#endif
diff --git a/Modules/Python/resources/PythonSnippets.xml b/Modules/Python/resources/PythonSnippets.xml
index a301307dd3..7e8a1bcb5d 100644
--- a/Modules/Python/resources/PythonSnippets.xml
+++ b/Modules/Python/resources/PythonSnippets.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<PythonSnippets>
- <PythonSnippet key="medianfilter" value="filter = itk.MedianImageFilter[ mitkImage, mitkImage ].New()&#10;filter.SetRadius( 1 )&#10;filter.SetInput( mitkImage )&#10;filter.Update()&#10;mitkImage_new = filter.GetOutput()"/>
- <PythonSnippet key="vtk.vtkDecimatePro" value="deci = vtk.vtkDecimatePro()&#10;deci.SetInputConnection( mitkSurface )&#10;deci.SetTargetReduction(0.9)&#10;deci.PreserveTopologyOn()&#10;deci.Update()&#10;&#10;mitkSurface_new = deci.GetOutput()"/>
+ <PythonSnippet key="medianfilter" value="import SimpleITK as sitk&#10;filter = sitk.MedianImageFilter()&#10;filter.SetRadius(1)&#10;mitkImage_new = filter.Execute(mitkImage)"/>
+ <PythonSnippet key="vtk.vtkDecimatePro" value="deci = vtk.vtkDecimatePro()&#10;deci.SetInputData( mitkSurface )&#10;deci.SetTargetReduction(0.9)&#10;deci.PreserveTopologyOn()&#10;deci.Update()&#10;&#10;mitkSurface_new = deci.GetOutput()"/>
<PythonSnippet key="opencv median filter" value="mitkImage_new = cv2.medianBlur(mitkImage, 3)"/>
<PythonSnippet key="vtk: create cone" value="coneSrc = vtk.vtkConeSource()&#10;coneSrc.SetResolution(60)&#10;coneSrc.SetCenter(-2,0,0)&#10;coneSrc.Update()&#10;cone = coneSrc.GetOutput()"/>
</PythonSnippets>
diff --git a/Modules/QmlItems/QmlMitkRenderWindowItem.cpp b/Modules/QmlItems/QmlMitkRenderWindowItem.cpp
index e5b6a2c3d7..22f4af8222 100644
--- a/Modules/QmlItems/QmlMitkRenderWindowItem.cpp
+++ b/Modules/QmlItems/QmlMitkRenderWindowItem.cpp
@@ -1,405 +1,405 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "QmlMitkRenderWindowItem.h"
#include <vtkOpenGLExtensionManager.h>
#include <QVTKInteractor.h>
#include<vtkEventQtSlotConnect.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKInteractorAdapter.h>
// MITK event types
#include "mitkMousePressEvent.h"
#include "mitkMouseMoveEvent.h"
#include "mitkMouseDoubleClickEvent.h"
#include "mitkMouseReleaseEvent.h"
#include "mitkInteractionKeyEvent.h"
#include "mitkMouseWheelEvent.h"
#include "mitkInternalEvent.h"
-#include "mitkGeometry2DDataMapper2D.h"
+#include "mitkPlaneGeometryDataMapper2D.h"
#include "QmlMitkBigRenderLock.h"
#define INTERACTION_LEGACY // TODO: remove INTERACTION_LEGACY!
#if defined INTERACTION_LEGACY
#include "InteractionLegacy/QmitkEventAdapter.h"
#include "mitkGlobalInteraction.h"
#endif
QmlMitkRenderWindowItem* QmlMitkRenderWindowItem::GetInstanceForVTKRenderWindow( vtkRenderWindow* rw )
{
return GetInstances()[rw];
}
QMap<vtkRenderWindow*, QmlMitkRenderWindowItem*>& QmlMitkRenderWindowItem::GetInstances()
{
static QMap<vtkRenderWindow*, QmlMitkRenderWindowItem*> s_Instances;
return s_Instances;
}
QmlMitkRenderWindowItem
::QmlMitkRenderWindowItem(QQuickItem* parent,
const QString& name,
mitk::VtkPropRenderer* /*renderer*/,
mitk::RenderingManager* renderingManager)
: QVTKQuickItem(parent)
{
mitk::RenderWindowBase::Initialize( renderingManager, name.toStdString().c_str() );
/* from QmitkRenderWindow. Required?
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);
*/
GetInstances()[QVTKQuickItem::GetRenderWindow()] = this;
}
// called from QVTKQuickItem when window is painted for the first time!
void QmlMitkRenderWindowItem::init()
{
QVTKQuickItem::init();
mitk::DataStorage::Pointer m_DataStorage = mitk::RenderWindowBase::GetRenderer()->GetDataStorage();
if (m_DataStorage.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()) );
}
// TODO the following code needs to be moved to a multi-widget item
if ( mitk::RenderWindowBase::GetRenderer()->GetMapperID() == mitk::BaseRenderer::Standard2D )
{
this->SetCrossHairPositioningOnClick(true);
}
if ( mitk::RenderWindowBase::GetRenderer()->GetMapperID() == mitk::BaseRenderer::Standard2D
&& m_DataStorage.IsNotNull() )
{
mitk::DataNode::Pointer planeNode = mitk::RenderWindowBase::GetRenderer()->GetCurrentWorldGeometry2DNode();
switch ( mitk::RenderWindowBase::GetRenderer()->GetSliceNavigationController()->GetDefaultViewDirection() )
{
case mitk::SliceNavigationController::Axial:
planeNode->SetColor(1.0,0.0,0.0);
break;
case mitk::SliceNavigationController::Sagittal:
planeNode->SetColor(0.0,1.0,0.0);
break;
case mitk::SliceNavigationController::Frontal:
planeNode->SetColor(0.0,0.0,1.0);
break;
default:
planeNode->SetColor(1.0,1.0,0.0);
}
planeNode->SetProperty("layer", mitk::IntProperty::New(1000) );
planeNode->SetProperty("visible", mitk::BoolProperty::New(true) );
planeNode->SetProperty("helper object", mitk::BoolProperty::New(true) );
- mitk::Geometry2DDataMapper2D::Pointer mapper = mitk::Geometry2DDataMapper2D::New();
+ mitk::PlaneGeometryDataMapper2D::Pointer mapper = mitk::PlaneGeometryDataMapper2D::New();
mapper->SetDatastorageAndGeometryBaseNode( m_DataStorage, m_PlaneNodeParent );
planeNode->SetMapper( mitk::BaseRenderer::Standard2D, mapper );
m_DataStorage->Add( planeNode, m_PlaneNodeParent );
}
}
void QmlMitkRenderWindowItem::InitView( mitk::BaseRenderer::MapperSlotId mapperID,
mitk::SliceNavigationController::ViewDirection viewDirection )
{
m_MapperID = mapperID;
m_ViewDirection = viewDirection;
}
void QmlMitkRenderWindowItem::SetDataStorage(mitk::DataStorage::Pointer storage)
{
m_DataStorage = storage;
}
mitk::Point2D QmlMitkRenderWindowItem::GetMousePosition(QMouseEvent* me) const
{
mitk::Point2D point;
point[0] = me->x();
point[1] = me->y();
return point;
}
mitk::Point2D QmlMitkRenderWindowItem::GetMousePosition(QWheelEvent* we) const
{
mitk::Point2D point;
point[0] = we->x();
point[1] = we->y();
return point;
}
mitk::InteractionEvent::MouseButtons QmlMitkRenderWindowItem::GetEventButton(QMouseEvent* me) const
{
mitk::InteractionEvent::MouseButtons eventButton;
switch (me->button())
{
case Qt::LeftButton:
eventButton = mitk::InteractionEvent::LeftMouseButton;
break;
case Qt::RightButton:
eventButton = mitk::InteractionEvent::RightMouseButton;
break;
case Qt::MidButton:
eventButton = mitk::InteractionEvent::MiddleMouseButton;
break;
default:
eventButton = mitk::InteractionEvent::NoButton;
break;
}
return eventButton;
}
mitk::InteractionEvent::MouseButtons QmlMitkRenderWindowItem::GetButtonState(QMouseEvent* me) const
{
mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton;
if (me->buttons() & Qt::LeftButton)
{
buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton;
}
if (me->buttons() & Qt::RightButton)
{
buttonState = buttonState | mitk::InteractionEvent::RightMouseButton;
}
if (me->buttons() & Qt::MidButton)
{
buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton;
}
return buttonState;
}
mitk::InteractionEvent::ModifierKeys QmlMitkRenderWindowItem::GetModifiers(QInputEvent* me) const
{
mitk::InteractionEvent::ModifierKeys modifiers = mitk::InteractionEvent::NoKey;
if (me->modifiers() & Qt::ALT)
{
modifiers = modifiers | mitk::InteractionEvent::AltKey;
}
if (me->modifiers() & Qt::CTRL)
{
modifiers = modifiers | mitk::InteractionEvent::ControlKey;
}
if (me->modifiers() & Qt::SHIFT)
{
modifiers = modifiers | mitk::InteractionEvent::ShiftKey;
}
return modifiers;
}
mitk::InteractionEvent::MouseButtons QmlMitkRenderWindowItem::GetButtonState(QWheelEvent* we) const
{
mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton;
if (we->buttons() & Qt::LeftButton)
{
buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton;
}
if (we->buttons() & Qt::RightButton)
{
buttonState = buttonState | mitk::InteractionEvent::RightMouseButton;
}
if (we->buttons() & Qt::MidButton)
{
buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton;
}
return buttonState;
}
void QmlMitkRenderWindowItem::mousePressEvent(QMouseEvent* me)
{
mitk::Point2D mousePosition = GetMousePosition(me);
mitk::Point3D worldPosition = mitk::RenderWindowBase::GetRenderer()->Map2DRendererPositionTo3DWorldPosition(mousePosition);
mitk::MousePressEvent::Pointer mPressEvent =
mitk::MousePressEvent::New(mitk::RenderWindowBase::GetRenderer(), mousePosition, worldPosition, GetButtonState(me), GetModifiers(me), GetEventButton(me));
#if defined INTERACTION_LEGACY
bool modernInteractorHandledEvent =
#endif
mitk::RenderWindowBase::HandleEvent(mPressEvent.GetPointer());
#if defined INTERACTION_LEGACY
if (!modernInteractorHandledEvent)
{
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(mitk::RenderWindowBase::GetRenderer(), me));
mitk::RenderWindowBase::mousePressMitkEvent(&myevent);
}
#endif
QVTKQuickItem::mousePressEvent(me);
// if (m_ResendQtEvents)
// me->ignore();
}
void QmlMitkRenderWindowItem::mouseReleaseEvent(QMouseEvent* me)
{
mitk::Point2D mousePosition = GetMousePosition(me);
mitk::Point3D worldPosition = mitk::RenderWindowBase::GetRenderer()->Map2DRendererPositionTo3DWorldPosition(mousePosition);
mitk::MouseReleaseEvent::Pointer mReleaseEvent =
mitk::MouseReleaseEvent::New(mitk::RenderWindowBase::GetRenderer(), mousePosition, worldPosition, GetButtonState(me), GetModifiers(me), GetEventButton(me));
#if defined INTERACTION_LEGACY
bool modernInteractorHandledEvent =
#endif
mitk::RenderWindowBase::HandleEvent(mReleaseEvent.GetPointer());
#if defined INTERACTION_LEGACY
if (!modernInteractorHandledEvent)
{
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(mitk::RenderWindowBase::GetRenderer(), me));
mitk::RenderWindowBase::mouseReleaseMitkEvent(&myevent);
}
#endif
QVTKQuickItem::mouseReleaseEvent(me);
// if (m_ResendQtEvents)
// me->ignore();
}
void QmlMitkRenderWindowItem::mouseMoveEvent(QMouseEvent* me)
{
mitk::Point2D mousePosition = GetMousePosition(me);
mitk::Point3D worldPosition = mitk::RenderWindowBase::GetRenderer()->Map2DRendererPositionTo3DWorldPosition(mousePosition);
mitk::MouseMoveEvent::Pointer mMoveEvent =
mitk::MouseMoveEvent::New(mitk::RenderWindowBase::GetRenderer(), mousePosition, worldPosition, GetButtonState(me), GetModifiers(me));
#if defined INTERACTION_LEGACY
bool modernInteractorHandledEvent =
#endif
mitk::RenderWindowBase::HandleEvent(mMoveEvent.GetPointer());
#if defined INTERACTION_LEGACY
if (!modernInteractorHandledEvent)
{
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(mitk::RenderWindowBase::GetRenderer(), me));
mitk::RenderWindowBase::mouseMoveMitkEvent(&myevent);
}
#endif
QVTKQuickItem::mouseMoveEvent(me);
// TODO: why was this not put here initially? What is special about mouse move?
// if (m_ResendQtEvents)
// me->ignore();
}
void QmlMitkRenderWindowItem::wheelEvent(QWheelEvent *we)
{
mitk::Point2D mousePosition = GetMousePosition(we);
mitk::Point3D worldPosition = mitk::RenderWindowBase::GetRenderer()->Map2DRendererPositionTo3DWorldPosition(mousePosition);
mitk::MouseWheelEvent::Pointer mWheelEvent =
mitk::MouseWheelEvent::New(mitk::RenderWindowBase::GetRenderer(), mousePosition, worldPosition, GetButtonState(we), GetModifiers(we), we->delta());
#if defined INTERACTION_LEGACY
bool modernInteractorHandledEvent =
#endif
mitk::RenderWindowBase::HandleEvent(mWheelEvent.GetPointer());
#if defined INTERACTION_LEGACY
if (!modernInteractorHandledEvent)
{ // TODO: INTERACTION_LEGACY
mitk::WheelEvent myevent(QmitkEventAdapter::AdaptWheelEvent(mitk::RenderWindowBase::GetRenderer(), we));
mitk::RenderWindowBase::wheelMitkEvent(&myevent);
}
#endif
QVTKQuickItem::wheelEvent(we);
// if (m_ResendQtEvents)
// we->ignore();
}
void QmlMitkRenderWindowItem::prepareForRender()
{
// Adjust camera is kaputt wenn nicht der renderingmanager dem vtkprop bescheid sagt!
// this is just a workaround
QmlMitkBigRenderLock::GetMutex().lock();
mitk::RenderWindowBase::GetRenderer()->ForceImmediateUpdate();
}
void QmlMitkRenderWindowItem::cleanupAfterRender()
{
QmlMitkBigRenderLock::GetMutex().unlock();
}
void QmlMitkRenderWindowItem::SetCrossHairPositioningOnClick(bool enabled)
{
if (enabled)
{
mitk::GlobalInteraction::GetInstance()->AddListener( mitk::RenderWindowBase::GetSliceNavigationController() );
}
else
{
mitk::GlobalInteraction::GetInstance()->RemoveListener( mitk::RenderWindowBase::GetSliceNavigationController() );
}
}
void QmlMitkRenderWindowItem::SetPlaneNodeParent( mitk::DataNode::Pointer node )
{
m_PlaneNodeParent = node;
}
void QmlMitkRenderWindowItem::geometryChanged(const QRectF & newGeometry, const QRectF & oldGeometry)
{
QVTKQuickItem::geometryChanged(newGeometry, oldGeometry);
this->resizeMitkEvent( newGeometry.width(), newGeometry.height() );
}
vtkRenderWindow* QmlMitkRenderWindowItem::GetVtkRenderWindow()
{
return QVTKQuickItem::GetRenderWindow();
}
vtkRenderWindowInteractor* QmlMitkRenderWindowItem::GetVtkRenderWindowInteractor()
{
return QVTKQuickItem::GetInteractor();
}
diff --git a/Modules/Overlays/CMakeLists.txt b/Modules/QtOverlays/CMakeLists.txt
similarity index 100%
copy from Modules/Overlays/CMakeLists.txt
copy to Modules/QtOverlays/CMakeLists.txt
diff --git a/Modules/Overlays/QmitkCustomWidgetOverlay.cpp b/Modules/QtOverlays/QmitkCustomWidgetOverlay.cpp
similarity index 100%
rename from Modules/Overlays/QmitkCustomWidgetOverlay.cpp
rename to Modules/QtOverlays/QmitkCustomWidgetOverlay.cpp
diff --git a/Modules/Overlays/QmitkCustomWidgetOverlay.h b/Modules/QtOverlays/QmitkCustomWidgetOverlay.h
similarity index 93%
rename from Modules/Overlays/QmitkCustomWidgetOverlay.h
rename to Modules/QtOverlays/QmitkCustomWidgetOverlay.h
index 0ab0901c1a..539a20513e 100644
--- a/Modules/Overlays/QmitkCustomWidgetOverlay.h
+++ b/Modules/QtOverlays/QmitkCustomWidgetOverlay.h
@@ -1,66 +1,66 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QmitkCustomWidgetOverlay_H_HEADER_INCLUDED_C10DC4EB
#define QmitkCustomWidgetOverlay_H_HEADER_INCLUDED_C10DC4EB
// MITK
#include "QmitkOverlay.h"
-#include <MitkOverlaysExports.h>
+#include <MitkQtOverlaysExports.h>
/** \class QmitkCustomWidgetOverlay
* \brief object representing a custom widget that is handled and positioned
* as an overlay.
*
* A QmitkCustomWidgetOverlay is a generic sub-class of QmitkOverlay. It
* offers the possibility to set the internal m_Widget from the outside.
*
* This offers the possibility to position custom widgets 'on top of' other
* widgets using the positioning mechanism of all overlays.
*
* \warn The custom widgets need to be configured and connected manually.
* Properties cannot be set.
*
* \ingroup Overlays
*/
- class MitkOverlays_EXPORT QmitkCustomWidgetOverlay : public QmitkOverlay
+ class MitkQtOverlays_EXPORT QmitkCustomWidgetOverlay : public QmitkOverlay
{
public:
/**
* @brief Default Constructor
**/
QmitkCustomWidgetOverlay( const char* id );
/**
* @brief Default Destructor
**/
virtual ~QmitkCustomWidgetOverlay();
void SetWidget( QWidget* widget );
QSize GetNeededSize();
};
#endif /* QmitkCustomWidgetOverlay_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Modules/Overlays/QmitkOverlay.cpp b/Modules/QtOverlays/QmitkOverlay.cpp
similarity index 100%
rename from Modules/Overlays/QmitkOverlay.cpp
rename to Modules/QtOverlays/QmitkOverlay.cpp
diff --git a/Modules/Overlays/QmitkOverlay.h b/Modules/QtOverlays/QmitkOverlay.h
similarity index 97%
rename from Modules/Overlays/QmitkOverlay.h
rename to Modules/QtOverlays/QmitkOverlay.h
index 8e3a83a524..635febcf58 100644
--- a/Modules/Overlays/QmitkOverlay.h
+++ b/Modules/QtOverlays/QmitkOverlay.h
@@ -1,133 +1,133 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKOVERLAY_H_HEADER_INCLUDED_C10DC4EB
#define MITKOVERLAY_H_HEADER_INCLUDED_C10DC4EB
// MITK
#include "mitkCommon.h"
#include "mitkPropertyList.h"
// Qt
#include <QWidget>
-#include <MitkOverlaysExports.h>
+#include <MitkQtOverlaysExports.h>
/**
\brief Abstract base class for all overlay-objects in MITK
This class is the basis for all classes representing objects that can be visualized as overlays in MITK.
It encapsulates an ID, as well as a display-position and a layer.
The ID is used to access mitkProperties in a PropertyList that holds information that is needed for the visualization,
e.g. text for TextOverlays or scaleFactor for ScalarBarOverlays ...
The display-position encodes where on the screen the overlay will be positioned at
(see and USE the constants defined by DisplayPosition):
\verbatim
0 - 1 - 2
| | |
3 - - 4
| | |
5 - 6 - 7
\endverbatim
The layer is needed if several overlays shall be put in the same position.
In this case the layer defines the order in which the objects are layouted.
\ingroup Qmitk
*/
-class MitkOverlays_EXPORT QmitkOverlay : public QObject
+class MitkQtOverlays_EXPORT QmitkOverlay : public QObject
{
Q_OBJECT
public:
/** \brief enumeration of all possible display positions */
enum DisplayPosition
{
top_Left = 0,
top_Center = 1,
top_Right = 2,
middle_Left = 3,
middle_Right = 4,
bottom_Left = 5,
bottom_Center = 6,
bottom_Right = 7
};
/**
* @brief Constructor with string ID
**/
QmitkOverlay(const char* id);
/**
* @brief Default Destructor
**/
virtual ~QmitkOverlay();
/** \brief setter for the display-position */
virtual void SetPosition( DisplayPosition );
/** \brief getter for the display-position */
virtual DisplayPosition GetPosition();
/** \brief setter for the layer */
virtual void SetLayer( unsigned int );
/** \brief getter for the layer */
virtual unsigned int GetLayer();
/**
* \brief abstract method to internally setup the overlay
*/
virtual void GenerateData( mitk::PropertyList::Pointer /*pl*/ ) {};
/**
* \brief returns the internally handled QWidget
*/
virtual QWidget* GetWidget();
virtual QSize GetNeededSize() = 0;
protected:
/**
\brief Add drop shadow effect via QGraphicsEffect
*/
void AddDropShadow( QWidget* widget );
/** \brief ID of the overlay */
const char* m_Id;
/** \brief position of the overlay */
DisplayPosition m_Position;
/** \brief layer of the overlay */
unsigned int m_Layer;
/** \brief internal QWidget representing the overlay */
QWidget* m_Widget;
bool m_WidgetIsCustom;
};
#endif /* MITKOVERLAY_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Modules/Overlays/QmitkOverlayController.cpp b/Modules/QtOverlays/QmitkOverlayController.cpp
similarity index 100%
rename from Modules/Overlays/QmitkOverlayController.cpp
rename to Modules/QtOverlays/QmitkOverlayController.cpp
diff --git a/Modules/Overlays/QmitkOverlayController.h b/Modules/QtOverlays/QmitkOverlayController.h
similarity index 97%
rename from Modules/Overlays/QmitkOverlayController.h
rename to Modules/QtOverlays/QmitkOverlayController.h
index c524d4e8bd..192b2adec9 100644
--- a/Modules/Overlays/QmitkOverlayController.h
+++ b/Modules/QtOverlays/QmitkOverlayController.h
@@ -1,168 +1,168 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKOVERLAYCONTROLLER_H_HEADER_INCLUDED_C1E77191
#define MITKOVERLAYCONTROLLER_H_HEADER_INCLUDED_C1E77191
// MITK-Stuff
#include "mitkCommon.h"
#include "mitkPropertyList.h"
#include "QmitkOverlay.h"
#include <QObject>
#include <string>
-#include <MitkOverlaysExports.h>
+#include <MitkQtOverlaysExports.h>
class QmitkRenderWindow;
/** \class QmitkOverlayController
* \brief controller that manages the positioning and stacking of QmitkOverlays
*
* This controller manages all QmitkOverlays of one QmitkRenderWindow.
*
* When constructed, it creates one QWidget for each possible display-position and sets the
* appropriate attributes and layouts.
*
* It is possible to add new Overlays using AddOverlay( QmitkOverlay ).
* This overlay will be added to the correct Widget according to its destined position (stored in QmitkOverlay).
* If this widget already holds an overlay, the layer-property is taken into account. If no layer has been set,
* the overlay will be appended at the end.
*
* It is possible to set the visibility of all overlays at a time using SetOverlayVisibility(bool).
*
* RenderWindow specific properties can be set using the internal mitk::PropertyList. This propertyList and the
* 'default' propertyList of the RenderingManager will be concatenated before the overlay is set up.
* If one property exists in both propertyLists, the one in the QmitkOverlayController will be used!
*
* \sa QmitkOverlay
* \sa QmitkRenderWindow
* \ingroup Qmitk
*/
-class MitkOverlays_EXPORT QmitkOverlayController : public QObject
+class MitkQtOverlays_EXPORT QmitkOverlayController : public QObject
{
Q_OBJECT
public:
/**
* \brief constructor with mandatory QmitkRenderWindow and optional mitk::PropertyList
*/
QmitkOverlayController( QmitkRenderWindow* rw, mitk::PropertyList* pl = NULL );
virtual ~QmitkOverlayController();
/**
* \brief adds an instance of QmitkOverlay to the RenderWindow
*
* This method adds the given QmitkOverlay as a sub-widget to the registered RenderWindow.
* It will be added to the correct position in the RenderWindow as it's defined by the overlays
* position-variable. The layer-property will only be considered if necessary.
*/
void AddOverlay( QmitkOverlay* );
void RemoveOverlay( QmitkOverlay* );
void RemoveAllOverlays();
/**
* \brief setting the visibility of all overlays
*/
void SetOverlayVisibility( bool visible );
/**
* \brief getter for the RenderWindow-specific PropertyList
*/
mitk::PropertyList* GetPropertyList();
/**
* \brief setter for the RenderWindow-specific PropertyList
*/
void SetPropertyList( mitk::PropertyList* );
public slots :
/**
* \brief adjusts the position of all overlays to the position of the RenderWindow
*
* This method updates the position of all Widgets according to the position of the RenderWindow
* and the extend of the overlays.
*/
void AdjustAllOverlayPosition();
void AdjustOverlayPosition( QmitkOverlay::DisplayPosition displayPosition );
void UpdateAllOverlays();
void UpdateOverlayData( QmitkOverlay* overlay );
protected:
/**
* \brief setting up the widgets that will hold all overlays
*
* This method sets up the 8 QWidgets that will later hold all QmitkOverlays.
* This includes the correct setting of layouts, alignments and the widget
* attributes necessary to achieve a translucent background and correct rendering
* on all platforms.
*/
void InitializeOverlayLayout();
/**
* \brief re-aligning the overlays - not implemented yet
*/
virtual void AlignOverlays();
/**
* \brief initializes one QWidget - internally used by InitializeOverlayLayout()
*/
void InitializeWidget( QmitkOverlay::DisplayPosition pos );
void RestackOverlays( QmitkOverlay::DisplayPosition pos );
QSize GetMinimumSizeForWidget( QmitkOverlay::DisplayPosition displayPosition );
typedef std::map< QmitkOverlay::DisplayPosition, QWidget* > OverlayPositionMap;
typedef std::vector< QmitkOverlay* > OverlayVector;
/**
* \brief all QmitkOverlays that are currently added
*/
OverlayVector m_AllOverlays;
/**
* \brief all possible positions and the QWidgets representing the corresponding QmitkOverlays
*/
OverlayPositionMap m_PositionedOverlays;
/**
* \brief RenderWindow that all Overlays will be added to
*/
QmitkRenderWindow* m_RenderWindow;
/**
* \brief PropertyList for RenderWindow-specific properties
*/
mitk::PropertyList::Pointer m_PropertyList;
};
#endif /* MITKOVERLAYCONTROLLER_H_HEADER_INCLUDED_C1E77191 */
diff --git a/Modules/Overlays/QmitkScalarBar.cpp b/Modules/QtOverlays/QmitkScalarBar.cpp
similarity index 100%
rename from Modules/Overlays/QmitkScalarBar.cpp
rename to Modules/QtOverlays/QmitkScalarBar.cpp
diff --git a/Modules/Overlays/QmitkScalarBar.h b/Modules/QtOverlays/QmitkScalarBar.h
similarity index 94%
rename from Modules/Overlays/QmitkScalarBar.h
rename to Modules/QtOverlays/QmitkScalarBar.h
index 4c37bd3321..a327a84aee 100644
--- a/Modules/Overlays/QmitkScalarBar.h
+++ b/Modules/QtOverlays/QmitkScalarBar.h
@@ -1,86 +1,86 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKSCALARBAR_H_HEADER_INCLUDED_C10DC4EB
#define MITKSCALARBAR_H_HEADER_INCLUDED_C10DC4EB
#include <mitkCommon.h>
-#include <MitkOverlaysExports.h>
+#include <MitkQtOverlaysExports.h>
#include <QPen>
#include <QWidget>
-class MitkOverlays_EXPORT QmitkScalarBar : public QWidget
+class MitkQtOverlays_EXPORT QmitkScalarBar : public QWidget
{
Q_OBJECT
public:
enum alignment
{
vertical = 0,
horizontal = 1
};
/**
* @brief Default Constructor
**/
QmitkScalarBar( QWidget *parent = 0 );
/**
* @brief Default Destructor
**/
virtual ~QmitkScalarBar();
virtual void SetScaleFactor( double scale );
virtual void SetAlignment( alignment align );
void SetPen( const QPen& pen );
void SetNumberOfSubdivisions( unsigned int subs );
unsigned int GetNumberOfSubdivisions();
protected:
void paintEvent(QPaintEvent* event);
void SetupGeometry( alignment align );
void CleanUpLines();
//void moveEvent(QMoveEvent*);
alignment m_Alignment;
double m_ScaleFactor;
QLine* m_MainLine;
std::vector<QLine*> m_SubDivisionLines;
QPen m_Pen;
unsigned int m_NumberOfSubDivisions;
};
#endif /* MITKSCALARBAR_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Modules/Overlays/QmitkScalarBarOverlay.cpp b/Modules/QtOverlays/QmitkScalarBarOverlay.cpp
similarity index 100%
rename from Modules/Overlays/QmitkScalarBarOverlay.cpp
rename to Modules/QtOverlays/QmitkScalarBarOverlay.cpp
diff --git a/Modules/Overlays/QmitkScalarBarOverlay.h b/Modules/QtOverlays/QmitkScalarBarOverlay.h
similarity index 95%
rename from Modules/Overlays/QmitkScalarBarOverlay.h
rename to Modules/QtOverlays/QmitkScalarBarOverlay.h
index e514c8a4dc..506b28526f 100644
--- a/Modules/Overlays/QmitkScalarBarOverlay.h
+++ b/Modules/QtOverlays/QmitkScalarBarOverlay.h
@@ -1,94 +1,94 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKSCALARBAROVERLAY_H_HEADER_INCLUDED_C10DC4EB
#define MITKSCALARBAROVERLAY_H_HEADER_INCLUDED_C10DC4EB
-#include <MitkOverlaysExports.h>
+#include <MitkQtOverlaysExports.h>
// MITK-Stuff
#include "mitkCommon.h"
#include "mitkPropertyList.h"
#include "QmitkOverlay.h"
#include <QmitkScalarBar.h>
/** \class QmitkScalarBarOverlay
* \brief object representing a text that is drawn as an overlay
*
* \ingroup Qmitk
*/
- class MitkOverlays_EXPORT QmitkScalarBarOverlay : public QmitkOverlay
+ class MitkQtOverlays_EXPORT QmitkScalarBarOverlay : public QmitkOverlay
{
Q_OBJECT
public:
/**
* @brief Default Constructor
**/
QmitkScalarBarOverlay( const char* id );
/**
* @brief Default Destructor
**/
virtual ~QmitkScalarBarOverlay();
/**
* \brief Setup the QLabel with overlay specific information
*
* First, this method sets text-overlay specific properties as described in the class docu above.
* Secondly, the actual text of the label is set.
*
* \WARNING No error will be issued if the property containing the text is not found, the TextOverlay
* will show an empty string!
*/
virtual void GenerateData( mitk::PropertyList::Pointer );
QSize GetNeededSize();
protected:
/**
* \brief internal helper class to determine text-properties
*
* This method is only used internally to apply the text specific properties that can be set
* using a mitk::PropertyList. If a property cannot be found, a default value is used.
*
* The values of these properties are then attributed to the label using QFont and QPalette.
*/
void GetProperties( mitk::PropertyList::Pointer );
void SetupCallback( mitk::BaseProperty::Pointer prop );
void SetScaleFactor();
/** \brief QWidget internally representing the TextOverlay */
QmitkScalarBar* m_ScalarBar;
mitk::BaseProperty::Pointer m_ObservedProperty;
mitk::PropertyList::Pointer m_PropertyList;
unsigned long m_ObserverTag;
};
#endif /* MITKSCALARBAROVERLAY_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Modules/Overlays/QmitkTextOverlay.cpp b/Modules/QtOverlays/QmitkTextOverlay.cpp
similarity index 100%
rename from Modules/Overlays/QmitkTextOverlay.cpp
rename to Modules/QtOverlays/QmitkTextOverlay.cpp
diff --git a/Modules/Overlays/QmitkTextOverlay.h b/Modules/QtOverlays/QmitkTextOverlay.h
similarity index 97%
rename from Modules/Overlays/QmitkTextOverlay.h
rename to Modules/QtOverlays/QmitkTextOverlay.h
index 437c9159ac..02f95d92bd 100644
--- a/Modules/Overlays/QmitkTextOverlay.h
+++ b/Modules/QtOverlays/QmitkTextOverlay.h
@@ -1,119 +1,119 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKTEXTOVERLAY_H_HEADER_INCLUDED_C10DC4EB
#define MITKTEXTOVERLAY_H_HEADER_INCLUDED_C10DC4EB
// MITK
#include "mitkCommon.h"
#include "mitkPropertyList.h"
#include "QmitkOverlay.h"
// Qt
#include <QLabel>
-#include <MitkOverlaysExports.h>
+#include <MitkQtOverlaysExports.h>
/** \class QmitkTextOverlay
* \brief object representing a text that is drawn as an overlay
*
* A QmitkTextOverlay is a text-specific implementation of QmitkOverlay.
* It can be used whenever a simple text is to be rendered as an overlay in
* a QmitkRenderWindow.
*
* Instead of a QWidget (as in QmitkOverlay) a QmitkTextOverlay is internally
* represented by a QLabel. You can access it via GetWidget().
*
* Calling GenerateData( mitk::PropertyList::Pointer ) will setup the textoverlay.
* This includes setting of the actual text (that must be stored in the property
* with the name that is given the overlay as ID).
*
* e.g. mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( "overlay.text.patientName", "Max" );
* --
* QmitkTextOverlay* nameOverlay = new QmitkTextOverlay( "overlay.text.patientName" );
*
* In order to customize the look of the textoverlays, a number of additional properties can be set
* (default values in square brackets):
*
* overlay.color : defines the text-color (mitk::ColorProperty)
* overlay.fontSize : defines the fontSize of the text (mitk::IntProperty)
* overlay.kerning : defines if kerning is to be used (mitk::BoolProperty)
* overlay.fontFamily : defines the fon family that is to be used (mitk::StringProperty)
*
* \ingroup Qmitk
*/
- class MitkOverlays_EXPORT QmitkTextOverlay : public QmitkOverlay
+ class MitkQtOverlays_EXPORT QmitkTextOverlay : public QmitkOverlay
{
public:
/**
* @brief Default Constructor
**/
QmitkTextOverlay( const char* id );
/**
* @brief Default Destructor
**/
virtual ~QmitkTextOverlay();
/**
* \brief Setup the QLabel with overlay specific information
*
* First, this method sets text-overlay specific properties as described in the class docu above.
* Secondly, the actual text of the label is set.
*
* \WARNING No error will be issued if the property containing the text is not found, the TextOverlay
* will show an empty string!
*/
void GenerateData( mitk::PropertyList::Pointer );
QSize GetNeededSize();
protected:
/**
* \brief internal helper class to determine text-properties
*
* This method is only used internally to apply the font specific properties that can be set
* using a mitk::PropertyList. If a property cannot be found, a default value is used.
*
* The values of these properties are then attributed to the QLabel using QFont and QPalette.
*/
void UpdateFontProperties( mitk::PropertyList::Pointer );
void SetupCallback( mitk::BaseProperty::Pointer prop );
void UpdateDisplayedTextFromProperties();
/** \brief QLabel internally representing the TextOverlay */
QLabel* m_Label;
mitk::PropertyList::Pointer m_PropertyList;
mitk::BaseProperty::Pointer m_ObservedProperty;
unsigned long m_ObserverTag;
};
#endif /* MITKTEXTOVERLAY_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Modules/Overlays/files.cmake b/Modules/QtOverlays/files.cmake
similarity index 100%
copy from Modules/Overlays/files.cmake
copy to Modules/QtOverlays/files.cmake
diff --git a/Modules/QtWidgets/CMakeLists.txt b/Modules/QtWidgets/CMakeLists.txt
index 36db107362..c55beb2393 100644
--- a/Modules/QtWidgets/CMakeLists.txt
+++ b/Modules/QtWidgets/CMakeLists.txt
@@ -1,8 +1,8 @@
MITK_CREATE_MODULE(
- DEPENDS MitkPlanarFigure
+ DEPENDS MitkPlanarFigure MitkOverlays
PACKAGE_DEPENDS VTK|vtkGUISupportQt Qt4|QtGui
SUBPROJECTS MITK-CoreUI
EXPORT_DEFINE QMITK_EXPORT
)
add_subdirectory(Testing)
diff --git a/Modules/QtWidgets/QmitkDataStorageFilterProxyModel.cpp b/Modules/QtWidgets/QmitkDataStorageFilterProxyModel.cpp
new file mode 100644
index 0000000000..2f2e387023
--- /dev/null
+++ b/Modules/QtWidgets/QmitkDataStorageFilterProxyModel.cpp
@@ -0,0 +1,85 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+#include <mitkStringProperty.h>
+#include <mitkNodePredicateFirstLevel.h>
+#include <mitkNodePredicateAnd.h>
+#include <mitkNodePredicateData.h>
+#include <mitkNodePredicateNot.h>
+#include <mitkNodePredicateOr.h>
+#include <mitkNodePredicateProperty.h>
+#include <mitkPlanarFigure.h>
+#include <mitkProperties.h>
+#include <mitkRenderingManager.h>
+
+#include "QmitkDataStorageFilterProxyModel.h"
+#include "QmitkDataStorageTreeModel.h"
+#include "QmitkNodeDescriptorManager.h"
+#include <QmitkEnums.h>
+#include <QmitkCustomVariants.h>
+
+#include <QIcon>
+#include <QMimeData>
+#include <QTextStream>
+
+#include <map>
+
+QmitkDataStorageFilterProxyModel::QmitkDataStorageFilterProxyModel(QObject* parent)
+: QSortFilterProxyModel(parent)
+{
+}
+
+QmitkDataStorageFilterProxyModel::~QmitkDataStorageFilterProxyModel()
+{
+}
+
+
+void QmitkDataStorageFilterProxyModel::AddFilterPredicate(mitk::NodePredicateBase::Pointer pred)
+{
+ m_Predicates.insert(pred);
+ this->invalidateFilter();
+}
+
+bool QmitkDataStorageFilterProxyModel::RemoveFilterPredicate(mitk::NodePredicateBase::Pointer pred)
+{
+ bool removed = m_Predicates.erase(pred) != 0;
+ if (removed) {
+ this->invalidateFilter();
+ }
+ return removed;
+}
+
+bool QmitkDataStorageFilterProxyModel::HasFilterPredicate(mitk::NodePredicateBase::Pointer pred)
+{
+ return m_Predicates.find(pred) != m_Predicates.end();
+}
+
+bool QmitkDataStorageFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QmitkDataStorageTreeModel* model = dynamic_cast<QmitkDataStorageTreeModel*>(this->sourceModel());
+ assert(model);
+
+ QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
+
+ for (FilterPredicatesCollection::iterator iter = m_Predicates.begin(); iter != m_Predicates.end(); ++iter) {
+ if ((*iter)->CheckNode(model->GetNode(index0))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
diff --git a/Modules/QtWidgets/QmitkDataStorageFilterProxyModel.h b/Modules/QtWidgets/QmitkDataStorageFilterProxyModel.h
new file mode 100644
index 0000000000..90b318e301
--- /dev/null
+++ b/Modules/QtWidgets/QmitkDataStorageFilterProxyModel.h
@@ -0,0 +1,63 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+#ifndef QMITKDATASTORAGEFILTERPROXYMODEL_H_
+#define QMITKDATASTORAGEFILTERPROXYMODEL_H_
+
+#include <MitkQtWidgetsExports.h>
+
+#include <mitkDataStorage.h>
+#include <mitkNodePredicateBase.h>
+
+#include <QSortFilterProxyModel>
+
+#include <set>
+
+/// \ingroup QmitkModule
+class QMITK_EXPORT QmitkDataStorageFilterProxyModel : public QSortFilterProxyModel
+{
+//# CTORS,DTOR
+public:
+ QmitkDataStorageFilterProxyModel(QObject* parent = 0);
+ ~QmitkDataStorageFilterProxyModel();
+
+public:
+ ///
+ /// If the predicate pred returns true, the node will be hidden in the data manager view
+ ///
+ void AddFilterPredicate(mitk::NodePredicateBase::Pointer pred);
+
+ ///
+ /// Remove a predicate from the list of filters. Returns true if pred was found and removed.
+ ///
+ bool RemoveFilterPredicate(mitk::NodePredicateBase::Pointer pred);
+
+ ///
+ /// Check if predicate is present in the list of filtering predicates.
+ ///
+ bool HasFilterPredicate(mitk::NodePredicateBase::Pointer pred);
+
+//#
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
+
+protected:
+ typedef std::set<mitk::NodePredicateBase::Pointer> FilterPredicatesCollection;
+ FilterPredicatesCollection m_Predicates;
+};
+
+#endif /* QMITKDATASTORAGEFILTERPROXYMODEL_H_ */
diff --git a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp
index b267a98f49..3f129ce411 100644
--- a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp
+++ b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp
@@ -1,925 +1,855 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkStringProperty.h>
#include <mitkNodePredicateFirstLevel.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateData.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateOr.h>
#include <mitkNodePredicateProperty.h>
#include <mitkPlanarFigure.h>
#include <mitkProperties.h>
#include <mitkRenderingManager.h>
#include "QmitkDataStorageTreeModel.h"
#include "QmitkNodeDescriptorManager.h"
#include <QmitkEnums.h>
#include <QmitkCustomVariants.h>
+#include <QmitkMimeTypes.h>
#include <QIcon>
#include <QMimeData>
#include <QTextStream>
#include <map>
QmitkDataStorageTreeModel::QmitkDataStorageTreeModel( mitk::DataStorage* _DataStorage
, bool _PlaceNewNodesOnTop
- , bool _ShowHelperObjects
- , bool _ShowNodesContainingNoData
, QObject* parent )
: QAbstractItemModel(parent)
, m_DataStorage(0)
, m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop)
-, m_ShowHelperObjects(_ShowHelperObjects)
-, m_ShowNodesContainingNoData(_ShowNodesContainingNoData)
, m_Root(0)
{
- this->UpdateNodeVisibility();
this->SetDataStorage(_DataStorage);
}
QmitkDataStorageTreeModel::~QmitkDataStorageTreeModel()
{
// set data storage to 0 = remove all listeners
this->SetDataStorage(0);
m_Root->Delete(); m_Root = 0;
-
- //Removing all observers
- for ( NodeTagMapType::iterator dataIter = m_HelperObjectObserverTags.begin(); dataIter != m_HelperObjectObserverTags.end(); ++dataIter )
- {
- (*dataIter).first->GetProperty("helper object")->RemoveObserver( (*dataIter).second );
- }
- m_HelperObjectObserverTags.clear();
}
mitk::DataNode::Pointer QmitkDataStorageTreeModel::GetNode( const QModelIndex &index ) const
{
return this->TreeItemFromIndex(index)->GetDataNode();
}
const mitk::DataStorage::Pointer QmitkDataStorageTreeModel::GetDataStorage() const
{
return m_DataStorage.GetPointer();
}
QModelIndex QmitkDataStorageTreeModel::index( int row, int column, const QModelIndex & parent ) const
{
TreeItem* parentItem;
if (!parent.isValid())
parentItem = m_Root;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
TreeItem *childItem = parentItem->GetChild(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
int QmitkDataStorageTreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentTreeItem = this->TreeItemFromIndex(parent);
return parentTreeItem->GetChildCount();
}
Qt::ItemFlags QmitkDataStorageTreeModel::flags( const QModelIndex& index ) const
{
mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
if (index.isValid())
{
if(DicomPropertiesExists(*dataNode))
{
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable
| Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}else{
return Qt::ItemIsDropEnabled;
}
}
int QmitkDataStorageTreeModel::columnCount( const QModelIndex& /* parent = QModelIndex() */ ) const
{
return 1;
}
QModelIndex QmitkDataStorageTreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = this->TreeItemFromIndex(index);
TreeItem *parentItem = childItem->GetParent();
if (parentItem == m_Root)
return QModelIndex();
return this->createIndex(parentItem->GetIndex(), 0, parentItem);
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItemFromIndex( const QModelIndex &index ) const
{
if (index.isValid())
return static_cast<TreeItem *>(index.internalPointer());
else
return m_Root;
}
Qt::DropActions QmitkDataStorageTreeModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
Qt::DropActions QmitkDataStorageTreeModel::supportedDragActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data,
Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent)
{
// Early exit, returning true, but not actually doing anything (ignoring data).
if (action == Qt::IgnoreAction)
{
return true;
}
// Note, we are returning true if we handled it, and false otherwise
bool returnValue = false;
if(data->hasFormat("application/x-qabstractitemmodeldatalist"))
{
returnValue = true;
// First we extract a Qlist of TreeItem* pointers.
- QString arg = QString(data->data("application/x-qabstractitemmodeldatalist").data());
- QStringList listOfTreeItemAddressPointers = arg.split(",");
-
- QStringList::iterator slIter;
- QList<TreeItem*> listOfItemsToDrop;
-
- for(slIter = listOfTreeItemAddressPointers.begin();
- slIter != listOfTreeItemAddressPointers.end();
- slIter++)
- {
- long val = (*slIter).toLong();
- listOfItemsToDrop << static_cast<TreeItem *>((void*)val);
- }
+ QList<TreeItem*> listOfItemsToDrop = ToTreeItemPtrList(data);
// Retrieve the TreeItem* where we are dropping stuff, and its parent.
TreeItem* dropItem = this->TreeItemFromIndex(parent);
TreeItem* parentItem = dropItem->GetParent();
// If item was dropped onto empty space, we select the root node
if(dropItem == m_Root)
{
parentItem = m_Root;
}
// Dragging and Dropping is only allowed within the same parent, so use the first item in list to validate.
// (otherwise, you could have a derived image such as a segmentation, and assign it to another image).
// NOTE: We are assuming the input list is valid... i.e. when it was dragged, all the items had the same parent.
if(listOfItemsToDrop[0] != dropItem && listOfItemsToDrop[0]->GetParent() == parentItem)
{
// Retrieve the index of where we are dropping stuff.
QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem);
QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem);
// Iterate through the list of TreeItem (which may be at non-consecutive indexes).
QList<TreeItem*>::iterator diIter;
for (diIter = listOfItemsToDrop.begin();
diIter != listOfItemsToDrop.end();
diIter++)
{
// Here we assume that as you remove items, one at a time, that GetIndex() will be valid.
this->beginRemoveRows(parentModelIndex, (*diIter)->GetIndex(), (*diIter)->GetIndex());
parentItem->RemoveChild(*diIter);
this->endRemoveRows();
}
// Select the target index position, or put it at the end of the list.
int dropIndex = dropItemModelIndex.row();
if (dropIndex == -1)
{
dropIndex = parentItem->GetChildCount();
}
// Now insert items again at the drop item position
this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1);
for (diIter = listOfItemsToDrop.begin();
diIter != listOfItemsToDrop.end();
diIter++)
{
parentItem->InsertChild( (*diIter), dropIndex );
dropIndex++;
}
this->endInsertRows();
// Change Layers to match.
this->AdjustLayerProperty();
}
}
else if(data->hasFormat("application/x-mitk-datanodes"))
{
returnValue = true;
- QString arg = QString(data->data("application/x-mitk-datanodes").data());
- QStringList listOfDataNodeAddressPointers = arg.split(",");
int numberOfNodesDropped = 0;
- QStringList::iterator slIter;
- for (slIter = listOfDataNodeAddressPointers.begin();
- slIter != listOfDataNodeAddressPointers.end();
- slIter++)
+ QList<mitk::DataNode*> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
+ mitk::DataNode* node = NULL;
+ foreach(node, dataNodeList)
{
- long val = (*slIter).toLong();
- mitk::DataNode* node = static_cast<mitk::DataNode *>((void*)val);
-
if(node && m_DataStorage.IsNotNull() && !m_DataStorage->Exists(node))
{
m_DataStorage->Add( node );
mitk::BaseData::Pointer basedata = node->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
numberOfNodesDropped++;
}
}
}
// Only do a rendering update, if we actually dropped anything.
if (numberOfNodesDropped > 0)
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
return returnValue;
}
QStringList QmitkDataStorageTreeModel::mimeTypes() const
{
QStringList types = QAbstractItemModel::mimeTypes();
types << "application/x-qabstractitemmodeldatalist";
types << "application/x-mitk-datanodes";
return types;
}
-QMimeData * QmitkDataStorageTreeModel::mimeData(const QModelIndexList & indexes) const{
+QMimeData * QmitkDataStorageTreeModel::mimeData(const QModelIndexList & indexes) const
+{
+ return mimeDataFromModelIndexList(indexes);
+}
+QMimeData *QmitkDataStorageTreeModel::mimeDataFromModelIndexList(const QModelIndexList &indexes)
+{
QMimeData * ret = new QMimeData;
QString treeItemAddresses("");
QString dataNodeAddresses("");
+ QByteArray baTreeItemPtrs;
+ QByteArray baDataNodePtrs;
+
+ QDataStream dsTreeItemPtrs(&baTreeItemPtrs, QIODevice::WriteOnly);
+ QDataStream dsDataNodePtrs(&baDataNodePtrs, QIODevice::WriteOnly);
+
for (int i = 0; i < indexes.size(); i++)
{
TreeItem* treeItem = static_cast<TreeItem*>(indexes.at(i).internalPointer());
- long treeItemAddress = reinterpret_cast<long>(treeItem);
- long dataNodeAddress = reinterpret_cast<long>(treeItem->GetDataNode().GetPointer());
+
+ dsTreeItemPtrs << reinterpret_cast<quintptr>(treeItem);
+ dsDataNodePtrs << reinterpret_cast<quintptr>(treeItem->GetDataNode().GetPointer());
+
+ // --------------- deprecated -----------------
+ unsigned long long treeItemAddress = reinterpret_cast<unsigned long long>(treeItem);
+ unsigned long long dataNodeAddress = reinterpret_cast<unsigned long long>(treeItem->GetDataNode().GetPointer());
QTextStream(&treeItemAddresses) << treeItemAddress;
QTextStream(&dataNodeAddresses) << dataNodeAddress;
if (i != indexes.size() - 1)
{
QTextStream(&treeItemAddresses) << ",";
QTextStream(&dataNodeAddresses) << ",";
}
+ // -------------- end deprecated -------------
}
+ // ------------------ deprecated -----------------
ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toAscii()));
ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toAscii()));
+ // --------------- end deprecated -----------------
+
+ ret->setData(QmitkMimeTypes::DataStorageTreeItemPtrs, baTreeItemPtrs);
+ ret->setData(QmitkMimeTypes::DataNodePtrs, baDataNodePtrs);
return ret;
}
QVariant QmitkDataStorageTreeModel::data( const QModelIndex & index, int role ) const
{
mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
// get name of treeItem (may also be edited)
QString nodeName;
if(DicomPropertiesExists(*dataNode))
{
mitk::BaseProperty* seriesDescription = (dataNode->GetProperty("dicom.series.SeriesDescription"));
mitk::BaseProperty* studyDescription = (dataNode->GetProperty("dicom.study.StudyDescription"));
mitk::BaseProperty* patientsName = (dataNode->GetProperty("dicom.patient.PatientsName"));
nodeName.append(patientsName->GetValueAsString().c_str()).append("\n");
nodeName.append(studyDescription->GetValueAsString().c_str()).append("\n");
nodeName.append(seriesDescription->GetValueAsString().c_str());
}else{
nodeName = QString::fromStdString(dataNode->GetName());
}
if(nodeName.isEmpty())
{
nodeName = "unnamed";
}
if (role == Qt::DisplayRole)
return nodeName;
else if(role == Qt::ToolTipRole)
return nodeName;
else if(role == Qt::DecorationRole)
{
QmitkNodeDescriptor* nodeDescriptor
= QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode);
return nodeDescriptor->GetIcon();
}
else if(role == Qt::CheckStateRole)
{
return dataNode->IsVisible(0);
}
else if(role == QmitkDataNodeRole)
{
return QVariant::fromValue<mitk::DataNode::Pointer>(mitk::DataNode::Pointer(dataNode));
}
else if(role == QmitkDataNodeRawPointerRole)
{
return QVariant::fromValue<mitk::DataNode*>(dataNode);
}
return QVariant();
}
bool QmitkDataStorageTreeModel::DicomPropertiesExists(const mitk::DataNode& node) const
{
bool propertiesExists = false;
mitk::BaseProperty* seriesDescription = (node.GetProperty("dicom.series.SeriesDescription"));
mitk::BaseProperty* studyDescription = (node.GetProperty("dicom.study.StudyDescription"));
mitk::BaseProperty* patientsName = (node.GetProperty("dicom.patient.PatientsName"));
if(patientsName!=NULL && studyDescription!=NULL && seriesDescription!=NULL)
{
if((!patientsName->GetValueAsString().empty())&&
(!studyDescription->GetValueAsString().empty())&&
(!seriesDescription->GetValueAsString().empty()))
{
propertiesExists = true;
}
}
return propertiesExists;
}
QVariant QmitkDataStorageTreeModel::headerData(int /*section*/,
Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root)
return QString::fromStdString(m_Root->GetDataNode()->GetName());
return QVariant();
}
void QmitkDataStorageTreeModel::SetDataStorage( mitk::DataStorage* _DataStorage )
{
if(m_DataStorage != _DataStorage) // dont take the same again
{
if(m_DataStorage.IsNotNull())
{
// remove Listener for the data storage itself
m_DataStorage.ObjectDelete.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const itk::Object*>( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) );
// remove listeners for the nodes
m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::AddNode ) );
m_DataStorage->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::SetNodeModified ) );
m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::RemoveNode ) );
}
// take over the new data storage
m_DataStorage = _DataStorage;
// delete the old root (if necessary, create new)
if(m_Root)
m_Root->Delete();
mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New();
rootDataNode->SetName("Data Manager");
m_Root = new TreeItem(rootDataNode, 0);
this->reset();
if(m_DataStorage.IsNotNull())
{
// add Listener for the data storage itself
m_DataStorage.ObjectDelete.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const itk::Object*>( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) );
// add listeners for the nodes
m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::AddNode ) );
m_DataStorage->ChangedNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::SetNodeModified ) );
m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::RemoveNode ) );
mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate);
// finally add all nodes to the model
this->Update();
}
}
}
void QmitkDataStorageTreeModel::SetDataStorageDeleted( const itk::Object* /*_DataStorage*/ )
{
this->SetDataStorage(0);
}
void QmitkDataStorageTreeModel::AddNodeInternal(const mitk::DataNode *node)
{
if(node == 0
|| m_DataStorage.IsNull()
|| !m_DataStorage->Exists(node)
- || !m_Predicate->CheckNode(node)
|| m_Root->Find(node) != 0)
return;
// find out if we have a root node
TreeItem* parentTreeItem = m_Root;
QModelIndex index;
mitk::DataNode* parentDataNode = this->GetParentNode(node);
if(parentDataNode) // no top level data node
{
parentTreeItem = m_Root->Find(parentDataNode); // find the corresponding tree item
if(!parentTreeItem)
{
this->AddNode(parentDataNode);
parentTreeItem = m_Root->Find(parentDataNode);
if(!parentTreeItem)
return;
}
// get the index of this parent with the help of the grand parent
index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem);
}
// add node
if(m_PlaceNewNodesOnTop)
{
// emit beginInsertRows event
beginInsertRows(index, 0, 0);
parentTreeItem->InsertChild(new TreeItem(
const_cast<mitk::DataNode*>(node)), 0);
}
else
{
beginInsertRows(index, parentTreeItem->GetChildCount()
, parentTreeItem->GetChildCount());
new TreeItem(const_cast<mitk::DataNode*>(node), parentTreeItem);
}
// emit endInsertRows event
endInsertRows();
this->AdjustLayerProperty();
}
void QmitkDataStorageTreeModel::AddNode( const mitk::DataNode* node )
{
if(node == 0
|| m_DataStorage.IsNull()
|| !m_DataStorage->Exists(node)
|| m_Root->Find(node) != 0)
return;
- bool isHelperObject (false);
- NodeTagMapType::iterator searchIter = m_HelperObjectObserverTags.find( const_cast<mitk::DataNode*>(node) );
- if (node->GetBoolProperty("helper object", isHelperObject) && searchIter == m_HelperObjectObserverTags.end()) {
- itk::SimpleMemberCommand<QmitkDataStorageTreeModel>::Pointer command = itk::SimpleMemberCommand<QmitkDataStorageTreeModel>::New();
- command->SetCallbackFunction(this, &QmitkDataStorageTreeModel::UpdateNodeVisibility);
- m_HelperObjectObserverTags.insert( std::pair<mitk::DataNode*, unsigned long>( const_cast<mitk::DataNode*>(node), node->GetProperty("helper object")->AddObserver( itk::ModifiedEvent(), command ) ) );
- }
-
- if (m_Predicate->CheckNode(node))
this->AddNodeInternal(node);
}
void QmitkDataStorageTreeModel::SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop)
{
m_PlaceNewNodesOnTop = _PlaceNewNodesOnTop;
}
void QmitkDataStorageTreeModel::RemoveNodeInternal( const mitk::DataNode* node )
{
if(!m_Root) return;
TreeItem* treeItem = m_Root->Find(node);
if(!treeItem)
return; // return because there is no treeitem containing this node
TreeItem* parentTreeItem = treeItem->GetParent();
QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem);
// emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model)
this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex());
// remove node
std::vector<TreeItem*> children = treeItem->GetChildren();
delete treeItem;
// emit endRemoveRows event
endRemoveRows();
// move all children of deleted node into its parent
for ( std::vector<TreeItem*>::iterator it = children.begin()
; it != children.end(); it++)
{
// emit beginInsertRows event
beginInsertRows(parentIndex, parentTreeItem->GetChildCount(), parentTreeItem->GetChildCount());
// add nodes again
parentTreeItem->AddChild(*it);
// emit endInsertRows event
endInsertRows();
}
this->AdjustLayerProperty();
}
void QmitkDataStorageTreeModel::RemoveNode( const mitk::DataNode* node )
{
if (node == 0)
return;
- //Removing Observer
- bool isHelperObject (false);
- NodeTagMapType::iterator searchIter = m_HelperObjectObserverTags.find( const_cast<mitk::DataNode*>(node) );
- if (node->GetBoolProperty("helper object", isHelperObject) && searchIter != m_HelperObjectObserverTags.end()) {
- (*searchIter).first->GetProperty("helper object")->RemoveObserver( (*searchIter).second );
- m_HelperObjectObserverTags.erase(const_cast<mitk::DataNode*>(node));
- }
-
this->RemoveNodeInternal(node);
}
void QmitkDataStorageTreeModel::SetNodeModified( const mitk::DataNode* node )
{
TreeItem* treeItem = m_Root->Find(node);
- if(!treeItem)
- {
- // check if the node still fits the predicates
- if( m_Predicate->CheckNode( node ) )
- {
- this->UpdateNodeVisibility();
- }
- }
- else
- {
+ if(treeItem) {
TreeItem* parentTreeItem = treeItem->GetParent();
// as the root node should not be removed one should always have a parent item
if(!parentTreeItem)
return;
QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem);
// now emit the dataChanged signal
emit dataChanged(index, index);
}
}
mitk::DataNode* QmitkDataStorageTreeModel::GetParentNode( const mitk::DataNode* node ) const
{
mitk::DataNode* dataNode = 0;
mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage->GetSources(node);
if(_Sources->Size() > 0)
dataNode = _Sources->front();
return dataNode;
}
bool QmitkDataStorageTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
if(!dataNode)
return false;
if(role == Qt::EditRole && !value.toString().isEmpty())
{
dataNode->SetStringProperty("name", value.toString().toStdString().c_str());
mitk::PlanarFigure* planarFigure = dynamic_cast<mitk::PlanarFigure*>(dataNode->GetData());
if (planarFigure != NULL)
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if(role == Qt::CheckStateRole)
{
// Please note: value.toInt() returns 2, independentely from the actual checkstate of the index element.
// Therefore the checkstate is being estimated again here.
QVariant qcheckstate = index.data(Qt::CheckStateRole);
int checkstate = qcheckstate.toInt();
bool isVisible = bool(checkstate);
dataNode->SetVisibility(!isVisible);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
// inform listeners about changes
emit dataChanged(index, index);
return true;
}
bool QmitkDataStorageTreeModel::setHeaderData( int /*section*/, Qt::Orientation /*orientation*/, const QVariant& /* value */, int /*role = Qt::EditRole*/ )
{
return false;
}
void QmitkDataStorageTreeModel::AdjustLayerProperty()
{
/// transform the tree into an array and set the layer property descending
std::vector<TreeItem*> vec;
this->TreeToVector(m_Root, vec);
int i = vec.size()-1;
for(std::vector<TreeItem*>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
mitk::DataNode::Pointer dataNode = (*it)->GetDataNode();
bool fixedLayer = false;
if (!(dataNode->GetBoolProperty("fixedLayer", fixedLayer) && fixedLayer))
dataNode->SetIntProperty("layer", i);
--i;
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataStorageTreeModel::TreeToVector(TreeItem* parent, std::vector<TreeItem*>& vec) const
{
TreeItem* current;
for(int i = 0; i<parent->GetChildCount(); ++i)
{
current = parent->GetChild(i);
this->TreeToVector(current, vec);
vec.push_back(current);
}
}
QModelIndex QmitkDataStorageTreeModel::IndexFromTreeItem( TreeItem* item ) const
{
if(item == m_Root)
return QModelIndex();
else
return this->createIndex(item->GetIndex(), 0, item);
}
QList<mitk::DataNode::Pointer> QmitkDataStorageTreeModel::GetNodeSet() const
{
QList<mitk::DataNode::Pointer> res;
if(m_Root)
this->TreeToNodeSet(m_Root, res);
return res;
}
void QmitkDataStorageTreeModel::TreeToNodeSet( TreeItem* parent, QList<mitk::DataNode::Pointer>& vec ) const
{
TreeItem* current;
for(int i = 0; i<parent->GetChildCount(); ++i)
{
current = parent->GetChild(i);
vec.push_back(current->GetDataNode());
this->TreeToNodeSet(current, vec);
}
}
QModelIndex QmitkDataStorageTreeModel::GetIndex( const mitk::DataNode* node ) const
{
if(m_Root)
{
TreeItem* item = m_Root->Find(node);
if(item)
return this->IndexFromTreeItem(item);
}
return QModelIndex();
}
+QList<QmitkDataStorageTreeModel::TreeItem *> QmitkDataStorageTreeModel::ToTreeItemPtrList(const QMimeData* mimeData)
+{
+ if (mimeData == NULL || !mimeData->hasFormat(QmitkMimeTypes::DataStorageTreeItemPtrs))
+ {
+ return QList<TreeItem*>();
+ }
+ return ToTreeItemPtrList(mimeData->data(QmitkMimeTypes::DataStorageTreeItemPtrs));
+}
+
+QList<QmitkDataStorageTreeModel::TreeItem *> QmitkDataStorageTreeModel::ToTreeItemPtrList(const QByteArray& ba)
+{
+ QList<TreeItem*> result;
+ QDataStream ds(ba);
+ while(!ds.atEnd())
+ {
+ quintptr treeItemPtr;
+ ds >> treeItemPtr;
+ result.push_back(reinterpret_cast<TreeItem*>(treeItemPtr));
+ }
+ return result;
+}
+
QmitkDataStorageTreeModel::TreeItem::TreeItem( mitk::DataNode* _DataNode, TreeItem* _Parent )
: m_Parent(_Parent)
, m_DataNode(_DataNode)
{
if(m_Parent)
m_Parent->AddChild(this);
}
QmitkDataStorageTreeModel::TreeItem::~TreeItem()
{
if(m_Parent)
m_Parent->RemoveChild(this);
}
void QmitkDataStorageTreeModel::TreeItem::Delete()
{
while(m_Children.size() > 0)
delete m_Children.back();
delete this;
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::Find( const mitk::DataNode* _DataNode ) const
{
QmitkDataStorageTreeModel::TreeItem* item = 0;
if(_DataNode)
{
if(m_DataNode == _DataNode)
item = const_cast<TreeItem*>(this);
else
{
for(std::vector<TreeItem*>::const_iterator it = m_Children.begin(); it != m_Children.end(); ++it)
{
if(item)
break;
item = (*it)->Find(_DataNode);
}
}
}
return item;
}
int QmitkDataStorageTreeModel::TreeItem::IndexOfChild( const TreeItem* item ) const
{
std::vector<TreeItem*>::const_iterator it = std::find(m_Children.begin(), m_Children.end(), item);
return it != m_Children.end() ? std::distance(m_Children.begin(), it): -1;
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetChild( int index ) const
{
return (m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())? m_Children.at(index): 0;
}
void QmitkDataStorageTreeModel::TreeItem::AddChild( TreeItem* item )
{
this->InsertChild(item);
}
void QmitkDataStorageTreeModel::TreeItem::RemoveChild( TreeItem* item )
{
std::vector<TreeItem*>::iterator it = std::find(m_Children.begin(), m_Children.end(), item);
if(it != m_Children.end())
{
m_Children.erase(it);
item->SetParent(0);
}
}
int QmitkDataStorageTreeModel::TreeItem::GetChildCount() const
{
return m_Children.size();
}
int QmitkDataStorageTreeModel::TreeItem::GetIndex() const
{
if (m_Parent)
return m_Parent->IndexOfChild(this);
return 0;
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetParent() const
{
return m_Parent;
}
mitk::DataNode::Pointer QmitkDataStorageTreeModel::TreeItem::GetDataNode() const
{
return m_DataNode;
}
void QmitkDataStorageTreeModel::TreeItem::InsertChild( TreeItem* item, int index )
{
std::vector<TreeItem*>::iterator it = std::find(m_Children.begin(), m_Children.end(), item);
if(it == m_Children.end())
{
if(m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())
{
it = m_Children.begin();
std::advance(it, index);
m_Children.insert(it, item);
}
else
m_Children.push_back(item);
// add parent if necessary
if(item->GetParent() != this)
item->SetParent(this);
}
}
std::vector<QmitkDataStorageTreeModel::TreeItem*> QmitkDataStorageTreeModel::TreeItem::GetChildren() const
{
return m_Children;
}
void QmitkDataStorageTreeModel::TreeItem::SetParent( TreeItem* _Parent )
{
m_Parent = _Parent;
if(m_Parent)
m_Parent->AddChild(this);
}
-void QmitkDataStorageTreeModel::SetShowHelperObjects(bool _ShowHelperObjects)
-{
- m_ShowHelperObjects = _ShowHelperObjects;
- this->UpdateNodeVisibility();
-}
-
-void QmitkDataStorageTreeModel::SetShowNodesContainingNoData(bool _ShowNodesContainingNoData)
-{
- m_ShowNodesContainingNoData = _ShowNodesContainingNoData;
- this->UpdateNodeVisibility();
-}
-
-void QmitkDataStorageTreeModel::UpdateNodeVisibility()
-{
- mitk::NodePredicateData::Pointer dataIsNull = mitk::NodePredicateData::New(0);
- mitk::NodePredicateNot::Pointer dataIsNotNull = mitk::NodePredicateNot::New(dataIsNull);// Show only nodes that really contain dat
-
- if (m_ShowHelperObjects)
- {
- if (m_ShowNodesContainingNoData)
- {
- // Show every node
- m_Predicate = mitk::NodePredicateOr::New(dataIsNull, dataIsNotNull);
- }
- else
- {
- // Show helper objects but not nodes containing no data
- m_Predicate = dataIsNotNull;
- }
- }
- else
- {
- mitk::NodePredicateProperty::Pointer isHelperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true));
- mitk::NodePredicateNot::Pointer isNotHelperObject = mitk::NodePredicateNot::New(isHelperObject);// Show only nodes that are not helper objects
- if (m_ShowNodesContainingNoData)
- {
- // Don't show helper objects but nodes containing no data
- m_Predicate = isNotHelperObject;
- }
- else
- {
- // Don't show helper objects and nodes containing no data
- m_Predicate = mitk::NodePredicateAnd::New(isNotHelperObject, dataIsNotNull);
- }
- }
- this->Update();
-}
-
void QmitkDataStorageTreeModel::Update()
{
- if (m_DataStorage.IsNotNull())
- {
- this->reset();
-
- mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate);
-
- for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end(); it++)
+ if (m_DataStorage.IsNotNull())
{
- // save node
- this->AddNodeInternal(*it);
- }
+ this->reset();
- mitk::DataStorage::SetOfObjects::ConstPointer _NotNodeSet = m_DataStorage->GetSubset(mitk::NodePredicateNot::New(m_Predicate));
+ mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetAll();
- for(mitk::DataStorage::SetOfObjects::const_iterator it=_NotNodeSet->begin(); it!=_NotNodeSet->end(); it++)
- {
- // remove node
- this->RemoveNodeInternal(*it);
+ for (mitk::DataStorage::SetOfObjects::const_iterator it = _NodeSet->begin(); it != _NodeSet->end(); it++)
+ {
+ // save node
+ this->AddNodeInternal(*it);
+ }
}
-
- }
}
-
diff --git a/Modules/QtWidgets/QmitkDataStorageTreeModel.h b/Modules/QtWidgets/QmitkDataStorageTreeModel.h
index 4badf8601c..6e780d8a1d 100644
--- a/Modules/QtWidgets/QmitkDataStorageTreeModel.h
+++ b/Modules/QtWidgets/QmitkDataStorageTreeModel.h
@@ -1,293 +1,261 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKDATASTORAGETREEMODEL_H_
#define QMITKDATASTORAGETREEMODEL_H_
#include <MitkQtWidgetsExports.h>
#include <mitkDataStorage.h>
#include <mitkNodePredicateBase.h>
#include <mitkWeakPointer.h>
#include <QAbstractListModel>
#include "QmitkEnums.h"
#include "QmitkCustomVariants.h"
#include <vector>
#include <string>
#include <QList>
/// \ingroup QmitkModule
class QMITK_EXPORT QmitkDataStorageTreeModel : public QAbstractItemModel
{
//# CONSTANTS,TYPEDEFS
public:
static const std::string COLUMN_NAME;
static const std::string COLUMN_TYPE;
static const std::string COLUMN_VISIBILITY;
//# CTORS,DTOR
public:
QmitkDataStorageTreeModel(mitk::DataStorage* _DataStorage
, bool _PlaceNewNodesOnTop=false
- , bool _ShowHelperObjects=false
- , bool _ShowNodesContainingNoData=false
, QObject* parent = 0);
~QmitkDataStorageTreeModel();
//# GETTER
public:
- typedef std::map<mitk::DataNode*, unsigned long> NodeTagMapType;
///
/// Get node at a specific model index.
/// This function is used to get a node from a QModelIndex
///
mitk::DataNode::Pointer GetNode(const QModelIndex &index) const;
///
/// Returns a copy of the node-vector that is shown by this model
///
virtual QList<mitk::DataNode::Pointer> GetNodeSet() const;
///
/// Get the DataStorage.
///
const mitk::DataStorage::Pointer GetDataStorage() const;
///
/// Get the top placement flag
///
bool GetPlaceNewNodesOnTopFlag()
{
return m_PlaceNewNodesOnTop;
}
- ///
- /// Get the helper object visibility flag
- ///
- bool GetShowHelperObjectsFlag()
- {
- return m_ShowHelperObjects;
- }
-
- ///
- /// Get the visibility flag for showing nodes that contain no data
- ///
- bool GetShowNodesContainingNoDataFlag()
- {
- return m_ShowNodesContainingNoData;
- }
-
///
/// Set the top placement flag
///
void SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop);
//# (Re-)implemented from QAbstractItemModel
//# Read model
Qt::ItemFlags flags(const QModelIndex& index) const;
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
//# hierarchical model
///
/// called whenever the model or the view needs to create a QModelIndex for a particular
/// child item (or a top-level item if parent is an invalid QModelIndex)
///
QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
QModelIndex parent ( const QModelIndex & index ) const;
//# editable model
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
Qt::DropActions supportedDropActions() const;
Qt::DropActions supportedDragActions() const;
QStringList mimeTypes() const;
QMimeData * mimeData(const QModelIndexList & indexes) const;
+ static QMimeData* mimeDataFromModelIndexList(const QModelIndexList& indexes);
+
//# End of QAbstractItemModel
//# SETTER
public:
///
/// Sets the DataStorage. The whole model will be resetted.
///
void SetDataStorage(mitk::DataStorage* _DataStorage);
///
/// Notify that the DataStorage was deleted. The whole model will be resetted.
///
void SetDataStorageDeleted(const itk::Object* _DataStorage);
///
/// Adds a node to this model.
/// If a predicate is set (not null) the node will be checked against it.The node has to have a data object (no one wants to see empty nodes).
///
virtual void AddNode(const mitk::DataNode* node);
///
/// Removes a node from this model. Also removes any event listener from the node.
///
virtual void RemoveNode(const mitk::DataNode* node);
///
/// Sets a node to modfified. Called by the DataStorage
///
virtual void SetNodeModified(const mitk::DataNode* node);
///
/// \return an index for the given datatreenode in the tree. If the node is not found
///
QModelIndex GetIndex(const mitk::DataNode*) const;
- ///
- /// Show or hide helper objects
- ///
- void SetShowHelperObjects(bool _ShowHelperObjects);
-
- ///
- /// Show or hide objects that contain no data
- ///
- void SetShowNodesContainingNoData(bool _ShowNodesContainingNoData);
-
- ///
- /// Update the visibility of data nodes according to the preference settings
- ///
- void UpdateNodeVisibility();
-
//# MISC
protected:
///
/// Helper class to represent a tree structure of DataNodes
///
class TreeItem
{
public:
///
/// Constructs a new TreeItem with the given DataNode (must not be 0)
///
TreeItem(mitk::DataNode* _DataNode, TreeItem* _Parent=0);
///
/// Removes itself as child from its parent-> Does not delete its children
/// \sa Delete()
///
virtual ~TreeItem();
///
/// Find the index of an item
///
int IndexOfChild(const TreeItem* item) const;
///
/// \return The child at pos index or 0 if it not exists
///
TreeItem* GetChild(int index) const;
///
/// Find the TreeItem containing a special tree node (recursive tree function)
///
TreeItem* Find( const mitk::DataNode* _DataNode) const;
///
/// Get the amount of children
///
int GetChildCount() const;
///
/// \return the index of this node in its parent list
///
int GetIndex() const;
///
/// \return the parent of this tree item
///
TreeItem* GetParent() const;
///
/// Return the DataNode associated with this node
///
mitk::DataNode::Pointer GetDataNode() const;
///
/// Get all children as vector
///
std::vector<TreeItem*> GetChildren() const;
///
/// add another item as a child of this (only if not already in that list)
///
void AddChild( TreeItem* item);
///
/// remove another item as child from this
///
void RemoveChild( TreeItem* item);
///
/// inserts a child at the given position. if pos is not in range
/// the element is added at the end
///
void InsertChild( TreeItem* item, int index=-1 );
/// Sets the parent on the treeitem
void SetParent(TreeItem* _Parent);
///
/// Deletes the whole tree branch
///
void Delete();
protected:
TreeItem* m_Parent;
std::vector<TreeItem*> m_Children;
mitk::DataNode::Pointer m_DataNode;
};
+
+ QList<TreeItem*> ToTreeItemPtrList(const QMimeData* mimeData);
+ QList<TreeItem*> ToTreeItemPtrList(const QByteArray& ba);
+
///
/// Adjusts the LayerProperty according to the nodes position
///
void AdjustLayerProperty();
///
/// invoked after m_DataStorage or m_Predicate changed
///
TreeItem* TreeItemFromIndex(const QModelIndex &index) const;
///
/// Gives a ModelIndex for the Tree Item
///
QModelIndex IndexFromTreeItem(TreeItem*) const;
///
/// Returns the first element in the nodes sources list (if available) or 0
///
mitk::DataNode* GetParentNode(const mitk::DataNode* node) const;
///
/// Adds all Childs in parent to vec. Before a child is added the function is called recursively
///
void TreeToVector(TreeItem* parent, std::vector<TreeItem*>& vec) const;
///
/// Adds all Childs in parent to vec. Before a child is added the function is called recursively
///
void TreeToNodeSet(TreeItem* parent, QList<mitk::DataNode::Pointer> &vec) const;
///
- /// Update Tree Model according to predicates
+ /// Update Tree Model
///
void Update();
//# ATTRIBUTES
protected:
mitk::WeakPointer<mitk::DataStorage> m_DataStorage;
mitk::NodePredicateBase::Pointer m_Predicate;
bool m_PlaceNewNodesOnTop;
- bool m_ShowHelperObjects;
- bool m_ShowNodesContainingNoData;
TreeItem* m_Root;
- NodeTagMapType m_HelperObjectObserverTags;
-
private:
void AddNodeInternal(const mitk::DataNode*);
void RemoveNodeInternal(const mitk::DataNode*);
///
/// Checks if dicom properties patient name, study names and series name exists
///
bool DicomPropertiesExists(const mitk::DataNode&) const;
};
#endif /* QMITKDATASTORAGETREEMODEL_H_ */
diff --git a/Modules/QtWidgets/QmitkLineEditLevelWindowWidget.cpp b/Modules/QtWidgets/QmitkLineEditLevelWindowWidget.cpp
index c45d864e19..9795932318 100644
--- a/Modules/QtWidgets/QmitkLineEditLevelWindowWidget.cpp
+++ b/Modules/QtWidgets/QmitkLineEditLevelWindowWidget.cpp
@@ -1,164 +1,166 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkLineEditLevelWindowWidget.h"
#include "QmitkLevelWindowWidgetContextMenu.h"
#include <mitkRenderingManager.h>
#include <itkCommand.h>
#include <QValidator>
#include <QLayout>
#include <QLineEdit>
#include <limits>
using namespace std;
/**
* Constructor
*/
QmitkLineEditLevelWindowWidget::QmitkLineEditLevelWindowWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
m_Manager = mitk::LevelWindowManager::New();
itk::ReceptorMemberCommand<QmitkLineEditLevelWindowWidget>::Pointer command = itk::ReceptorMemberCommand<QmitkLineEditLevelWindowWidget>::New();
command->SetCallbackFunction(this, &QmitkLineEditLevelWindowWidget::OnPropertyModified);
m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command);
m_IsObserverTagSet = true;
m_Contextmenu = new QmitkLevelWindowWidgetContextMenu(this); // true);
QVBoxLayout* layout = new QVBoxLayout( this );
layout->setMargin(0);
layout->setSpacing(0);
m_LevelInput = new QLineEdit( this );
m_LevelInput->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred));
+ m_LevelInput->setToolTip("Edit this field to change the center of the levelwindow.");
//m_LevelInput->setFrameShape( QLineEdit::LineEditPanel );
//m_LevelInput->setFrameShadow( QLineEdit::Sunken );
m_WindowInput = new QLineEdit( this );
m_WindowInput->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred));
+ m_WindowInput->setToolTip("Edit this field to change the span of the levelwindow. This number describes the whole span around the center.");
//m_WindowInput->setFrameShape( QLineEdit::LineEditPanel );
//m_WindowInput->setFrameShadow( QLineEdit::Sunken );
layout->addWidget(m_LevelInput);
layout->addWidget(m_WindowInput);
// signals and slots connections
connect( m_LevelInput, SIGNAL(editingFinished()), this, SLOT( SetLevelValue() ) );
connect( m_WindowInput, SIGNAL(editingFinished()), this, SLOT( SetWindowValue() ) );
// Validator for both LineEdit-widgets, to limit the valid input-range to int.
//QValidator* validatorWindowInput = new QIntValidator(1, 20000000, this);
QValidator* validatorWindowInput = new QDoubleValidator(0, numeric_limits<double>::max(), 2, this);
m_WindowInput->setValidator(validatorWindowInput);
//QValidator* validatorLevelInput = new QIntValidator(-10000000, 10000000, this);
//QValidator* validatorLevelInput = new QDoubleValidator(numeric_limits<double>::min(), numeric_limits<double>::max(), 2, this);
//m_LevelInput->setValidator(validatorLevelInput);
this->hide();
}
QmitkLineEditLevelWindowWidget::~QmitkLineEditLevelWindowWidget()
{
if( m_IsObserverTagSet )
{
m_Manager->RemoveObserver(m_ObserverTag);
m_IsObserverTagSet = false;
}
}
void QmitkLineEditLevelWindowWidget::OnPropertyModified(const itk::EventObject& )
{
try
{
m_LevelWindow = m_Manager->GetLevelWindow();
//setValidator();
QString level;
level.setNum((int)(m_LevelWindow.GetLevel()));
m_LevelInput->setText(level);
QString window;
window.setNum((int)(m_LevelWindow.GetWindow()));
m_WindowInput->setText(window);
m_LevelInput->setEnabled(!m_LevelWindow.IsFixed());
m_WindowInput->setEnabled(!m_LevelWindow.IsFixed());
this->show();
}
catch(...)
{
try
{
this->hide();
}
catch(...)
{
}
}
}
void QmitkLineEditLevelWindowWidget::setLevelWindowManager(mitk::LevelWindowManager* levelWindowManager)
{
if( m_IsObserverTagSet )
{
m_Manager->RemoveObserver(m_ObserverTag);
m_IsObserverTagSet = false;
}
m_Manager = levelWindowManager;
if ( m_Manager.IsNotNull() )
{
itk::ReceptorMemberCommand<QmitkLineEditLevelWindowWidget>::Pointer command = itk::ReceptorMemberCommand<QmitkLineEditLevelWindowWidget>::New();
command->SetCallbackFunction(this, &QmitkLineEditLevelWindowWidget::OnPropertyModified);
m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command);
m_IsObserverTagSet = true;
}
}
void QmitkLineEditLevelWindowWidget::SetDataStorage( mitk::DataStorage* ds )
{
m_Manager->SetDataStorage(ds);
}
//read the levelInput and change level and slider when the button "ENTER" was pressed in the windowInput-LineEdit
void QmitkLineEditLevelWindowWidget::SetLevelValue()
{
double level = m_LevelInput->text().toDouble();
m_LevelWindow.SetLevelWindow(level, m_LevelWindow.GetWindow());
m_Manager->SetLevelWindow(m_LevelWindow);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
//read the windowInput and change window and slider when the button "ENTER" was pressed in the windowInput-LineEdit
void QmitkLineEditLevelWindowWidget::SetWindowValue()
{
double window = m_WindowInput->text().toDouble();
m_LevelWindow.SetLevelWindow(m_LevelWindow.GetLevel(), window);
m_Manager->SetLevelWindow(m_LevelWindow);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkLineEditLevelWindowWidget::contextMenuEvent( QContextMenuEvent * )
{
m_Contextmenu->setLevelWindowManager(m_Manager.GetPointer());
m_Contextmenu->getContextMenu();
}
mitk::LevelWindowManager* QmitkLineEditLevelWindowWidget::GetManager()
{
return m_Manager.GetPointer();
}
diff --git a/Modules/QtWidgets/QmitkMimeTypes.cpp b/Modules/QtWidgets/QmitkMimeTypes.cpp
new file mode 100644
index 0000000000..d216bc9139
--- /dev/null
+++ b/Modules/QtWidgets/QmitkMimeTypes.cpp
@@ -0,0 +1,44 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "QmitkMimeTypes.h"
+
+const QString QmitkMimeTypes::DataNodePtrs = "application/x-qmitk-datanode-ptrs";
+const QString QmitkMimeTypes::DataStorageTreeItemPtrs = "application/x-qmitk-datastorage-treeitem-ptrs";
+
+#include <iostream>
+
+QList<mitk::DataNode *> QmitkMimeTypes::ToDataNodePtrList(const QByteArray &ba)
+{
+ QDataStream ds(ba);
+ QList<mitk::DataNode*> result;
+ while(!ds.atEnd())
+ {
+ quintptr dataNodePtr;
+ ds >> dataNodePtr;
+ result.push_back(reinterpret_cast<mitk::DataNode*>(dataNodePtr));
+ }
+ return result;
+}
+
+QList<mitk::DataNode *> QmitkMimeTypes::ToDataNodePtrList(const QMimeData *mimeData)
+{
+ if (mimeData == NULL || !mimeData->hasFormat(QmitkMimeTypes::DataNodePtrs))
+ {
+ return QList<mitk::DataNode*>();
+ }
+ return ToDataNodePtrList(mimeData->data(QmitkMimeTypes::DataNodePtrs));
+}
diff --git a/Modules/QtWidgets/QmitkMimeTypes.h b/Modules/QtWidgets/QmitkMimeTypes.h
new file mode 100644
index 0000000000..87b9207ab8
--- /dev/null
+++ b/Modules/QtWidgets/QmitkMimeTypes.h
@@ -0,0 +1,46 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef QMITKMIMETYPES_H
+#define QMITKMIMETYPES_H
+
+#include <MitkQtWidgetsExports.h>
+
+#include <QString>
+#include <QMimeData>
+#include <QByteArray>
+#include <QList>
+
+namespace mitk {
+class DataNode;
+}
+
+/**
+ * @brief The QmitkMimeTypes class prov
+ */
+class QMITK_EXPORT QmitkMimeTypes
+{
+public:
+
+ static const QString DataNodePtrs; // = "application/x-qmitk-datanode-ptrs";
+ static const QString DataStorageTreeItemPtrs; // = "application/x-qmitk-datastorage-treeitem-ptrs";
+
+ static QList<mitk::DataNode*> ToDataNodePtrList(const QByteArray& ba);
+
+ static QList<mitk::DataNode*> ToDataNodePtrList(const QMimeData *mimeData);
+};
+
+#endif // QMITKMIMETYPES_H
diff --git a/Modules/QtWidgets/QmitkRenderWindow.cpp b/Modules/QtWidgets/QmitkRenderWindow.cpp
index 710b1a176c..b7190d6db5 100644
--- a/Modules/QtWidgets/QmitkRenderWindow.cpp
+++ b/Modules/QtWidgets/QmitkRenderWindow.cpp
@@ -1,551 +1,542 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkRenderWindow.h"
#include <QCursor>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QKeyEvent>
#include <QResizeEvent>
#include <QTimer>
#include <QDragEnterEvent>
#include <QDropEvent>
#include "QmitkEventAdapter.h" // TODO: INTERACTION_LEGACY
#include "mitkMousePressEvent.h"
#include "mitkMouseMoveEvent.h"
#include "mitkMouseDoubleClickEvent.h"
#include "mitkMouseReleaseEvent.h"
#include "mitkInteractionKeyEvent.h"
#include "mitkMouseWheelEvent.h"
#include "mitkInternalEvent.h"
#include "QmitkRenderWindowMenu.h"
+#include "QmitkMimeTypes.h"
QmitkRenderWindow::QmitkRenderWindow(QWidget *parent,
QString name,
mitk::VtkPropRenderer* /*renderer*/,
mitk::RenderingManager* renderingManager,mitk::BaseRenderer::RenderingMode::Type renderingMode) :
QVTKWidget(parent), m_ResendQtEvents(true), m_MenuWidget(NULL), m_MenuWidgetActivated(false), m_LayoutIndex(0)
{
if(renderingMode == mitk::BaseRenderer::RenderingMode::DepthPeeling)
{
GetRenderWindow()->SetMultiSamples(0);
GetRenderWindow()->SetAlphaBitPlanes(1);
}
else if(renderingMode == mitk::BaseRenderer::RenderingMode::MultiSampling)
{
GetRenderWindow()->SetMultiSamples(8);
}
else if(renderingMode == mitk::BaseRenderer::RenderingMode::Standard)
{
GetRenderWindow()->SetMultiSamples(0);
}
Initialize(renderingManager, name.toStdString().c_str(),renderingMode); // Initialize mitkRenderWindowBase
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);
}
QmitkRenderWindow::~QmitkRenderWindow()
{
Destroy(); // Destroy mitkRenderWindowBase
}
void QmitkRenderWindow::SetResendQtEvents(bool resend)
{
m_ResendQtEvents = resend;
}
void QmitkRenderWindow::SetLayoutIndex(unsigned int layoutIndex)
{
m_LayoutIndex = layoutIndex;
if (m_MenuWidget)
m_MenuWidget->SetLayoutIndex(layoutIndex);
}
unsigned int QmitkRenderWindow::GetLayoutIndex()
{
if (m_MenuWidget)
return m_MenuWidget->GetLayoutIndex();
else
return 0;
}
void QmitkRenderWindow::LayoutDesignListChanged(int layoutDesignIndex)
{
if (m_MenuWidget)
m_MenuWidget->UpdateLayoutDesignList(layoutDesignIndex);
}
void QmitkRenderWindow::mousePressEvent(QMouseEvent *me)
{
mitk::Point2D displayPos = GetMousePosition(me);
mitk::Point3D worldPos = m_Renderer->Map2DRendererPositionTo3DWorldPosition(GetMousePosition(me));
mitk::MousePressEvent::Pointer mPressEvent = mitk::MousePressEvent::New(m_Renderer,
displayPos,
worldPos,
GetButtonState(me),
GetModifiers(me), GetEventButton(me));
if (!this->HandleEvent(mPressEvent.GetPointer()))
{ // TODO: INTERACTION_LEGACY
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(m_Renderer, me));
this->mousePressMitkEvent(&myevent);
QVTKWidget::mousePressEvent(me);
}
if (m_ResendQtEvents)
me->ignore();
}
void QmitkRenderWindow::mouseDoubleClickEvent( QMouseEvent *me )
{
mitk::Point2D displayPos = GetMousePosition(me);
mitk::Point3D worldPos = m_Renderer->Map2DRendererPositionTo3DWorldPosition(GetMousePosition(me));
mitk::MouseDoubleClickEvent::Pointer mPressEvent = mitk::MouseDoubleClickEvent::New(m_Renderer,displayPos, worldPos, GetButtonState(me),
GetModifiers(me), GetEventButton(me));
if (!this->HandleEvent(mPressEvent.GetPointer()))
{ // TODO: INTERACTION_LEGACY
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(m_Renderer, me));
this->mousePressMitkEvent(&myevent);
QVTKWidget::mousePressEvent(me);
}
if (m_ResendQtEvents)
me->ignore();
}
void QmitkRenderWindow::mouseReleaseEvent(QMouseEvent *me)
{
mitk::Point2D displayPos = GetMousePosition(me);
mitk::Point3D worldPos = m_Renderer->Map2DRendererPositionTo3DWorldPosition(GetMousePosition(me));
mitk::MouseReleaseEvent::Pointer mReleaseEvent = mitk::MouseReleaseEvent::New(m_Renderer, displayPos,worldPos, GetButtonState(me),
GetModifiers(me), GetEventButton(me));
if (!this->HandleEvent(mReleaseEvent.GetPointer()))
{ // TODO: INTERACTION_LEGACY
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(m_Renderer, me));
this->mouseReleaseMitkEvent(&myevent);
QVTKWidget::mouseReleaseEvent(me);
}
if (m_ResendQtEvents)
me->ignore();
}
void QmitkRenderWindow::mouseMoveEvent(QMouseEvent *me)
{
mitk::Point2D displayPos = GetMousePosition(me);
mitk::Point3D worldPos = m_Renderer->Map2DRendererPositionTo3DWorldPosition(GetMousePosition(me));
this->AdjustRenderWindowMenuVisibility(me->pos());
mitk::MouseMoveEvent::Pointer mMoveEvent = mitk::MouseMoveEvent::New(m_Renderer, displayPos, worldPos, GetButtonState(me),
GetModifiers(me));
if (!this->HandleEvent(mMoveEvent.GetPointer()))
{ // TODO: INTERACTION_LEGACY
mitk::MouseEvent myevent(QmitkEventAdapter::AdaptMouseEvent(m_Renderer, me));
this->mouseMoveMitkEvent(&myevent);
QVTKWidget::mouseMoveEvent(me);
}
}
void QmitkRenderWindow::wheelEvent(QWheelEvent *we)
{
mitk::Point2D displayPos = GetMousePosition(we);
mitk::Point3D worldPos = m_Renderer->Map2DRendererPositionTo3DWorldPosition(GetMousePosition(we));
mitk::MouseWheelEvent::Pointer mWheelEvent = mitk::MouseWheelEvent::New(m_Renderer, displayPos,worldPos, GetButtonState(we),
GetModifiers(we), GetDelta(we));
if (!this->HandleEvent(mWheelEvent.GetPointer()))
{ // TODO: INTERACTION_LEGACY
mitk::WheelEvent myevent(QmitkEventAdapter::AdaptWheelEvent(m_Renderer, we));
this->wheelMitkEvent(&myevent);
QVTKWidget::wheelEvent(we);
}
if (m_ResendQtEvents)
we->ignore();
}
void QmitkRenderWindow::keyPressEvent(QKeyEvent *ke)
{
mitk::InteractionEvent::ModifierKeys modifiers = GetModifiers(ke);
std::string key = GetKeyLetter(ke);
mitk::InteractionKeyEvent::Pointer keyEvent = mitk::InteractionKeyEvent::New(m_Renderer, key, modifiers);
if (!this->HandleEvent(keyEvent.GetPointer()))
{ // TODO: INTERACTION_LEGACY
QPoint cp = mapFromGlobal(QCursor::pos());
mitk::KeyEvent mke(QmitkEventAdapter::AdaptKeyEvent(m_Renderer, ke, cp));
this->keyPressMitkEvent(&mke);
ke->accept();
QVTKWidget::keyPressEvent(ke);
}
if (m_ResendQtEvents)
ke->ignore();
}
void QmitkRenderWindow::enterEvent(QEvent *e)
{
// TODO implement new event
QVTKWidget::enterEvent(e);
}
void QmitkRenderWindow::DeferredHideMenu()
{
MITK_DEBUG << "QmitkRenderWindow::DeferredHideMenu";
if (m_MenuWidget)
m_MenuWidget->HideMenu();
}
void QmitkRenderWindow::leaveEvent(QEvent *e)
{
mitk::InternalEvent::Pointer internalEvent = mitk::InternalEvent::New(this->m_Renderer, NULL, "LeaveRenderWindow");
if (!this->HandleEvent(internalEvent.GetPointer()))
if (m_MenuWidget)
m_MenuWidget->smoothHide();
QVTKWidget::leaveEvent(e);
}
void QmitkRenderWindow::paintEvent(QPaintEvent* /*event*/)
{
//We are using our own interaction and thus have to call the rendering manually.
this->GetRenderer()->GetRenderingManager()->RequestUpdate(GetRenderWindow());
}
void QmitkRenderWindow::resizeEvent(QResizeEvent* event)
{
this->resizeMitkEvent(event->size().width(), event->size().height());
QVTKWidget::resizeEvent(event);
emit resized();
}
void QmitkRenderWindow::moveEvent(QMoveEvent* event)
{
QVTKWidget::moveEvent(event);
// after a move the overlays need to be positioned
emit moved();
}
void QmitkRenderWindow::showEvent(QShowEvent* event)
{
QVTKWidget::showEvent(event);
// this singleshot is necessary to have the overlays positioned correctly after initial show
// simple call of moved() is no use here!!
QTimer::singleShot(0, this, SIGNAL( moved() ));
}
void QmitkRenderWindow::ActivateMenuWidget(bool state, QmitkStdMultiWidget* stdMultiWidget)
{
m_MenuWidgetActivated = state;
if (!m_MenuWidgetActivated && m_MenuWidget)
{
//disconnect Signal/Slot Connection
disconnect(m_MenuWidget, SIGNAL( SignalChangeLayoutDesign(int) ), this, SLOT(OnChangeLayoutDesign(int)));
disconnect(m_MenuWidget, SIGNAL( ResetView() ), this, SIGNAL( ResetView()));
disconnect(m_MenuWidget, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SIGNAL( ChangeCrosshairRotationMode(int)));
delete m_MenuWidget;
m_MenuWidget = 0;
}
else if (m_MenuWidgetActivated && !m_MenuWidget)
{
//create render window MenuBar for split, close Window or set new setting.
m_MenuWidget = new QmitkRenderWindowMenu(this, 0, m_Renderer, stdMultiWidget);
m_MenuWidget->SetLayoutIndex(m_LayoutIndex);
//create Signal/Slot Connection
connect(m_MenuWidget, SIGNAL( SignalChangeLayoutDesign(int) ), this, SLOT(OnChangeLayoutDesign(int)));
connect(m_MenuWidget, SIGNAL( ResetView() ), this, SIGNAL( ResetView()));
connect(m_MenuWidget, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SIGNAL( ChangeCrosshairRotationMode(int)));
}
}
void QmitkRenderWindow::AdjustRenderWindowMenuVisibility(const QPoint& /*pos*/)
{
if (m_MenuWidget)
{
m_MenuWidget->ShowMenu();
m_MenuWidget->MoveWidgetToCorrectPos(1.0f);
}
}
void QmitkRenderWindow::HideRenderWindowMenu()
{
// DEPRECATED METHOD
}
void QmitkRenderWindow::OnChangeLayoutDesign(int layoutDesignIndex)
{
emit SignalLayoutDesignChanged(layoutDesignIndex);
}
void QmitkRenderWindow::OnWidgetPlaneModeChanged(int mode)
{
if (m_MenuWidget)
m_MenuWidget->NotifyNewWidgetPlanesMode(mode);
}
void QmitkRenderWindow::FullScreenMode(bool state)
{
if (m_MenuWidget)
m_MenuWidget->ChangeFullScreenMode(state);
}
void QmitkRenderWindow::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("application/x-mitk-datanodes"))
{
event->accept();
}
}
void QmitkRenderWindow::dropEvent(QDropEvent * event)
{
- if (event->mimeData()->hasFormat("application/x-mitk-datanodes"))
+ QList<mitk::DataNode*> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(event->mimeData());
+ if (!dataNodeList.empty())
{
- QString arg = QString(event->mimeData()->data("application/x-mitk-datanodes").data());
- QStringList listOfDataNodes = arg.split(",");
- std::vector<mitk::DataNode*> vectorOfDataNodePointers;
-
- for (int i = 0; i < listOfDataNodes.size(); i++)
- {
- long val = listOfDataNodes[i].toLong();
- mitk::DataNode* node = static_cast<mitk::DataNode *>((void*) val);
- vectorOfDataNodePointers.push_back(node);
- }
-
- emit NodesDropped(this, vectorOfDataNodePointers);
+ emit NodesDropped(this, dataNodeList.toVector().toStdVector());
}
}
mitk::Point2D QmitkRenderWindow::GetMousePosition(QMouseEvent* me) const
{
mitk::Point2D point;
point[0] = me->x();
point[1] = me->y();
m_Renderer->GetDisplayGeometry()->ULDisplayToDisplay(point, point);
return point;
}
mitk::Point2D QmitkRenderWindow::GetMousePosition(QWheelEvent* we) const
{
mitk::Point2D point;
point[0] = we->x();
point[1] = we->y();
m_Renderer->GetDisplayGeometry()->ULDisplayToDisplay(point, point);
return point;
}
mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetEventButton(QMouseEvent* me) const
{
mitk::InteractionEvent::MouseButtons eventButton;
switch (me->button())
{
case Qt::LeftButton:
eventButton = mitk::InteractionEvent::LeftMouseButton;
break;
case Qt::RightButton:
eventButton = mitk::InteractionEvent::RightMouseButton;
break;
case Qt::MidButton:
eventButton = mitk::InteractionEvent::MiddleMouseButton;
break;
default:
eventButton = mitk::InteractionEvent::NoButton;
break;
}
return eventButton;
}
mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QMouseEvent* me) const
{
mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton;
if (me->buttons() & Qt::LeftButton)
{
buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton;
}
if (me->buttons() & Qt::RightButton)
{
buttonState = buttonState | mitk::InteractionEvent::RightMouseButton;
}
if (me->buttons() & Qt::MidButton)
{
buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton;
}
return buttonState;
}
mitk::InteractionEvent::ModifierKeys QmitkRenderWindow::GetModifiers(QInputEvent* me) const
{
mitk::InteractionEvent::ModifierKeys modifiers = mitk::InteractionEvent::NoKey;
if (me->modifiers() & Qt::ALT)
{
modifiers = modifiers | mitk::InteractionEvent::AltKey;
}
if (me->modifiers() & Qt::CTRL)
{
modifiers = modifiers | mitk::InteractionEvent::ControlKey;
}
if (me->modifiers() & Qt::SHIFT)
{
modifiers = modifiers | mitk::InteractionEvent::ShiftKey;
}
return modifiers;
}
mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QWheelEvent* we) const
{
mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton;
if (we->buttons() & Qt::LeftButton)
{
buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton;
}
if (we->buttons() & Qt::RightButton)
{
buttonState = buttonState | mitk::InteractionEvent::RightMouseButton;
}
if (we->buttons() & Qt::MidButton)
{
buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton;
}
return buttonState;
}
std::string QmitkRenderWindow::GetKeyLetter(QKeyEvent *ke) const
{
// Converting Qt Key Event to string element.
std::string key = "";
int tkey = ke->key();
if (tkey < 128)
{ //standard ascii letter
key = (char) toupper(tkey);
}
else
{ // special keys
switch (tkey)
{
case Qt::Key_Return:
key = mitk::InteractionEvent::KeyReturn;
break;
case Qt::Key_Enter:
key = mitk::InteractionEvent::KeyEnter;
break;
case Qt::Key_Escape:
key = mitk::InteractionEvent::KeyEnter;
break;
case Qt::Key_Delete:
key = mitk::InteractionEvent::KeyDelete;
break;
case Qt::Key_Up:
key = mitk::InteractionEvent::KeyArrowUp;
break;
case Qt::Key_Down:
key = mitk::InteractionEvent::KeyArrowDown;
break;
case Qt::Key_Left:
key = mitk::InteractionEvent::KeyArrowLeft;
break;
case Qt::Key_Right:
key = mitk::InteractionEvent::KeyArrowRight;
break;
case Qt::Key_F1:
key = mitk::InteractionEvent::KeyF1;
break;
case Qt::Key_F2:
key = mitk::InteractionEvent::KeyF2;
break;
case Qt::Key_F3:
key = mitk::InteractionEvent::KeyF3;
break;
case Qt::Key_F4:
key = mitk::InteractionEvent::KeyF4;
break;
case Qt::Key_F5:
key = mitk::InteractionEvent::KeyF5;
break;
case Qt::Key_F6:
key = mitk::InteractionEvent::KeyF6;
break;
case Qt::Key_F7:
key = mitk::InteractionEvent::KeyF7;
break;
case Qt::Key_F8:
key = mitk::InteractionEvent::KeyF8;
break;
case Qt::Key_F9:
key = mitk::InteractionEvent::KeyF9;
break;
case Qt::Key_F10:
key = mitk::InteractionEvent::KeyF10;
break;
case Qt::Key_F11:
key = mitk::InteractionEvent::KeyF11;
break;
case Qt::Key_F12:
key = mitk::InteractionEvent::KeyF12;
break;
case Qt::Key_End:
key = mitk::InteractionEvent::KeyEnd;
break;
case Qt::Key_Home:
key = mitk::InteractionEvent::KeyPos1;
break;
case Qt::Key_Insert:
key = mitk::InteractionEvent::KeyInsert;
break;
case Qt::Key_PageDown:
key = mitk::InteractionEvent::KeyPageDown;
break;
case Qt::Key_PageUp:
key = mitk::InteractionEvent::KeyPageUp;
break;
case Qt::Key_Space:
key = mitk::InteractionEvent::KeySpace;
break;
}
}
return key;
}
int QmitkRenderWindow::GetDelta(QWheelEvent* we) const
{
return we->delta();
-}
\ No newline at end of file
+}
diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.cpp b/Modules/QtWidgets/QmitkStdMultiWidget.cpp
index ba05240253..da95b1a399 100644
--- a/Modules/QtWidgets/QmitkStdMultiWidget.cpp
+++ b/Modules/QtWidgets/QmitkStdMultiWidget.cpp
@@ -1,2212 +1,2199 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#define SMW_INFO MITK_INFO("widget.stdmulti")
#include "QmitkStdMultiWidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <qsplitter.h>
#include <QMotifStyle>
#include <QList>
#include <QMouseEvent>
#include <QTimer>
#include "mitkProperties.h"
#include "mitkPlaneGeometryDataMapper2D.h"
#include "mitkGlobalInteraction.h"
#include "mitkDisplayInteractor.h"
#include "mitkPointSet.h"
#include "mitkPositionEvent.h"
#include "mitkStateEvent.h"
#include "mitkLine.h"
#include "mitkInteractionConst.h"
#include "mitkDataStorage.h"
#include "mitkOverlayManager.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateProperty.h"
#include "mitkStatusBar.h"
#include "mitkImage.h"
#include "mitkVtkLayerController.h"
#include <iomanip>
QmitkStdMultiWidget::QmitkStdMultiWidget(QWidget* parent, Qt::WindowFlags f, mitk::RenderingManager* renderingManager, mitk::BaseRenderer::RenderingMode::Type renderingMode, const QString& name)
: QWidget(parent, f),
mitkWidget1(NULL),
mitkWidget2(NULL),
mitkWidget3(NULL),
mitkWidget4(NULL),
levelWindowWidget(NULL),
QmitkStdMultiWidgetLayout(NULL),
m_Layout(LAYOUT_DEFAULT),
m_PlaneMode(PLANE_MODE_SLICING),
m_RenderingManager(renderingManager),
m_GradientBackgroundFlag(true),
m_TimeNavigationController(NULL),
m_MainSplit(NULL),
m_LayoutSplit(NULL),
m_SubSplit1(NULL),
m_SubSplit2(NULL),
mitkWidget1Container(NULL),
mitkWidget2Container(NULL),
mitkWidget3Container(NULL),
mitkWidget4Container(NULL),
m_PendingCrosshairPositionEvent(false),
m_CrosshairNavigationEnabled(false)
{
/******************************************************
* Use the global RenderingManager if none was specified
* ****************************************************/
if (m_RenderingManager == NULL)
{
m_RenderingManager = mitk::RenderingManager::GetInstance();
}
m_TimeNavigationController = m_RenderingManager->GetTimeNavigationController();
/*******************************/
//Create Widget manually
/*******************************/
//create Layouts
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
QmitkStdMultiWidgetLayout->setContentsMargins(0,0,0,0);
//Set Layout to widget
this->setLayout(QmitkStdMultiWidgetLayout);
// QmitkNavigationToolBar* toolBar = new QmitkNavigationToolBar();
// QmitkStdMultiWidgetLayout->addWidget( toolBar );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//creae Widget Container
mitkWidget1Container = new QWidget(m_SubSplit1);
mitkWidget2Container = new QWidget(m_SubSplit1);
mitkWidget3Container = new QWidget(m_SubSplit2);
mitkWidget4Container = new QWidget(m_SubSplit2);
mitkWidget1Container->setContentsMargins(0,0,0,0);
mitkWidget2Container->setContentsMargins(0,0,0,0);
mitkWidget3Container->setContentsMargins(0,0,0,0);
mitkWidget4Container->setContentsMargins(0,0,0,0);
//create Widget Layout
QHBoxLayout *mitkWidgetLayout1 = new QHBoxLayout(mitkWidget1Container);
QHBoxLayout *mitkWidgetLayout2 = new QHBoxLayout(mitkWidget2Container);
QHBoxLayout *mitkWidgetLayout3 = new QHBoxLayout(mitkWidget3Container);
QHBoxLayout *mitkWidgetLayout4 = new QHBoxLayout(mitkWidget4Container);
mitkWidgetLayout1->setMargin(0);
mitkWidgetLayout2->setMargin(0);
mitkWidgetLayout3->setMargin(0);
mitkWidgetLayout4->setMargin(0);
//set Layout to Widget Container
mitkWidget1Container->setLayout(mitkWidgetLayout1);
mitkWidget2Container->setLayout(mitkWidgetLayout2);
mitkWidget3Container->setLayout(mitkWidgetLayout3);
mitkWidget4Container->setLayout(mitkWidgetLayout4);
//set SizePolicy
mitkWidget1Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mitkWidget2Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mitkWidget3Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mitkWidget4Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
//insert Widget Container into the splitters
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget3Container );
m_SubSplit2->addWidget( mitkWidget4Container );
// m_RenderingManager->SetGlobalInteraction( mitk::GlobalInteraction::GetInstance() );
//Create RenderWindows 1
mitkWidget1 = new QmitkRenderWindow(mitkWidget1Container, name + ".widget1", NULL, m_RenderingManager,renderingMode);
mitkWidget1->setMaximumSize(2000,2000);
mitkWidget1->SetLayoutIndex( AXIAL );
mitkWidgetLayout1->addWidget(mitkWidget1);
//Create RenderWindows 2
mitkWidget2 = new QmitkRenderWindow(mitkWidget2Container, name + ".widget2", NULL, m_RenderingManager,renderingMode);
mitkWidget2->setMaximumSize(2000,2000);
mitkWidget2->setEnabled( TRUE );
mitkWidget2->SetLayoutIndex( SAGITTAL );
mitkWidgetLayout2->addWidget(mitkWidget2);
//Create RenderWindows 3
mitkWidget3 = new QmitkRenderWindow(mitkWidget3Container, name + ".widget3", NULL, m_RenderingManager,renderingMode);
mitkWidget3->setMaximumSize(2000,2000);
mitkWidget3->SetLayoutIndex( CORONAL );
mitkWidgetLayout3->addWidget(mitkWidget3);
//Create RenderWindows 4
mitkWidget4 = new QmitkRenderWindow(mitkWidget4Container, name + ".widget4", NULL, m_RenderingManager,renderingMode);
mitkWidget4->setMaximumSize(2000,2000);
mitkWidget4->SetLayoutIndex( THREE_D );
mitkWidgetLayout4->addWidget(mitkWidget4);
//create SignalSlot Connection
connect( mitkWidget1, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget1, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget1, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget1, SLOT(OnWidgetPlaneModeChanged(int)) );
connect( mitkWidget2, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget2, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget2, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget2, SLOT(OnWidgetPlaneModeChanged(int)) );
connect( mitkWidget3, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget3, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget3, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget3, SLOT(OnWidgetPlaneModeChanged(int)) );
connect( mitkWidget4, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget4, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget4, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget4, SLOT(OnWidgetPlaneModeChanged(int)) );
//Create Level Window Widget
levelWindowWidget = new QmitkLevelWindowWidget( m_MainSplit ); //this
levelWindowWidget->setObjectName(QString::fromUtf8("levelWindowWidget"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(levelWindowWidget->sizePolicy().hasHeightForWidth());
levelWindowWidget->setSizePolicy(sizePolicy);
levelWindowWidget->setMaximumSize(QSize(50, 2000));
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//resize Image.
this->resize( QSize(364, 477).expandedTo(minimumSizeHint()) );
//Initialize the widgets.
this->InitializeWidget();
//Activate Widget Menu
this->ActivateMenuWidget( true );
}
void QmitkStdMultiWidget::InitializeWidget()
{
m_PositionTracker = NULL;
// transfer colors in WorldGeometry-Nodes of the associated Renderer
QColor qcolor;
//float color[3] = {1.0f,1.0f,1.0f};
mitk::DataNode::Pointer planeNode;
mitk::IntProperty::Pointer layer;
// of widget 1
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(1.0,0.0,0.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
// ... of widget 2
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(0.0,1.0,0.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
// ... of widget 3
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(0.0,0.0,1.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
// ... of widget 4
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(1.0,1.0,0.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
mitk::OverlayManager::Pointer OverlayManager = mitk::OverlayManager::New();
mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetMapperID(mitk::BaseRenderer::Standard3D);
// Set plane mode (slicing/rotation behavior) to slicing (default)
m_PlaneMode = PLANE_MODE_SLICING;
// Set default view directions for SNCs
mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Axial );
mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Sagittal );
mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Frontal );
mitkWidget4->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Original );
/*************************************************/
//Write Layout Names into the viewers -- hardCoded
//Info for later:
//int view = this->GetRenderWindow1()->GetSliceNavigationController()->GetDefaultViewDirection();
//QString layoutName;
//if( view == mitk::SliceNavigationController::Axial )
// layoutName = "Axial";
//else if( view == mitk::SliceNavigationController::Sagittal )
// layoutName = "Sagittal";
//else if( view == mitk::SliceNavigationController::Frontal )
// layoutName = "Coronal";
//else if( view == mitk::SliceNavigationController::Original )
// layoutName = "Original";
//if( view >= 0 && view < 4 )
// //write LayoutName --> Viewer 3D shoudn't write the layoutName.
//Render Window 1 == axial
m_CornerAnnotaions[0].cornerText = vtkCornerAnnotation::New();
m_CornerAnnotaions[0].cornerText->SetText(0, "Axial");
m_CornerAnnotaions[0].cornerText->SetMaximumFontSize(12);
m_CornerAnnotaions[0].textProp = vtkTextProperty::New();
m_CornerAnnotaions[0].textProp->SetColor( 1.0, 0.0, 0.0 );
m_CornerAnnotaions[0].cornerText->SetTextProperty( m_CornerAnnotaions[0].textProp );
m_CornerAnnotaions[0].ren = vtkRenderer::New();
m_CornerAnnotaions[0].ren->AddActor(m_CornerAnnotaions[0].cornerText);
m_CornerAnnotaions[0].ren->InteractiveOff();
mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[0].ren,true);
//Render Window 2 == sagittal
m_CornerAnnotaions[1].cornerText = vtkCornerAnnotation::New();
m_CornerAnnotaions[1].cornerText->SetText(0, "Sagittal");
m_CornerAnnotaions[1].cornerText->SetMaximumFontSize(12);
m_CornerAnnotaions[1].textProp = vtkTextProperty::New();
m_CornerAnnotaions[1].textProp->SetColor( 0.0, 1.0, 0.0 );
m_CornerAnnotaions[1].cornerText->SetTextProperty( m_CornerAnnotaions[1].textProp );
m_CornerAnnotaions[1].ren = vtkRenderer::New();
m_CornerAnnotaions[1].ren->AddActor(m_CornerAnnotaions[1].cornerText);
m_CornerAnnotaions[1].ren->InteractiveOff();
mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[1].ren,true);
//Render Window 3 == coronal
m_CornerAnnotaions[2].cornerText = vtkCornerAnnotation::New();
m_CornerAnnotaions[2].cornerText->SetText(0, "Coronal");
m_CornerAnnotaions[2].cornerText->SetMaximumFontSize(12);
m_CornerAnnotaions[2].textProp = vtkTextProperty::New();
m_CornerAnnotaions[2].textProp->SetColor( 0.295, 0.295, 1.0 );
m_CornerAnnotaions[2].cornerText->SetTextProperty( m_CornerAnnotaions[2].textProp );
m_CornerAnnotaions[2].ren = vtkRenderer::New();
m_CornerAnnotaions[2].ren->AddActor(m_CornerAnnotaions[2].cornerText);
m_CornerAnnotaions[2].ren->InteractiveOff();
mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[2].ren,true);
/*************************************************/
// create a slice rotator
// m_SlicesRotator = mitk::SlicesRotator::New();
// @TODO next line causes sure memory leak
// rotator will be created nonetheless (will be switched on and off)
m_SlicesRotator = mitk::SlicesRotator::New("slices-rotator");
m_SlicesRotator->AddSliceController(
mitkWidget1->GetSliceNavigationController() );
m_SlicesRotator->AddSliceController(
mitkWidget2->GetSliceNavigationController() );
m_SlicesRotator->AddSliceController(
mitkWidget3->GetSliceNavigationController() );
// create a slice swiveller (using the same state-machine as SlicesRotator)
m_SlicesSwiveller = mitk::SlicesSwiveller::New("slices-rotator");
m_SlicesSwiveller->AddSliceController(
mitkWidget1->GetSliceNavigationController() );
m_SlicesSwiveller->AddSliceController(
mitkWidget2->GetSliceNavigationController() );
m_SlicesSwiveller->AddSliceController(
mitkWidget3->GetSliceNavigationController() );
//connect to the "time navigation controller": send time via sliceNavigationControllers
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget1->GetSliceNavigationController() , false);
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget2->GetSliceNavigationController() , false);
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget3->GetSliceNavigationController() , false);
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget4->GetSliceNavigationController() , false);
mitkWidget1->GetSliceNavigationController()
->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
//reverse connection between sliceNavigationControllers and m_TimeNavigationController
mitkWidget1->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
mitkWidget2->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
mitkWidget3->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
mitkWidget4->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
m_MouseModeSwitcher = mitk::MouseModeSwitcher::New();
m_LastLeftClickPositionSupplier =
mitk::CoordinateSupplier::New("navigation", NULL);
mitk::GlobalInteraction::GetInstance()->AddListener(
m_LastLeftClickPositionSupplier
);
// setup gradient background
m_GradientBackground1 = mitk::GradientBackground::New();
m_GradientBackground1->SetRenderWindow(
mitkWidget1->GetRenderWindow() );
m_GradientBackground1->Disable();
m_GradientBackground2 = mitk::GradientBackground::New();
m_GradientBackground2->SetRenderWindow(
mitkWidget2->GetRenderWindow() );
m_GradientBackground2->Disable();
m_GradientBackground3 = mitk::GradientBackground::New();
m_GradientBackground3->SetRenderWindow(
mitkWidget3->GetRenderWindow() );
m_GradientBackground3->Disable();
m_GradientBackground4 = mitk::GradientBackground::New();
m_GradientBackground4->SetRenderWindow(
mitkWidget4->GetRenderWindow() );
m_GradientBackground4->SetGradientColors(0.1,0.1,0.1,0.5,0.5,0.5);
m_GradientBackground4->Enable();
// setup the department logo rendering
- m_LogoRendering1 = mitk::ManufacturerLogo::New();
- m_LogoRendering1->SetRenderWindow(
- mitkWidget1->GetRenderWindow() );
- m_LogoRendering1->Disable();
-
- m_LogoRendering2 = mitk::ManufacturerLogo::New();
- m_LogoRendering2->SetRenderWindow(
- mitkWidget2->GetRenderWindow() );
- m_LogoRendering2->Disable();
-
- m_LogoRendering3 = mitk::ManufacturerLogo::New();
- m_LogoRendering3->SetRenderWindow(
- mitkWidget3->GetRenderWindow() );
- m_LogoRendering3->Disable();
-
- m_LogoRendering4 = mitk::ManufacturerLogo::New();
- m_LogoRendering4->SetRenderWindow(
- mitkWidget4->GetRenderWindow() );
- m_LogoRendering4->Enable();
+ m_LogoRendering = mitk::LogoOverlay::New();
+ mitk::BaseRenderer::Pointer renderer4 = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow());
+ m_LogoRendering->SetOpacity(0.5);
+ mitk::Point2D offset;
+ offset.Fill(0.03);
+ m_LogoRendering->SetOffsetVector(offset);
+ m_LogoRendering->SetRelativeSize(0.2);
+ m_LogoRendering->SetCornerPosition(1);
+ renderer4->GetOverlayManager()->AddOverlay(m_LogoRendering.GetPointer(),renderer4);
m_RectangleRendering1 = mitk::RenderWindowFrame::New();
m_RectangleRendering1->SetRenderWindow(
mitkWidget1->GetRenderWindow() );
m_RectangleRendering1->Enable(1.0,0.0,0.0);
m_RectangleRendering2 = mitk::RenderWindowFrame::New();
m_RectangleRendering2->SetRenderWindow(
mitkWidget2->GetRenderWindow() );
m_RectangleRendering2->Enable(0.0,1.0,0.0);
m_RectangleRendering3 = mitk::RenderWindowFrame::New();
m_RectangleRendering3->SetRenderWindow(
mitkWidget3->GetRenderWindow() );
m_RectangleRendering3->Enable(0.0,0.0,1.0);
m_RectangleRendering4 = mitk::RenderWindowFrame::New();
m_RectangleRendering4->SetRenderWindow(
mitkWidget4->GetRenderWindow() );
m_RectangleRendering4->Enable(1.0,1.0,0.0);
}
QmitkStdMultiWidget::~QmitkStdMultiWidget()
{
DisablePositionTracking();
DisableNavigationControllerEventListening();
m_TimeNavigationController->Disconnect(mitkWidget1->GetSliceNavigationController());
m_TimeNavigationController->Disconnect(mitkWidget2->GetSliceNavigationController());
m_TimeNavigationController->Disconnect(mitkWidget3->GetSliceNavigationController());
m_TimeNavigationController->Disconnect(mitkWidget4->GetSliceNavigationController());
mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[0].ren );
mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[1].ren );
mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[2].ren );
//Delete CornerAnnotation
m_CornerAnnotaions[0].cornerText->Delete();
m_CornerAnnotaions[0].textProp->Delete();
m_CornerAnnotaions[0].ren->Delete();
m_CornerAnnotaions[1].cornerText->Delete();
m_CornerAnnotaions[1].textProp->Delete();
m_CornerAnnotaions[1].ren->Delete();
m_CornerAnnotaions[2].cornerText->Delete();
m_CornerAnnotaions[2].textProp->Delete();
m_CornerAnnotaions[2].ren->Delete();
}
void QmitkStdMultiWidget::RemovePlanesFromDataStorage()
{
if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull())
{
if(m_DataStorage.IsNotNull())
{
m_DataStorage->Remove(m_PlaneNode1);
m_DataStorage->Remove(m_PlaneNode2);
m_DataStorage->Remove(m_PlaneNode3);
m_DataStorage->Remove(m_Node);
}
}
}
void QmitkStdMultiWidget::AddPlanesToDataStorage()
{
if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull())
{
if (m_DataStorage.IsNotNull())
{
m_DataStorage->Add(m_Node);
m_DataStorage->Add(m_PlaneNode1, m_Node);
m_DataStorage->Add(m_PlaneNode2, m_Node);
m_DataStorage->Add(m_PlaneNode3, m_Node);
static_cast<mitk::PlaneGeometryDataMapper2D*>(m_PlaneNode1->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node);
static_cast<mitk::PlaneGeometryDataMapper2D*>(m_PlaneNode2->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node);
static_cast<mitk::PlaneGeometryDataMapper2D*>(m_PlaneNode3->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node);
}
}
}
void QmitkStdMultiWidget::changeLayoutTo2DImagesUp()
{
SMW_INFO << "changing layout to 2D images up... " << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//Set Layout to widget
this->setLayout(QmitkStdMultiWidgetLayout);
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget Container into splitter top
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit1->addWidget( mitkWidget3Container );
//set SplitterSize for splitter top
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
//insert Widget Container into splitter bottom
m_SubSplit2->addWidget( mitkWidget4Container );
//set SplitterSize for splitter m_LayoutSplit
splitterSize.clear();
splitterSize.push_back(400);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt
m_MainSplit->show();
//show Widget if hidden
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
//Change Layout Name
m_Layout = LAYOUT_2D_IMAGES_UP;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutTo2DImagesLeft()
{
SMW_INFO << "changing layout to 2D images left... " << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget into the splitters
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit1->addWidget( mitkWidget3Container );
//set splitterSize of SubSplit1
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_SubSplit2->addWidget( mitkWidget4Container );
//set splitterSize of Layout Split
splitterSize.clear();
splitterSize.push_back(400);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show Widget if hidden
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
//update Layout Name
m_Layout = LAYOUT_2D_IMAGES_LEFT;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToDefault()
{
SMW_INFO << "changing layout to default... " << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget container into the splitters
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget3Container );
m_SubSplit2->addWidget( mitkWidget4Container );
//set splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_SubSplit2->setSizes( splitterSize );
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show Widget if hidden
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_DEFAULT;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_DEFAULT );
mitkWidget2->LayoutDesignListChanged( LAYOUT_DEFAULT );
mitkWidget3->LayoutDesignListChanged( LAYOUT_DEFAULT );
mitkWidget4->LayoutDesignListChanged( LAYOUT_DEFAULT );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToBig3D()
{
SMW_INFO << "changing layout to big 3D ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget4Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_BIG_3D;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_BIG_3D );
mitkWidget2->LayoutDesignListChanged( LAYOUT_BIG_3D );
mitkWidget3->LayoutDesignListChanged( LAYOUT_BIG_3D );
mitkWidget4->LayoutDesignListChanged( LAYOUT_BIG_3D );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToWidget1()
{
SMW_INFO << "changing layout to big Widget1 ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget1Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
mitkWidget2->hide();
mitkWidget3->hide();
mitkWidget4->hide();
m_Layout = LAYOUT_WIDGET1;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET1 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET1 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET1 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET1 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToWidget2()
{
SMW_INFO << "changing layout to big Widget2 ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget2Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
mitkWidget3->hide();
mitkWidget4->hide();
m_Layout = LAYOUT_WIDGET2;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET2 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET2 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET2 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET2 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToWidget3()
{
SMW_INFO << "changing layout to big Widget3 ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget3Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
mitkWidget4->hide();
m_Layout = LAYOUT_WIDGET3;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET3 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET3 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET3 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET3 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToRowWidget3And4()
{
SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//add Widgets to splitter
m_LayoutSplit->addWidget( mitkWidget3Container );
m_LayoutSplit->addWidget( mitkWidget4Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_ROW_WIDGET_3_AND_4;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToColumnWidget3And4()
{
SMW_INFO << "changing layout to Widget3 and 4 in one Column..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//add Widgets to splitter
m_LayoutSplit->addWidget( mitkWidget3Container );
m_LayoutSplit->addWidget( mitkWidget4Container );
//set SplitterSize
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_COLUMN_WIDGET_3_AND_4;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToRowWidgetSmall3andBig4()
{
SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl;
this->changeLayoutToRowWidget3And4();
m_Layout = LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4;
}
void QmitkStdMultiWidget::changeLayoutToSmallUpperWidget2Big3and4()
{
SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget into the splitters
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget3Container );
m_SubSplit2->addWidget( mitkWidget4Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit2->setSizes( splitterSize );
splitterSize.clear();
splitterSize.push_back(500);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt
m_MainSplit->show();
//show Widget if hidden
mitkWidget1->hide();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutTo2x2Dand3DWidget()
{
SMW_INFO << "changing layout to 2 x 2D and 3D Widget" << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//add Widgets to splitter
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget4Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_2X_2D_AND_3D_WIDGET;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToLeft2Dand3DRight2D()
{
SMW_INFO << "changing layout to 2D and 3D left, 2D right Widget" << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//add Widgets to splitter
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget4Container );
m_SubSplit2->addWidget( mitkWidget2Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutTo2DUpAnd3DDown()
{
SMW_INFO << "changing layout to 2D up and 3D down" << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//Set Layout to widget
this->setLayout(QmitkStdMultiWidgetLayout);
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget Container into splitter top
m_SubSplit1->addWidget( mitkWidget1Container );
//set SplitterSize for splitter top
QList<int> splitterSize;
// splitterSize.push_back(1000);
// splitterSize.push_back(1000);
// splitterSize.push_back(1000);
// m_SubSplit1->setSizes( splitterSize );
//insert Widget Container into splitter bottom
m_SubSplit2->addWidget( mitkWidget4Container );
//set SplitterSize for splitter m_LayoutSplit
splitterSize.clear();
splitterSize.push_back(700);
splitterSize.push_back(700);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
mitkWidget2->hide();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_2D_UP_AND_3D_DOWN;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
//update all Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::SetDataStorage( mitk::DataStorage* ds )
{
mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetDataStorage(ds);
mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetDataStorage(ds);
mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetDataStorage(ds);
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetDataStorage(ds);
m_DataStorage = ds;
}
void QmitkStdMultiWidget::Fit()
{
vtkRenderer * vtkrenderer;
mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDisplayGeometry()->Fit();
mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetDisplayGeometry()->Fit();
mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetDisplayGeometry()->Fit();
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetDisplayGeometry()->Fit();
int w = vtkObject::GetGlobalWarningDisplay();
vtkObject::GlobalWarningDisplayOff();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkObject::SetGlobalWarningDisplay(w);
}
void QmitkStdMultiWidget::InitPositionTracking()
{
//PoinSetNode for MouseOrientation
m_PositionTrackerNode = mitk::DataNode::New();
m_PositionTrackerNode->SetProperty("name", mitk::StringProperty::New("Mouse Position"));
m_PositionTrackerNode->SetData( mitk::PointSet::New() );
m_PositionTrackerNode->SetColor(1.0,0.33,0.0);
m_PositionTrackerNode->SetProperty("layer", mitk::IntProperty::New(1001));
m_PositionTrackerNode->SetVisibility(true);
m_PositionTrackerNode->SetProperty("inputdevice", mitk::BoolProperty::New(true) );
m_PositionTrackerNode->SetProperty("BaseRendererMapperID", mitk::IntProperty::New(0) );//point position 2D mouse
m_PositionTrackerNode->SetProperty("baserenderer", mitk::StringProperty::New("N/A"));
}
void QmitkStdMultiWidget::AddDisplayPlaneSubTree()
{
// add the displayed planes of the multiwidget to a node to which the subtree
// @a planesSubTree points ...
float white[3] = {1.0f,1.0f,1.0f};
mitk::PlaneGeometryDataMapper2D::Pointer mapper;
// ... of widget 1
mitk::BaseRenderer* renderer1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow());
m_PlaneNode1 = renderer1->GetCurrentWorldPlaneGeometryNode();
m_PlaneNode1->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true));
m_PlaneNode1->SetProperty("name", mitk::StringProperty::New(std::string(renderer1->GetName()) + ".plane"));
m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true));
mapper = mitk::PlaneGeometryDataMapper2D::New();
m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
// ... of widget 2
mitk::BaseRenderer* renderer2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow());
m_PlaneNode2 = renderer2->GetCurrentWorldPlaneGeometryNode();
m_PlaneNode2->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true));
m_PlaneNode2->SetProperty("name", mitk::StringProperty::New(std::string(renderer2->GetName()) + ".plane"));
m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true));
mapper = mitk::PlaneGeometryDataMapper2D::New();
m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
// ... of widget 3
mitk::BaseRenderer* renderer3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow());
m_PlaneNode3 = renderer3->GetCurrentWorldPlaneGeometryNode();
m_PlaneNode3->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true));
m_PlaneNode3->SetProperty("name", mitk::StringProperty::New(std::string(renderer3->GetName()) + ".plane"));
m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true));
mapper = mitk::PlaneGeometryDataMapper2D::New();
m_PlaneNode3->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
m_Node = mitk::DataNode::New();
m_Node->SetProperty("name", mitk::StringProperty::New("Widgets"));
m_Node->SetProperty("helper object", mitk::BoolProperty::New(true));
}
mitk::SliceNavigationController* QmitkStdMultiWidget::GetTimeNavigationController()
{
return m_TimeNavigationController;
}
void QmitkStdMultiWidget::EnableStandardLevelWindow()
{
levelWindowWidget->disconnect(this);
levelWindowWidget->SetDataStorage(mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDataStorage());
levelWindowWidget->show();
}
void QmitkStdMultiWidget::DisableStandardLevelWindow()
{
levelWindowWidget->disconnect(this);
levelWindowWidget->hide();
}
// CAUTION: Legacy code for enabling Qt-signal-controlled view initialization.
// Use RenderingManager::InitializeViews() instead.
bool QmitkStdMultiWidget::InitializeStandardViews( const mitk::Geometry3D * geometry )
{
return m_RenderingManager->InitializeViews( geometry );
}
void QmitkStdMultiWidget::RequestUpdate()
{
m_RenderingManager->RequestUpdate(mitkWidget1->GetRenderWindow());
m_RenderingManager->RequestUpdate(mitkWidget2->GetRenderWindow());
m_RenderingManager->RequestUpdate(mitkWidget3->GetRenderWindow());
m_RenderingManager->RequestUpdate(mitkWidget4->GetRenderWindow());
}
void QmitkStdMultiWidget::ForceImmediateUpdate()
{
m_RenderingManager->ForceImmediateUpdate(mitkWidget1->GetRenderWindow());
m_RenderingManager->ForceImmediateUpdate(mitkWidget2->GetRenderWindow());
m_RenderingManager->ForceImmediateUpdate(mitkWidget3->GetRenderWindow());
m_RenderingManager->ForceImmediateUpdate(mitkWidget4->GetRenderWindow());
}
void QmitkStdMultiWidget::wheelEvent( QWheelEvent * e )
{
emit WheelMoved( e );
}
void QmitkStdMultiWidget::mousePressEvent(QMouseEvent * e)
{
if (e->button() == Qt::LeftButton) {
mitk::Point3D pointValue = this->GetLastLeftClickPosition();
emit LeftMouseClicked(pointValue);
}
}
void QmitkStdMultiWidget::moveEvent( QMoveEvent* e )
{
QWidget::moveEvent( e );
// it is necessary to readjust the position of the overlays as the StdMultiWidget has moved
// unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here
emit Moved();
}
void QmitkStdMultiWidget::leaveEvent ( QEvent * /*e*/ )
{
//set cursor back to initial state
m_SlicesRotator->ResetMouseCursor();
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow1() const
{
return mitkWidget1;
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow2() const
{
return mitkWidget2;
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow3() const
{
return mitkWidget3;
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow4() const
{
return mitkWidget4;
}
const mitk::Point3D& QmitkStdMultiWidget::GetLastLeftClickPosition() const
{
return m_LastLeftClickPositionSupplier->GetCurrentPoint();
}
const mitk::Point3D QmitkStdMultiWidget::GetCrossPosition() const
{
const mitk::PlaneGeometry *plane1 =
mitkWidget1->GetSliceNavigationController()->GetCurrentPlaneGeometry();
const mitk::PlaneGeometry *plane2 =
mitkWidget2->GetSliceNavigationController()->GetCurrentPlaneGeometry();
const mitk::PlaneGeometry *plane3 =
mitkWidget3->GetSliceNavigationController()->GetCurrentPlaneGeometry();
mitk::Line3D line;
if ( (plane1 != NULL) && (plane2 != NULL)
&& (plane1->IntersectionLine( plane2, line )) )
{
mitk::Point3D point;
if ( (plane3 != NULL)
&& (plane3->IntersectionPoint( line, point )) )
{
return point;
}
}
return m_LastLeftClickPositionSupplier->GetCurrentPoint();
}
void QmitkStdMultiWidget::EnablePositionTracking()
{
if (!m_PositionTracker)
{
m_PositionTracker = mitk::PositionTracker::New("PositionTracker", NULL);
}
mitk::GlobalInteraction* globalInteraction = mitk::GlobalInteraction::GetInstance();
if (globalInteraction)
{
if(m_DataStorage.IsNotNull())
m_DataStorage->Add(m_PositionTrackerNode);
globalInteraction->AddListener(m_PositionTracker);
}
}
void QmitkStdMultiWidget::DisablePositionTracking()
{
mitk::GlobalInteraction* globalInteraction =
mitk::GlobalInteraction::GetInstance();
if(globalInteraction)
{
if (m_DataStorage.IsNotNull())
m_DataStorage->Remove(m_PositionTrackerNode);
globalInteraction->RemoveListener(m_PositionTracker);
}
}
void QmitkStdMultiWidget::EnsureDisplayContainsPoint(
mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p)
{
mitk::Point2D pointOnPlane;
displayGeometry->Map( p, pointOnPlane );
// point minus origin < width or height ==> outside ?
mitk::Vector2D pointOnRenderWindow_MM;
pointOnRenderWindow_MM = pointOnPlane.GetVectorFromOrigin()
- displayGeometry->GetOriginInMM();
mitk::Vector2D sizeOfDisplay( displayGeometry->GetSizeInMM() );
if ( sizeOfDisplay[0] < pointOnRenderWindow_MM[0]
|| 0 > pointOnRenderWindow_MM[0]
|| sizeOfDisplay[1] < pointOnRenderWindow_MM[1]
|| 0 > pointOnRenderWindow_MM[1] )
{
// point is not visible -> move geometry
mitk::Vector2D offset( (pointOnRenderWindow_MM - sizeOfDisplay / 2.0)
/ displayGeometry->GetScaleFactorMMPerDisplayUnit() );
displayGeometry->MoveBy( offset );
}
}
void QmitkStdMultiWidget::MoveCrossToPosition(const mitk::Point3D& newPosition)
{
// create a PositionEvent with the given position and
// tell the slice navigation controllers to move there
mitk::Point2D p2d;
mitk::PositionEvent event( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()), 0, 0, 0,
mitk::Key_unknown, p2d, newPosition );
mitk::StateEvent stateEvent(mitk::EIDLEFTMOUSEBTN, &event);
mitk::StateEvent stateEvent2(mitk::EIDLEFTMOUSERELEASE, &event);
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent );
mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent );
mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent );
// just in case SNCs will develop something that depends on the mouse
// button being released again
mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent2 );
mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent2 );
mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent2 );
break;
case PLANE_MODE_ROTATION:
m_SlicesRotator->HandleEvent( &stateEvent );
// just in case SNCs will develop something that depends on the mouse
// button being released again
m_SlicesRotator->HandleEvent( &stateEvent2 );
break;
case PLANE_MODE_SWIVEL:
m_SlicesSwiveller->HandleEvent( &stateEvent );
// just in case SNCs will develop something that depends on the mouse
// button being released again
m_SlicesSwiveller->HandleEvent( &stateEvent2 );
break;
}
// determine if cross is now out of display
// if so, move the display window
EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())
->GetDisplayGeometry(), newPosition );
EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())
->GetDisplayGeometry(), newPosition );
EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())
->GetDisplayGeometry(), newPosition );
// update displays
m_RenderingManager->RequestUpdateAll();
}
void QmitkStdMultiWidget::HandleCrosshairPositionEvent()
{
if(!m_PendingCrosshairPositionEvent)
{
m_PendingCrosshairPositionEvent=true;
QTimer::singleShot(0,this,SLOT( HandleCrosshairPositionEventDelayed() ) );
}
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes)
{
mitk::Point3D crosshairPos = this->GetCrossPosition();
mitk::DataNode::Pointer node;
int maxlayer = -32768;
if(nodes.IsNotNull())
{
mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer();
// find node with largest layer, that is the node shown on top in the render window
for (unsigned int x = 0; x < nodes->size(); x++)
{
if ( (nodes->at(x)->GetData()->GetGeometry() != NULL) &&
nodes->at(x)->GetData()->GetGeometry()->IsInside(crosshairPos) )
{
int layer = 0;
if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue;
if(layer > maxlayer)
{
if( static_cast<mitk::DataNode::Pointer>(nodes->at(x))->IsVisible( baseRenderer ) )
{
node = nodes->at(x);
maxlayer = layer;
}
}
}
}
}
return node;
}
void QmitkStdMultiWidget::HandleCrosshairPositionEventDelayed()
{
m_PendingCrosshairPositionEvent = false;
// find image with highest layer
mitk::TNodePredicateDataType<mitk::Image>::Pointer isImageData = mitk::TNodePredicateDataType<mitk::Image>::New();
mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->m_DataStorage->GetSubset(isImageData).GetPointer();
mitk::DataNode::Pointer node;
mitk::DataNode::Pointer topSourceNode;
mitk::Image::Pointer image;
bool isBinary = false;
node = this->GetTopLayerNode(nodes);
if(node.IsNotNull())
{
node->GetBoolProperty("binary",isBinary);
if(isBinary)
{
mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = m_DataStorage->GetSources(node, NULL, true);
if(!sourcenodes->empty())
{
topSourceNode = this->GetTopLayerNode(sourcenodes);
}
if(topSourceNode.IsNotNull())
{
image = dynamic_cast<mitk::Image*>(topSourceNode->GetData());
}
else
{
image = dynamic_cast<mitk::Image*>(node->GetData());
}
}
else
{
image = dynamic_cast<mitk::Image*>(node->GetData());
}
}
mitk::Point3D crosshairPos = this->GetCrossPosition();
std::string statusText;
std::stringstream stream;
itk::Index<3> p;
mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer();
unsigned int timestep = baseRenderer->GetTimeStep();
if(image.IsNotNull() && (image->GetTimeSteps() > timestep ))
{
image->GetGeometry()->WorldToIndex(crosshairPos, p);
stream.precision(2);
stream<<"Position: <" << std::fixed <<crosshairPos[0] << ", " << std::fixed << crosshairPos[1] << ", " << std::fixed << crosshairPos[2] << "> mm";
stream<<"; Index: <"<<p[0] << ", " << p[1] << ", " << p[2] << "> ";
mitk::ScalarType pixelValue = image->GetPixelValueByIndex(p, timestep);
if (fabs(pixelValue)>1000000 || fabs(pixelValue) < 0.01)
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< std::scientific<< pixelValue <<" ";
}
else
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< pixelValue <<" ";
}
}
else
{
stream << "No image information at this position!";
}
statusText = stream.str();
mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str());
}
void QmitkStdMultiWidget::EnableNavigationControllerEventListening()
{
// Let NavigationControllers listen to GlobalInteraction
mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance();
// Listen for SliceNavigationController
mitkWidget1->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate<QmitkStdMultiWidget>( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) );
mitkWidget2->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate<QmitkStdMultiWidget>( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) );
mitkWidget3->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate<QmitkStdMultiWidget>( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) );
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
gi->AddListener( mitkWidget1->GetSliceNavigationController() );
gi->AddListener( mitkWidget2->GetSliceNavigationController() );
gi->AddListener( mitkWidget3->GetSliceNavigationController() );
gi->AddListener( mitkWidget4->GetSliceNavigationController() );
break;
case PLANE_MODE_ROTATION:
gi->AddListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
gi->AddListener( m_SlicesSwiveller );
break;
}
gi->AddListener( m_TimeNavigationController );
m_CrosshairNavigationEnabled = true;
}
void QmitkStdMultiWidget::DisableNavigationControllerEventListening()
{
// Do not let NavigationControllers listen to GlobalInteraction
mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance();
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
gi->RemoveListener( mitkWidget1->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget2->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget3->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget4->GetSliceNavigationController() );
break;
case PLANE_MODE_ROTATION:
m_SlicesRotator->ResetMouseCursor();
gi->RemoveListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
m_SlicesSwiveller->ResetMouseCursor();
gi->RemoveListener( m_SlicesSwiveller );
break;
}
gi->RemoveListener( m_TimeNavigationController );
m_CrosshairNavigationEnabled = false;
}
int QmitkStdMultiWidget::GetLayout() const
{
return m_Layout;
}
bool QmitkStdMultiWidget::GetGradientBackgroundFlag() const
{
return m_GradientBackgroundFlag;
}
void QmitkStdMultiWidget::EnableGradientBackground()
{
// gradient background is by default only in widget 4, otherwise
// interferences between 2D rendering and VTK rendering may occur.
//m_GradientBackground1->Enable();
//m_GradientBackground2->Enable();
//m_GradientBackground3->Enable();
m_GradientBackground4->Enable();
m_GradientBackgroundFlag = true;
}
void QmitkStdMultiWidget::DisableGradientBackground()
{
//m_GradientBackground1->Disable();
//m_GradientBackground2->Disable();
//m_GradientBackground3->Disable();
m_GradientBackground4->Disable();
m_GradientBackgroundFlag = false;
}
void QmitkStdMultiWidget::EnableDepartmentLogo()
{
- m_LogoRendering4->Enable();
+ m_LogoRendering->SetVisibility(true);
}
void QmitkStdMultiWidget::DisableDepartmentLogo()
{
- m_LogoRendering4->Disable();
+ m_LogoRendering->SetVisibility(false);
}
bool QmitkStdMultiWidget::IsDepartmentLogoEnabled() const
{
- return m_LogoRendering4->IsEnabled();
+ return m_LogoRendering->IsVisible(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
}
bool QmitkStdMultiWidget::IsCrosshairNavigationEnabled() const
{
return m_CrosshairNavigationEnabled;
}
mitk::SlicesRotator * QmitkStdMultiWidget::GetSlicesRotator() const
{
return m_SlicesRotator;
}
mitk::SlicesSwiveller * QmitkStdMultiWidget::GetSlicesSwiveller() const
{
return m_SlicesSwiveller;
}
void QmitkStdMultiWidget::SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer)
{
if (m_DataStorage.IsNotNull())
{
mitk::DataNode* n = m_DataStorage->GetNamedNode(widgetName);
if (n != NULL)
n->SetVisibility(visible, renderer);
}
}
void QmitkStdMultiWidget::SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer)
{
if (m_PlaneNode1.IsNotNull())
{
m_PlaneNode1->SetVisibility(visible, renderer);
}
if (m_PlaneNode2.IsNotNull())
{
m_PlaneNode2->SetVisibility(visible, renderer);
}
if (m_PlaneNode3.IsNotNull())
{
m_PlaneNode3->SetVisibility(visible, renderer);
}
m_RenderingManager->RequestUpdateAll();
}
void QmitkStdMultiWidget::SetWidgetPlanesLocked(bool locked)
{
//do your job and lock or unlock slices.
GetRenderWindow1()->GetSliceNavigationController()->SetSliceLocked(locked);
GetRenderWindow2()->GetSliceNavigationController()->SetSliceLocked(locked);
GetRenderWindow3()->GetSliceNavigationController()->SetSliceLocked(locked);
}
void QmitkStdMultiWidget::SetWidgetPlanesRotationLocked(bool locked)
{
//do your job and lock or unlock slices.
GetRenderWindow1()->GetSliceNavigationController()->SetSliceRotationLocked(locked);
GetRenderWindow2()->GetSliceNavigationController()->SetSliceRotationLocked(locked);
GetRenderWindow3()->GetSliceNavigationController()->SetSliceRotationLocked(locked);
}
void QmitkStdMultiWidget::SetWidgetPlanesRotationLinked( bool link )
{
m_SlicesRotator->SetLinkPlanes( link );
m_SlicesSwiveller->SetLinkPlanes( link );
emit WidgetPlanesRotationLinked( link );
}
void QmitkStdMultiWidget::SetWidgetPlaneMode( int userMode )
{
MITK_DEBUG << "Changing crosshair mode to " << userMode;
// first of all reset left mouse button interaction to default if PACS interaction style is active
m_MouseModeSwitcher->SelectMouseMode( mitk::MouseModeSwitcher::MousePointer );
emit WidgetNotifyNewCrossHairMode( userMode );
int mode = m_PlaneMode;
bool link = false;
// Convert user interface mode to actual mode
{
switch(userMode)
{
case 0:
mode = PLANE_MODE_SLICING;
link = false;
break;
case 1:
mode = PLANE_MODE_ROTATION;
link = false;
break;
case 2:
mode = PLANE_MODE_ROTATION;
link = true;
break;
case 3:
mode = PLANE_MODE_SWIVEL;
link = false;
break;
}
}
// Slice rotation linked
m_SlicesRotator->SetLinkPlanes( link );
m_SlicesSwiveller->SetLinkPlanes( link );
// Do nothing if mode didn't change
if ( m_PlaneMode == mode )
{
return;
}
mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance();
// Remove listeners of previous mode
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
// Notify MainTemplate GUI that this mode has been deselected
emit WidgetPlaneModeSlicing( false );
gi->RemoveListener( mitkWidget1->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget2->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget3->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget4->GetSliceNavigationController() );
break;
case PLANE_MODE_ROTATION:
// Notify MainTemplate GUI that this mode has been deselected
emit WidgetPlaneModeRotation( false );
m_SlicesRotator->ResetMouseCursor();
gi->RemoveListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
// Notify MainTemplate GUI that this mode has been deselected
emit WidgetPlaneModeSwivel( false );
m_SlicesSwiveller->ResetMouseCursor();
gi->RemoveListener( m_SlicesSwiveller );
break;
}
// Set new mode and add corresponding listener to GlobalInteraction
m_PlaneMode = mode;
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
// Notify MainTemplate GUI that this mode has been selected
emit WidgetPlaneModeSlicing( true );
// Add listeners
gi->AddListener( mitkWidget1->GetSliceNavigationController() );
gi->AddListener( mitkWidget2->GetSliceNavigationController() );
gi->AddListener( mitkWidget3->GetSliceNavigationController() );
gi->AddListener( mitkWidget4->GetSliceNavigationController() );
m_RenderingManager->InitializeViews();
break;
case PLANE_MODE_ROTATION:
// Notify MainTemplate GUI that this mode has been selected
emit WidgetPlaneModeRotation( true );
// Add listener
gi->AddListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
// Notify MainTemplate GUI that this mode has been selected
emit WidgetPlaneModeSwivel( true );
// Add listener
gi->AddListener( m_SlicesSwiveller );
break;
}
// Notify MainTemplate GUI that mode has changed
emit WidgetPlaneModeChange(m_PlaneMode);
}
void QmitkStdMultiWidget::SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower )
{
m_GradientBackground1->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackground2->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackground3->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackground4->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackgroundFlag = true;
}
void QmitkStdMultiWidget::SetDepartmentLogoPath( const char * path )
{
- m_LogoRendering1->SetLogoSource(path);
- m_LogoRendering2->SetLogoSource(path);
- m_LogoRendering3->SetLogoSource(path);
- m_LogoRendering4->SetLogoSource(path);
+ m_LogoRendering->SetLogoImagePath(path);
}
void QmitkStdMultiWidget::SetWidgetPlaneModeToSlicing( bool activate )
{
if ( activate )
{
this->SetWidgetPlaneMode( PLANE_MODE_SLICING );
}
}
void QmitkStdMultiWidget::SetWidgetPlaneModeToRotation( bool activate )
{
if ( activate )
{
this->SetWidgetPlaneMode( PLANE_MODE_ROTATION );
}
}
void QmitkStdMultiWidget::SetWidgetPlaneModeToSwivel( bool activate )
{
if ( activate )
{
this->SetWidgetPlaneMode( PLANE_MODE_SWIVEL );
}
}
void QmitkStdMultiWidget::OnLayoutDesignChanged( int layoutDesignIndex )
{
switch( layoutDesignIndex )
{
case LAYOUT_DEFAULT:
{
this->changeLayoutToDefault();
break;
}
case LAYOUT_2D_IMAGES_UP:
{
this->changeLayoutTo2DImagesUp();
break;
}
case LAYOUT_2D_IMAGES_LEFT:
{
this->changeLayoutTo2DImagesLeft();
break;
}
case LAYOUT_BIG_3D:
{
this->changeLayoutToBig3D();
break;
}
case LAYOUT_WIDGET1:
{
this->changeLayoutToWidget1();
break;
}
case LAYOUT_WIDGET2:
{
this->changeLayoutToWidget2();
break;
}
case LAYOUT_WIDGET3:
{
this->changeLayoutToWidget3();
break;
}
case LAYOUT_2X_2D_AND_3D_WIDGET:
{
this->changeLayoutTo2x2Dand3DWidget();
break;
}
case LAYOUT_ROW_WIDGET_3_AND_4:
{
this->changeLayoutToRowWidget3And4();
break;
}
case LAYOUT_COLUMN_WIDGET_3_AND_4:
{
this->changeLayoutToColumnWidget3And4();
break;
}
case LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4:
{
this->changeLayoutToRowWidgetSmall3andBig4();
break;
}
case LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4:
{
this->changeLayoutToSmallUpperWidget2Big3and4();
break;
}
case LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET:
{
this->changeLayoutToLeft2Dand3DRight2D();
break;
}
};
}
void QmitkStdMultiWidget::UpdateAllWidgets()
{
mitkWidget1->resize( mitkWidget1Container->frameSize().width()-1, mitkWidget1Container->frameSize().height() );
mitkWidget1->resize( mitkWidget1Container->frameSize().width(), mitkWidget1Container->frameSize().height() );
mitkWidget2->resize( mitkWidget2Container->frameSize().width()-1, mitkWidget2Container->frameSize().height() );
mitkWidget2->resize( mitkWidget2Container->frameSize().width(), mitkWidget2Container->frameSize().height() );
mitkWidget3->resize( mitkWidget3Container->frameSize().width()-1, mitkWidget3Container->frameSize().height() );
mitkWidget3->resize( mitkWidget3Container->frameSize().width(), mitkWidget3Container->frameSize().height() );
mitkWidget4->resize( mitkWidget4Container->frameSize().width()-1, mitkWidget4Container->frameSize().height() );
mitkWidget4->resize( mitkWidget4Container->frameSize().width(), mitkWidget4Container->frameSize().height() );
}
void QmitkStdMultiWidget::HideAllWidgetToolbars()
{
mitkWidget1->HideRenderWindowMenu();
mitkWidget2->HideRenderWindowMenu();
mitkWidget3->HideRenderWindowMenu();
mitkWidget4->HideRenderWindowMenu();
}
void QmitkStdMultiWidget::ActivateMenuWidget( bool state )
{
mitkWidget1->ActivateMenuWidget( state, this );
mitkWidget2->ActivateMenuWidget( state, this );
mitkWidget3->ActivateMenuWidget( state, this );
mitkWidget4->ActivateMenuWidget( state, this );
}
bool QmitkStdMultiWidget::IsMenuWidgetEnabled() const
{
return mitkWidget1->GetActivateMenuWidgetFlag();
}
void QmitkStdMultiWidget::ResetCrosshair()
{
if (m_DataStorage.IsNotNull())
{
m_RenderingManager->InitializeViewsByBoundingObjects(m_DataStorage);
//m_RenderingManager->InitializeViews( m_DataStorage->ComputeVisibleBoundingGeometry3D() );
// reset interactor to normal slicing
this->SetWidgetPlaneMode(PLANE_MODE_SLICING);
}
}
void QmitkStdMultiWidget::EnableColoredRectangles()
{
m_RectangleRendering1->Enable(1.0, 0.0, 0.0);
m_RectangleRendering2->Enable(0.0, 1.0, 0.0);
m_RectangleRendering3->Enable(0.0, 0.0, 1.0);
m_RectangleRendering4->Enable(1.0, 1.0, 0.0);
}
void QmitkStdMultiWidget::DisableColoredRectangles()
{
m_RectangleRendering1->Disable();
m_RectangleRendering2->Disable();
m_RectangleRendering3->Disable();
m_RectangleRendering4->Disable();
}
bool QmitkStdMultiWidget::IsColoredRectanglesEnabled() const
{
return m_RectangleRendering1->IsEnabled();
}
mitk::MouseModeSwitcher* QmitkStdMultiWidget::GetMouseModeSwitcher()
{
return m_MouseModeSwitcher;
}
void QmitkStdMultiWidget::MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode )
{
if ( mouseMode == 0 )
{
this->EnableNavigationControllerEventListening();
}
else
{
this->DisableNavigationControllerEventListening();
}
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane1()
{
return this->m_PlaneNode1;
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane2()
{
return this->m_PlaneNode2;
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane3()
{
return this->m_PlaneNode3;
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane(int id)
{
switch(id)
{
case 1: return this->m_PlaneNode1;
break;
case 2: return this->m_PlaneNode2;
break;
case 3: return this->m_PlaneNode3;
break;
default: return NULL;
}
}
diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.h b/Modules/QtWidgets/QmitkStdMultiWidget.h
index 3f69ce0ddb..c81a1ca84b 100644
--- a/Modules/QtWidgets/QmitkStdMultiWidget.h
+++ b/Modules/QtWidgets/QmitkStdMultiWidget.h
@@ -1,358 +1,355 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKSTDMULTIWIDGET_H_
#define QMITKSTDMULTIWIDGET_H_
#include <MitkQtWidgetsExports.h>
#include "mitkPositionTracker.h"
#include "mitkSlicesRotator.h"
#include "mitkSlicesSwiveller.h"
#include "mitkRenderWindowFrame.h"
-#include "mitkManufacturerLogo.h"
+#include "mitkLogoOverlay.h"
#include "mitkGradientBackground.h"
#include "mitkCoordinateSupplier.h"
#include "mitkDataStorage.h"
#include "mitkMouseModeSwitcher.h"
#include <qwidget.h>
#include <qsplitter.h>
#include <QFrame>
#include <QmitkRenderWindow.h>
#include <QmitkLevelWindowWidget.h>
#include "vtkTextProperty.h"
#include "vtkCornerAnnotation.h"
#include "mitkBaseRenderer.h"
class QHBoxLayout;
class QVBoxLayout;
class QGridLayout;
class QSpacerItem;
class QmitkLevelWindowWidget;
class QmitkRenderWindow;
namespace mitk {
class RenderingManager;
}
/// \ingroup QmitkModule
class QMITK_EXPORT QmitkStdMultiWidget : public QWidget
{
Q_OBJECT
public:
QmitkStdMultiWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::RenderingManager* renderingManager = 0, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard, const QString& name = "stdmulti");
virtual ~QmitkStdMultiWidget();
mitk::SliceNavigationController*
GetTimeNavigationController();
void RequestUpdate();
void ForceImmediateUpdate();
mitk::MouseModeSwitcher* GetMouseModeSwitcher();
QmitkRenderWindow* GetRenderWindow1() const;
QmitkRenderWindow* GetRenderWindow2() const;
QmitkRenderWindow* GetRenderWindow3() const;
QmitkRenderWindow* GetRenderWindow4() const;
const mitk::Point3D &
GetLastLeftClickPosition() const;
const mitk::Point3D
GetCrossPosition() const;
void EnablePositionTracking();
void DisablePositionTracking();
int GetLayout() const;
mitk::SlicesRotator * GetSlicesRotator() const;
mitk::SlicesSwiveller * GetSlicesSwiveller() const;
bool GetGradientBackgroundFlag() const;
/*!
\brief Access node of widget plane 1
\return DataNode holding widget plane 1
*/
mitk::DataNode::Pointer GetWidgetPlane1();
/*!
\brief Access node of widget plane 2
\return DataNode holding widget plane 2
*/
mitk::DataNode::Pointer GetWidgetPlane2();
/*!
\brief Access node of widget plane 3
\return DataNode holding widget plane 3
*/
mitk::DataNode::Pointer GetWidgetPlane3();
/*!
\brief Convenience method to access node of widget planes
\param id number of widget plane to be returned
\return DataNode holding widget plane 3
*/
mitk::DataNode::Pointer GetWidgetPlane(int id);
bool IsColoredRectanglesEnabled() const;
bool IsDepartmentLogoEnabled() const;
bool IsCrosshairNavigationEnabled() const;
void InitializeWidget();
/// called when the StdMultiWidget is closed to remove the 3 widget planes and the helper node from the DataStorage
void RemovePlanesFromDataStorage();
void AddPlanesToDataStorage();
void SetDataStorage( mitk::DataStorage* ds );
/** \brief Listener to the CrosshairPositionEvent
Ensures the CrosshairPositionEvent is handled only once and at the end of the Qt-Event loop
*/
void HandleCrosshairPositionEvent();
/// activate Menu Widget. true: activated, false: deactivated
void ActivateMenuWidget( bool state );
bool IsMenuWidgetEnabled() const;
protected:
void UpdateAllWidgets();
void HideAllWidgetToolbars();
mitk::DataNode::Pointer GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes);
public slots:
/// Receives the signal from HandleCrosshairPositionEvent, executes the StatusBar update
void HandleCrosshairPositionEventDelayed();
void changeLayoutTo2DImagesUp();
void changeLayoutTo2DImagesLeft();
void changeLayoutToDefault();
void changeLayoutToBig3D();
void changeLayoutToWidget1();
void changeLayoutToWidget2();
void changeLayoutToWidget3();
void changeLayoutToRowWidget3And4();
void changeLayoutToColumnWidget3And4();
void changeLayoutToRowWidgetSmall3andBig4();
void changeLayoutToSmallUpperWidget2Big3and4();
void changeLayoutTo2x2Dand3DWidget();
void changeLayoutToLeft2Dand3DRight2D();
void changeLayoutTo2DUpAnd3DDown();
void Fit();
void InitPositionTracking();
void AddDisplayPlaneSubTree();
void EnableStandardLevelWindow();
void DisableStandardLevelWindow();
bool InitializeStandardViews( const mitk::Geometry3D * geometry );
void wheelEvent( QWheelEvent * e );
void mousePressEvent(QMouseEvent * e);
void moveEvent( QMoveEvent* e );
void leaveEvent ( QEvent * e );
void EnsureDisplayContainsPoint(
mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p);
void MoveCrossToPosition(const mitk::Point3D& newPosition);
void EnableNavigationControllerEventListening();
void DisableNavigationControllerEventListening();
void EnableGradientBackground();
void DisableGradientBackground();
void EnableDepartmentLogo();
void DisableDepartmentLogo();
void EnableColoredRectangles();
void DisableColoredRectangles();
void SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer=NULL);
void SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer=NULL);
void SetWidgetPlanesLocked(bool locked);
void SetWidgetPlanesRotationLocked(bool locked);
void SetWidgetPlanesRotationLinked( bool link );
void SetWidgetPlaneMode( int mode );
void SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower );
void SetDepartmentLogoPath( const char * path );
void SetWidgetPlaneModeToSlicing( bool activate );
void SetWidgetPlaneModeToRotation( bool activate );
void SetWidgetPlaneModeToSwivel( bool activate );
void OnLayoutDesignChanged( int layoutDesignIndex );
void ResetCrosshair();
void MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode );
signals:
void LeftMouseClicked(mitk::Point3D pointValue);
void WheelMoved(QWheelEvent*);
void WidgetPlanesRotationLinked(bool);
void WidgetPlanesRotationEnabled(bool);
void ViewsInitialized();
void WidgetPlaneModeSlicing(bool);
void WidgetPlaneModeRotation(bool);
void WidgetPlaneModeSwivel(bool);
void WidgetPlaneModeChange(int);
void WidgetNotifyNewCrossHairMode(int);
void Moved();
public:
/** Define RenderWindow (public)*/
QmitkRenderWindow* mitkWidget1;
QmitkRenderWindow* mitkWidget2;
QmitkRenderWindow* mitkWidget3;
QmitkRenderWindow* mitkWidget4;
QmitkLevelWindowWidget* levelWindowWidget;
/********************************/
enum { PLANE_MODE_SLICING = 0, PLANE_MODE_ROTATION, PLANE_MODE_SWIVEL };
enum { LAYOUT_DEFAULT = 0, LAYOUT_2D_IMAGES_UP, LAYOUT_2D_IMAGES_LEFT,
LAYOUT_BIG_3D, LAYOUT_WIDGET1, LAYOUT_WIDGET2, LAYOUT_WIDGET3,
LAYOUT_2X_2D_AND_3D_WIDGET, LAYOUT_ROW_WIDGET_3_AND_4,
LAYOUT_COLUMN_WIDGET_3_AND_4, LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4 ,
LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4,LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET,
LAYOUT_2D_UP_AND_3D_DOWN};
enum {
AXIAL,
SAGITTAL,
CORONAL,
THREE_D
};
protected:
QHBoxLayout* QmitkStdMultiWidgetLayout;
int m_Layout;
int m_PlaneMode;
mitk::RenderingManager* m_RenderingManager;
mitk::RenderWindowFrame::Pointer m_RectangleRendering3;
mitk::RenderWindowFrame::Pointer m_RectangleRendering2;
mitk::RenderWindowFrame::Pointer m_RectangleRendering1;
mitk::RenderWindowFrame::Pointer m_RectangleRendering4;
- mitk::ManufacturerLogo::Pointer m_LogoRendering1;
- mitk::ManufacturerLogo::Pointer m_LogoRendering2;
- mitk::ManufacturerLogo::Pointer m_LogoRendering3;
- mitk::ManufacturerLogo::Pointer m_LogoRendering4;
+ mitk::LogoOverlay::Pointer m_LogoRendering;
mitk::GradientBackground::Pointer m_GradientBackground1;
mitk::GradientBackground::Pointer m_GradientBackground2;
mitk::GradientBackground::Pointer m_GradientBackground4;
mitk::GradientBackground::Pointer m_GradientBackground3;
bool m_GradientBackgroundFlag;
mitk::MouseModeSwitcher::Pointer m_MouseModeSwitcher;
mitk::CoordinateSupplier::Pointer m_LastLeftClickPositionSupplier;
mitk::PositionTracker::Pointer m_PositionTracker;
mitk::SliceNavigationController* m_TimeNavigationController;
mitk::SlicesRotator::Pointer m_SlicesRotator;
mitk::SlicesSwiveller::Pointer m_SlicesSwiveller;
mitk::DataNode::Pointer m_PositionTrackerNode;
mitk::DataStorage::Pointer m_DataStorage;
mitk::DataNode::Pointer m_PlaneNode1;
mitk::DataNode::Pointer m_PlaneNode2;
mitk::DataNode::Pointer m_PlaneNode3;
mitk::DataNode::Pointer m_Node;
QSplitter *m_MainSplit;
QSplitter *m_LayoutSplit;
QSplitter *m_SubSplit1;
QSplitter *m_SubSplit2;
QWidget *mitkWidget1Container;
QWidget *mitkWidget2Container;
QWidget *mitkWidget3Container;
QWidget *mitkWidget4Container;
struct
{
vtkCornerAnnotation *cornerText;
vtkTextProperty *textProp;
vtkRenderer *ren;
} m_CornerAnnotaions[3];
bool m_PendingCrosshairPositionEvent;
bool m_CrosshairNavigationEnabled;
};
#endif /*QMITKSTDMULTIWIDGET_H_*/
diff --git a/Modules/QtWidgets/files.cmake b/Modules/QtWidgets/files.cmake
index f2246f6666..d7a26fd2cb 100644
--- a/Modules/QtWidgets/files.cmake
+++ b/Modules/QtWidgets/files.cmake
@@ -1,66 +1,68 @@
set(CPP_FILES
QmitkApplicationCursor.cpp
QmitkEnums.h
QmitkCustomVariants.h
QmitkDataStorageComboBox.cpp
QmitkDataStorageListModel.cpp
QmitkDataStorageTableModel.cpp
QmitkDataStorageTreeModel.cpp
QmitkEventAdapter.cpp
QmitkLevelWindowPresetDefinitionDialog.cpp
QmitkLevelWindowRangeChangeDialog.cpp
QmitkLevelWindowWidgetContextMenu.cpp
QmitkLevelWindowWidget.cpp
QmitkLineEditLevelWindowWidget.cpp
QmitkMemoryUsageIndicatorView.cpp
+QmitkMimeTypes.cpp
QmitkNodeDescriptor.cpp
QmitkNodeDescriptorManager.cpp
QmitkRenderWindowMenu.cpp
QmitkProgressBar.cpp
QmitkPropertiesTableEditor.cpp
QmitkPropertiesTableModel.cpp
QmitkPropertyDelegate.cpp
QmitkRegisterClasses.cpp
QmitkRenderingManager.cpp
QmitkRenderingManagerFactory.cpp
QmitkRenderWindow.cpp
QmitkServiceListWidget.cpp
QmitkSliderLevelWindowWidget.cpp
QmitkStdMultiWidget.cpp
QmitkMouseModeSwitcher.cpp
+QmitkDataStorageFilterProxyModel.cpp
)
set(MOC_H_FILES
QmitkDataStorageComboBox.h
QmitkDataStorageTableModel.h
QmitkLevelWindowPresetDefinitionDialog.h
QmitkLevelWindowRangeChangeDialog.h
QmitkLevelWindowWidgetContextMenu.h
QmitkLevelWindowWidget.h
QmitkLineEditLevelWindowWidget.h
QmitkMemoryUsageIndicatorView.h
QmitkNodeDescriptor.h
QmitkNodeDescriptorManager.h
QmitkRenderWindowMenu.h
QmitkProgressBar.h
QmitkPropertiesTableEditor.h
QmitkPropertyDelegate.h
QmitkRenderingManager.h
QmitkRenderWindow.h
QmitkServiceListWidget.h
QmitkSliderLevelWindowWidget.h
QmitkStdMultiWidget.h
QmitkMouseModeSwitcher.h
)
set(UI_FILES
QmitkLevelWindowPresetDefinition.ui
QmitkLevelWindowWidget.ui
QmitkLevelWindowRangeChange.ui
QmitkMemoryUsageIndicator.ui
QmitkServiceListWidgetControls.ui
)
set(QRC_FILES
Qmitk.qrc
)
diff --git a/Modules/QtWidgetsExt/CMakeLists.txt b/Modules/QtWidgetsExt/CMakeLists.txt
index 7916170c25..fb35dcde93 100644
--- a/Modules/QtWidgetsExt/CMakeLists.txt
+++ b/Modules/QtWidgetsExt/CMakeLists.txt
@@ -1,6 +1,6 @@
MITK_CREATE_MODULE(
- INCLUDE_DIRS QmitkApplicationBase QmitkPropertyObservers QmitkFunctionalityComponents
+ INCLUDE_DIRS QmitkApplicationBase QmitkPropertyObservers
DEPENDS MitkImageStatistics MitkQtWidgets
PACKAGE_DEPENDS Qt4|QtWebKit Qwt Qxt
WARNINGS_AS_ERRORS
)
diff --git a/Modules/QtWidgetsExt/QmitkColorTransferFunctionCanvas.cpp b/Modules/QtWidgetsExt/QmitkColorTransferFunctionCanvas.cpp
index daef0d636c..5f4d6f4e4e 100755
--- a/Modules/QtWidgetsExt/QmitkColorTransferFunctionCanvas.cpp
+++ b/Modules/QtWidgetsExt/QmitkColorTransferFunctionCanvas.cpp
@@ -1,169 +1,169 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkColorTransferFunctionCanvas.h"
#include <QPainter>
#include <QLineEdit>
#include <QColorDialog>
QmitkColorTransferFunctionCanvas::QmitkColorTransferFunctionCanvas(
QWidget * parent, Qt::WindowFlags f) :
QmitkTransferFunctionCanvas(parent, f), m_ColorTransferFunction(0)
{
// used for drawing a border
setContentsMargins(1,1,1,1);
}
void QmitkColorTransferFunctionCanvas::SetTitle(const QString& title)
{
m_Title=title;
}
void QmitkColorTransferFunctionCanvas::paintEvent(QPaintEvent*)
{
QPainter painter(this);
// Render gray background
QRect contentsRect = this->contentsRect();
painter.setPen(Qt::gray);
painter.drawRect(0, 0, contentsRect.width()+1, contentsRect.height()+1);
if( ! this->isEnabled() )
return;
if (m_ColorTransferFunction)
{
for (int x = contentsRect.x(); x < contentsRect.x() + contentsRect.width(); x++)
{
double xVal = m_Min + ((float) x) / contentsRect.width() * (m_Max
- m_Min);
QColor col((int) (m_ColorTransferFunction->GetRedValue(xVal) * 255),
(int) (m_ColorTransferFunction->GetGreenValue(xVal) * 255),
(int) (m_ColorTransferFunction->GetBlueValue(xVal) * 255));
painter.setPen(col);
painter.drawLine(x, 1, x, contentsRect.height());
}
}
//paint title
if (m_Title.size()>0)
{
painter.setPen(Qt::black);
painter.drawText(QPoint(11,21),m_Title);
painter.setPen(Qt::white);
painter.drawText(QPoint(10,20),m_Title);
}
//paint min and max
QString qs_min = QString::number( m_Min );
QString qs_max = QString::number( m_Max );
QRect qr_min = painter.fontMetrics().boundingRect( qs_min );
QRect qr_max = painter.fontMetrics().boundingRect( qs_max );
int y,x;
y=this->contentsRect().height()-qr_min.height()+5;
x=10;
painter.setPen(Qt::black);
painter.drawText(QPoint(x+1,y+1),qs_min);
painter.setPen(Qt::white);
painter.drawText(QPoint(x ,y ),qs_min);
y=this->contentsRect().height()-qr_max.height()+5;
x=this->contentsRect().width()-qr_max.width()-6;
painter.setPen(Qt::black);
painter.drawText(QPoint(x,y+1),qs_max);
painter.setPen(Qt::white);
painter.drawText(QPoint(x,y ),qs_max);
if (m_ColorTransferFunction)
{
// now paint the handles
painter.setBrush(Qt::black);
painter.setPen(Qt::black);
for (int i = 0; i < this->GetFunctionSize(); i++)
{
int handleHeight = (i == m_GrabbedHandle) ? (int) (contentsRect.height() / 1.5)
: contentsRect.height() / 2;
int handleWidth = (i == m_GrabbedHandle) ? 6 : 4;
std::pair<int,int> point = this->FunctionToCanvas(std::make_pair(
GetFunctionX(i), 0.0f));
int y = height() / 2;
painter.drawRoundRect(point.first - handleWidth / 2,
y - handleHeight / 2, handleWidth, handleHeight, 50, 50);
if (i == m_GrabbedHandle && m_LineEditAvailable)
{
int xCursor = m_XEdit->cursorPosition();
- m_XEdit->setText(QString::number(GetFunctionX(m_GrabbedHandle)));
+ m_XEdit->setText(QString::number(GetFunctionX(m_GrabbedHandle), 'g', 4));
m_XEdit->setCursorPosition( xCursor );
}
}
}
}
int QmitkColorTransferFunctionCanvas::GetNearHandle(int x, int,
unsigned int maxSquaredDistance)
{
for (int i = 0; i < this->GetFunctionSize(); i++)
{
std::pair<int,int> point = this->FunctionToCanvas(std::make_pair(
GetFunctionX(i), (double) 0.0));
if ((unsigned int) ((point.first - x) * (point.first - x))
< maxSquaredDistance)
{
return i;
}
}
return -1;
}
void QmitkColorTransferFunctionCanvas::DoubleClickOnHandle(int handle)
{
double xVal = GetFunctionX(handle);
QColor col((int) (m_ColorTransferFunction->GetRedValue(xVal) * 255),
(int) (m_ColorTransferFunction->GetGreenValue(xVal) * 255),
(int) (m_ColorTransferFunction->GetBlueValue(xVal) * 255));
QColor result = QColorDialog::getColor(col);
if (result.isValid())
{
m_ColorTransferFunction->AddRGBPoint(xVal, result.red() / 255.0,
result.green() / 255.0, result.blue() / 255.0);
this->update();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkColorTransferFunctionCanvas::MoveFunctionPoint(int index,
std::pair<double,double> pos)
{
double color[3];
m_ColorTransferFunction->GetColor(GetFunctionX(index), color);
RemoveFunctionPoint( GetFunctionX(index));
m_ColorTransferFunction->AddRGBPoint(pos.first, color[0], color[1], color[2]);
}
void QmitkColorTransferFunctionCanvas::AddRGB(double x, double r, double g,
double b)
{
m_ColorTransferFunction->AddRGBPoint(x, r, g, b);
}
diff --git a/Modules/QtWidgetsExt/QmitkPiecewiseFunctionCanvas.cpp b/Modules/QtWidgetsExt/QmitkPiecewiseFunctionCanvas.cpp
index 896dd74620..1aeefe5649 100755
--- a/Modules/QtWidgetsExt/QmitkPiecewiseFunctionCanvas.cpp
+++ b/Modules/QtWidgetsExt/QmitkPiecewiseFunctionCanvas.cpp
@@ -1,162 +1,161 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPiecewiseFunctionCanvas.h"
#include <QPainter>
#include <QLineEdit>
QmitkPiecewiseFunctionCanvas::QmitkPiecewiseFunctionCanvas(QWidget * parent,
Qt::WindowFlags f) :
QmitkTransferFunctionCanvas(parent, f), m_PiecewiseFunction(0)
{
// used for drawing a border
setContentsMargins(1,1,1,1);
}
void QmitkPiecewiseFunctionCanvas::SetTitle(const QString& title)
{
m_Title=title;
}
void QmitkPiecewiseFunctionCanvas::paintEvent(QPaintEvent*)
{
QPainter painter(this);
PaintHistogram(painter);
if (m_Title.size()>0)
{
painter.setPen(Qt::black);
painter.drawText(QPoint(11,21),m_Title);
painter.setPen(Qt::white);
painter.drawText(QPoint(10,20),m_Title);
}
{
- QString qs_min = QString::number( m_Min );
- QString qs_max = QString::number( m_Max );
+ QString qs_min = QString::number( m_Min, 'g', 4 );
+ QString qs_max = QString::number( m_Max, 'g', 4 );
QRect qr_min = painter.fontMetrics().boundingRect( qs_min );
QRect qr_max = painter.fontMetrics().boundingRect( qs_max );
int y,x;
y=this->contentsRect().height()-qr_min.height()+5;
x=10;
// Fill the tf presets in the generator widget
painter.setPen(Qt::black);
painter.drawText(QPoint(x+1,y+1),qs_min);
painter.setPen(Qt::white);
painter.drawText(QPoint(x ,y ),qs_min);
y=this->contentsRect().height()-qr_max.height()+5;
x=this->contentsRect().width()-qr_max.width()-6;
painter.setPen(Qt::black);
painter.drawText(QPoint(x,y+1),qs_max);
painter.setPen(Qt::white);
painter.drawText(QPoint(x,y ),qs_max);
}
painter.setPen(Qt::gray);
QRect contentsRect = this->contentsRect();
painter.drawRect(0, 0, contentsRect.width()+1, contentsRect.height()+1);
if (m_PiecewiseFunction && this->isEnabled())
{
double* dp = m_PiecewiseFunction->GetDataPointer();
// Render lines
painter.setPen(Qt::black);
for (int i = -1; i < m_PiecewiseFunction->GetSize(); i++)
{
std::pair<int,int> left;
std::pair<int,int> right;
if(i < 0)
left = this->FunctionToCanvas(std::make_pair(-32768, dp[0 * 2 + 1]));
else
left = this->FunctionToCanvas(std::make_pair(dp[i * 2], dp[i * 2 + 1]));
if(i+1 >= m_PiecewiseFunction->GetSize())
right = this->FunctionToCanvas(std::make_pair(32768, dp[(i ) * 2 + 1]));
else
right = this->FunctionToCanvas(std::make_pair(dp[(i+1) * 2], dp[(i+1) * 2 + 1]));
painter.drawLine(left.first, left.second, right.first, right.second);
}
// Render Points
for (int i = 0; i < m_PiecewiseFunction->GetSize(); i++)
{
std::pair<int,int> point = this->FunctionToCanvas(std::make_pair(
dp[i * 2], dp[i * 2 + 1]));
if (i == m_GrabbedHandle)
{
painter.setBrush(QBrush(Qt::red));
if (m_LineEditAvailable)
{
int xCursor = m_XEdit->cursorPosition();
int yCursor = m_YEdit->cursorPosition();
- m_XEdit->setText(QString::number(GetFunctionX(m_GrabbedHandle)));
- m_YEdit->setText(QString::number(GetFunctionY(m_GrabbedHandle)));
+ m_XEdit->setText(QString::number(GetFunctionX(m_GrabbedHandle), 'g', 4));
+ m_YEdit->setText(QString::number(GetFunctionY(m_GrabbedHandle), 'g', 4));
m_XEdit->setCursorPosition( xCursor );
m_YEdit->setCursorPosition( yCursor );
}
}
else
{
painter.setBrush(QBrush(Qt::green));
}
painter.drawEllipse(point.first - 4, point.second - 4, 8, 8);
}
painter.setBrush(Qt::NoBrush);
}
}
int QmitkPiecewiseFunctionCanvas::GetNearHandle(int x, int y,
unsigned int maxSquaredDistance)
{
double* dp = m_PiecewiseFunction->GetDataPointer();
for (int i = 0; i < m_PiecewiseFunction->GetSize(); i++)
{
std::pair<int,int> point = this->FunctionToCanvas(std::make_pair(dp[i * 2],
dp[i * 2 + 1]));
if ((unsigned int) ((point.first - x) * (point.first - x) + (point.second
- y) * (point.second - y)) <= maxSquaredDistance)
{
return i;
}
}
return -1;
}
void QmitkPiecewiseFunctionCanvas::MoveFunctionPoint(int index,
std::pair<double,double> pos)
{
RemoveFunctionPoint(GetFunctionX(index));
m_GrabbedHandle = AddFunctionPoint(pos.first, pos.second);
}
-
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp
index 8c410c3e06..51b1d48376 100755
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp
@@ -1,268 +1,268 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkTransferFunctionWidget.h"
#include <mitkTransferFunctionProperty.h>
#include <QPlastiqueStyle>
QmitkTransferFunctionWidget::QmitkTransferFunctionWidget(QWidget* parent,
Qt::WindowFlags f) :
QWidget(parent, f)
{
this->setupUi(this);
// signals and slots connections
connect(m_XEditScalarOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetXValueScalar( const QString & )));
connect(m_YEditScalarOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetYValueScalar( const QString & )));
connect(m_XEditGradientOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetXValueGradient( const QString & )));
connect(m_YEditGradientOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetYValueGradient( const QString & )));
connect(m_XEditColor, SIGNAL( textEdited ( const QString & ) ), this, SLOT(SetXValueColor( const QString & )));
QPlastiqueStyle *sliderStyle = new QPlastiqueStyle();
m_RangeSlider->setMaximum(2048);
m_RangeSlider->setMinimum(-2048);
m_RangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
m_RangeSlider->setStyle(sliderStyle);
connect(m_RangeSlider, SIGNAL(spanChanged(double,double)),this, SLOT(OnSpanChanged(double,double)));
//reset button
connect(m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider()));
m_ScalarOpacityFunctionCanvas->SetQLineEdits(m_XEditScalarOpacity, m_YEditScalarOpacity);
m_GradientOpacityCanvas->SetQLineEdits(m_XEditGradientOpacity, m_YEditGradientOpacity);
m_ColorTransferFunctionCanvas->SetQLineEdits(m_XEditColor, 0);
m_ScalarOpacityFunctionCanvas->SetTitle("Grayvalue -> Opacity");
m_GradientOpacityCanvas->SetTitle("Grayvalue/Gradient -> Opacity");
m_ColorTransferFunctionCanvas->SetTitle("Grayvalue -> Color");
}
QmitkTransferFunctionWidget::~QmitkTransferFunctionWidget()
{
}
void QmitkTransferFunctionWidget::SetIntegerMode(bool intMode)
{
m_RangeSlider->setIntegerMode(intMode);
}
void QmitkTransferFunctionWidget::SetScalarLabel(const QString& scalarLabel)
{
m_textLabelX->setText(scalarLabel);
m_textLabelX_2->setText(scalarLabel);
m_textLabelX_3->setText(scalarLabel);
m_ScalarOpacityFunctionCanvas->SetTitle(scalarLabel + " -> Opacity");
m_GradientOpacityCanvas->SetTitle(scalarLabel + "/Gradient -> Opacity");
m_ColorTransferFunctionCanvas->SetTitle(scalarLabel + " -> Color");
}
void QmitkTransferFunctionWidget::ShowScalarOpacityFunction(bool show)
{
m_ScalarOpacityWidget->setVisible(show);
}
void QmitkTransferFunctionWidget::ShowColorFunction(bool show)
{
m_ColorWidget->setVisible(show);
}
void QmitkTransferFunctionWidget::ShowGradientOpacityFunction(bool show)
{
m_GradientOpacityWidget->setVisible(show);
}
void QmitkTransferFunctionWidget::SetScalarOpacityFunctionEnabled(bool enable)
{
m_ScalarOpacityWidget->setEnabled(enable);
}
void QmitkTransferFunctionWidget::SetColorFunctionEnabled(bool enable)
{
m_ColorWidget->setEnabled(enable);
}
void QmitkTransferFunctionWidget::SetGradientOpacityFunctionEnabled(bool enable)
{
m_GradientOpacityWidget->setEnabled(enable);
}
-void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode* node)
+void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode* node, const mitk::BaseRenderer* renderer)
{
if (node)
{
- tfpToChange = dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction"));
+ tfpToChange = dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction", renderer));
if(!tfpToChange)
{
if (! dynamic_cast<mitk::Image*>(node->GetData()))
{
MITK_WARN << "QmitkTransferFunctionWidget::SetDataNode called with non-image node";
goto turnOff;
}
node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New() );
}
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
if( mitk::BaseData* data = node->GetData() )
{
mitk::SimpleHistogram *h = histogramCache[data];
m_RangeSliderMin= h->GetMin();
m_RangeSliderMax= h->GetMax();
m_RangeSlider->blockSignals(true);
m_RangeSlider->setMinimum(m_RangeSliderMin);
m_RangeSlider->setMaximum(m_RangeSliderMax);
m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax);
m_RangeSlider->blockSignals(false);
m_ScalarOpacityFunctionCanvas->SetHistogram( h );
m_GradientOpacityCanvas->SetHistogram( h );
m_ColorTransferFunctionCanvas->SetHistogram( h );
}
OnUpdateCanvas();
return;
}
turnOff:
m_ScalarOpacityFunctionCanvas->setEnabled(false);
m_ScalarOpacityFunctionCanvas->SetHistogram(0);
m_GradientOpacityCanvas->setEnabled(false);
m_GradientOpacityCanvas->SetHistogram(0);
m_ColorTransferFunctionCanvas->setEnabled(false);
m_ColorTransferFunctionCanvas->SetHistogram(0);
tfpToChange = 0;
}
void QmitkTransferFunctionWidget::OnUpdateCanvas()
{
if(tfpToChange.IsNull())
return;
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
if(tf.IsNull())
return;
m_ScalarOpacityFunctionCanvas->SetPiecewiseFunction( tf->GetScalarOpacityFunction() );
m_GradientOpacityCanvas->SetPiecewiseFunction( tf->GetGradientOpacityFunction() );
m_ColorTransferFunctionCanvas->SetColorTransferFunction( tf->GetColorTransferFunction() );
UpdateRanges();
m_ScalarOpacityFunctionCanvas->update();
m_GradientOpacityCanvas->update();
m_ColorTransferFunctionCanvas->update();
}
void QmitkTransferFunctionWidget::SetXValueScalar( const QString text )
{
if ( !text.endsWith( "." ))
{
m_ScalarOpacityFunctionCanvas->SetX(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetYValueScalar( const QString text )
{
if ( !text.endsWith( "." ))
{
m_ScalarOpacityFunctionCanvas->SetY(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetXValueGradient( const QString text )
{
if ( !text.endsWith( "." ))
{
m_GradientOpacityCanvas->SetX(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetYValueGradient( const QString text )
{
if ( !text.endsWith( "." ))
{
m_GradientOpacityCanvas->SetY(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetXValueColor( const QString text )
{
if ( !text.endsWith( "." ))
{
m_ColorTransferFunctionCanvas->SetX(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::UpdateRanges()
{
double lower = m_RangeSlider->lowerValue();
double upper = m_RangeSlider->upperValue();
m_ScalarOpacityFunctionCanvas->SetMin(lower);
m_ScalarOpacityFunctionCanvas->SetMax(upper);
m_GradientOpacityCanvas->SetMin(lower);
m_GradientOpacityCanvas->SetMax(upper);
m_ColorTransferFunctionCanvas->SetMin(lower);
m_ColorTransferFunctionCanvas->SetMax(upper);
}
void QmitkTransferFunctionWidget::OnSpanChanged(double, double)
{
UpdateRanges();
m_GradientOpacityCanvas->update();
m_ColorTransferFunctionCanvas->update();
m_ScalarOpacityFunctionCanvas->update();
}
void QmitkTransferFunctionWidget::OnResetSlider()
{
m_RangeSlider->blockSignals(true);
m_RangeSlider->setUpperValue(m_RangeSliderMax);
m_RangeSlider->setLowerValue(m_RangeSliderMin);
m_RangeSlider->blockSignals(false);
UpdateRanges();
m_GradientOpacityCanvas->update();
m_ColorTransferFunctionCanvas->update();
m_ScalarOpacityFunctionCanvas->update();
}
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h
index b3ccaf4fb5..093e56e891 100755
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h
@@ -1,87 +1,90 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKTRANSFERFUNCTIONWIDGET_H
#define QMITKTRANSFERFUNCTIONWIDGET_H
#include "ui_QmitkTransferFunctionWidget.h"
#include "MitkQtWidgetsExtExports.h"
#include <mitkCommon.h>
#include <QWidget>
#include <mitkDataNode.h>
#include <mitkTransferFunctionProperty.h>
#include <QSlider>
#include <QPushButton>
#include <QmitkTransferFunctionWidget.h>
+namespace mitk {
+class BaseRenderer;
+}
class MitkQtWidgetsExt_EXPORT QmitkTransferFunctionWidget : public QWidget, public Ui::QmitkTransferFunctionWidget
{
Q_OBJECT
public:
QmitkTransferFunctionWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
~QmitkTransferFunctionWidget () ;
- void SetDataNode(mitk::DataNode* node);
+ void SetDataNode(mitk::DataNode* node, const mitk::BaseRenderer* renderer = NULL);
void SetIntegerMode(bool intMode);
void SetScalarLabel(const QString& scalarLabel);
void ShowScalarOpacityFunction(bool show);
void ShowColorFunction(bool show);
void ShowGradientOpacityFunction(bool show);
void SetScalarOpacityFunctionEnabled(bool enable);
void SetColorFunctionEnabled(bool enable);
void SetGradientOpacityFunctionEnabled(bool enable);
public slots:
void SetXValueScalar( const QString text );
void SetYValueScalar( const QString text );
void SetXValueGradient( const QString text );
void SetYValueGradient( const QString text );
void SetXValueColor( const QString text );
void OnUpdateCanvas();
void UpdateRanges();
void OnResetSlider();
void OnSpanChanged (double lower, double upper);
protected:
mitk::TransferFunctionProperty::Pointer tfpToChange;
double m_RangeSliderMin;
double m_RangeSliderMax;
mitk::SimpleHistogramCache histogramCache;
};
#endif
diff --git a/Modules/Remeshing/Testing/mitkACVDTest.cpp b/Modules/Remeshing/Testing/mitkACVDTest.cpp
index e163b6737d..e52a9dd24c 100644
--- a/Modules/Remeshing/Testing/mitkACVDTest.cpp
+++ b/Modules/Remeshing/Testing/mitkACVDTest.cpp
@@ -1,121 +1,124 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkACVD.h>
#include <mitkIOUtil.h>
#include <mitkTestingMacros.h>
+#include <vtkDebugLeaks.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <sstream>
#define _MITK_TEST_FOR_EXCEPTION(STATEMENT, EXCEPTION, MESSAGE) \
MITK_TEST_OUTPUT_NO_ENDL(<< MESSAGE) \
try \
{ \
STATEMENT; \
MITK_TEST_OUTPUT(<< " [FAILED]") \
mitk::TestManager::GetInstance()->TestFailed(); \
} \
catch (const EXCEPTION& e) \
{ \
MITK_TEST_OUTPUT(<< "\n " << e.GetDescription() << " [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
template <typename T>
static T lexical_cast(const std::string& string)
{
std::istringstream sstream(string);
T value;
sstream >> value;
if (sstream.fail())
{
MITK_ERROR << "Lexical cast failed for '" << string << "'!";
exit(EXIT_FAILURE);
}
return value;
}
static void Remesh_SurfaceIsNull_ThrowsException()
{
mitk::Surface::ConstPointer surface;
_MITK_TEST_FOR_EXCEPTION(mitk::ACVD::Remesh(surface, 0, 100, 0.0), mitk::Exception, "Remesh_SurfaceIsNull_ThrowsException")
}
static void Remesh_PolyDataIsNull_ThrowsException()
{
mitk::Surface::ConstPointer surface = mitk::Surface::New().GetPointer();
_MITK_TEST_FOR_EXCEPTION(mitk::ACVD::Remesh(surface, 0, 100, 0.0), mitk::Exception, "Remesh_PolyDataIsNull_ThrowsException")
}
static void Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException()
{
mitk::Surface::ConstPointer surface = mitk::Surface::New().GetPointer();
_MITK_TEST_FOR_EXCEPTION(mitk::ACVD::Remesh(surface, 1, 100, 0.0), mitk::Exception, "Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException")
}
static void Remesh_SurfaceHasNoPolygons_ThrowsException()
{
mitk::Surface::Pointer surface = mitk::Surface::New();
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
surface->SetVtkPolyData(polyData);
_MITK_TEST_FOR_EXCEPTION(mitk::ACVD::Remesh(surface.GetPointer(), 0, 100, 0.0), mitk::Exception, "Remesh_SurfaceHasNoPolygons_ThrowsException")
}
static void Remesh_SurfaceIsValid_ReturnsRemeshedSurface(const std::string& filename, unsigned int t, int numVertices, double gradation, int subsampling, double edgeSplitting, int optimizationLevel, bool forceManifold, bool boundaryFixing)
{
mitk::Surface::ConstPointer surface = mitk::IOUtil::LoadSurface(filename).GetPointer();
mitk::Surface::Pointer remeshedSurface = mitk::ACVD::Remesh(surface, t, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing);
MITK_TEST_CONDITION(remeshedSurface.IsNotNull() && remeshedSurface->GetVtkPolyData() != NULL && remeshedSurface->GetVtkPolyData()->GetNumberOfPolys() != 0, "Remesh_SurfaceIsValid_ReturnsRemeshedSurface")
}
int mitkACVDTest(int argc, char* argv[])
{
if (argc != 10)
{
MITK_ERROR << "Invalid argument count!\n"
<< "Usage: mitkACVDTest <filename> <t> <numVertices> <gradation> <subsampling>\n"
<< " <edgeSplitting> <optimizationLevel> <forceManifiold>\n"
<< " <boundaryFixing>\n"
<< " See MITK API documentation of mitk::ACVD::Remesh() for details.";
return EXIT_FAILURE;
}
const std::string filename = argv[1];
const unsigned int t = lexical_cast<unsigned int>(argv[2]);
const int numVertices = lexical_cast<int>(argv[3]);
const double gradation = lexical_cast<double>(argv[4]);
const int subsampling = lexical_cast<int>(argv[5]);
const double edgeSplitting = lexical_cast<double>(argv[6]);
const int optimizationLevel = lexical_cast<int>(argv[7]);
const bool forceManifold = lexical_cast<bool>(argv[8]);
const bool boundaryFixing = lexical_cast<bool>(argv[9]);
MITK_TEST_BEGIN("mitkACVDTest")
+ vtkDebugLeaks::SetExitError(0);
+
Remesh_SurfaceIsNull_ThrowsException();
Remesh_PolyDataIsNull_ThrowsException();
Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException();
Remesh_SurfaceHasNoPolygons_ThrowsException();
Remesh_SurfaceIsValid_ReturnsRemeshedSurface(filename, t, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing);
MITK_TEST_END()
}
diff --git a/Modules/SceneSerialization/CMakeLists.txt b/Modules/SceneSerialization/CMakeLists.txt
index 461ad17ea5..56710c481d 100644
--- a/Modules/SceneSerialization/CMakeLists.txt
+++ b/Modules/SceneSerialization/CMakeLists.txt
@@ -1,8 +1,8 @@
MITK_CREATE_MODULE(
- INCLUDE_DIRS BaseDataSerializer BasePropertySerializer BasePropertyDeserializer
+ INCLUDE_DIRS BaseDataSerializer
DEPENDS MitkSceneSerializationBase
PACKAGE_DEPENDS Poco
WARNINGS_AS_ERRORS
)
add_subdirectory(Testing)
diff --git a/Modules/SceneSerialization/mitkSceneIO.cpp b/Modules/SceneSerialization/mitkSceneIO.cpp
index 5df2e1a6d3..a0a7348a9f 100644
--- a/Modules/SceneSerialization/mitkSceneIO.cpp
+++ b/Modules/SceneSerialization/mitkSceneIO.cpp
@@ -1,537 +1,531 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <Poco/TemporaryFile.h>
#include <Poco/Path.h>
#include <Poco/Delegate.h>
#include <Poco/Zip/Compress.h>
#include <Poco/Zip/Decompress.h>
#include "mitkSceneIO.h"
#include "mitkBaseDataSerializer.h"
#include "mitkPropertyListSerializer.h"
#include "mitkSceneReader.h"
#include "mitkProgressBar.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkStandaloneDataStorage.h"
#include <mitkStandardFileLocations.h>
#include <itkObjectFactoryBase.h>
#include <tinyxml.h>
#include <fstream>
#include <sstream>
+#include <mitkIOUtil.h>
#include "itksys/SystemTools.hxx"
mitk::SceneIO::SceneIO()
-:m_WorkingDirectory(""),
- m_UnzipErrors(0)
+ :m_WorkingDirectory(""),
+ m_UnzipErrors(0)
{
}
mitk::SceneIO::~SceneIO()
{
}
std::string mitk::SceneIO::CreateEmptyTempDirectory()
{
-
mitk::UIDGenerator uidGen("UID_",6);
//std::string returnValue = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + Poco::Path::separator() + "SceneIOTemp" + uidGen.GetUID();
std::string returnValue = Poco::Path::temp() + "SceneIOTemp" + uidGen.GetUID();
std::string uniquename = returnValue + Poco::Path::separator();
Poco::File tempdir( uniquename );
try
{
bool existsNot = tempdir.createDirectory();
if (!existsNot)
- {
+ {
MITK_ERROR << "Warning: Directory already exitsts: " << uniquename << " (choosing another)";
returnValue = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + Poco::Path::separator() + "SceneIOTempDirectory" + uidGen.GetUID();
uniquename = returnValue + Poco::Path::separator();
Poco::File tempdir2( uniquename );
if (!tempdir2.createDirectory())
- {
+ {
MITK_ERROR << "Warning: Second directory also already exitsts: " << uniquename;
- }
}
+ }
}
catch( std::exception& e )
{
MITK_ERROR << "Could not create temporary directory " << uniquename << ":" << e.what();
return "";
}
-
return returnValue;
}
mitk::DataStorage::Pointer mitk::SceneIO::LoadScene( const std::string& filename,
- DataStorage* pStorage,
- bool clearStorageFirst )
+ DataStorage* pStorage,
+ bool clearStorageFirst )
{
// prepare data storage
DataStorage::Pointer storage = pStorage;
if ( storage.IsNull() )
{
storage = StandaloneDataStorage::New().GetPointer();
}
if ( clearStorageFirst )
{
try
{
storage->Remove( storage->GetAll() );
}
catch(...)
{
MITK_ERROR << "DataStorage cannot be cleared properly.";
}
}
// test input filename
if ( filename.empty() )
{
MITK_ERROR << "No filename given. Not possible to load scene.";
return storage;
}
// test if filename can be read
std::ifstream file( filename.c_str(), std::ios::binary );
if (!file.good())
{
MITK_ERROR << "Cannot open '" << filename << "' for reading";
return storage;
}
// get new temporary directory
m_WorkingDirectory = CreateEmptyTempDirectory();
if (m_WorkingDirectory.empty())
{
MITK_ERROR << "Could not create temporary directory. Cannot open scene files.";
return storage;
}
// unzip all filenames contents to temp dir
m_UnzipErrors = 0;
Poco::Zip::Decompress unzipper( file, Poco::Path( m_WorkingDirectory ) );
unzipper.EError += Poco::Delegate<SceneIO, std::pair<const Poco::Zip::ZipLocalFileHeader, const std::string> >(this, &SceneIO::OnUnzipError);
unzipper.EOk += Poco::Delegate<SceneIO, std::pair<const Poco::Zip::ZipLocalFileHeader, const Poco::Path> >(this, &SceneIO::OnUnzipOk);
unzipper.decompressAllFiles();
unzipper.EError -= Poco::Delegate<SceneIO, std::pair<const Poco::Zip::ZipLocalFileHeader, const std::string> >(this, &SceneIO::OnUnzipError);
unzipper.EOk -= Poco::Delegate<SceneIO, std::pair<const Poco::Zip::ZipLocalFileHeader, const Poco::Path> >(this, &SceneIO::OnUnzipOk);
if ( m_UnzipErrors )
{
MITK_ERROR << "There were " << m_UnzipErrors << " errors unzipping '" << filename << "'. Will attempt to read whatever could be unzipped.";
}
// test if index.xml exists
// parse index.xml with TinyXML
- TiXmlDocument document( m_WorkingDirectory + Poco::Path::separator() + "index.xml" );
+ TiXmlDocument document( m_WorkingDirectory + mitk::IOUtil::GetDirectorySeparator() + "index.xml" );
if (!document.LoadFile())
{
- MITK_ERROR << "Could not open/read/parse " << m_WorkingDirectory << "/index.xml\nTinyXML reports: " << document.ErrorDesc() << std::endl;
+ MITK_ERROR << "Could not open/read/parse " << m_WorkingDirectory << mitk::IOUtil::GetDirectorySeparator() << "index.xml\nTinyXML reports: " << document.ErrorDesc() << std::endl;
return storage;
}
SceneReader::Pointer reader = SceneReader::New();
if ( !reader->LoadScene( document, m_WorkingDirectory, storage ) )
{
MITK_ERROR << "There were errors while loading scene file " << filename << ". Your data may be corrupted";
}
// delete temp directory
try
{
Poco::File deleteDir( m_WorkingDirectory );
deleteDir.remove(true); // recursive
}
catch(...)
{
MITK_ERROR << "Could not delete temporary directory " << m_WorkingDirectory;
}
// return new data storage, even if empty or uncomplete (return as much as possible but notify calling method)
return storage;
-
}
bool mitk::SceneIO::SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes, const DataStorage* storage,
- const std::string& filename)
+ const std::string& filename)
{
if (!sceneNodes)
{
MITK_ERROR << "No set of nodes given. Not possible to save scene.";
return false;
}
if (!storage)
{
MITK_ERROR << "No data storage given. Not possible to save scene."; // \TODO: Technically, it would be possible to save the nodes without their relation
return false;
}
if ( filename.empty() )
{
MITK_ERROR << "No filename given. Not possible to save scene.";
return false;
}
try
{
-
m_FailedNodes = DataStorage::SetOfObjects::New();
m_FailedProperties = PropertyList::New();
// start XML DOM
TiXmlDocument document;
TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" ); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere...
document.LinkEndChild( decl );
TiXmlElement* version = new TiXmlElement("Version");
version->SetAttribute("Writer", __FILE__ );
version->SetAttribute("Revision", "$Revision: 17055 $" );
version->SetAttribute("FileVersion", 1 );
document.LinkEndChild(version);
//DataStorage::SetOfObjects::ConstPointer sceneNodes = storage->GetSubset( predicate );
if ( sceneNodes.IsNull() )
{
MITK_WARN << "Saving empty scene to " << filename;
}
else
{
if ( sceneNodes->size() == 0 )
{
MITK_WARN << "Saving empty scene to " << filename;
}
- MITK_INFO << "Storing scene with " << sceneNodes->size() << " objects to " << filename;
+ MITK_INFO << "Storing scene with " << sceneNodes->size() << " objects to " << filename;
m_WorkingDirectory = CreateEmptyTempDirectory();
if (m_WorkingDirectory.empty())
{
MITK_ERROR << "Could not create temporary directory. Cannot create scene files.";
return false;
}
ProgressBar::GetInstance()->AddStepsToDo( sceneNodes->size() );
// find out about dependencies
typedef std::map< DataNode*, std::string > UIDMapType;
typedef std::map< DataNode*, std::list<std::string> > SourcesMapType;
UIDMapType nodeUIDs; // for dependencies: ID of each node
SourcesMapType sourceUIDs; // for dependencies: IDs of a node's parent nodes
UIDGenerator nodeUIDGen("OBJECT_");
for (DataStorage::SetOfObjects::const_iterator iter = sceneNodes->begin();
- iter != sceneNodes->end();
- ++iter)
+ iter != sceneNodes->end();
+ ++iter)
{
DataNode* node = iter->GetPointer();
if (!node)
continue; // unlikely event that we get a NULL pointer as an object for saving. just ignore
// generate UIDs for all source objects
DataStorage::SetOfObjects::ConstPointer sourceObjects = storage->GetSources( node );
for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = sourceObjects->begin();
- sourceIter != sourceObjects->end();
- ++sourceIter )
+ sourceIter != sourceObjects->end();
+ ++sourceIter )
{
if ( std::find( sceneNodes->begin(), sceneNodes->end(), *sourceIter ) == sceneNodes->end() )
continue; // source is not saved, so don't generate a UID for this source
// create a uid for the parent object
if ( nodeUIDs[ *sourceIter ].empty() )
{
nodeUIDs[ *sourceIter ] = nodeUIDGen.GetUID();
}
// store this dependency for writing
sourceUIDs[ node ].push_back( nodeUIDs[*sourceIter] );
}
if ( nodeUIDs[ node ].empty() )
{
nodeUIDs[ node ] = nodeUIDGen.GetUID();
}
}
// write out objects, dependencies and properties
for (DataStorage::SetOfObjects::const_iterator iter = sceneNodes->begin();
- iter != sceneNodes->end();
- ++iter)
+ iter != sceneNodes->end();
+ ++iter)
{
DataNode* node = iter->GetPointer();
if (node)
{
TiXmlElement* nodeElement = new TiXmlElement("node");
std::string filenameHint( node->GetName() );
filenameHint = itksys::SystemTools::MakeCindentifier(filenameHint.c_str()); // escape filename <-- only allow [A-Za-z0-9_], replace everything else with _
// store dependencies
UIDMapType::iterator searchUIDIter = nodeUIDs.find(node);
if ( searchUIDIter != nodeUIDs.end() )
{
// store this node's ID
nodeElement->SetAttribute("UID", searchUIDIter->second.c_str() );
}
SourcesMapType::iterator searchSourcesIter = sourceUIDs.find(node);
if ( searchSourcesIter != sourceUIDs.end() )
{
// store all source IDs
for ( std::list<std::string>::iterator sourceUIDIter = searchSourcesIter->second.begin();
- sourceUIDIter != searchSourcesIter->second.end();
- ++sourceUIDIter )
+ sourceUIDIter != searchSourcesIter->second.end();
+ ++sourceUIDIter )
{
TiXmlElement* uidElement = new TiXmlElement("source");
uidElement->SetAttribute("UID", sourceUIDIter->c_str() );
nodeElement->LinkEndChild( uidElement );
}
}
// store basedata
if ( BaseData* data = node->GetData() )
{
//std::string filenameHint( node->GetName() );
bool error(false);
TiXmlElement* dataElement( SaveBaseData( data, filenameHint, error ) ); // returns a reference to a file
if (error)
{
m_FailedNodes->push_back( node );
}
// store basedata properties
PropertyList* propertyList = data->GetPropertyList();
if (propertyList && !propertyList->IsEmpty() )
{
TiXmlElement* baseDataPropertiesElement( SavePropertyList( propertyList, filenameHint + "-data") ); // returns a reference to a file
dataElement->LinkEndChild( baseDataPropertiesElement );
}
nodeElement->LinkEndChild( dataElement );
}
// store all renderwindow specific propertylists
if (RenderingManager::IsInstantiated())
{
const RenderingManager::RenderWindowVector& allRenderWindows( RenderingManager::GetInstance()->GetAllRegisteredRenderWindows() );
for ( RenderingManager::RenderWindowVector::const_iterator rw = allRenderWindows.begin();
- rw != allRenderWindows.end();
- ++rw)
+ rw != allRenderWindows.end();
+ ++rw)
{
if (vtkRenderWindow* renderWindow = *rw)
{
std::string renderWindowName( mitk::BaseRenderer::GetInstance(renderWindow)->GetName() );
BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(renderWindow);
PropertyList* propertyList = node->GetPropertyList(renderer);
if ( propertyList && !propertyList->IsEmpty() )
{
TiXmlElement* renderWindowPropertiesElement( SavePropertyList( propertyList, filenameHint + "-" + renderWindowName) ); // returns a reference to a file
renderWindowPropertiesElement->SetAttribute("renderwindow", renderWindowName);
nodeElement->LinkEndChild( renderWindowPropertiesElement );
}
}
}
}
// don't forget the renderwindow independent list
PropertyList* propertyList = node->GetPropertyList();
if ( propertyList && !propertyList->IsEmpty() )
{
TiXmlElement* propertiesElement( SavePropertyList( propertyList, filenameHint + "-node") ); // returns a reference to a file
nodeElement->LinkEndChild( propertiesElement );
}
document.LinkEndChild( nodeElement );
}
else
{
MITK_WARN << "Ignoring NULL node during scene serialization.";
}
ProgressBar::GetInstance()->Progress();
} // end for all nodes
-
} // end if sceneNodes
if ( !document.SaveFile( m_WorkingDirectory + Poco::Path::separator() + "index.xml" ) )
{
MITK_ERROR << "Could not write scene to " << m_WorkingDirectory << Poco::Path::separator() << "index.xml" << "\nTinyXML reports '" << document.ErrorDesc() << "'";
return false;
}
else
{
try
{
Poco::File deleteFile( filename.c_str() );
if (deleteFile.exists())
{
deleteFile.remove();
}
// create zip at filename
std::ofstream file( filename.c_str(), std::ios::binary | std::ios::out);
if (!file.good())
{
MITK_ERROR << "Could not open a zip file for writing: '" << filename << "'";
return false;
}
else
{
Poco::Zip::Compress zipper( file, true );
Poco::Path tmpdir( m_WorkingDirectory );
zipper.addRecursive( tmpdir );
zipper.close();
}
try
{
Poco::File deleteDir( m_WorkingDirectory );
deleteDir.remove(true); // recursive
}
catch(...)
{
MITK_ERROR << "Could not delete temporary directory " << m_WorkingDirectory;
return false; // ok?
}
}
catch(std::exception& e)
{
MITK_ERROR << "Could not create ZIP file from " << m_WorkingDirectory << "\nReason: " << e.what();
return false;
}
return true;
}
}
catch(std::exception& e)
{
MITK_ERROR << "Caught exception during saving temporary files to disk. Error description: '" << e.what() << "'";
return false;
}
}
-
TiXmlElement* mitk::SceneIO::SaveBaseData( BaseData* data, const std::string& filenamehint, bool& error )
{
assert(data);
error = true;
// find correct serializer
// the serializer must
// - create a file containing all information to recreate the BaseData object --> needs to know where to put this file (and a filename?)
// - TODO what to do about writers that creates one file per timestep?
TiXmlElement* element = new TiXmlElement("data");
element->SetAttribute( "type", data->GetNameOfClass() );
// construct name of serializer class
std::string serializername(data->GetNameOfClass());
serializername += "Serializer";
std::list<itk::LightObject::Pointer> thingsThatCanSerializeThis = itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str());
if (thingsThatCanSerializeThis.size() < 1)
{
MITK_ERROR << "No serializer found for " << data->GetNameOfClass() << ". Skipping object";
}
for ( std::list<itk::LightObject::Pointer>::iterator iter = thingsThatCanSerializeThis.begin();
- iter != thingsThatCanSerializeThis.end();
- ++iter )
+ iter != thingsThatCanSerializeThis.end();
+ ++iter )
{
if (BaseDataSerializer* serializer = dynamic_cast<BaseDataSerializer*>( iter->GetPointer() ) )
{
serializer->SetData(data);
serializer->SetFilenameHint(filenamehint);
serializer->SetWorkingDirectory( m_WorkingDirectory );
try
{
std::string writtenfilename = serializer->Serialize();
element->SetAttribute("file", writtenfilename);
error = false;
}
catch (std::exception& e)
{
MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what();
}
break;
}
}
return element;
}
TiXmlElement* mitk::SceneIO::SavePropertyList( PropertyList* propertyList, const std::string& filenamehint)
{
assert(propertyList);
// - TODO what to do about shared properties (same object in two lists or behind several keys)?
TiXmlElement* element = new TiXmlElement("properties");
// construct name of serializer class
PropertyListSerializer::Pointer serializer = PropertyListSerializer::New();
serializer->SetPropertyList(propertyList);
serializer->SetFilenameHint(filenamehint);
serializer->SetWorkingDirectory( m_WorkingDirectory );
try
{
std::string writtenfilename = serializer->Serialize();
element->SetAttribute("file", writtenfilename);
PropertyList::Pointer failedProperties = serializer->GetFailedProperties();
if (failedProperties.IsNotNull())
{
// move failed properties to global list
m_FailedProperties->ConcatenatePropertyList( failedProperties, true );
}
}
catch (std::exception& e)
{
MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what();
}
return element;
}
-
const mitk::SceneIO::FailedBaseDataListType* mitk::SceneIO::GetFailedNodes()
{
return m_FailedNodes.GetPointer();
}
const mitk::PropertyList* mitk::SceneIO::GetFailedProperties()
{
return m_FailedProperties;
}
void mitk::SceneIO::OnUnzipError(const void* /*pSender*/, std::pair<const Poco::Zip::ZipLocalFileHeader, const std::string>& info)
{
++m_UnzipErrors;
MITK_ERROR << "Error while unzipping: " << info.second;
}
void mitk::SceneIO::OnUnzipOk(const void* /*pSender*/, std::pair<const Poco::Zip::ZipLocalFileHeader, const Poco::Path>& /*info*/)
{
// MITK_INFO << "Unzipped ok: " << info.second.toString();
-}
+}
\ No newline at end of file
diff --git a/Modules/SceneSerialization/mitkSceneReaderV1.cpp b/Modules/SceneSerialization/mitkSceneReaderV1.cpp
index 914b3b8ff3..5439781217 100644
--- a/Modules/SceneSerialization/mitkSceneReaderV1.cpp
+++ b/Modules/SceneSerialization/mitkSceneReaderV1.cpp
@@ -1,361 +1,367 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSceneReaderV1.h"
#include "mitkSerializerMacros.h"
#include "mitkDataNodeFactory.h"
#include "mitkBaseRenderer.h"
#include "mitkPropertyListDeserializer.h"
#include "mitkProgressBar.h"
#include "Poco/Path.h"
#include <mitkRenderingModeProperty.h>
MITK_REGISTER_SERIALIZER(SceneReaderV1)
bool mitk::SceneReaderV1::LoadScene( TiXmlDocument& document, const std::string& workingDirectory, DataStorage* storage )
{
assert(storage);
bool error(false);
// TODO prepare to detect errors (such as cycles) from wrongly written or edited xml files
//Get number of elements to initialze progress bar
// 1. if there is a <data type="..." file="..."> element,
// - construct a name for the appropriate serializer
// - try to instantiate this serializer via itk object factory
// - if serializer could be created, use it to read the file into a BaseData object
// - if successful, call the new node's SetData(..)
// create a node for the tag "data" and test if node was created
typedef std::vector<mitk::DataNode::Pointer> DataNodeVector;
DataNodeVector DataNodes;
unsigned int listSize = 0;
for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL; element = element->NextSiblingElement("node") )
{
++listSize;
- DataNodes.push_back( LoadBaseDataFromDataTag( element->FirstChildElement("data"), workingDirectory, error ) );
+ }
+
+ ProgressBar::GetInstance()->AddStepsToDo(listSize * 2);
+
+ for (TiXmlElement* element = document.FirstChildElement("node"); element != NULL; element = element->NextSiblingElement("node"))
+ {
+ DataNodes.push_back(LoadBaseDataFromDataTag(element->FirstChildElement("data"), workingDirectory, error));
+ ProgressBar::GetInstance()->Progress();
}
OrderedLayers orderedLayers;
this->GetLayerOrder(document, workingDirectory, DataNodes, orderedLayers);
- ProgressBar::GetInstance()->AddStepsToDo( listSize );
// iterate all nodes
// first level nodes should be <node> elements
DataNodeVector::iterator nit = DataNodes.begin();
for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit )
{
mitk::DataNode::Pointer node = *nit;
// in case dataXmlElement is valid test whether it containts the "properties" child tag
// and process further if and only if yes
TiXmlElement *dataXmlElement = element->FirstChildElement("data");
if( dataXmlElement && dataXmlElement->FirstChildElement("properties") )
{
TiXmlElement *baseDataElement = dataXmlElement->FirstChildElement("properties");
if ( node->GetData() )
{
DecorateBaseDataWithProperties( node->GetData(), baseDataElement, workingDirectory);
}
else
{
MITK_WARN << "BaseData properties stored in scene file, but BaseData can't be read" << std::endl;
}
}
// 2. check child nodes
const char* uida = element->Attribute("UID");
std::string uid("");
if (uida)
{
uid = uida;
m_NodeForID[uid] = node.GetPointer();
m_IDForNode[ node.GetPointer() ] = uid;
}
else
{
MITK_ERROR << "No UID found for current node. Node will have no parents.";
error = true;
}
// 3. if there are <properties> nodes,
// - instantiate the appropriate PropertyListDeSerializer
// - use them to construct PropertyList objects
// - add these properties to the node (if necessary, use renderwindow name)
bool success = DecorateNodeWithProperties(node, element, workingDirectory);
if (!success)
{
MITK_ERROR << "Could not load properties for node.";
error = true;
}
// remember node for later adding to DataStorage
//node->GetIntProperty("layer", layer);
int layer;
OrderedLayers::iterator it = orderedLayers.find(uid);
layer = (*it).second;
m_OrderedNodePairs.insert( std::make_pair( layer, std::make_pair( node, std::list<std::string>() ) ) );
// 4. if there are <source> elements, remember parent objects
for( TiXmlElement* source = element->FirstChildElement("source"); source != NULL; source = source->NextSiblingElement("source") )
{
const char* sourceUID = source->Attribute("UID");
if (sourceUID)
{
m_OrderedNodePairs[layer].second.push_back( std::string(sourceUID) );
}
}
ProgressBar::GetInstance()->Progress();
} // end for all <node>
// remove all unknown parent UIDs
for (LayerPropertyMapType::iterator nodesIter = m_OrderedNodePairs.begin();
nodesIter != m_OrderedNodePairs.end();
++nodesIter)
{
for (std::list<std::string>::iterator parentsIter = nodesIter->second.second.begin();
parentsIter != nodesIter->second.second.end();)
{
if (m_NodeForID.find( *parentsIter ) == m_NodeForID.end())
{
parentsIter = nodesIter->second.second.erase( parentsIter );
MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects.";
error = true;
}
else
{
++parentsIter;
}
}
}
// repeat
// for all created nodes
unsigned int lastMapSize(0);
while ( lastMapSize != m_OrderedNodePairs.size()) // this is to prevent infinite loops; each iteration must at least add one node to DataStorage
{
lastMapSize = m_OrderedNodePairs.size();
for (LayerPropertyMapType::iterator nodesIter = m_OrderedNodePairs.begin();
nodesIter != m_OrderedNodePairs.end();
++nodesIter)
{
bool addNow(true);
// if any parent node is not yet in DataStorage, skip node for now and check later
for (std::list<std::string>::iterator parentsIter = nodesIter->second.second.begin();
parentsIter != nodesIter->second.second.end();
++parentsIter)
{
if ( !storage->Exists( m_NodeForID[ *parentsIter ] ) )
{
addNow = false;
break;
}
}
if (addNow)
{
DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New();
for (std::list<std::string>::iterator parentsIter = nodesIter->second.second.begin();
parentsIter != nodesIter->second.second.end();
++parentsIter)
{
parents->push_back( m_NodeForID[ *parentsIter ] );
}
// if all parents are found in datastorage (or are unknown), add node to DataStorage
storage->Add( nodesIter->second.first, parents );
// remove this node from m_OrderedNodePairs
m_OrderedNodePairs.erase( nodesIter );
// break this for loop because iterators are probably invalid
break;
}
}
}
// All nodes that are still in m_OrderedNodePairs at this point are not part of a proper directed graph structure. We'll add such nodes without any parent information.
for (LayerPropertyMapType::iterator nodesIter = m_OrderedNodePairs.begin();
nodesIter != m_OrderedNodePairs.end();
++nodesIter)
{
storage->Add( nodesIter->second.first );
MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage without parents.";
error = true;
}
return !error;
}
void mitk::SceneReaderV1::GetLayerOrder(TiXmlDocument& document, const std::string& workingDirectory, std::vector<mitk::DataNode::Pointer> DataNodes, OrderedLayers& order)
{
typedef std::vector<mitk::DataNode::Pointer> DataNodeVector;
DataNodeVector::iterator nit = DataNodes.begin();
for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit )
{
DataNode::Pointer node = *nit;
DecorateNodeWithProperties(node, element, workingDirectory);
int layer;
node->GetIntProperty("layer", layer);
std::string uid = element->Attribute("UID");
this->m_UnorderedLayers.insert( std::make_pair( layer, uid ) );
}
int lastLayer = itk::NumericTraits<int>::min();
UnorderedLayers::iterator it;
for (it = m_UnorderedLayers.begin(); it != m_UnorderedLayers.end(); it++)
{
int currentLayer = (*it).first;
if (currentLayer == lastLayer)
{
++currentLayer;
}
order.insert( std::make_pair( (*it).second, currentLayer ) );
lastLayer = currentLayer;
}
}
mitk::DataNode::Pointer mitk::SceneReaderV1::LoadBaseDataFromDataTag( TiXmlElement* dataElement, const std::string& workingDirectory, bool& error )
{
DataNode::Pointer node;
if (dataElement)
{
const char* filename( dataElement->Attribute("file") );
if ( filename )
{
DataNodeFactory::Pointer factory = DataNodeFactory::New();
factory->SetFileName( workingDirectory + Poco::Path::separator() + filename );
try
{
factory->Update();
node = factory->GetOutput();
}
catch (std::exception& e)
{
MITK_ERROR << "Error during attempt to read '" << filename << "'. Exception says: " << e.what();
error = true;
}
if (node.IsNull())
{
MITK_ERROR << "Error during attempt to read '" << filename << "'. Factory returned NULL object.";
error = true;
}
}
}
// in case there was no <data> element we create a new empty node (for appending a propertylist later)
if (node.IsNull())
{
node = DataNode::New();
}
return node;
}
bool mitk::SceneReaderV1::DecorateNodeWithProperties(DataNode* node, TiXmlElement* nodeElement, const std::string& workingDirectory)
{
assert(node);
assert(nodeElement);
bool error(false);
for( TiXmlElement* properties = nodeElement->FirstChildElement("properties"); properties != NULL; properties = properties->NextSiblingElement("properties") )
{
const char* propertiesfilea( properties->Attribute("file") );
std::string propertiesfile( propertiesfilea ? propertiesfilea : "" );
const char* renderwindowa( properties->Attribute("renderwindow") );
std::string renderwindow( renderwindowa ? renderwindowa : "" );
PropertyList::Pointer propertyList = node->GetPropertyList(renderwindow); // DataNode implementation always returns a propertylist
// clear all properties from node that might be set by DataNodeFactory during loading
propertyList->Clear();
// use deserializer to construct new properties
PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New();
deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile);
bool success = deserializer->Deserialize();
error |= !success;
PropertyList::Pointer readProperties = deserializer->GetOutput();
if (readProperties.IsNotNull())
{
propertyList->ConcatenatePropertyList( readProperties, true ); // true = replace
}
else
{
MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell your developer.";
error = true;
}
}
return !error;
}
bool mitk::SceneReaderV1::DecorateBaseDataWithProperties(BaseData::Pointer data, TiXmlElement *baseDataNodeElem, const std::string &workingDir)
{
// check given variables, initialize error variable
assert(baseDataNodeElem);
bool error(false);
// get the file name stored in the <properties ...> tag
const char* baseDataPropertyFile( baseDataNodeElem->Attribute("file") );
// check if the filename was found
if(baseDataPropertyFile)
{
//PropertyList::Pointer dataPropList = data->GetPropertyList();
PropertyListDeserializer::Pointer propertyDeserializer = PropertyListDeserializer::New();
// initialize the property reader
propertyDeserializer->SetFilename(workingDir + Poco::Path::separator() + baseDataPropertyFile);
bool ioSuccess = propertyDeserializer->Deserialize();
error = !ioSuccess;
// get the output
PropertyList::Pointer inProperties = propertyDeserializer->GetOutput();
// store the read-in properties to the given node or throw error otherwise
if( inProperties.IsNotNull() )
{
data->SetPropertyList( inProperties );
}
else
{
MITK_ERROR << "The property deserializer did not return a (valid) property list.";
error = true;
}
}
else
{
MITK_ERROR << "Function DecorateBaseDataWithProperties(...) called with false TiXmlElement. \n \t ->Given element does not contain a 'file' attribute. \n";
error = true;
}
return !error;
}
diff --git a/Modules/SceneSerializationBase/CMakeLists.txt b/Modules/SceneSerializationBase/CMakeLists.txt
index 7d5f63c169..c1517fa523 100644
--- a/Modules/SceneSerializationBase/CMakeLists.txt
+++ b/Modules/SceneSerializationBase/CMakeLists.txt
@@ -1,7 +1,7 @@
MITK_CREATE_MODULE(
- INCLUDE_DIRS BaseDataSerializer BasePropertySerializer
+ INCLUDE_DIRS BasePropertySerializer
DEPENDS MitkCore
WARNINGS_AS_ERRORS
)
add_subdirectory(Testing)
diff --git a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp
index 12bed51bf8..1f3582f020 100644
--- a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp
+++ b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp
@@ -1,504 +1,360 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkCorrectorAlgorithm.h"
#include "mitkImageCast.h"
#include "mitkImageAccessByItk.h"
#include "mitkImageDataItem.h"
#include "mitkContourUtils.h"
#include "mitkLegacyAdaptors.h"
#include <mitkContourModelUtils.h>
+
+#include "itkImageDuplicator.h"
+#include "itkImageRegionIterator.h"
+
+
mitk::CorrectorAlgorithm::CorrectorAlgorithm()
:ImageToImageFilter()
{
}
mitk::CorrectorAlgorithm::~CorrectorAlgorithm()
{
}
void mitk::CorrectorAlgorithm::GenerateData()
{
Image::Pointer inputImage = const_cast<Image*>(ImageToImageFilter::GetInput(0));
if (inputImage.IsNull() || inputImage->GetDimension() != 2)
{
itkExceptionMacro("CorrectorAlgorithm needs a 2D image as input.");
}
if (m_Contour.IsNull())
{
itkExceptionMacro("CorrectorAlgorithm needs a Contour object as input.");
}
// copy the input (since m_WorkingImage will be changed later)
m_WorkingImage = inputImage;
TimeGeometry::Pointer originalGeometry = NULL;
if (inputImage->GetTimeGeometry() )
{
originalGeometry = inputImage->GetTimeGeometry()->Clone();
m_WorkingImage->SetTimeGeometry( originalGeometry );
}
else
{
itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy.");
}
Image::Pointer temporarySlice;
// Convert to ipMITKSegmentationTYPE (because TobiasHeimannCorrectionAlgorithm relys on that data type)
{
itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
CastToItkImage( m_WorkingImage, correctPixelTypeImage );
assert (correctPixelTypeImage.IsNotNull() );
// possible bug in CastToItkImage ?
// direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
// mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
// virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
// solution here: we overwrite it with an unity matrix
itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
imageDirection.SetIdentity();
//correctPixelTypeImage->SetDirection(imageDirection);
temporarySlice = this->GetOutput();
// temporarySlice = ImportItkImage( correctPixelTypeImage );
+ m_FillColor = 1;
+ m_EraseColor = 0;
+ ImprovedHeimannCorrectionAlgorithm(correctPixelTypeImage);
CastToMitkImage( correctPixelTypeImage, temporarySlice );
}
-
-
- mitkIpPicDescriptor* temporarySlicePic = mitkIpPicNew();
- CastToIpPicDescriptor( temporarySlice, temporarySlicePic );
- TobiasHeimannCorrectionAlgorithm( temporarySlicePic );
-
temporarySlice->SetTimeGeometry(originalGeometry);
-
}
-void mitk::CorrectorAlgorithm::TobiasHeimannCorrectionAlgorithm(mitkIpPicDescriptor* pic)
+bool mitk::CorrectorAlgorithm::ImprovedHeimannCorrectionAlgorithm(itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic)
{
/*!
Some documentation (not by the original author)
TobiasHeimannCorrectionAlgorithm will be called, when the user has finished drawing a freehand line.
There should be different results, depending on the line's properties:
1. Without any prior segmentation, the start point and the end point of the drawn line will be
connected to a contour and the area enclosed by the contour will be marked as segmentation.
2. When the whole line is inside a segmentation, start and end point will be connected to
a contour and the area of this contour will be subtracted from the segmentation.
3. When the line starts inside a segmentation and ends outside with only a single
transition from segmentation to no-segmentation, nothing will happen.
4. When there are multiple transitions between inside-segmentation and
outside-segmentation, the line will be divided in so called segments. Each segment is
either fully inside or fully outside a segmentation. When it is inside a segmentation, its
enclosed area will be subtracted from the segmentation. When the segment is outside a
segmentation, its enclosed area it will be added to the segmentation.
The algorithm is described in full length in Tobias Heimann's diploma thesis
(MBI Technical Report 145, p. 37 - 40).
*/
- int oaSize = 1000000; // if we need a fixed number, then let it be big
- int* _ofsArray = new int[ oaSize ];
- for (int i=0; i<oaSize; i++) _ofsArray[i] = 0;
-
- std::vector<TSegData> segData;
- segData.reserve( 16 );
-
-
ContourModel::Pointer projectedContour = mitk::ContourModelUtils::ProjectContourTo2DSlice( m_WorkingImage, m_Contour, true, false );
- if (projectedContour.IsNull())
- {
- delete[] _ofsArray;
- return;
- }
+ bool firstPointIsFillingColor = false;
- if (projectedContour->GetNumberOfVertices() < 2)
+ if (projectedContour.IsNull() ||
+ projectedContour->GetNumberOfVertices() < 2 )
{
- delete[] _ofsArray;
- return;
+ return false;
}
- // convert the projected contour into a ipSegmentation format
- mitkIpInt4_t* _points = new mitkIpInt4_t[2 * projectedContour->GetNumberOfVertices()];
- ContourModel::VertexIterator iter = projectedContour->Begin();
- ContourModel::VertexIterator end = projectedContour->End();
- unsigned int index(0);
+ // Read the first point of the contour
+ ContourModel::VertexIterator contourIter = projectedContour->Begin();
+ if (contourIter == projectedContour->End())
+ return false;
+ itk::Index<2> previousIndex;
+ previousIndex[0] = (*contourIter)->Coordinates[0];
+ previousIndex[1] = (*contourIter)->Coordinates[1];
+ ++contourIter;
- while( iter != end)
- {
- _points[ 2 * index + 0 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[0] + 0.5 );
- _points[ 2 * index + 1 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[1] + 0.5 );
- ++index;
- iter++;
- }
+ int currentColor = ( pic->GetPixel(previousIndex) == m_FillColor);
+ firstPointIsFillingColor = currentColor;
+ TSegData currentSegment;
+ int countOfSegments = 1;
- // store ofsets of the drawn line in array
- int _ofsNum = 0;
- unsigned int num = projectedContour->GetNumberOfVertices();
- int lastOfs = -1;
- for (unsigned int i=0; i<num-1; i++)
- {
- float x = _points [2*i] + 0.5;
- float y = _points [2*i+1] + 0.5;
- float difX = _points [2*i+2] - x + 0.5;
- float difY = _points [2*i+3] - y + 0.5;
- float length = sqrt( difX*difX + difY*difY );
- float dx = difX / length;
- float dy = difY / length;
- for (int p=0; ((float)p)<length; p++)
- {
- // if ofs is out of bounds, very nasty things will happen, so better check coordinates:
- if (x<0) x=0.5;
- else if (x>=pic->n[0]) x = pic->n[0]-0.5;
- if (y<0) y=0.5;
- else if (y>=pic->n[1]) y = pic->n[1]-0.5;
- // ok, now store safe ofs
- int ofs = (int)(x) + pic->n[0]*((int)(y));
- x += dx;
- y += dy;
- if (ofs != lastOfs)
- {
- _ofsArray[_ofsNum++] = ofs;
- lastOfs = ofs;
- }
- }
- }
- if (_ofsNum == 0)
+ bool firstSegment = true;
+ ContourModel::VertexIterator contourEnd = projectedContour->End();
+ for (; contourIter != contourEnd; ++contourIter)
{
- // contour was completely outside the binary image
- delete[] _ofsArray;
- delete[] _points;
- return;
- }
-
- ipMITKSegmentationTYPE* picdata = static_cast<ipMITKSegmentationTYPE*>(pic->data);
-
- // divide line in logical segments:
- int numSegments = 0;
- ipMITKSegmentationTYPE state = *(picdata + _ofsArray[0]);
- int ofsP = 1;
- int modifyStart, modifyEnd; // start of first and end of last segment
- bool nextSegment;
- segData.clear();
- do
- {
- nextSegment = false;
- while (ofsP<_ofsNum && *(picdata + _ofsArray[ofsP])==state) ofsP++;
- if (ofsP<_ofsNum)
+ // Get current point
+ itk::Index<2> currentIndex;
+ currentIndex[0] = (*contourIter)->Coordinates[0] +0.5;
+ currentIndex[1] = (*contourIter)->Coordinates[1] +0.5;
+
+ // Calculate length and slope
+ double slopeX = currentIndex[0] - previousIndex[0];
+ double slopeY = currentIndex[1] - previousIndex[1];
+ double length = std::sqrt(slopeX * slopeX + slopeY * slopeY);
+ double deltaX = slopeX / length;
+ double deltaY = slopeY / length;
+
+ for (double i = 0; i <= length && length > 0; i+=1)
{
- int lineStart = ofsP-1;
- if (numSegments==0) modifyStart = ofsP;
- state = *(picdata + _ofsArray[ofsP]);
- while (ofsP<_ofsNum && *(picdata + _ofsArray[ofsP])==state) ofsP++;
- if (ofsP<_ofsNum)
+ itk::Index<2> temporaryIndex;
+ temporaryIndex[0] = previousIndex[0] + deltaX * i;
+ temporaryIndex[1] = previousIndex[1] + deltaY * i;
+ if ( ! pic->GetLargestPossibleRegion().IsInside(temporaryIndex))
+ continue;
+ if ( (pic->GetPixel(temporaryIndex) == m_FillColor) != currentColor)
{
- int lineEnd = ofsP;
- modifyEnd = lineEnd;
- nextSegment = true;
- // now we've got a valid segment from lineStart to lineEnd
- TSegData thisSegData;
- thisSegData.lineStart = lineStart;
- thisSegData.lineEnd = lineEnd;
- thisSegData.modified = modifySegment( lineStart, lineEnd, state, pic, _ofsArray );
- segData.push_back( thisSegData );
- numSegments++;
- }
- }
- } while (nextSegment);
-
- for (int segNr=0; segNr < numSegments; segNr++)
- {
- // draw line if modified:
- if ( segData[segNr].modified )
- {
- for (int i=segData[segNr].lineStart+1; i<segData[segNr].lineEnd; i++)
- {
- *(picdata + _ofsArray[i]) = 1;
+ currentSegment.points.push_back(temporaryIndex);
+ if ( ! firstSegment)
+ {
+ ModifySegment( currentSegment, pic);
+ } else
+ {
+ firstSegment = false;
+ }
+ currentSegment = TSegData();
+ ++countOfSegments;
+ currentColor = (pic->GetPixel(temporaryIndex) == m_FillColor);
}
+ currentSegment.points.push_back(temporaryIndex);
}
+ previousIndex = currentIndex;
}
- if (numSegments == 0)
+ // Check if only on Segment
+ if (firstSegment && currentSegment.points.size() > 0)
{
- if (num <= 1)
- { // only a single pixel. _ofsArray[_ofsNum-1] in else statement would crash, so don't do anything
- // no movement: delete operation
-
- // This behaviour would probably confuse users when they use the correction
- // tool to change a segmentation and it deletes much more than selected
-
- // if (state == 1) ipMITKSegmentationReplaceRegion4N( pic, _ofsArray[0], 0 );
- }
- else if ( *(picdata + _ofsArray[_ofsNum-1]) == *(picdata + _ofsArray[0]))
- {
- // start point and end point both inside or both outside any segmentation
- // normal paint operation
- mitkIpInt4_t* p = new mitkIpInt4_t[2 * num];
- for (unsigned int i = 0; i < num; i++)
+ ContourModel::Pointer projectedContour = mitk::ContourModelUtils::ProjectContourTo2DSlice( m_WorkingImage, m_Contour, true, false );
+ projectedContour->Close();
+ if (firstPointIsFillingColor)
+ {
+ ContourModelUtils::FillContourInSlice(projectedContour, 0, m_WorkingImage, m_EraseColor);
+ } else
{
- p[2 * i] = (mitkIpInt4_t) _points [2 * i];
- p[2 * i + 1] = (mitkIpInt4_t) _points [2 * i + 1];
+ ContourModelUtils::FillContourInSlice(projectedContour, 0, m_WorkingImage, m_FillColor);
}
-
- if (state == 0) ipMITKSegmentationCombineRegion (pic, p, num, 0, IPSEGMENTATION_OR, 1);
- else ipMITKSegmentationCombineRegion (pic, p, num, 0, IPSEGMENTATION_AND, 0);
-
- delete[] p;
- }
}
+ return true;
+}
- int numberOfContourPoints( 0 );
- int oneContourOffset( 0 );
- int newBufferSize( 0 );
+static void ColorSegment(const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic, int fillColor, int eraseColor)
+{
+ int colorMode = (pic->GetPixel(segment.points[0]) == fillColor);
+ int color = 0;
+ if (colorMode)
+ color = eraseColor;
+ else
+ color = fillColor;
- int imageSize = pic->n[0]*pic->n[1];
- for (oneContourOffset = 0; oneContourOffset < imageSize; oneContourOffset++)
- if ( ((ipMITKSegmentationTYPE*) pic->data)[oneContourOffset]> 0) break;
+ std::vector< itk::Index<2> >::const_iterator indexIterator;
+ std::vector< itk::Index<2> >::const_iterator indexEnd;
- float* contourPoints = ipMITKSegmentationGetContour8N( pic, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
+ indexIterator = segment.points.begin();
+ indexEnd = segment.points.end();
- if (contourPoints)
+ for (; indexIterator != indexEnd; ++indexIterator)
{
-
- // copy point from float* to mitk::ContourModel
- ContourModel::Pointer contourInImageIndexCoordinates = mitk::ContourModel::New();
- contourInImageIndexCoordinates->Initialize();
- Point3D newPoint;
- for (int index = 0; index < numberOfContourPoints; ++index)
- {
- newPoint[0] = contourPoints[ 2 * index + 0 ];
- newPoint[1] = contourPoints[ 2 * index + 1];
- newPoint[2] = 0;
-
- contourInImageIndexCoordinates->AddVertex( newPoint );
- }
-
- free(contourPoints);
-
- mitk::ContourModelUtils::FillContourInSlice( contourInImageIndexCoordinates, m_WorkingImage );
+ pic->SetPixel(*indexIterator, color);
}
-
- delete[] _ofsArray;
- delete[] _points;
}
-bool mitk::CorrectorAlgorithm::modifySegment( int lineStart, int lineEnd, ipMITKSegmentationTYPE state, mitkIpPicDescriptor *pic, int* _ofsArray )
+static itk::Index<2> GetFirstPoint(const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic, int fillColor)
{
- // offsets for pixels right, top, left, bottom
- int nbDelta4[4];
- nbDelta4[0]=1; nbDelta4[1]=pic->n[0]; nbDelta4[1]*=-1; // necessary because of unsigned declaration of pic->n
- nbDelta4[2]=-1; nbDelta4[3]=pic->n[0];
-
- // offsets for pixels right, top-right, top, top-left left, bottom-left, bottom, bottom-right
- int nbDelta8[8];
- nbDelta8[0] = 1; nbDelta8[1] = nbDelta4[1]+1; nbDelta8[2] = nbDelta4[1]; nbDelta8[3] = nbDelta4[1]-1;
- nbDelta8[4] = -1; nbDelta8[5] = nbDelta4[3]-1; nbDelta8[6] = nbDelta4[3]; nbDelta8[7] = nbDelta4[3]+1;
-
- ipMITKSegmentationTYPE* picdata = static_cast<ipMITKSegmentationTYPE*>(pic->data);
+ int colorMode = (pic->GetPixel(segment.points[0]) == fillColor);
- ipMITKSegmentationTYPE saveStart = *(picdata + _ofsArray[lineStart]);
- ipMITKSegmentationTYPE saveEnd = *(picdata + _ofsArray[lineEnd]);
- ipMITKSegmentationTYPE newState = ((!state)&1) + 2; // probably equal to: ipMITKSegmentationTYPE newState = 3 - state;
+ std::vector< itk::Index<2> >::const_iterator indexIterator;
+ std::vector< itk::Index<2> >::const_iterator indexEnd;
- // make two copies of pic:
- mitkIpPicDescriptor *seg1 = mitkIpPicClone( pic );
- mitkIpPicDescriptor *seg2 = mitkIpPicClone( pic );
+ indexIterator = segment.points.begin();
+ indexEnd = segment.points.end();
- int i;
-
- // mark line in original
- for (i=lineStart; i<=lineEnd; i++) {
- *(picdata + _ofsArray[i]) = 3;
- }
-
- // mark the first side in copy 1:
- bool firstPix = true;
- bool modified;
- int line = pic->n[0]; // #pixels in line
- int maxOfs = (int)(line * pic->n[1]); // #pixels in slice
-
- for (i=lineStart+1; i<lineEnd; i++) {
- do {
- modified = false;
- for (int nb=0; nb<8; nb++) {
- int nbOfs = _ofsArray[i] + nbDelta8[nb];
- if ( nbOfs < 0 // above first line
- || nbOfs >= maxOfs // below last line
- ) continue;
- ipMITKSegmentationTYPE nbVal = *(picdata + nbOfs);
- ipMITKSegmentationTYPE destVal = *(((ipMITKSegmentationTYPE*)seg1->data) + nbOfs);
- if (nbVal!=3 && destVal!=newState) { // get only neigbhours that are not part of the line itself
- if (firstPix) {
- *(((ipMITKSegmentationTYPE*)seg1->data) + nbOfs) = newState; // this one is used to mark the side!
- firstPix = false;
- modified = true;
- }
- else {
- int tnb = 0;
- while ( tnb < 4
- && ((nbOfs + nbDelta4[tnb]) >= 0) && ((nbOfs + nbDelta4[tnb]) < maxOfs)
- && *(((ipMITKSegmentationTYPE*)seg1->data) + nbOfs + nbDelta4[tnb]) != newState
- )
- tnb++;
-
- if (tnb < 4 && ((nbOfs + nbDelta4[tnb]) >= 0) && ((nbOfs + nbDelta4[tnb]) < maxOfs) ) {
- *(((ipMITKSegmentationTYPE*)seg1->data) + nbOfs) = newState; // we've got a buddy close
- modified = true;
- }
- }
+ for (; indexIterator != indexEnd; ++indexIterator)
+ {
+ itk::Index<2> index;
+ for (int xOffset = -1 ; xOffset < 2; ++xOffset)
+ {
+ for (int yOffset = -1 ; yOffset < 2; ++yOffset)
+ {
+ index[0] = (*indexIterator)[0] - xOffset;
+ index[1] = (*indexIterator)[1] - yOffset;
+ if ((pic->GetPixel(index) == fillColor) != colorMode)
+ {
+ return index;
}
}
- } while (modified);
- }
-
- // mark the other side in copy 2:
- for (i=lineStart+1; i<lineEnd; i++) {
- for (int nb=0; nb<4; nb++) {
- int nbOfs = _ofsArray[i] + nbDelta4[nb];
- if ( nbOfs < 0 // above first line
- || nbOfs >= maxOfs // below last line
- ) continue;
- ipMITKSegmentationTYPE lineVal = *(picdata + nbOfs);
- ipMITKSegmentationTYPE side1Val = *(((ipMITKSegmentationTYPE*)seg1->data) + nbOfs);
- if (lineVal != 3 && side1Val != newState) {
- *(((ipMITKSegmentationTYPE*)seg2->data) + nbOfs) = newState;
- }
- }
- }
-
- // take care of line ends for multiple segments:
- *(((ipMITKSegmentationTYPE*)seg1->data) + _ofsArray[lineStart]) = newState;
- *(((ipMITKSegmentationTYPE*)seg1->data) + _ofsArray[lineEnd]) = newState;
- *(((ipMITKSegmentationTYPE*)seg2->data) + _ofsArray[lineStart]) = newState;
- *(((ipMITKSegmentationTYPE*)seg2->data) + _ofsArray[lineEnd]) = newState;
-
-
- // replace regions:
- newState = (!state)&1;
- int sizeRegion1 = 0, sizeRegion2 = 0;
- for (i=lineStart+1; i<lineEnd; i++) {
- if (*(((ipMITKSegmentationTYPE*)seg1->data) + _ofsArray[i]) != newState) {
- sizeRegion1 += ipMITKSegmentationReplaceRegion4N( seg1, _ofsArray[i], newState );
- }
- if (*(((ipMITKSegmentationTYPE*)seg2->data) + _ofsArray[i]) != newState) {
- sizeRegion2 += ipMITKSegmentationReplaceRegion4N( seg2, _ofsArray[i], newState );
}
}
+ mitkThrow() << "No Starting point is found next to the curve.";
+}
- // combine image:
- //printf( "Size Region1 = %8i Size Region2 = %8i\n", sizeRegion1, sizeRegion2 );
- int sizeDif;
- ipMITKSegmentationTYPE *current, *segSrc;
- if (sizeRegion1 < sizeRegion2) {
- segSrc = (ipMITKSegmentationTYPE*)seg1->data;
- sizeDif = sizeRegion2 - sizeRegion1;
- }
- else {
- segSrc = (ipMITKSegmentationTYPE*)seg2->data;
- sizeDif = sizeRegion1 - sizeRegion2;
+static int FillRegion(const itk::Index<2> startIndex, itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic, int fillColor, int eraseColor)
+{
+ int numberOfPixel = 0;
+ int mode = (pic->GetPixel(startIndex) == fillColor);
+ int drawColor = fillColor;
+ if (mode)
+ {
+ drawColor = eraseColor;
}
- modified = false;
- if (sizeDif > 2*(lineEnd-lineStart)) {
- // decision is safe enough:
- ipMITKSegmentationTYPE *end = picdata + (pic->n[0]*pic->n[1]);
- for (current = picdata; current<end; current++) {
- if (*segSrc == newState) *current = newState;
- segSrc++;
- }
- modified = true;
+ std::vector<itk::Index<2> > workPoints;
+ workPoints.push_back(startIndex);
+ while (workPoints.size() > 0)
+ {
+ itk::Index<2> currentIndex = workPoints.back();
+ workPoints.pop_back();
+ if ((pic->GetPixel(currentIndex) == fillColor) == mode)
+ ++numberOfPixel;
+ pic->SetPixel(currentIndex, drawColor);
+
+ currentIndex[0] -= 1;
+ if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == fillColor) == mode)
+ workPoints.push_back(currentIndex);
+ currentIndex[0] += 2;
+ if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == fillColor) == mode)
+ workPoints.push_back(currentIndex);
+ currentIndex[0] -= 1;
+ currentIndex[1] -= 1;
+ if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == fillColor) == mode)
+ workPoints.push_back(currentIndex);
+ currentIndex[1] += 2;
+ if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == fillColor) == mode)
+ workPoints.push_back(currentIndex);
}
+ return numberOfPixel;
+}
- // restore line:
- for (int i=lineStart+1; i<lineEnd; i++) {
- *(picdata + _ofsArray[i]) = state;
- }
- // restore end points:
- *(picdata + _ofsArray[lineStart]) = saveStart;
- *(picdata + _ofsArray[lineEnd]) = saveEnd;
+static itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer CloneImage(itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic)
+{
+ typedef itk::Image< ipMITKSegmentationTYPE, 2 > ItkImageType;
- mitkIpPicFree( seg1 );
- mitkIpPicFree( seg2 );
+ typedef itk::ImageDuplicator< ItkImageType > DuplicatorType;
+ DuplicatorType::Pointer duplicator = DuplicatorType::New();
+ duplicator->SetInputImage(pic);
+ duplicator->Update();
- return modified;
+ return duplicator->GetOutput();
}
-void mitk::CorrectorAlgorithm::CalculateDifferenceImage( Image* modifiedImage, Image* originalImage )
+static void OverwriteImage(itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer source, itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer target)
{
- /*
- * modifiedImage has ipMITKSegmentationTYPE
- * originalImage may be any type
- *
- * --> we calculate a diff image using ITK, switching for the correct type of originalImage
- */
- m_DifferenceImage = NULL;
- Image::Pointer tmpPtr = originalImage;
- AccessFixedDimensionByItk_1( tmpPtr, ItkCalculateDifferenceImage, 2, modifiedImage );
+ typedef itk::Image< ipMITKSegmentationTYPE, 2 > ItkImageType;
+ typedef itk::ImageRegionIterator<ItkImageType> ImageIteratorType;
+
+ ImageIteratorType sourceIter(source, source->GetLargestPossibleRegion());
+ ImageIteratorType targetIter(target, target->GetLargestPossibleRegion());
+ while ( ! sourceIter.IsAtEnd())
+ {
+ targetIter.Set(sourceIter.Get());
+ ++sourceIter;
+ ++targetIter;
+ }
}
-template<typename TPixel, unsigned int VImageDimension>
-void mitk::CorrectorAlgorithm::ItkCalculateDifferenceImage( itk::Image<TPixel, VImageDimension>* originalImage, Image* modifiedMITKImage )
+bool mitk::CorrectorAlgorithm::ModifySegment(const TSegData &segment, itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic)
{
- typedef itk::Image<ipMITKSegmentationTYPE, VImageDimension> ModifiedImageType;
- typedef itk::Image<short signed int, VImageDimension> DiffImageType;
- typedef itk::ImageRegionConstIterator< itk::Image<TPixel,VImageDimension> > OriginalSliceIteratorType;
- typedef itk::ImageRegionConstIterator< ModifiedImageType > ModifiedSliceIteratorType;
- typedef itk::ImageRegionIterator< DiffImageType > DiffSliceIteratorType;
-
- typename ModifiedImageType::Pointer modifiedImage;
- CastToItkImage( modifiedMITKImage, modifiedImage );
-
- // create new image as a copy of the input
- // this new image is the output of this filter class
- typename DiffImageType::Pointer diffImage;
- m_DifferenceImage = Image::New();
- PixelType pixelType( mitk::MakeScalarPixelType<short>() );
- m_DifferenceImage->Initialize( pixelType, 2, modifiedMITKImage->GetDimensions() );
- CastToItkImage( m_DifferenceImage, diffImage );
-
- // iterators over both input images (original and modified) and the output image (diff)
- ModifiedSliceIteratorType modifiedIterator( modifiedImage, diffImage->GetLargestPossibleRegion() );
- OriginalSliceIteratorType originalIterator( originalImage, diffImage->GetLargestPossibleRegion() );
- DiffSliceIteratorType diffIterator( diffImage, diffImage->GetLargestPossibleRegion() );
-
- modifiedIterator.GoToBegin();
- originalIterator.GoToBegin();
- diffIterator.GoToBegin();
-
- while ( !diffIterator.IsAtEnd() )
+ try
{
- short signed int difference = static_cast<short signed int>( static_cast<signed int>(modifiedIterator.Get()) -
- static_cast<signed int>(originalIterator.Get())); // not good for bigger values ?!
- diffIterator.Set( difference );
+ typedef itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer ItkImagePointerType;
+ // Find the current ColorMode:
+
+ // Kein erster Punkt
+ // Erster Punkt finden
+ ItkImagePointerType firstSideImage = CloneImage(pic);
+ ColorSegment(segment, firstSideImage, m_FillColor, m_EraseColor);
+ ItkImagePointerType secondSideImage = CloneImage(firstSideImage);
+ itk::Index<2> firstPoint = GetFirstPoint(segment, firstSideImage, m_FillColor);
+ int firstSidePixel = FillRegion(firstPoint, firstSideImage, m_FillColor, m_EraseColor);
+
+ // TODO Problem: Was ist wenn keine Zweite Seite vorhanden?
+ try
+ {
+ itk::Index<2> secondPoint = GetFirstPoint(segment, firstSideImage, m_FillColor);
+ int secondSidePixel = FillRegion(secondPoint, secondSideImage, m_FillColor, m_EraseColor);
- ++modifiedIterator;
- ++originalIterator;
- ++diffIterator;
+ if (firstSidePixel < secondSidePixel)
+ {
+ OverwriteImage(firstSideImage, pic);
+ } else
+ {
+ OverwriteImage(secondSideImage, pic);
+ }
+ }
+ catch (mitk::Exception e)
+ {
+ e.what();
+ }
+ return true;
}
-}
-
+ catch(...)
+ {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h
index b2665b81e1..b33a2746c2 100644
--- a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h
+++ b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h
@@ -1,99 +1,91 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkCorrectorAlgorithmhIncluded
#define mitkCorrectorAlgorithmhIncluded
#include "mitkImageToImageFilter.h"
#include <MitkSegmentationExports.h>
#include "mitkContourModel.h"
#include "ipSegmentation.h"
#include <itkImage.h>
namespace mitk
{
-
/**
* This class encapsulates an algorithm, which takes a 2D binary image and a contour.
* The algorithm tests if the line begins and ends inside or outside a segmentation
* and whether areas should be added to or subtracted from the segmentation shape.
*
* This class has two outputs:
- * \li a difference image from GetDifferenceImage()
* \li the modified input image from GetOutput()
*
- * The difference image is an image of the same dimensions as the input. Each pixel has
- * one of three values -1, 0, +1 meaning
- * \li <b>-1</b> this pixel was foreground in the input image and should be removed from the segmentation
- * \li <b>0</b> this pixel needs no change
- * \li <b>+1</b> this pixel was background in the input image and should be added to the segmentation
- *
* The output image is a combination of the original input with the generated difference image.
*
* \sa CorrectorTool2D
*/
class MitkSegmentation_EXPORT CorrectorAlgorithm : public ImageToImageFilter
{
public:
mitkClassMacro(CorrectorAlgorithm, ImageToImageFilter);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/**
* \brief User drawn contour
*/
void SetContour( ContourModel* contour){this->m_Contour = contour;}
/**
* \brief Calculated difference image.
*/
//itkGetObjectMacro(DifferenceImage, Image);
- protected:
// used by TobiasHeimannCorrectionAlgorithm
typedef struct
{
int lineStart;
int lineEnd;
bool modified;
+
+ std::vector< itk::Index<2> > points;
}
TSegData;
+ protected:
+
CorrectorAlgorithm();
virtual ~CorrectorAlgorithm();
// does the actual processing
virtual void GenerateData();
- void TobiasHeimannCorrectionAlgorithm(mitkIpPicDescriptor* pic);
- bool modifySegment( int lineStart, int lineEnd, ipMITKSegmentationTYPE state, mitkIpPicDescriptor *pic, int* _ofsArray );
-
- void CalculateDifferenceImage( Image* modifiedImage, Image* originalImage );
- template<typename TPixel, unsigned int VImageDimension>
- void ItkCalculateDifferenceImage( itk::Image<TPixel, VImageDimension>* originalImage, Image* modifiedMITKImage );
+ bool ImprovedHeimannCorrectionAlgorithm(itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic);
+ bool ModifySegment(const TSegData &segment, itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer pic);
Image::Pointer m_WorkingImage;
ContourModel::Pointer m_Contour;
Image::Pointer m_DifferenceImage;
-};
+ int m_FillColor;
+ int m_EraseColor;
+};
}
#endif
-
diff --git a/Modules/Segmentation/CMakeLists.txt b/Modules/Segmentation/CMakeLists.txt
index fef70bd1b5..5a35144363 100644
--- a/Modules/Segmentation/CMakeLists.txt
+++ b/Modules/Segmentation/CMakeLists.txt
@@ -1,7 +1,7 @@
MITK_CREATE_MODULE(
- INCLUDE_DIRS Algorithms Controllers DataManagement Interactions IO Rendering SegmentationUtilities/BooleanOperations SegmentationUtilities/MorphologicalOperations
+ INCLUDE_DIRS Algorithms Controllers DataManagement Interactions Rendering SegmentationUtilities/BooleanOperations SegmentationUtilities/MorphologicalOperations
DEPENDS MitkAlgorithmsExt MitkIpSegmentation MitkIpFunc MitkLegacyAdaptors MitkSurfaceInterpolation MitkGraphAlgorithms MitkContourModel
PACKAGE_DEPENDS ITK|ITKBinaryMathematicalMorphology+ITKLabelVoting+ITKRegionGrowing+ITKFastMarching+ITKAnisotropicSmoothing+ITKWatersheds
)
add_subdirectory(Testing)
diff --git a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
index b53d0d0879..18f9d35b54 100644
--- a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
@@ -1,711 +1,708 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkRegionGrowingTool.h"
#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkImageDataItem.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkApplicationCursor.h"
#include "ipSegmentation.h"
#include "mitkRegionGrowingTool.xpm"
#include "mitkOverwriteDirectedPlaneImageFilter.h"
#include "mitkExtractDirectedPlaneImageFilterNew.h"
// us
#include <usModule.h>
#include <usModuleResource.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
namespace mitk {
MITK_TOOL_MACRO(MitkSegmentation_EXPORT, RegionGrowingTool, "Region growing tool");
}
#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
mitk::RegionGrowingTool::RegionGrowingTool()
:FeedbackContourTool("PressMoveRelease"),
m_LowerThreshold(200),
m_UpperThreshold(200),
m_InitialLowerThreshold(200),
m_InitialUpperThreshold(200),
m_ScreenYDifference(0),
m_OriginalPicSlice(NULL),
m_SeedPointMemoryOffset(0),
m_VisibleWindow(0),
m_DefaultWindow(0),
- m_MouseDistanceScaleFactor(0.5),
+ m_MouseDistanceScaleFactor(-0.5),
m_LastWorkingSeed(-1),
m_FillFeedbackContour(true)
{
}
mitk::RegionGrowingTool::~RegionGrowingTool()
{
}
void mitk::RegionGrowingTool::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
CONNECT_FUNCTION( "Move", OnMouseMoved);
CONNECT_FUNCTION( "Release", OnMouseReleased);
}
const char** mitk::RegionGrowingTool::GetXPM() const
{
return mitkRegionGrowingTool_xpm;
}
us::ModuleResource mitk::RegionGrowingTool::GetIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("RegionGrowing_48x48.png");
return resource;
}
us::ModuleResource mitk::RegionGrowingTool::GetCursorIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("RegionGrowing_Cursor_32x32.png");
return resource;
}
const char* mitk::RegionGrowingTool::GetName() const
{
return "Region Growing";
}
void mitk::RegionGrowingTool::Activated()
{
Superclass::Activated();
}
void mitk::RegionGrowingTool::Deactivated()
{
Superclass::Deactivated();
}
/**
1 Determine which slice is clicked into
2 Determine if the user clicked inside or outside of the segmentation
3 Depending on the pixel value under the mouse click position, two different things happen: (separated out into OnMousePressedInside and OnMousePressedOutside)
3.1 Create a skeletonization of the segmentation and try to find a nice cut
3.1.1 Call a ipSegmentation algorithm to create a nice cut
3.1.2 Set the result of this algorithm as the feedback contour
3.2 Initialize region growing
3.2.1 Determine memory offset inside the original image
3.2.2 Determine initial region growing parameters from the level window settings of the image
3.2.3 Perform a region growing (which generates a new feedback contour)
*/
bool mitk::RegionGrowingTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
return false;
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
//ToolLogger::SetVerboseness(3);
MITK_DEBUG << "OnMousePressed" << std::endl;
if ( FeedbackContourTool::CanHandleEvent(interactionEvent) > 0.0 )
{
MITK_DEBUG << "OnMousePressed: FeedbackContourTool says ok" << std::endl;
// 1. Find out which slice the user clicked, find out which slice of the toolmanager's reference and working image corresponds to that
if (positionEvent)
{
MITK_DEBUG << "OnMousePressed: got positionEvent" << std::endl;
m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice( positionEvent );
m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
if ( m_WorkingSlice.IsNotNull() ) // can't do anything without the segmentation
{
MITK_DEBUG << "OnMousePressed: got working slice" << std::endl;
// 2. Determine if the user clicked inside or outside of the segmentation
const BaseGeometry* workingSliceGeometry = m_WorkingSlice->GetGeometry();
Point3D mprojectedPointIn2D;
workingSliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D);
itk::Index<2> projectedPointInWorkingSlice2D;
projectedPointInWorkingSlice2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 );
projectedPointInWorkingSlice2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 );
if ( workingSliceGeometry->IsIndexInside( projectedPointInWorkingSlice2D ) )
{
MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << projectedPointInWorkingSlice2D << ") IS in working slice" << std::endl;
// Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
CastToItkImage( m_WorkingSlice, correctPixelTypeImage );
assert (correctPixelTypeImage.IsNotNull() );
// possible bug in CastToItkImage ?
// direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
// mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
// virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
// solution here: we overwrite it with an unity matrix
itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
imageDirection.SetIdentity();
correctPixelTypeImage->SetDirection(imageDirection);
Image::Pointer temporarySlice = Image::New();
// temporarySlice = ImportItkImage( correctPixelTypeImage );
CastToMitkImage( correctPixelTypeImage, temporarySlice );
mitkIpPicDescriptor* workingPicSlice = mitkIpPicNew();
CastToIpPicDescriptor(temporarySlice, workingPicSlice);
int initialWorkingOffset = projectedPointInWorkingSlice2D[1] * workingPicSlice->n[0] + projectedPointInWorkingSlice2D[0];
if ( initialWorkingOffset < static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) &&
initialWorkingOffset >= 0 )
{
// 3. determine the pixel value under the last click
bool inside = static_cast<ipMITKSegmentationTYPE*>(workingPicSlice->data)[initialWorkingOffset] != 0;
m_PaintingPixelValue = inside ? 0 : 1; // if inside, we want to remove a part, otherwise we want to add something
if ( m_LastWorkingSeed >= static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) ||
m_LastWorkingSeed < 0 )
{
inside = false;
}
if ( m_ReferenceSlice.IsNotNull() )
{
MITK_DEBUG << "OnMousePressed: got reference slice" << std::endl;
m_OriginalPicSlice = mitkIpPicNew();
CastToIpPicDescriptor(m_ReferenceSlice, m_OriginalPicSlice);
// 3.1. Switch depending on the pixel value
if (inside)
{
OnMousePressedInside( NULL, interactionEvent, workingPicSlice, initialWorkingOffset);
}
else
{
OnMousePressedOutside( NULL, interactionEvent);
}
}
}
}
}
}
}
MITK_DEBUG << "end OnMousePressed" << std::endl;
return true;
}
/**
3.1 Create a skeletonization of the segmentation and try to find a nice cut
3.1.1 Call a ipSegmentation algorithm to create a nice cut
3.1.2 Set the result of this algorithm as the feedback contour
*/
bool mitk::RegionGrowingTool::OnMousePressedInside( StateMachineAction*, InteractionEvent* interactionEvent, mitkIpPicDescriptor* workingPicSlice, int initialWorkingOffset)
{
if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
return false;
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); // checked in OnMousePressed
// 3.1.1. Create a skeletonization of the segmentation and try to find a nice cut
// apply the skeletonization-and-cut algorithm
// generate contour to remove
// set m_ReferenceSlice = NULL so nothing will happen during mouse move
// remember to fill the contour with 0 in mouserelease
mitkIpPicDescriptor* segmentationHistory = ipMITKSegmentationCreateGrowerHistory( workingPicSlice, m_LastWorkingSeed, NULL ); // free again
if (segmentationHistory)
{
tCutResult cutContour = ipMITKSegmentationGetCutPoints( workingPicSlice, segmentationHistory, initialWorkingOffset ); // tCutResult is a ipSegmentation type
mitkIpPicFree( segmentationHistory );
if (cutContour.cutIt)
{
int timestep = positionEvent->GetSender()->GetTimeStep();
// 3.1.2 copy point from float* to mitk::Contour
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
contourInImageIndexCoordinates->Expand(timestep + 1);
contourInImageIndexCoordinates->SetClosed(true, timestep);
Point3D newPoint;
for (int index = 0; index < cutContour.deleteSize; ++index)
{
newPoint[0] = cutContour.deleteCurve[ 2 * index + 0 ] - 0.5;//correction is needed because the output of the algorithm is center based
newPoint[1] = cutContour.deleteCurve[ 2 * index + 1 ] - 0.5;//and we want our contour displayed corner based.
newPoint[2] = 0.0;
contourInImageIndexCoordinates->AddVertex( newPoint, timestep );
}
free(cutContour.traceline);
free(cutContour.deleteCurve); // perhaps visualize this for fun?
free(cutContour.onGradient);
ContourModel::Pointer contourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( m_WorkingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true: sub 0.5 for ipSegmentation correction
FeedbackContourTool::SetFeedbackContour( *contourInWorldCoordinates );
FeedbackContourTool::SetFeedbackContourVisible(true);
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
m_FillFeedbackContour = true;
}
else
{
m_FillFeedbackContour = false;
}
}
else
{
m_FillFeedbackContour = false;
}
m_ReferenceSlice = NULL;
return true;
}
/**
3.2 Initialize region growing
3.2.1 Determine memory offset inside the original image
3.2.2 Determine initial region growing parameters from the level window settings of the image
3.2.3 Perform a region growing (which generates a new feedback contour)
*/
bool mitk::RegionGrowingTool::OnMousePressedOutside( StateMachineAction*, InteractionEvent* interactionEvent )
{
if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
return false;
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); // checked in OnMousePressed
// 3.2 If we have a reference image, then perform an initial region growing, considering the reference image's level window
// if click was outside the image, don't continue
const BaseGeometry* sliceGeometry = m_ReferenceSlice->GetGeometry();
Point3D mprojectedPointIn2D;
sliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D );
itk::Index<2> projectedPointIn2D;
projectedPointIn2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 );
projectedPointIn2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 );
if ( sliceGeometry->IsIndexInside( mprojectedPointIn2D ) )
{
MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << mprojectedPointIn2D << ") IS in reference slice" << std::endl;
// 3.2.1 Remember Y cursor position and initial seed point
- //m_ScreenYPositionAtStart = static_cast<int>(positionEvent->GetDisplayPosition()[1]);
- m_LastScreenPosition = ApplicationCursor::GetInstance()->GetCursorPosition();
+ m_LastScreenPosition = positionEvent->GetPointerPositionOnScreen();
m_ScreenYDifference = 0;
m_SeedPointMemoryOffset = projectedPointIn2D[1] * m_OriginalPicSlice->n[0] + projectedPointIn2D[0];
m_LastWorkingSeed = m_SeedPointMemoryOffset; // remember for skeletonization
if ( m_SeedPointMemoryOffset < static_cast<int>( m_OriginalPicSlice->n[0] * m_OriginalPicSlice->n[1] ) &&
m_SeedPointMemoryOffset >= 0 )
{
// 3.2.2 Get level window from reference DataNode
// Use some logic to determine initial gray value bounds
LevelWindow lw(0, 500);
m_ToolManager->GetReferenceData(0)->GetLevelWindow(lw); // will fill lw if levelwindow property is present, otherwise won't touch it.
ScalarType currentVisibleWindow = lw.GetWindow();
if (!mitk::Equal(currentVisibleWindow, m_VisibleWindow))
{
m_InitialLowerThreshold = currentVisibleWindow / 20.0;
m_InitialUpperThreshold = currentVisibleWindow / 20.0;
m_LowerThreshold = m_InitialLowerThreshold;
m_UpperThreshold = m_InitialUpperThreshold;
// 3.2.3. Actually perform region growing
mitkIpPicDescriptor* result = PerformRegionGrowingAndUpdateContour(positionEvent->GetSender()->GetTimeStep());
ipMITKSegmentationFree( result);
// display the contour
FeedbackContourTool::SetFeedbackContourVisible(true);
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
m_FillFeedbackContour = true;
}
}
return true;
}
return false;
}
/**
If in region growing mode (m_ReferenceSlice != NULL), then
1. Calculate the new thresholds from mouse position (relative to first position)
2. Perform a new region growing and update the feedback contour
*/
bool mitk::RegionGrowingTool::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
return false;
if ( m_ReferenceSlice.IsNotNull() && m_OriginalPicSlice )
{
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (positionEvent)
{
- ApplicationCursor* cursor = ApplicationCursor::GetInstance();
- if (!cursor) return false;
- m_ScreenYDifference += cursor->GetCursorPosition()[1] - m_LastScreenPosition[1];
- cursor->SetCursorPosition( m_LastScreenPosition );
+ m_ScreenYDifference += positionEvent->GetPointerPositionOnScreen()[1] - m_LastScreenPosition[1];
+ m_LastScreenPosition = positionEvent->GetPointerPositionOnScreen();
m_LowerThreshold = std::max<mitk::ScalarType>(0.0, m_InitialLowerThreshold - m_ScreenYDifference * m_MouseDistanceScaleFactor);
m_UpperThreshold = std::max<mitk::ScalarType>(0.0, m_InitialUpperThreshold - m_ScreenYDifference * m_MouseDistanceScaleFactor);
// 2. Perform region growing again and show the result
mitkIpPicDescriptor* result = PerformRegionGrowingAndUpdateContour(positionEvent->GetSender()->GetTimeStep());
ipMITKSegmentationFree( result );
// 3. Update the contour
mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(positionEvent->GetSender()->GetRenderWindow());
}
}
return true;
}
/**
If the feedback contour should be filled, then it is done here. (Contour is NOT filled, when skeletonization is done but no nice cut was found)
*/
bool mitk::RegionGrowingTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
return false;
// 1. If we have a working slice, use the contour to fill a new piece on segmentation on it (or erase a piece that was selected by ipMITKSegmentationGetCutPoints)
if ( m_WorkingSlice.IsNotNull() && m_OriginalPicSlice )
{
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (positionEvent)
{
// remember parameters for next time
m_InitialLowerThreshold = m_LowerThreshold;
m_InitialUpperThreshold = m_UpperThreshold;
int timestep = positionEvent->GetSender()->GetTimeStep();
if (m_FillFeedbackContour)
{
// 3. use contour to fill a region in our working slice
ContourModel* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
if (feedbackContour)
{
ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( m_WorkingSlice, feedbackContour, false, false ); // false: don't add any 0.5
// false: don't constrain the contour to the image's inside
if (projectedContour.IsNotNull())
{
FeedbackContourTool::FillContourInSlice( projectedContour, timestep, m_WorkingSlice, m_PaintingPixelValue );
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
- //MITK_DEBUG << "OnMouseReleased: writing back to dimension " << affectedDimension << ", slice " << affectedSlice << " in working image" << std::endl;
+ //MITK_DEBUG << "OnMouseReleased: wri<<ting back to dimension " << affectedDimension << ", slice " << affectedSlice << " in working image" << std::endl;
// 4. write working slice back into image volume
this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice);
}
}
}
FeedbackContourTool::SetFeedbackContourVisible(false);
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
}
}
m_ReferenceSlice = NULL; // don't leak
m_WorkingSlice = NULL;
m_OriginalPicSlice = NULL;
return true;
}
/**
Uses ipSegmentation algorithms to do the actual region growing. The result (binary image) is first smoothed by a 5x5 circle mask, then
its contour is extracted and converted to MITK coordinates.
*/
mitkIpPicDescriptor* mitk::RegionGrowingTool::PerformRegionGrowingAndUpdateContour(int timestep)
{
// 1. m_OriginalPicSlice and m_SeedPointMemoryOffset are set to sensitive values, as well as m_LowerThreshold and m_UpperThreshold
assert (m_OriginalPicSlice);
if (m_OriginalPicSlice->n[0] != 256 || m_OriginalPicSlice->n[1] != 256) // ???
assert( (m_SeedPointMemoryOffset < static_cast<int>( m_OriginalPicSlice->n[0] * m_OriginalPicSlice->n[1] )) && (m_SeedPointMemoryOffset >= 0) ); // inside the image
// 2. ipSegmentation is used to perform region growing
float ignored;
int oneContourOffset( 0 );
mitkIpPicDescriptor* regionGrowerResult = ipMITKSegmentationGrowRegion4N( m_OriginalPicSlice,
m_SeedPointMemoryOffset, // seed point
true, // grayvalue interval relative to seed point gray value?
m_LowerThreshold,
m_UpperThreshold,
0, // continue until done (maxIterations == 0)
NULL, // allocate new memory (only this time, on mouse move we'll reuse the old buffer)
oneContourOffset, // a pixel that is near the resulting contour
ignored // ignored by us
);
if (!regionGrowerResult || oneContourOffset == -1)
{
ContourModel::Pointer dummyContour = ContourModel::New();
dummyContour->Initialize();
FeedbackContourTool::SetFeedbackContour( *dummyContour );
if (regionGrowerResult) ipMITKSegmentationFree(regionGrowerResult);
return NULL;
}
// 3. We smooth the result a little to reduce contour complexity
bool smoothResult( true ); // currently fixed, perhaps remove else block
mitkIpPicDescriptor* smoothedRegionGrowerResult;
if (smoothResult)
{
// Smooth the result (otherwise very detailed contour)
smoothedRegionGrowerResult = SmoothIPPicBinaryImage( regionGrowerResult, oneContourOffset );
ipMITKSegmentationFree( regionGrowerResult );
}
else
{
smoothedRegionGrowerResult = regionGrowerResult;
}
// 4. convert the result of region growing into a mitk::Contour
// At this point oneContourOffset could be useless, if smoothing destroyed a thin bridge. In these
// cases, we have two or more unconnected segmentation regions, and we don't know, which one is touched by oneContourOffset.
// In the bad case, the contour is not the one around our seedpoint, so the result looks very strange to the user.
// -> we remove the point where the contour started so far. Then we look from the bottom of the image for the first segmentation pixel
// and start another contour extraction from there. This is done, until the seedpoint is inside the contour
int numberOfContourPoints( 0 );
int newBufferSize( 0 );
float* contourPoints = ipMITKSegmentationGetContour8N( smoothedRegionGrowerResult, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
if (contourPoints)
{
while ( !ipMITKSegmentationIsInsideContour( contourPoints, // contour
numberOfContourPoints, // points in contour
m_SeedPointMemoryOffset % smoothedRegionGrowerResult->n[0], // test point x
m_SeedPointMemoryOffset / smoothedRegionGrowerResult->n[0] // test point y
) )
{
// we decide that this cannot be part of the segmentation because the seedpoint is not contained in the contour (fill the 4-neighborhood with 0)
ipMITKSegmentationReplaceRegion4N( smoothedRegionGrowerResult, oneContourOffset, 0 );
// move the contour offset to the last row (x position of the seed point)
int rowLength = smoothedRegionGrowerResult->n[0]; // number of pixels in a row
oneContourOffset = m_SeedPointMemoryOffset % smoothedRegionGrowerResult->n[0] // x of seed point
+ rowLength*(smoothedRegionGrowerResult->n[1]-1); // y of last row
while ( oneContourOffset >=0
&& (*(static_cast<ipMITKSegmentationTYPE*>(smoothedRegionGrowerResult->data) + oneContourOffset) == 0) )
{
oneContourOffset -= rowLength; // if pixel at data+oneContourOffset is 0, then move up one row
}
if ( oneContourOffset < 0 )
{
break; // just use the last contour we found
}
free(contourPoints); // release contour memory
contourPoints = ipMITKSegmentationGetContour8N( smoothedRegionGrowerResult, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
}
// copy point from float* to mitk::Contour
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
contourInImageIndexCoordinates->Expand(timestep + 1);
contourInImageIndexCoordinates->SetClosed(true, timestep);
Point3D newPoint;
for (int index = 0; index < numberOfContourPoints; ++index)
{
newPoint[0] = contourPoints[ 2 * index + 0 ] - 0.5;//correction is needed because the output of the algorithm is center based
newPoint[1] = contourPoints[ 2 * index + 1 ] - 0.5;//and we want our contour displayed corner based.
newPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex( newPoint, timestep );
}
free(contourPoints);
ContourModel::Pointer contourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( m_ReferenceSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true: sub 0.5 for ipSegmentation correctio
FeedbackContourTool::SetFeedbackContour( *contourInWorldCoordinates );
}
// 5. Result HAS TO BE freed by caller, contains the binary region growing result
return smoothedRegionGrowerResult;
}
/**
Helper method for SmoothIPPicBinaryImage. Smoothes a given part of and image.
\param sourceImage The original binary image.
\param dest The smoothed image (will be written without bounds checking).
\param contourOfs One offset of the contour. Is updated if a pixel is changed (which might change the contour).
\param maskOffsets Memory offsets that describe the smoothing mask.
\param maskSize Entries of the mask.
\param startOffset First pixel that should be smoothed using this mask.
\param endOffset Last pixel that should be smoothed using this mask.
*/
void mitk::RegionGrowingTool::SmoothIPPicBinaryImageHelperForRows( mitkIpPicDescriptor* sourceImage, mitkIpPicDescriptor* dest, int &contourOfs, int* maskOffsets, int maskSize, int startOffset, int endOffset )
{
// work on the very first row
ipMITKSegmentationTYPE* current;
ipMITKSegmentationTYPE* source = ((ipMITKSegmentationTYPE*)sourceImage->data) + startOffset; // + 1! don't read at start-1
ipMITKSegmentationTYPE* end = ((ipMITKSegmentationTYPE*)dest->data) + endOffset;
int ofs = startOffset;
int minority = (maskSize - 1) / 2;
for (current = ((ipMITKSegmentationTYPE*)dest->data) + startOffset; current<end; current++)
{
mitkIpInt1_t sum( 0 );
for (int i = 0; i < maskSize; ++i)
{
sum += *(source+maskOffsets[i]);
}
if (sum > minority)
{
*current = 1;
contourOfs = ofs;
}
else
{
*current = 0;
}
++source;
++ofs;
}
}
/**
Smoothes a binary ipPic image with a 5x5 mask. The image borders (some first and last rows) are treated differently.
*/
mitkIpPicDescriptor* mitk::RegionGrowingTool::SmoothIPPicBinaryImage( mitkIpPicDescriptor* image, int &contourOfs, mitkIpPicDescriptor* dest )
{
if (!image) return NULL;
// Original code from /trunk/mbi-qm/Qmitk/Qmitk2DSegTools/RegionGrowerTool.cpp (first version by T. Boettger?). Reformatted and documented and restructured.
#define MSK_SIZE5x5 21
#define MSK_SIZE3x3 5
#define MSK_SIZE3x1 3
// mask is an array of coordinates that form a rastered circle like this
//
// OOO
// OOOOO
// OOOOO
// OOOOO
// OOO
//
//
int mask5x5[MSK_SIZE5x5][2]
= {
/******/ {-1,-2}, {0,-2}, {1,-2}, /*****/
{-2,-1}, {-1,-1}, {0,-1}, {1,-1}, {2,-1},
{-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0},
{-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1},
/******/ {-1, 2}, {0, 2}, {1, 2} /*****/
};
int mask3x3[MSK_SIZE3x3][2]
= {
/******/ {0,-1}, /*****/
{-1, 0}, {0, 0}, {1, 0},
/******/ {0, 1} /*****/
};
int mask3x1[MSK_SIZE3x1][2]
= {
{-1, 0}, {0, 0}, {1, 0}
};
// The following lines iterate over all the pixels of a (sliced) image (except the first and last three rows).
// For each pixel, all the coordinates around it (according to mask) are evaluated (this means 21 pixels).
// If more than 10 of the evaluated pixels are non-zero, then the central pixel is set to 1, else to 0.
// This is determining a majority. If there is no clear majority, then the central pixel itself "decides".
int maskOffset5x5[MSK_SIZE5x5];
int line = image->n[0];
for (int i=0; i<MSK_SIZE5x5; i++)
{
maskOffset5x5[i] = mask5x5[i][0] + line * mask5x5[i][1]; // calculate memory offsets from the x,y mask elements
}
int maskOffset3x3[MSK_SIZE3x3];
for (int i=0; i<MSK_SIZE3x3; i++)
{
maskOffset3x3[i] = mask3x3[i][0] + line * mask3x3[i][1]; // calculate memory offsets from the x,y mask elements
}
int maskOffset3x1[MSK_SIZE3x1];
for (int i=0; i<MSK_SIZE3x1; i++)
{
maskOffset3x1[i] = mask3x1[i][0] + line * mask3x1[i][1]; // calculate memory offsets from the x,y mask elements
}
if (!dest)
{
// create pic if necessary
dest = ipMITKSegmentationNew( image );
}
int spareOut3Rows = 3*image->n[0];
int spareOut1Rows = 1*image->n[0];
if ( image->n[1] > 0 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x1, MSK_SIZE3x1, 1, dest->n[0] );
if ( image->n[1] > 3 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x3, MSK_SIZE3x3, spareOut1Rows, dest->n[0]*3 );
if ( image->n[1] > 6 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset5x5, MSK_SIZE5x5, spareOut3Rows, dest->n[0]*dest->n[1] - spareOut3Rows );
if ( image->n[1] > 8 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x3, MSK_SIZE3x3, dest->n[0]*dest->n[1] -spareOut3Rows, dest->n[0]*dest->n[1] - spareOut1Rows );
if ( image->n[1] > 10) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x1, MSK_SIZE3x1, dest->n[0]*dest->n[1] -spareOut1Rows, dest->n[0]*dest->n[1] - 1 );
// correction for first pixel (sorry for the ugliness)
if ( *((ipMITKSegmentationTYPE*)(dest->data)+1) == 1 )
{
*((ipMITKSegmentationTYPE*)(dest->data)+0) = 1;
}
if (dest->n[0] * dest->n[1] > 2)
{
// correction for last pixel
if ( *((ipMITKSegmentationTYPE*)(dest->data)+dest->n[0]*dest->n[1]-2) == 1 )
{
*((ipMITKSegmentationTYPE*)(dest->data)+dest->n[0]*dest->n[1]-1) = 1;
}
}
return dest;
}
diff --git a/Modules/Segmentation/Testing/Data/img.nrrd b/Modules/Segmentation/Testing/Data/img.nrrd
deleted file mode 100644
index 04a51b53cb..0000000000
--- a/Modules/Segmentation/Testing/Data/img.nrrd
+++ /dev/null
@@ -1,17 +0,0 @@
-NRRD0004
-# Complete NRRD file format specification at:
-# http://teem.sourceforge.net/nrrd/format.html
-content: SomeIDNumber42
-type: short
-dimension: 3
-space: right-anterior-superior
-sizes: 3 3 1
-thicknesses: 1 1 1
-space directions: (1,0,0) (0,1,0) (0,0,1)
-centerings: cell cell cell
-kinds: space space space
-encoding: ASCII
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-
-1 2 3 4 5 6 7 8 9
diff --git a/Modules/Segmentation/Testing/Data/lungs.vtk b/Modules/Segmentation/Testing/Data/lungs.vtk
deleted file mode 100644
index 5b0f7f17ac..0000000000
--- a/Modules/Segmentation/Testing/Data/lungs.vtk
+++ /dev/null
@@ -1,18985 +0,0 @@
-# vtk DataFile Version 3.0
-vtk output
-ASCII
-DATASET POLYDATA
-POINTS 7860 float
-59 174 77.8 95 170 80.2059 55 171 80.2222
-56 171 79.2353 56 172 78.5806 57 172 78.1765
-58 173 78.2 59 173 78.6923 61 173 79.6452
-87 173 80.4194 88 173 79.8 89 173 79.4571
-91 173 80.4706 58 174 78.5172 60 174 78.1765
-89 174 80.4706 91 174 80.8235 59 175 78.5172
-60 175 78.0909 63 175 79.4571 88 175 80.5588
-64 176 80.1429 63 177 80.2059 65 177 80.2059
-67 177 80.1429 81 177 80.4706 82 177 79.8
-84 177 79.8 62 177.087 81 64 177.5 81
-68 178 80.2059 80 178 80.2059 82 178 80.2059
-69 179 79.8529 77 179 80.2059 79 179 79.8
-80 179 80.2059 81 179 80.8235 70 180 80.5455
-74 180 80.4706 114 150 83.4706 113 151 83.4706
-112.739 151 84 114 152 82.8529 39 155 83.8
-38.6667 155 84 113 155 82.8 114 155 82.8
-39 156 83.1429 38.3333 156 84 40 156 83.4706
-114 156 83.1429 40 157 83.1429 40 158 83.8
-40.6667 158 84 42 158.833 84 41.3333 159 84
-109 159 83.4706 112 159 81.1765 113 159 81.4545
-43 160 83.2059 108 160 83.4706 109 160 82.8
-111 160 81.5294 112 160 81.1765 113 160 82.3
-110 161 82.2 111 161 81.5143 112 161 81.8182
-44 162 82.8 45 162 82.8 107 162 83.0323
-109 162 83.0323 110 162 82.2 111 162 82.2
-112 162 83.4828 46 163 83.4194 110 163 83.2059
-46.25 164 84 47 164 83.4194 106 164 82.2
-109 164 83.4706 104 165 83.4 105 165 82.4545
-106 165 82.2 108 165 83.4706 49 166 82.8
-50 166 82.8 51.1667 166 84 103 166 83.9
-51.4 167 84 99 167 83.2174 101 167 81.9
-96 168 83.4828 97 168 82.7 98 168 82.8182
-101 168 81.8824 95 169 81.8824 96 169 81.9677
-97 169 82.5556 93 170 82.3636 93 169.333 84
-96 170 81.2222 54 171 82.6552 93 171 81.6667
-94 171 81.1936 91 172 81.6207 92 172 81.9677
-93 172 81.6 94 172 81.8824 95 172 81.5294
-97 172 83.8846 68 173 83.3333 76 173 83.4706
-85 173 83.6842 86 173 81.7826 93 173 82.2
-71 174 82.6452 76 174 82.4571 84 174 83.6842
-85 174 83.8333 92 174 81.5294 57 174.727 84
-75 175 82.6452 80 175 82.4571 82 175 82.0714
-86 175 81.6 69 176 82.6452 71 176 82.8529
-72 176 83.8064 74 176 83.4194 80 176 82.2
-87 176 81.4545 60.2609 177 84 75 177 82.4571
-87 177 81.5294 89 177 82.8529 81 181.25 84
-115 146.357 87 36 149 86.4194 114 149 84.1765
-36 150 86.4194 37 150 86.8 36.0909 151 87
-37 151 86.0323 37 152 85.5556 37 153 86.0526
-38 153 86.6842 111 153 86.9091 37 154 86.1667
-38 154 84.7826 39 154 85.8261 38 155 84.6667
-38 156 85.0714 37.6538 156 87 41 157 84.6818
-41 158 84.1364 40 159 85.8571 41 159 84.1364
-44 158.278 87 108 159 84.5294 41 160 85.2273
-45.5 160 87 41.2 161 87 47 163 84.2727
-46 164 84.2308 52 165 85.3548 100 165 86.5455
-102 165 84.5294 53 166 86.0323 52 167 84.2647
-106 167 84.5294 51 168 84.9677 53 168 84.4545
-95 167.63 87 53 169 84.2647 92 168.75 87
-105 169 86.2059 67 169.75 87 89 170 84.8824
-98 170 85.56 98 171 85.7727 72 172 85
-74 172 85.5556 82 172 84.5294 84 172 84.6923
-98 172 85.3043 99 172 85.2 73 173 85.8261
-74 173 85.8261 84 173 84.8333 73 174 85.1538
-99 174 86.8235 73 175 85 74 175 84.5172
-184.833 178 87 186 178 85.8462 186 179 85
-188 179 84.9677 189 179 85.3 191 179 85.1818
-193 179 84.375 195 179 85.6552 196 179 86.069
-198 179 85.4545 198 178.261 87 201 179 86.4706
-202 179 86.2059 186 180 86.8235 189 180 85.3548
-190 180 84.6 191 180 84.6 193 180 84.4286
-196 180 86.1 198 180 85.5 200 180 86.2059
-201 179.75 87 193 181 86.8966 68 181.706 87
-82 182 84.5294 84 183.087 87 117 143 89.8
-118 143 89.4706 118 142.25 90 117 144 88.5
-118 144 89.4706 115 145 89.2174 116 145 87.9677
-117 145 88.2 34 146 89.6087 115 146 87.6818
-116 146 87.5769 117 146 89 35 147 87.9677
-116 147 87.2308 35 148 87.5769 36 148 87.4545
-35 149 87.5455 35.7727 152 90 39 153 89.7273
-151 155 88.8 42.6429 157 90 152 157 88.8
-153 157 89.1429 43 157.278 90 44 157.105 90
-45.4545 158 90 152 158 89.8 153 158 89.8
-45.8947 159 90 153 159 89.9 47.2857 161 90
-52 162 89.55 48 162.286 90 55 164 88.3043
-56 164 89.2174 98 164 88.8529 55 165 87.6923
-56 165 89.2174 96 165 89.2059 95.1818 165 90
-99 165 87.9677 45 165.346 90 56 166 88
-63 167 87.375 64.6 167 90 92.7692 167 90
-95 167 89.3182 94.375 167 90 64.3 168 90
-68.3333 168 90 93 167.75 90 93 168 89.5714
-94 168 89 94 167.75 90 72 168.474 90
-73 168.333 90 66 169.4 90 50 170.105 90
-174 175 89.4 175 175 88.8 176 175 89.4194
-176 176 89.0323 177 176 88.6452 178.6 176 90
-181 176 89.4231 181 177 89.3077 181 178 89.04
-182 178 88.7586 183 178 89.3182 184 178 89
-202 178 87.5172 204 178 88.5 182 179 89.4194
-183 179 89.7391 184 179 88.875 204 179 88.1538
-181 180 89.8235 183 180 89.4194 202 180 88
-119 140 92.7778 120 140 91.6452 118 141 91.9615
-119 141 90.8571 120 141 91.2 118 142 90.2
-119 142 90.1765 120 142 91.5 120.654 142 93
-119 143 90.5294 150 145 92.8 149.714 145 93
-150 146 91.8 150 147 91.5 151 147 91.8529
-117.895 148 93 150 148 91.8529 151 148 91.5
-151 149 90.5294 151 150 90.1765 36.5909 153 93
-39 154.5 93 39.1053 155 93 39.1667 156 93
-40 156.526 93 154 157 90.5294 156.105 159 93
-46 159.563 93 50.75 160 93 153 160 91.1471
-155 160 91.7 45.3333 161 93 51 161 91.0714
-52 161 91.2273 154 161 90.6 45.8667 162 93
-51 162 90.5 50.6875 162 93 154 162 91.7
-156 161.455 93 155 163 92.7391 155.25 163 93
-47 164 92.3077 46.25 164 93 159 164 91.5
-47 164.857 93 63 165 90.6667 92 165 90.8824
-159 165 90.8824 45 165.591 93 46.5455 166 93
-64 166 90.2609 66 166 92.6842 67 166 92.8636
-92 166 90.2 93 166 91.0385 158 166 91.5
-160 166 90.5806 161 166 92.3077 46.6 167 93
-65 166.684 93 69 166.4 93 70 166.227 93
-71 167 91.5556 72 167 92 75 167 90.6
-93 167 92.25 94 167 92.25 161 167 92.7391
-161.5 167 93 68.3333 168 93 72 168 91.5
-94 168 90.2143 160 168 92.4444 161 168 92.25
-162 168 91.5556 48.4 169 93 67 169 90.2727
-162 170 91.2353 51.2857 171 93 66 170.208 93
-167 171 92.8966 52.625 173 93 170 173 92.8235
-173 173 92.7778 174 174 90.2308 170 175 92.1429
-180 175 91.5 171 176 92.4194 172 175.091 93
-172 176 91.8889 174 176 90.2222 179 176 90.5455
-185 175.618 93 179 177 92.7 183 177 90.375
-177 178 91.2 178 178 92.7 178.333 178 93
-179 177.333 93 179.143 178 93 180 178 90.6
-176 178.833 93 177 178.818 93 177.286 179 93
-178 179 92.2105 179 179 91.5 204.833 179 93
-180 180 90.5294 204 180.172 93 121 139 93.2727
-123.105 139 96 33 140.857 96 34 141 94.8462
-34 142 93.9 35 143 93.6818 149 143 94.8889
-150 144 94.1818 149 145 93.7895 40 151 94.5
-40.0714 153 96 40 153.071 96 39.3529 156 96
-149.588 156 96 46 156.591 96 45 157.133 96
-48 158 94.8 47 159 93.8571 49 159 94.0714
-50.1818 159 96 45.6667 160 96 47 159.625 96
-52 159.895 96 45.5714 161 96 157 161 93.2308
-51 162 94.0714 52 161.722 96 52.8333 162 96
-54 161.5 96 156 162 95.25 158 162 93.2609
-159 162 93.6 41 163 94.8261 46 163 94.125
-51 162.692 96 52 163 95.4 52.75 163 96
-156 163 95.5714 46 164 93.3158 45.2273 164 96
-52 163.6 96 90 164 93.3214 155 164 93.6667
-43 165 94.1111 46 165 93.75 47 165 93.75
-156 165 93.2 45 166 94.5882 45.7273 166 96
-47 165.273 96 46.2727 166 96 54 166 94
-54.2 166 96 69.25 166 96 162 166 94.7727
-46 166.375 96 46 167 94.9286 54 166.667 96
-64.4615 167 96 69 166.5 96 155 166.474 96
-163 166.455 96 47 168 94.5 72 168 94.5
-94.55 168 96 164 168 94.1111 165 168 95.1
-46 169 95.8846 46.1667 169 96 47.5 169 96
-72 169 95.3182 164 169 94.1111 165 169 94.5556
-166 169 94.8 52 170 93.2 94 169.688 96
-166 170 93.4286 167 170 93.5455 51 170.625 96
-163 171 93.6 166 171 94.3636 168 171 94.375
-168 170.133 96 170 171 94.8 52 172 94
-52.1818 172 96 162 172 94.5 163 172 94.3
-164 172 95.7391 165 172 95.8636 167 172 94.3548
-168 172 94.3548 173 172 93.5172 52 172.5 96
-59 173 95.125 164 173 95.4194 165 173 95.0323
-171 173 93.1818 172 173 93.4545 216 173 95.8
-75 174 95 74.8421 174 96 76 173.533 96
-76 174 95 76.6364 174 96 167 174 95.1429
-172 174 93.8182 214 174 95.4706 168 175 94.5
-172 175 93.1765 183 174.941 96 170 177 94.5
-178 176.65 96 179 176.316 96 204.323 177 96
-176.85 178 96 178 178 93.2 179.591 178 96
-176 179 93.3158 177 179 93.8571 177 178.375 96
-178 178.609 96 177 180 94.1538 68 184.056 96
-124 138.071 99 33 139.357 99 34 140.056 99
-149 141 98.2174 150 140.5 99 149 142 96.2609
-115 143.111 99 41 153 98.6 40 154 98.0526
-41 154 98.7 42 154 98.6 43 154 97.9286
-43 153.773 99 44 155 97.5 44 156 98.1667
-44.7143 156 99 46 157 98.4545 42.8182 158 99
-45 158 97.4444 47 158 98.4706 48 158 98.25
-44 158.846 99 45 159 98.6 46 159 98
-46.75 159 99 47 158.75 99 46 160 97.6364
-46 159.375 99 47 160 97 49.1818 160 99
-51 160 97.5 46 161 97.2 47 161 97.5
-51 160.667 99 53 160.545 99 45.2778 162 99
-51 161.333 99 53 161.625 99 53 162 96.75
-161 162 97.8529 49.9333 163 99 52 162.2 99
-59 163 98.25 44.3158 164 99 60 163.667 99
-64 163.933 99 59 165 97 60 164.333 99
-60 165 97.6364 64.8182 165 99 66 165 97.125
-66.7143 165 99 68.75 165 99 47 166 97.8462
-47.3333 166 99 54 166 96.4 59 166 96
-58.2632 166 99 60 166 97.0909 65 166 98.7143
-64.8182 166 99 66 166 98.0526 66.75 166 99
-69 166 96.4286 70 165.833 99 224 166 98.8
-225 166 98.8 225 165.75 99 46 167 97.5
-47.8182 167 99 59 167 97.3636 58.25 167 99
-60 167 97.7143 67 166.286 99 69 167 96.75
-70 167 98.6 70 166.5 99 70.3333 167 99
-72 167 98.6 71.6667 167 99 72 166.5 99
-223 167 97.8529 224 167 97.6452 47 168 96.75
-46.4545 168 99 47.8571 168 99 56 168 98.7273
-55.8667 168 99 56 167.867 99 56.5 168 99
-61.8182 168 99 64.25 168 99 70 168 96.2609
-71 167.222 99 71 168 96.7895 73 168 97
-74 167.357 99 74 168 97.7727 222 168 97.8529
-223 168 97.3 224 168 98.7391 47 169 97.3636
-56 168.286 99 62 169 97.6552 62.9286 169 99
-64.25 169 99 69 169 96.9 71 169 97.35
-74.1 169 99 92.7 169 99 167 168.2 99
-221 169 97.7 222 169 97.3 223 169 98.7391
-46 170 97.5 52 169.462 99 54.2 170 99
-62 170 97.8182 62.6842 170 99 68 169.875 99
-69 170 98.25 68.5 170 99 70 170 97.1739
-71 170 97.25 72 170 97.5 72.9091 170 99
-74 169.056 99 77 170 97.5 76.4545 170 99
-77 169.571 99 170 170 96.4545 220 170 96.9
-221 170 97.0385 222 170 98.7391 61 171 98.7931
-60.7778 171 99 61.2857 171 99 69 170.5 99
-70 171 97.3333 71 171 97.25 72 171 98.625
-77 171 97.8 77.8571 171 99 94 170.294 99
-164 171 96.2727 165 171 96.4091 218 171 97.4
-219 171 96.6 220 171 96.2 221 171 98.2174
-49 172 96.3333 54 171.75 99 59 171.519 99
-60 172 98 69.1429 172 99 71 172 96.3
-72.4375 172 99 77 171.75 99 216 172 97.1818
-216 171.231 99 217 172 97.2414 218 172 96.5172
-219 172 97.5 220 172 98.7273 48 172.722 99
-50 173 97.875 51.5 173 99 58 173 96.5172
-57.1724 173 99 61 172.286 99 215 173 96.5294
-217 173 96.5294 218 173 97.3548 51 174 98.2174
-67 173.818 99 67.25 174 99 75.5 174 99
-78 174 98.7273 78.1053 174 99 180 173.097 99
-211 174 98.88 216 174 96.5294 58 174.737 99
-67 175 97.8462 66.0909 175 99 76 174.643 99
-77 175 98.4 77.75 175 99 78 174.667 99
-210 175 97.25 212 175 97.8261 213 175 96.6
-214 175 96.2 67 176 98.069 66.3571 176 99
-67.9 176 99 77 175.188 99 178 175.923 99
-178.25 176 99 209 176 96.4545 210 176 96.1154
-211 176 97.56 212 176 98.4444 213 176 98.1
-214 176 98.4231 67 176.5 99 179 176.75 99
-179.095 177 99 210 177 96.5806 212 176.833 99
-214 176.172 99 177 178.579 99 178 178.467 99
-63 183.375 99 66 183.818 99 67 184 98
-151 137 101.824 32 138 101.609 33 137.333 102
-150 138 100.696 33 139 99.5769 150 139 99.6667
-149 140 100.8 123 141 100.579 122 144 100.962
-120.8 145 102 107.773 150 102 41 152 99.5455
-34.5882 153 102 45 155 100.579 45.3913 155 102
-41 156 100.154 42 156 100.111 45 156 99.3158
-42 157 99.2727 43 157 100.111 46 157 99.6
-47 157 101.7 44 158 101.75 47 158 102
-48 158 100 43.8421 159 102 50 159 100.071
-51 160 99.4286 50 161 100.826 54 161 101.7
-55 161 101.5 158 161 101.667 157.25 161 102
-158 160.813 102 51 162 99.75 52 162 99.5455
-53 162 100.125 56 161.077 102 158 161.75 102
-227 162 101.1 228 162 101.739 46 162.444 102
-49 162.667 102 49 163 101.8 50 162.2 102
-60 162.944 102 226 163 100.5 227 163 99.9
-225 164 101.1 226 164 99.9 227 164 100.227
-47 165 101.167 59 165 101.727 65 165 99.8571
-66 165 101.5 80 164.567 102 225 165 99.5294
-226 165 100.111 46 166 101.824 60.875 166 102
-65 166 101 65.2 166 102 66 165.2 102
-66.8 166 102 226 165.944 102 46 167 99.9375
-47 167 101.077 60.75 167 102 61.1429 167 102
-62 166.455 102 64 167 100.5 65 167 100.364
-66 167 100.286 70 167 99.8571 72 166.563 102
-167 167 100.5 47 168 100.636 56 168 99.8571
-65 168 100.2 66 168 100.773 67 168 101.654
-74 167.105 102 94 168 101.786 95.375 168 102
-167 168 99.5455 62.6364 169 102 66 169 101.727
-67 169 101.8 68 169 101.8 75 168.571 102
-75 169 101.25 76 168.455 102 76 169 100.2
-95.9167 169 102 54 169.591 102 55 170 101.182
-56 169.167 102 56 170 100.5 61 170 99.8182
-64.4545 170 102 67 170 101.7 73.5455 170 102
-75 169.75 102 76 169.857 102 76.1429 170 102
-52 170.474 102 53 170.143 102 54.3333 171 102
-61 171 99.6 51 172 102 58 171.727 102
-60 172 101 73 171.667 102 72.9333 172 102
-78 171.917 102 60.25 173 102 72 173 101.182
-78 173 101.25 78 172.333 102 79.5 173 102
-180 172.316 102 67.3333 174 102 68 174 101.25
-68.6667 174 102 77 174 100.579 77.75 174 102
-79 174 102 187 174 101.419 188 174 101.8
-206.895 174 102 58 174.25 102 66 175 102
-68 175 102 77 175 99.6 78 174.75 102
-207 175 101 65.5625 176 102 68.1364 176 102
-173 176 100.688 173 175.632 102 176.565 176 102
-215 176 100.826 215.6 176 102 161 176.074 102
-212 177 99.1034 176.8 178 102 203.5 178 102
-212 178 100.556 203 178.867 102 210 179 100.355
-202.091 180 102 203 181 100.75 66 185 100.08
-200 184.172 102 232 99 104.8 232 98.7143 105
-232 99.5 105 235 111 104.824 235 112 104.824
-151 133 104.471 32 136 103.6 31.3 136 105
-33 135.867 105 150 137 102.167 153 141 103.2
-154 142 104.8 154.75 143 105 230 156 104.419
-49 157 104.318 229 157 104.8 45 158 103.313
-46 158 103.615 229 158 103.7 230 158 104.053
-44 159 103.125 45 159 102.75 46 159 103.8
-53 158.316 105 228 159 104.206 229 159 103.5
-37.1765 160 105 54 160 103.5 164 160 103.8
-229 160 103.5 157.533 161 105 158 160.417 105
-158.875 161 105 228 161 102.682 228.944 161 105
-49 162 102.273 50 162 102.316 59.8 162 105
-62 162 104.545 158 161.875 105 46 163 104
-48 163 102.375 225 163 103.111 45.1429 164 105
-46 163.455 105 47 164 103.05 45 165 103.286
-60 165 102.75 167 165 102.529 46 165.25 105
-60 166 103.105 63 166 105 65 166 102.429
-60 167 102.45 61.8571 167 105 62 166.333 105
-62.6667 167 105 64 167 104.5 63.5 167 105
-64.1 167 105 65 166.4 105 64 167.25 105
-68 168 102.261 69 168 103.962 71 168 103.556
-72 168 104.778 73 168 104.333 74 168 104.684
-96.7143 168 105 166 168 103.875 166.75 168 105
-62 169 103.05 69 169 103.304 71 169 103.304
-73 169 104.063 75 169 102.818 76 169 102.947
-97.5455 169 105 54 170 103.929 55 170 103.125
-56 170 104.143 62 170 103.235 65 170 103.636
-66 170 103.65 74 169.273 105 77 170 103
-52 171 103 53 171 102.692 54 171 103
-71 171 103.304 73 171 102.4 78 171 104.75
-178 170.261 105 179 171 103 181 171 104.419
-52 172 103.179 58 172 103.125 72 172 103.826
-77 171.286 105 182 172 104 184 172 102.882
-188 172 104.8 58 173 103.826 59 173 103.5
-70 173 103.125 72 173 103.8 78 173 103.5
-78.4 173 105 81 173 105 181 173 103.5
-182 173 103.909 188 173 102.783 207 173 104.333
-208.125 173 105 59 174 102.692 69.75 174 105
-80 173.857 105 198 174 102.667 206 174 104.217
-210 173.273 105 67 175 103.615 67.75 175 105
-68.2857 175 105 88 175 104 87.25 175 105
-88.75 175 105 176 175 104.308 176 174.455 105
-177 174.87 105 177 175 104.438 66 176 104.625
-67 176 104.625 68 176 103 88 175.75 105
-173.231 176 105 176 176 104.438 178.067 176 105
-204.091 178 105 203.25 179 105 200.571 180 105
-201 179.4 105 203 179.056 105 206 180 103.8
-201.75 181 105 205 181 104.333 206 181 103.8
-207 181 104.1 173 182 103.56 175.667 185 105
-230 94 107.4 230 93.1429 108 231 95 106.889
-231 96 106.355 231 97 106.182 232 97 106.636
-232 98 105.577 231 99 106.5 233 99 106.333
-233 98.1667 108 232 100 105.2 233.292 100 108
-233 101.5 108 233 102 107.684 233 103 106.111
-233 104 105.882 233 105 106.182 234 105 105.682
-234 106 105.222 235 105.75 108 234 107 105.2
-234 108 105.529 235 110 105.577 235.913 110 108
-234 111 105.529 236 111 106.421 236.292 114 108
-235 116 106.355 235 117 107.032 235 119 107.8
-235 120 107.8 236 120 107.739 236 121 106.696
-236 123 105.667 236 125 106.889 236 126 107.333
-235 127 107.824 236 128 106.355 236 130 107.1
-150 131 107.778 150 132 105.9 149.192 132 108
-151 132 105.818 235 132 107.8 31 135 106.8
-31 134.143 108 32 135 105.136 31 136 107
-33 135.133 108 235 136 107.471 120 139.435 108
-235 140 106.889 155 141 105.667 234 141 107.471
-235 141 107.217 234 142 107.143 235 141.857 108
-234 143 107.032 155 144 105.545 156 144 107.625
-234 144 107.333 233 145 107.824 162 151 107.471
-231 156 106.714 230.933 157 108 225.933 159 108
-57 160 107.684 168 160 107.471 57 161 106
-58 161 106.636 59 161 105.316 60 161 105.783
-158 161 106.05 58 162 108 59 162 106.2
-63 162 106 82 161.833 108 83 162 107.8
-83 161.833 108 84 162 106.759 160 162 106.714
-159.455 162 108 160 161.455 108 160.75 162 108
-46 164 105.6 64 166 106.286 65 166 106.636
-66 166 105.75 173 166 106.2 174 166 107.032
-176 166 107.778 62 167 105.333 64 167 105.231
-174 167 107.55 176 167 107.739 177 167 106.962
-216 167 107.1 168.13 168 108 174 168 105.75
-177 168 106.889 178 168 106.889 218 168 105.2
-74 169 105.333 166 168.25 108 167.2 169 108
-168 168.2 108 179 169 105.529 181 169 106.2
-183 170 105.529 192 169.333 108 195 170 107.471
-207 170 107.8 77 171 105.316 96 170.111 108
-197 171 106.645 198 171 106.457 208 171 106.457
-82 172 107.25 82 171.625 108 82.75 172 108
-197 172 106.5 198 172 106.826 203.5 172 108
-205.75 172 108 207 172 106.826 208 172 106.355
-80 173 106.2 82 172.375 108 175 173 107.087
-174.563 173 108 200 173 107.885 203 173 107.912
-205.455 173 108 209 173 106.105 210 173 105.474
-68 174 105.273 69 174 105.6 90 174 107.526
-89.75 174 108 90.75 174 108 175 174 106.895
-176 174 106.25 203 174 107.5 68 175 105.24
-88 175 105.818 90 174.75 108 177 174.895 108
-206 175 106.5 205.833 175 108 171 176 107.5
-171 175.333 108 172.231 176 108 176 175.933 108
-177.13 176 108 205 175.909 108 205 176 107.864
-206 176 106.636 205 178 105.882 204 179 105.29
-201 180 107.25 202 180 107.211 203 180 106.962
-202 181 106 203 181 107.348 169 182 106.235
-203 182 106.826 204 182 106.2 205 182 105.455
-171 183 105.176 173 183 105.778 204 183 107.1
-205 183 107.778 172 184 106.5 86 189.824 108
-227 88 110.4 226.5 88 111 228 89 109.444
-228 90 108.9 228 91 109.2 229 91 109.174
-229 92 108.667 230 91.8182 111 229 93 108.581
-230 93 108.2 233 101 109.5 232 102 108.24
-230.167 107 111 231 108 110.824 230.833 108 111
-232 109 109.182 236 119 108.545 236.64 125 111
-150 129.966 111 234.692 130 111 149 130.231 111
-148.63 131 111 235 131 109.227 236 131 108.273
-236 132 108.158 31 133 110.25 30.5882 135 111
-128 135 110.423 129 135 110.206 128 136 108.231
-129 136 110.1 129 136.818 111 157 138.643 111
-157 140 109.304 232.316 140 111 235.806 140 111
-156 141 108.136 156 142 109.08 157 142 109.4
-156 143 109.227 158 143 109.313 157 144 108.182
-232 145 109.2 234 145 108.682 234.567 145 111
-162 146 110.143 161 147 109.355 231 147 110.824
-233 147 110.864 164 148 110.471 232 148 110.909
-162 149 109.75 232 149 110.423 232.714 149 111
-231 150 110.423 232.929 150 111 231 151 109.696
-232 151 108.789 231 152 109.421 232 152 109
-231 153 110.053 230 154 108.692 170 157 109.457
-168 158 109.2 171 158 109.457 60 159 110.1
-168 159 108.529 172 159 109.457 223 158.875 111
-224 159 110.739 170 160 109.2 171 160 109.457
-172 160 109.8 174 160 110.143 82 161 108.909
-173 161 109.886 175 161 109.457 177 161 110.206
-177.818 161 111 105 162 110.25 106 162 109.2
-174 162 109.8 175 162 109.457 178 162 110.8
-220 162 110.25 220 161.417 111 106 163 109
-106.25 163 111 160 163 108.429 161 163 109.364
-161.2 163 111 175 163 108.882 161 164 109
-178 164 110.333 160 164.909 111 161.13 165 111
-179 165 108.968 184 165 109.457 183 166 109.457
-185 166 109.457 210 166 110.471 214 166 109.2
-215 166 108.882 66 167 109.6 65.125 167 111
-66 166.417 111 67 166.625 111 67.2727 167 111
-184 167 110.333 185 167 110.679 186 167 110.032
-187 167 109.457 194 167 110.8 193.5 167 111
-195 166.625 111 209 167 110.125 215 167 108.529
-66 168 109.5 65.25 168 111 67 168 110.308
-166.696 168 111 169 167.563 111 169 168 110.222
-170 168 110.735 171 168 110.735 172 167.87 111
-185 168 110.211 187 168 108.529 192 168 110.211
-192.714 168 111 193.25 168 111 195 168 109.645
-201 168 109.853 203 168 110.684 204 168 110.684
-207 167.5 111 210 168 109.826 213 168 110.864
-214 168 110.04 92.6842 169 111 167 168.875 111
-168 168.947 111 169 168.438 111 172 169 109.645
-173 169 109.429 192.818 169 111 194 169 109.5
-193.25 169 111 202 169 110.625 205 169 110.471
-207 169 108.75 93.25 170 111 173 170 109.35
-173.688 170 111 193 169.25 111 94 170.4 111
-95 170.625 111 173 171 111 82 172 108.818
-186 172 110.55 185.727 172 111 205 172 109.636
-205 171.375 111 92 173 110.55 91.25 173 111
-93 172.455 111 93 173 110.4 175 173 110.625
-186 172.375 111 195 173 110.471 195 172.571 111
-196 172.444 111 196 173 109.5 205 173 110.143
-90.5 174 111 91 173.2 111 91 174 108.6
-92 174 110.438 94 174 110.55 95 173.667 111
-95 174 109.875 175 174 109.75 176 174 109.313
-196 174 109.821 197 174 109.889 197.667 174 111
-204 174 108.947 205 173.4 111 205.75 174 111
-91 174.25 111 95 174.75 111 171 175 108.273
-176 175 109.909 195.563 175 111 197 175 110.217
-85 176 108 84.25 176 111 85 175.25 111
-85.1875 176 111 171.857 176 111 177 176 108.29
-196 176 111 197 176 110.143 205 175.333 111
-85 176.188 111 197 176.286 111 212 180.067 111
-207 67 113.333 208 68 112.645 209 68 112.889
-210 68.0667 114 210 70 112.457 213 71 112.313
-214 71 112.75 215 71 113.5 215 72 112.25
-216 73 111.261 217 73 111.273 213 74 112.8
-216 74 111.968 218 74 112.364 218.231 74 114
-218 75 111.783 218 76 112.313 219.091 76 114
-218 77 113.419 219 77 113.679 219.25 77 114
-219 78 113.778 220 78 113.419 220 79 113.143
-221 80 113.419 221.857 81 114 222 82 113.8
-222.167 84 114 223 84 113.143 224 85 113.333
-225 85 113.55 225 87 113.778 226 87 112.696
-226 88 111.783 227 87.2632 114 229 98 111.176
-231 110 111.529 230.04 113 114 231 114 111.529
-232 119 112.773 232 120 111.947 233 121 111.5
-233 128 111.581 234 129 112.227 31 130 113.793
-149 130 111.333 233.375 130 114 234 130 113.348
-31 131 112.636 32 131 112.5 234 131 112.364
-31 132 113.182 30.875 132 114 32 132 112.5
-232 132 112.2 233 132 111.455 131 133 112.962
-132 133 113.1 132 132.182 114 149 132.944 114
-129 134 112.111 130 134 111.581 131 134 111.9
-132 134 113.778 232 133.684 114 233 134 111.931
-130 135 111.2 131 135 112.7 126 135.067 114
-158 136 113.333 31.2857 137 114 232 137 111.581
-157 138 112.08 229.5 138 114 233 138 111.176
-229 142 113.824 230 142 113.143 108 143 113.545
-161 143 111.857 231 144 112.5 165 145 112.8
-164 146 112.313 229 146 113.8 231 146 111.091
-230 147 111.176 232.962 148 114 229 149 111.931
-226 151 113.143 227 152 113.545 229 152 113.909
-232.176 152 114 228 153 112.909 103 154 113.4
-104 154 113.455 101.818 155 114 103 155 111.429
-104 155 113 59 157 112.235 59 158 111.529
-222 157.565 114 177 159 113 220 160 112.545
-106 161.053 114 106.783 162 114 161 163 113.571
-189 163 113.206 106 163.13 114 159.677 164 114
-189 164 112.889 191 164 112.889 197.25 164 114
-208 164 112.457 161.667 165 114 191 165 113.684
-192 165 112.889 198 165 113.25 205 165 113.217
-67 166 112 66.4737 166 114 67 165.667 114
-68 166 112.241 68.8947 166 114 190 166 113.5
-191 166 113.25 192 166 111.947 197 166 113.885
-197 165.667 114 198 166 113.778 199 166 112.5
-203 166 111.75 66 166.75 114 68 167 111.923
-192 167 111.545 193 167 111.273 56 168 112.25
-56 167.125 114 56.5833 168 114 66.1429 168 114
-68 167.947 114 67.8571 168 114 90.625 168 114
-93 167.261 114 167.769 168 114 168 167.25 114
-172 167.391 114 193 168 111.6 56 169 111.75
-56.2 169 114 169 168.609 114 184 169 113.684
-184 168.333 114 185 168.75 114 185 169 113.308
-192.417 169 114 202.65 169 114 203 168.125 114
-204 168.455 114 173 169.857 114 185 170 113.308
-184.6 170 114 193 170 111.9 194 169.444 114
-194 170 112.125 95 170.261 114 185 171 112.263
-186 171 113.182 192.889 171 114 194 171 112
-195 171 112.696 93 171.684 114 185 172 113.182
-186.438 172 114 194 172 113 195 172 111.667
-196 172 112.714 204 171.875 114 205 172 112.875
-204.4 172 114 205.231 172 114 94 173 111.5
-185 172.111 114 205 173 112.5 204.867 173 114
-205.5 173 114 91.8667 174 114 94.6667 174 114
-195 173.722 114 197.429 174 114 206 173.25 114
-206 174 111.429 93 174.393 114 172 175 111.75
-172.125 175 114 196 174.667 114 205 175 113.571
-206.15 175 114 85 176 111.346 171 175.545 114
-176 186.853 114 181 187.808 114 201.75 67 117
-204 67 116.125 203 68 116.471 205 69 116.1
-208 73 116.217 209 73 116.125 208 74 116.333
-207.5 74 117 209 74 115.962 210 76 116.1
-211 76 116.217 215 77 115.2 214 78 115.8
-216 78 115.645 217 78 116.333 213 78.6667 117
-218 79 116.444 221.966 80 117 219 81 115.2
-222 81 114.136 221 82 114.176 221 83 114.857
-225 84.1111 117 223 86.8667 117 224 89 115.7
-225 89 115.227 225 90 115.5 224.697 92 117
-224 95 116.824 234.059 105 117 226 108 116.4
-227 110 116.778 228 111 116.824 228 112 116.206
-228 113 116.419 229 114 114.529 229 115 114.857
-229 118 115.8 230 119 116.885 231 119 115.759
-231 121 114.931 230 122 114.882 30 125 116.087
-31 126 115.5 228.5 126 117 146 127.966 117
-145.955 128 117 146 129 115.655 32 130 114.231
-134 130 116.5 135 130 116.471 230 130 116.778
-132 131 116.069 133 131 114.818 134 131 115.3
-135 131 116.778 132 132 114.182 133 132 114.091
-134 132 115.5 133 133 114.931 159 133 115.5
-229 133 116.143 230 133 115.147 149.433 134 117
-230 134 116.032 231 134 116.1 232 134 114.692
-159 135 114.2 161 135 116.217 228 135 116.8
-229 135 115.889 232 135 115.364 159 136 114.857
-160 136 115.56 161 136 116.739 163 136 116.333
-229 136 116.625 162 137 116.217 230 137 114.4
-164 138 116.739 164 139 115.889 226 142 116.824
-105.867 143 117 226 143 116.143 229 143 114.176
-167 144 115.2 228 144 115.853 229 144 115.235
-104 144.933 117 103.857 145 117 105 145 115.5
-168 145 116.625 229 145 115 168 146 116.885
-169 146 116.778 170 146 116.333 227 146 116.545
-170 148 115.8 172 149 115.457 222.125 149 117
-223 150 115.457 224 151 115.2 220 152 116.143
-221 152 115.853 222 152 115.8 224 152 115.853
-51 152.087 117 221 153 115.457 222 153 115.8
-223 153 116.471 102 154 116.143 104 154 115.5
-219 154 116.5 101.895 155 117 103.545 155 117
-182 154.75 117 216 155 116.471 217 155 116.032
-218 155 116.333 181 156 115.457 182 156 116.4
-216 156 115.8 217 156 116.333 217.75 156 117
-223 155.917 117 161 157 114.8 160.313 157 117
-161 156.083 117 162 157 116 162.333 157 117
-182 157 116.032 185 157 116.206 212 157 116.471
-214 157 116.559 216 157 115.457 217 157 116.333
-217.75 157 117 161 157.55 117 162 157.857 117
-176 158 114.207 183 158 115.853 212 158 115.457
-216 158 115.457 217 158 116.032 218 158 115.929
-185 159 115.457 205 158.833 117 208 159 116.419
-210 159 116.125 189 160 115.457 192 160 116.8
-207 160 116.032 208 160 115.645 209 160 116.217
-217 160 114.9 187 161 114.29 188 161 114.968
-204 161 115.8 205 161 115.645 207 161 116.419
-208 161 116.419 209.5 161 117 217 161 116.069
-103.083 162 117 206 162 116.1 210 162 114.667
-216 162 116.864 217 162 116.88 58 163 116.739
-57.8182 163 117 58.25 163 117 69 162.818 117
-103 163 116.087 103 162.125 117 211 163 114.931
-69 164 116.217 103 163.875 117 162.077 164 117
-68 165 116.25 68 164.813 117 159.933 165 117
-197 165 114.333 69 166 114.667 170 166 114.9
-190 166 114.75 190 165.455 117 191 166 115.2
-56 167 114.75 56 166 117 66 167 114.333
-67 167 116.348 67.3333 167 117 91 167 114.783
-191 167 115.765 192 167 116.455 56 168 117
-67 168 114.692 68 167.385 117 89.0909 168 117
-168.125 168 117 172 168 116.1 171.684 168 117
-184 168 114.6 184 167 117 184.333 168 117
-190.923 168 117 192 168 114.923 193 168 115.333
-193.333 168 117 201.067 168 117 202 167.067 117
-203 168 114.13 204.467 168 117 56 169 114.563
-89.25 169 117 91 169 115 94.6364 169 117
-171 169 115.579 172 169 115.7 184 168.8 117
-184 169 116 185 169 116.25 192 169 114.789
-202 169 116.6 201.923 169 117 204.609 169 117
-79 170 115.875 79 169.727 117 80 169.417 117
-80 170 115.385 185 170 116.571 192 169.737 117
-79 170.273 117 80 170.304 117 94 170.286 117
-185 171 115.737 186 171 114.474 195 171 116.727
-194.875 171 117 204 171 116.8 204 170.857 117
-94 171.455 117 186 172 114.778 194 172 115.286
-194 171.467 117 195 172 116.333 196 172 115
-205 172 114.474 92.2273 173 117 195 173 115.773
-196 173 116.1 205 173 114.6 93 174 116.75
-171 173.889 117 197 174 114.692 205 174 115.286
-206 174 115.636 206 175 114.818 172 175.933 117
-204 185 115.579 176.85 186 117 177 185.813 117
-178 185.417 117 184 186 116.735 184 187.385 117
-200.25 67 120 200.333 69 120 204 70 117.968
-202.125 71 120 204 71 118.313 204 74 119.143
-206 77 118.457 208 77 118.5 207 78 119.032
-210 78 118.25 217 79 117.273 210 79.5455 120
-214 80 119.5 216 80 117.261 217 80 117.103
-216 81 117.667 221 86 118.364 219 87 119.824
-220 87 119.8 220.5 87 120 220 88 119.559
-221 88 119.5 222 87.2857 120 222 89 119.1
-222 90.3333 120 223 90.7692 120 224 91.125 120
-222.545 93 120 224 93 118.56 33 105 119.8
-33 107 119.471 32 108 119.739 33 108 119.824
-223.867 108 120 32 109 118.556 33 109 119.824
-224.526 109 120 31 110 119.526 225 110 119.1
-32 111 118.5 224 111 119.419 224 112 118.457
-225 112 118.2 31 113 117.75 224 113 118.457
-225 113 118.645 226 113 118.3 226 114 119.864
-31 119 117.529 226 119 118.457 226 120 118.457
-227 120 118.258 230 120 117.391 225 121 119.471
-227 121 119.739 229 121 118.08 33 127 118.818
-29.4857 128 120 227.929 128 120 145.147 129 120
-228 129 119.864 226 130 119.143 162 131 118.8
-226 131 119.118 161 132 118.235 164 132 118.8
-227 132 118.457 34.4545 133 120 34 134 119.211
-226 135 118.457 230 135 117.517 231 135 117.409
-230 136 117.429 165 137 117.176 169 136.167 120
-169 137 119.143 168 138 118.457 224 138 118.8
-226 138 118.75 110 139 119.824 167 139 118.645
-225 139 119.032 226 139 119.333 227 139 118.556
-167 140 118 226 140 118.941 228 140 117.265
-224 141 118.8 106.133 142 120 221 142 118.8
-106 142.5 120 105.75 143 120 170 143 118.645
-173 143 118.8 103 144 119.769 105.857 144 120
-220 144 118.457 102 145 117.6 103 145 117.947
-104 144.667 120 105 144.857 120 221 145 118.457
-99 146 118.853 101 146 118.182 102 146 117.231
-219 146 118.457 221 146 118.8 222 146 119.206
-223 146 119.471 174 147 118.2 219 147 118.8
-221 147 119.559 222 147 119.273 223 147 118.909
-220.286 148 120 221 148 119.559 222 148 118.545
-221 149 119.1 179 150 118.457 220.346 150 120
-177 151 118.556 178 151 118.889 179 151 118.457
-213 152 118.8 218 152 117.857 181 153 119.1
-185 153 119.824 215 153 118.457 217 153 117.882
-102 153.85 120 103.438 154 120 210 154 118.457
-215 154 118.2 222 154 117.455 223 154 118.111
-224 154 117.45 104 155 119.143 209 155 118.457
-211 155 118.457 213 155 118.7 219 155 117.273
-221 155 118.759 222 155 119.172 223 155 118.435
-103 155.895 120 104 155.143 120 184 156 117.529
-189 156 118.457 211 156 117.882 213 156 117.968
-218.727 156 120 219 155.87 120 219.429 156 120
-220 156 119.294 222 156 119.04 161 157 118.737
-162 157 118.636 189 157 118.2 201 157 119.206
-219 156.75 120 219 157 119.5 198 158 119.419
-202 158 119.206 203 159 118.4 165 160 119.609
-164.727 160 120 165 159.75 120 202 160 117.182
-210 160 117.6 165 160.6 120 210 161 117.333
-211 161 119.786 211.25 161 120 212.75 161 120
-214 161 118.909 216 161 118.105 57 162 118.688
-57 161.125 120 58 161.083 120 58 162 118.565
-104 162 118.65 105 162 118.111 106 162 117.375
-188 162 119.684 57 163 118.688 67.5333 163 120
-68 162.417 120 101 163 119.308 100.143 163 120
-102 162.739 120 102 163 118.364 103 162.563 120
-104 163 119 188 163 119 57 164 119
-56.5556 164 120 57.8 164 120 101 164 119.217
-102 164 119.25 103 164 118 103.111 164 120
-181 164 119.308 188 164 119.308 189 164 118.889
-57 165 117.75 56.25 165 120 57.25 165 120
-68 165 118.125 68.3125 165 120 162 164.053 120
-162.667 165 120 169 164.5 120 180.739 165 120
-189 165 118.444 190 165 117.75 197 165 119.667
-198 165 119.55 57 165.25 120 68 166 118.826
-69 165.55 120 69 166 118.313 93.2 166 120
-161 165.947 120 182 166 118.364 183 166 117.375
-189.067 166 120 191 165.333 120 198 166 118.25
-199 166 118.95 56 167 117.75 68 167 118
-162 166.261 120 171.519 167 120 183 166.636 120
-190 166.737 120 198 166.35 120 200 167 119.182
-199.25 167 120 200 166.571 120 201 166.632 120
-201 167 117.375 184 168 117.75 193 168 118.579
-192.25 168 120 201 168 118 202 167.417 120
-192 169 119.211 192 168.375 120 203 169 119.87
-203 168.857 120 79 170 117.563 80 170 118.75
-193 170 119.684 203 170 117.391 204 170 117.6
-93 171 119 94 171 118 94.3704 171 120
-94.3704 172 120 94 172.667 120 170.192 175 120
-171 175.808 120 184 184.267 120 176.533 186 120
-180 186 117.25 181 186 117.6 181.8 186 120
-182.091 186 120 185 186 117.091 175 186.588 120
-181 187 120 184 187 117.652 183.053 187 120
-185 187 117.088 182 187.615 120 200.25 68 123
-200.333 69 123 205 80 122.625 207 80 121.556
-208 80 122.423 210 80 120.714 221 79.913 123
-205 80.75 123 207 81 121.889 214 81 120.12
-206 82 122.032 207 82 121.645 208 82 122.8
-213 82 120.333 214 82 120.231 211 83 121.645
-213 83 121.5 210.182 84 123 212 84 121.8
-213 84 122.125 213 84.875 123 214 85.5 123
-216 87 122.739 217 87 122.55 221 87 120.273
-222 87 120.333 218 88 121.2 220 89 121.038
-221 89 120.103 221 90 120.231 221 91 121.5
-223 91 122.25 220 92 122.129 221 92 121.7
-222 92 121.889 222.667 92 123 222 93 120.529
-34 102 121.962 34 101.182 123 33 103 121.895
-34 103 121.7 33 104 120.682 34 104 121.5
-31.8235 105 123 34 105 121.5 32 106 120.667
-222 107 120.529 220 109 122.778 224 109 121
-220 110 122.333 221 110 122.032 222 110 122.206
-223 110 121.909 221 111 122.806 222 111 121.909
-221 114 122.032 222 114 120.857 220 115 122.143
-225 115 120.273 226 115 120.692 223 116 121.25
-224 116 121.125 225 116 120.333 221 117 121.457
-224 117 121.2 222 118 122.333 223 118 122.739
-223 119 122.063 223 120 121.853 222 121 121.457
-224 121 120.529 221 122 121.457 223 122 121.457
-226 122 120.455 227 122 121.219 221 123 121.457
-224 123 121.5 225 123 121.853 226 123 121.909
-227 123 121.219 149 123.7 123 226 124 121.909
-227 124 120.094 34.4737 126 123 226 126 121.125
-161 126.5 123 165 127 122.824 225 127 122.1
-226 127 121.7 34.7391 128 123 134 127.833 123
-145.059 128 123 165 128 121.8 217.875 128 123
-219 128 121.8 223 128 121.8 227 128 122.167
-135 128.077 123 162 129 121.235 164 129 121.8
-167 129 121.8 226 129 120.115 227 129 120.316
-35 130 121.818 136.4 130 123 124 133 121.355
-219 133 121.457 168 134 121.5 220 135 121.8
-219 136 122.786 218 138 121.457 220 138 121.457
-221 138 121.645 222 138 121.304 174 139 121.457
-177 139 122.471 220 139 122.8 221 139 122.8
-222 139 122.217 223 139 120.5 104.6 140 123
-106 140 121.355 173 140 121.2 177 141 122.1
-178 141 122.032 179 141 122.471 221 141 120.818
-105 142 123 106 142 120.857 176 142 122.129
-215 142 122.25 102 143 120.29 103 143 120.261
-104 143 120.75 176 143 121.543 212 143 122.471
-104 144 120.857 116 144 121.714 117 143.818 123
-181 144 121.8 182 144 122.471 212 144 121.457
-214 144 121.886 104.417 145 123 106 145 122
-116 145 120.167 117 145 120.3 179 145 121.457
-215 145 121.8 105 145.438 123 106 145.261 123
-116 145.739 123 181 146 122.778 184 146 121.8
-210 146 122.806 214 146 121.645 216 146 121.457
-46 147 121.111 181 147 122.778 182 147 122.778
-184 147 121.457 205 147 122.471 205 146.5 123
-208 147 121.457 209 147 121.8 211 147 121.8
-91 147.5 123 181 148 121.7 205 148 121.457
-207 148 121.457 211 148 121.457 212 148 122.125
-214 148 122.125 90 149 122.419 188 149 121.8
-210 149 121.457 212.375 149 123 42 150 122.4
-41.625 150 123 42 149.625 123 42.2727 150 123
-89 150 120.882 203 150 121.853 204 150 121.457
-209 150 121.457 210 150 121.645 211 150 122.217
-211.75 150 123 220 150 121.08 52 151 120.692
-208 151 121.457 214 150.625 123 53 152 122.5
-54.75 152 123 62 151.5 123 84 152 120.529
-189 152 121.457 208 152 121.2 177 153 122.609
-176.4 153 123 177 152.727 123 177.75 153 123
-177 153.25 123 103 154.211 123 104 155 120.857
-200 155 121.457 101.313 156 123 103 156 120.375
-217 156 122.182 216.455 156 123 218 155.813 123
-218 156 122.182 219.429 156 123 102 156.846 123
-103 156.933 123 217 157 121.696 216.286 157 123
-218 157 122.182 219 157 120.75 217 157.5 123
-206 159 122.053 207 159 121.875 165 159.813 123
-207 160 121.355 208 159.083 123 209 159.727 123
-209 160 122.438 209.429 160 123 60 161 122.333
-165 160.75 123 166 161 121.091 186 161 122.71
-187 160.364 123 188 161 122.55 207 161 121.696
-208 161 122.053 209 160.333 123 212 161 121.125
-57 161.455 123 70 162 120.273 72 161.263 123
-72 162 121.645 167 162 122.125 166.125 162 123
-167 161.125 123 187 162 120.222 57 163 122.625
-71 163 121 98 163 122.526 98 162.625 123
-99 162.045 123 99 163 120.261 100 163 120.158
-102 163 121.636 101.667 163 123 103 163 120.875
-167 162.467 123 169 163 122.71 168.25 163 123
-181 163 122.55 180.87 163 123 181.75 163 123
-57 164 120.75 58 163.273 123 90.6957 164 123
-93 164 122.4 100 164 121.091 102 164 121.125
-103 164 120.333 161 164 121.2 168 164 122.739
-167.923 164 123 172 163.6 123 182 163.143 123
-57 165 120.375 161 164.6 123 163 164.391 123
-182 165 122.842 182 164.857 123 191.375 165 123
-195 164.333 123 196 164.217 123 198 164.923 123
-172.654 166 123 182 166 120.783 195.8 166 123
-210 166 122.609 209.75 166 123 85 167 122.222
-84.125 167 123 85 166.632 123 85.5833 167 123
-162 166.783 123 163 166.526 123 191 167 121.235
-191 166.167 123 200 167 121.125 201 167 121.235
-210 167 122.438 211 167 122.4 84 168 122.4
-83.25 168 123 169 167.609 123 192 168 120.375
-201 168 120.4 202 168 121.05 203 168 120.783
-211 168 120.2 211.875 168 123 84 168.2 123
-90.125 169 123 91 169.368 123 95.1875 170 123
-211 169.15 123 212 169.375 123 92.4615 171 123
-93 172 121.75 170 171.87 123 170 173 120.75
-171 172.727 123 193 174 122.6 193 173.333 123
-194 173.067 123 194 175 120 194.9 175 123
-171 175.316 123 159 180.31 123 183.4 184 123
-184.545 184 123 182.895 185 123 175.143 186 123
-177 185.4 123 177 186 121.615 180.417 186 123
-181 186 121.091 178 187 121.889 179 187 122.1
-180 187 121.5 183 186.333 123 178 187.909 123
-182 188.435 123 193 188.077 123 92 190.6 123
-203 70 125.71 202 71 124.5 202.37 71 126
-202.286 73 126 208 81 123.12 205 83 125.727
-208 83 123.682 207 84 124.826 206 85 125.778
-205.8 85 126 206.5 85 126 206 86 125.125
-205.364 86 126 206.875 86 126 209 86 125.125
-210.375 86 126 211 85.7727 126 207.4 87 126
-209 87 125.032 210 87 125.333 210.545 87 126
-214 87 124.304 212 87.25 126 211.143 88 126
-213 88 125.625 210.867 89 126 212 89 124.645
-213 90 125.333 216 91 125.7 223.909 91 126
-215 92 125.739 216 92 125.75 224 92 124.636
-214 93 125.778 217 93 124.889 216 94 124.645
-217 94 125.217 218 94 125.625 217 95 125.217
-218 95 125.211 219 95 125.786 36 96 125.8
-36 95.7143 126 216 96 124.645 217 96 124.889
-218 96 124.111 219 96 123.136 35 97 125.778
-36 97 125.471 36 98 125.824 34 99 125.609
-35 99 124.5 34 100 124.421 35 100 124.5
-215 100 124.457 35 101 124.818 216 105 124.457
-218 109 124.5 219 109 124 218 111 123.882
-219 111 123.517 216 112 125.471 221 112 123.176
-215 113 125.5 218 113 125.885 220 113 124
-219 114 125.864 214 116 125.824 215.75 117 126
-217 119 124.457 36 121 124.457 37 121 125.471
-152.6 121 126 155 121 124.457 157 121 124.8
-215 121 124.457 152 122 125.625 153 122 124.853
-166 121.833 126 153 123 123.882 155 123 124.457
-165 123 125.125 218 123 124.457 36 124 124.8
-146.923 124 126 165 124 125.217 170 123.833 126
-218 124 124.8 220 124 123.818 36 125 124.457
-160 125 124.313 165 125 125.125 170 125 124.8
-212 125 125.1 211.4 125 126 219.857 125 126
-221 125 125.25 223 125 125.545 224 125 125.206
-35 126 123.882 36 126 124.645 37 126 124.645
-145.8 126 126 160 126 123.783 170 126 124.457
-212 126 125.778 213 126 125.55 213.6 126 126
-219 126 125.885 223 126 125.545 224 126 124.909
-36 127 125.217 213.25 127 126 36 128 124.826
-37 128 124.889 174 127.25 126 217 127.739 126
-216.571 128 126 228 128 123.75 227.25 128 126
-37 129 124.645 38.5 129 126 174 129 124.645
-214 129 125.55 216 129 125.55 216 128.727 126
-228 128.75 126 38 130 125.471 174 130 124.889
-146.5 131 126 212 131 124.457 37 132 125.559
-176 132 124.645 216 132 124.889 177 133 125.143
-211 133 124.8 215 133 124.457 211 134 124.457
-217 135 124.3 216 136 124.147 217 136 124.5
-176 137 124.111 213 138 124.2 207.167 139 126
-209 139 124.457 217 139 124.125 224 139 125.455
-223.2 139 126 224 138.556 126 225 138.5 126
-225 139 125.143 102 140 124.2 104 140 124.227
-182 140 124.645 183 140 124.7 207.5 140 126
-216 140 124.8 217 140 124.545 43 141 125.824
-103 141 123.947 104.857 141 126 167 141 124.385
-166.364 141 126 167 140.417 126 182 141 124.889
-184 141 124.645 209 141 124.645 216 141 124.345
-218 141 123.818 42 142 124.235 43 142 125.559
-99 142 124.2 105 141.25 126 167 142 124
-183 142 124.645 186 142 124.7 186.722 142 126
-203 142 124.457 207.222 142 126 209 142 124.645
-213 142 124.5 46 142.5 126 168 143 123.13
-169 143 124.3 185 143 124.645 190 143 125.778
-191 143 124.457 192 143 124.645 205 143 124.8
-97 144 123.182 105 144 124.826 116 143.769 126
-168 144 124 169 144 123 184 144 123.882
-190 144 125.032 191 144 124.645 198 144 124.457
-202 144 124.457 105 145 124.105 106 145 124.2
-116.737 145 126 168 144.37 126 169 144.609 126
-188 145 125.1 189 144.125 126 193 145 125.55
-201 145 124.457 205 145 124.457 89 145.25 126
-115 145.857 126 115.25 146 126 194 146 124.457
-90 147 124.5 116 146.111 126 191 147 124.645
-202 147 124.457 196 148 124.8 43 149 124.364
-44 149 125.609 45 149 125.8 59 149 125.824
-191 149 124.457 194 149 123.529 197 149 124.556
-214 149 124.412 216 149 124.56 217 149 124.364
-42 150 123.818 43 149.857 126 44 149.273 126
-59.3333 150 126 60 150 125.75 61 150 125.333
-64 150 124.457 212.25 150 126 215 150 125.833
-216 150 125.864 217 150 124.909 54 151 123.316
-55 151 123.833 56 151 124.5 211.4 151 126
-214.75 151 126 54 152 124.286 59 151.375 126
-177 153 124.286 218 153 125.667 217.727 153 126
-176 154 125.308 102 155 125.8 174 155 125.55
-174 154.571 126 175 155 124.862 214 155 125.118
-215 155 124.5 217 155 124.875 217.4 155 126
-175 156 124.889 176 156 124.929 176.667 156 126
-214 155.909 126 216 156 123.938 217.368 156 126
-218 156 123.6 219 156 123.692 100 156.333 126
-102 157 123.75 103 156.273 126 204 157 125.4
-216 157 124.714 218 157 123.6 219 157 123.391
-100 157.909 126 205 158 123.8 206 158 124.091
-184 159 125.323 184 158.125 126 185 158.217 126
-185 159 124.258 205 159 123.517 208 158.923 126
-165 160 123.333 185 160 123.9 186 160 123.13
-208.654 160 126 209 160 123.75 61 161 123.3
-72 161 123.789 74 161 125.471 94 161 125.455
-94.5455 161 126 180 161 125.727 180 160.714 126
-181 160.444 126 185 161 125.684 57 162 124.2
-57.6 162 126 60 162 125.25 61 162 123.75
-70 162 124.579 73 162 123.556 92 162 124.7
-167 162 125.625 167.333 162 126 168 161.923 126
-168 162 125.143 181 162 123.188 180.063 162 126
-208 162 124.875 60 162.097 126 61 162.273 126
-69 163 124.5 71 163 125.727 71.25 163 126
-167.391 163 126 168 163 123.2 171 162.265 126
-181.25 163 126 207 162.2 126 208 163 126
-90 164 124.92 97.7273 164 126 163 164 125.25
-163 163.813 126 181 164 123.563 182 164 123.783
-190 163.773 126 87 165 125.4 86.6 165 126
-87.8571 165 126 192 165 124.111 194 165 123.1
-86 166 124.35 87 166 124.444 87.6364 166 126
-90.7391 166 126 164.435 166 126 191.857 166 126
-198 166 125.318 210 166 125.25 84.4737 167 126
-86 167 124.25 86.5833 167 126 162 166.6 126
-163 167 124.8 171.2 167 126 189 166.143 126
-210 167 124.125 211 167 123.75 84 168 123.818
-90 168 123.4 211 168 125.211 191 170 124.696
-190.333 170 126 192 169.889 126 192 170 125.25
-169 171 124.765 170 170.842 126 170 171 125.609
-191 170.909 126 192 171 124.263 191.083 171 126
-169 172 124.043 168.375 172 126 192 172 125.455
-193 172 124.875 171 173 124.636 170.737 173 126
-193 173 123.75 194 173 123.75 170 174 125.211
-171 174 125 195 175 124.2 195.13 175 126
-194 175.435 126 195 175.375 126 197 178 124.889
-197 179 124.821 197.733 179 126 197 179.917 126
-175 183 125.6 179 183 125.769 164 183.941 126
-184 184 124.2 175 185 124.889 176 185 125.308
-177 184.714 126 184 185 125.684 170 185.722 126
-170.714 186 126 173 185.714 126 176 185.375 126
-171 186.087 126 172 186.261 126 179 186.455 126
-180 186.333 126 192 186.818 126 182.5 188 126
-93 190 125 96 190.059 126 202.654 72 129
-207 72 128.806 209 72.6087 129 210 73.0909 129
-208 76 128 207.533 76 129 210 79 126.789
-210 78.2632 129 211 79 128.6 210 80 127.364
-210.857 80 129 211 79.6667 129 212 80 128.833
-211.5 80 129 212 79.9091 129 212 81 128.483
-211.5 81 129 212.5 81 129 212 81.4545 129
-207 85 126.857 205.1 86 129 207 86 126.5
-208 86 126.214 211 85.6667 129 212 86 126.5
-213 86 126.5 207 87 128 212 87 126.857
-213 87 127.071 205.833 88 129 207 87.0909 129
-210 88 126.4 211 87.75 129 211 88 127
-206 88.1667 129 210 89 127.773 205 90 128.684
-214 90 126.316 204 90.625 129 205 91 127.889
-211 90.625 129 212 90.4167 129 213 91 127.071
-215 91 126.882 223 91 128.143 204 92 128.125
-223 92 126.882 37 93 128.6 38 92.7143 129
-38.0909 93 129 203 93 128.684 205 93 127.457
-208 93 128.206 209 93 128.032 210 93 128.667
-37 94 128.053 203 94 128.333 209 94 128.333
-213.125 94 129 219 94 127.286 36 95 127
-202.739 95 129 209 95 128.125 34.9333 96 129
-203.5 96 129 209.583 96 129 213 96 128.625
-212.75 96 129 206 97 127.8 208 97 127.457
-210 96.7143 129 210 97 128.684 205 97.5 129
-209 98 127.889 211 98 127.889 212 99 127.889
-213 99 127.5 209 100 127.645 209 101 127.457
-212 102 127.457 208 103 127.8 208 104 127.457
-205 109 128.206 203 110 128.143 206 110 128.032
-207 110 127.457 214 110 127.457 212 111 127.457
-200 111.833 129 201 113 127.457 198.625 114 129
-204 114 127.853 218 114 126.818 199 115 127.8
-200 115 127.457 201 117 127.457 215 117 126.265
-223 117 127.895 222.632 117 129 223.875 117 129
-211 118 127.457 212 118 127.5 223 118 128
-222.143 118 129 223.261 118 129 202 119 128.8
-208 119 127.457 213 119 128.206 214 119 127.182
-202 120 128.419 203 120 128.5 209 120 127.457
-161 120.417 129 204 121 128.118 209 121 128.032
-152 121.818 129 166.6 122 129 205 122 127.457
-29.8235 123 129 167 122.25 129 168.6 123 129
-149 123.7 129 170.25 124 129 188 124 128.909
-187.833 124 129 208 124 127.889 196 125 128.143
-197 125 127.8 206 125 127.457 218 124.955 129
-218.1 125 129 39 126 127.182 189 126 128.824
-199 126 128.032 204 126 127.457 206 126 127.645
-210 126 128.308 133 126.824 129 172.75 127 129
-174 126.857 129 174.286 127 129 199 127 128.333
-205 127 127.457 206 127 127.889 210.455 127 129
-211 127 126.75 214 127 128.077 214.571 127 129
-216 126.25 129 218 127 126.3 217.25 127 129
-173 127.125 129 199 128 128.125 206 128 128.125
-215 128 126.964 228 128 126.818 179 128.182 129
-181 129 127.645 206.833 129 129 39 130 126.581
-146.273 130 129 179 130 127.8 183 130 127.457
-197 130 127.853 198 130 127.889 205 130 127.457
-207 130 128.25 209 129.417 129 39 131 126.529
-40 131 127.2 41.625 131 129 197 131 128.4
-198 131 128.55 201 131 128.125 209 131 127.457
-40 132 127.853 188 133 128.032 40 134 127.286
-180 134 127.543 187 134 127.889 188 134 128.217
-192 134 128.471 193 133.75 129 184 135 128.1
-188.286 135 129 192 135 127.457 43 136 127.8
-43.875 136 129 182 136 127.2 184 136 128.778
-185 136 128.778 186 136 128.125 206 136 127.457
-219 136 128.55 183 137 128.143 184 137 128.778
-185 137 128.778 196 137 128.55 203 137 127.8
-218 137 128.625 217.813 137 129 219 137 127.696
-220.375 137 129 102 138 126.29 184 138 127.75
-187 138 127.645 188 138 127.962 202 138 128.559
-219 137.667 129 220 137.375 129 222 138 128.4
-221.25 138 129 223 138 127.25 224 138 127.875
-224.375 138 129 186 139 128.1 187 139 127.889
-188 139 128.333 201 139 128.8 203 139 128.559
-205 139 128.032 206 139 127.444 223 139 126.429
-222.6 139 129 225 138.714 129 225.105 139 129
-186 140 126.563 187 140 127.111 188 140 127.853
-192 140 127.457 193 140 127.457 197 140 127.645
-200 140 127.457 204 140 128.423 204.714 140 129
-225 139.133 129 104 141 127.636 166.667 141 129
-167 140.143 129 188 141 128.4 189 141 128.909
-190 141 128.182 196 141 127.457 205.167 141 129
-213 141 127.154 214 141 127 105 142 126.818
-166.435 142 129 189 142 128.897 199 142 127.235
-200 142 126.882 201 142 126.176 207 142 128
-48 143 127.5 106 143 128.167 187.5 143 129
-189 143 128.833 188.857 143 129 194 143 127.345
-206 143 126.316 207 143 128 208 143 126.682
-50 143.188 129 207 144 127.615 208 144 127.7
-113.6 145 129 114 144.143 129 188 144.091 129
-114 146 128.217 115 147 128.769 114.714 147 129
-116 146.609 129 43 149 127.636 44 149 127.286
-44.4 149 129 45 148.455 129 46 148.727 129
-46 149 128.182 47 149 127.95 47.4667 149 129
-67 149 126.529 46 149.25 129 47 149.875 129
-59 150 126.094 211.455 150 129 214 150 126.75
-59 151 127 210 151 127.625 210 150.522 129
-211 151 126.3 213.667 151 129 208.813 152 129
-210 152 127.889 211 152 127.95 209 153 129
-211 152.304 129 216 153 128.786 214 153.565 129
-217 154 127.875 218 153.933 129 217.75 154 129
-174 154.5 129 176.895 155 129 205 155 128.71
-206 155 128.118 207 154.625 129 207 155 128.667
-101 156 128 102 156 127.826 174.074 156 129
-177 155.087 129 177 156 126.577 183 156 128.25
-182.125 156 129 204 156 127.147 206 156 128.308
-97 157 127.846 98 156.313 129 98 157 127.821
-100 156.067 129 101 156.625 129 101.25 157 129
-102 157 127.2 176 157 126.115 177 157 126.441
-183 157 127.8 184 156.632 129 184 157 128.125
-202 157 128.824 203 157 126.9 214 156.618 129
-217 157 127.5 178 158 128.71 183 158 128.222
-184 158 126.158 61 159 128.727 62 159 127.645
-95 159 128.4 183 158.778 129 183.1 159 129
-207.435 159 129 58.375 160 129 62 160 126.9
-71.9259 160 129 73 160 127.3 75 159.895 129
-94 160 126.75 95 160 127.038 95.7727 160 129
-179 160 128.8 180 159.045 129 180 160 126.577
-187 160 126.316 204 159.333 129 208 160 127.962
-62.4667 161 129 75 161 127.818 95 161 126.682
-95.5862 161 129 179.357 161 129 185 161 126.6
-186 161 128.348 186 160.545 129 208 161 127.304
-62 161.636 129 61.4286 162 129 71 162 128.625
-71.0769 162 129 92 161.056 129 168.769 162 129
-170 162 126.2 180 161.947 129 186 162 126.75
-187 162 128.217 207 162 126.692 207 161.167 129
-61 162.2 129 88.4545 163 129 89 162.455 129
-90 162.105 129 95 163 127.92 97.875 163 129
-167.833 163 129 181 162.231 129 187 162.75 129
-88 164 127.8 88 163.455 129 89 164 126.9
-95 164 127.714 97 164 128.286 96.6429 164 129
-100.176 164 129 163 163.571 129 163.857 164 129
-172.382 164 129 188 163.067 129 193 163.263 129
-86.5417 165 129 87 164.522 129 89 165 127.125
-90 165 127.5 97 165 128.769 98 165 128.217
-162.045 165 129 196 165 128.273 86 166 128.2
-86.3636 166 129 87.5833 166 129 91 165.261 129
-99 165.333 129 162 166 127.929 168.923 166 129
-194 166 126.818 195 166 128.294 195 165.6 129
-196 166 128.429 197 166 127.909 85 167 127.111
-86 167 127.05 92 167 127.5 93 167 128.5
-95.6667 167 129 165 167 126.857 189 167 127.125
-189.667 167 129 191 166.385 129 193 166.111 129
-166 168 128.1 166.857 168 129 189 168 127.696
-190 168 129 95.3704 169 129 164 168.333 129
-167.25 169 129 188.727 169 129 190 169 126.375
-95 169.909 129 168 170 127.75 169 170 126.783
-169.773 170 129 191 169.125 129 192 170 126.75
-168 171 128.25 167.87 171 129 169.944 171 129
-192 171 128.063 192 172 126.333 193 172 126.474
-193 173 126.45 194 173 126.45 194 174 127.222
-194 175 127.111 195 175 126.6 196 177 127.714
-196 176.75 129 197 177 127.333 197.833 177 129
-196 178 127.364 198.667 178 129 198 179.75 129
-207 180 128 92 181 128.667 92.375 181 129
-196 180.778 129 197 181 128.526 196.4 181 129
-202 181 127.174 204 181 127.765 207 181 127.393
-208 181 128.55 92 182 127.636 92.9091 182 129
-200.75 182 129 202 182 127.038 206 182 128.471
-207 182 128 208 182 127.444 209 182 126.9
-92 183 128.571 92.6667 183 129 174 183 126.273
-173.375 183 129 177 183 127.773 197 183 128.609
-198 183 128.71 207 183 128.333 208 183 126.261
-92 183.125 129 172 184 128.526 171.25 184 129
-171 185 128.455 172 185 127.8 173 185 126.682
-170 185.9 129 170.25 186 129 176 185.929 129
-175.68 187 129 179 187 127.565 178.45 187 129
-180 187 127.385 181 186.4 129 179 188 127
-178.5 188 129 180 188 126.5 181 188 127.5
-182 188 127.688 192.727 189 129 94 189.409 129
-95 190 127 193 189.194 129 86 191 126.5
-90.7368 191 129 87 191.8 129 90 191.452 129
-203 72 130.929 204 72 131.308 207 74 131.727
-208 74 130.962 211 74 130.765 208 75 130
-207.474 75 132 209 75 131.526 209 75.375 132
-208 76.5556 132 211 79 129.6 210 80 130.636
-212 80 129.231 212 81 129.882 213 82 130.5
-214 83 130.2 214.6 83 132 214 84 132
-206 85 130.2 214 85 129.429 213.5 85 132
-215 84.1 132 215 85 129.545 206.667 86 132
-210.727 86 132 215 85.5 132 42 87 131.909
-205.9 87 132 205.182 88 132 207 88 132
-41 89 131.824 205 89 130.846 205 88.2857 132
-206 89 129.882 207 89 130.857 208 89 130
-206 90 129.125 208 90 130.345 209 90 129.529
-210 90 129.261 39 91 131.739 211 91 129.391
-212 91 130.75 216 91 131.571 215.8 91 132
-216 90.7143 132 38 92 131.143 39 92 130.962
-39.6 92 132 203.37 92 132 212 92 130.364
-216 92 130.875 39 93 131 212 93 130.655
-216 92.75 132 211 95 132 212 95 132
-213 95 130.071 215 95 131.609 215 94.25 132
-216 95 132 202.533 96 132 215 95.3333 132
-211 97 129.094 34.5 98 132 203 98 131.129
-204 99 131.419 205 99 131.25 206 99 130.773
-37 100 129.529 201.727 100 132 207 100 130.304
-202 101 131.032 203 101 130.457 204 101 130.8
-202 102.25 132 202.857 103 132 203.167 104 132
-198.346 112 132 196 115.929 132 223 117 130.4
-194 118 131.739 193.889 118 132 223 118 130.636
-194 119 131.419 193.143 119 132 195 120 131.559
-212 120 129.882 153 121 129.667 155 121 130.543
-161 121 129.875 192 121 131.806 192 120.75 132
-192.5 121 132 195 121 131.471 212 121 130.154
-161 122 130.543 166 122 129.45 192.667 122 132
-193.75 122 132 40 123 131.1 152 123 129.857
-166 123 129.581 168 123 129.45 191 123 131.125
-193 122.75 132 193 123 131.909 202 123 129.545
-209 123 129.818 210 123 130.56 41 124 131.684
-159 124 130.543 167 124 130.147 187 124 130.364
-188 123.087 132 189 124 130.5 190 124 130.75
-195 124 129.857 210 124 129.409 218 124 131.625
-218 123.727 132 40 125 130.5 150 125 130.645
-157 125 130.543 165 125 129.529 170 125 130.355
-186 125 129.545 185.64 125 132 187 125 129.261
-191.75 125 132 192 124.5 132 194 125 131.182
-209 125 129.469 217 125 129.563 43 126 130.8
-157 126 130.543 158 126 129.581 160 126 129.2
-161 126 130.2 163 126 130.543 187 126 129.2
-190 126 130.235 201 126 129.094 208 126 129.714
-151 127 130.889 153 127 131.143 154 127 131.471
-155 127 131.118 156 127 131.471 159 127 129.5
-170 127 130.543 188 127 129.818 192 126.6 132
-192 127 131.824 210 127 130.667 133 127.5 132
-160 128 130.3 174 128 131.333 175 127.875 132
-176 127.625 132 180 127.435 132 185 128 131.885
-184.857 128 132 187 128 130.235 188 128 129.818
-191 128 131.206 200 128 129.844 201 128 130.545
-206.913 128 132 209.933 128 132 216 127.889 132
-44 129 130.645 161 129 131.824 164 128.909 132
-184 128.231 132 192 129 130.3 200 129 129.844
-201 129 130.182 207 128.286 132 42 130 130.111
-44 130 131.333 187 130 129.529 188 130 129.529
-189 130 130.08 190 130 129.882 191 130 130.5
-192 130 130.111 194 130 130.2 201 130 129.091
-44 131 131.333 188 131 129.265 189 131 130.773
-192 131 131.217 193 131 130.2 199 131 130.2
-46 132 131.333 192 132 131.333 194 132 130.5
-196 132 129.882 199 132 132 43 133 131.909
-47 133 131.032 106 133 129.882 110 132.265 132
-189.538 133 132 192 133 130 193 133 129.529
-195 133 130.235 197 133 131.217 197.462 133 132
-42 134 130.909 48 134 131.419 189 134 130.071
-190 133.545 132 191 134 130.8 194 134 129.682
-195 134 130.5 196 134 130.3 197.5 134 132
-198.857 134 132 45 134.857 132 103 135 129.265
-196 135 130 101 136 129.265 102 136 129.176
-189 136 129.517 196.571 136 132 218 136 129.167
-217.105 136 132 189 137 129.774 190 137 129.469
-196.696 137 132 201 137 129.9 221 136.875 132
-221 137 130.875 49 137.85 132 199.688 138 132
-217 138 131 220 138 129.682 223 138 130.615
-45 139 130.545 46 139 131.206 49 139 130.457
-52 139 130.457 199 139 129.882 199 138.478 132
-222 138.545 132 223 139 130.286 224 139 130.154
-50 141 130.457 87 141 131.206 131.294 141 132
-168 141 130.105 185 141 131.625 186 141 131.438
-186.188 141 132 204.75 141 132 205 140.813 132
-207.333 141 132 50 142 130.2 86 142 130.457
-106 142 131.143 167 142 130.182 186 142 132
-188 142 129.391 205.417 142 132 106 142.286 132
-187 143 131.25 186.333 143 132 187 142.857 132
-187.667 143 132 206 142.259 132 56 144 130.457
-75 144 130.457 80 144 130.457 85 144 129.265
-158 144 130.875 157.667 144 132 159 143.091 132
-159 144 130.421 159.667 144 132 171 144 129.789
-172 143.25 132 186.813 144 132 189 144 132
-74 145 130.457 81 145 129.529 82 145 130.235
-84 145 129.818 113.818 145 132 158 144.75 132
-159 145 131.308 158.143 145 132 159.545 145 132
-170 145 130.8 172 145 130.853 116.111 146 132
-159 145.4 132 172 146 131.118 73 147 129.176
-114 147 129.556 116 146.375 132 114 148 131
-115 147.947 132 45 149 129.783 46 149 129.6
-47 149 130.75 212 150 129.783 212 151 130.957
-208.8 152 132 210.545 152 132 63 153 131.077
-62.2 153 132 63 152.667 132 64 153 130.95
-208 153 129.75 210.133 153 132 216 153 129.273
-218 153 130.826 65 153.571 132 65 154 131.667
-66 153.667 132 66 154 131.419 207 154 130.875
-206.625 154 132 209 154 131.667 209.5 154 132
-216 154 130.667 217 154 129.474 64.8125 155 132
-66 155 131.118 181 155 130.3 182 155 129.1
-183 155 129.167 203.25 155 132 208 155 130.5
-209 155 131.8 210 155 131.471 211 154.421 132
-211 155 130.969 212 154.192 132 65.6 156 132
-67 155.125 132 67 156 131.323 68 156 131.667
-98.5455 156 132 175 155.818 132 176 155.65 132
-180.923 156 132 182 156 129.115 201 156 130.696
-202 155.419 132 208 156 131.8 209 155.5 132
-210.25 156 132 64 157 131.8 64.5 157 132
-66 157 131.769 68 157 131.118 69 157 131.118
-70.1875 157 132 99 156.357 132 99.4091 157 132
-175.1 157 132 184.077 157 132 200 157 130.543
-206.143 157 132 209 157 131.824 209.667 157 132
-212 156.292 132 214 156.519 132 61.2273 158 132
-65 158 131.654 70 157.75 132 93.6667 158 132
-94 157.474 132 185 158 129.947 184.188 158 132
-200 158 130.543 201 158 130.355 206 158 130.5
-206 157.071 132 61 158.278 132 71.4167 159 132
-72 158.533 132 74 158.824 132 75 159 130.889
-98 158.567 132 178 159 130.174 179 158.1 132
-179 159 129.158 183 158.188 132 184 159 131.348
-184 158.375 132 185 159 131.2 200 159 131.71
-204.25 159 132 207 159 130.579 206.25 159 132
-77 159.455 132 77.75 160 132 181 159.227 132
-185 160 130.742 186 160 129.783 206 160 131.885
-207 160 131.04 77 161 131.118 78 160.4 132
-78 161 131.743 89 161 131.053 92.6 161 132
-178 160.545 132 91 161.474 132 99 163 130.909
-181 162.375 132 186 162.474 132 96 163.571 132
-163 164 129.947 168.265 164 132 184 164 131.471
-183.25 164 132 189 163.45 132 193 164 131.625
-87 165 130.65 87.75 165 132 92 164.409 132
-96 165 129.158 98.9333 165 132 163 165 131.172
-164 165 131.333 183.333 165 132 185 165 130.147
-194 165 130.875 195 165 130.5 87 166 129.75
-97 166 131.684 163 166 131.5 166 165.903 132
-190 165.833 132 189.875 166 132 167 166.567 132
-93 168 129.316 163.769 168 132 167 168 129.091
-168 167.346 132 168 168 130.3 188 168 132
-95 168.273 132 166 169 130.227 167 169 129.1
-189 168.857 132 189 169 131.571 190 169 130.105
-62.75 170 132 63 169.8 132 64 169.143 132
-64 170 129.429 94 170 129.882 190 170 129.45
-191 170 129.778 63 171 131.571 62.75 171 132
-169 170.895 132 176 171 131.25 175.143 171 132
-197 170.625 132 175 172 131.667 176 172 130.5
-178 172 131.71 179 172 131.71 179.429 172 132
-198 172 130.444 199 172 131.4 176 173 131.308
-177 172.667 132 179 173 131.71 179.273 173 132
-175 174 131.4 198 173.909 132 198 175.4 132
-199 175.8 132 197 176.6 132 199 177 131.125
-180 179 131.71 196 178.4 132 201 179 130.444
-200.067 179 132 178 180 131.71 178 179.75 132
-178.75 180 132 92 181 132 178 181 130.895
-177 181 132 178.875 181 132 208.526 181 132
-92 182 131 179 181.091 132 196 181.455 132
-92 183 129.333 171 182.941 132 199 183 130.696
-201 183 130.364 206 183 130 172 183.684 132
-180.875 184 132 198 184 129.794 199 184 130.6
-200 184 130.625 202 184 130.821 203 184 131.471
-204 184 131.824 182 184.6 132 183 184.6 132
-184 184.625 132 199 185 131.4 200 185 130.5
-201 185 130.2 202 185 130.8 203 185 131.1
-204 185 130.962 168 185.045 132 171 186 129.45
-172 186 129.75 191 186 131.571 201 186 129.2
-175 187 131.217 176 188 129.783 178 189 130.579
-179 188.75 132 179 189 131.625 93 189.8 132
-179 189.167 132 193 189.323 132 85 191 131.727
-91 190.056 132 86 68 134.625 87 68 134.125
-85 69 134.206 87 69 134.419 91 69 134.824
-203 72.6538 135 207.278 75 135 208 75.6842 135
-215 77 133.444 49 78 134.8 214 78 134.769
-210 79 132.529 214 78.2857 135 216 78.1333 135
-213 79.8667 135 214 80 133.962 213 81 133.5
-212.375 81 135 211.714 82 135 207 82.375 135
-207 83 134.118 208 83 133.846 209 83 134.824
-209.333 83 135 211.714 83 135 43 84 133.696
-44 84 134.419 44 83.1429 135 206 84 132.125
-207 84 133.846 208 84 133.5 208.714 84 135
-209 83.3333 135 210 84 134.769 210.167 84 135
-213 84 134.143 214 83.5 135 213.667 84 135
-42 85 133 41.5652 85 135 43 85 132.581
-44 85 134.471 207 85 134.75 207.125 85 135
-208 84.4167 135 210 84.3333 135 213.75 85 135
-214 84.3333 135 215 84.625 135 215.25 85 135
-42 86 132.261 43 86 133.2 207 86 132.5
-211 86 133.8 41 87 132.316 43.5909 87 135
-206 87 132.143 41 88 132.1 42 88 132.882
-206 88 133.227 40 89 132.115 205 89 132.6
-206 89 133.714 207 89 133.412 39 90 133.8
-206 89.6 135 40 91 132.176 216 91 132.857
-215 94 132.75 214.4 94 135 215.6 94 135
-214 95 133.421 213.333 95 135 216 94.4 135
-214 96 133.444 215 96 132.9 215.737 96 135
-216 95.375 135 214 97 133.778 215 97 134.053
-214 97.9167 135 210 102 134.71 210 101.727 135
-202.278 103 135 230.5 103 135 40 115 132.581
-196 117.143 135 193.25 119 135 192 120.75 135
-192.667 121 135 43 122 133.355 44.25 122 135
-190.75 122 135 192.75 122 135 193.25 122 135
-193 122.167 135 40 124 132.176 188 123.833 135
-189 123.833 135 190 123.286 135 218 123.421 135
-192 125 132.75 193 125 132.316 218.806 125 135
-192 126 132.75 148 127 132.857 149 127 133.2
-150 127 132.176 209.375 127 135 133 128 133.444
-186.143 128 135 206.125 128 135 209.909 128 135
-216 128 133.2 148 129 133.543 149 129 133.543
-156 129 133.543 163 129 132.857 174 129 132.103
-206 129 134.182 207 129 133.25 216 128.75 135
-154 130 133.543 204 130 134.71 203.85 130 135
-205 130 134.25 206 130 134.684 207 129.368 135
-215 130 134.308 215 129.25 135 148 131 132.857
-163 131 133.543 174 131 134.286 189.353 131 135
-204 130.75 135 215 131 133 215.667 131 135
-151 132 134.118 160 132 133.5 162 132 133.8
-163 132 133.543 166 132 134.471 199 131.462 135
-215 132 133.688 214.125 132 135 150 133 134.143
-189 133 133.75 189 132.286 135 191 133 132.833
-44 134 132.29 45 134 132.529 51 134 134.143
-52 134 134.206 150 134 134.032 156 134 133.645
-157 134 133.889 163 134 133.125 164 134 133.147
-175 134 134.727 189 134 133.227 190 134 133.364
-190.5 134 135 46 135 132.882 47 135 132.882
-51 134.833 135 53 135 134.333 154 135 134.471
-155 135 134.143 164 135 133.455 187.643 135 135
-189 135 133.345 198.333 135 135 47 136 134.559
-47.625 136 135 165 136 134.531 190 136 133.966
-211 136 134.654 210.8 136 135 213 136 133.8
-214 136 134.032 215 136 134.333 46 137 133.182
-47 137 134.559 48 137 134.897 49 136.583 135
-57 137 134.8 57 136.75 135 189 136.455 135
-190 136.526 135 195.5 137 135 211 137 134.118
-210.091 137 135 212 137 134.118 214 137 133.8
-215 137 132.857 216 137 132.1 46 138 132.529
-47 138 133.182 56 138 134.217 56 137.143 135
-55.25 138 135 90 138 132.882 161 138 134.714
-55 139 132.429 55 138.1 135 215 138.609 135
-117 140 134.6 116.714 140 135 118 140 133.8
-119 139.455 135 119 140 134.053 119.316 140 135
-185 139.867 135 69 141 133.8 73 141 133.457
-76 141 134.824 76 140.6 135 79 141 133.457
-186 140.444 135 186.333 141 135 203 141 134.032
-204 141 133.35 207.455 141 135 77 142 132.909
-104.5 142 135 105.75 142 135 168 142 132.321
-169 142 133.179 170 142 133.32 185 142 132.13
-186.333 142 135 203 142 134.824 105 142.6 135
-186 143 132.429 186.545 143 135 187 143 132.857
-159 144 134 170 143.167 135 171 143.391 135
-172 143.105 135 186 143.429 135 187 144 134.25
-187.25 144 135 159 145 133.636 188 144.375 135
-113.5 146 135 115 146 134.7 161 146 133.95
-160 146 135 161 145.125 135 162 146 135
-113 147 132.789 113 146.125 135 161 147 134.125
-160.563 147 135 162 147 134.679 172 147 132.091
-113 148 133.3 112.37 148 135 161 147.467 135
-162 147.273 135 173 148 133.645 174 148 134.739
-178 148 133.6 178 147.417 135 50 149 133.714
-49.8125 149 135 51 149 133.6 112.818 149 135
-114 149 134.727 125 148.04 135 174 149 134
-175 149 133.846 177 149 133.355 178 149 133
-178.783 149 135 51 150 133 50.0909 150 135
-52 149.067 135 53 149.565 135 53.9091 150 135
-113 149.133 135 178 150 133.688 53 150.667 135
-177 151 134.71 178 151 133.8 210 151 132.692
-211 151 132.346 179 152 133.969 179.917 152 135
-210 152 133.125 63 153 133 63.7273 153 135
-178 152.188 135 180 153 133.258 181 153 134.55
-65 153.625 135 66 153.667 135 66.2727 154 135
-180 154 132.103 182 153.769 135 210 154 132.375
-211 153.6 135 179.409 155 135 182.955 155 135
-212 154.263 135 214 155 134.471 213.333 155 135
-65 156 133.688 64.5625 156 135 68 155.3 135
-175 156 132.4 177 156 132.875 183 156 134.885
-198 155.65 135 210 156 132.2 212 156 134.625
-213 156 133.4 214 156 133.826 65 157 132.261
-98.6774 157 135 165 157 134.16 164.364 157 135
-165 156.417 135 176 156.867 135 175.867 157 135
-181 156.077 135 182 157 133.2 183 157 134.333
-198 157 132.529 208 157 132.75 210 157 132.273
-61.1429 158 135 67 158 133.258 70 158 132.273
-71 157.625 135 71 158 132.75 195 158 134.471
-197 158 133.543 205 158 133.5 205 157.5 135
-204.333 158 135 208 158 134.609 209.917 158 135
-210 157.909 135 61 159 134.167 61.4545 159 135
-65.9333 159 135 71 158.375 135 72 158.727 135
-77 158.654 135 208 159 134.6 209 159 134.609
-60 160 132.875 61 160 134.2 62 160 134.9
-78 160 132.222 79 159.217 135 80 159.263 135
-80 160 133.765 200.435 160 135 208 159.143 135
-209 159.214 135 60 161 132.333 61 161 133
-62 161 132.692 79 161 132.771 81 161 133.8
-87.5 161 135 95.5 161 135 169 161 133.385
-182 161 134.143 200 160.909 135 77 162 132.577
-81 162 134.471 92 161.778 135 178 162 132.581
-179 162 132.222 182 162 133.421 186 161.931 135
-72 163 132.818 76 162.323 135 81 162.261 135
-93 162.182 135 178 163 133.846 177.333 163 135
-181 163 133.111 182 163 133.355 183 162.364 135
-183 163 133.645 98 163.769 135 182 164 132.794
-183 164 132.194 187.947 164 135 190 164 132.333
-191 164 132.333 88 164.25 135 88 165 133
-91 164.957 135 168.222 165 135 183 165 132.789
-189 165 133.853 190 165 132.882 195 165 134.25
-195 164.333 135 98.4 166 135 149.588 166 135
-165 166 133.962 166 166 133.125 169 166 133.5
-168.5 166 135 172 166 132.261 173 165.091 135
-182 165.292 135 186 165.955 135 187 166 134.842
-195 166 134.143 97 166.706 135 165 166.6 135
-166 166.192 135 168 166.125 135 168 167 133.174
-169 166.286 135 173 167 134.25 172.125 167 135
-173.875 167 135 195 167 134.053 94 167.091 135
-94 168 132.778 95 167.7 135 173 168 134.679
-174 168 134.032 189 168 132.6 195 168 134.419
-196 167.25 135 196 168 134.471 165.433 169 135
-174 169 133.5 196 169 133.625 63 170 135
-64 170 133.2 174 170 133.645 175 170 133.174
-195 169.545 135 196 170 133.688 197 169.75 135
-197 170 133.875 63 171 134 168 170.5 135
-176 170.067 135 196.417 171 135 86 172 133.543
-174.3 172 135 178 171.8 135 179.875 172 135
-219 171.739 135 83 173 134.778 84.7143 173 135
-87 173 133.543 173.926 173 135 174 172.75 135
-177 172.733 135 179.917 173 135 205 173 133.696
-205 172.091 135 206 173 133.565 206.647 173 135
-81 174 134.52 80.5556 174 135 82 174 134.333
-85 173.667 135 176 173.25 135 178 173.273 135
-179.182 174 135 198 173.857 135 205 173.667 135
-206 174 135 81 174.8 135 86 175 134.087
-174 175 134.143 175 175 132.429 175.316 175 135
-179 174.333 135 86 176 133.421 87 176 133.889
-198 175.364 135 199.261 176 135 207 176 134.053
-207 175.25 135 208 175.571 135 208 176 132.429
-86 177 134.182 85.8696 177 135 87 177 134.308
-176 177 134.609 177 177 134.667 207 177 134.069
-208 177 134.182 208.545 177 135 86 177.333 135
-87 177.545 135 176 178 134.609 177 178 134.625
-177.375 178 135 180 177.222 135 181 177.684 135
-199.929 178 135 200.091 178 135 201 177.565 135
-207 178 132.6 208 178 133.091 208.737 178 135
-176 178.6 135 177 179 134.55 178 178.417 135
-178 179 133.688 179 179 132.273 181 179 132.158
-196 179 133.227 198 178.933 135 199 178.684 135
-177 180 135 179 180 132.75 180 180 132.833
-181 180 132.167 182.065 180 135 197 179.429 135
-197 180 134.143 178 180.909 135 178 181 134.625
-180.375 181 135 182 181 133.364 196 181 133.071
-196.818 181 135 197 180.667 135 198 180.818 135
-177 181.5 135 178 181.333 135 181.125 182 135
-199 182 134.6 182 182.875 135 182 184 134.25
-166 184.045 135 184 184.1 135 174 186 134.318
-180 185.391 135 174 187 132.333 177 186.333 135
-190.4 187 135 90 188 134.609 89.625 188 135
-178 187.087 135 90 189 134.125 90.875 189 135
-174 189 134.1 193 188.591 135 91 189.143 135
-179 190 133.154 180 189.133 135 180 190 132.947
-181 190 134.684 88.4737 191 135 84 192 133.304
-93 191.391 135 80 192.5 135 92 68 135.3
-92.6429 68 138 82 69 136.773 83 69 135.273
-84 68.1923 138 66 70 136.5 66 69.4348 138
-69 70 137.419 72 70 137.824 75 70 136.645
-81 70 136 82 70 136.2 83 70 135.6
-84 70 135.75 86.875 70 138 87 69.9333 138
-89 69.875 138 89.1333 70 138 93 70 136.645
-94 69.1818 138 94 70 137.206 97 70 137.684
-65 71 137.739 66 71 136.962 67 71 137.333
-80 70.9444 138 83 71 137 90 71 137.684
-93 71 136.645 94 71 136.457 97 71 137.217
-97.8571 71 138 63 72 137.679 64 72 137.8
-64 71.3333 138 96 72 137.125 97 72 137.125
-97.875 72 138 62 73 137.778 97 72.875 138
-98 72.3333 138 97.3333 73 138 98 73 137.684
-98.5 73 138 99.25 73 138 101 73 136.889
-202 73 136.2 203 73 136.5 92 73.5 138
-101 74 137.419 202 74 136.636 203 73.5 138
-51 76 136.364 51 75.7778 138 52 76 136.364
-52.75 76 138 211 76 136.147 49 77 136.929
-50 77 135.316 51 77 135.261 52 77 137.053
-52.5 77 138 48 78 136.071 50 78 135.321
-51 78 136.556 47 79 137.455 48 79 135.261
-49 79 136 214 79 136.875 216 79 136.444
-47 80 135.5 48 80 136.5 213 80 135.333
-215 80 136.25 46 81 136.125 213 81 135.536
-214 80.2 138 214 81 136.286 45 82 135.714
-214 82 135.346 218.333 82 138 44 83 135.167
-45 83 135.2 46 83 136.5 207 83 136.071
-209 83 135.15 212 83 135.273 219 83 137.739
-218 83 138 45 84 135.529 207 84 136.5
-208 84 135.714 210 84 135.143 213 84 135.273
-218 84 137.52 217.5 84 138 219 83.3333 138
-207.2 85 138 214 85 135.333 215 85 135.45
-218 85 136.8 218.6 85 138 218 86 138
-40.5 87 138 215 94 135.391 215 95 137.25
-216 95 135.333 215 97 137.571 214 98 135.75
-213 98 138 41.375 99 138 204 99 136.889
-213 99 137.25 213.75 99 138 213 100 137.526
-202 101 135.968 212 101 137.667 211.25 101 138
-212 100.25 138 209.263 102 138 211 101.091 138
-211 102 136.696 210 103 135.938 209.421 103 138
-211.545 103 138 210 103.917 138 42 109 137.545
-42.6842 110 138 197 118 136.25 195 121 137.217
-195.316 121 138 45.5 122 138 192 122 135.783
-193 123 136.5 194.857 123 138 199 124 137.824
-188 125 136.2 189 125 136.2 191 125 135.667
-217 125 137.864 49 126 137.143 188 126 136.355
-190 126 137.032 192 126 136.8 186 127 135.222
-191 126.5 138 208 127 135.6 218 126.375 138
-207 128 136.826 208 128 137.143 99 128.5 138
-103 129 135.882 105 128.172 138 206 129 137.571
-208 129 135.818 97 130 137.471 99 130 136.457
-183 130 136.2 184 130 135.875 204 129.864 138
-205 129.533 138 206 129.333 138 98 131 136.889
-177 131 136.543 186 130.4 138 190 130.143 138
-190.4 131 138 204 131 135.6 203 131 138
-204.444 131 138 31 132 135.783 97 132 136.826
-173 132 135.667 182 132 136.543 184 132 136.25
-198 131.85 138 199 131.739 138 202 132 137.4
-202 131.842 138 203 132 136.25 203.583 132 138
-215 132 138 54 133 136.2 55 133 136.8
-56 132.5 138 89.6 133 138 93 133 136.8
-168 133 136.543 172 133 136.543 175 133 135.194
-177 133 136.2 184 133 136.889 184.909 133 138
-200 133 136.636 201 133 137.55 202 133 136.444
-203 133 137 56 134 137.143 92 134 137.032
-151 134 135.529 152 134 136.543 153 134 135.529
-174 134 135.176 176 134 135.455 180 133.273 138
-184 134 137.625 185 134 137.125 202 134 137.4
-51 135 135.2 54 135 135.6 57 135 136.556
-86 134.833 138 87 135 137.206 152 135 136.543
-160 135 136.355 175 135 135.441 185 135 137
-186 135 136.95 187 134.286 138 187 135 136.421
-201 134.182 138 213 134.727 138 48 136 135.391
-49 136 136.313 50 136 137.8 51 136 137.8
-53 136 135.4 55 136 136.2 57 136 136.125
-58 136 137.1 60 136 136.8 82 136 137.471
-89 136 135.968 152 136 135.968 158 136 136.2
-167 136 136.111 170 136 136.543 174 136 137.118
-176 136 135.577 192.818 136 138 210.6 136 138
-211 135.818 138 219 136 136.962 50 137 136.286
-52 136.533 138 53 136.65 138 55.3333 137 138
-56 137 135.429 153 137 135.857 159 137 136.111
-162 137 135.316 167 137 136.696 170 137 136.543
-177 137 137.55 195 137 137.053 209 137 137.625
-210 136.375 138 219 137 137.516 52 137.467 138
-55.5455 138 138 74 138 136.457 77 138 136.457
-79 138 137.217 80 138 137.217 158 138 137.4
-170 138 136.543 175 138 137.824 209 138 136.5
-210 138 135.794 220 138 137.318 221 138 137.143
-154 139 136.543 171 139 137.679 172 139 137.75
-196 139 136.5 208 139 136.75 209 139 135.875
-210 139 136 211 139 136.429 119 140 136
-155 140 137.471 184 139.625 138 184.2 140 138
-203 140 135.158 207 140 136.5 209 140 136.5
-182.684 141 138 202 140.056 138 208 140.75 138
-103.563 142 138 105.9 142 138 130.735 142 138
-156 142 137.4 185.7 142 138 201 142 136.457
-202 142 135.794 157 143 137.857 201 143 137.032
-202 143 136.645 203 143 137.217 205 142.69 138
-207 142.286 138 170 144 136.154 183 143.182 138
-185 143.261 138 188 144 135.29 155 145 137.182
-170.056 145 138 161.667 146 138 170 146 136.5
-162 146.25 138 169 147 137.471 168.143 147 138
-33.8235 148 138 175 148 137.053 50 149 135.333
-51 149 136.105 112 149 135.794 153 149 135.2
-51 150 137 53 149.522 138 54 150 135.6
-54.5 150 138 113 150 137.438 114 149.37 138
-163 150 137.609 163 149.625 138 179 149.5 138
-56.7273 151 138 58 150.125 138 58 151 137.222
-58.5833 151 138 112 150.933 138 163 151 137.71
-164 151 137.7 164.273 151 138 58 151.368 138
-173 151.333 138 176 151.5 138 64 153 135.333
-210 153 135.176 65 154 135.333 95 153.067 138
-182 154 135.783 210 154 138 121.176 155 138
-181 155 137.5 181 154.375 138 182 155 136.853
-67 155.222 138 98.5667 156 138 164.6 156 138
-182 156 136 211 156 135.692 166 157 135.667
-167 157 137.032 57 158 136.875 56.8 158 138
-58 158 135.375 59 158 135.375 63 158 137.739
-71 158 136.8 92.7368 158 138 165 157.875 138
-165.222 158 138 168 158 137.824 193 158 136.765
-207 157.467 138 208 158 137.25 208 157.947 138
-208.25 158 138 57 158.75 138 58 158.875 138
-59 158.467 138 62 159 135.667 72 159 135.375
-77 159 136.5 81 158.44 138 86 159 137.118
-90 159 136.6 168 159 137.471 170 159 137.735
-192 159 137.4 208 159 135.857 209 158.75 138
-209 159 137.25 73 160 136.2 74 160 136.457
-76 160 137.9 77 159.6 138 168 160 136.929
-171.37 160 138 194 160 136.543 73 161 136.2
-76 160.143 138 84 161 136.543 86 161 136.355
-91 161 136.5 106 161 136.714 105.25 161 138
-106.375 161 138 172.067 161 138 194 161 136.8
-193.263 161 138 195 161 137.25 195.467 161 138
-199 161 138 91 161.286 138 91 162 136.636
-91.625 162 138 106 162 136.875 105.25 162 138
-106.375 162 138 167.588 162 138 195 162 137.55
-200 161.75 138 76.9231 163 138 78 163 135.652
-89 163 136.826 91 162.333 138 176.935 163 138
-187.278 163 138 194 163 136.263 195 163 137.25
-77.75 164 138 194 164 137.143 195 164 135.75
-78 164.25 138 87 164.429 138 90.4348 165 138
-98.5 165 138 119.294 165 138 168 165 135.947
-91 166 136.889 167 165.565 138 168 166 135.222
-90 167 137.735 98 167 137.053 97.25 167 138
-99 166.417 138 99 167 136.688 165.567 167 138
-169 167 135.833 171.857 167 138 87 168 137.1
-86.6667 168 138 89 168 136.8 90 168 137.323
-91 167.857 138 93 167.261 138 99 168 136.565
-100 167.813 138 100 168 137.182 174 167.091 138
-196 167.25 138 63 169 136.875 62.625 169 138
-63 168 138 87 169 136.25 88 169 136.688
-89 169 136.543 90.15 169 138 98.8696 169 138
-100 169 135.273 201 169 137.71 63 169.429 138
-86 170 135.115 88 170 136.645 89 170 137.032
-196 170 136.313 196 169.25 138 197 170 135.45
-201 170 137.667 202 170 137.609 202.188 170 138
-89 171 137.684 100 170.133 138 174 170.636 138
-175 171 137.842 175 170.75 138 197 171 135.778
-201 170.188 138 202 170.75 138 83 172 136.421
-82.4444 172 138 176 172 136.688 177 172 136.138
-178 172 135.48 179 172 135.875 198 172 135.882
-84 173 136 173 172.867 138 174 172.455 138
-175 173 137 178 173 135.45 179 173 136.375
-198 173 135.581 205 173 137.727 206 173 137.75
-80.625 174 138 82.75 174 138 84 173.526 138
-85.0667 174 138 81 174.375 138 85.85 175 138
-175.368 175 138 205 175 137.684 205 174.5 138
-169 176 137.8 168.818 176 138 199 176 135.667
-202.286 176 138 203 175.474 138 204 176 137.323
-205 176 136.412 206 175.417 138 169 177 136.895
-168 177 138 175.75 177 138 176 176.571 138
-177 176.364 138 177.467 177 138 198 177 136.4
-199 177 136.4 202 177 137.55 201.813 177 138
-205 177 136.2 206 177 136 169 177.875 138
-177.333 178 138 179 178 137.143 179.4 178 138
-198 178 136.556 199 178 136.444 201.667 178 138
-203 178 135.375 204 178 135.9 208.526 178 138
-177 179 136.125 177 178.375 138 178 179 137.333
-179 179 137.5 179.167 179 138 197 179 135.45
-201 179 137.333 178 180 137.5 179 180 135.75
-181 180 137.318 182 180 135.333 201.684 180 138
-208.077 180 138 172 180.8 138 181 181 137
-181.714 181 138 198 181 137 201.087 181 138
-209 180.923 138 172 182 136.263 178 182 135.375
-183 182 136.364 197 181.333 138 198 181.045 138
-200 181.727 138 172 183 135.273 173 182.071 138
-173 183 135.4 182 183 135.75 183 183 135.923
-191 183 137.4 190.667 183 138 191 182.8 138
-191.273 183 138 184 183.591 138 187 184 136.645
-188 183.818 138 188.5 184 138 191 183.6 138
-167 184.071 138 189 184.667 138 189 185 137.864
-72 185.75 138 85 186 137.125 85 185.364 138
-89 186 135.577 88.3 186 138 196 186 135.462
-195.313 186 138 72 187 136.25 73 187 136.696
-84 187 136.969 85 187 137.032 90 187 135.857
-90.3226 187 138 174 186.091 138 177.944 187 138
-190.455 187 138 195 187 136.5 196 187 135.577
-198 187 135.231 73 188 137 89 188 135.652
-90.3333 188 138 191 187.75 138 73 188.158 138
-88.8 190 138 90.1053 190 138 180 189.125 138
-182.091 190 138 74 190.842 138 179 190.913 138
-180 190.875 138 181 190.929 138 182 190.286 138
-86 192.045 138 86 69 140.571 87 69 139.5
-89 69 140.625 89.1333 69 141 86.5333 70 141
-89 70 138.857 97 69.2 141 63 71 140
-64 71 138.136 71 71 138.529 72 71 138.882
-79 71 138.12 80 71 138.143 86 71 138.24
-87 70.3684 141 87 71 139 88 71 139.429
-89 71 139.08 98 70.5 141 98 71 138.5
-99 71 138.3 99.6429 71 141 62 72 138.214
-65 72 138.909 73 72 139.355 81 72 138.24
-87 72 139.345 98 72 139 100 72 138.857
-60 73 139.8 61 73 138.833 63 73 138.2
-74 73 139.8 76 73 139.889 80 73 140.217
-81 73 139.556 86 73 139.3 87 73 139.556
-89 73 138.931 97 73 138.167 99 73 139
-102 73 138.96 58 74 139.5 59 74 138.6
-60 74 138.6 61 74 139 62 74 139.4
-63 74 140.1 77 74 139.645 78 74 139.889
-80 74 139.889 89 74 140.1 95 73.5417 141
-98 74 139.5 56 75 138.75 58 75 138.25
-59 75 138.667 60 75 139.75 64 74.6 141
-77 75 140.471 79 74.8333 141 83 75 139.889
-87 75 140.806 90 75 139.457 97 75 140.769
-98 75 140.318 99 75 140.684 203 75 140.6
-204 74.1111 141 52 76 139.125 54 76 138.545
-53.25 76 141 55 76 138.316 57 76 138.818
-59 76 139.962 84 76 139.8 85 76 139.8
-86 76 140.206 100 76 139.7 101 76 139.7
-53 76.375 141 53 77 139.636 87 77 140.471
-99 77 140.679 102 77 140.824 54 77.75 141
-96 78 139.8 99 78 140.032 100 78 140.206
-47.3846 79 141 213.737 80 141 217 80 138.103
-53 80.25 141 216 80.9091 141 207 82.9444 141
-48 84 140.471 219 84 139.2 218 84.75 141
-219 84.4 141 215 96 138.29 214 97 139.5
-212.5 98 141 213 97.6842 141 214 98 139.8
-211.778 99 141 212 98.5 141 213.737 100 141
-211.167 101 141 210 104 139 211 104 139.696
-42 105 138.667 210 104.5 141 211 105 140.8
-210.5 105 141 229 105.25 141 42 107 138.783
-210 107 139.091 210 108 140.526 209.25 108 141
-43 109 138.968 43 111 138.529 45 112 140.471
-201 114 140.76 201 115 139.44 202.8 115 141
-204 115 140.76 203.5 115 141 204.286 115 141
-199 116 138.469 202 116 139.143 203 115.5 141
-203 116 140.647 203.5 116 141 201 117 140.118
-202 117 139.846 203 116.167 141 200 118 140.76
-200.167 118 141 201 117.333 141 48 119 139.8
-198 119 138.818 199 119.818 141 200 119.333 141
-197 122 140.143 198 122 140.8 200 121.25 141
-50 123 139.457 198 123 139.645 199 123 138.261
-200 123 138 197 124 139.543 200 124 138.8
-50 125 139.579 53 125 139.8 99 124.833 141
-103 125 140.824 196 125 138.667 198 125 139.625
-199 125 139.35 200 124.55 141 218 125 139
-100 126 140.143 193 126 138.1 196 126 139.6
-199 125.407 141 218 126 138.818 46 127 140.609
-45 127 141 100 127 139.853 102 127 140.545
-216 127 138.333 217 127 138.231 53 128 139.313
-192 128 139.5 216 128 138.321 54 129 139.645
-57 129 139.457 58 129 139.8 96 129 139.2
-189 129 138.6 131 130 138.103 188 130 138.517
-191 130 139.421 204 130 138.45 205 130 138.75
-206 130 138.2 221 130 139.8 222 129.474 141
-222 130 139.333 55 131 138.529 56 131 139.2
-130 131 140.182 132 131 138.6 188 131 139.636
-204 131 138.571 215 131 138.321 221 131 139.091
-220.125 131 141 222 131 139.2 60 132 139.457
-87 132 139.457 186 132 140.8 187 131.565 141
-188 131.909 141 188.071 132 141 190.5 132 141
-197.3 132 141 203 132 139.75 63 133 139.8
-88 133 138.882 185.923 133 141 201 132.75 141
-202 132.167 141 71 135 139.457 182 134.591 141
-112.87 136 141 115 135.955 141 178 136 140.531
-178.625 136 141 184 136 139.607 215 135.75 141
-52 137 139.75 55 136.462 141 173 137 138.455
-182.556 137 141 184 137 139.125 185 137 138.9
-190.286 137 141 194.667 137 141 199 136.25 141
-216 136.667 141 217 137 138.783 216.056 137 141
-129.308 138 141 183 138 139.781 184 138 139.031
-185 138 139.781 186 138 140.7 193.091 138 141
-207 137.727 141 173 139 139.091 174 139 138.094
-175 139 138.5 179 139 138.115 184 139 138.714
-184.889 139 141 192 138.091 141 193 139 139.889
-194 139 138.667 213 138.867 141 212.75 139 141
-105 139.87 141 109 140 139.765 110 140 140.25
-176 139.828 141 179 140 138.652 180 140 139.636
-191 140 140.118 192 140 139.455 194 140 138.857
-196 140 138.103 197 140 139.44 210 140 141
-103.63 141 141 106 141 139.846 108 141 140.735
-107.25 141 141 109 141 139.6 110.875 141 141
-169 140.818 141 171 141 139.645 173 140.261 141
-180 141 139.778 181 141 140 184.273 141 141
-193 141 139.455 194 141 139.147 195 141 139.412
-196 141 138.9 197 141 139.444 198 141 139.696
-199 141 140.438 106.4 142 141 170 142 140.8
-182 142 139.038 192 141.5 141 198 142 140.4
-199 142 139.385 157 144 138.316 181.87 144 141
-183 144 139 184 144 140.053 184.316 144 141
-201 144 138.9 207.857 144 141 170 145 139.5
-201 145 138.947 202 145 140.571 127.548 146 141
-161 146 138.5 168 145.222 141 201 146 139.875
-161 147 138.75 162 147 138.529 168 147 138.158
-167.053 147 141 211 147 140.667 210.818 147 141
-211 146.714 141 114 148 140.444 125 147.481 141
-212 148 140.76 211.833 148 141 212 147.5 141
-213 147.625 141 213 148 140.182 177.667 149 141
-213 149 139.846 214 149 139.385 220 149 139.364
-219 149 141 220 148.143 141 53 150 139.138
-64 150 140.71 164.933 150 141 214 149.875 141
-57.25 151 141 58 150 141 59 151 141
-62 151 140.118 63 151 140.118 64 151 140.471
-162.333 151 141 173 150.955 141 178 151 140.9
-179 153 138.375 180 153 138.75 180 154 138.75
-181 154 138.29 92 155 140.419 167 155 140.625
-169 155 139.8 170 155 139.8 207 155 140.211
-208 155 139.962 210 155 138.529 67 156 140.864
-68 155.565 141 69 155.222 141 71.5556 156 141
-99.0303 156 141 164.867 156 141 167 156 138.316
-168 156 139.147 169 156 139.2 170.773 156 141
-208 156 140.806 209 156 139.235 65 157 139.5
-90 157 138.783 92 157 139.355 168 157 138.794
-170 157 139.543 187 157 140.8 187 156.818 141
-188 157 139.645 191 156.192 141 191 157 138.9
-195 156.684 141 197 156.848 141 57 158 138.474
-58 158 139.105 59 158 139.05 66 158 140.9
-91 158 139.2 92 158 139.355 176 157.391 141
-187 158 140.625 188 158 139.111 191 158 138.194
-209 158 138.375 84 158.263 141 92 159 138.529
-189 159 139.125 190 159 139.25 200 159 138.857
-92 160 138.577 102 160 140.667 102.6 160 141
-166.63 160 141 188 159.13 141 199 160 140.1
-199 159.7 141 219 160 140.4 220 160 139.875
-76 161 138.529 77 161 139.8 78.5 161 141
-93 161 138.167 103 161 139.895 104 160.813 141
-104 161 138.75 106 161 138.391 181 160.333 141
-200 161 138.333 219 160.75 141 82.75 162 141
-89 162 139.2 90 162 138.231 90 161.077 141
-104 161.75 141 106 162 138.391 172 162 140.318
-193 161.909 141 193.083 162 141 195 162 139.125
-77.8125 163 141 85.8125 163 141 90 163 138.2
-91 163 139.304 185.375 163 141 194 163 140.063
-77.4167 164 141 79 163.909 141 91 163.813 141
-185.4 164 141 194 164 138.273 195 164 138.529
-77 165 138.938 78 165 140.077 178 164.778 141
-195 165 138.529 76 166 139.895 77 166 139.174
-172 166 140.739 184 165.52 141 195 166 138.529
-64 167 140.294 63 167 141 64 166 141
-76 167 139.565 75.45 167 141 77 167 140.55
-97 166.8 141 171 166.231 141 172 167 138.316
-173 167 138.677 200.125 167 141 76 168 140.125
-99 168 140.75 99 167.875 141 173 168 138.321
-174 168 138.968 196 168 138.29 63 169 138.818
-75 169 140.25 74.6316 169 141 100 169 139.304
-174 169 139.313 195 169 139.571 202 169 138.455
-203 169 139.853 205 169 140.667 75 170 140.667
-75.2 170 141 85.32 170 141 174 170 138.75
-175 170 138.29 203 170 140.167 201 170.783 141
-202 171 138.273 202.833 171 141 83 172 140.727
-83.125 172 141 82 173 138.778 83 173 140.318
-84 173 139.579 87 172.545 141 173 173 141
-174 173 139.286 81 174 138.29 82 174 138.265
-87 174 139.8 169 175 140.526 204.714 175 141
-205 174.895 141 168.545 176 141 170 176 139.421
-174 175.467 141 176 177 138.375 177 177 138.75
-202 177 139.125 202.172 177 141 170 177.4 141
-180 178 138.391 208.091 178 141 180 179 139
-51.5667 180 141 180 180 138.231 203.261 180 141
-172.286 181 141 182 181 138.545 183 182 139.636
-185 182 139.929 186 182 140.667 198 181.182 141
-171 183 140.5 175 182.517 141 182 183 138.75
-185 183 140.217 186 183 139.6 191 183 138.6
-167.143 184 141 182 184 139.5 183 183.429 141
-189 184 138.75 189.429 184 141 71 185 139.35
-71 184.267 141 90.5667 185 141 180 184.333 141
-86 185.684 141 86 186 139.714 87 185.933 141
-87 186 140.833 88 186 139.227 74 187 138.667
-75 186.455 141 83 187 138.136 86 187 139.333
-87 187 139.696 106 186.433 141 169 187 140.167
-169 186.688 141 178.625 187 141 192 187 139.125
-74 188 138.857 78 187.895 141 81 188 139.543
-83 188 138.091 84 188 138.103 86 188 140.727
-87 188 139.889 169 188 139.655 168.409 188 141
-170 187.182 141 170.75 188 141 193 187.033 141
-74 189 140.647 75 189 139.5 84 189 139.846
-172.467 189 141 73.9091 190 141 76 190 139.364
-82 190 139.543 83 190 139.543 84 190 140.419
-89 189.75 141 89 190 139.8 180 190 140.1
-180.75 190 141 182 189.889 141 80 191 139.2
-83 191 139.543 84 191 140.032 85 191 140.727
-89 191 139.235 179 190.091 141 182 190.182 141
-84 192 138.794 88 192 139 90 192 139.2
-89 193.13 141 68 68.8529 144 67.5455 69 144
-69 68.6571 144 70 68.4857 144 71 68.4857 144
-72 68.4857 144 73 68.4857 144 74 68.3529 144
-75 68.3429 144 76 68.3529 144 77 68.5862 144
-78 68.7391 144 79 68.9444 144 79.1667 69 144
-83 69 144 91 69 144 92 69 144
-93 69 144 94 69 144 65 69.8235 144
-64.5 70 144 66 69.3529 144 67 69.2143 144
-80 69.1515 144 81 69.1818 144 82 69.1818 144
-84 69.2609 144 85 69.9444 144 85.0833 70 144
-89.2273 70 144 90 69.2609 144 95 69.2727 144
-96 70 144 63 70.8235 144 62.7391 71 144
-64 70.2069 144 86 70.4783 144 87 70.7857 144
-88 70.7391 144 89 70.2941 144 97 70.6 144
-98 71 141.882 97.25 71 144 99 71 143.7
-62 71.7727 144 61.7727 72 144 98 72 141.316
-97 72 144 99 72 141.882 100 71.9167 144
-99.9231 72 144 101 71.7391 144 101.353 72 144
-60 72.8235 144 59.5 73 144 61 72.5 144
-97.3158 73 144 99 73 141.545 99.6207 73 144
-102 72.3793 144 102.529 73 144 57.5 74 144
-58 73.8235 144 59 73.1765 144 73 74 141.783
-87 74 141.316 94.6471 74 144 95 73.6667 144
-95.5 74 144 98 73.7222 144 99 74 142.364
-98.4545 74 144 99.2609 74 144 103 73.7273 144
-103.182 74 144 56 75 144 57 74.2609 144
-67.3333 75 144 68 74.75 144 69 74.5455 144
-70 74.3182 144 71 74.2857 144 72 74.2857 144
-73 74.7727 144 73.4167 75 144 94.0833 75 144
-95.6471 75 144 99 74.4615 144 103.364 75 144
-204 74.3929 144 203.393 75 144 205 74.1765 144
-206 74.7857 144 206.261 75 144 54 76 144
-55 75.4074 144 63.0909 76 144 64 75.6429 144
-65 75.4444 144 66 75.3182 144 67 75.1176 144
-74 75.25 144 75 75.697 144 76 75.8485 144
-76.4545 76 144 80 76 141.818 94 76 141.25
-95 75.4074 144 103.364 76 144 203.324 76 144
-207 75.5 144 207.739 76 144 50.7059 77 144
-51 76.8529 144 52 77 144 53.0833 77 144
-61 77 143.833 61.2 77 144 62 76.75 144
-63 76.0588 144 77 76.1765 144 78 76.2222 144
-79 76.5238 144 79.9091 77 144 103.036 77 144
-203.647 77 144 208 76.2069 144 209 76.8148 144
-209.227 77 144 49 78 144 50 77.4286 144
-53 77.0909 144 60.0909 78 144 61 77.0909 144
-80 77.0455 144 81 77.375 144 82 77.75 144
-82.3636 78 144 84 78 142.364 102.429 78 144
-103 77.0588 144 204 77.5217 144 204.324 78 144
-210 77.6071 144 210.688 78 144 48 78.8214 144
-47.8148 79 144 58.0909 79 144 59 78.5455 144
-60 78.0455 144 83 78.3182 144 84 78.4444 144
-85 78.4444 144 86 78.5455 144 86.9091 79 144
-89 79 141.75 101.389 79 144 102 78.5217 144
-204.647 79 144 211 78.1515 144 212 78.5 144
-212.739 79 144 47.4783 80 144 55 80 144
-56 79.7059 144 57 79.75 144 58 79.0588 144
-87 79.0455 144 88 79.4444 144 89 79.5455 144
-90 79.6429 144 91 79.8182 144 91.6667 80 144
-100.059 80 144 101 79.3043 144 205 79.7059 144
-205.147 80 144 213 79.1765 144 214 79.697 144
-214.455 80 144 46 81 144 47 80.5 144
-53 81 141.75 54.5833 81 144 92 80.1176 144
-93 80.1176 144 94 80.4118 144 95 80.75 144
-96 80.75 144 97 80.6 144 98 80.375 144
-99 80.4118 144 100 80.0455 144 205.5 81 144
-215 80.3529 144 216 80.697 144 216.455 81 144
-45 81.6071 144 44.6667 82 144 52 82 143.833
-52.0909 82 144 53 81.6429 144 54 81.3182 144
-205.971 82 144 217 81.5217 144 217.478 82 144
-44 83 144 51.0588 83 144 52 82.0588 144
-206 82.0435 144 206.647 83 144 218 82.9231 144
-218.056 83 144 43.3529 84 144 49.7059 84 144
-50 83.7826 144 51 83.0455 144 207 83.6667 144
-207.176 84 144 218 84 142 219 83.7391 144
-219.273 84 144 43 84.6667 144 42.7857 85 144
-48.6207 85 144 49 84.5217 144 207.647 85 144
-220 84.5926 144 220.478 85 144 42 86 144
-48.0357 86 144 207.824 86 144 221 85.6667 144
-221.176 86 144 41.2143 87 144 47.5294 87 144
-48 86.0588 144 207.971 87 144 221.824 87 144
-41 87.2727 144 40.5152 88 144 47.0357 88 144
-208 87.1667 144 208.179 88 144 222 87.5 144
-222.176 88 144 40 89 144 46.697 89 144
-47 88.0909 144 208.353 89 144 222.667 89 144
-39.5152 90 144 46.3636 90 144 208 90 144
-218 90 143.824 217.909 90 144 218 89.9412 144
-218.036 90 144 223 89.6471 144 223.261 90 144
-39 91 144 46.0357 91 144 207.586 91 144
-218 91 143.833 217.909 91 144 218.045 91 144
-223.793 91 144 38.5152 92 144 45.697 92 144
-46 91.0909 144 207.486 92 144 218 91.0625 144
-224 91.5 144 224.176 92 144 38.1765 93 144
-45.5455 93 144 207.343 93 144 224.485 93 144
-38 93.5 144 37.8235 94 144 45.3636 94 144
-207.176 94 144 224.824 94 144 37.5152 95 144
-45.0357 95 144 207 95 144 225 94.5 144
-225.176 95 144 37.1765 96 144 44.8529 96 144
-45 95.1667 144 206.824 96 144 225.485 96 144
-37 96.5 144 36.8235 97 144 44.6765 97 144
-206.515 97 144 225.824 97 144 36.6571 98 144
-44.6765 98 144 206.176 98 144 226 97.5 144
-226.176 98 144 36.3429 99 144 44.5143 99 144
-206 99 144 211.793 99 144 212 98.4545 144
-213 98.4 144 213.462 99 144 226.485 99 144
-36.1765 100 144 44.5 100 144 205.824 100 144
-211.75 100 144 213.333 100 144 226.824 100 144
-36 100.5 144 35.8235 101 144 44.3529 101 144
-205.821 101 144 211.522 101 144 213 101 144
-227 100.353 144 227.324 101 144 35.5152 102 144
-44.3636 102 144 205.393 102 144 210.667 102 144
-211 101.522 144 213.179 102 144 227.647 102 144
-35.1765 103 144 43 103 141.682 44 103 142.364
-44.3636 103 144 205.214 103 144 210.353 103 144
-213.185 103 144 228 103 144 35 103.5 144
-34.8235 104 144 44.5455 104 144 205 103.353 144
-204.676 104 144 210 104 141.462 210.379 104 144
-212.706 104 144 213 103.5 144 228 104 144
-34.5152 105 144 44.697 105 144 204.353 105 144
-210.478 105 144 212.538 105 144 228.324 105 144
-34.1765 106 144 44.8529 106 144 204 106 144
-209.944 106 144 210 105.917 144 213 105.5 144
-213.261 106 144 221 106 143.7 220 106 144
-221 105 144 221.091 106 144 228.647 106 144
-34 106.545 144 33.8529 107 144 45 106.833 144
-45.0294 107 144 203.676 107 144 209 107 144
-212 107 141.545 213 107 142.2 213.522 107 144
-219 107 143 218.739 107 144 219 106.647 144
-220 107 143 220.333 107 144 221 106.077 144
-229 107 144 33.5152 108 144 45.0294 108 144
-203.353 108 144 208.708 108 144 212 108 144
-213 107.667 144 219 108 142.2 218.333 108 144
-220 108 143.118 220.179 108 144 229.324 108 144
-33.1818 109 144 45.1818 109 144 203 108.706 144
-202.853 109 144 209 109 142.8 208.5 109 144
-210 108.923 144 209.857 109 144 211 108.179 144
-218 109 142.95 217.759 109 144 218 108.462 144
-219 109 142.2 219.667 109 144 220 108.455 144
-229.647 109 144 33 110 144 45.5294 110 144
-202.697 110 144 209 110 143.824 208 110 144
-209.053 110 144 218 110 143.824 217.941 110 144
-218.167 110 144 219 109.706 144 230 110 144
-32.8235 111 144 45.8529 111 144 202.429 111 144
-209 110.2 144 218 110.2 144 230 111 144
-32.6571 112 144 46 111.455 144 46.1818 112 144
-202.045 112 144 230.176 112 144 32.4857 113 144
-46.5294 113 144 202 112.059 144 201.429 113 144
-230.485 113 144 32.4857 114 144 47 113.941 144
-47.0357 114 144 201.045 114 144 208 114 143.842
-207.8 114 144 208 113.8 144 209 113.8 144
-209 114 143.842 210 113.417 144 210 114 142.95
-211 113.588 144 211 114 142.95 211.583 114 144
-230.824 114 144 32.4857 115 144 47.5294 115 144
-202 115 144 203.417 115 144 204 114.696 144
-205 114.588 144 205 115 142.25 206 114.417 144
-207 114.8 144 207 115 143.727 207.2 115 144
-208 114.2 144 209 114.091 144 210 114.412 144
-211 114.304 144 231 115 144 32.4857 116 144
-48 115.941 144 48.0357 116 144 201 115.6 144
-200.636 116 144 201.8 116 144 203 116 142
-202.2 116 144 203.8 116 144 204.2 116 144
-205 115.636 144 205.8 116 144 206.2 116 144
-207 115.2 144 231 116 144 32.4857 117 144
-48.5294 117 144 200.083 117 144 202 116.077 144
-204 116.043 144 206 116.063 144 231 117 144
-32.4857 118 144 49 117.727 144 49.2143 118 144
-200 117.2 144 199.818 118 144 231 118 144
-32.4857 119 144 49.8214 119 144 199.583 119 144
-231 119 144 32.4857 120 144 50 119.217 144
-50.6207 120 144 99 119.833 144 98.6667 120 144
-100 119.833 144 101 120 143.684 101 119.882 144
-101.167 120 144 199 119.636 144 198.818 120 144
-230.824 120 144 32.4857 121 144 51 120.478 144
-51.5217 121 144 97 121 143.684 97 120.833 144
-96.8333 121 144 98 121 143.684 98 120.667 144
-101.167 121 144 198 121 141.3 199 120.8 144
-199.083 121 144 230.657 121 144 32.4857 122 144
-44 122 141.938 43 122 144 44 121.353 144
-45 121.773 144 45.1786 122 144 52 121.478 144
-52.5217 122 144 97 122 143.684 96.6667 122 144
-100 122 143.684 101 122 143.684 101.333 122 144
-199.647 122 144 230.514 122 144 32.4857 123 144
-43.9565 123 144 45 123 142.263 45.5 123 144
-53 122.478 144 53.5217 123 144 96 122.667 144
-95.6667 123 144 98 123 143.684 100 123 143.684
-101 123 143 102 122.8 144 102.083 123 144
-200 122.5 144 200.353 123 144 230.343 123 144
-32.4857 124 144 44 123.056 144 45 124 143.824
-44.9444 124 144 45.2 124 144 54 123.478 144
-54.7059 124 144 95 124 143.684 95 123.667 144
-94.6667 124 144 96 124 143.684 97 124 143.684
-101 124 141.346 102 124 141.24 103 123.393 144
-103 124 141.783 104 123.966 144 104.059 124 144
-200.273 124 144 230.176 124 144 32.4857 125 144
-45 125 144 46 124.4 144 46.5455 125 144
-55 124.217 144 56 124.955 144 56.0588 125 144
-95 125 143.684 94.6667 125 144 96 125 143.684
-97 125 143 102 125 141.24 104 125 141.75
-105 124.727 144 105.222 125 144 200 124.353 144
-199.607 125 144 230 125 144 32.3429 126 144
-44.5 126 144 46 126 142.286 47 125.417 144
-47.6364 126 144 57 125.941 144 57.0588 126 144
-92 125.833 144 91.6667 126 144 93 125.667 144
-94 125.364 144 102 126 141.75 103 126 141.346
-105 126 141.75 105.643 126 144 197.455 126 144
-198 125.824 144 199 125.5 144 230 126 144
-32.3235 127 144 44.0556 127 144 48 126.8 144
-48.2 127 144 58 126.696 144 58.3889 127 144
-89 127 143.684 89 126.882 144 88.6667 127 144
-90 126.833 144 91 126.667 144 105.821 127 144
-195 126.824 144 194.647 127 144 196 126.485 144
-197 126.152 144 230 127 144 32.3429 128 144
-45 127.773 144 45.8333 128 144 46.1667 128 144
-47 127.706 144 48 127.059 144 59 127.478 144
-59.7059 128 144 88 128 143.684 88 127.667 144
-87.6667 128 144 89 128 143.684 90 128 143
-106 128 144 193.571 128 144 194 127.478 144
-230 128 144 32.4857 129 144 46 128.034 144
-60 129 141.75 60 128.217 144 61 128.955 144
-61.0909 129 144 85 129 143.684 85 128.882 144
-84.6667 129 144 86 128.833 144 87 128.667 144
-89 129 142.364 106.147 129 144 192 129 141.13
-193.227 129 144 230.147 129 144 32.4857 130 144
-62 129.588 144 62.6364 130 144 84 129.667 144
-83.6667 130 144 85 130 143 106.571 130 144
-192 130 142.286 193 130 143.053 193.545 130 144
-220.706 130 144 221 129.815 144 222 129.625 144
-222.353 130 144 230.303 130 144 32.4857 131 144
-63 130.25 144 64 130.588 144 65 130.882 144
-65.3333 131 144 81 130.882 144 80.6667 131 144
-82 130.833 144 83 130.364 144 106.727 131 144
-192 131 143.833 193 131 143.833 194 130.833 144
-194 131 143.824 195 130.917 144 195 131 143.833
-195.091 131 144 197.417 131 144 198 130.759 144
-199 130.708 144 199.412 131 144 220 131 141.25
-219 131 144 220 130.522 144 222 130.545 144
-221.545 131 144 230.303 131 144 32.4857 132 144
-66 131.25 144 67 131.588 144 67.6364 132 144
-75 131.882 144 74.6667 132 144 76 131.882 144
-77 131.882 144 78 131.682 144 79 131.588 144
-80 131.25 144 107 131.375 144 107.357 132 144
-129.167 132 144 130 131.821 144 131 132 142
-130.294 132 144 187 132 144 188 131.739 144
-188.545 132 144 193 132 143.842 194.2 132 144
-195 131.2 144 196.667 132 144 197 131.5 144
-200 131.476 144 200.393 132 144 218 132 142.263
-217.607 132 144 218 131.607 144 219 132 141
-220 132 141.176 221 131.5 144 220.727 132 144
-230.303 132 144 32.6571 133 144 68 132.182 144
-69 132.357 144 70 132.455 144 71 132.455 144
-72 133 141.75 72 132.455 144 73 132.357 144
-74 132.182 144 107.739 133 144 127 133 144
-128 132.5 144 129 132.034 144 130.778 133 144
-186 132.706 144 185.815 133 144 188.739 133 144
-192.2 133 144 193 132.2 144 194 132.091 144
-197 132.455 144 197.214 133 144 201 133 142
-200.739 133 144 202 133 142.364 203 133 141.24
-217 133 142.2 216.586 133 144 217 132.586 144
-218 133 141.571 219 133 143.118 219.294 133 144
-220 132.571 144 230.485 133 144 32.8235 134 144
-108 133.261 144 108.586 134 144 126 133.667 144
-125.353 134 144 130.824 134 144 185.593 134 144
-188 134 142 188.414 134 144 192.059 134 144
-197.176 134 144 201 133.375 144 201.588 134 144
-202 134 142.5 216 134 143.786 215.964 134 144
-216 133.944 144 217 134 141.652 218 134 143
-218.261 134 144 219 133.227 144 230.818 134 144
-33 135 144 108.957 135 144 123 135 144
-124 134.657 144 125 134.176 144 130.657 135 144
-180 135 142 181 135 142.364 186 134.733 144
-186.8 135 144 187.083 135 144 188 134.522 144
-192 135 144 196.667 135 144 197 134.353 144
-201.455 135 144 216 135 141.667 215.588 135 144
-217 135 142.25 217.304 135 144 218 134.273 144
-230.824 135 144 33 136 144 109 135.083 144
-110 135.353 144 111 135.227 144 112 135.478 144
-112.364 136 144 115.294 136 144 116 135.571 144
-117 135.667 144 118 135.971 144 119 135.824 144
-120 135.966 144 121 135.793 144 122 135.586 144
-129.875 136 144 130 135.852 144 180 136 143.727
-181 136 143.8 182 136 143.842 187 135.034 144
-191.455 136 144 195.815 136 144 196 135.815 144
-200.773 136 144 201 135.667 144 216 135.412 144
-217 135.25 144 230.657 136 144 33 137 144
-53 137 141.429 54.0833 137 144 55 136.621 144
-56 136.514 144 57 136.233 144 58 136.393 144
-59 136.739 144 59.375 137 144 113 136.656 144
-114 136.815 144 115 136.227 144 129.185 137 144
-181 137 143.8 182 137 142.765 190 136.733 144
-189.75 137 144 191 136.5 144 194.545 137 144
-195 136.815 144 200 137 143.167 200.227 137 144
-212 137 143.1 213 137 143.211 213.833 137 144
-214 136.917 144 214.091 137 144 215 137 142.421
-216 137 141.176 230.514 137 144 33 138 144
-54.0588 138 144 59 138 141.652 60 137.909 144
-60.0909 138 144 128.821 138 144 129 137.5 144
-180.636 138 144 181 137.2 144 181.364 138 144
-189 138 143.571 190 138 143.571 190 137.8 144
-191 138 141.75 191 137.455 144 192 137.353 144
-193 137.273 144 194 137.214 144 199 137.545 144
-198.545 138 144 200 137.185 144 205.5 138 144
-206 137.824 144 207 137.233 144 208 137.261 144
-209 137.412 144 209.833 138 144 210 138 143.684
-211 138 143.684 211.286 138 144 212 137.545 144
-212.5 138 144 213 138 143.167 214 137.083 144
-214 138 141.938 230.343 138 144 33 139 144
-55 138.727 144 55.5455 139 144 58.5455 139 144
-59 138.783 144 60 138.059 144 129 138.5 144
-129.179 139 144 180.688 139 144 181.833 139 144
-185 138.783 144 184.545 139 144 186 138.621 144
-187 138.5 144 188 138.214 144 189 138.091 144
-190 139 142.286 189.455 139 144 198.059 139 144
-203.739 139 144 204 138.824 144 205 138.176 144
-209.588 139 144 211 139 142.364 212 138.217 144
-212 139 141.75 230.176 139 144 33.3529 140 144
-56 139.152 144 57 139.176 144 58 139.176 144
-73 140 143.813 72.8571 140 144 73 139.941 144
-73.0833 140 144 104 140 144 105 139.227 144
-106 139.571 144 107 139.786 144 108 139.5 144
-109 139.214 144 110 139.353 144 110.478 140 144
-129.647 140 144 161 140 141.24 168 140 142.385
-177 140 144 181 139.313 144 181 140 141.938
-184 139.353 144 183.353 140 144 189.552 140 144
-198.706 140 144 202.393 140 144 203 139.5 144
-209.25 140 144 230 140 144 33.6765 141 144
-73 140.167 144 103.676 141 144 107 141 141.12
-110.739 141 144 129.818 141 144 165 141 143
-173 140.515 144 172.407 141 144 174 140.353 144
-175 140.353 144 176 140.176 144 178 140.313 144
-178.667 141 144 183.217 141 144 190 140.722 144
-190.833 141 144 199 140.294 144 200 141 144
-201 141 144 202 140.333 144 209 140.667 144
-208.882 141 144 230 141 144 34 142 144
-104 141.688 144 104.227 142 144 107 142 142.8
-108 142 144 109.545 142 144 110 141.773 144
-130 142 144 160.818 142 144 161 141.75 144
-162 141.059 144 163 141.304 144 164 141.412 144
-165 141.412 144 166 141.2 144 167 141.091 144
-168 141.091 144 168.909 142 144 171.75 142 144
-172 141.647 144 179 141.5 144 179.393 142 144
-183.964 142 144 191 141.036 144 192 141.773 144
-192.417 142 144 208.455 142 144 230 142 144
-34 143 144 105 142.607 144 106 142.353 144
-107 142.182 144 109 142.176 144 129.571 143 144
-160.304 143 144 169 142.091 144 169.625 143 144
-171.059 143 144 180 142.607 144 180.333 143 144
-184 142.077 144 184.522 143 144 193 142.412 144
-193.625 143 144 195 143 141.3 198 143 144
-208.179 143 144 230 143 144 34 144 144
-128.941 144 144 129 143.941 144 159.818 144 144
-160 143.636 144 170 143.353 144 171 143.091 144
-181 143.815 144 181.179 144 144 184.607 144 144
-194 143.222 144 195 143.643 144 196 143.515 144
-197 143.152 144 199 143.75 144 199.182 144 144
-204 143.848 144 203.545 144 144 205 143.852 144
-205.364 144 144 208 143.455 144 207.5 144 144
-229.824 144 144 34 145 144 127.727 145 144
-128 144.727 144 159 145 143 159.636 145 144
-166 145 144 167 144.727 144 168 144.571 144
-169 144.778 144 170 144.688 144 171 144.625 144
-172 144.588 144 172.304 145 144 182 145 144
-183.75 145 144 184 144.81 144 199.696 145 144
-202 145 144 203 144.261 144 206 144.292 144
-207 144.261 144 229.485 145 144 34 146 144
-64 146 143.824 63.5 146 144 64 145.833 144
-64.1429 146 144 127.5 146 144 160 145.8 144
-160 146 143.727 160.059 146 144 167 146 144
-173 146 144 183 145.5 144 200 145.636 144
-200.8 146 144 201.056 146 144 229.176 146 144
-34.3529 147 144 64 146.2 144 126.375 147 144
-127 146.63 144 158.091 147 144 159 146.091 144
-160 146.091 144 167.222 147 144 173.571 147 144
-201 146.059 144 211 147 141.857 229 147 144
-34.6765 148 144 63.8571 148 144 64 147.8 144
-64.1667 148 144 110 148 144 111 147.824 144
-112 147.848 144 112.455 148 144 124 148 144
-125 147.207 144 126 147.176 144 157.304 148 144
-158 147.059 144 168 147.778 144 168.214 148 144
-174 147.706 144 174.217 148 144 212 147.833 144
-211.909 148 144 213 147.333 144 214 147.657 144
-215 148 144 229 148 144 35 149 144
-64 149 141.682 63 149 144 65 148.455 144
-65.2609 149 144 108.227 149 144 109 148.5 144
-113 148.353 144 113.393 149 144 123.676 149 144
-156.5 149 144 157 148.389 144 169 149 144
-175 149 143 174.588 149 144 211.955 149 144
-216 149 144 220 149 144 228.824 149 144
-35.1765 150 144 59.1667 150 144 60 149.821 144
-61 149.667 144 62 149.5 144 65.7222 150 144
-108 150 141.652 107.357 150 144 108 149.217 144
-113 150 144 123.214 150 144 155.607 150 144
-156 149.5 144 163 150 144 164 149.414 144
-165 149.955 144 165.056 150 144 170 149.848 144
-170.185 150 144 175 150 143.625 174.667 150 144
-177 150 143.684 178 150 141.429 212 149.059 144
-212.941 150 144 215 150 144 228.485 150 144
-35.3429 151 144 58 151 141.6 59.0455 151 144
-66 150.833 144 66.0909 151 144 106.955 151 144
-107 150.909 144 112 150.667 144 111.353 151 144
-122.185 151 144 123 150.214 144 155 151 144
-162.214 151 144 165.214 151 144 171 151 144
-173.714 151 144 174 150.667 144 177 151 141.429
-213 150.036 144 214 150.364 144 228.176 151 144
-35.6571 152 144 60 152 144 62 152 141.682
-66 152 143.842 67 151.909 144 67 152 143.833
-67.2 152 144 94.2174 152 144 95 151.182 144
-96 151.217 144 97 151.696 144 98 151.941 144
-98 152 143.842 99 151.941 144 99 152 143.842
-99.2 152 144 107 151.091 144 108 151.706 144
-109 151.773 144 110 151.586 144 111 151.176 144
-121.571 152 144 122 151.294 144 154.657 152 144
-162.786 152 144 165 152 144 172 151.294 144
-173 151.294 144 187 152 143.769 186.909 152 144
-187 151.833 144 187.083 152 144 227.824 152 144
-228 151.5 144 36 153 144 61 152.343 144
-62 152.486 144 63 152.486 144 64 152.414 144
-65 152.304 144 66 152.059 144 67 152.2 144
-68 153 143.667 67.6667 153 144 68 152.667 144
-68.1667 153 144 73 153 143.769 72.9655 153 144
-73 152.857 144 74 152.417 144 74 153 142.6
-74.3043 153 144 93.1852 153 144 94 152.185 144
-99 153 143.842 99.2 153 144 121.179 153 144
-154.343 153 144 163 152.261 144 164 152.773 144
-168.625 153 144 169 152.778 144 170 152.571 144
-170 153 142.286 170.706 153 144 187 152.056 144
-227.485 153 144 36.3429 154 144 68 153.167 144
-73 154 143.833 72.9412 154 144 74 154 143.824
-74.0435 154 144 92 154 144 93 153.185 144
-99.4118 154 144 121.485 154 144 154.176 154 144
-164 154 143.824 163.944 154 144 164 153.833 144
-165 153.588 144 165 154 142.95 166 153.964 144
-167 153.786 144 168 153.357 144 171 153.417 144
-171.368 154 144 227.176 154 144 36.6571 155 144
-68.4545 155 144 69 154.625 144 70 154.778 144
-71 155 144 72 155 143.833 72 154.941 144
-72.2 155 144 73 154.2 144 74 154.059 144
-89.2 155 144 90 154.879 144 91 154.667 144
-99.25 155 144 121.029 155 144 154 154.5 144
-153.824 155 144 164 154.2 144 164.8 155 144
-166 155 141.429 171.586 155 144 203 155 141.571
-202 155 144 203 154.5 144 204 154.586 144
-204.923 155 144 226.647 155 144 227 154.333 144
-37 156 144 67.4783 156 144 68 155.294 144
-72.5652 156 144 87.5217 156 144 88 155.522 144
-89 155.043 144 99 156 144 120.824 156 144
-121 155.143 144 153.515 156 144 165 156 144
-171.486 156 144 185.955 156 144 186 155.938 144
-187 155.478 144 188 155.393 144 189 155 144
-190 155 144 191 155.393 144 191.773 156 144
-198.759 156 144 199 155.696 144 200 155.179 144
-201 155.176 144 205 155.091 144 206 156 143.625
-205.833 156 144 226.324 156 144 37.5152 157 144
-66.8214 157 144 67 156.688 144 72.1765 157 144
-86 157 144 87 156.522 144 98.3529 157 144
-120.514 157 144 153 157 144 165.485 157 144
-171.486 157 144 186 157 142.364 185.571 157 144
-192 156.185 144 193 156.545 144 193.833 157 144
-195 157 144 197.667 157 144 198 156.786 144
-205 156.909 144 204.917 157 144 225.824 157 144
-226 156.647 144 37.8235 158 144 67 157.294 144
-68 158 144 71.2143 158 144 72 157.214 144
-83.9412 158 144 84 157.957 144 85 157.727 144
-98 157.522 144 97.6071 158 144 120.176 158 144
-152.515 158 144 165.5 158 144 171.657 158 144
-174.5 158 144 175 157.333 144 176 157.414 144
-177 157.786 144 177.6 158 144 185.818 158 144
-194 157.091 144 196 157.353 144 197 157.414 144
-203.455 158 144 204 157.647 144 225.485 158 144
-38 158.5 144 38.1765 159 144 69 158.5 144
-70 158.657 144 71 158.207 144 83 159 144
-97.1818 159 144 101.917 159 144 102 158.955 144
-102.091 159 144 119.824 159 144 120 158.5 144
-152.176 159 144 165.853 159 144 171.5 159 144
-174.5 159 144 178 158.235 144 178.722 159 144
-186 158.273 144 186.696 159 144 200.091 159 144
-201 158.697 144 202 158.364 144 203 158.185 144
-225 159 144 38.5152 160 144 82 160 143
-82.6364 160 144 97 159.8 144 96.9412 160 144
-100.294 160 144 101 159.478 144 103 159.476 144
-103.478 160 144 119.514 160 144 152 159.353 144
-151.676 160 144 166 159.556 144 166.19 160 144
-171.393 160 144 174.966 160 144 179 159.238 144
-179.727 160 144 187 159.241 144 188 159.829 144
-188.5 160 144 195 159.588 144 194.364 160 144
-196 159.786 144 197 159.676 144 198 159.657 144
-199 159.353 144 200 159.034 144 217.647 160 144
-218 159.739 144 219 159 144 220 159.588 144
-220.304 160 144 224.485 160 144 39 161 144
-79 161 141.75 80 161 143 81 161 143.684
-83 160.667 144 83 161 143.684 84 160.667 144
-84.3333 161 144 90 161 144 91 160.824 144
-91.375 161 144 96.9545 161 144 99.5882 161 144
-100 160.417 144 101 161 141.12 104 161 144
-119.514 161 144 151.353 161 144 167 160.944 144
-167.059 161 144 171 160.917 144 170.941 161 144
-175 160.059 144 175.571 161 144 180 160.353 144
-180.917 161 144 181.2 161 144 182 160.81 144
-182.444 161 144 189 160.207 144 190 160.176 144
-191 160.607 144 192 161 144 195 161 142
-194.25 161 144 217 161 143.824 216.909 161 144
-217 160.917 144 218 161 142.714 219 161 141.25
-220 161 144 224 161 144 39.5152 162 144
-79 162 143 80 162 143 81 162 142.364
-85 161.25 144 86 161.941 144 86.0909 162 144
-89 161.586 144 88.2941 162 144 92 161.455 144
-92.3529 162 144 96.7778 162 144 100 161.304 144
-101 161.828 144 102 162 144 103 162 144
-119.514 162 144 151 161.522 144 150.676 162 144
-168 161.727 144 168.6 162 144 171 162 143.684
-170.667 162 144 176 162 144 181 161.045 144
-183 161.313 144 183.917 162 144 193 162 144
-194 162 143.75 194 161.8 144 216 162 143
-215.588 162 144 216 161.588 144 217 162 143.053
-218 162 144 219 161.478 144 223.485 162 144
-39.8235 163 144 78 163 141.6 79 163 142.765
-87 162.588 144 88 162.179 144 92.0345 163 144
-96.9643 163 144 119.514 163 144 150.353 163 144
-168.375 163 144 171 162.286 144 171.217 163 144
-176.485 163 144 184 162.059 144 184.727 163 144
-216 162.412 144 217 162.273 144 223 163 144
-40 163.5 144 40.1765 164 144 77.1667 164 144
-78 163.706 144 78.4545 164 144 91.1852 164 144
-92 163.043 144 97 163.045 144 97.6364 164 144
-119.514 164 144 150 163.667 144 149.824 164 144
-168.043 164 144 171.414 164 144 176.966 164 144
-185 163.5 144 185.375 164 144 222.393 164 144
-40.5152 165 144 64.6471 165 144 65 164.818 144
-66 164.75 144 67 164.909 144 67 165 143.833
-67.0588 165 144 76 165 144 77 164.043 144
-78.3929 165 144 90 165 144 91 164.185 144
-98 164.522 144 98.4783 165 144 119.514 165 144
-149.793 165 144 160 165 143.824 159.917 165 144
-160 164.917 144 161 164.941 144 161 165 143.833
-161.091 165 144 167.515 165 144 168 164.059 144
-171.4 165 144 177 164.059 144 177.727 165 144
-181 164.966 144 180.917 165 144 182 164.966 144
-182.083 165 144 185.478 165 144 199 165 143.842
-198.8 165 144 199 164.8 144 199.091 165 144
-210.966 165 144 211 164.941 144 212 164.909 144
-212 165 143.4 212.077 165 144 221.5 165 144
-222 164.5 144 41 166 144 63.4138 166 144
-64 165.393 144 65 166 141 66.5455 166 144
-67 165.091 144 75.5 166 144 78.1515 166 144
-89.1923 166 144 99 166 141.857 98.7059 166 144
-119.514 166 144 149.739 166 144 160 165.059 144
-161 165.091 144 166.522 166 144 167 165.607 144
-171 165.706 144 170.848 166 144 178 165.214 144
-179 165.176 144 180 165.324 144 183 165.333 144
-183.957 166 144 184.167 166 144 185 165.688 144
-199 166 143.833 198.941 166 144 200 165.588 144
-200 166 142.95 201 166 144 211 166 141.5
-210.773 166 144 212 166 144 221.179 166 144
-41.5152 167 144 63.0556 167 144 65 167 142.263
-65.6875 167 144 66 166.706 144 75.0345 167 144
-78 166.227 144 77.5 167 144 88 167 144
-89 166.227 144 96 166.667 144 95.5 167 144
-97 166.586 144 98 167 143.571 98 166.923 144
-99 167 142.615 119.514 167 144 149.739 167 144
-165.593 167 144 166 166.522 144 170.152 167 144
-184 166.056 144 199 166.167 144 199.217 167 144
-202 166.343 144 203 166.676 144 203.647 167 144
-211 166.455 144 220.824 167 144 221 166.455 144
-42 168 144 63 168 142 64 167.739 144
-65 167.324 144 74.5 168 144 75 167.056 144
-77 167.944 144 76.9655 168 144 87.2143 168 144
-91 168 143.571 91 167.957 144 90.9412 168 144
-92 167.818 144 93 167.966 144 93.1667 168 144
-94.2941 168 144 95 167.478 144 119.353 168 144
-149.786 168 144 165.034 168 144 170 167.455 144
-169.824 168 144 199.5 168 144 204 167.261 144
-205 167.621 144 206 167.739 144 207 167.455 144
-207 168 142.8 207.353 168 144 220.485 168 144
-42.6667 169 144 73.8485 169 144 74 168.773 144
-76.6471 169 144 86.7391 169 144 87 168.5 144
-90 168.727 144 89.7273 169 144 94 168.185 144
-119.029 169 144 149.971 169 144 164.545 169 144
-165 168.091 144 170 169 144 200 168.944 144
-200.029 169 144 204 169 141.125 206.944 169 144
-207 168.857 144 220 169 144 43 169.647 144
-43.1765 170 144 74 170 142.263 73.6071 170 144
-76.2333 170 144 85.8519 170 144 86 169.81 144
-89 169.941 144 88.9412 170 144 118.5 170 144
-119 169.056 144 150 169.083 144 150.324 170 144
-165 170 141.5 164.583 170 144 170.773 170 144
-200.414 170 144 205 170 141.682 206.333 170 144
-219.333 170 144 43.8235 171 144 74 171 143.118
-73.7059 171 144 75 171 143.167 75.2381 171 144
-76 170.304 144 85 171 142.105 85.75 171 144
-87 171 144 88 170.727 144 118.176 171 144
-150.647 171 144 165 170.417 144 166 170.478 144
-167 171 144 170 171 141.167 171 170.455 144
-171 171 143 171.273 171 144 201 171 144
-203 170.688 144 202.688 171 144 204 170.304 144
-205 170.515 144 206 170.353 144 218.647 171 144
-219 170.478 144 44 171.261 144 44.5 172 144
-74 171.294 144 75 171.185 144 84 172 141.875
-85 172 141.75 86 171.25 144 86 172 142.364
-117.853 172 144 118 171.545 144 150.824 172 144
-168 171.607 144 168.478 172 144 171 172 144
-202 171.647 144 218 172 144 45 172.586 144
-45.3529 173 144 117.5 173 144 151 172.353 144
-151.324 173 144 169 173 143.833 168.917 173 144
-169.167 173 144 170 172.545 144 217.333 173 144
-46 174 144 117.029 174 144 151.647 174 144
-168.294 174 144 170 173.833 144 170.056 174 144
-173 174 141.9 216.5 174 144 217 173.393 144
-46.6667 175 144 116.5 175 144 117 174.056 144
-152 174.522 144 152.324 175 144 168.261 175 144
-170.739 175 144 174 175 142.5 203.5 175 144
-204 174.955 144 205 174.815 144 205.179 175 144
-215.5 175 144 216 174.5 144 47 175.393 144
-47.5 176 144 115.848 176 144 116 175.773 144
-152.647 176 144 168.529 176 144 171 175.5 144
-171.261 176 144 202.81 176 144 203 175.2 144
-205.957 176 144 214.393 176 144 215 175.5 144
-48 176.5 144 48.5 177 144 115.176 177 144
-153 176.522 144 153.324 177 144 169 176.593 144
-169.393 177 144 171.333 177 144 202.643 177 144
-206 176.045 144 206.778 177 144 213.393 177 144
-214 176.393 144 49 177.5 144 49.5 178 144
-114.5 178 144 115 177.261 144 154 178 144
-170 177.944 144 171 178 144 203 177.909 144
-203.043 178 144 207 177.261 144 207.607 178 144
-212.667 178 144 213 177.5 144 50 178.5 144
-50.5 179 144 113.848 179 144 114 178.773 144
-155 179 144 183 179 143.824 182.941 179 144
-183 178.955 144 183.167 179 144 203.414 179 144
-208 178.647 144 208.176 179 144 211.697 179 144
-212 178.688 144 51 179.5 144 51.5 180 144
-113 180 144 156 180 144 182.964 180 144
-184 179.278 144 184 180 142.143 185 179.824 144
-185.214 180 144 203.515 180 144 209 179.824 144
-210 180 144 211 179.676 144 52 180.5 144
-52.6071 181 144 112 181 144 157 181 144
-183 181 142.5 182.783 181 144 184 181 141.571
-185 181 141.125 186 180.957 144 186.056 181 144
-202.706 181 144 203 180.773 144 53 181.333 144
-53.8148 182 144 111 182 144 158 181.848 144
-158.227 182 144 165 182 143.824 164.957 182 144
-165 181 144 166 181.333 144 166 182 142.2
-166.706 182 144 172 182 144 173 181.545 144
-173.455 182 144 183 181.455 144 184 182 141.938
-183.353 182 144 187 181.63 144 187.37 182 144
-198.353 182 144 199 181.476 144 200 181.179 144
-201 181.343 144 202 181.343 144 54 182.152 144
-55 182.848 144 55.2273 183 144 110 183 144
-159 182.5 144 159.773 183 144 165 182.043 144
-166 183 142.8 165.786 183 144 167 182.833 144
-167 183 143.667 167.077 183 144 171.739 183 144
-174 182.429 144 175 182.643 144 176 182.286 144
-177 182.214 144 178 182.393 144 179 183 144
-183.462 183 144 188 182.773 144 188.417 183 144
-198.515 183 144 56 183.5 144 57 184 144
-70.5882 184 144 71 183.72 144 72 183.966 144
-72.0588 184 144 87.9583 184 144 88 183.957 144
-89 183.5 144 89.7727 184 144 109 184 144
-160 183.152 144 161 184 144 166 183.5 144
-167 184 141.429 166.5 184 144 168 183.545 144
-168.625 184 144 171.167 184 144 180 183.478 144
-181 184 144 182.545 184 144 183 183.545 144
-189 183.318 144 190 183.706 144 190.217 184 144
-198.182 184 144 58 184.676 144 58.6471 185 144
-70.4138 185 144 73 184.593 144 73.5238 185 144
-87.4138 185 144 90 184.227 144 90.6071 185 144
-108 185 144 162 185 144 166.6 185 144
-169 184.182 144 170 184.176 144 171 184.042 144
-182 184.171 144 190.786 185 144 198.179 185 144
-59 185.176 144 60 185.824 144 60.5 186 144
-71 185.5 144 71.7727 186 144 74 185.455 144
-75 185.957 144 75.0909 186 144 83.3529 186 144
-84 185.676 144 85 185.667 144 86 186 144
-87 185.706 144 90.4286 186 144 107 186 144
-163 186 144 166.414 186 144 178 185.964 144
-177.857 186 144 178.2 186 144 191 185.214 144
-191.786 186 144 196.688 186 144 197 185.815 144
-198 185.192 144 61 186.176 144 62 186.824 144
-62.2609 187 144 72 186.179 144 73 186.667 144
-73.2727 187 144 76 186.303 144 77 186.75 144
-78 186.964 144 79 186.966 144 80 186.647 144
-81 186.514 144 82 186.343 144 83 186.176 144
-90 186.5 144 89.6471 187 144 105.706 187 144
-106 186.848 144 164 186.821 144 164.227 187 144
-166.077 187 144 176 186.767 144 175.611 187 144
-177 186.207 144 178.706 187 144 192 186.214 144
-192.815 187 144 195.522 187 144 196 186.5 144
-63 187.5 144 63.7391 188 144 74 188 144
-89.1471 188 144 103.478 188 144 104 187.586 144
-105 187.343 144 165 187.515 144 166 187.045 144
-169 187.217 144 168.217 188 144 170 187.217 144
-171 187.909 144 171.063 188 144 174.179 188 144
-175 187.324 144 178.5 188 144 193 187.152 144
-194 187.676 144 195 187.522 144 64 188.176 144
-65 188.657 144 66 189 144 74.625 189 144
-85 188.727 144 84.7931 189 144 86 188.407 144
-86.7273 189 144 89 188.5 144 88.7059 189 144
-102.5 189 144 103 188.393 144 168.455 189 144
-170 189 141.429 171.083 189 144 173 189 144
-174 188.227 144 178.485 189 144 67 189.5 144
-68 190 144 75 189.353 144 75 190 141.938
-76 190 143.571 76 189.941 144 76.0357 190 144
-84.9706 190 144 87 189.214 144 88 189.414 144
-101.393 190 144 102 189.5 144 169 189.353 144
-170 189.522 144 171 189.091 144 173 190 144
-179 190 141.167 178.5 190 144 182 190 143
-69 190.343 144 70 190.657 144 71 191 144
-72 191 144 73 190.778 144 74 190.714 144
-75 190.688 144 76 190.083 144 85 190.056 144
-85.6071 191 144 100 191 144 101 190.333 144
-174 191 144 178 191 144 86 191.478 144
-86.3529 192 144 98 192 144 99 191.5 144
-175 191.514 144 176 191.514 144 177 191.514 144
-87 192.815 144 87.1852 193 144 95 193 144
-96 192.657 144 97 192.343 144 88 193.786 144
-89 193.824 144 90 193.647 144 91 193.514 144
-92 193.514 144 93 193.514 144 94 193.343 144
-
-POLYGONS 13733 54932
-3 0 13 17
-3 14 0 17
-3 3 2 4
-3 5 3 4
-3 7 3 6
-3 6 3 5
-3 2 13 4
-3 5 4 13
-3 6 5 13
-3 9 10 11
-3 0 7 13
-3 7 6 13
-3 14 7 0
-3 14 8 7
-3 19 8 14
-3 10 9 20
-3 20 9 126
-3 11 10 15
-3 15 10 20
-3 12 11 16
-3 16 11 15
-3 16 121 12
-3 17 18 14
-3 19 14 22
-3 21 8 19
-3 28 17 13
-3 17 28 18
-3 14 18 22
-3 22 18 28
-3 132 20 126
-3 15 20 132
-3 21 19 29
-3 29 19 22
-3 23 21 29
-3 21 23 24
-3 24 127 21
-3 125 25 26
-3 27 125 26
-3 24 23 29
-3 127 24 30
-3 34 31 25
-3 26 25 32
-3 32 25 31
-3 27 26 32
-3 30 24 38
-3 127 30 33
-3 31 34 36
-3 36 34 35
-3 37 31 36
-3 37 32 31
-3 27 32 37
-3 38 33 30
-3 39 33 38
-3 35 34 39
-3 35 137 36
-3 37 36 137
-3 40 140 42
-3 42 41 40
-3 40 41 43
-3 43 41 42
-3 43 42 47
-3 47 42 46
-3 48 44 45
-3 49 48 45
-3 50 44 48
-3 51 46 58
-3 47 46 51
-3 51 2917 47
-3 50 48 52
-3 52 155 50
-3 48 53 52
-3 54 155 52
-3 53 54 52
-3 46 160 58
-3 160 57 58
-3 51 58 59
-3 65 51 59
-3 60 55 56
-3 61 160 71
-3 160 61 57
-3 57 61 62
-3 58 57 66
-3 66 57 62
-3 63 58 66
-3 64 58 63
-3 59 58 65
-3 65 58 64
-3 56 69 60
-3 70 60 69
-3 62 61 72
-3 66 62 72
-3 63 66 67
-3 64 63 68
-3 68 63 67
-3 65 64 75
-3 75 64 68
-3 75 2917 65
-3 76 60 70
-3 72 61 71
-3 66 72 73
-3 67 66 74
-3 74 66 73
-3 68 67 75
-3 75 67 74
-3 69 165 70
-3 76 70 165
-3 72 71 81
-3 73 72 77
-3 77 72 81
-3 77 74 73
-3 75 74 77
-3 164 78 79
-3 164 76 165
-3 164 79 86
-3 80 71 168
-3 81 71 80
-3 82 80 168
-3 89 82 168
-3 83 80 82
-3 84 80 83
-3 81 80 85
-3 85 80 84
-3 78 86 79
-3 88 86 87
-3 92 89 168
-3 84 83 171
-3 171 83 82
-3 171 85 84
-3 88 87 90
-3 90 87 86
-3 174 91 92
-3 89 92 96
-3 93 94 174
-3 101 93 174
-3 94 95 174
-3 174 95 91
-3 92 91 96
-3 96 91 95
-3 89 96 177
-3 101 97 93
-3 93 97 98
-3 94 93 99
-3 99 93 98
-3 180 95 94
-3 96 95 180
-3 103 173 175
-3 3 173 103
-3 3 7 173
-3 173 7 264
-3 101 100 1
-3 97 101 1
-3 102 97 1
-3 102 98 97
-3 99 98 111
-3 111 98 102
-3 111 94 99
-3 122 103 175
-3 3 103 2
-3 104 100 101
-3 107 104 101
-3 1 100 105
-3 105 100 104
-3 122 2 103
-3 112 264 7
-3 179 185 115
-3 11 179 115
-3 11 106 179
-3 179 106 107
-3 104 107 108
-3 105 104 109
-3 109 104 108
-3 105 110 1
-3 105 109 110
-3 1 110 102
-3 111 102 110
-3 122 13 2
-3 8 112 7
-3 115 185 114
-3 11 115 9
-3 106 11 12
-3 121 106 12
-3 121 107 106
-3 108 107 116
-3 116 107 121
-3 109 108 111
-3 111 108 116
-3 110 109 111
-3 112 8 21
-3 117 112 127
-3 113 123 118
-3 184 113 118
-3 125 184 118
-3 119 184 125
-3 114 119 120
-3 115 114 120
-3 9 115 126
-3 111 116 136
-3 136 116 121
-3 127 112 21
-3 117 127 128
-3 128 193 117
-3 194 123 113
-3 131 118 123
-3 125 118 124
-3 124 118 131
-3 126 119 125
-3 120 119 126
-3 115 120 126
-3 15 121 16
-3 28 13 122
-3 129 193 128
-3 129 130 194
-3 194 130 123
-3 123 130 134
-3 131 123 134
-3 25 124 131
-3 125 124 25
-3 126 125 27
-3 132 136 15
-3 121 15 136
-3 28 122 133
-3 128 127 33
-3 129 128 130
-3 34 131 134
-3 25 131 34
-3 135 126 27
-3 132 126 135
-3 136 132 135
-3 29 133 218
-3 29 22 133
-3 22 28 133
-3 130 128 33
-3 134 130 33
-3 27 219 135
-3 136 135 219
-3 29 38 24
-3 134 33 39
-3 34 134 39
-3 38 29 218
-3 27 37 219
-3 219 37 137
-3 218 39 38
-3 137 35 39
-3 140 234 138
-3 139 236 237
-3 140 138 42
-3 141 139 237
-3 142 139 141
-3 40 43 140
-3 43 234 140
-3 143 144 141
-3 141 144 142
-3 144 147 142
-3 148 42 138
-3 2917 234 43
-3 145 144 143
-3 147 144 145
-3 146 145 143
-3 147 145 146
-3 42 148 46
-3 47 2917 43
-3 154 149 146
-3 147 146 150
-3 150 146 149
-3 151 147 150
-3 154 152 149
-3 149 152 150
-3 44 152 45
-3 44 151 152
-3 151 150 152
-3 44 155 151
-3 46 148 760
-3 153 152 154
-3 45 153 49
-3 152 153 45
-3 44 50 155
-3 154 49 153
-3 154 157 49
-3 157 48 49
-3 48 157 53
-3 155 54 156
-3 244 155 55
-3 55 155 156
-3 46 760 160
-3 51 65 2917
-3 53 156 54
-3 53 157 156
-3 157 158 156
-3 55 158 56
-3 55 156 158
-3 55 60 245
-3 55 245 244
-3 245 60 159
-3 157 163 161
-3 157 161 158
-3 158 161 56
-3 60 162 159
-3 160 760 71
-3 56 161 163
-3 69 56 163
-3 76 162 60
-3 69 163 165
-3 76 164 162
-3 256 168 760
-3 71 760 168
-3 78 164 165
-3 86 252 164
-3 86 88 252
-3 81 75 77
-3 165 359 78
-3 252 88 166
-3 252 166 257
-3 256 167 168
-3 78 359 86
-3 257 166 169
-3 167 261 92
-3 168 167 92
-3 85 171 81
-3 171 75 81
-3 166 90 170
-3 88 90 166
-3 169 166 173
-3 173 166 170
-3 264 169 173
-3 261 259 174
-3 92 261 174
-3 86 359 172
-3 86 172 90
-3 90 172 170
-3 172 173 170
-3 89 177 82
-3 171 82 177
-3 2917 171 177
-3 173 172 175
-3 175 172 359
-3 178 264 112
-3 179 107 176
-3 176 101 174
-3 101 176 107
-3 94 111 180
-3 359 122 175
-3 183 178 182
-3 184 276 183
-3 111 181 180
-3 187 180 181
-3 180 187 96
-3 182 178 112
-3 179 184 185
-3 186 181 111
-3 187 181 186
-3 177 96 187
-3 182 112 117
-3 183 182 188
-3 189 183 188
-3 113 183 189
-3 184 183 113
-3 185 184 190
-3 185 190 114
-3 117 193 182
-3 188 182 191
-3 191 182 193
-3 189 188 194
-3 194 188 191
-3 113 189 194
-3 119 190 184
-3 114 190 119
-3 136 192 111
-3 186 111 192
-3 187 186 192
-3 194 191 193
-3 194 193 129
-3 133 122 218
-3 136 219 220
-3 196 195 197
-3 197 195 295
-3 198 196 197
-3 198 199 196
-3 201 202 200
-3 202 203 205
-3 200 202 205
-3 203 204 205
-3 205 204 206
-3 206 207 291
-3 295 208 197
-3 198 197 208
-3 199 198 209
-3 209 198 208
-3 210 199 209
-3 200 199 211
-3 211 199 210
-3 201 200 211
-3 212 201 211
-3 202 201 213
-3 213 201 212
-3 203 202 213
-3 204 203 214
-3 214 203 213
-3 215 204 214
-3 206 204 215
-3 215 216 206
-3 207 206 216
-3 211 210 217
-3 217 210 209
-3 212 211 217
-3 217 213 212
-3 214 213 217
-3 215 214 217
-3 220 137 39
-3 219 137 220
-3 221 222 223
-3 221 227 224
-3 222 221 225
-3 225 221 224
-3 225 315 222
-3 224 227 228
-3 315 225 228
-3 228 225 224
-3 226 540 230
-3 227 226 231
-3 231 226 230
-3 228 227 232
-3 232 227 231
-3 232 315 228
-3 230 540 138
-3 234 230 138
-3 234 231 230
-3 232 231 315
-3 315 231 234
-3 235 233 229
-3 238 235 229
-3 236 233 235
-3 761 233 236
-3 237 235 238
-3 236 235 237
-3 237 238 141
-3 139 142 236
-3 142 761 236
-3 143 141 238
-3 239 142 147
-3 239 419 142
-3 238 320 143
-3 320 146 143
-3 146 320 154
-3 147 151 239
-3 148 138 760
-3 155 239 151
-3 241 239 155
-3 320 762 154
-3 762 157 154
-3 155 244 241
-3 325 240 243
-3 243 240 242
-3 247 242 240
-3 243 242 248
-3 248 242 247
-3 248 325 243
-3 159 246 245
-3 159 249 246
-3 247 250 248
-3 762 163 157
-3 159 162 249
-3 251 162 164
-3 251 164 253
-3 252 253 164
-3 253 252 336
-3 165 163 262
-3 333 252 254
-3 254 252 257
-3 255 333 254
-3 165 262 359
-3 255 254 258
-3 258 254 257
-3 259 451 260
-3 256 451 261
-3 261 451 259
-3 167 256 261
-3 258 257 263
-3 263 257 169
-3 264 258 263
-3 255 258 264
-3 267 259 260
-3 75 171 2917
-3 263 169 264
-3 264 346 255
-3 351 346 265
-3 265 346 264
-3 259 267 174
-3 269 265 264
-3 178 363 270
-3 363 178 275
-3 271 266 354
-3 271 354 272
-3 272 273 274
-3 271 272 274
-3 268 274 273
-3 267 268 273
-3 267 273 174
-3 264 178 269
-3 269 178 360
-3 275 178 276
-3 184 365 276
-3 179 805 184
-3 354 179 176
-3 272 354 176
-3 174 272 176
-3 273 272 174
-3 178 277 360
-3 270 277 178
-3 276 178 183
-3 122 359 278
-3 187 192 177
-3 279 280 385
-3 385 280 281
-3 391 282 279
-3 279 282 280
-3 281 280 282
-3 283 281 282
-3 281 283 284
-3 122 382 218
-3 1226 192 136
-3 285 286 395
-3 401 287 286
-3 288 286 287
-3 395 286 289
-3 289 286 288
-3 289 290 395
-3 393 395 290
-3 196 290 195
-3 393 290 196
-3 196 199 393
-3 199 200 393
-3 393 200 205
-3 205 291 292
-3 287 401 293
-3 287 293 288
-3 289 288 294
-3 294 288 293
-3 290 289 295
-3 295 289 294
-3 290 295 195
-3 291 205 206
-3 207 296 291
-3 292 291 296
-3 293 297 298
-3 294 293 298
-3 295 294 298
-3 295 298 208
-3 216 215 299
-3 216 299 207
-3 207 299 296
-3 299 409 296
-3 215 409 299
-3 209 409 217
-3 208 409 209
-3 409 215 217
-3 300 301 410
-3 301 304 410
-3 300 302 303
-3 301 300 304
-3 304 300 303
-3 303 302 306
-3 306 302 305
-3 304 303 307
-3 307 303 306
-3 307 308 304
-3 223 302 221
-3 305 302 223
-3 222 305 223
-3 222 309 305
-3 309 306 305
-3 307 306 308
-3 308 306 309
-3 221 302 227
-3 222 315 309
-3 315 308 309
-3 233 415 229
-3 415 414 229
-3 302 226 227
-3 302 540 226
-3 312 310 311
-3 423 312 311
-3 312 314 310
-3 313 312 423
-3 314 312 313
-3 316 313 423
-3 314 313 317
-3 317 313 316
-3 317 914 314
-3 317 316 318
-3 914 317 318
-3 142 419 761
-3 540 760 138
-3 319 316 423
-3 318 316 319
-3 914 318 319
-3 2917 315 234
-3 229 320 238
-3 241 322 321
-3 239 241 321
-3 319 240 325
-3 324 322 241
-3 323 322 324
-3 319 423 240
-3 241 244 324
-3 245 425 244
-3 246 425 245
-3 240 423 247
-3 325 248 250
-3 330 325 250
-3 427 426 249
-3 249 426 246
-3 247 423 250
-3 249 430 327
-3 249 162 430
-3 427 249 327
-3 250 423 329
-3 330 250 329
-3 442 163 762
-3 251 331 162
-3 331 430 162
-3 337 332 328
-3 333 328 332
-3 330 329 334
-3 326 330 434
-3 434 330 334
-3 335 331 251
-3 336 332 337
-3 252 333 336
-3 333 332 336
-3 423 338 329
-3 329 338 334
-3 339 434 338
-3 338 434 334
-3 335 342 443
-3 335 251 342
-3 251 253 342
-3 337 253 336
-3 760 451 256
-3 341 339 338
-3 340 341 338
-3 440 344 441
-3 163 442 262
-3 343 443 342
-3 255 346 333
-3 573 441 344
-3 262 442 349
-3 342 345 343
-3 451 347 260
-3 344 440 348
-3 348 440 356
-3 573 344 357
-3 357 344 348
-3 262 349 454
-3 454 350 262
-3 352 346 351
-3 347 805 179
-3 354 347 179
-3 355 347 354
-3 260 347 355
-3 348 356 357
-3 358 573 357
-3 262 350 359
-3 360 351 265
-3 352 351 360
-3 361 363 362
-3 363 364 362
-3 362 364 365
-3 365 184 805
-3 266 366 354
-3 366 355 354
-3 367 355 366
-3 267 367 268
-3 267 260 367
-3 260 355 367
-3 358 357 368
-3 368 369 358
-3 265 269 360
-3 363 361 270
-3 270 361 370
-3 364 363 371
-3 371 363 275
-3 276 364 371
-3 365 364 276
-3 271 643 266
-3 366 266 832
-3 832 266 643
-3 367 366 474
-3 366 832 474
-3 372 271 274
-3 474 268 367
-3 274 268 372
-3 372 268 474
-3 356 373 357
-3 368 357 374
-3 374 357 373
-3 375 369 368
-3 375 368 374
-3 377 270 370
-3 276 371 275
-3 372 643 271
-3 375 374 378
-3 378 374 373
-3 278 359 376
-3 380 360 277
-3 277 270 377
-3 277 377 380
-3 379 122 278
-3 494 122 379
-3 122 494 382
-3 177 192 1226
-3 518 386 383
-3 507 383 386
-3 385 384 516
-3 387 384 385
-3 507 386 388
-3 388 389 507
-3 389 391 516
-3 385 391 279
-3 385 516 391
-3 281 387 385
-3 386 518 388
-3 389 388 390
-3 389 390 391
-3 387 281 284
-3 284 392 387
-3 285 387 392
-3 393 387 285
-3 285 395 393
-3 391 283 282
-3 391 390 283
-3 283 392 284
-3 283 394 392
-3 285 392 286
-3 392 394 286
-3 283 390 396
-3 396 397 283
-3 398 399 394
-3 398 394 397
-3 397 394 283
-3 399 400 401
-3 399 401 394
-3 394 401 286
-3 292 393 205
-3 382 707 218
-3 402 396 390
-3 403 396 402
-3 403 404 405
-3 403 405 396
-3 396 405 397
-3 400 398 397
-3 400 397 406
-3 406 397 405
-3 400 406 401
-3 292 296 407
-3 405 408 406
-3 401 406 408
-3 297 293 408
-3 293 401 408
-3 296 409 407
-3 297 408 298
-3 532 408 405
-3 298 408 532
-3 39 218 1226
-3 39 1226 220
-3 304 411 410
-3 413 412 414
-3 761 413 414
-3 761 414 415
-3 418 416 539
-3 423 418 539
-3 417 416 418
-3 417 914 416
-3 414 412 229
-3 310 418 311
-3 310 417 418
-3 310 914 417
-3 415 233 761
-3 418 423 311
-3 310 314 914
-3 319 573 914
-3 420 761 419
-3 229 762 320
-3 419 239 421
-3 421 420 419
-3 319 325 573
-3 239 542 421
-3 239 321 542
-3 542 321 322
-3 542 322 422
-3 322 323 422
-3 326 325 330
-3 324 422 323
-3 246 424 425
-3 324 244 422
-3 426 424 246
-3 426 554 424
-3 429 554 426
-3 429 426 428
-3 428 426 427
-3 327 430 557
-3 427 327 431
-3 431 327 557
-3 428 427 431
-3 429 428 431
-3 328 432 564
-3 573 326 440
-3 430 331 433
-3 328 564 337
-3 328 333 432
-3 438 432 333
-3 440 326 434
-3 331 335 433
-3 433 335 449
-3 570 435 337
-3 570 337 564
-3 435 436 437
-3 570 436 435
-3 339 439 434
-3 439 447 434
-3 440 434 447
-3 443 449 335
-3 337 444 253
-3 337 435 444
-3 444 435 445
-3 435 437 445
-3 445 437 446
-3 333 346 438
-3 346 576 438
-3 423 470 338
-3 439 341 447
-3 339 341 439
-3 441 573 440
-3 448 449 443
-3 443 343 448
-3 444 342 253
-3 445 450 444
-3 446 450 445
-3 346 579 576
-3 338 452 340
-3 340 447 341
-3 340 452 447
-3 452 456 447
-3 356 447 456
-3 447 356 440
-3 442 453 349
-3 454 449 448
-3 458 449 454
-3 343 345 455
-3 343 455 448
-3 448 455 454
-3 345 459 455
-3 342 459 345
-3 444 459 342
-3 579 346 352
-3 352 584 579
-3 584 352 586
-3 451 805 347
-3 452 338 470
-3 349 453 457
-3 454 349 458
-3 457 458 349
-3 459 454 455
-3 459 350 454
-3 459 460 350
-3 589 462 461
-3 586 352 353
-3 365 805 598
-3 456 452 470
-3 573 358 464
-3 464 471 573
-3 465 458 457
-3 465 457 466
-3 466 457 453
-3 466 460 465
-3 466 359 460
-3 359 350 460
-3 461 467 589
-3 462 467 461
-3 352 360 595
-3 360 468 595
-3 353 352 607
-3 352 595 607
-3 608 361 469
-3 463 362 598
-3 463 469 362
-3 469 361 362
-3 365 598 362
-3 456 470 356
-3 464 369 375
-3 358 369 464
-3 471 464 375
-3 453 477 466
-3 359 466 472
-3 466 477 472
-3 468 360 639
-3 608 626 370
-3 608 370 361
-3 470 893 356
-3 375 475 471
-3 476 471 475
-3 478 617 472
-3 478 472 477
-3 376 617 479
-3 376 472 617
-3 376 359 472
-3 370 653 377
-3 480 628 473
-3 480 473 629
-3 372 474 485
-3 373 356 893
-3 475 378 481
-3 375 378 475
-3 476 475 482
-3 482 475 481
-3 483 471 476
-3 483 476 482
-3 376 648 278
-3 479 648 376
-3 380 639 360
-3 485 643 372
-3 481 378 678
-3 482 481 679
-3 679 481 678
-3 483 482 486
-3 486 482 679
-3 487 483 486
-3 278 648 684
-3 379 488 484
-3 379 278 488
-3 650 685 484
-3 685 379 484
-3 380 377 987
-3 378 489 678
-3 679 490 486
-3 381 487 490
-3 487 486 490
-3 381 491 492
-3 381 492 487
-3 491 493 664
-3 492 491 664
-3 859 278 684
-3 488 278 859
-3 495 494 685
-3 494 379 685
-3 378 373 496
-3 373 893 496
-3 378 496 489
-3 496 497 489
-3 498 678 489
-3 498 489 497
-3 679 499 490
-3 381 490 500
-3 490 499 500
-3 381 500 491
-3 500 501 491
-3 493 491 501
-3 507 493 501
-3 502 493 507
-3 387 493 502
-3 503 700 382
-3 382 495 503
-3 494 495 382
-3 504 701 687
-3 893 505 496
-3 496 505 497
-3 498 497 505
-3 499 498 506
-3 506 498 505
-3 500 499 506
-3 501 500 506
-3 383 507 501
-3 502 507 508
-3 384 502 508
-3 502 384 387
-3 382 700 707
-3 510 512 513
-3 512 514 513
-3 515 505 893
-3 505 515 506
-3 501 506 515
-3 383 501 518
-3 516 508 507
-3 508 516 384
-3 513 511 510
-3 501 515 518
-3 516 389 519
-3 507 389 516
-3 516 519 389
-3 515 521 518
-3 388 518 521
-3 388 521 390
-3 524 393 292
-3 292 407 524
-3 521 1217 390
-3 522 403 525
-3 522 526 403
-3 399 398 526
-3 399 526 523
-3 523 526 522
-3 523 400 399
-3 523 527 400
-3 390 528 402
-3 529 525 528
-3 529 530 525
-3 528 525 402
-3 402 525 403
-3 530 404 531
-3 530 529 404
-3 531 404 526
-3 526 404 403
-3 398 531 526
-3 398 400 531
-3 400 527 531
-3 529 528 532
-3 532 528 390
-3 404 529 405
-3 529 532 405
-3 407 409 524
-3 218 707 533
-3 220 1226 136
-3 1052 298 532
-3 208 298 1052
-3 533 1226 218
-3 409 208 1052
-3 411 534 410
-3 534 411 1258
-3 535 412 536
-3 411 304 757
-3 1258 411 757
-3 412 413 536
-3 410 540 300
-3 538 537 914
-3 761 536 413
-3 540 302 300
-3 304 308 758
-3 758 757 304
-3 539 914 537
-3 762 412 535
-3 416 914 539
-3 759 758 308
-3 539 537 423
-3 308 315 759
-3 315 2917 759
-3 412 762 229
-3 541 761 420
-3 421 541 420
-3 421 542 541
-3 542 543 541
-3 546 541 544
-3 544 541 543
-3 544 545 546
-3 422 543 542
-3 546 545 547
-3 765 543 422
-3 548 545 544
-3 547 545 548
-3 548 549 547
-3 325 326 573
-3 422 768 765
-3 549 548 769
-3 424 550 425
-3 422 244 768
-3 551 768 244
-3 425 550 552
-3 424 553 550
-3 553 424 554
-3 425 555 244
-3 555 551 244
-3 555 425 556
-3 425 552 556
-3 550 557 552
-3 557 556 552
-3 558 553 559
-3 558 557 553
-3 557 550 553
-3 554 559 553
-3 429 776 554
-3 557 430 556
-3 560 561 430
-3 556 430 561
-3 557 558 431
-3 431 558 562
-3 561 560 558
-3 562 558 560
-3 431 562 429
-3 429 563 776
-3 562 563 429
-3 560 433 565
-3 430 433 560
-3 562 560 566
-3 566 560 565
-3 563 562 566
-3 432 567 564
-3 568 567 432
-3 568 432 438
-3 779 568 438
-3 565 433 569
-3 433 449 569
-3 564 567 570
-3 436 570 785
-3 437 571 572
-3 437 436 571
-3 436 785 571
-3 438 786 572
-3 438 572 779
-3 571 779 572
-3 576 786 438
-3 577 569 449
-3 444 450 575
-3 572 575 446
-3 572 446 437
-3 446 575 450
-3 786 575 572
-3 760 805 451
-3 579 578 576
-3 449 458 577
-3 459 444 588
-3 444 574 588
-3 580 581 582
-3 583 579 584
-3 585 584 586
-3 459 587 460
-3 459 588 587
-3 591 580 590
-3 582 592 580
-3 592 590 580
-3 592 582 581
-3 594 583 593
-3 584 595 583
-3 595 593 583
-3 596 584 585
-3 595 584 596
-3 353 597 586
-3 597 463 598
-3 597 598 586
-3 599 600 601
-3 601 600 814
-3 602 458 465
-3 602 815 458
-3 815 577 458
-3 465 460 587
-3 465 587 602
-3 603 587 588
-3 462 589 467
-3 604 591 590
-3 605 591 604
-3 592 606 590
-3 606 604 590
-3 606 592 581
-3 593 820 594
-3 593 468 820
-3 595 468 593
-3 595 596 607
-3 597 353 607
-3 608 463 609
-3 608 469 463
-3 609 463 610
-3 610 463 597
-3 610 611 609
-3 612 613 614
-3 644 573 471
-3 599 615 616
-3 616 600 599
-3 442 477 453
-3 815 617 618
-3 815 602 617
-3 602 587 617
-3 619 587 603
-3 617 587 619
-3 620 621 622
-3 622 623 620
-3 606 605 604
-3 625 820 468
-3 625 468 639
-3 626 608 609
-3 627 609 611
-3 627 628 609
-3 628 626 609
-3 613 628 627
-3 612 628 613
-3 612 473 628
-3 473 612 629
-3 629 630 631
-3 474 832 833
-3 599 632 615
-3 615 632 633
-3 616 615 634
-3 634 615 633
-3 634 600 616
-3 635 618 478
-3 617 478 618
-3 635 479 619
-3 617 619 479
-3 620 636 621
-3 623 636 620
-3 370 626 640
-3 628 641 626
-3 641 640 626
-3 628 480 641
-3 631 660 629
-3 660 631 642
-3 474 833 485
-3 471 483 644
-3 645 599 680
-3 599 645 632
-3 632 645 646
-3 633 632 647
-3 647 632 646
-3 647 634 633
-3 477 635 478
-3 477 648 635
-3 635 648 479
-3 484 859 649
-3 488 859 484
-3 484 649 650
-3 668 669 624
-3 624 637 668
-3 637 651 668
-3 652 637 638
-3 651 637 652
-3 370 654 653
-3 370 640 654
-3 655 653 654
-3 656 654 640
-3 641 657 640
-3 657 656 640
-3 480 658 641
-3 641 658 657
-3 480 659 658
-3 480 629 659
-3 660 659 629
-3 661 662 663
-3 483 487 644
-3 487 492 644
-3 664 644 492
-3 680 665 645
-3 645 665 666
-3 646 645 667
-3 667 645 666
-3 667 647 646
-3 670 668 651
-3 652 670 651
-3 987 377 653
-3 654 671 655
-3 671 654 672
-3 654 656 672
-3 657 673 656
-3 673 672 656
-3 658 674 657
-3 674 673 657
-3 674 658 659
-3 675 662 661
-3 691 662 675
-3 676 661 663
-3 675 661 676
-3 485 677 643
-3 387 664 493
-3 680 681 665
-3 665 681 682
-3 666 665 683
-3 683 665 682
-3 683 667 666
-3 648 698 684
-3 686 669 687
-3 669 668 687
-3 703 668 670
-3 687 668 703
-3 688 671 672
-3 673 689 672
-3 689 688 672
-3 674 690 673
-3 690 689 673
-3 676 691 675
-3 499 678 498
-3 679 678 499
-3 692 694 693
-3 693 694 680
-3 680 694 695
-3 681 680 696
-3 696 680 695
-3 682 681 697
-3 697 681 696
-3 697 683 682
-3 698 699 684
-3 859 684 699
-3 859 699 707
-3 685 503 495
-3 685 700 503
-3 702 686 701
-3 687 701 686
-3 703 504 687
-3 866 688 689
-3 690 866 689
-3 714 517 693
-3 693 517 704
-3 692 704 509
-3 692 693 704
-3 509 705 692
-3 705 694 692
-3 695 694 706
-3 706 694 705
-3 697 696 706
-3 706 696 695
-3 504 702 701
-3 716 702 504
-3 710 510 511
-3 710 512 510
-3 514 512 867
-3 512 710 867
-3 514 712 711
-3 867 712 514
-3 393 713 387
-3 517 715 704
-3 509 704 715
-3 509 715 705
-3 715 738 705
-3 738 697 706
-3 738 706 705
-3 703 716 504
-3 718 708 717
-3 717 708 709
-3 511 719 710
-3 511 513 719
-3 514 719 513
-3 514 720 719
-3 730 719 720
-3 721 711 722
-3 721 720 711
-3 720 514 711
-3 712 722 711
-3 2917 177 1226
-3 393 520 713
-3 520 1014 713
-3 714 885 723
-3 714 723 724
-3 517 714 725
-3 725 714 724
-3 517 725 726
-3 517 726 715
-3 726 738 715
-3 727 718 717
-3 728 718 727
-3 729 717 709
-3 727 717 729
-3 721 730 720
-3 520 393 877
-3 1021 877 393
-3 1021 393 524
-3 723 885 734
-3 734 885 733
-3 724 723 735
-3 735 723 734
-3 736 724 735
-3 725 724 737
-3 737 724 736
-3 726 725 738
-3 738 725 737
-3 727 739 728
-3 729 739 727
-3 893 521 515
-3 731 522 525
-3 731 732 740
-3 731 740 522
-3 522 740 523
-3 741 523 740
-3 734 733 742
-3 735 734 742
-3 894 743 736
-3 894 736 735
-3 737 736 743
-3 744 738 737
-3 893 1217 521
-3 746 527 741
-3 527 523 741
-3 735 742 894
-3 530 745 525
-3 531 746 530
-3 530 746 745
-3 746 531 527
-3 524 409 901
-3 390 1051 532
-3 707 747 533
-3 532 1051 1052
-3 747 748 533
-3 533 748 749
-3 749 748 902
-3 533 749 902
-3 902 1226 533
-3 913 753 750
-3 752 751 754
-3 1103 410 534
-3 755 753 913
-3 756 755 913
-3 750 753 914
-3 914 753 755
-3 535 754 751
-3 535 536 754
-3 755 756 538
-3 914 755 538
-3 538 756 537
-3 535 751 762
-3 761 764 536
-3 756 423 537
-3 541 546 761
-3 546 764 761
-3 547 763 764
-3 546 547 764
-3 544 543 766
-3 766 543 765
-3 544 766 548
-3 763 549 767
-3 547 549 763
-3 764 763 767
-3 768 766 765
-3 548 766 769
-3 766 768 769
-3 769 767 549
-3 769 770 767
-3 764 767 770
-3 771 764 770
-3 551 769 768
-3 772 769 551
-3 772 773 770
-3 772 770 769
-3 770 773 771
-3 774 771 773
-3 774 554 918
-3 555 775 551
-3 551 775 772
-3 559 773 558
-3 558 773 926
-3 554 773 559
-3 774 773 554
-3 554 776 918
-3 918 776 777
-3 762 930 442
-3 555 924 775
-3 556 924 555
-3 556 925 924
-3 561 926 556
-3 556 926 925
-3 926 561 558
-3 776 563 778
-3 777 776 778
-3 566 778 563
-3 567 777 778
-3 568 777 567
-3 568 779 931
-3 931 779 780
-3 760 1132 805
-3 781 782 783
-3 565 569 791
-3 565 791 566
-3 791 945 566
-3 939 778 945
-3 945 778 566
-3 940 778 939
-3 570 940 784
-3 570 778 940
-3 570 567 778
-3 784 785 570
-3 785 786 571
-3 571 786 779
-3 780 779 786
-3 780 786 787
-3 787 786 576
-3 781 788 782
-3 569 577 791
-3 793 574 792
-3 792 574 794
-3 940 444 784
-3 940 794 444
-3 794 574 444
-3 575 784 444
-3 785 784 575
-3 786 785 575
-3 576 578 787
-3 789 796 797
-3 797 790 789
-3 792 945 801
-3 793 792 801
-3 793 801 574
-3 795 578 803
-3 579 803 578
-3 789 946 798
-3 789 798 796
-3 796 798 799
-3 797 796 800
-3 800 796 799
-3 800 790 797
-3 801 588 574
-3 802 951 580
-3 951 581 580
-3 803 579 583
-3 803 804 1128
-3 804 585 586
-3 804 586 1128
-3 586 598 1128
-3 952 573 825
-3 798 946 806
-3 799 798 807
-3 807 798 806
-3 814 800 807
-3 807 800 799
-3 790 800 814
-3 577 808 953
-3 577 953 950
-3 801 953 808
-3 801 808 588
-3 802 591 954
-3 580 591 802
-3 951 809 581
-3 803 594 810
-3 583 594 803
-3 811 812 804
-3 811 804 810
-3 810 804 803
-3 812 585 804
-3 812 813 585
-3 813 596 585
-3 601 946 599
-3 806 946 601
-3 814 807 806
-3 601 814 806
-3 577 815 808
-3 588 808 816
-3 816 808 815
-3 588 816 603
-3 954 605 957
-3 591 605 954
-3 581 809 606
-3 809 817 606
-3 820 810 594
-3 820 821 810
-3 822 811 810
-3 822 810 821
-3 607 813 822
-3 607 596 813
-3 597 823 610
-3 610 823 611
-3 613 824 614
-3 824 612 614
-3 831 612 824
-3 573 644 825
-3 952 825 664
-3 618 826 815
-3 826 816 815
-3 603 826 619
-3 816 826 603
-3 622 621 827
-3 622 827 623
-3 605 606 957
-3 957 606 817
-3 637 818 819
-3 637 624 818
-3 819 960 637
-3 625 828 820
-3 828 821 820
-3 822 821 829
-3 829 821 828
-3 607 822 830
-3 830 822 829
-3 966 607 830
-3 597 607 966
-3 967 597 966
-3 823 597 967
-3 611 823 627
-3 627 823 968
-3 824 613 627
-3 968 824 627
-3 629 612 831
-3 630 629 831
-3 831 631 630
-3 839 631 831
-3 825 644 834
-3 664 825 834
-3 600 634 814
-3 477 442 648
-3 618 635 826
-3 619 826 635
-3 621 636 827
-3 623 827 636
-3 637 960 638
-3 960 835 638
-3 625 639 828
-3 829 828 836
-3 836 828 639
-3 830 829 837
-3 837 829 836
-3 976 966 830
-3 976 830 838
-3 838 830 837
-3 839 840 642
-3 839 642 631
-3 840 841 842
-3 839 841 840
-3 841 989 842
-3 833 843 485
-3 664 834 644
-3 599 1154 680
-3 647 814 634
-3 648 442 698
-3 649 859 855
-3 855 844 649
-3 844 650 649
-3 650 844 845
-3 845 846 847
-3 844 846 845
-3 624 669 848
-3 624 848 985
-3 638 835 652
-3 835 985 652
-3 639 380 849
-3 836 639 849
-3 836 850 837
-3 653 838 850
-3 838 837 850
-3 653 655 976
-3 653 976 838
-3 976 655 993
-3 851 659 988
-3 988 659 660
-3 840 660 642
-3 840 852 660
-3 852 988 660
-3 842 852 840
-3 853 852 842
-3 854 842 662
-3 854 853 842
-3 662 842 663
-3 663 842 989
-3 995 663 989
-3 677 485 843
-3 1154 693 680
-3 667 814 647
-3 859 990 855
-3 856 844 855
-3 845 857 650
-3 650 857 685
-3 848 669 858
-3 670 985 848
-3 670 848 858
-3 985 670 652
-3 380 987 849
-3 653 850 987
-3 671 993 655
-3 659 862 674
-3 994 659 851
-3 862 659 994
-3 662 691 854
-3 995 676 663
-3 996 387 997
-3 683 814 667
-3 991 685 992
-3 992 685 857
-3 686 861 669
-3 860 861 686
-3 669 861 858
-3 861 703 858
-3 858 703 670
-3 671 688 993
-3 862 863 674
-3 674 863 690
-3 676 864 691
-3 995 864 676
-3 387 870 997
-3 697 892 683
-3 892 814 683
-3 700 999 859
-3 700 859 707
-3 991 999 685
-3 999 700 685
-3 686 702 860
-3 860 702 1006
-3 865 861 860
-3 703 861 865
-3 993 688 1008
-3 688 866 1008
-3 690 1009 866
-3 690 863 1009
-3 868 869 867
-3 870 387 713
-3 870 713 1013
-3 693 1187 714
-3 699 698 707
-3 702 716 1006
-3 1006 716 880
-3 703 865 1018
-3 709 708 872
-3 872 708 871
-3 871 873 872
-3 1009 1008 866
-3 710 874 867
-3 867 875 868
-3 874 875 867
-3 876 867 869
-3 876 712 867
-3 713 1014 1013
-3 1004 1014 520
-3 1004 520 877
-3 1187 1023 714
-3 697 738 892
-3 716 1018 880
-3 1018 716 703
-3 871 708 881
-3 708 718 881
-3 872 882 709
-3 873 882 872
-3 730 710 719
-3 730 883 710
-3 883 874 710
-3 721 722 884
-3 721 884 874
-3 721 874 883
-3 875 874 884
-3 876 722 712
-3 884 722 876
-3 878 877 1021
-3 1046 885 879
-3 714 1023 885
-3 728 886 881
-3 728 881 718
-3 882 729 709
-3 882 887 729
-3 721 883 730
-3 890 1033 731
-3 1033 732 731
-3 892 738 891
-3 728 739 886
-3 739 887 886
-3 729 887 739
-3 525 895 890
-3 731 525 890
-3 741 740 732
-3 733 885 1046
-3 743 897 737
-3 894 897 743
-3 892 737 897
-3 892 744 737
-3 891 738 744
-3 891 744 892
-3 733 1046 742
-3 892 897 899
-3 525 745 895
-3 746 1040 745
-3 898 896 901
-3 901 896 524
-3 742 1046 899
-3 899 894 742
-3 897 894 899
-3 900 898 901
-3 903 1047 901
-3 901 409 903
-3 747 902 748
-3 903 409 1052
-3 904 905 906
-3 909 1093 750
-3 1095 909 750
-3 1095 750 914
-3 751 910 911
-3 912 910 752
-3 752 910 751
-3 750 1093 913
-3 912 754 536
-3 912 752 754
-3 913 1093 756
-3 912 536 764
-3 762 751 911
-3 1258 757 759
-3 1105 914 915
-3 540 410 1103
-3 915 914 916
-3 760 540 1103
-3 757 758 759
-3 916 914 573
-3 759 2917 4237
-3 771 918 764
-3 917 919 923
-3 773 772 920
-3 920 921 773
-3 771 774 918
-3 928 922 919
-3 923 919 922
-3 772 775 924
-3 772 924 920
-3 924 925 920
-3 921 920 926
-3 926 920 925
-3 921 926 773
-3 777 927 918
-3 777 568 927
-3 932 1115 573
-3 922 928 929
-3 938 923 929
-3 929 923 922
-3 931 927 568
-3 1121 927 931
-3 1301 1132 760
-3 929 928 933
-3 933 938 929
-3 780 787 1121
-3 780 1121 931
-3 1121 787 1126
-3 783 934 935
-3 782 934 783
-3 935 781 783
-3 936 781 935
-3 937 928 789
-3 938 933 937
-3 937 933 928
-3 782 943 934
-3 788 943 782
-3 936 788 781
-3 943 788 936
-3 937 789 790
-3 937 790 938
-3 944 945 791
-3 792 939 945
-3 794 939 792
-3 940 939 794
-3 787 578 1126
-3 941 578 795
-3 942 941 795
-3 795 803 1128
-3 795 1128 942
-3 791 577 947
-3 791 947 948
-3 791 948 944
-3 948 1137 949
-3 948 949 944
-3 944 949 945
-3 945 949 801
-3 952 932 573
-3 577 950 947
-3 950 953 947
-3 801 949 1137
-3 801 1137 953
-3 805 1128 598
-3 932 952 1141
-3 938 790 814
-3 802 954 951
-3 951 954 809
-3 956 812 811
-3 1140 813 812
-3 809 957 817
-3 954 957 809
-3 819 958 959
-3 818 958 819
-3 959 960 819
-3 962 955 961
-3 963 956 964
-3 963 961 956
-3 961 955 956
-3 811 964 956
-3 811 822 964
-3 822 1140 964
-3 1140 822 813
-3 824 969 831
-3 664 1141 952
-3 1144 958 624
-3 958 818 624
-3 961 965 962
-3 963 965 961
-3 967 968 823
-3 968 969 824
-3 831 969 970
-3 970 971 831
-3 831 971 839
-3 833 832 972
-3 832 1366 972
-3 930 698 442
-3 1144 624 975
-3 960 975 835
-3 1144 975 960
-3 976 967 966
-3 977 968 967
-3 969 968 977
-3 970 969 978
-3 978 969 977
-3 1155 971 978
-3 978 971 970
-3 979 971 1155
-3 839 971 979
-3 839 980 841
-3 979 980 839
-3 841 980 989
-3 643 1366 832
-3 972 981 833
-3 981 843 833
-3 982 983 844
-3 844 984 846
-3 983 984 844
-3 846 984 847
-3 624 985 975
-3 975 985 835
-3 849 987 836
-3 986 987 849
-3 836 987 850
-3 994 977 967
-3 978 977 994
-3 851 988 978
-3 851 978 994
-3 1155 978 988
-3 1155 852 979
-3 1155 988 852
-3 853 979 852
-3 980 979 853
-3 854 980 853
-3 854 989 980
-3 1382 1366 677
-3 1366 643 677
-3 1382 677 981
-3 843 981 677
-3 996 664 387
-3 693 1154 1365
-3 855 991 856
-3 990 991 855
-3 856 982 844
-3 856 991 982
-3 991 992 982
-3 845 992 857
-3 845 983 992
-3 983 982 992
-3 847 983 845
-3 984 983 847
-3 987 986 849
-3 993 967 976
-3 994 967 993
-3 989 854 1165
-3 854 691 1165
-3 995 989 1165
-3 997 998 1161
-3 996 997 1161
-3 698 930 707
-3 990 859 999
-3 991 990 999
-3 862 1001 863
-3 862 994 1001
-3 994 993 1001
-3 691 1002 1165
-3 995 1002 864
-3 1002 691 864
-3 998 997 870
-3 1161 998 1003
-3 1004 1161 1003
-3 1005 1161 1004
-3 693 1169 1187
-3 1365 1169 693
-3 860 1006 1000
-3 860 1000 1007
-3 1000 1006 1007
-3 1007 865 860
-3 1001 993 1009
-3 1009 993 1008
-3 1001 1009 863
-3 1011 868 1010
-3 1011 1179 868
-3 1179 869 868
-3 1179 1012 869
-3 1013 998 870
-3 1003 998 1014
-3 1014 998 1013
-3 1004 1003 1014
-3 1005 1004 877
-3 1015 1005 877
-3 878 1005 1015
-3 1162 1005 878
-3 1162 878 1163
-3 1163 878 1021
-3 1007 1006 1018
-3 1018 1006 880
-3 865 1007 1018
-3 873 871 1189
-3 871 1188 1189
-3 873 1189 1019
-3 1010 875 884
-3 868 875 1010
-3 876 1011 1010
-3 876 1010 884
-3 869 1020 876
-3 1020 1011 876
-3 1012 1020 869
-3 1015 877 878
-3 1016 1022 879
-3 885 1016 879
-3 1017 1016 885
-3 885 1023 1017
-3 871 881 1024
-3 871 1024 1025
-3 871 1025 1188
-3 873 1026 882
-3 873 1019 1026
-3 1028 1029 1027
-3 1030 1032 1033
-3 1031 1032 1030
-3 1022 1046 879
-3 881 886 1034
-3 881 1034 1024
-3 1034 1035 1024
-3 1024 1036 1025
-3 1024 1035 1036
-3 1036 1196 1025
-3 1036 1026 1196
-3 1036 887 1026
-3 882 1026 887
-3 1027 1037 1028
-3 1029 1037 1027
-3 888 1202 889
-3 1038 888 889
-3 1039 1031 1030
-3 1205 1031 1039
-3 1033 890 1039
-3 1033 1039 1030
-3 1033 1032 1040
-3 1033 1040 732
-3 887 1034 886
-3 1035 1034 887
-3 1036 1035 887
-3 888 1204 1202
-3 1204 888 1038
-3 1205 1039 890
-3 1205 890 895
-3 741 732 1040
-3 1041 524 896
-3 1427 895 745
-3 1040 1427 745
-3 741 1040 746
-3 1022 1210 1046
-3 902 747 707
-3 898 1045 1042
-3 896 898 1042
-3 896 1042 1041
-3 1043 1044 900
-3 1045 900 1044
-3 1045 898 900
-3 1050 899 1046
-3 1043 900 1047
-3 900 901 1047
-3 1049 1046 1048
-3 1050 1046 1049
-3 1433 899 1050
-3 1217 1051 390
-3 1049 1048 1220
-3 1225 1222 1051
-3 1051 1222 1052
-3 1047 903 1215
-3 903 1052 1223
-3 1055 1053 1056
-3 1056 1053 1060
-3 1058 1053 1055
-3 1056 1058 1055
-3 1060 1057 1056
-3 1058 1056 1057
-3 1058 1057 1059
-3 1059 1057 1060
-3 1059 1062 1058
-3 905 1059 1060
-3 904 1061 1062
-3 905 904 1062
-3 905 1062 1059
-3 905 1063 906
-3 905 1060 1063
-3 1060 1238 1063
-3 906 1061 904
-3 906 1063 1061
-3 1063 1064 1061
-3 1064 1062 1061
-3 1238 1064 1063
-3 1065 1237 1066
-3 1067 1066 1237
-3 1238 1067 1237
-3 1067 1238 1068
-3 1066 1067 1070
-3 1070 1067 1068
-3 1238 1239 1069
-3 1238 1069 1068
-3 1070 1068 1069
-3 1072 1066 1070
-3 1242 1069 1239
-3 1070 1069 1071
-3 1071 1069 1242
-3 1072 1070 1071
-3 1071 1242 1073
-3 1072 1071 1073
-3 1073 1242 1074
-3 1072 1073 1076
-3 1076 1073 1074
-3 1076 1074 1075
-3 1074 1242 1077
-3 907 1075 1077
-3 1075 1074 1077
-3 907 1078 1076
-3 907 1076 1075
-3 907 1081 908
-3 1077 1081 907
-3 907 908 1078
-3 908 1081 1080
-3 908 1080 1078
-3 1078 1080 1079
-3 1472 1082 1081
-3 1243 1079 1080
-3 1081 1243 1080
-3 1082 1243 1081
-3 1084 1082 1083
-3 1084 1083 1085
-3 1085 1083 1086
-3 1086 1084 1085
-3 1087 1084 1086
-3 1088 1084 1087
-3 1087 1089 1088
-3 1088 1089 1090
-3 1090 1091 1088
-3 1089 1091 1090
-3 1094 1093 1092
-3 1095 1092 1093
-3 909 1095 1093
-3 1098 1097 1099
-3 1102 1251 1096
-3 1100 1097 1098
-3 1504 1100 1098
-3 910 1100 911
-3 910 1099 1100
-3 1099 1097 1100
-3 1099 910 1101
-3 910 912 1101
-3 1504 911 1100
-3 534 1258 1256
-3 1095 914 1259
-3 1504 762 911
-3 1259 914 1105
-3 1101 912 764
-3 1263 1259 1105
-3 1102 1106 1104
-3 1104 1106 1107
-3 1258 759 4237
-3 1112 1263 1105
-3 1109 1107 1108
-3 1108 1107 1106
-3 915 916 1105
-3 916 1112 1105
-3 1110 1109 1108
-3 916 573 1111
-3 1112 916 1111
-3 1108 1114 1110
-3 1110 1114 1113
-3 573 1268 1111
-3 1268 1112 1111
-3 1114 1270 1113
-3 760 1511 2369
-3 1115 1268 573
-3 1288 917 1116
-3 1276 1115 1290
-3 919 917 1118
-3 917 1288 1118
-3 1116 917 1117
-3 1118 928 919
-3 917 923 1117
-3 1532 927 1119
-3 1290 1115 932
-3 1117 923 938
-3 1121 1119 927
-3 1120 1290 932
-3 1122 1119 1121
-3 1122 1123 1119
-3 1123 1124 1292
-3 1119 1123 1292
-3 1124 942 1292
-3 935 934 1125
-3 935 1125 936
-3 1297 1120 932
-3 928 1118 789
-3 1126 1122 1121
-3 1123 1122 1127
-3 1127 1122 1126
-3 941 1124 1127
-3 1124 1123 1127
-3 942 1124 941
-3 942 1128 1292
-3 1129 1130 1131
-3 1131 1130 1132
-3 934 943 1125
-3 936 1125 943
-3 1133 1134 1135
-3 1135 1136 1133
-3 1297 932 1141
-3 1118 1311 789
-3 1127 1126 578
-3 941 1127 578
-3 1129 805 1132
-3 1130 1129 1132
-3 1133 1315 1134
-3 1136 1315 1133
-3 948 947 1137
-3 1298 1141 1318
-3 1311 946 789
-3 947 953 1137
-3 423 893 470
-3 1142 1318 1141
-3 1143 1318 1142
-3 946 1311 599
-3 956 955 1138
-3 1138 1139 956
-3 956 1140 812
-3 1139 1140 956
-3 959 958 1144
-3 959 1144 960
-3 1138 962 1145
-3 955 962 1138
-3 964 1145 963
-3 964 1139 1145
-3 1139 1138 1145
-3 1140 1139 964
-3 1142 1141 1146
-3 1147 1142 1146
-3 1143 1142 1147
-3 1148 1143 1147
-3 1323 1148 1353
-3 962 965 1145
-3 963 1145 965
-3 974 973 1577
-3 1577 1150 974
-3 664 1151 1141
-3 1151 1146 1141
-3 1147 1146 1151
-3 1152 1147 1151
-3 1148 1147 1152
-3 1153 1148 1152
-3 1160 1148 1153
-3 1353 1148 1160
-3 1149 1343 1154
-3 974 1156 973
-3 974 1157 1156
-3 1157 1150 1158
-3 1157 974 1150
-3 1153 1152 1151
-3 1160 1153 1159
-3 1354 1353 1160
-3 1365 1154 1343
-3 1166 1382 981
-3 664 996 1151
-3 1153 1151 996
-3 1159 1153 996
-3 996 1160 1159
-3 1161 1160 996
-3 1354 1160 1161
-3 1354 1161 1162
-3 1005 1162 1161
-3 1373 1162 1163
-3 1168 1163 1167
-3 1359 1168 1175
-3 1377 1164 1169
-3 707 930 5643
-3 995 1165 1002
-3 1171 1172 1170
-3 1167 1163 1173
-3 1168 1167 1174
-3 1174 1167 1173
-3 1183 1168 1174
-3 1175 1168 1183
-3 1184 1175 1183
-3 1164 1176 1177
-3 1169 1164 1178
-3 1178 1164 1177
-3 1186 1169 1178
-3 1187 1169 1186
-3 1172 1180 1170
-3 1173 1163 1021
-3 1021 1174 1173
-3 1185 1016 1176
-3 1177 1176 1016
-3 1017 1177 1016
-3 1178 1177 1017
-3 1017 1186 1178
-3 1179 1011 1020
-3 1012 1179 1020
-3 1193 1182 1181
-3 1409 1194 1181
-3 1194 1193 1181
-3 1021 1183 1174
-3 1184 1183 1195
-3 1195 1183 1021
-3 1016 1185 1022
-3 1022 1185 1415
-3 1023 1186 1017
-3 1187 1186 1023
-3 1188 1025 1196
-3 1019 1196 1026
-3 1019 1189 1196
-3 1189 1188 1196
-3 1028 1197 1029
-3 1190 1198 1191
-3 1192 1198 1190
-3 1193 1205 1182
-3 1031 1205 1193
-3 1031 1193 1194
-3 1194 1409 1199
-3 1194 1199 1031
-3 1031 1199 1032
-3 524 1195 1021
-3 524 1413 1195
-3 1200 1022 1201
-3 1201 1022 1415
-3 1028 1037 1197
-3 1029 1197 1037
-3 1202 1203 889
-3 1038 1203 1204
-3 1038 889 1203
-3 1206 1040 1032
-3 1206 1032 1199
-3 524 1041 1413
-3 1207 1413 1208
-3 1208 1413 1041
-3 1201 1207 1208
-3 1201 1208 1200
-3 1200 1208 1209
-3 1200 1209 1022
-3 1205 895 1427
-3 1206 1427 1040
-3 1210 1208 1041
-3 1209 1208 1210
-3 1022 1209 1210
-3 1041 1042 1211
-3 1041 1211 1210
-3 1210 1211 1046
-3 1433 892 899
-3 1044 1043 1212
-3 1212 1213 1044
-3 1044 1214 1045
-3 1213 1214 1044
-3 1045 1211 1042
-3 1045 1214 1211
-3 1046 1211 1048
-3 1047 1212 1043
-3 1047 1215 1212
-3 1215 1213 1212
-3 1214 1213 1216
-3 1216 1213 1215
-3 1211 1214 1216
-3 1216 1215 1218
-3 1211 1216 1219
-3 1219 1216 1218
-3 1048 1211 1220
-3 1211 1219 1220
-3 1049 1433 1050
-3 1217 1221 1051
-3 1051 1221 1225
-3 1215 903 1223
-3 1218 1215 1223
-3 1219 1218 1223
-3 1220 1219 1224
-3 1224 1219 1223
-3 1893 1433 1049
-3 1893 1049 1224
-3 1224 1049 1220
-3 902 707 5643
-3 1217 1632 1221
-3 1221 1632 1225
-3 1893 1224 1223
-3 1632 1052 1225
-3 1225 1052 1222
-3 902 5643 1226
-3 1229 1227 1230
-3 1234 1229 1230
-3 1227 1231 1230
-3 1234 1230 1232
-3 1232 1230 1231
-3 1232 1231 1233
-3 1234 1232 1233
-3 1233 1231 1235
-3 1234 1233 1236
-3 1236 1233 1235
-3 1235 1231 1469
-3 1054 1469 1053
-3 1054 1236 1469
-3 1236 1235 1469
-3 1054 1053 1234
-3 1054 1234 1236
-3 1053 1469 1060
-3 1234 1053 1058
-3 1058 1062 1234
-3 1238 1060 1469
-3 1062 1064 1234
-3 1234 1064 1663
-3 1064 1237 1663
-3 1238 1237 1064
-3 1237 1065 1066
-3 1237 1066 1663
-3 1066 1072 1663
-3 1241 1240 1239
-3 1242 1239 1240
-3 1241 1242 1240
-3 1472 1242 1241
-3 1470 1472 1241
-3 1072 1076 1079
-3 1242 1472 1077
-3 1077 1472 1081
-3 1076 1078 1079
-3 1472 1473 1082
-3 1473 1083 1082
-3 1475 1083 1473
-3 1082 1084 1243
-3 1243 1084 1244
-3 1086 1083 1475
-3 1476 1086 1475
-3 1086 1476 1087
-3 1084 1088 1244
-3 1089 1087 1476
-3 1244 1088 1091
-3 1089 1476 1246
-3 1249 1089 1246
-3 1089 1249 1091
-3 1245 1247 1248
-3 1245 1248 1092
-3 1245 1092 1503
-3 1091 1249 1250
-3 1091 1250 1244
-3 1248 1094 1092
-3 1096 1246 1489
-3 1249 1246 1096
-3 1251 1249 1096
-3 1251 1250 1249
-3 1251 1244 1250
-3 1262 1244 1251
-3 1099 1252 1098
-3 1099 1487 1252
-3 1095 1503 1092
-3 1102 1096 1489
-3 1499 1102 1489
-3 1098 1252 1253
-3 1967 1487 1101
-3 1487 1099 1101
-3 1098 1253 1504
-3 1255 1254 1257
-3 1257 1254 1256
-3 1258 1500 1255
-3 1257 1258 1255
-3 1505 1102 1499
-3 1103 534 1502
-3 1256 1502 534
-3 1258 1257 1256
-3 1259 1503 1095
-3 1505 1508 1102
-3 1094 423 1093
-3 1251 1102 1262
-3 1967 1101 764
-3 1102 1104 1262
-3 1260 1259 1263
-3 1506 1259 1260
-3 1093 423 756
-3 1508 1261 1106
-3 1102 1508 1106
-3 1104 1107 1262
-3 1263 1112 1264
-3 1260 1263 1265
-3 1265 1263 1264
-3 1260 1512 1506
-3 1261 1108 1106
-3 1109 1262 1107
-3 1264 1112 1266
-3 1265 1264 1267
-3 1267 1264 1266
-3 1260 1265 1267
-3 1273 1260 1267
-3 1512 1260 1273
-3 1109 1110 1262
-3 1268 1266 1112
-3 1268 1267 1266
-3 1273 1267 1268
-3 1114 1108 1269
-3 1262 1110 1271
-3 1110 1113 1271
-3 1103 1511 760
-3 1272 1512 1273
-3 1270 1271 1113
-3 1114 1269 1275
-3 1114 1275 1271
-3 1114 1271 1270
-3 1274 1517 1518
-3 1517 1274 1269
-3 1275 1269 1274
-3 1272 1273 1278
-3 1276 1272 1278
-3 1277 1275 1274
-3 1279 1280 1277
-3 1115 1273 1268
-3 1115 1278 1273
-3 1284 1279 1281
-3 1282 1280 1279
-3 1284 1282 1279
-3 1115 1276 1278
-3 1284 1281 1283
-3 1286 1282 1284
-3 1285 1283 1281
-3 1284 1283 1286
-3 1286 1283 1285
-3 1287 1285 1281
-3 1287 1286 1285
-3 1289 1276 1290
-3 1525 1288 1287
-3 918 1740 764
-3 1287 1288 1116
-3 918 927 1740
-3 927 1531 1740
-3 1525 1533 1118
-3 1525 1118 1288
-3 1287 1116 1117
-3 1531 927 1532
-3 2369 1301 760
-3 1773 1289 1291
-3 1292 1532 1119
-3 1293 1290 1120
-3 1289 1290 1293
-3 1291 1289 1293
-3 1773 1291 1300
-3 1300 1291 1294
-3 1533 1296 1118
-3 1120 1297 1293
-3 1291 1293 1298
-3 1298 1293 1297
-3 1294 1291 1299
-3 1299 1291 1298
-3 1300 1294 1302
-3 1302 1294 1299
-3 1296 1295 1535
-3 1118 1296 1535
-3 1287 1117 814
-3 1303 1300 1302
-3 1304 1300 1303
-3 1300 1304 1305
-3 1118 1535 1311
-3 1129 1301 805
-3 1131 1301 1129
-3 1132 1301 1131
-3 1135 1134 1538
-3 1135 1538 1136
-3 1298 1297 1141
-3 1302 1299 1308
-3 1308 1299 1298
-3 1303 1302 1309
-3 1309 1302 1308
-3 1304 1303 1309
-3 1305 1304 1310
-3 1310 1304 1309
-3 1312 1311 1535
-3 938 814 1117
-3 1307 1313 1306
-3 1313 1307 1314
-3 1315 1541 1134
-3 1538 1134 1541
-3 1315 1136 1316
-3 1316 1136 1538
-3 1538 1317 1316
-3 1318 1308 1298
-3 1309 1308 1318
-3 1321 1541 1315
-3 1316 1319 1315
-3 1319 1316 1317
-3 1320 1309 1318
-3 1310 1309 1320
-3 1801 599 1311
-3 1321 1315 1322
-3 1315 1319 1322
-3 1322 1319 1317
-3 1318 1143 1320
-3 1310 1320 1323
-3 1323 1320 1143
-3 1324 1310 1323
-3 599 1801 1154
-3 1323 1143 1148
-3 1325 1324 1323
-3 1326 1324 1325
-3 1329 1801 1328
-3 1154 1801 1149
-3 1149 1801 1329
-3 1330 1331 1332
-3 1330 1333 1334
-3 1332 1333 1330
-3 1325 1323 1353
-3 1326 1325 1336
-3 1336 1325 1335
-3 1324 1326 1337
-3 1337 1326 1336
-3 1338 1324 1337
-3 1542 1324 1338
-3 1342 1327 1362
-3 1364 1327 1342
-3 1328 1327 1364
-3 1329 1328 1343
-3 1149 1329 1343
-3 1344 1331 1330
-3 1345 1331 1344
-3 1334 1346 1330
-3 1346 1344 1330
-3 1347 1577 973
-3 1150 1348 1349
-3 1150 1577 1348
-3 1348 1350 1349
-3 1335 1325 1353
-3 1336 1335 1353
-3 1337 1336 1354
-3 1354 1336 1353
-3 1338 1337 1354
-3 1355 1338 1354
-3 1566 1338 1355
-3 1566 1355 1356
-3 1357 1339 1340
-3 1341 1339 1358
-3 1358 1339 1357
-3 1341 1358 1561
-3 1563 1359 1360
-3 1342 1362 1363
-3 1364 1342 1363
-3 1328 1364 1365
-3 1343 1328 1365
-3 1346 1345 1344
-3 1156 1157 1367
-3 1156 1367 1347
-3 1156 1347 973
-3 1367 1157 1158
-3 1367 1158 1368
-3 1349 1158 1150
-3 1349 1369 1158
-3 1369 1368 1158
-3 1350 1369 1349
-3 1351 1369 1350
-3 1351 1352 1370
-3 1371 1370 1352
-3 1355 1354 1162
-3 1372 1356 1355
-3 1162 1372 1355
-3 1374 1373 1357
-3 1358 1357 1163
-3 1163 1357 1373
-3 1561 1358 1168
-3 1168 1358 1163
-3 1562 1561 1168
-3 1359 1562 1168
-3 1360 1359 1375
-3 1362 1361 1377
-3 1377 1361 1376
-3 1363 1362 1377
-3 1169 1363 1377
-3 1365 1363 1169
-3 1364 1363 1365
-3 1382 1378 1366
-3 981 1383 1166
-3 1384 1351 1370
-3 1371 1379 1370
-3 1379 1384 1370
-3 1379 1371 1380
-3 1162 1381 1372
-3 1162 1373 1381
-3 1374 1381 1373
-3 1359 1175 1375
-3 1377 1376 1164
-3 1166 1383 1382
-3 1380 1384 1379
-3 1171 1170 1385
-3 1171 1385 1172
-3 1175 1388 1389
-3 1609 1175 1389
-3 1164 1389 1388
-3 1176 1164 1388
-3 1170 1180 1385
-3 1172 1385 1180
-3 1390 1392 1393
-3 1392 1613 1393
-3 1181 1182 1394
-3 1386 1395 1387
-3 1396 1398 1399
-3 1397 1398 1396
-3 1175 1184 1413
-3 1388 1175 1400
-3 1400 1175 1413
-3 1176 1400 1185
-3 1388 1400 1176
-3 1401 1190 1191
-3 1401 1402 1190
-3 1192 1190 1403
-3 1403 1190 1402
-3 1391 1403 1402
-3 1391 1390 1403
-3 1390 1404 1403
-3 1404 1390 1393
-3 1613 1405 1393
-3 1405 1406 1407
-3 1613 1406 1405
-3 1394 1182 1408
-3 1181 1394 1409
-3 1394 1408 1409
-3 1396 1399 1410
-3 1411 1410 1399
-3 1411 1399 1412
-3 1184 1195 1413
-3 1414 1400 1413
-3 1414 1185 1400
-3 1414 1415 1185
-3 1191 1416 1401
-3 1191 1198 1416
-3 1403 1416 1192
-3 1192 1416 1198
-3 1404 1416 1403
-3 1417 1405 1407
-3 1182 1205 1408
-3 1205 1419 1408
-3 1419 1409 1408
-3 1409 1419 1199
-3 1420 1396 1410
-3 1411 1421 1410
-3 1421 1411 1412
-3 1414 1413 1430
-3 1415 1629 1201
-3 1422 1423 1424
-3 1424 1425 1422
-3 1203 1202 1418
-3 1202 1631 1418
-3 1418 1426 1203
-3 1418 1625 1426
-3 1203 1426 1204
-3 1205 1427 1419
-3 1427 1199 1419
-3 1199 1427 1206
-3 1410 1428 1420
-3 1428 1410 1429
-3 1410 1421 1429
-3 1429 1421 1432
-3 1207 1430 1413
-3 1201 1629 1207
-3 1629 1430 1207
-3 1433 814 892
-3 1422 1431 1423
-3 1425 1431 1422
-3 1426 1631 1202
-3 1204 1426 1202
-3 1429 1432 1428
-3 1632 1217 893
-3 1226 2516 2917
-3 1052 1632 1633
-3 1435 1436 1437
-3 1434 1435 1437
-3 1435 1434 1438
-3 1436 1435 1438
-3 1437 1436 1439
-3 1439 1436 1438
-3 1434 1638 1438
-3 1441 1437 1439
-3 1445 1438 1638
-3 1439 1438 1445
-3 1440 1441 1439
-3 1638 1639 1445
-3 1441 1440 1442
-3 1448 1441 1444
-3 1444 1441 1442
-3 1440 1439 1445
-3 1442 1440 1445
-3 1444 1442 1443
-3 1443 1442 1446
-3 1446 1442 1445
-3 1444 1443 1447
-3 1447 1443 1446
-3 1448 1444 1447
-3 1446 1445 1645
-3 1449 1447 1446
-3 1451 1448 1447
-3 1449 1451 1447
-3 1645 1647 1446
-3 1450 1446 1647
-3 1449 1446 1450
-3 1451 1449 1450
-3 1647 1452 1450
-3 1451 1450 1453
-3 1453 1450 1452
-3 1453 1454 1451
-3 1452 1648 1455
-3 1452 1455 1453
-3 1456 1454 1453
-3 1456 1453 1455
-3 1648 1457 1455
-3 1455 1457 1456
-3 1457 1458 1456
-3 1457 1654 1458
-3 1654 1459 1458
-3 1653 1654 1460
-3 1461 1460 1654
-3 1461 1462 1460
-3 1461 1463 1462
-3 1462 1463 1460
-3 1464 1460 1463
-3 1463 1466 1464
-3 1465 1466 1463
-3 1659 1467 1465
-3 1465 1467 1466
-3 1228 1227 1468
-3 1228 1468 1466
-3 1228 1466 1467
-3 1468 1227 1229
-3 1467 1659 1228
-3 1228 1659 1227
-3 1234 1468 1229
-3 1227 1659 1231
-3 1234 4051 1468
-3 1469 1231 1662
-3 1238 1469 1664
-3 1238 1664 1239
-3 1664 1666 1239
-3 1239 1666 1241
-3 1241 1666 1470
-3 1072 1079 1663
-3 1471 1470 1666
-3 1663 1079 1243
-3 1471 1670 1470
-3 1470 1670 1472
-3 1673 1472 1670
-3 1473 1472 1673
-3 1475 1473 1474
-3 1243 1244 1663
-3 1674 1474 1473
-3 1474 1674 1475
-3 1475 1674 1476
-3 1476 1477 1246
-3 1476 1480 1477
-3 1480 1481 1477
-3 1477 1481 1246
-3 1486 1482 1478
-3 1483 1478 1482
-3 1247 1493 1248
-3 1247 1479 1493
-3 1245 1479 1247
-3 1481 1480 1484
-3 1481 1484 1246
-3 1485 1482 1486
-3 1483 1482 1487
-3 1487 1482 1485
-3 1487 1967 1483
-3 1248 1493 1094
-3 1245 1503 1694
-3 1489 1480 1488
-3 1246 1484 1489
-3 1484 1480 1489
-3 1252 1485 1486
-3 1252 1486 1504
-3 1487 1485 1252
-3 1490 1491 1492
-3 1494 1490 1492
-3 1492 1491 1693
-3 1697 1094 1493
-3 1701 1694 1503
-3 1252 1504 1253
-3 1490 1494 1496
-3 1496 1494 1495
-3 1491 1490 1497
-3 1497 1490 1496
-3 1497 1693 1491
-3 1498 1499 1488
-3 1488 1499 1489
-3 1256 1254 1502
-3 1502 1255 1494
-3 1502 1254 1255
-3 1500 1494 1255
-3 1500 1495 1494
-3 1496 1495 1501
-3 1501 1495 1500
-3 1501 1497 1496
-3 1705 1499 1498
-3 1500 1258 1501
-3 2278 1497 1501
-3 1705 1712 1499
-3 1499 1712 1505
-3 1258 2278 1501
-3 1697 423 1094
-3 1503 1259 1506
-3 1258 4237 2278
-3 1712 1507 1261
-3 1505 1712 1261
-3 1508 1505 1261
-3 1512 1503 1506
-3 1719 1503 1512
-3 2686 1967 764
-3 1103 1978 1511
-3 1507 1509 1510
-3 1261 1507 1513
-3 1513 1507 1510
-3 1108 1261 1513
-3 1514 1512 1515
-3 1513 1510 1721
-3 1108 1513 1269
-3 1262 1271 1519
-3 1511 1724 2369
-3 1272 1515 1512
-3 1513 1721 1269
-3 1272 1276 1515
-3 1721 1516 1518
-3 1269 1721 1517
-3 1517 1721 1518
-3 1514 1515 1276
-3 1271 1275 1519
-3 1518 1277 1274
-3 1277 1519 1275
-3 1731 1514 1276
-3 1518 1516 1520
-3 1279 1518 1520
-3 1277 1518 1279
-3 1277 1280 1519
-3 1519 1280 1524
-3 2686 764 1740
-3 1279 1520 1281
-3 1280 1282 1524
-3 1289 1731 1276
-3 1520 1521 1522
-3 1281 1520 1523
-3 1282 1286 1524
-3 1521 1735 1522
-3 1523 1520 1522
-3 4845 930 762
-3 1523 1522 1525
-3 1281 1523 1287
-3 1287 1523 1525
-3 1287 1524 1286
-3 1773 2021 1289
-3 1526 1529 1528
-3 1527 1530 1526
-3 1530 1529 1526
-3 1522 2034 1525
-3 1530 1528 1529
-3 1533 1525 2034
-3 1292 1531 1532
-3 1128 1531 1292
-3 1753 1300 1534
-3 1533 1776 1535
-3 1296 1533 1295
-3 1301 1128 805
-3 1774 1534 1779
-3 1776 1788 1535
-3 1295 1533 1535
-3 1305 1534 1300
-3 1310 1534 1305
-3 1779 1534 1310
-3 1542 1779 1310
-3 1535 1788 1312
-3 1797 1536 1306
-3 1307 1306 1536
-3 1537 1307 1536
-3 1789 1542 1790
-3 1306 1313 1806
-3 1797 1306 1806
-3 1307 1537 1314
-3 1537 1540 1314
-3 1542 1310 1324
-3 1539 1790 1542
-3 1312 1801 1311
-3 1287 814 4422
-3 1313 1810 1806
-3 1313 1540 1810
-3 1314 1540 1313
-3 1538 1811 1317
-3 1783 1539 1542
-3 1543 1783 1542
-3 1545 1328 1808
-3 1799 1545 1808
-3 1317 1811 1322
-3 1811 1546 1322
-3 1543 1542 1547
-3 1548 1543 1547
-3 1560 1549 1544
-3 1562 1544 1549
-3 1563 1544 1562
-3 1550 1544 1563
-3 1545 1550 1327
-3 1328 1545 1327
-3 1551 1552 1553
-3 1551 1553 1554
-3 1553 1555 1554
-3 1322 1546 1321
-3 1547 1542 1556
-3 1557 1547 1556
-3 1548 1547 1558
-3 1558 1547 1557
-3 1339 1548 1558
-3 1815 1548 1339
-3 1341 1815 1339
-3 1341 1559 1560
-3 1815 1341 1560
-3 1560 1559 1549
-3 1549 1559 1561
-3 1562 1549 1561
-3 1327 1550 1563
-3 1332 1823 1564
-3 1331 1823 1332
-3 1552 1551 1333
-3 1552 1333 1564
-3 1564 1333 1332
-3 1334 1333 1551
-3 1334 1551 1565
-3 1565 1551 1554
-3 1565 1554 1555
-3 1348 1817 1351
-3 1817 1578 1351
-3 1556 1542 1338
-3 1566 1556 1338
-3 1557 1556 1566
-3 1566 1558 1557
-3 1339 1558 1567
-3 1567 1558 1566
-3 1339 1567 1340
-3 1559 1341 1561
-3 1359 1563 1562
-3 1327 1563 1362
-3 1569 1570 1568
-3 1571 1823 1345
-3 1823 1331 1345
-3 1565 1572 1573
-3 1565 1573 1334
-3 1334 1573 1346
-3 1555 1572 1565
-3 1574 1575 1366
-3 1366 1575 972
-3 1575 981 972
-3 1576 1577 1347
-3 1350 1348 1351
-3 1351 1578 1352
-3 1356 1579 1566
-3 1579 1567 1566
-3 1340 1579 1357
-3 1567 1579 1340
-3 1361 1563 1360
-3 1362 1563 1361
-3 1580 1569 1568
-3 1847 1569 1580
-3 1581 1568 1570
-3 1580 1568 1581
-3 1571 1345 1830
-3 1345 1346 1830
-3 1830 1346 1573
-3 1850 981 1575
-3 1347 1367 1576
-3 1367 1368 1576
-3 1369 1582 1368
-3 1368 1582 1576
-3 1582 1369 1351
-3 1352 1578 1834
-3 1371 1352 1834
-3 1583 1585 1586
-3 1584 1585 1583
-3 1579 1587 1841
-3 1579 1356 1587
-3 1356 1372 1587
-3 1841 1357 1579
-3 1841 1595 1357
-3 1595 1374 1357
-3 1360 1588 1589
-3 1375 1588 1360
-3 1361 1360 1590
-3 1360 1589 1590
-3 1590 1376 1361
-3 1581 1847 1580
-3 1383 1850 1597
-3 981 1850 1383
-3 1351 1384 1582
-3 1591 1380 1834
-3 1380 1371 1834
-3 1583 1592 1593
-3 1583 1586 1592
-3 1592 1586 1585
-3 1594 1372 1381
-3 1594 1587 1372
-3 1595 1594 1374
-3 1595 1596 1594
-3 1594 1381 1374
-3 1375 1175 1588
-3 1588 1175 1874
-3 1376 1590 1164
-3 1383 1597 1382
-3 1382 1597 1378
-3 1380 1591 1384
-3 1598 1593 1592
-3 1870 1599 1592
-3 1599 1598 1592
-3 1600 1587 1594
-3 1596 1601 1594
-3 1601 1600 1594
-3 1602 1596 1595
-3 1602 1601 1596
-3 1874 1175 1609
-3 1604 1593 1598
-3 1614 1593 1604
-3 1386 1387 1604
-3 1386 1604 1599
-3 1599 1604 1598
-3 1599 1870 1386
-3 1870 1605 1386
-3 1600 1601 1606
-3 1602 1607 1601
-3 1607 1606 1601
-3 1880 1608 1602
-3 1608 1607 1602
-3 1610 1611 1609
-3 1610 1609 1389
-3 1389 1612 1610
-3 1389 1164 1612
-3 1164 1590 1612
-3 1603 1392 1391
-3 1391 1392 1390
-3 1392 1619 1613
-3 1392 1603 1619
-3 1387 1614 1604
-3 1387 1395 1614
-3 1395 1876 1614
-3 1605 1395 1386
-3 1876 1395 1605
-3 1397 1606 1607
-3 1398 1397 1607
-3 1608 1398 1607
-3 1608 1880 1398
-3 1398 1880 1399
-3 1615 1611 1610
-3 1616 1611 1615
-3 1617 1610 1612
-3 1615 1610 1617
-3 1402 1401 1618
-3 1402 1618 1391
-3 1613 1619 1406
-3 1619 1407 1406
-3 1396 1620 1397
-3 1399 1880 1412
-3 1880 1621 1412
-3 1414 1616 1615
-3 1415 1622 1623
-3 1414 1622 1415
-3 1414 1617 1622
-3 1414 1615 1617
-3 1401 1624 1618
-3 1401 1416 1624
-3 1416 1404 1624
-3 1393 1624 1404
-3 1405 1624 1393
-3 1405 1886 1624
-3 1619 1417 1407
-3 1619 1886 1417
-3 1886 1405 1417
-3 1625 1418 1626
-3 1418 1887 1626
-3 1627 1620 1420
-3 1620 1396 1420
-3 1627 1621 1888
-3 1421 1412 1621
-3 1628 1616 1430
-3 1616 1414 1430
-3 1623 1629 1415
-3 1623 1622 1629
-3 1424 1423 1630
-3 1424 1630 1425
-3 1625 1892 1631
-3 1625 1631 1426
-3 1626 1892 1625
-3 1420 1428 1627
-3 1428 1432 1627
-3 1432 1621 1627
-3 1621 1432 1421
-3 1628 1430 1891
-3 1430 1629 1891
-3 1423 1431 1630
-3 1425 1630 1431
-3 814 1433 1893
-3 1634 1636 1635
-3 1434 1437 1635
-3 1636 1637 1635
-3 1434 1635 1637
-3 1637 1903 1434
-3 1441 1635 1437
-3 1434 1903 1641
-3 1434 1641 1638
-3 1448 1635 1441
-3 1640 1638 1641
-3 1639 1638 1642
-3 1642 1638 1640
-3 1641 1642 1640
-3 1639 1642 1643
-3 1445 1639 1643
-3 1445 1643 1645
-3 1645 1643 1644
-3 1644 1643 1908
-3 1908 1649 1644
-3 1644 1649 1645
-3 1651 1448 1454
-3 1448 1451 1454
-3 1646 1645 1649
-3 1647 1645 1646
-3 1647 1648 1452
-3 1454 1456 1651
-3 1647 1646 1649
-3 1912 1648 1647
-3 1648 1909 1650
-3 1651 1456 1458
-3 1912 1647 1649
-3 1913 1650 1909
-3 1648 1650 1652
-3 1648 1652 1457
-3 1913 1914 1650
-3 1650 1914 1652
-3 1653 1651 1459
-3 1651 1458 1459
-3 1457 1652 1654
-3 1654 1653 1459
-3 1653 1460 1656
-3 1654 1652 1655
-3 1654 1655 1461
-3 1655 1652 1914
-3 1464 1656 1460
-3 1461 1655 1463
-3 1466 1656 1464
-3 1657 1658 1655
-3 1655 1658 1463
-3 1463 1658 1465
-3 1466 1468 1656
-3 1922 1658 1657
-3 1465 1658 1659
-3 1658 1922 1660
-3 1658 1660 1659
-3 1231 1660 1661
-3 1660 1231 1659
-3 1662 1231 1661
-3 4051 1234 1663
-3 1666 1664 1665
-3 1666 1665 1667
-3 1667 1665 1668
-3 1669 1666 1667
-3 1471 1666 1669
-3 1669 1667 1668
-3 1471 1669 1670
-3 1669 1668 1670
-3 1670 1668 1671
-3 1670 1671 1673
-3 1673 1671 1672
-3 1672 1951 1673
-3 1673 1951 1674
-3 1673 1674 1473
-3 1676 1677 1947
-3 1951 1954 1675
-3 1674 1951 1675
-3 1675 1954 1476
-3 1675 1476 1674
-3 1476 1954 1678
-3 1677 1676 1956
-3 1677 1956 1478
-3 1681 1679 1680
-3 1245 1681 1479
-3 1476 1678 1480
-3 1480 1678 1685
-3 1682 1677 1478
-3 1682 1955 1677
-3 1956 1486 1478
-3 1478 1483 1682
-3 1483 1967 1955
-3 1483 1955 1682
-3 1686 1687 1683
-3 1683 1687 1688
-3 1684 1683 1689
-3 1689 1683 1688
-3 1479 1681 1493
-3 1245 1694 1963
-3 1685 1965 1488
-3 1480 1685 1488
-3 1687 1686 1691
-3 1691 1686 1690
-3 1688 1687 1692
-3 1692 1687 1691
-3 1692 1689 1688
-3 1486 1956 1504
-3 2279 1494 1686
-3 1492 1686 1494
-3 1690 1686 1492
-3 1693 1690 1492
-3 1693 1691 1690
-3 1689 1692 1693
-3 1693 1692 1691
-3 1493 1681 1697
-3 1703 1695 1965
-3 1488 1965 1696
-3 1696 1965 1695
-3 1488 1696 1498
-3 1494 2279 1502
-3 1693 1497 2278
-3 1689 1693 2278
-3 1696 1695 1698
-3 1698 1695 1704
-3 1498 1696 1699
-3 1699 1696 1698
-3 1498 1699 1700
-3 1956 3036 1504
-3 1707 1694 1701
-3 1702 1694 1707
-3 1709 1694 1702
-3 1704 1695 1703
-3 1969 1698 1704
-3 1699 1698 1969
-3 1970 1699 1969
-3 1970 1705 1699
-3 1699 1705 1700
-3 1700 1705 1498
-3 1701 1503 1706
-3 1707 1701 1706
-3 1702 1707 1708
-3 1709 1702 1711
-3 1711 1702 1708
-3 1703 1710 1704
-3 1710 1969 1704
-3 1705 1970 1971
-3 1708 1707 1711
-3 1711 1707 1706
-3 1972 1709 1711
-3 1705 1971 1712
-3 1503 1711 1706
-3 1972 1711 1713
-3 1968 1985 1710
-3 1712 1985 1507
-3 1712 1710 1985
-3 1719 1711 1503
-3 1714 1711 1719
-3 1713 1711 1714
-3 1972 1713 1714
-3 1983 1972 1714
-3 1504 3036 762
-3 3634 1978 1103
-3 1719 1512 1514
-3 1983 1714 1719
-3 1985 1509 1507
-3 1509 1985 1715
-3 1718 1715 1717
-3 1715 1718 1509
-3 1509 1718 1510
-3 4845 762 3036
-3 1724 1511 1716
-3 1983 1719 1725
-3 1715 2000 1717
-3 1718 1717 1720
-3 1721 1718 1720
-3 1718 1721 1510
-3 1722 1724 1716
-3 2000 1730 1717
-3 1720 1717 1730
-3 1721 1720 1726
-3 1722 1723 1724
-3 1719 1514 1727
-3 1725 1719 1727
-3 1728 1725 1727
-3 1516 1726 1720
-3 1721 1726 1516
-3 1729 1728 1731
-3 1731 1728 1727
-3 1516 1720 1521
-3 1720 1730 1521
-3 1514 1731 1727
-3 2008 1729 1731
-3 2008 1731 1732
-3 1733 1735 1730
-3 1521 1730 1735
-3 1516 1521 1520
-3 1733 1738 1734
-3 1735 1733 1734
-3 1289 1732 1731
-3 2021 1732 1289
-3 1738 1736 1737
-3 1734 1738 1739
-3 1735 1734 1739
-3 1735 1739 1522
-3 2023 1746 1736
-3 1741 1736 1746
-3 1737 1736 1741
-3 1738 1737 1742
-3 1742 1737 1741
-3 1739 1738 1743
-3 1743 1738 1742
-3 2034 1739 1743
-3 1522 1739 2034
-3 1744 2028 1526
-3 2028 1745 1526
-3 1527 1526 1745
-3 1749 2021 1753
-3 1751 1746 2023
-3 1746 2032 1742
-3 1746 1742 1741
-3 1743 1742 2032
-3 1528 2028 1744
-3 1528 1747 2028
-3 1526 1528 1744
-3 1748 1530 1745
-3 1745 1530 1527
-3 1746 1751 1752
-3 1530 1747 1528
-3 1748 1747 1530
-3 1753 2021 1773
-3 1749 1753 1754
-3 1750 2031 1755
-3 1751 1750 1756
-3 1756 1750 1755
-3 1757 1752 1756
-3 1756 1752 1751
-3 1531 1128 3731
-3 1759 1760 1761
-3 1759 1763 1762
-3 1761 1763 1759
-3 1753 1773 1300
-3 1754 1753 1764
-3 2045 1754 1765
-3 1765 1754 1764
-3 1755 2031 1768
-3 1768 2031 1767
-3 1756 1755 1769
-3 1769 1755 1768
-3 1770 1757 1756
-3 1769 1770 1756
-3 2034 1758 1533
-3 1301 3731 1128
-3 1759 1771 1760
-3 1762 1771 1759
-3 1772 1771 1762
-3 1763 1772 1762
-3 1764 1753 1774
-3 1765 1764 1774
-3 1779 1765 1774
-3 2025 1765 1779
-3 2046 2025 1779
-3 1766 1781 1775
-3 1788 1766 1775
-3 1767 1766 1788
-3 1768 1767 1776
-3 1776 1767 1788
-3 1769 1768 1777
-3 1777 1768 1776
-3 1770 1769 1778
-3 1778 1769 1777
-3 1533 1770 1778
-3 4845 5643 930
-3 1753 1534 1774
-3 1775 1781 1782
-3 1788 1775 1782
-3 1778 1777 1776
-3 1533 1778 1776
-3 2056 1779 1783
-3 1784 2056 1783
-3 2066 1785 1780
-3 1781 1780 1786
-3 1786 1780 1785
-3 1787 1781 1786
-3 2067 1782 1787
-3 1787 1782 1781
-3 1542 1789 1779
-3 1789 1783 1779
-3 1790 1783 1789
-3 2066 2060 1791
-3 1791 2060 1544
-3 1785 2066 1791
-3 1792 1785 1791
-3 1798 1785 1792
-3 1793 1785 1798
-3 1786 1785 1794
-3 1794 1785 1793
-3 1787 1786 1795
-3 1795 1786 1794
-3 1795 2067 1787
-3 2074 1796 1788
-3 1536 1797 2081
-3 2081 1537 1536
-3 1783 1790 1539
-3 1784 1783 1543
-3 1792 1791 1798
-3 1794 1793 1799
-3 1799 1793 1798
-3 1795 1794 1799
-3 1796 1800 1801
-3 1788 1796 1801
-3 1788 1801 1312
-3 1806 1807 1797
-3 2080 1540 2081
-3 1540 1537 2081
-3 1798 1791 1550
-3 1799 1798 1545
-3 1801 1800 1328
-3 1809 1805 2421
-3 2080 2091 1540
-3 2091 1810 1540
-3 1548 1784 1543
-3 1815 1784 1548
-3 1544 1784 1815
-3 1550 1791 1544
-3 1545 1798 1550
-3 1809 1812 1813
-3 1809 1816 1812
-3 1816 1809 2421
-3 1541 1321 1814
-3 1546 1811 2109
-3 1544 1815 1560
-3 1553 1552 1824
-3 1812 1553 1813
-3 1824 1813 1553
-3 1555 1553 1812
-3 1555 1812 1816
-3 1546 2121 1321
-3 1321 2121 1814
-3 2110 2446 1817
-3 2446 1835 1817
-3 1819 1820 1818
-3 1821 2128 1822
-3 1822 2128 1821
-3 1564 1824 1552
-3 1564 1823 1824
-3 1825 1813 1824
-3 1816 1831 1555
-3 1826 2120 1575
-3 1348 1833 2110
-3 1817 1348 2110
-3 1835 1578 1817
-3 1818 1820 1827
-3 1828 1827 1820
-3 1829 2128 1569
-3 1821 1569 2128
-3 1829 1570 2128
-3 1821 2128 1569
-3 1569 2128 1570
-3 1571 1830 1823
-3 1830 1824 1823
-3 1573 1572 1831
-3 1573 1831 1824
-3 1573 1824 1830
-3 1825 1824 1831
-3 1831 1572 1555
-3 1826 1574 1832
-3 1575 1574 1826
-3 1577 1576 1833
-3 1577 1833 1348
-3 1834 1578 1835
-3 1836 2140 1837
-3 1837 1838 1836
-3 1839 1818 1827
-3 1828 1840 1827
-3 1840 1839 1827
-3 1842 1841 1828
-3 1841 1840 1828
-3 1845 1843 1844
-3 1845 1846 1590
-3 1844 1846 1845
-3 1569 1847 1829
-3 1570 1847 1581
-3 1829 1847 1570
-3 1849 1832 1574
-3 1848 1832 1849
-3 1849 1574 1366
-3 1576 1582 1833
-3 1835 1851 1834
-3 1834 1851 1852
-3 1853 1583 1854
-3 1853 2140 1583
-3 1584 1583 1836
-3 1836 1583 2140
-3 1584 1838 1585
-3 1584 1836 1838
-3 1585 1838 1855
-3 1853 1854 1838
-3 1855 1838 1854
-3 1839 1856 1865
-3 1839 1840 1856
-3 1841 1587 1856
-3 1841 1856 1840
-3 1841 1842 1595
-3 1857 1843 1845
-3 1858 1843 1857
-3 1589 1588 1857
-3 1589 1857 1845
-3 1590 1589 1845
-3 1846 1859 1590
-3 1860 2149 1861
-3 1860 1862 1863
-3 1861 1862 1860
-3 1378 2485 1849
-3 1378 1849 1366
-3 1868 1597 1850
-3 1384 1851 1582
-3 1852 1851 1384
-3 1591 1852 1384
-3 1834 1852 1591
-3 1593 1854 1583
-3 1593 1864 1854
-3 1864 1855 1854
-3 1585 1864 1592
-3 1855 1864 1585
-3 1865 1856 1587
-3 1858 1857 1588
-3 1858 1588 2152
-3 2152 1588 1874
-3 1859 2153 1590
-3 1860 1866 2149
-3 1863 1866 1860
-3 1867 1866 1863
-3 1378 1868 2485
-3 1868 1378 1597
-3 1864 1593 1869
-3 1592 1864 1870
-3 1864 1869 1870
-3 1865 1587 1600
-3 1865 1600 1878
-3 1871 1602 1595
-3 1871 1595 1872
-3 1872 1595 1842
-3 1590 2153 1873
-3 1874 1873 2153
-3 1603 2154 1875
-3 1593 1614 1869
-3 1870 1869 1876
-3 1876 1869 1614
-3 1870 1876 1605
-3 1606 1877 1878
-3 1600 1606 1878
-3 1872 1878 1877
-3 1872 1877 1871
-3 1871 1877 1879
-3 1602 1871 1880
-3 1871 1879 1880
-3 1874 1609 1873
-3 1611 1873 1609
-3 1611 1881 1873
-3 1881 1590 1873
-3 1590 1881 1612
-3 1391 1882 1603
-3 1603 1882 2154
-3 1603 1875 1619
-3 1875 2157 1619
-3 1397 1877 1606
-3 1397 1883 1877
-3 1883 1879 1877
-3 1880 1879 1884
-3 1884 1879 1883
-3 1881 1616 1885
-3 1611 1616 1881
-3 1612 1885 1617
-3 1881 1885 1612
-3 1391 1618 1882
-3 1886 1882 1618
-3 1886 1619 2157
-3 1397 1620 1883
-3 1620 1888 1883
-3 1888 1884 1883
-3 1880 1884 1888
-3 1880 1888 1621
-3 1885 1616 1889
-3 1617 1890 1622
-3 1617 1885 1890
-3 1885 1889 1890
-3 1886 1618 1624
-3 1620 1627 1888
-3 1616 1628 1889
-3 1628 1891 1889
-3 1891 1890 1889
-3 1622 1891 1629
-3 1890 1891 1622
-3 1631 2160 1418
-3 1631 1892 2160
-3 893 2500 1632
-3 1895 1896 1894
-3 1896 1632 1894
-3 1633 1632 1896
-3 1633 1896 2163
-3 2163 2173 1633
-3 1893 1223 2515
-3 1633 2173 1898
-3 1052 1633 1898
-3 2172 1052 1898
-3 1635 1899 1634
-3 1634 1899 1636
-3 1899 1900 1636
-3 1900 1902 1636
-3 1637 1636 1901
-3 1902 1903 1636
-3 1901 1636 1903
-3 1637 1901 1903
-3 1902 1904 1903
-3 1906 1903 1904
-3 1641 1903 1906
-3 1635 1448 2180
-3 1906 1904 1905
-3 1642 1906 1643
-3 1641 1906 1642
-3 1643 1906 1910
-3 1910 1908 1643
-3 1651 2180 1448
-3 1906 1905 1907
-3 1910 1906 1907
-3 2189 1908 1910
-3 1649 1908 1911
-3 1911 1908 2189
-3 1911 1912 1649
-3 1912 1909 1648
-3 1912 1913 1909
-3 2183 1914 1911
-3 1911 1914 1912
-3 1913 1912 1914
-3 1653 2180 1651
-3 1656 2180 1653
-3 1914 1916 1915
-3 1914 1915 1655
-3 4051 2180 1656
-3 1915 1657 1655
-3 1918 2198 1915
-3 1918 1915 1917
-3 1917 1915 1916
-3 1657 1915 2198
-3 2199 1657 2198
-3 1916 1919 1917
-3 1918 1917 1920
-3 1920 1917 1919
-3 1918 1920 1921
-3 1920 2203 1922
-3 1920 1922 1921
-3 1657 1921 1922
-3 1923 1922 2203
-3 1924 1922 1923
-3 1924 1925 1922
-3 1922 1925 1660
-3 1660 1925 1661
-3 1927 1926 1662
-3 1927 1662 1661
-3 1468 4051 1656
-3 2557 2563 1926
-3 1926 2563 1662
-3 1469 1662 2563
-3 1664 1469 2220
-3 2219 1929 1928
-3 1930 1929 2219
-3 1929 1930 1931
-3 1664 2220 1932
-3 1936 1933 1930
-3 1931 1930 1934
-3 1934 1930 1933
-3 1932 1935 1937
-3 1932 1937 1664
-3 1933 1936 1938
-3 1934 1933 1938
-3 2226 1937 1935
-3 1664 1937 1665
-3 2226 1939 1937
-3 1937 1939 1941
-3 1665 1937 1941
-3 1939 1943 1940
-3 1941 1939 1940
-3 1665 1941 1668
-3 1938 1936 1942
-3 1941 1940 1944
-3 1944 1940 1943
-3 1668 1941 1945
-3 1945 1941 1944
-3 1944 1943 1946
-3 1945 1944 1946
-3 1668 1945 2233
-3 2233 1945 1946
-3 1936 3036 1942
-3 1942 3036 1947
-3 1938 1942 1947
-3 2234 2232 1946
-3 2234 1946 1943
-3 2233 2236 1671
-3 2233 1671 1668
-3 1671 2236 2238
-3 1671 2238 1948
-3 1947 3036 1676
-3 1948 2238 1949
-3 1949 2238 1952
-3 1671 1948 1950
-3 1950 1948 1949
-3 1672 1671 1951
-3 1671 1950 1951
-3 1950 1949 1953
-3 1954 1950 1953
-3 1951 1950 1954
-3 1949 1952 2247
-3 1953 1949 2247
-3 2606 1947 1677
-3 1953 1678 1954
-3 1244 1262 1663
-3 2256 1678 1953
-3 2606 1677 1955
-3 2254 1679 1245
-3 1679 1958 1680
-3 1245 1679 1681
-3 2258 1957 1678
-3 2254 1245 1963
-3 2272 2254 1963
-3 1678 1957 1959
-3 1684 2279 1683
-3 1680 1958 1681
-3 2272 1963 1961
-3 2275 1960 2276
-3 1959 2276 1960
-3 1959 1960 1685
-3 1678 1959 1685
-3 1967 1966 1955
-3 1966 2263 1955
-3 1683 2279 1686
-3 1684 1689 2278
-3 1962 1960 2275
-3 1965 1960 1962
-3 1685 1960 1965
-3 1964 1961 1963
-3 2272 1961 1964
-3 1958 1697 1681
-3 1964 1963 1694
-3 2279 1103 1502
-3 1975 2281 1964
-3 1965 1962 1703
-3 1709 1964 1694
-3 1962 2275 1968
-3 1968 2275 1976
-3 1703 1962 1968
-3 2281 1975 1973
-3 1968 1976 1977
-3 1703 1968 1710
-3 1969 1710 1971
-3 1970 1969 1971
-3 1972 1964 1709
-3 1975 1964 1972
-3 1974 1973 1975
-3 1710 1712 1971
-3 1968 1977 1985
-3 1979 1975 1972
-3 1974 1975 1991
-3 1973 1974 1991
-3 2288 1973 1991
-3 2287 2293 1976
-3 1977 1976 1980
-3 1981 1977 1980
-3 1982 1977 1981
-3 1977 1982 1985
-3 1983 1979 1972
-3 1975 1979 1983
-3 1991 1975 1983
-3 1976 2293 1986
-3 1980 1976 1984
-3 1984 1976 1986
-3 1981 1980 1984
-3 1982 1981 1984
-3 2296 2288 1991
-3 1982 1984 1985
-3 1987 1511 1978
-3 2304 1988 2300
-3 1986 2300 1988
-3 2000 1986 1988
-3 1715 1984 2000
-3 1984 1986 2000
-3 1985 1984 1715
-3 1511 1989 1990
-3 1716 1511 1990
-3 1987 1989 1511
-3 1992 2296 1991
-3 1988 2304 1995
-3 1990 1994 1716
-3 1983 1725 1991
-3 1992 1991 2008
-3 2330 2004 2304
-3 1995 2304 2004
-3 2305 2001 1996
-3 1993 2305 1997
-3 1997 2305 1996
-3 1723 1722 1998
-3 1723 1998 1993
-3 1723 1993 1997
-3 1716 1999 1722
-3 1722 1999 1998
-3 1999 1716 1994
-3 1991 1725 1728
-3 2008 1991 1728
-3 1988 1995 2000
-3 1996 2001 2002
-3 2003 1996 2002
-3 1724 2003 2369
-3 1724 1997 2003
-3 1997 1996 2003
-3 1723 1997 1724
-3 1729 2008 1728
-3 2000 1995 2005
-3 2005 1995 2004
-3 2006 2000 2005
-3 2007 2000 2006
-3 1730 2000 2007
-3 2002 2001 2369
-3 2003 2002 2369
-3 2321 1992 2008
-3 2004 2330 2009
-3 2013 2004 2009
-3 2005 2004 2010
-3 2010 2004 2013
-3 2006 2005 2011
-3 2011 2005 2010
-3 2007 2006 2012
-3 2012 2006 2011
-3 1730 2007 2012
-3 2331 2686 1740
-3 2013 2014 2010
-3 2011 2010 2015
-3 2015 2010 2014
-3 2012 2011 1733
-3 1733 2011 2015
-3 1730 2012 1733
-3 2016 2014 2013
-3 2015 2014 1733
-3 1733 2014 2016
-3 2706 2355 2001
-3 2321 2008 2019
-3 2019 2008 1732
-3 2017 2321 2019
-3 2018 1736 2016
-3 1733 1736 1738
-3 1733 2016 1736
-3 2363 2331 1740
-3 2017 2019 2020
-3 2021 2017 2020
-3 2366 2363 1740
-3 2001 2355 2369
-3 2021 2019 1732
-3 2020 2019 2021
-3 2017 2021 1749
-3 2341 2017 2024
-3 2024 2017 1749
-3 2022 2027 2018
-3 2360 2022 2018
-3 2027 2023 2018
-3 2018 2023 1736
-3 1740 2367 2366
-3 2022 2360 2030
-3 2027 2022 2026
-3 1531 2367 1740
-3 1745 2028 2377
-3 2029 1745 2377
-3 2025 2024 1749
-3 2030 2371 2036
-3 2022 2030 2031
-3 2031 2030 2038
-3 2026 2022 2031
-3 1750 2026 2031
-3 1751 2027 1750
-3 2027 2026 1750
-3 2023 2027 1751
-3 2032 2033 1743
-3 2033 2034 1743
-3 2035 1748 2029
-3 2029 1748 1745
-3 2045 2025 1749
-3 1781 2036 2371
-3 2038 2030 2037
-3 1746 1752 2039
-3 2039 2040 1746
-3 1746 2040 2032
-3 2040 2041 2032
-3 2033 2032 2042
-3 2042 2032 2041
-3 2034 2042 1758
-3 2034 2033 2042
-3 2035 1747 1748
-3 2035 2044 1747
-3 2044 2043 1747
-3 1754 2045 1749
-3 2025 2045 1765
-3 2037 2030 2047
-3 2047 2030 2036
-3 2038 2037 1766
-3 1766 2037 2047
-3 2048 2038 1766
-3 2031 2038 2048
-3 1752 1757 2049
-3 1752 2049 2050
-3 1752 2050 2039
-3 2050 2051 2052
-3 2050 2052 2039
-3 2039 2052 2040
-3 2041 2040 2053
-3 2053 2040 2052
-3 1758 2042 2053
-3 2042 2041 2053
-3 1761 1760 2054
-3 1761 2055 1763
-3 2054 2055 1761
-3 1784 2046 2056
-3 1781 2379 2061
-3 2061 2379 2057
-3 1766 2036 1781
-3 2047 2036 1766
-3 1767 2048 1766
-3 2031 2048 1767
-3 2058 2049 1757
-3 2058 1757 2059
-3 2059 1757 1770
-3 2051 2058 2059
-3 2052 2051 2059
-3 2052 2059 1533
-3 1758 2052 1533
-3 2053 2052 1758
-3 1760 1771 2054
-3 1772 2054 1771
-3 2055 2054 1772
-3 1763 2055 1772
-3 2056 2046 1779
-3 2046 1784 2060
-3 1533 2059 1770
-3 2057 2060 2066
-3 2061 2057 2062
-3 2062 2057 2066
-3 1781 2061 1780
-3 1780 2061 2062
-3 2063 2064 2065
-3 2060 1784 1544
-3 1780 2062 2066
-3 2067 2071 1782
-3 1782 2071 1788
-3 2071 2074 1788
-3 2063 2068 2064
-3 2067 1795 2069
-3 2071 2067 2070
-3 2070 2067 2069
-3 2411 2072 2071
-3 2073 2071 2072
-3 2074 2071 2073
-3 2075 2094 2076
-3 2075 2077 2078
-3 2076 2077 2075
-3 2077 2402 2078
-3 1797 2080 2081
-3 2079 2080 1797
-3 2082 2419 2407
-3 1795 1799 2069
-3 1808 2069 1799
-3 2070 2069 1808
-3 2070 1808 2071
-3 2072 2071 1328
-3 2071 1808 1328
-3 1800 2072 1328
-3 2073 2072 1800
-3 2074 2073 1800
-3 1796 2074 1800
-3 2083 2094 2075
-3 1802 1803 2083
-3 1802 2083 2078
-3 2078 2083 2075
-3 1802 2402 1804
-3 1802 2078 2402
-3 2084 2085 1805
-3 2086 2088 2089
-3 2089 1807 1806
-3 2089 2088 1807
-3 2088 2090 1807
-3 1797 1807 2090
-3 1797 2090 2091
-3 1797 2091 2079
-3 2429 2091 2090
-3 2080 2079 2091
-3 2092 2419 2082
-3 2092 2082 2407
-3 4422 1524 1287
-3 2093 2094 2083
-3 1803 2093 2083
-3 1803 2095 2093
-3 1804 1803 1802
-3 2084 1805 1809
-3 2096 2087 2086
-3 2089 2097 2086
-3 2097 2096 2086
-3 1806 1810 2098
-3 1806 2098 2089
-3 2089 2098 2097
-3 2091 2429 2099
-3 2091 2099 1810
-3 2098 1810 2099
-3 2443 1538 1541
-3 1811 2443 2108
-3 1811 1538 2443
-3 2101 2419 2092
-3 2124 2419 2101
-3 2102 2101 2092
-3 2103 2094 2093
-3 2104 2094 2103
-3 2105 2093 2095
-3 2103 2093 2105
-3 1813 2106 2107
-3 1813 2107 1809
-3 1809 2107 2084
-3 2099 2097 2098
-3 1814 2443 1541
-3 2108 2109 1811
-3 2447 2123 2100
-3 2123 2111 2100
-3 2124 2101 2112
-3 2101 2102 2112
-3 2113 2112 2102
-3 2102 2125 2113
-3 2103 2116 2104
-3 2105 2116 2103
-3 2106 1813 2117
-3 2118 2107 2106
-3 2118 2106 2119
-3 2119 2106 2117
-3 2119 1816 2118
-3 1816 2421 2118
-3 2819 1826 1832
-3 2120 1826 2819
-3 1546 2109 2130
-3 2446 2131 1835
-3 2111 2122 2458
-3 2111 2123 2122
-3 1819 1818 2124
-3 1819 2124 2112
-3 1819 2112 2113
-3 2113 2125 1819
-3 1819 2125 1820
-3 2114 2115 2126
-3 2127 2126 2115
-3 2117 1825 2129
-3 1813 1825 2117
-3 1816 2129 1831
-3 1816 2119 2129
-3 2119 2117 2129
-3 1546 2130 2121
-3 2123 2458 2122
-3 2132 2458 2123
-3 1818 2133 2124
-3 2142 1828 1820
-3 2142 1820 2125
-3 2127 2134 2126
-3 2134 2135 2136
-3 2134 2127 2135
-3 2137 2135 2127
-3 2135 2138 2139
-3 2137 2138 2135
-3 2138 2144 2139
-3 1825 1831 2129
-3 1850 1575 2120
-3 1837 2140 1838
-3 2133 1818 1839
-3 2133 1839 2146
-3 1842 2142 2141
-3 1842 1828 2142
-3 2136 2135 2143
-3 2135 2139 2143
-3 1843 2144 1844
-3 1843 2139 2144
-3 1843 2143 2139
-3 1844 2144 2480
-3 1846 1844 2480
-3 1832 1848 2484
-3 1582 2476 1833
-3 2476 1851 2131
-3 2476 1582 1851
-3 1835 2131 1851
-3 1838 2140 1853
-3 1865 2145 2146
-3 1839 1865 2146
-3 2142 2146 2145
-3 2142 2145 2141
-3 2141 2145 2151
-3 2141 2151 1842
-3 2143 1843 1858
-3 2143 1858 2479
-3 2148 2479 1858
-3 1846 2148 2147
-3 1846 2147 2153
-3 1846 2153 1859
-3 1861 2150 1862
-3 2149 2150 1861
-3 1862 2150 1863
-3 1849 2484 1848
-3 1849 2485 2484
-3 1850 2156 1868
-3 1865 2151 2145
-3 1842 2151 1872
-3 2152 2148 1858
-3 2152 2147 2148
-3 2153 2147 2152
-3 1867 2149 1866
-3 2150 2149 1867
-3 1863 2150 1867
-3 2154 2485 1868
-3 2154 1868 2155
-3 1868 2156 2155
-3 1878 2151 1865
-3 1878 1872 2151
-3 2153 2152 1874
-3 2155 1875 2154
-3 2155 2156 1875
-3 2156 2157 1875
-3 2490 2489 1882
-3 2489 2154 1882
-3 1882 1886 2490
-3 2158 2490 1886
-3 2157 2158 1886
-3 2492 2493 1887
-3 1887 2493 1626
-3 2159 1887 1418
-3 1418 2160 2159
-3 1892 2889 2160
-3 2889 1892 1626
-3 2500 2906 1632
-3 1894 2162 1895
-3 2162 1896 1895
-3 2163 1896 2507
-3 2163 2508 2164
-3 2507 2508 2163
-3 2508 2165 2164
-3 1897 2166 2161
-3 2167 1897 2161
-3 3403 1893 2515
-3 1894 1632 2504
-3 1632 2168 2504
-3 2504 2162 1894
-3 2169 2163 2164
-3 2169 2173 2163
-3 2165 2169 2164
-3 1897 2171 2166
-3 1897 2170 2171
-3 1897 2167 2170
-3 2170 2167 2172
-3 2161 2172 2167
-3 2172 2161 2515
-3 1898 2173 2915
-3 2171 2170 1898
-3 2171 1898 2915
-3 2172 1898 2170
-3 1052 2515 1223
-3 2172 2515 1052
-3 1635 2174 1899
-3 1899 2174 1900
-3 2174 2175 1900
-3 1902 1900 2175
-3 1902 1905 1904
-3 1905 2176 1907
-3 1907 2176 2177
-3 2178 1907 2177
-3 1910 1907 2179
-3 1907 2178 2179
-3 2181 2182 2176
-3 2176 2182 2177
-3 2521 2178 2182
-3 2182 2178 2177
-3 2178 2521 2179
-3 2191 2179 2521
-3 1910 2191 2189
-3 2179 2191 1910
-3 2184 2182 2181
-3 2185 2182 2184
-3 2521 2182 2186
-3 2186 2182 2185
-3 2521 2186 2191
-3 2189 2187 1911
-3 1911 2187 2183
-3 2187 2188 2183
-3 2183 2188 1914
-3 2184 2181 2525
-3 2185 2184 2525
-3 2523 2185 2525
-3 2186 2185 2523
-3 2187 2189 2190
-3 2188 2187 2190
-3 2188 2190 1914
-3 2191 2192 2189
-3 2190 2189 2193
-3 2193 2189 2192
-3 2196 2190 2193
-3 1914 2190 2196
-3 2192 2191 2194
-3 2194 2193 2192
-3 2194 2196 2193
-3 2196 2194 2195
-3 2196 2197 1914
-3 1914 2197 2200
-3 1914 2200 1916
-3 2196 2200 2197
-3 1916 2200 1919
-3 1921 2198 1918
-3 2199 2198 1921
-3 1657 2199 1921
-3 1919 2200 2201
-3 1919 2202 1920
-3 2201 2202 1919
-3 1920 2202 2203
-3 2201 2200 2204
-3 2202 2201 2203
-3 2201 2204 2203
-3 2203 2204 1923
-3 1923 2205 1924
-3 2962 1924 2205
-3 2962 2546 1924
-3 1925 1924 2546
-3 2204 2206 2207
-3 1923 2204 2208
-3 2208 2204 2207
-3 2209 2962 2205
-3 2209 2205 2208
-3 2208 2205 1923
-3 1925 2546 1661
-3 2546 2549 1661
-3 2208 2207 2210
-3 1926 2209 2208
-3 1926 2208 2210
-3 1927 2549 1926
-3 1926 2549 2209
-3 2549 1927 1661
-3 2210 2207 2557
-3 2210 2557 1926
-3 2574 2563 2562
-3 2563 2574 1469
-3 2213 2212 2217
-3 2212 2213 2211
-3 2211 2213 2214
-3 2214 2212 2211
-3 1469 2574 2220
-3 2215 2213 2217
-3 2214 2213 2216
-3 2216 2213 2215
-3 2216 2572 2214
-3 2215 2217 1928
-3 1928 2218 2215
-3 2218 2216 2215
-3 2218 2572 2216
-3 2217 2219 1928
-3 2218 1929 1931
-3 1928 1929 2218
-3 1931 2572 2218
-3 1930 2219 2217
-3 2220 2226 1932
-3 1930 2217 1936
-3 2220 2574 2221
-3 1932 2226 2222
-3 1932 2222 1935
-3 2220 2221 2224
-3 2224 2221 2223
-3 2226 2220 2225
-3 2225 2220 2224
-3 2222 2226 1935
-3 2224 2223 2227
-3 2225 2224 2228
-3 2228 2224 2227
-3 2226 2225 1939
-3 1939 2225 2228
-3 2227 2579 2230
-3 2227 2230 2228
-3 1943 1939 2230
-3 1939 2228 2230
-3 1934 1938 2587
-3 2582 2229 2579
-3 2230 2579 2229
-3 2582 2231 2229
-3 2229 2231 2234
-3 2230 2229 2234
-3 1943 2230 2234
-3 2232 2233 1946
-3 2587 1938 1947
-3 2234 2235 2232
-3 2235 2236 2232
-3 2233 2232 2236
-3 2234 2231 2237
-3 2234 2237 2240
-3 2235 2234 2238
-3 2238 2234 2240
-3 2236 2235 2238
-3 2240 2237 2239
-3 2237 2231 2245
-3 2245 2231 2586
-3 2239 2237 2245
-3 2240 2239 2241
-3 2238 2240 2244
-3 2244 2240 2241
-3 2239 2245 2242
-3 2241 2239 2242
-3 2244 2241 2242
-3 2238 2244 1952
-3 2242 2245 2243
-3 2246 2242 2243
-3 2244 2242 2246
-3 2587 1947 2606
-3 2245 2586 2249
-3 2244 2246 2250
-3 1952 2244 2247
-3 2244 2250 2247
-3 2247 2248 1953
-3 2243 2245 2249
-3 2246 2243 2250
-3 2250 2243 2249
-3 2247 2250 2251
-3 2252 2247 2251
-3 2248 2247 2253
-3 2253 2247 2252
-3 2248 2253 1953
-3 1676 3036 1956
-3 2250 2249 2605
-3 2615 2250 2605
-3 2251 2250 2615
-3 2251 2615 2255
-3 2251 2255 2252
-3 2253 2252 2256
-3 2256 2252 2255
-3 2253 2256 1953
-3 2258 2255 2615
-3 2256 2255 2258
-3 1955 2257 2606
-3 2254 2601 1679
-3 2256 2258 1678
-3 1679 2601 1958
-3 1958 2601 2265
-3 2615 2261 2258
-3 2258 2261 2262
-3 2257 1955 2263
-3 2259 2254 2272
-3 2272 2273 2260
-3 2260 2273 2266
-3 2274 2260 2266
-3 2267 2268 2269
-3 2262 2261 2269
-3 2258 2262 2270
-3 2258 2270 1957
-3 2264 2279 2271
-3 2279 1684 2271
-3 2278 2271 1684
-3 2266 2273 2274
-3 2262 2269 2275
-3 2270 2262 2276
-3 2276 2262 2275
-3 1957 2276 1959
-3 2270 2276 1957
-3 2274 2273 2272
-3 2269 2268 2280
-3 2263 1966 2277
-3 2272 1964 2274
-3 2268 2267 2280
-3 2275 2269 2280
-3 1966 2648 2277
-3 2280 2267 2653
-3 1958 2265 1697
-3 2281 2274 1964
-3 1967 2648 1966
-3 2288 2274 2281
-3 2275 2280 2282
-3 2279 3634 1103
-3 2282 2280 2283
-3 2275 2282 2287
-3 2275 2287 1976
-3 2288 2281 1973
-3 2288 2658 2274
-3 2282 2283 2285
-3 2285 2283 2284
-3 2287 2282 2286
-3 2286 2282 2285
-3 2290 2284 2662
-3 2284 2290 2285
-3 2286 2285 2291
-3 2291 2285 2290
-3 2287 2286 2292
-3 2292 2286 2291
-3 2287 2292 2293
-3 3634 2294 1978
-3 1978 2294 2295
-3 2289 2288 2297
-3 2299 2289 2297
-3 2293 2292 2291
-3 2295 2294 2301
-3 2288 2296 2303
-3 2297 2288 2303
-3 2299 2297 2298
-3 2291 2290 2300
-3 2293 2300 1986
-3 2291 2300 2293
-3 2688 2307 2668
-3 2668 2307 2676
-3 2295 2301 2302
-3 1978 2302 1987
-3 2295 2302 1978
-3 1992 2303 2296
-3 2298 2297 2313
-3 2299 2298 2313
-3 2691 2299 2313
-3 2300 2685 2304
-3 2307 2688 2305
-3 2305 2688 2706
-3 2306 2307 2305
-3 2302 2301 3172
-3 3172 1987 2302
-3 1989 1987 3172
-3 2297 2303 2308
-3 2313 2297 2321
-3 2321 2297 2308
-3 2305 2706 2001
-3 2306 2305 1993
-3 1998 2306 1993
-3 1998 2310 2306
-3 2310 2307 2306
-3 2310 2317 2307
-3 1990 1989 1994
-3 1994 1989 3172
-3 1992 2308 2303
-3 2321 2308 1992
-3 2691 2313 2314
-3 2328 2315 2309
-3 2316 2309 2315
-3 2304 2309 2316
-3 2310 1998 1999
-3 2310 1999 2317
-3 1999 1994 2318
-3 2324 1994 3172
-3 2318 1994 2324
-3 2312 2320 2311
-3 2320 2319 2311
-3 2339 2315 2328
-3 2304 2316 2330
-3 2330 2316 2322
-3 1999 2323 2317
-3 2318 2323 1999
-3 2324 2323 2318
-3 2320 2325 2319
-3 2313 2321 2326
-3 2314 2313 2333
-3 2333 2313 2326
-3 2334 2314 2333
-3 2327 2314 2334
-3 2315 2339 2345
-3 2316 2315 2345
-3 2329 2316 2345
-3 2322 2316 2330
-3 2330 2316 2329
-3 2326 2321 2017
-3 2333 2326 2332
-3 2721 2327 2334
-3 2336 2335 2328
-3 2335 2337 2328
-3 2337 2338 2328
-3 2339 2328 2338
-3 2329 2345 2346
-3 2009 2330 2329
-3 2332 2326 2341
-3 2341 2326 2017
-3 2333 2332 2341
-3 2334 2333 2341
-3 2715 2342 2336
-3 2336 2342 2335
-3 2337 2335 2343
-3 2343 2335 2342
-3 2339 2338 2344
-3 2345 2339 2344
-3 2346 2345 2350
-3 2009 2329 2346
-3 2346 2013 2009
-3 2706 2340 2355
-3 2355 2340 2347
-3 2344 2338 2349
-3 2345 2344 2361
-3 2361 2350 2345
-3 2013 2346 2742
-3 2744 2013 2742
-3 2362 2013 2744
-3 2013 2362 2016
-3 2351 2352 2353
-3 2353 2354 2351
-3 2369 2355 2730
-3 2347 2730 2355
-3 2739 2348 2370
-3 2740 2370 2356
-3 2342 2715 2357
-3 2357 2715 2356
-3 2337 2343 2364
-3 2338 2337 2358
-3 2358 2337 2364
-3 2349 2338 2359
-3 2359 2338 2358
-3 2344 2349 2360
-3 2360 2349 2359
-3 2360 2361 2344
-3 2362 2744 2755
-3 2016 2362 2018
-3 2331 2363 2738
-3 2756 2738 2363
-3 2343 2342 2371
-3 2364 2343 2371
-3 2359 2358 2030
-3 2360 2359 2030
-3 2361 2360 2365
-3 2365 2018 2755
-3 2362 2755 2018
-3 2366 2756 2363
-3 2348 2334 2341
-3 2370 2348 2341
-3 2357 2356 2371
-3 2342 2357 2371
-3 2358 2364 2030
-3 2030 2364 2371
-3 2018 2365 2360
-3 2761 2366 2367
-3 1531 2368 2367
-3 2372 2373 2374
-3 2374 2375 2372
-3 2025 2341 2024
-3 2372 2376 2373
-3 2375 2376 2372
-3 2046 2341 2025
-3 2370 2341 2046
-3 2356 2370 2046
-3 2028 1747 2767
-3 2377 2028 2767
-3 2035 2377 2378
-3 2035 2029 2377
-3 2371 2356 2046
-3 2379 2371 2046
-3 2381 2380 1747
-3 2380 2767 1747
-3 1747 2043 2381
-3 2378 2043 2044
-3 2381 2043 2378
-3 2035 2378 2044
-3 2379 2046 2057
-3 1781 2371 2379
-3 2382 2384 2385
-3 2385 2050 2049
-3 2385 2384 2050
-3 2384 2386 2050
-3 2386 2051 2050
-3 2381 2387 2380
-3 2388 2387 2381
-3 2378 2388 2381
-3 2389 2383 2382
-3 2390 2383 2389
-3 2385 2391 2382
-3 2391 2389 2382
-3 2049 2058 2392
-3 2049 2392 2385
-3 2385 2392 2391
-3 2058 2789 2392
-3 2058 2051 2789
-3 2051 2386 2789
-3 2057 2046 2060
-3 2389 2393 2390
-3 2391 2393 2389
-3 2789 2391 2392
-3 2394 2398 2395
-3 2065 2799 2396
-3 2064 2799 2065
-3 2396 2063 2065
-3 2395 2397 2394
-3 2398 2397 2395
-3 2397 2399 2400
-3 2398 2399 2397
-3 2399 2401 2400
-3 2077 2814 3259
-3 3259 2402 2077
-3 2064 2403 2799
-3 2068 2403 2064
-3 2396 2404 2063
-3 2063 2404 2068
-3 2068 2404 2403
-3 2396 2418 2404
-3 2801 2406 2405
-3 2394 2397 2408
-3 2409 2408 2397
-3 2409 2400 2410
-3 2409 2397 2400
-3 2401 2410 2400
-3 2076 2813 2412
-3 2094 2813 2076
-3 2814 2077 2412
-3 2412 2077 2076
-3 2804 2815 2402
-3 2413 2414 2415
-3 2817 2414 2413
-3 2404 2417 2403
-3 2417 2404 2416
-3 2418 2416 2404
-3 2405 2406 2419
-3 2407 2419 2406
-3 2072 2411 2071
-3 2420 2813 2094
-3 1804 2815 2827
-3 2402 2815 1804
-3 2084 2829 2085
-3 1805 2085 2817
-3 2085 2829 2817
-3 2817 2413 1805
-3 2421 1805 2413
-3 2421 2413 2415
-3 2118 2421 2415
-3 2422 2424 2425
-3 2423 2424 2422
-3 2425 2424 2426
-3 2426 2086 2087
-3 2426 2424 2086
-3 2424 2428 2086
-3 2427 2088 2428
-3 2088 2086 2428
-3 2088 2429 2090
-3 2427 2429 2088
-3 2416 2430 2417
-3 2433 2434 2824
-3 2824 2435 2433
-3 2844 2092 2407
-3 2420 2094 2436
-3 2095 1803 2437
-3 2095 2437 2420
-3 2095 2420 2436
-3 2827 2437 1804
-3 2437 1803 1804
-3 2422 2425 2440
-3 2426 2440 2425
-3 2087 2096 2440
-3 2426 2087 2440
-3 2441 2427 2428
-3 2429 2427 2442
-3 2442 2427 2441
-3 2429 2442 2099
-3 2444 2445 2833
-3 2432 2444 2833
-3 2432 2431 2444
-3 2431 2110 2444
-3 2446 2110 2431
-3 2100 2434 2433
-3 2100 2111 2434
-3 2433 2435 2447
-3 2433 2447 2100
-3 2864 2419 2124
-3 2102 2092 2844
-3 2436 2104 2448
-3 2094 2104 2436
-3 2095 2448 2105
-3 2436 2448 2095
-3 2829 2107 2118
-3 2829 2084 2107
-3 2853 2438 1832
-3 2819 1832 2438
-3 2096 2839 2440
-3 2441 2839 2097
-3 2839 2096 2097
-3 2099 2441 2097
-3 2442 2441 2099
-3 2443 1814 2449
-3 2108 2443 2449
-3 2109 2108 2450
-3 2450 2854 2109
-3 2110 1833 2445
-3 2110 2445 2444
-3 2131 2446 2457
-3 2111 2451 2452
-3 2123 2843 2451
-3 2123 2447 2843
-3 2452 2451 2843
-3 2102 2453 2125
-3 2102 2844 2453
-3 2849 2455 2114
-3 2454 2455 2849
-3 2115 2114 2456
-3 2114 2455 2456
-3 2104 2116 2448
-3 2105 2448 2116
-3 2819 2439 2120
-3 2109 2467 2130
-3 2467 2109 2854
-3 2458 2451 2111
-3 2123 2451 2132
-3 2132 2451 2458
-3 2849 2114 2459
-3 2114 2126 2459
-3 2115 2456 2470
-3 2127 2115 2470
-3 2462 2463 2464
-3 2464 2465 2462
-3 1832 2868 2853
-3 2130 2466 2121
-3 2467 2466 2130
-3 2133 2864 2124
-3 2133 2468 2469
-3 2133 2469 2864
-3 2468 2125 2469
-3 2468 2142 2125
-3 2134 2459 2126
-3 2134 2136 2470
-3 2137 2127 2470
-3 2137 2471 2138
-3 2470 2471 2137
-3 2138 2471 2144
-3 2472 2461 2460
-3 2473 2472 2460
-3 2474 2475 2463
-3 2483 2462 2465
-3 2483 2474 2462
-3 2463 2462 2474
-3 2439 1850 2120
-3 2476 2131 2457
-3 2146 2468 2133
-3 2146 2477 2468
-3 2142 2468 2477
-3 2143 2470 2136
-3 2143 2478 2470
-3 2478 2471 2470
-3 2144 2471 2479
-3 2471 2478 2479
-3 2479 2480 2144
-3 2473 2481 2472
-3 2481 2865 2472
-3 2481 2473 2482
-3 2474 2483 2475
-3 2868 1832 2484
-3 423 4373 893
-3 2142 2477 2146
-3 2479 2478 2143
-3 2480 2479 2148
-3 1846 2480 2148
-3 2865 2481 2487
-3 2482 2488 2481
-3 2488 2487 2481
-3 2439 2156 1850
-3 2489 2485 2154
-3 2489 2490 2158
-3 2156 2486 2157
-3 2486 2158 2157
-3 2881 2491 2492
-3 2493 2492 2491
-3 2492 1887 2881
-3 2493 2889 1626
-3 2494 2496 2497
-3 2495 2496 2494
-3 2496 2498 2497
-3 814 1893 4422
-3 2159 2881 1887
-3 2499 2881 2159
-3 2160 2499 2159
-3 2499 2160 2889
-3 2494 2497 2892
-3 2892 2497 2498
-3 893 4373 2500
-3 2900 2906 2500
-3 2161 2501 2901
-3 2901 2502 2161
-3 2899 2162 2904
-3 2899 1896 2162
-3 2507 1896 2899
-3 2501 2161 2503
-3 1632 2906 2910
-3 2910 2168 1632
-3 2505 2162 2506
-3 2505 2903 2162
-3 2904 2162 2903
-3 2161 2166 2503
-3 2166 2512 2503
-3 2161 2502 2515
-3 2515 2502 3945
-3 2506 2162 2504
-3 2506 2504 2513
-3 2513 2509 2506
-3 2510 2506 2509
-3 2510 2511 2507
-3 2508 2507 2511
-3 2508 2511 2169
-3 2165 2508 2169
-3 2171 2512 2166
-3 2510 2509 2513
-3 2514 2510 2513
-3 2511 2510 2514
-3 2169 2511 2514
-3 2173 2169 2514
-3 2512 2171 2915
-3 2915 2173 2514
-3 1635 2919 2174
-3 2175 2174 2518
-3 2919 2517 2174
-3 2517 2518 2174
-3 2175 2518 1902
-3 2519 2518 2517
-3 2518 2519 1902
-3 2519 2520 1902
-3 1902 2520 1905
-3 1905 2520 2176
-3 2520 2522 2176
-3 2181 2176 2522
-3 2181 2522 2525
-3 2186 2523 2191
-3 2523 2525 2524
-3 2191 2523 2531
-3 2523 2524 2531
-3 2526 2525 2522
-3 2527 2524 2525
-3 2191 2531 2194
-3 2528 2525 2526
-3 2529 2528 2526
-3 2530 2527 2525
-3 2528 2530 2525
-3 2532 2533 2194
-3 2532 2194 2531
-3 2943 2194 2533
-3 2195 2194 2943
-3 2531 2534 2535
-3 2532 2531 2536
-3 2536 2531 2535
-3 2536 2537 2532
-3 2538 2195 2943
-3 2946 2538 2943
-3 2196 2195 2538
-3 2948 2535 2534
-3 2536 2535 2948
-3 2949 2536 2948
-3 2537 2536 2949
-3 2946 2541 2538
-3 2538 2961 2196
-3 2540 2542 2539
-3 2539 2542 2543
-3 2541 2539 2543
-3 2541 2961 2538
-3 2961 2200 2196
-3 2544 2543 2542
-3 2955 2541 2544
-3 2544 2541 2543
-3 2961 2541 2955
-3 2545 2200 2961
-3 2200 2545 2204
-3 2545 2547 2548
-3 2551 2545 2548
-3 2204 2545 2551
-3 2206 2204 2551
-3 2209 2964 2962
-3 2546 2964 2549
-3 2548 2547 2551
-3 2551 2554 2206
-3 2554 2207 2206
-3 2964 2209 2549
-3 2551 2547 2552
-3 2553 2551 2552
-3 2554 2551 2553
-3 2977 2207 2554
-3 2550 2560 2547
-3 2552 2547 2560
-3 2553 2552 2555
-3 2554 2553 2556
-3 2556 2553 2555
-3 2557 2554 2556
-3 2977 2557 2207
-3 2555 2552 2561
-3 2561 2552 2560
-3 2556 2555 2562
-3 2562 2555 2561
-3 2557 2556 2563
-3 2563 2556 2562
-3 2558 2981 2564
-3 2558 2564 2565
-3 2568 2564 2981
-3 2565 2564 2566
-3 2566 2564 2568
-3 2561 2560 2571
-3 2562 2561 2571
-3 2981 3496 2567
-3 2981 2567 2568
-3 2994 2571 2560
-3 2569 2567 3496
-3 2568 2567 2570
-3 2570 2567 2569
-3 2572 2566 2568
-3 2570 2572 2568
-3 2212 2569 3496
-3 2570 2569 2572
-3 2572 2569 2212
-3 2574 2571 2573
-3 2571 2574 2562
-3 2212 3496 2217
-3 2212 2214 2572
-3 2997 2573 2571
-3 2217 3496 1936
-3 3004 2573 2997
-3 1262 4051 1663
-3 2572 1931 4052
-3 2574 2575 2221
-3 1931 1934 4052
-3 2575 2574 2223
-3 2575 2223 2221
-3 2576 2573 2578
-3 2574 2573 2576
-3 2223 2574 2577
-3 2577 2574 2576
-3 2223 2577 2227
-3 4052 1934 2587
-3 2582 2576 2578
-3 2577 2576 2582
-3 2577 2582 2227
-3 2580 2578 3004
-3 2582 2578 2581
-3 2581 2578 2580
-3 2579 2227 2582
-3 2581 2580 3010
-3 2582 2581 2583
-3 3010 2580 2585
-3 3010 2231 2583
-3 2582 2583 2231
-3 2580 2584 2585
-3 2585 2231 3010
-3 2586 2585 3014
-3 2231 2585 2586
-3 3026 2592 3014
-3 2586 3014 2592
-3 2589 2590 2591
-3 2588 2587 2600
-3 2589 2593 2594
-3 2590 2589 2594
-3 2591 2590 2597
-3 2599 2586 2592
-3 2586 2599 2249
-3 2600 2587 2606
-3 3533 2254 2593
-3 2594 2593 2596
-3 2596 2593 2254
-3 2590 2594 2597
-3 2597 2594 2596
-3 2595 2591 2598
-3 2610 2592 3527
-3 2592 2610 2604
-3 2599 2592 2604
-3 2601 2254 3533
-3 2254 2597 2596
-3 2591 2597 2607
-3 2598 2591 2608
-3 2602 2598 2608
-3 2608 2598 2602
-3 2603 2595 2598
-3 2249 2599 2605
-3 2599 2604 2605
-3 2588 2600 2618
-3 2618 2600 2606
-3 2607 2597 2254
-3 2591 2607 2608
-3 2603 2598 2609
-3 2609 2621 2603
-3 2604 2612 2613
-3 2604 2613 2605
-3 2614 2605 2613
-3 2615 2605 2614
-3 2606 2257 2617
-3 2617 2257 2616
-3 2618 2606 2617
-3 2620 2607 2254
-3 2608 2607 2259
-3 2259 2607 2620
-3 2609 2598 2608
-3 2622 2610 2611
-3 2604 2610 2623
-3 2623 2610 2622
-3 2624 2604 2623
-3 2612 2625 2613
-3 2613 2625 2626
-3 2614 2613 2626
-3 2615 2614 2627
-3 2627 2614 2626
-3 2617 2616 2628
-3 2618 2617 2631
-3 2631 2617 2628
-3 2644 2618 2631
-3 2601 2619 2265
-3 2259 2620 2254
-3 2272 2608 2259
-3 2260 2608 2272
-3 2621 2609 2608
-3 2629 2624 2623
-3 2267 2625 2633
-3 2626 2625 2269
-3 2269 2625 2267
-3 2261 2626 2269
-3 2627 2626 2261
-3 2615 2627 2261
-3 2257 2263 2616
-3 2628 2616 2630
-3 2630 2616 2263
-3 2631 2628 2630
-3 3055 2264 2271
-3 3587 3055 2271
-3 2260 2274 2608
-3 2640 2629 2623
-3 2635 2636 3073
-3 2637 2630 2263
-3 2631 2630 2637
-3 2644 2631 2637
-3 2264 3055 2279
-3 3587 2271 2278
-3 2639 2621 2608
-3 2632 2621 2639
-3 2645 2632 2639
-3 2623 2622 2640
-3 2634 2642 2641
-3 2634 2641 2633
-3 2633 2641 2267
-3 2635 2643 2636
-3 3073 2643 2635
-3 2263 2277 2637
-3 2645 2639 2608
-3 2637 2277 2648
-3 2644 2637 2648
-3 2646 2265 2619
-3 2645 2608 2658
-3 2645 2649 2651
-3 2647 2622 2652
-3 2640 2622 2647
-3 2641 2640 2650
-3 2267 2641 2650
-3 2658 2608 2274
-3 2650 2640 2653
-3 2267 2650 2653
-3 1697 2265 2646
-3 2649 2645 2658
-3 3110 2654 2652
-3 2640 2647 2652
-3 2659 2652 2654
-3 2640 2652 2659
-3 2653 2640 2659
-3 2653 2655 2280
-3 2651 2649 2658
-3 3110 2661 2654
-3 2655 2653 2659
-3 2280 2655 2283
-3 2655 2659 2656
-3 2657 2655 2656
-3 2283 2655 2657
-3 2648 1967 3095
-3 3106 2651 2658
-3 2660 2661 3110
-3 2284 2657 2656
-3 2283 2657 2284
-3 2675 3095 1967
-3 3634 2669 2294
-3 2288 2289 2658
-3 2654 2661 2659
-3 2284 2656 2659
-3 2668 2669 3121
-3 3106 2658 2289
-3 2670 3106 2289
-3 2659 2662 2284
-3 2659 2673 2662
-3 2663 2664 2665
-3 2663 2666 2667
-3 2665 2666 2663
-3 2681 2670 2289
-3 3144 2670 2671
-3 2672 2661 2660
-3 2683 2661 2672
-3 3162 2659 2661
-3 3163 2659 3162
-3 2659 3163 2673
-3 2674 2662 2673
-3 2685 2662 2674
-3 2290 2662 2685
-3 2686 2675 1967
-3 2668 3121 2688
-3 2676 3154 2669
-3 2676 2669 2668
-3 3154 2294 2669
-3 3154 2677 2294
-3 2677 2301 2294
-3 2678 2679 2680
-3 2671 2670 2691
-3 2691 2670 2681
-3 2682 2671 2691
-3 3144 2671 2682
-3 2692 3144 2682
-3 2673 3163 2684
-3 2674 2673 2684
-3 2685 2674 2684
-3 2300 2290 2685
-3 2675 2686 2687
-3 2698 2675 2687
-3 2689 2301 2677
-3 2690 2679 2678
-3 2680 2690 2678
-3 2299 2691 2289
-3 2691 2681 2289
-3 2692 2682 2701
-3 3169 2694 3137
-3 2705 3137 2694
-3 2683 2672 2696
-3 2696 2672 2695
-3 2697 2683 2696
-3 2683 2697 3162
-3 2697 2304 3162
-3 2684 3162 2304
-3 2685 2684 2304
-3 2698 2687 2686
-3 2307 3164 2676
-3 2689 3172 2301
-3 2719 2679 2690
-3 2699 2719 2690
-3 2680 2700 2690
-3 2700 2699 2690
-3 2682 2691 2711
-3 2701 2693 2692
-3 2703 3159 2702
-3 2694 3169 2715
-3 2705 2694 2725
-3 3179 2696 2695
-3 2309 2696 2328
-3 2697 2696 2309
-3 2304 2697 2309
-3 2331 2698 2686
-3 2706 2726 2340
-3 3164 2317 2707
-3 3164 2307 2317
-3 3164 2707 3172
-3 2312 2311 2708
-3 2719 2699 2709
-3 2700 2710 2699
-3 2710 2709 2699
-3 2710 2700 2720
-3 2314 2711 2691
-3 2701 2682 2711
-3 2712 2702 3159
-3 2722 2712 3159
-3 2703 2702 2713
-3 2713 2702 2712
-3 2704 2703 2713
-3 3167 3160 2714
-3 3167 2714 2724
-3 3169 3167 2724
-3 2715 3169 2724
-3 2328 2696 3179
-3 2707 2317 2716
-3 3172 2707 2717
-3 2717 2707 2716
-3 2717 2324 3172
-3 2319 3183 3184
-3 2319 3184 2708
-3 2319 2708 2311
-3 2718 2312 2708
-3 2312 2718 2320
-3 2710 2719 2709
-3 2720 2719 2710
-3 2314 2327 2711
-3 2701 2711 2327
-3 2693 2701 2721
-3 2722 2721 2712
-3 2712 2721 2732
-3 2713 2712 2732
-3 2723 2704 2713
-3 2723 2729 3176
-3 2714 3176 2729
-3 2694 2715 2725
-3 2340 2726 2730
-3 2317 2323 2716
-3 2324 2716 2323
-3 2717 2716 2324
-3 2319 2727 3183
-3 2731 2728 2727
-3 2325 2731 2727
-3 2325 2727 2319
-3 2718 2731 2325
-3 2718 2325 2320
-3 2721 2701 2327
-3 2714 2729 2734
-3 2715 2724 2733
-3 2336 2725 2715
-3 2328 2725 2336
-3 2723 2713 2732
-3 2729 2723 2732
-3 2724 2714 2733
-3 2732 2721 2334
-3 2334 2348 2732
-3 2740 2732 2739
-3 2729 2732 2740
-3 2734 2729 2740
-3 2714 2734 2733
-3 2715 2733 2356
-3 2735 3193 2736
-3 3193 2737 2736
-3 3171 2331 2738
-3 2340 2730 2347
-3 2739 2732 2348
-3 2741 2734 2740
-3 2356 2733 2734
-3 2350 2742 2346
-3 2743 2744 2742
-3 2353 2352 2745
-3 2354 2353 2745
-3 2736 2746 2735
-3 2747 2746 2736
-3 2737 2747 2736
-3 3201 2748 2749
-3 3201 2749 2738
-3 2750 2738 2749
-3 2751 2738 2750
-3 2369 3718 3731
-3 2730 3718 2369
-3 2740 2739 2370
-3 2356 2741 2740
-3 2734 2741 2356
-3 2350 2361 2752
-3 2350 2752 3203
-3 2350 3203 2742
-3 3203 2753 2742
-3 2743 2742 2754
-3 2754 2742 2753
-3 2744 2743 2755
-3 2755 2743 2754
-3 1524 4422 1519
-3 2352 2351 2745
-3 2354 2745 2351
-3 2757 2738 2756
-3 2758 2738 2757
-3 3201 2738 2758
-3 2750 2749 2748
-3 2751 2750 2368
-3 3198 2751 2368
-3 1531 3198 2368
-3 3731 3198 1531
-3 2369 3731 1301
-3 2752 2361 2759
-3 2361 2365 2759
-3 2753 2760 2365
-3 2759 2365 2760
-3 2754 2753 2365
-3 2755 2754 2365
-3 2756 2366 2761
-3 2367 2757 2761
-3 2757 2756 2761
-3 2758 2757 2367
-3 2368 2758 2367
-3 2758 2368 2762
-3 2748 2762 2368
-3 2750 2748 2368
-3 2374 2373 2763
-3 2374 2763 2375
-3 2373 2376 2763
-3 2375 2763 2376
-3 2767 3226 2377
-3 2377 3226 2378
-3 2768 2766 2770
-3 2769 2766 2768
-3 2771 2773 2772
-3 2380 2783 2767
-3 3226 2785 2378
-3 2768 2770 2775
-3 2766 2776 2770
-3 2776 2775 2770
-3 2776 2766 2777
-3 2778 2771 2772
-3 2382 2383 2779
-3 2382 2779 2773
-3 2773 2779 2772
-3 2773 2384 2382
-3 2773 2780 2384
-3 2773 2774 2780
-3 2780 2781 2384
-3 2384 2782 2386
-3 2781 2782 2384
-3 2783 2380 3236
-3 2380 2784 3236
-3 2380 2387 2784
-3 3240 2784 2387
-3 3240 2387 2785
-3 2785 2387 2388
-3 2785 2388 2378
-3 1697 4373 423
-3 3241 2775 2776
-3 2777 3241 2776
-3 2778 2787 3249
-3 2778 2772 2787
-3 2772 2779 2787
-3 2383 2390 2787
-3 2779 2383 2787
-3 2788 2781 2780
-3 3249 2788 2780
-3 2782 2781 2789
-3 2789 2781 2788
-3 2782 2789 2386
-3 2784 2790 3236
-3 3240 2790 2784
-3 2792 2791 2786
-3 2791 2797 2786
-3 2390 3249 2787
-3 2390 2393 3249
-3 3249 2391 2788
-3 3249 2393 2391
-3 2789 2788 2391
-3 2793 2795 2796
-3 2794 2795 2793
-3 2394 2797 2792
-3 2792 2797 2791
-3 2792 2798 2394
-3 2398 2394 2798
-3 2793 2796 2800
-3 2795 2801 2796
-3 2801 2800 2796
-3 2797 2836 3247
-3 2836 2797 2394
-3 2398 2802 2399
-3 2398 2798 2802
-3 2802 2803 2399
-3 2399 2803 2401
-3 2402 3259 2804
-3 2396 2799 2418
-3 2810 2811 2809
-3 2812 2793 2800
-3 2801 2405 2812
-3 2801 2812 2800
-3 2795 2406 2801
-3 2795 2407 2406
-3 2795 2844 2407
-3 2410 2803 2802
-3 2410 2802 2409
-3 2401 2803 2410
-3 2412 2813 2814
-3 2815 2804 2816
-3 2816 2804 2828
-3 2805 2414 2817
-3 2415 2414 2805
-3 2415 2805 2818
-3 2818 2805 2806
-3 2403 2417 2799
-3 2417 2820 2799
-3 2418 2799 2820
-3 2821 2418 2820
-3 2821 2822 2418
-3 2416 2418 2823
-3 2823 2418 2822
-3 2825 2809 2824
-3 2809 2811 2824
-3 2824 2811 2435
-3 2405 3290 2812
-3 2408 2836 2394
-3 2408 2409 2826
-3 2409 3281 2826
-3 2409 2802 3281
-3 2420 2437 2814
-3 2420 2814 2813
-3 2437 2827 2814
-3 2816 2827 2815
-3 2828 2827 2816
-3 2829 2830 2817
-3 2415 2831 2118
-3 2415 2818 2831
-3 2439 2819 2807
-3 3306 2439 2807
-3 3306 2807 2808
-3 2422 3299 2423
-3 2423 3299 2424
-3 2417 2430 2820
-3 2821 2430 2832
-3 2821 2820 2430
-3 2832 2430 2833
-3 2416 2823 2430
-3 2833 2430 2823
-3 2432 2822 2431
-3 2432 2823 2822
-3 2432 2833 2823
-3 2446 2431 3288
-3 2431 2822 3288
-3 3288 2834 2446
-3 2824 2434 2825
-3 3290 2405 2419
-3 2826 2836 2408
-3 2837 2836 2826
-3 3281 2837 2826
-3 2118 2830 2829
-3 2830 2118 2831
-3 2819 2438 2838
-3 2839 3299 2422
-3 2422 2440 2839
-3 2428 3309 2441
-3 2833 2445 2832
-3 3301 2111 2842
-3 3301 2434 2111
-3 2447 2842 2843
-3 2447 2835 2842
-3 2447 2435 2835
-3 3301 2842 2835
-3 2419 3302 3290
-3 3302 2419 2864
-3 2848 3314 2454
-3 3314 3322 2454
-3 2838 2853 3305
-3 2853 2838 2438
-3 2441 3309 2839
-3 3321 2449 1814
-3 3321 2450 2449
-3 2450 2108 2449
-3 2450 2840 2854
-3 2446 2834 2457
-3 2452 2842 2111
-3 2843 2842 2452
-3 2844 2848 2453
-3 2849 2848 2454
-3 2454 3322 2455
-3 2455 3322 2856
-3 2456 2455 2856
-3 2850 2464 2846
-3 2846 2845 2850
-3 2845 2851 2850
-3 2852 2845 2847
-3 2851 2845 2852
-3 1814 2121 3321
-3 3321 2121 2861
-3 2832 2445 3329
-3 3329 2445 1833
-3 2848 2855 2453
-3 2453 2855 2125
-3 2855 2848 3344
-3 2849 3344 2848
-3 2456 2856 2470
-3 2460 2461 2857
-3 2463 2858 2464
-3 2465 2850 2859
-3 2465 2464 2850
-3 2860 2859 2851
-3 2859 2850 2851
-3 2852 2860 2851
-3 2439 3306 2486
-3 2466 2861 2121
-3 2862 2861 2467
-3 2467 2861 2466
-3 2467 2854 2862
-3 2469 2855 2864
-3 2855 2469 2125
-3 2459 3330 2849
-3 2459 2856 3330
-3 2134 2856 2459
-3 2470 2856 2134
-3 2857 2472 2865
-3 2461 2472 2857
-3 2460 2866 2473
-3 2460 2857 2866
-3 2857 2865 2866
-3 2463 2475 2867
-3 2463 2867 2858
-3 2858 2867 3335
-3 2483 2465 2867
-3 3335 2867 2465
-3 2859 3335 2465
-3 2860 3335 2859
-3 2868 2485 2853
-3 1833 2476 3329
-3 2457 2863 2476
-3 2476 2863 3329
-3 2866 2865 2869
-3 2473 2869 2482
-3 2866 2869 2473
-3 2475 2483 2867
-3 2484 2485 2868
-3 2487 2869 2865
-3 2482 2869 2488
-3 2869 2487 2488
-3 2439 2486 2156
-3 2870 2872 2873
-3 2489 3889 2485
-3 2874 3360 3356
-3 2874 2875 2876
-3 3356 2875 2874
-3 2870 2877 2871
-3 2877 2878 2879
-3 2877 2870 2878
-3 2870 2873 2878
-3 3365 2873 2872
-3 2878 2873 3365
-3 2489 2158 3889
-3 2158 2486 3889
-3 2880 3360 2874
-3 2881 3360 2880
-3 2491 2880 2876
-3 2876 2880 2874
-3 2876 2885 2491
-3 2882 2879 2878
-3 3365 2883 2878
-3 2883 2882 2878
-3 2880 2491 2881
-3 2884 2493 2491
-3 2884 2491 2885
-3 2882 2886 3366
-3 2882 2883 2886
-3 2887 2886 2883
-3 2885 2888 2884
-3 2884 2888 2889
-3 2884 2889 2493
-3 2495 2494 2886
-3 2886 2494 3366
-3 2886 2887 2496
-3 2886 2496 2495
-3 2494 3369 3366
-3 2887 2498 2496
-3 2887 2883 2498
-3 2499 2888 2881
-3 2499 2889 2888
-3 2891 2890 2498
-3 2891 2498 2883
-3 2494 2892 3369
-3 2890 2893 2892
-3 2890 2892 2498
-3 2891 2893 2890
-3 3381 2894 2895
-3 2895 2894 2896
-3 2895 2897 3381
-3 2896 2897 2895
-3 3395 4422 1893
-3 1893 3404 3395
-3 2898 2902 3398
-3 2903 2898 3400
-3 2902 2898 2903
-3 3403 3404 1893
-3 2902 3410 3398
-3 2503 2901 2501
-3 2503 2905 2901
-3 2502 2901 2905
-3 2502 2905 3945
-3 2910 2906 2907
-3 2168 2910 2908
-3 3410 2168 2908
-3 2902 2168 3410
-3 2909 2902 2903
-3 2909 2504 2902
-3 2909 3414 2504
-3 2168 2902 2504
-3 2903 2505 2909
-3 2899 3418 2507
-3 2512 2905 2503
-3 2910 2911 2908
-3 2513 2504 3414
-3 2506 2912 2505
-3 2510 2912 2506
-3 2507 2913 2510
-3 2510 2913 2912
-3 2913 2507 3418
-3 2905 2512 2915
-3 3945 2914 2515
-3 2513 3421 2514
-3 3427 3403 2515
-3 3423 2514 3421
-3 3423 2915 2514
-3 2916 3426 2516
-3 2516 1226 3428
-3 2516 3426 2917
-3 2916 2516 3428
-3 2517 2918 2519
-3 2919 2918 2517
-3 2519 2918 2520
-3 2920 2919 2921
-3 2921 2919 1635
-3 2922 2923 3437
-3 2924 2925 2926
-3 2928 2926 2929
-3 2928 2927 2926
-3 2927 2924 2926
-3 2929 2930 2931
-3 2929 2926 2930
-3 2932 2930 2925
-3 2925 2930 2926
-3 2933 2931 2930
-3 2934 2931 2933
-3 2935 2930 2932
-3 2933 2930 2935
-3 2933 2936 2934
-3 2935 2936 2933
-3 2522 3450 2526
-3 2524 2527 2937
-3 2526 3450 2529
-3 3450 2938 2529
-3 2937 2530 2939
-3 2527 2530 2937
-3 2524 2940 2531
-3 2524 2937 2940
-3 2937 2939 2940
-3 2533 3456 2941
-3 2532 3456 2533
-3 2942 2533 2941
-3 2942 2943 2533
-3 2528 2529 2947
-3 2947 2529 2938
-3 2528 2939 2530
-3 2528 2944 2939
-3 2531 2944 2534
-3 2531 2940 2944
-3 2940 2939 2944
-3 2532 2537 3456
-3 3456 2537 2950
-3 2950 2945 2942
-3 2943 2942 2946
-3 2946 2942 2945
-3 2952 2528 2947
-3 2952 2948 2944
-3 2952 2944 2528
-3 2534 2944 2948
-3 2950 2537 2949
-3 2950 2949 2951
-3 2945 2950 2951
-3 2945 2951 2540
-3 2945 2540 2539
-3 2541 2945 2539
-3 2946 2945 2541
-3 3467 3470 2948
-3 2949 2948 2953
-3 2953 2948 3470
-3 2540 2953 2542
-3 2540 2951 2953
-3 2951 2949 2953
-3 3471 2953 3470
-3 2542 3471 2958
-3 2542 2953 3471
-3 2958 2544 2542
-3 2954 2956 2957
-3 3468 2954 2957
-3 2959 2544 2958
-3 2544 2959 2960
-3 2544 2960 2955
-3 2961 2955 2960
-3 2957 2956 2969
-3 2969 2956 2963
-3 3468 2957 2969
-3 2970 3468 2987
-3 2987 3468 2969
-3 2547 2961 2550
-3 2961 2960 2550
-3 2545 2961 2547
-3 2962 2964 2546
-3 3470 2970 2971
-3 2972 3470 2971
-3 2550 2960 2959
-3 2976 2550 2959
-3 3501 2967 2966
-3 3501 2966 2973
-3 2973 2966 2965
-3 2963 2968 2986
-3 2986 2968 2974
-3 2969 2963 2986
-3 2971 2970 2975
-3 2975 2972 2971
-3 2986 2974 2979
-3 2975 2970 2980
-3 2980 2970 2987
-3 2554 2557 2977
-3 2978 2973 2981
-3 2978 2981 2558
-3 2978 2558 2559
-3 2558 2978 2559
-3 2558 3501 2978
-3 3501 2973 2978
-3 2979 2982 2986
-3 2987 2969 2986
-3 2976 2985 2984
-3 2976 2984 2550
-3 2550 2984 2560
-3 2558 2565 3501
-3 2982 2990 2986
-3 2980 2987 2991
-3 2988 2983 2980
-3 2988 2980 2989
-3 2989 2980 2991
-3 2988 2989 3495
-3 2992 2985 3495
-3 2985 2992 2984
-3 2984 2992 2994
-3 2560 2984 2994
-3 2565 2566 3501
-3 2987 2986 2991
-3 2991 2986 2990
-3 3495 2989 2992
-3 2992 2989 2991
-3 2995 2991 2990
-3 2992 2991 3005
-3 3005 2991 2995
-3 2993 2992 3005
-3 2994 2992 2993
-3 2566 2572 3501
-3 2993 3005 2997
-3 2994 2993 2997
-3 2996 2995 3503
-3 3005 2995 2996
-3 2994 2997 2571
-3 2996 3503 2998
-3 3501 2572 4052
-3 3005 2996 2998
-3 2998 3503 2999
-3 3005 2998 2999
-3 2997 3005 3004
-3 3005 2999 3000
-3 3509 3001 3000
-3 3002 3000 3001
-3 3003 3000 3002
-3 3003 3002 3005
-3 3000 3003 3005
-3 3004 2578 2573
-3 3004 3005 2580
-3 3001 3006 3007
-3 3002 3001 3009
-3 3005 3002 3009
-3 3019 3005 3009
-3 2580 3005 3019
-3 2584 2580 3019
-3 2581 3010 2583
-3 3007 3008 3012
-3 3012 3008 3011
-3 3007 3012 3013
-3 3001 3007 3013
-3 3009 3001 3013
-3 2584 3019 3014
-3 2584 3014 2585
-3 3012 3011 3013
-3 3009 3013 3023
-3 3031 3009 3023
-3 3019 3009 3018
-3 3014 3019 3026
-3 3020 3016 3015
-3 3021 3016 3020
-3 3022 3015 3017
-3 3020 3015 3022
-3 2588 4052 2587
-3 3011 3008 3045
-3 3024 3009 3043
-3 3018 3009 3024
-3 3019 3018 3025
-3 3026 3019 3025
-3 3013 3011 3045
-3 3023 3013 3027
-3 3031 3023 3028
-3 3028 3023 3027
-3 3018 3024 3029
-3 3025 3018 3519
-3 2588 3532 4052
-3 2589 3521 3520
-3 2591 3521 2589
-3 2591 3030 3521
-3 3013 3045 3051
-3 3028 3027 3539
-3 3031 3028 3539
-3 3029 3024 3032
-3 3032 3024 3043
-3 3032 3018 3029
-3 3519 3018 3032
-3 3026 3025 2592
-3 3520 2593 2589
-3 3033 2593 3520
-3 2595 3030 2591
-3 2595 3529 3030
-3 3034 3529 2595
-3 3027 3013 3539
-3 3009 3031 3035
-3 3043 3009 3035
-3 3025 3527 2592
-3 3533 2593 3033
-3 2595 3037 3034
-3 2595 3535 3037
-3 3038 3535 2595
-3 3539 3013 3051
-3 3540 3032 3043
-3 2601 3533 3039
-3 2603 3038 2595
-3 2603 3040 3038
-3 3549 3044 3045
-3 3574 3539 3051
-3 3031 3539 3052
-3 3035 3031 3052
-3 3564 3540 3043
-3 3550 2611 3527
-3 3527 2611 2610
-3 2588 2618 3532
-3 3049 3532 2618
-3 2601 3039 2619
-3 2603 2621 3040
-3 3052 3539 3574
-3 3043 3035 3046
-3 2612 3047 3048
-3 2612 2604 3047
-3 3056 3040 2621
-3 3572 3050 3041
-3 3045 3044 3081
-3 3051 3045 3081
-3 3046 3035 3053
-3 3053 3035 3052
-3 3043 3046 3061
-3 3061 3046 3053
-3 3061 3564 3043
-3 3063 2611 3054
-3 2611 3063 2622
-3 2624 3066 2604
-3 3066 3047 2604
-3 2612 2633 2625
-3 2618 2644 3049
-3 3078 2619 3039
-3 3056 2621 2632
-3 3044 3549 3081
-3 3598 3574 3059
-3 3059 3574 3051
-3 3574 3599 3052
-3 3053 3052 3061
-3 3061 3052 3060
-3 3586 3062 3063
-3 3586 3063 3054
-3 2624 2629 3064
-3 3065 3066 3064
-3 3064 3066 2624
-3 3067 2612 3048
-3 3068 3067 3048
-3 2612 3067 2633
-3 3553 3049 3088
-3 2632 3069 3056
-3 3069 2632 3057
-3 2632 3058 3057
-3 2632 3074 3058
-3 3051 3081 3070
-3 3059 3051 3070
-3 3070 3598 3059
-3 3061 3060 3071
-3 3085 3063 3062
-3 2629 2640 3064
-3 3065 3064 3072
-3 3072 3064 2640
-3 3072 2634 3068
-3 3065 3072 3068
-3 2634 2633 3068
-3 3068 2633 3067
-3 2644 2638 3049
-3 3088 3049 2638
-3 2645 3074 2632
-3 3079 3074 2645
-3 3074 3079 3075
-3 3060 3052 3083
-3 3071 3060 3083
-3 3063 3085 2622
-3 3072 2640 2641
-3 2642 3072 2641
-3 2634 3072 2642
-3 2636 2643 3073
-3 2638 2644 3077
-3 3088 2638 3087
-3 3087 2638 3077
-3 3080 3075 3079
-3 3074 3075 3080
-3 3074 3080 3613
-3 3070 3081 3082
-3 3626 3070 3082
-3 3052 3609 3620
-3 3076 3071 3084
-3 3084 3071 3083
-3 3077 2648 3086
-3 2644 2648 3077
-3 3087 3077 3086
-3 2619 3078 2646
-3 3079 2645 2651
-3 3619 3630 3089
-3 3619 3089 3081
-3 3082 3081 3090
-3 3090 3081 3089
-3 3090 3626 3082
-3 3091 3620 3626
-3 3620 3091 3052
-3 3084 3083 3092
-3 3076 3084 3092
-3 3085 3076 3092
-3 2622 3092 2652
-3 3085 3092 2622
-3 3087 3086 3093
-3 3088 3087 3093
-3 3096 3079 2651
-3 3080 3079 3096
-3 3622 3080 3094
-3 3626 3090 3089
-3 3116 3091 3626
-3 2652 3092 3110
-3 3095 3086 2648
-3 3093 3086 3095
-3 3632 3088 3095
-3 3095 3088 3093
-3 4097 2646 3078
-3 3080 3096 3106
-3 3052 3091 3116
-3 3092 3083 3110
-3 3642 3632 3095
-3 1697 2646 4097
-3 3080 3101 3109
-3 3097 3080 3109
-3 3094 3080 3098
-3 3098 3080 3097
-3 3099 3647 3100
-3 3083 3052 3110
-3 3080 3106 3112
-3 3101 3080 3112
-3 3098 3097 3102
-3 3099 3646 3103
-3 3647 3099 3103
-3 3642 3095 3104
-3 3642 3104 3105
-3 2651 3106 3096
-3 3101 3112 3107
-3 3108 3101 3107
-3 3109 3101 3108
-3 3097 3109 3123
-3 3102 3097 3123
-3 3110 3052 3116
-3 2675 3104 3095
-3 3655 3121 3656
-3 3656 3121 3634
-3 2669 3634 3121
-3 3107 3112 3113
-3 3108 3107 3114
-3 3114 3107 3113
-3 3109 3108 3114
-3 3661 3657 3102
-3 3103 3646 3662
-3 3115 3654 3647
-3 3117 3118 3659
-3 3111 3117 3659
-3 3111 3119 3117
-3 3120 3119 3111
-3 2670 3122 3106
-3 3122 3112 3106
-3 3113 3112 3122
-3 3114 3113 3122
-3 3109 3114 3133
-3 3133 3114 3122
-3 3123 3109 3133
-3 3102 3123 3124
-3 3124 3661 3102
-3 3116 3664 3125
-3 3110 3116 3125
-3 2660 3110 3139
-3 3119 3118 3117
-3 3126 3118 3119
-3 3120 3126 3119
-3 3127 3126 3120
-3 3130 3132 3131
-3 3128 3132 3130
-3 3672 3104 2675
-3 2670 3144 3122
-3 3133 3122 3144
-3 3123 3133 3134
-3 3124 3123 3135
-3 3135 3123 3134
-3 3135 3661 3124
-3 3103 3662 3147
-3 3147 3662 3158
-3 3647 3103 3148
-3 3148 3103 3147
-3 3115 3647 3160
-3 3676 3115 3149
-3 3149 3115 3160
-3 3125 3136 3137
-3 3110 3125 3138
-3 3138 3125 3137
-3 3139 3110 3138
-3 3128 3140 3141
-3 3128 3130 3140
-3 2665 2664 3140
-3 2665 3140 3131
-3 3131 3140 3130
-3 3131 3132 3142
-3 3131 3142 2665
-3 2665 3142 2666
-3 3142 2667 2666
-3 3143 2667 3142
-3 3134 3133 3145
-3 3145 3133 3144
-3 3135 3134 3146
-3 3146 3134 3145
-3 3158 3661 3135
-3 3158 3135 3146
-3 3149 3150 3676
-3 3676 3150 3136
-3 3136 3150 3137
-3 3138 3137 3151
-3 3152 3138 3151
-3 3139 3690 2660
-3 2660 3690 2672
-3 2664 3141 3140
-3 2664 2663 3141
-3 2663 3153 3141
-3 2667 3153 2663
-3 3153 2667 3143
-3 3121 3682 2706
-3 2680 3155 3156
-3 2679 3155 2680
-3 2680 3156 3684
-3 2692 3157 3144
-3 3157 3145 3144
-3 3146 3145 3157
-3 3158 3146 3157
-3 3147 3158 3159
-3 3647 3148 3160
-3 3160 3148 3176
-3 3137 3150 3169
-3 2705 3151 3137
-3 3161 3152 3151
-3 3161 3151 2705
-3 3690 3170 2672
-3 3162 2661 2683
-3 2698 3672 2675
-3 3674 3672 3171
-3 3171 3672 2698
-3 3121 2706 2688
-3 2676 3164 3154
-3 2677 3154 2689
-3 2689 3154 3164
-3 3155 2679 3165
-3 2692 2693 3157
-3 3696 3157 2693
-3 3157 3166 3158
-3 3159 3158 3166
-3 2703 3147 3159
-3 2704 3147 2703
-3 2704 3148 3147
-3 3176 3148 2704
-3 3149 3160 3167
-3 3150 3149 3168
-3 3168 3149 3167
-3 3169 3150 3168
-3 2695 2672 3170
-3 2684 3163 3162
-3 3180 3681 3171
-3 2689 3164 3172
-3 2679 2719 3165
-3 2700 2680 3684
-3 3714 2700 3684
-3 3173 3696 2693
-3 3175 3174 3166
-3 3159 3166 3174
-3 3176 2704 2723
-3 3169 3168 3167
-3 3177 3161 2705
-3 3170 3177 3178
-3 2695 3170 3179
-3 3170 3178 3179
-3 2331 3171 2698
-3 3704 3180 3171
-3 2706 3682 2726
-3 2726 3682 3707
-3 3713 2720 3714
-3 2720 2700 3714
-3 3173 2693 3185
-3 2722 3174 3175
-3 3716 2722 3175
-3 3174 2722 3159
-3 2714 3160 3176
-3 2705 2725 3177
-3 3178 3177 3181
-3 3179 3178 3182
-3 3182 3178 3181
-3 3179 3182 2328
-3 2720 3726 2719
-3 3713 3726 2720
-3 2721 3185 2693
-3 3716 3185 2722
-3 3185 2721 2722
-3 3181 3177 2725
-3 3182 3181 2725
-3 2328 3182 2725
-3 2726 3707 3720
-3 3183 2727 3186
-3 2718 3189 2731
-3 2738 3704 3171
-3 3704 2738 3198
-3 2730 2726 3720
-3 3732 3187 3188
-3 3732 3186 3187
-3 3186 2727 3187
-3 2728 3187 2727
-3 2728 3189 3187
-3 2728 2731 3189
-3 3731 3717 3198
-3 3720 3718 2730
-3 1262 1519 4422
-3 2735 3191 3193
-3 3190 3191 2735
-3 3192 3193 3191
-3 2737 3194 3195
-3 2737 3193 3194
-3 3194 3196 3195
-3 3198 2738 2751
-3 2735 2746 3190
-3 2747 3190 2746
-3 3191 3190 2747
-3 3191 2747 3192
-3 2747 2737 3192
-3 3195 3199 2737
-3 3199 3192 2737
-3 3196 3199 3195
-3 3200 3199 3196
-3 3197 3200 3196
-3 2752 3202 3739
-3 2752 3739 3203
-3 2758 3204 3201
-3 3201 3204 2748
-3 3205 3202 3207
-3 3206 3202 3205
-3 2752 3207 3202
-3 2752 2759 3207
-3 2760 3203 3739
-3 3208 2760 3739
-3 3203 2760 2753
-3 2758 2762 3204
-3 2748 3204 2762
-3 3206 3205 3209
-3 3205 3210 3209
-3 3207 3211 3205
-3 3211 3210 3205
-3 2759 3211 3207
-3 2759 3213 3211
-3 2759 3208 3213
-3 3208 2759 2760
-3 3210 3212 3209
-3 3213 3212 3210
-3 3211 3213 3210
-3 3214 2764 2765
-3 3214 3750 2764
-3 3214 2773 3215
-3 3216 2773 3214
-3 2765 3216 3214
-3 2765 3217 3216
-3 2765 2764 3217
-3 3217 3218 3216
-3 3217 2764 3750
-3 2768 3219 2769
-3 2766 2769 3779
-3 2769 3219 3779
-3 3779 3220 2766
-3 3221 3223 3222
-3 3222 3223 3224
-3 2771 3771 3215
-3 2773 2771 3215
-3 3216 2774 2773
-3 3216 3218 2774
-3 2767 2783 3225
-3 3225 3226 2767
-3 2768 3227 3219
-3 3227 2768 2775
-3 3228 3229 2777
-3 3228 2777 3220
-3 3220 2777 2766
-3 3230 3231 3765
-3 3247 3221 3232
-3 3222 3233 3221
-3 3233 3232 3221
-3 3233 3222 3224
-3 2771 2778 3771
-3 2780 2774 3249
-3 3234 3235 3236
-3 3236 3235 2783
-3 3235 3237 2783
-3 3225 2783 3238
-3 3238 2783 3237
-3 3238 3239 3240
-3 3238 3240 3225
-3 3225 3240 3226
-3 2785 3226 3240
-3 3227 2775 3241
-3 3241 2777 3229
-3 3241 3229 3242
-3 3250 3242 3229
-3 3243 3231 3230
-3 3251 3231 3243
-3 3244 3245 3230
-3 3245 3243 3230
-3 2786 3247 3232
-3 2792 2786 3232
-3 2798 2792 3232
-3 2798 3232 3233
-3 2778 3249 3248
-3 3234 3819 3255
-3 3236 3819 3234
-3 3239 2790 3240
-3 3820 3227 3241
-3 3241 3242 3820
-3 3250 3820 3242
-3 3245 3252 3243
-3 3252 3251 3243
-3 3835 3245 3244
-3 3835 2795 3245
-3 2795 3252 3245
-3 3246 3247 3811
-3 2786 2797 3247
-3 3233 3812 2798
-3 2790 3819 3236
-3 2794 2793 3257
-3 2794 3257 3251
-3 2794 3251 3252
-3 3251 3257 3256
-3 2795 2794 3252
-3 3247 3271 3811
-3 2798 3812 3258
-3 2804 3259 3253
-3 3253 3260 2804
-3 3260 3253 3254
-3 3261 3263 3262
-3 3262 3263 3274
-3 3255 3265 3264
-3 3265 3255 3266
-3 3267 3268 3269
-3 3822 3268 3267
-3 3269 3833 2811
-3 3268 3833 3269
-3 2793 3834 3257
-3 2795 3835 3270
-3 2836 3271 3247
-3 3272 2798 3258
-3 2798 3272 2802
-3 2804 3260 3273
-3 2805 3285 3261
-3 2806 2805 3261
-3 3262 2806 3261
-3 2806 3262 3274
-3 3264 2807 3286
-3 2808 2807 3264
-3 2808 3264 3275
-3 3275 3264 3265
-3 3276 3265 3266
-3 3275 3265 3276
-3 2810 2809 3277
-3 2810 3277 3267
-3 2810 3267 3269
-3 2811 2810 3269
-3 3833 4338 2811
-3 3834 2812 3278
-3 3834 2793 2812
-3 3278 3279 3280
-3 3834 3278 3280
-3 3270 3280 3279
-3 2795 3270 2844
-3 2836 3293 3271
-3 3281 3272 3258
-3 3293 3281 3258
-3 3272 3281 2802
-3 2804 3282 3283
-3 2804 3283 2828
-3 3273 3282 2804
-3 2805 2817 3284
-3 2805 3284 3285
-3 2806 2831 2818
-3 2806 3274 2831
-3 3838 2831 3274
-3 3286 2807 2819
-3 3275 3298 2808
-3 3298 3275 3276
-3 3288 2822 3287
-3 2809 3289 3277
-3 2825 3289 2809
-3 2811 4338 2435
-3 4338 3301 2435
-3 3290 3278 2812
-3 3290 3279 3278
-3 3270 3279 3291
-3 3291 3279 3290
-3 3270 3291 2844
-3 2836 3292 3293
-3 3293 3292 3281
-3 2814 2827 3294
-3 2827 2828 3294
-3 3294 2828 3283
-3 2817 2830 3284
-3 3284 2830 2831
-3 3284 2831 3285
-3 3295 3297 2838
-3 3296 3297 3295
-3 2838 3297 2819
-3 2424 3299 3845
-3 3309 2428 3845
-3 2428 2424 3845
-3 2822 3300 3287
-3 2822 2821 3300
-3 2821 2832 3300
-3 3312 2834 3288
-3 3301 2825 2434
-3 2835 2435 3301
-3 3302 3291 3290
-3 3302 3313 3291
-3 3291 3313 2844
-3 2837 3292 2836
-3 3281 3292 2837
-3 3295 3303 3304
-3 3295 3305 3303
-3 2838 3305 3295
-3 3298 3306 2808
-3 3306 3298 3276
-3 3307 3308 3299
-3 3307 3299 2839
-3 2840 3310 2841
-3 3310 2840 2841
-3 3311 2840 3310
-3 2844 3313 3314
-3 2848 2844 3314
-3 2845 3315 3316
-3 2846 3315 2845
-3 2847 3316 3303
-3 2847 2845 3316
-3 3316 3304 3303
-3 3305 3317 3303
-3 3317 2847 3303
-3 3305 2853 3318
-3 3305 3318 3317
-3 3319 3308 3307
-3 3858 3308 3319
-3 2839 3320 3307
-3 3307 3320 3319
-3 3327 2839 3309
-3 2450 3321 2840
-3 2840 3321 3310
-3 2854 2840 3311
-3 2834 3312 2457
-3 2846 2464 3323
-3 2846 3323 3324
-3 2846 3324 3315
-3 2847 3856 3325
-3 2847 3325 2852
-3 3317 3856 2847
-3 3318 3856 3317
-3 3326 3856 3318
-3 3318 2853 3326
-3 3319 3867 3858
-3 3320 3867 3319
-3 3327 3320 2839
-3 3321 2861 3328
-3 2832 3329 3300
-3 3302 3347 3863
-3 3330 3864 3344
-3 3330 3331 3332
-3 3864 3330 3332
-3 3322 3332 3331
-3 3322 3331 3333
-3 2856 3322 3334
-3 3334 3322 3333
-3 2464 2858 3335
-3 2464 3335 3323
-3 3335 3336 3323
-3 2860 3866 3323
-3 2860 3323 3336
-3 3324 3323 3866
-3 3325 2860 2852
-3 3866 2860 3325
-3 2485 3326 2853
-3 2485 3337 3326
-3 3337 3857 3326
-3 3338 3857 3337
-3 3339 3306 3858
-3 2854 3340 2862
-3 3345 2854 3311
-3 3345 3340 2854
-3 2457 3312 2863
-3 2864 3341 3302
-3 3302 3341 3347
-3 3342 3341 2864
-3 2855 3343 2864
-3 2864 3343 3342
-3 2855 3344 3343
-3 3344 2849 3330
-3 2856 3331 3330
-3 3333 3331 2856
-3 3334 3333 2856
-3 2860 3336 3335
-3 3873 3338 3337
-3 2486 3306 3339
-3 3350 2861 2862
-3 2862 3340 3350
-3 3345 3350 3340
-3 3348 3341 3342
-3 3347 3341 3348
-3 2485 3873 3337
-3 3339 3349 2486
-3 3345 3880 3350
-3 3346 3880 3345
-3 3348 3353 3347
-3 3353 3352 3347
-3 3348 3358 3353
-3 3873 2485 3889
-3 3354 2486 3349
-3 3355 3351 3877
-3 3356 3355 3877
-3 2871 3358 2870
-3 2871 3353 3358
-3 3359 3358 3891
-3 3359 2872 3358
-3 2872 2870 3358
-3 2486 3354 3889
-3 3360 3351 3355
-3 3361 3351 3360
-3 3356 3360 3355
-3 3356 3362 2875
-3 3356 3357 3362
-3 2875 3362 2876
-3 2871 2877 3353
-3 2877 3891 3353
-3 2879 3363 3359
-3 2879 3359 3891
-3 2879 3891 2877
-3 2872 3363 3365
-3 3359 3363 2872
-3 2876 3362 2885
-3 3363 2882 3364
-3 2879 2882 3363
-3 3363 3364 3365
-3 3894 2881 2888
-3 3894 2888 3362
-3 3366 3364 2882
-3 3366 3365 3364
-3 3365 3367 2883
-3 3365 3366 3367
-3 2885 3362 2888
-3 3369 3368 3366
-3 3368 3367 3366
-3 3367 3368 2883
-3 2883 3370 2891
-3 2883 3368 3370
-3 3368 3369 3370
-3 2893 3369 2892
-3 3370 3369 2893
-3 2891 3370 2893
-3 3372 3373 3371
-3 3375 3372 3371
-3 2894 3375 3373
-3 3373 3375 3371
-3 2894 3374 3376
-3 2894 3373 3374
-3 2500 4373 3952
-3 3381 3372 3375
-3 3375 2894 3381
-3 3377 2894 3376
-3 2896 2894 3377
-3 2896 3377 2897
-3 3381 3382 3383
-3 3381 2897 3382
-3 3382 2897 3377
-3 3386 3385 3378
-3 3387 3386 3378
-3 3389 3379 3380
-3 3388 3379 3389
-3 3391 3390 3384
-3 3385 3391 3384
-3 3392 3391 3385
-3 3386 3393 3385
-3 3393 3392 3385
-3 3387 3394 3386
-3 3394 3393 3386
-3 3395 3394 3387
-3 3396 3379 3388
-3 3405 3379 3396
-3 3397 3388 3389
-3 3396 3388 3397
-3 2900 2500 3952
-3 3398 3399 2898
-3 3402 3401 3382
-3 3940 3390 3391
-3 3392 3393 3403
-3 3394 3404 3393
-3 3404 3403 3393
-3 3395 3404 3394
-3 3397 3405 3396
-3 3411 2900 3952
-3 3406 3399 3410
-3 3398 3410 3399
-3 2899 2904 3400
-3 2906 2900 3411
-3 3407 3406 3408
-3 3406 3409 3408
-3 3410 3409 3406
-3 3400 2904 2903
-3 3411 3408 2906
-3 2906 3408 2907
-3 2907 3408 3412
-3 3954 3408 3409
-3 2908 3954 3409
-3 2908 3409 3410
-3 3414 2909 3413
-3 2505 4514 2909
-3 2909 4514 3413
-3 3956 3951 3403
-3 3934 3403 3951
-3 2907 3412 3953
-3 2910 2907 3953
-3 2911 2910 3954
-3 2910 3953 3954
-3 3954 2908 2911
-3 2505 3416 4514
-3 2912 3415 3416
-3 2912 3416 2505
-3 2912 2913 3417
-3 3415 2912 3417
-3 3418 3422 3417
-3 3417 2913 3418
-3 3418 3943 3422
-3 2915 3945 2905
-3 3945 3955 2914
-3 3427 3956 3403
-3 3419 3416 3415
-3 3420 3416 3419
-3 3417 3421 3415
-3 3421 3419 3415
-3 3422 3421 3417
-3 3943 3423 3422
-3 3423 3943 3945
-3 3423 3945 2915
-3 3955 3424 2914
-3 3414 3959 2513
-3 3420 3419 2513
-3 3420 2513 3959
-3 3421 2513 3419
-3 3422 3423 3421
-3 3427 2515 2914
-3 3427 2914 3424
-3 2916 3962 3425
-3 3426 2916 3425
-3 4531 3965 1226
-3 3428 1226 3965
-3 3426 3425 2917
-3 1226 5643 4531
-3 3428 3965 3430
-3 3428 3430 3431
-3 3429 2916 3428
-3 3431 3429 3428
-3 3432 2918 3433
-3 3433 2918 2919
-3 3432 2520 2918
-3 2919 3435 3433
-3 3435 2919 2920
-3 3433 3434 3438
-3 3433 3435 3434
-3 2921 3436 2920
-3 2920 3436 3435
-3 2520 4582 2522
-3 3438 3434 3437
-3 3434 3435 3437
-3 3439 3437 3435
-3 3440 3439 3436
-3 3439 3435 3436
-3 3975 3436 2921
-3 1635 3975 2921
-3 3437 2923 3438
-3 3440 3437 3439
-3 3440 2922 3437
-3 1635 2180 3975
-3 2922 3441 2923
-3 3441 2922 3440
-3 2924 3978 2925
-3 3442 2925 3978
-3 3978 2927 3443
-3 3978 2924 2927
-3 3442 3978 3443
-3 3442 3443 2928
-3 3442 2928 2929
-3 2931 3442 2929
-3 2931 3444 3442
-3 2925 3442 2932
-3 2932 3442 3444
-3 2928 3443 2927
-3 3444 2934 3445
-3 2931 2934 3444
-3 2932 3445 2935
-3 3444 3445 2932
-3 2934 2936 3445
-3 2935 3445 2936
-3 2522 3995 3450
-3 4002 3446 3447
-3 3983 3447 3446
-3 3983 3448 3447
-3 3447 3449 4002
-3 3448 3449 3447
-3 3451 3452 3449
-3 3451 3453 3454
-3 3449 3453 3451
-3 3450 3459 2938
-3 3455 3450 3995
-3 3459 3450 3455
-3 2941 3456 4020
-3 4020 2942 2941
-3 3457 3451 3454
-3 2938 3459 2947
-3 4020 3456 2950
-3 2950 2942 4020
-3 3459 3460 2947
-3 2948 2952 3461
-3 3462 4024 4027
-3 3463 3464 4028
-3 2952 3463 3465
-3 2952 3460 3463
-3 2952 2947 3460
-3 3464 3463 3460
-3 2952 3465 3461
-3 3465 3466 3461
-3 2948 3461 3467
-3 3461 3466 3467
-3 3463 4028 3481
-3 3463 3481 2954
-3 3468 3463 2954
-3 3468 3465 3463
-3 3466 3465 3469
-3 3469 3465 3468
-3 3467 3466 3469
-3 3467 3469 3470
-3 2954 3481 2956
-3 2970 3469 3468
-3 3470 3469 2970
-3 3471 3473 2958
-3 2958 3474 2959
-3 3473 3474 2958
-3 3475 3476 3477
-3 3472 3496 3478
-3 3472 3478 3479
-3 3480 4033 3472
-3 3479 3480 3472
-3 2956 3481 2963
-3 3470 2972 3471
-3 2972 3473 3471
-3 3474 3473 3482
-3 3474 3482 2959
-3 3483 3476 3475
-3 3486 3476 3483
-3 3483 3475 3486
-3 3478 3496 2965
-3 3478 2965 2966
-3 2967 3478 2966
-3 2967 3484 3478
-3 3484 3479 3478
-3 4642 3480 3479
-3 3484 4642 3479
-3 3481 2968 2963
-3 3493 2968 3481
-3 3473 2972 3487
-3 3482 3473 3485
-3 3485 3473 3487
-3 2959 3485 2976
-3 3482 3485 2959
-3 2965 3496 2973
-3 2967 3501 3484
-3 3501 4642 3484
-3 2968 3493 2974
-3 2972 2975 3487
-3 3485 3487 3488
-3 3485 3488 2976
-3 2974 3493 2979
-3 2975 2980 2983
-3 3487 2975 2983
-3 2976 3488 3489
-3 3491 3492 3490
-3 2973 3496 2981
-3 2982 2979 3493
-3 3487 2983 3495
-3 3488 3487 2985
-3 2985 3487 3495
-3 3489 3488 2985
-3 2976 3489 2985
-3 3492 3494 3490
-3 3497 2982 3493
-3 2982 3497 2990
-3 3495 2983 2988
-3 3493 3502 3497
-3 2990 3497 3499
-3 3499 3497 3498
-3 2990 3499 3500
-3 3497 3502 3505
-3 3498 3497 3506
-3 3506 3497 3505
-3 3499 3498 3500
-3 3500 3498 3506
-3 2990 3500 3503
-3 2990 3503 2995
-3 3507 3504 3502
-3 3505 3502 3504
-3 3505 3504 3506
-3 3506 3504 3507
-3 3507 3508 3506
-3 3509 3506 3508
-3 3503 3500 2999
-3 3500 3506 2999
-3 3506 3509 3000
-3 2999 3506 3000
-3 3509 3510 3001
-3 3001 3510 3006
-3 3510 3007 3006
-3 1936 4702 3036
-3 3007 3510 3008
-3 3511 3518 3510
-3 3008 3510 3518
-3 3511 3513 3518
-3 3015 3016 3512
-3 3015 3512 3017
-3 3511 3514 3513
-3 3512 3021 3515
-3 3016 3021 3512
-3 3017 3515 3022
-3 3512 3515 3017
-3 3516 3513 3514
-3 3517 3516 3514
-3 3518 3513 3516
-3 3518 3045 3008
-3 3021 3020 3515
-3 3022 3515 3020
-3 3521 3030 3522
-3 3524 3523 3525
-3 3531 3516 3517
-3 3518 3516 3526
-3 3526 3516 3531
-3 3549 3518 3526
-3 3518 3549 3045
-3 3032 3527 3519
-3 3519 3527 3025
-3 3033 3520 3521
-3 3522 3543 3521
-3 3528 3543 3522
-3 3030 3528 3522
-3 3030 3529 3528
-3 3523 3524 3536
-3 3530 3525 3523
-3 3536 3530 3523
-3 3526 3531 3563
-3 3032 3540 3541
-3 3527 3032 3541
-3 3521 3577 3033
-3 3577 3533 3033
-3 3571 3528 3529
-3 3534 3571 3529
-3 3034 3037 3529
-3 3529 3037 3534
-3 3537 3530 3536
-3 3537 3536 3538
-3 3531 3537 3538
-3 3531 3538 3563
-3 3532 4063 3542
-3 3037 3544 3534
-3 3544 3556 3534
-3 3535 3544 3037
-3 3038 3544 3535
-3 3544 3038 3040
-3 3545 3042 3041
-3 3545 3041 3546
-3 3041 3547 3546
-3 3524 3548 3536
-3 3536 3548 3561
-3 3562 3536 3561
-3 3538 3536 3562
-3 3526 3563 3549
-3 3541 3540 3550
-3 3550 3540 3564
-3 3541 3550 3527
-3 4063 3049 3553
-3 4063 3532 3049
-3 4063 3553 3542
-3 3533 3554 3039
-3 3577 3554 3533
-3 3543 3555 3521
-3 3528 3570 3543
-3 3571 3570 3528
-3 3534 3556 3571
-3 3040 3557 3544
-3 3546 3559 3558
-3 3546 3558 3545
-3 3545 3558 3560
-3 3042 3560 3041
-3 3545 3560 3042
-3 3548 3547 3573
-3 3573 3547 3041
-3 3561 3548 3573
-3 3538 4069 3563
-3 2611 3550 3564
-3 3552 3565 5316
-3 3551 3565 3552
-3 3551 3047 3565
-3 3551 3048 3047
-3 3542 3553 3566
-3 3577 3576 3554
-3 3521 3579 3577
-3 3555 3567 3521
-3 3567 3579 3521
-3 3543 3568 3555
-3 3568 3567 3555
-3 3569 3568 3543
-3 3570 3569 3543
-3 3557 3556 3544
-3 3040 3056 3557
-3 3557 3056 3582
-3 3560 3558 3572
-3 3560 3572 3041
-3 3050 3573 3041
-3 3549 3563 3585
-3 3564 3061 3575
-3 2611 3575 3054
-3 3564 3575 2611
-3 3565 3066 5316
-3 3047 3066 3565
-3 3048 3551 3068
-3 3039 4081 3078
-3 4081 3039 4072
-3 3554 4074 3039
-3 4074 3554 3576
-3 3579 3578 3577
-3 3567 3580 3579
-3 3568 3580 3567
-3 3569 3581 3568
-3 3556 3582 3571
-3 3557 3582 3556
-3 3057 3589 3069
-3 3057 3058 3589
-3 3593 3558 3559
-3 3572 3558 3593
-3 3572 3583 3050
-3 3050 3583 3573
-3 3583 3561 3573
-3 3584 3561 3585
-3 3563 3584 3585
-3 3549 3585 3081
-3 3598 3599 3574
-3 3586 3054 3575
-3 5316 3066 3065
-3 3611 3566 3553
-3 3577 4074 3576
-3 4089 4074 3577
-3 3578 4089 3577
-3 3579 4089 3578
-3 3580 4089 3579
-3 3580 3568 4083
-3 3581 3588 3568
-3 3588 4083 3568
-3 3569 3588 3581
-3 3570 3588 3569
-3 3571 3604 3570
-3 3604 3588 3570
-3 3582 3604 3571
-3 3056 3589 3582
-3 3056 3069 3589
-3 3058 3590 3589
-3 3058 3591 3590
-3 3074 3591 3058
-3 3591 3074 3592
-3 3559 3594 3593
-3 3572 3593 3595
-3 3583 3572 3596
-3 3596 3572 3595
-3 3585 3561 3597
-3 3599 3609 3052
-3 3061 3071 3600
-3 3575 3061 3600
-3 3062 3601 3085
-3 3586 3601 3062
-3 3065 3602 5316
-3 3068 3602 3065
-3 3566 3611 3603
-3 3566 3603 3612
-3 3587 2279 3055
-3 3604 4083 3588
-3 3605 3604 3582
-3 4085 3582 3589
-3 3590 4085 3589
-3 3074 3606 3592
-3 3594 3606 3593
-3 3583 3596 3615
-3 3561 3583 3615
-3 3597 3561 3615
-3 3585 3597 3607
-3 3081 3585 3619
-3 3598 3070 3608
-3 3599 3598 3609
-3 3609 3598 3608
-3 3610 3600 3076
-3 3600 3071 3076
-3 3601 3076 3085
-3 3553 3088 3611
-3 3603 3611 3612
-3 5338 3587 2278
-3 3613 3606 3074
-3 3613 3593 3606
-3 3595 3593 3613
-3 3596 3595 3614
-3 3614 3595 3613
-3 3615 3596 3614
-3 3597 3615 3617
-3 3617 3615 3616
-3 3607 3597 3618
-3 3618 3597 3617
-3 3585 3607 3625
-3 3625 3607 3618
-3 3619 3585 3625
-3 3626 3608 3070
-3 3609 3608 3620
-3 3620 3608 3626
-3 3612 3611 3621
-3 3621 3611 3088
-3 3078 4081 4097
-3 3622 3613 3080
-3 3622 3614 3613
-3 3615 3614 3623
-3 3623 3614 3622
-3 3623 4697 3616
-3 3623 3616 3615
-3 3617 3616 4697
-3 3624 3617 4697
-3 3617 3624 3618
-3 3625 3618 3624
-3 3627 3612 3621
-3 4672 3612 3627
-3 3094 3644 3622
-3 3644 3623 3622
-3 3644 3636 3623
-3 3625 3624 3628
-3 3619 3625 3629
-3 3639 3619 3629
-3 3630 3619 3639
-3 3089 3631 3626
-3 3621 3088 3632
-3 3632 4116 3621
-3 4116 4117 3621
-3 3627 3621 3633
-3 3633 3621 4117
-3 3643 4672 3627
-3 3643 3627 3633
-3 2279 3635 3634
-3 4115 3637 3628
-3 3625 3628 3638
-3 3638 3628 3637
-3 3629 3625 3639
-3 3639 3625 3638
-3 3630 3639 3649
-3 3089 3630 3640
-3 3640 3630 3649
-3 3641 3089 3640
-3 3631 3089 3641
-3 3116 3626 3631
-3 4117 3643 3633
-3 3094 3098 3644
-3 3645 3636 3644
-3 3645 3644 3646
-3 3645 3646 4115
-3 3637 4115 3646
-3 3637 3646 3099
-3 3100 3637 3099
-3 3638 3637 3100
-3 3647 3638 3100
-3 3647 3639 3638
-3 3648 3639 3647
-3 3649 3639 3648
-3 3640 3649 3650
-3 3650 3641 3640
-3 3651 3116 3631
-3 3632 3642 3105
-3 4116 3632 3652
-3 3652 3632 3105
-3 3098 3102 3644
-3 3649 3648 3654
-3 3654 3648 3647
-3 3654 3650 3649
-3 4694 4168 3655
-3 3634 4694 3655
-3 3653 3634 3655
-3 3656 3653 3655
-3 3634 3653 3656
-3 3102 3657 3644
-3 3646 3644 3662
-3 3662 3644 3657
-3 3658 3650 3654
-3 3664 3116 3651
-3 3659 3660 3111
-3 3104 3672 3105
-3 3672 3652 3105
-3 3662 3657 3661
-3 3654 3115 3658
-3 3658 3115 3663
-3 3118 4162 3660
-3 3659 3118 3660
-3 3120 3665 3666
-3 3120 3111 3665
-3 4163 3652 3672
-3 3655 4168 3121
-3 3663 3115 3676
-3 3663 3676 3677
-3 3664 3668 3125
-3 3669 4162 3118
-3 3669 3118 3126
-3 3126 3127 3670
-3 3127 3120 3666
-3 3127 3666 3670
-3 3670 3666 3129
-3 3129 3665 3128
-3 3129 3666 3665
-3 3671 3128 3665
-3 3671 3132 3128
-3 4163 3672 3673
-3 4163 3674 3667
-3 3675 3667 3674
-3 4170 3667 3675
-3 3662 3661 3158
-3 3668 3677 3676
-3 3668 3676 3136
-3 3125 3668 3136
-3 3126 3678 3669
-3 3670 3678 3126
-3 3129 3678 3670
-3 3129 3128 3678
-3 3141 3679 3671
-3 3141 3671 3678
-3 3141 3678 3128
-3 3132 3671 3680
-3 3680 3671 3679
-3 3132 3143 3142
-3 3132 3680 3143
-3 3673 3672 3674
-3 4163 3673 3674
-3 3675 3674 3681
-3 3153 3679 3141
-3 3680 3679 3153
-3 3143 3680 3153
-3 3171 3681 3674
-3 3704 4170 3675
-3 3121 4168 3682
-3 3161 3688 3152
-3 3138 3152 3689
-3 3689 3152 3688
-3 3689 4189 3139
-3 3689 3139 3138
-3 3690 3139 4189
-3 3675 3681 3691
-3 3682 3706 3692
-3 3156 3165 3694
-3 3155 3165 3156
-3 4193 3684 3694
-3 3694 3684 3156
-3 4195 3684 4193
-3 3686 4196 3685
-3 3695 4196 3686
-3 3687 3695 3686
-3 3157 3696 3166
-3 3688 3161 3697
-3 3177 3170 4833
-3 4833 3170 3690
-3 3180 3691 3681
-3 3704 3691 3180
-3 3675 3691 3704
-3 3717 4180 3704
-3 3692 3706 3720
-3 3165 2719 3694
-3 4193 3694 2719
-3 3684 4195 3714
-3 3699 3700 3701
-3 3173 3701 3696
-3 3173 3699 3701
-3 3702 3175 3701
-3 3696 3701 3175
-3 3696 3175 3166
-3 3161 3703 3697
-3 3177 3703 3161
-3 3703 3177 4833
-3 3717 3704 3198
-3 3705 4180 3717
-3 3692 3720 3707
-3 3682 3692 3707
-3 3708 3710 3711
-3 3709 3710 3708
-3 3710 3712 3711
-3 4841 4193 2719
-3 3714 3727 3713
-3 3715 3700 3699
-3 3173 3185 3715
-3 3173 3715 3699
-3 4190 3705 3718
-3 3706 4190 3718
-3 3719 3706 3718
-3 3720 3706 3719
-3 3183 3721 3184
-3 3184 3728 2708
-3 3721 3728 3184
-3 2708 3728 2718
-3 3708 3722 3709
-3 3722 3723 3724
-3 3722 3708 3723
-3 3708 3711 3723
-3 3725 3711 3712
-3 3723 3711 3725
-3 4841 2719 3726
-3 3185 4211 3715
-3 4211 3185 3716
-3 3705 3717 3731
-3 3718 3705 3731
-3 3720 3719 3718
-3 3183 3186 3721
-3 3728 3189 2718
-3 3723 3729 3724
-3 3725 3729 3723
-3 4841 3726 4223
-3 3726 3713 4223
-3 3727 3730 3713
-3 3730 4223 3713
-3 3187 3189 3733
-3 3733 3189 3728
-3 3734 3186 3732
-3 3188 3734 3732
-3 3188 3735 3734
-3 3188 3187 3735
-3 3735 3187 3733
-3 3193 3192 3736
-3 3193 3737 3194
-3 3736 3737 3193
-3 3194 3738 3196
-3 3737 3738 3194
-3 3196 3738 3197
-3 3199 3736 3192
-3 3737 3736 3199
-3 3200 3737 3199
-3 3738 3737 3200
-3 3197 3738 3200
-3 3202 3206 4254
-3 3206 4253 4254
-3 3202 4254 3740
-3 3202 3740 3739
-3 3739 3740 3208
-3 4253 3206 3209
-3 3741 4253 3209
-3 3740 4254 3742
-3 3740 3742 3213
-3 3208 3740 3213
-3 3743 3744 3745
-3 3745 3746 3743
-3 3212 3747 3741
-3 3212 3741 3209
-3 3212 3213 3748
-3 3742 3748 3213
-3 3749 3750 3214
-3 3743 3746 3761
-3 3751 3752 3746
-3 3752 3761 3746
-3 3752 3753 3754
-3 3751 3753 3752
-3 3741 3755 3756
-3 3741 3747 3755
-3 3212 3757 3747
-3 3758 3748 4268
-3 3758 3757 3748
-3 3757 3212 3748
-3 3215 3749 3214
-3 3215 3759 3749
-3 3750 3749 3760
-3 3760 3749 3759
-3 3217 3760 3218
-3 3217 3750 3760
-3 3754 3762 3752
-3 3762 3761 3752
-3 3774 3754 3753
-3 3762 3754 3774
-3 3219 3778 3779
-3 3763 4266 4262
-3 4267 3764 4262
-3 3764 3763 4262
-3 3765 3764 4267
-3 3223 3221 3766
-3 3756 3755 3223
-3 3756 3223 3766
-3 3224 3223 3755
-3 3224 3755 3767
-3 3767 3755 3747
-3 3757 3768 3747
-3 3768 3767 3747
-3 3758 3769 3757
-3 3769 3768 3757
-3 3769 3770 3771
-3 3758 3770 3769
-3 3770 3772 3771
-3 3771 3772 3215
-3 3759 3215 3772
-3 3760 3759 2774
-3 3760 2774 3218
-3 3761 3762 3773
-3 3774 3775 3762
-3 3775 3773 3762
-3 3775 4277 3776
-3 3774 4277 3775
-3 3234 3777 3235
-3 3778 3219 3227
-3 3778 3227 4278
-3 3220 3779 3228
-3 3228 3779 4279
-3 4279 3229 3228
-3 3780 4266 3763
-3 3764 3781 3763
-3 3781 3780 3763
-3 3765 3231 3781
-3 3765 3781 3764
-3 3765 3796 3230
-3 3782 3783 3246
-3 3246 3783 3247
-3 3783 3766 3247
-3 3766 3221 3247
-3 3224 3767 3233
-3 3784 3768 3785
-3 3784 3767 3768
-3 3769 3785 3768
-3 3786 3785 3769
-3 3769 3771 3786
-3 3801 3786 3771
-3 3771 2778 3801
-3 4285 3249 2774
-3 3775 3790 3773
-3 3790 3789 3773
-3 3776 3790 3775
-3 3791 3776 4277
-3 3791 3790 3776
-3 3234 3255 3807
-3 3235 3777 3793
-3 3794 3237 3793
-3 3237 3235 3793
-3 3237 3239 3238
-3 3794 3239 3237
-3 4278 3227 3795
-3 3229 4279 3821
-3 3250 3229 3821
-3 3780 3781 4294
-3 3231 3251 4294
-3 3781 3231 4294
-3 3244 3230 3796
-3 4296 3783 3797
-3 3783 3782 3797
-3 3246 3797 3782
-3 3767 4297 3798
-3 3767 3798 3233
-3 3233 3798 3812
-3 3784 4297 3767
-3 3802 3801 2778
-3 2778 3248 3802
-3 3248 3249 4285
-3 3248 4285 3802
-3 3254 3803 3787
-3 3787 3260 3254
-3 3804 3787 3788
-3 3804 3260 3787
-3 3805 3790 3791
-3 3792 3805 3791
-3 3807 3255 3806
-3 3794 3819 2790
-3 3239 3794 2790
-3 3795 3227 3820
-3 4294 3251 3823
-3 3808 3835 3244
-3 3808 3244 3809
-3 3809 3244 3796
-3 3810 4296 3797
-3 3811 3810 3797
-3 3246 3811 3797
-3 3812 3813 4306
-3 3812 3798 3813
-3 3803 3254 3814
-3 3814 3254 3253
-3 4314 3260 3804
-3 3817 3831 3818
-3 3255 3264 3806
-3 3821 3820 3250
-3 3821 3822 3820
-3 3822 3833 3268
-3 3821 3833 3822
-3 3256 3823 3251
-3 3257 3824 3825
-3 3257 3825 3256
-3 3256 3825 3823
-3 3809 3825 3824
-3 3809 3824 3808
-3 3808 3824 3826
-3 3808 3826 3835
-3 3827 3810 3811
-3 3811 3271 3827
-3 3812 4306 3830
-3 3258 3830 3829
-3 3258 3812 3830
-3 4320 3253 3259
-3 3260 4314 3273
-3 3261 3815 3816
-3 3263 3261 3816
-3 3817 3263 3816
-3 3818 3263 3817
-3 3274 3263 3818
-3 3274 3818 3831
-3 3264 3286 3806
-3 3255 3819 3266
-3 3795 3820 3843
-3 3822 3267 3843
-3 3822 3843 3820
-3 3257 3834 3824
-3 3834 3826 3824
-3 3826 3834 3835
-3 3271 3836 3828
-3 3830 3836 3829
-3 3829 3836 3837
-3 3829 3837 3258
-3 3259 2814 4330
-3 4330 4320 3259
-3 3273 4314 4332
-3 3261 3285 3815
-3 3831 3838 3274
-3 3839 3831 3832
-3 3839 3840 3831
-3 3840 3838 3831
-3 3286 3842 3806
-3 3267 3277 3843
-3 3835 3834 3280
-3 3270 3835 3280
-3 3293 3836 3271
-3 3293 3837 3836
-3 3837 3293 3258
-3 2814 3294 4331
-3 2814 4331 4330
-3 3294 3283 3282
-3 3294 3282 4331
-3 4331 3282 4332
-3 4332 3282 3273
-3 3815 3285 4347
-3 4348 3838 4340
-3 3840 4340 3838
-3 3841 3296 4335
-3 3844 3297 3841
-3 3297 3296 3841
-3 3844 3286 2819
-3 3844 4342 3286
-3 4342 3842 3286
-3 3266 4336 3276
-3 3288 3287 4913
-3 3287 4337 4913
-3 3312 3288 4913
-3 3277 3846 3843
-3 3289 3846 3277
-3 4338 4345 3301
-3 3285 2831 4347
-3 4348 4347 2831
-3 3838 4348 2831
-3 3296 3295 4335
-3 3844 2819 3297
-3 3287 3300 3850
-3 3287 3850 4337
-3 2825 3846 3289
-3 2825 3301 3846
-3 3846 3301 4345
-3 3863 3847 3302
-3 3847 3853 3302
-3 3853 3313 3302
-3 3304 3856 4335
-3 3295 3304 4335
-3 3848 3306 4336
-3 4336 3306 3276
-3 3299 3308 3848
-3 3845 3299 3848
-3 3309 3845 4357
-3 3310 3849 3311
-3 3851 3847 3863
-3 3314 3313 4361
-3 3313 3853 4361
-3 3314 4361 4362
-3 3854 3314 4362
-3 3316 3315 3855
-3 3316 3855 3856
-3 3316 3856 3304
-3 3306 3848 3858
-3 3848 3308 3858
-3 3309 4357 3859
-3 3309 3859 3327
-3 3849 3321 3860
-3 3310 3321 3849
-3 3311 3849 3861
-3 3849 3860 3861
-3 3862 3852 3851
-3 3863 3862 3851
-3 3314 3854 3864
-3 3314 3865 3322
-3 3864 3865 3314
-3 3855 3324 3866
-3 3315 3324 3855
-3 3325 3856 3855
-3 3325 3855 3866
-3 3326 4364 3856
-3 3857 4364 3326
-3 3327 3867 3320
-3 3860 3328 3868
-3 3321 3328 3860
-3 3868 4374 3861
-3 3868 3861 3860
-3 3311 3861 4374
-3 3311 4374 3869
-3 3850 3300 3329
-3 3347 3862 3863
-3 3871 3343 3870
-3 3864 3870 3343
-3 3344 3864 3343
-3 3865 3864 3332
-3 3322 3865 3332
-3 3858 3867 3339
-3 3328 2861 3868
-3 2861 3874 3868
-3 3311 3869 3345
-3 3345 3872 3877
-3 3345 3869 3872
-3 3872 3876 3877
-3 2863 4378 3329
-3 4378 2863 3312
-3 3347 3878 3862
-3 3343 3871 3342
-3 3338 3873 3857
-3 3867 3879 3339
-3 2861 3350 3874
-3 3877 3875 3346
-3 3345 3877 3346
-3 3342 4399 3348
-3 4395 3857 3873
-3 4395 3349 3879
-3 3349 3339 3879
-3 3880 3874 3350
-3 3880 3346 3875
-3 3880 3875 3881
-3 3877 3351 3881
-3 3877 3881 3875
-3 3877 3876 3356
-3 3882 3352 3883
-3 3882 3878 3352
-3 3878 3347 3352
-3 3348 3883 3884
-3 3348 4399 3883
-3 3882 3883 4399
-3 3348 3884 3358
-3 3885 3887 3888
-3 3886 3887 3885
-3 3887 4407 3888
-3 3889 4395 3873
-3 3354 3349 3889
-3 3349 4395 3889
-3 3874 3880 3361
-3 3880 3881 3361
-3 3881 3351 3361
-3 3356 3876 3357
-3 3876 3362 3357
-3 3353 3883 3352
-3 3353 3890 3883
-3 3890 3884 3883
-3 3358 3884 3891
-3 3884 3890 3891
-3 3893 3885 3892
-3 3892 3888 4407
-3 3892 3885 3888
-3 3891 3890 3353
-3 3361 3360 3894
-3 2881 3894 3360
-3 3896 3895 3898
-3 3895 3899 3898
-3 3900 3899 3895
-3 3904 3903 3897
-3 3903 3910 3897
-3 3899 3905 3898
-3 3906 3905 3899
-3 3900 3906 3899
-3 3906 3900 3907
-3 3900 3901 3907
-3 3908 3901 3902
-3 3907 3901 3908
-3 3909 3905 3906
-3 3909 3898 3905
-3 3904 3910 3903
-3 3913 3373 3372
-3 3374 3911 3376
-3 3374 3913 3911
-3 3374 3373 3913
-3 3912 3914 3911
-3 3914 3376 3911
-3 3916 3913 3372
-3 3376 3914 4473
-3 3372 3381 3916
-3 3376 4473 4486
-3 3376 4486 3377
-3 3920 3921 3919
-3 3916 3381 3929
-3 3377 4486 3382
-3 3384 3918 3917
-3 3385 3384 3917
-3 3917 5068 3385
-3 4476 3378 3385
-3 3378 3926 3387
-3 3378 4476 3926
-3 3379 3922 3380
-3 3923 3920 3919
-3 3924 3920 3923
-3 3925 3919 3921
-3 3923 3919 3925
-3 3922 3379 3927
-3 3380 3927 3389
-3 3922 3927 3380
-3 3923 2899 3924
-3 3923 3925 3928
-3 3923 3928 2899
-3 3929 3381 3383
-3 3929 3383 3401
-3 3401 3383 3382
-3 4506 3402 3382
-3 3384 3390 3918
-3 3387 3926 3395
-3 3927 3405 3930
-3 3379 3405 3927
-3 3389 3930 3397
-3 3927 3930 3389
-3 2898 3399 3924
-3 3399 3935 3924
-3 3400 2898 3924
-3 3924 2899 3400
-3 2899 3928 3936
-3 4506 3932 3402
-3 4506 3939 3932
-3 3933 3390 3940
-3 3940 3391 3942
-3 3391 3392 3934
-3 3942 3391 3934
-3 3392 3403 3934
-3 3397 3930 3405
-3 3407 3935 3406
-3 3931 3935 3407
-3 3399 3406 3935
-3 3401 3402 3937
-3 3402 3932 3937
-3 3937 3932 3938
-3 3939 3938 3932
-3 3940 3939 3933
-3 3942 3941 3940
-3 3934 3951 3942
-3 3931 3408 3952
-3 3407 3408 3931
-3 3943 3418 2899
-3 3943 2899 3936
-3 3937 5130 3401
-3 5130 3937 3946
-3 3937 3938 3946
-3 3939 3947 3938
-3 3947 3946 3938
-3 3948 3947 3939
-3 3940 3949 3939
-3 3949 3948 3939
-3 3941 3950 3940
-3 3950 3949 3940
-3 3942 3951 3941
-3 3951 3950 3941
-3 3408 3411 3952
-3 3408 3953 3412
-3 3953 3408 3954
-3 3413 4514 4511
-3 3944 3945 3943
-3 5130 3946 3956
-3 3946 3947 3956
-3 3948 3956 3947
-3 3949 3956 3948
-3 3951 3956 3949
-3 3950 3951 3949
-3 3957 4511 4513
-3 3957 3414 4511
-3 3414 3413 4511
-3 3427 5130 3956
-3 3414 3957 3958
-3 3957 4513 3958
-3 3414 3958 3959
-3 4514 3416 3960
-3 3960 3416 3420
-3 3960 3420 3959
-3 3960 3959 3961
-3 3960 3961 4525
-3 3427 3964 5130
-3 2917 3425 3962
-3 3963 3959 3958
-3 3961 3959 3963
-3 4525 3961 3963
-3 3427 3424 3964
-3 3966 2916 3429
-3 3430 3965 4529
-3 3431 3430 3966
-3 3429 3431 3966
-3 3967 3969 3970
-3 3968 3967 3970
-3 4532 3968 3970
-3 3971 4532 3970
-3 3970 3969 4545
-3 4548 3971 3970
-3 2520 3432 4578
-3 3432 3972 4578
-3 3433 3972 3432
-3 3433 3438 3972
-3 2520 4578 4582
-3 3438 3973 3972
-3 3440 3436 4588
-3 4588 3436 3975
-3 3974 3973 2923
-3 3973 3438 2923
-3 3974 3440 4588
-3 4588 3975 3977
-3 2923 3441 3974
-3 3440 3974 3441
-3 3980 3977 3975
-3 3975 2180 3980
-3 3980 3979 3977
-3 4601 3980 2180
-3 4582 3986 2522
-3 3984 3981 3983
-3 3982 3983 3981
-3 3983 3982 4605
-3 3983 3985 3984
-3 3983 3446 3985
-3 3986 3987 2522
-3 3987 3995 2522
-3 3987 3986 3988
-3 3988 3986 3989
-3 3986 3990 3989
-3 3446 4002 3991
-3 3446 3991 3985
-3 3983 4605 3448
-3 4605 4611 3448
-3 2180 4051 5237
-3 3992 3993 3994
-3 3994 3993 4621
-3 3987 3996 3995
-3 3988 3997 3987
-3 3997 3996 3987
-3 3998 3989 3999
-3 3998 3997 3989
-3 3997 3988 3989
-3 3999 4000 4012
-3 3999 3989 4000
-3 4001 4000 3990
-3 3990 4000 3989
-3 4002 3449 4003
-3 4003 4004 4002
-3 4611 3449 3448
-3 4003 3449 4611
-3 3994 4006 4005
-3 3994 4005 3992
-3 3992 4005 4007
-3 3993 3992 4008
-3 4008 3992 4007
-3 4022 4621 3993
-3 4008 4022 3993
-3 4009 3995 3996
-3 4010 3997 4011
-3 4010 4009 3997
-3 4009 3996 3997
-3 3998 4011 3997
-3 4001 4012 4000
-3 4013 4002 3452
-3 4013 3991 4002
-3 3452 4002 3449
-3 4004 4014 4002
-3 3449 4002 4014
-3 3453 3449 4015
-3 3449 4014 4015
-3 4015 3454 3453
-3 4016 3454 4015
-3 4017 4005 4006
-3 4007 4005 4018
-3 4018 4005 4017
-3 4022 4008 4018
-3 4018 4008 4007
-3 4009 4019 3455
-3 3995 4009 3455
-3 4019 4009 4010
-3 3451 4013 3452
-3 3457 4631 3451
-3 3451 4631 4013
-3 4016 3457 3454
-3 4631 3457 4016
-3 4021 4006 4031
-3 4017 4006 4021
-3 4017 4021 3458
-3 4017 4022 4018
-3 3459 3455 4019
-3 3459 4019 4023
-3 4023 4019 3461
-3 3461 4019 4010
-3 4021 4031 4024
-3 3458 4021 4025
-3 4021 4024 4025
-3 3458 4025 4017
-3 4022 4017 4025
-3 4023 4026 3460
-3 3459 4023 3460
-3 3461 4026 4023
-3 4024 4031 4027
-3 3462 4025 4024
-3 3464 3460 4026
-3 3464 4026 4028
-3 4028 4026 4029
-3 3461 4030 4026
-3 4030 4029 4026
-3 4030 3461 4010
-3 3481 4028 4032
-3 4032 4028 4029
-3 4030 4032 4029
-3 4033 4031 3472
-3 4033 4027 4031
-3 3462 4027 4033
-3 3477 3476 4034
-3 3477 4034 3475
-3 3472 4031 3496
-3 4033 3480 4642
-3 3462 4033 4642
-3 3476 3486 4034
-3 3475 4034 3486
-3 3493 3481 4032
-3 3493 4032 4647
-3 4647 4032 4629
-3 4035 4036 4636
-3 4636 4037 4035
-3 4038 4039 4036
-3 4035 4038 4036
-3 4035 3490 4038
-3 4035 3491 3490
-3 3491 4040 3492
-3 3491 4037 4040
-3 3491 4035 4037
-3 4040 4638 3492
-3 4041 4039 4038
-3 3490 3494 4042
-3 3490 4042 4038
-3 4038 4042 4041
-3 3494 4043 4042
-3 3492 4043 3494
-3 3492 4044 4043
-3 4638 4044 3492
-3 4045 4039 4041
-3 4042 4046 4041
-3 4046 4045 4041
-3 4046 4042 4043
-3 4045 4047 4039
-3 4046 4047 4045
-3 4647 3502 3493
-3 3502 4647 3507
-3 4642 3501 5261
-3 3507 4647 4050
-3 4050 3508 3507
-3 3509 3508 4050
-3 3496 4702 1936
-3 5261 3501 4052
-3 3510 3509 4050
-3 4050 5269 3510
-3 3510 4053 3511
-3 3510 5269 4053
-3 3511 4053 3514
-3 4052 3532 5285
-3 3514 4054 3517
-3 4053 4054 3514
-3 4055 3524 3525
-3 4056 4055 3525
-3 3517 4054 3531
-3 5285 3532 4057
-3 4058 5285 4057
-3 4059 3524 4055
-3 3525 3530 4056
-3 4056 3530 4060
-3 4054 4061 3531
-3 3532 3542 4057
-3 4059 4066 3524
-3 3530 4062 4060
-3 3537 4062 3530
-3 4061 3537 3531
-3 4062 3537 4061
-3 3542 3566 4057
-3 4058 4057 3566
-3 3547 4065 3546
-3 3546 4065 4064
-3 3548 4066 3547
-3 3547 4066 4065
-3 4066 3548 3524
-3 4067 3551 3552
-3 3546 4064 3559
-3 3562 3561 4068
-3 3562 4069 3538
-3 4068 4069 3562
-3 4067 3552 5316
-3 4672 4058 3566
-3 4676 3559 4064
-3 4068 3584 4071
-3 3561 3584 4068
-3 3563 4069 4071
-3 4069 4068 4071
-3 3551 4070 3068
-3 4072 3039 4073
-3 3039 4074 4073
-3 3563 4071 3584
-3 3586 3575 4678
-3 4075 3586 4678
-3 4073 4082 4072
-3 4074 4082 4073
-3 4089 3580 4083
-3 4077 3559 4676
-3 4077 3594 3559
-3 4678 3575 3600
-3 4078 4678 3600
-3 3586 4075 3601
-3 4075 4079 3601
-3 5316 3602 4080
-3 4080 3602 4070
-3 4070 3602 3068
-3 3612 4672 3566
-3 3587 4076 5326
-3 4076 3587 5338
-3 4082 4081 4072
-3 4084 3604 3605
-3 4085 3590 3592
-3 3591 3592 3590
-3 3592 3606 4690
-3 3606 3594 4690
-3 4690 3594 4077
-3 3610 4087 4086
-3 3610 4086 4078
-3 3610 4078 3600
-3 3610 3076 4087
-3 4079 3076 3601
-3 4686 3076 4079
-3 5326 2279 3587
-3 4082 4097 4081
-3 4083 3604 4122
-3 3582 4108 3605
-3 3592 4099 4085
-3 4099 3592 4695
-3 4090 4078 4092
-3 4091 4078 4090
-3 4078 4086 4092
-3 4086 4093 4092
-3 4093 4087 4094
-3 4093 4086 4087
-3 3076 4094 4087
-3 3076 4686 4094
-3 4683 3634 3635
-3 3604 4105 4122
-3 4107 4105 3604
-3 4084 4107 3604
-3 4098 4107 4084
-3 3605 4098 4084
-3 4108 4098 3605
-3 4720 4108 3582
-3 3582 4085 4720
-3 4099 4720 4085
-3 3623 4100 4697
-3 3628 3624 4697
-3 4090 4101 4091
-3 4092 4101 4090
-3 4093 4101 4092
-3 4111 4095 4102
-3 4103 4095 4096
-3 4102 4095 4103
-3 4082 4112 4097
-3 4074 4112 4082
-3 4089 4104 4074
-3 4083 4122 4089
-3 4122 4121 4089
-3 4107 4106 4105
-3 4124 4107 4098
-3 4108 4124 4098
-3 4720 4099 4704
-3 4721 4099 4695
-3 3623 3636 4100
-3 4100 3636 4114
-3 4110 4111 4102
-3 4110 4102 4103
-3 4672 3643 4118
-3 4672 4118 4714
-3 3634 4683 4694
-3 4104 4112 4074
-3 4104 4089 4733
-3 4105 4746 4122
-3 4106 4746 4105
-3 4107 4123 4106
-3 4124 4123 4107
-3 4108 4141 4124
-3 4099 4721 4704
-3 4113 4114 3636
-3 4128 4115 3628
-3 4109 3631 3641
-3 4109 4725 3631
-3 4714 4118 4119
-3 4714 4119 4132
-3 1697 4097 4120
-3 4120 4097 4112
-3 4120 4104 4731
-3 4120 4112 4104
-3 4121 4733 4089
-3 4125 4734 4721
-3 4126 4114 4113
-3 4136 4114 4126
-3 3636 3645 4127
-3 3636 4127 4113
-3 4113 4127 4126
-3 4115 4128 3645
-3 4127 3645 4128
-3 3641 3650 4109
-3 4109 3650 5374
-3 4725 3651 3631
-3 4138 3651 4725
-3 4117 4116 3652
-3 3652 4129 4117
-3 4117 4130 3643
-3 4117 4129 4130
-3 3643 4130 4118
-3 4131 4132 4118
-3 4118 4132 4119
-3 5338 2278 3683
-3 1697 4120 4731
-3 4121 4134 4733
-3 4134 4133 4733
-3 4766 4134 4122
-3 4134 4121 4122
-3 4746 4106 4782
-3 4123 4782 4106
-3 4124 4135 4123
-3 4141 4135 4124
-3 4136 4126 4137
-3 4127 4137 4126
-3 4142 4127 4128
-3 4129 3652 4148
-3 4130 4129 4139
-3 4139 4129 4148
-3 4140 4130 4139
-3 4118 4130 4140
-3 4755 4118 4140
-3 4131 4118 4755
-3 4741 4132 4758
-3 4135 4141 4123
-3 4141 4782 4123
-3 4136 4137 4154
-3 4127 4142 4137
-3 4142 4154 4137
-3 3658 5374 3650
-3 3651 4138 3664
-3 4143 4147 4145
-3 4144 4147 4143
-3 4146 4145 4147
-3 3111 3660 4774
-3 4845 3036 4702
-3 4139 4148 4149
-3 4150 4140 4139
-3 4150 4139 4149
-3 4152 4153 4166
-3 1697 4731 4780
-3 4155 4154 4142
-3 4156 5374 3658
-3 3658 3663 4156
-3 4157 4144 4143
-3 4158 4144 4157
-3 4145 4159 4143
-3 4159 4157 4143
-3 4160 4159 4145
-3 4146 4160 4145
-3 4147 4161 4146
-3 4161 4160 4146
-3 3660 4162 4147
-3 4162 4161 4147
-3 3111 4774 4802
-3 3665 3111 4802
-3 3652 4163 4148
-3 4149 4148 4164
-3 4164 4148 4163
-3 4150 4149 3667
-3 3667 4149 4164
-3 4151 4150 3667
-3 4151 3667 4775
-3 3667 4171 4775
-3 4165 4166 4167
-3 4166 4165 4152
-3 3663 4806 4786
-3 3663 4786 4156
-3 3663 3677 4806
-3 3664 4806 3668
-3 3664 4138 4806
-3 4157 4800 4158
-3 4159 4800 4157
-3 4160 4800 4159
-3 4172 4800 4160
-3 4161 4172 4160
-3 4162 3669 4161
-3 3665 4802 3671
-3 3667 4164 4163
-3 3667 4170 4171
-3 4167 4171 4170
-3 4167 4170 4165
-3 4165 4170 4152
-3 4763 3682 4168
-3 3668 4806 3677
-3 3669 4172 4161
-3 3678 4172 3669
-3 3678 4801 4172
-3 4802 4801 3678
-3 3671 4802 3678
-3 4170 3704 4152
-3 4762 4152 3704
-3 4763 4184 3682
-3 4173 4174 4175
-3 4175 4176 4177
-3 4174 4176 4175
-3 4176 4178 4177
-3 3704 4180 4762
-3 4181 4182 4183
-3 3706 3682 4184
-3 4175 4174 4173
-3 4177 4174 4175
-3 1697 4780 4838
-3 4179 4185 3685
-3 3685 4185 3686
-3 4185 3687 3686
-3 4186 3687 4185
-3 4187 4815 4188
-3 4188 3689 3688
-3 4188 4815 3689
-3 3689 4815 4189
-3 4190 4181 4180
-3 4182 4181 4190
-3 4183 4182 4190
-3 4184 4183 4190
-3 3706 4184 4190
-3 4192 3693 4191
-3 4193 4194 4195
-3 3685 4196 4835
-3 3695 3687 4197
-3 3687 4186 4197
-3 4188 4198 4187
-3 3688 4198 4188
-3 3688 3697 4198
-3 3690 4189 4833
-3 4190 4180 3705
-3 3693 4199 4191
-3 4192 3698 3693
-3 4192 4199 3698
-3 3693 3698 4199
-3 4204 4194 4193
-3 4195 4194 4204
-3 4835 4196 4200
-3 3695 4200 4196
-3 4201 3701 4197
-3 4201 4202 3701
-3 4197 3701 3695
-3 3700 4200 3701
-3 3695 3701 4200
-3 3701 4202 3702
-3 3697 4832 4198
-3 3697 3703 4832
-3 4833 4832 3703
-3 3709 4203 3710
-3 3710 4203 3712
-3 4193 4841 4204
-3 4205 4195 4204
-3 3714 4195 4205
-3 3714 4205 4206
-3 4202 4207 4208
-3 4202 4201 4207
-3 4208 4207 3715
-3 4200 3700 4207
-3 3715 4207 3700
-3 3702 4202 4208
-3 3702 4208 4837
-3 3702 4837 3175
-3 4837 4208 4209
-3 4837 3716 3175
-3 3683 2278 4237
-3 3683 4237 4823
-3 3724 3709 3722
-3 3724 4210 3709
-3 4210 4203 3709
-3 3712 4210 3725
-3 4203 4210 3712
-3 4206 4846 3727
-3 4206 3727 3714
-3 4208 4211 4209
-3 4208 3715 4211
-3 4837 4211 3716
-3 3721 4212 5455
-3 3721 3186 4212
-3 3721 5455 4213
-3 4213 3728 3721
-3 4850 1697 4838
-3 3724 3729 4210
-3 3725 4210 3729
-3 4214 4215 4216
-3 4216 4217 4214
-3 4846 4229 3730
-3 3727 4846 3730
-3 4218 4219 4212
-3 4218 4212 3186
-3 3733 3728 4213
-3 4220 4215 4214
-3 4221 4215 4220
-3 4217 4222 4214
-3 4222 4220 4214
-3 4223 3730 4229
-3 4224 4219 4218
-3 4225 4219 4224
-3 3186 3734 4224
-3 4218 3186 4224
-3 3735 3733 4236
-3 4220 4226 4221
-3 4222 4226 4220
-3 4227 4226 4222
-3 4229 4228 4223
-3 4232 4245 4234
-3 4233 4245 4232
-3 4248 4225 4224
-3 4235 4225 4248
-3 3734 4236 4224
-3 4224 4236 4248
-3 3735 4236 3734
-3 4229 4238 4228
-3 4239 4229 4846
-3 4239 4238 4229
-3 4239 4231 4240
-3 4231 4230 4240
-3 4230 4241 4240
-3 4242 4230 4231
-3 4241 4230 4242
-3 4232 4244 4233
-3 4244 4232 4243
-3 4232 4234 4243
-3 4245 4243 4234
-3 4243 4246 4247
-3 4245 4246 4243
-3 4869 4228 4238
-3 4869 4238 4239
-3 4249 4239 4240
-3 4241 4249 4240
-3 4249 4241 4242
-3 4243 4250 4244
-3 4247 4250 4243
-3 4870 4239 4251
-3 4239 4249 4251
-3 4252 4251 4249
-3 4256 4249 4242
-3 4256 4252 4249
-3 4870 4255 4260
-3 4870 4251 4255
-3 4251 4252 4255
-3 4256 4255 4252
-3 3741 4257 4253
-3 4254 4257 3742
-3 4254 4253 4257
-3 3745 3744 4258
-3 4259 3745 4258
-3 4259 4871 3745
-3 4871 3746 3745
-3 4871 3751 3746
-3 4260 4255 4261
-3 4256 4261 4255
-3 4256 4262 4261
-3 4872 4257 3741
-3 4872 3742 4257
-3 4872 3748 3742
-3 3744 3743 4258
-3 3743 3761 4276
-3 3743 4276 4259
-3 3743 4259 4258
-3 4263 3751 4871
-3 3753 3751 4264
-3 3751 4263 4264
-3 4265 3753 4264
-3 1697 4850 4373
-3 4270 4260 4261
-3 4266 4270 4261
-3 4262 4266 4261
-3 3741 3756 4872
-3 4269 4268 3748
-3 4269 4272 4268
-3 4277 3774 4265
-3 4265 3774 3753
-3 4271 3765 4267
-3 4872 3756 3766
-3 3770 3758 4268
-3 4272 3770 4268
-3 3770 4272 3772
-3 3772 4272 4274
-3 4273 3759 4274
-3 3759 3772 4274
-3 4273 2774 3759
-3 4275 4276 3761
-3 3761 3773 4275
-3 3777 3234 4874
-3 4882 3777 4874
-3 3778 4279 3779
-3 4278 4279 3778
-3 4266 4293 4270
-3 4293 4266 3780
-3 3765 4280 3796
-3 4271 4280 3765
-3 4296 4281 3783
-3 3783 4281 3766
-3 3785 3786 4282
-3 3784 3785 4282
-3 4283 4284 4274
-3 4274 4284 4273
-3 4273 4284 4285
-3 2774 4273 4285
-3 3787 4299 4276
-3 3788 4275 4286
-3 3788 4276 4275
-3 3788 3787 4276
-3 3773 3789 4286
-3 4275 3773 4286
-3 4277 4302 3791
-3 3791 4302 3792
-3 3234 3807 4874
-3 3794 3793 3777
-3 3794 3777 4287
-3 4287 3777 4882
-3 4288 4289 4290
-3 4290 4886 4288
-3 4291 4279 4278
-3 4291 4278 3795
-3 4291 3795 4292
-3 3821 4279 4291
-3 4294 4884 3780
-3 3780 4884 4293
-3 4280 4884 4294
-3 4280 4294 4295
-3 4280 4295 3796
-3 4304 4281 4305
-3 4281 4296 4305
-3 4297 4309 3798
-3 3799 4297 3784
-3 3800 3799 3784
-3 3800 3784 4298
-3 4298 3784 4282
-3 3786 4298 4282
-3 3786 4885 4298
-3 4885 4311 4298
-3 4283 4885 3801
-3 4885 3786 3801
-3 3802 4283 3801
-3 4284 4283 3802
-3 4285 4284 3802
-3 3803 4299 3787
-3 3788 4286 3804
-3 3789 3804 4286
-3 3789 3790 4300
-3 3804 3789 4300
-3 3790 3805 4300
-3 4300 3805 4301
-3 4302 4301 3792
-3 4302 4303 4301
-3 4301 3805 3792
-3 4302 4893 4303
-3 3807 3806 4350
-3 3819 3794 4287
-3 3823 4295 4294
-3 3796 4295 3825
-3 3825 4295 3823
-3 3796 3825 3809
-3 4306 4307 4308
-3 4306 3813 4307
-3 4309 3813 3798
-3 3799 4319 4297
-3 4297 4319 4309
-3 3799 4310 4319
-3 3800 4310 3799
-3 3800 4311 4310
-3 3800 4298 4311
-3 3814 3253 4312
-3 3814 4312 4313
-3 3814 4313 3803
-3 3803 4313 4299
-3 4300 4314 3804
-3 4315 4314 4300
-3 4301 4315 4300
-3 4303 4315 4301
-3 3815 4315 4303
-3 3815 4303 3816
-3 4893 4316 4303
-3 3816 4303 4316
-3 3817 3816 4316
-3 4919 4317 3817
-3 3831 3817 4317
-3 3827 4308 4327
-3 3271 4308 3827
-3 3828 4306 4308
-3 3828 4308 3271
-3 4306 3836 3830
-3 4306 3828 3836
-3 4328 4309 4318
-3 4319 4318 4309
-3 3253 4320 4312
-3 4320 4321 4312
-3 4322 4313 4312
-3 4322 4312 4321
-3 3817 4316 4919
-3 3832 4324 4323
-3 3831 4324 3832
-3 3831 4317 4324
-3 4323 4324 4333
-3 4333 4325 4326
-3 4324 4325 4333
-3 3266 3819 4336
-3 4339 4304 4305
-3 4305 4296 4339
-3 3810 4339 4296
-3 3810 3827 4339
-3 4319 4328 4318
-3 4329 4328 4319
-3 4310 4329 4319
-3 4321 4320 4331
-3 4331 4320 4330
-3 4322 4321 4332
-3 4332 4321 4331
-3 4314 4906 4332
-3 4906 4322 4332
-3 3832 4323 3839
-3 3840 3839 4323
-3 3840 4323 4333
-3 4325 4334 4326
-3 4334 4333 4326
-3 3841 4335 4910
-3 4910 4911 3841
-3 3841 4911 3844
-3 4342 3844 4911
-3 3806 3842 4350
-3 4922 4913 4337
-3 3843 4344 3795
-3 3821 4338 3833
-3 4327 4339 3827
-3 4925 3815 4347
-3 3840 4333 4340
-3 4334 4341 4333
-3 4349 4341 4334
-3 3842 4342 4350
-3 4343 3795 4344
-3 3843 3846 4344
-3 4345 4338 4355
-3 4347 4348 4925
-3 4949 4348 4340
-3 4333 4949 4340
-3 4349 4333 4341
-3 4335 3856 4363
-3 4933 3312 4913
-3 4351 3795 4343
-3 4352 3795 4351
-3 4344 4351 4343
-3 3846 4353 4344
-3 4344 4353 4351
-3 3846 4345 4353
-3 4353 4345 4354
-3 4355 4356 4345
-3 4356 4354 4345
-3 4356 4346 3847
-3 4355 4346 4356
-3 3847 4346 3853
-3 3845 3848 4357
-3 4964 4337 3850
-3 4933 4379 3312
-3 4351 4353 4352
-3 4354 4358 4353
-3 4356 4359 4354
-3 4359 4358 4354
-3 3851 3852 4359
-3 3851 4359 4356
-3 3847 3851 4356
-3 4360 3853 4346
-3 4360 4368 3853
-3 4368 4361 3853
-3 4363 3856 4364
-3 4363 4364 4950
-3 4950 4364 4365
-3 4364 3857 4365
-3 3859 4357 4962
-3 4964 3850 4366
-3 4353 4380 4352
-3 4353 4358 4380
-3 4359 4367 4358
-3 4367 4380 4358
-3 3852 3862 4367
-3 4359 3852 4367
-3 4360 4382 4368
-3 4361 4368 4369
-3 4362 4361 3864
-3 3864 4361 4369
-3 4362 3864 3854
-3 3327 4372 3867
-3 3327 3859 4372
-3 3859 4962 4372
-3 4374 4375 3869
-3 4376 4377 3850
-3 4377 4366 3850
-3 3850 3329 4376
-3 4379 4378 3312
-3 4381 4380 4367
-3 3862 4381 4367
-3 4368 4382 4399
-3 3870 4399 3871
-3 3870 4369 4399
-3 4369 4368 4399
-3 3864 4369 3870
-3 4383 4371 4370
-3 4383 4370 4371
-3 4372 4384 3867
-3 3868 3874 4374
-3 4403 4385 4374
-3 4375 4374 4385
-3 4386 4375 4385
-3 3869 4375 4386
-3 3869 4386 3872
-3 3872 4386 4973
-3 3876 4387 4388
-3 3876 3872 4387
-3 3872 4973 4387
-3 4974 4376 4389
-3 4974 4388 4376
-3 4377 4376 4387
-3 4387 4376 4388
-3 3329 4389 4376
-3 4378 4389 3329
-3 4378 4390 4391
-3 4392 4378 4379
-3 4390 4378 4392
-3 3862 3878 4381
-3 3878 4382 4381
-3 3871 4399 3342
-3 4393 4383 4401
-3 4394 3857 4395
-3 4394 4395 4396
-3 4396 3879 3867
-3 4396 3867 4384
-3 3874 4403 4374
-3 3876 4388 4974
-3 4397 4391 4390
-3 4392 4398 4390
-3 4398 4397 4390
-3 4392 4416 4398
-3 3878 4399 4382
-3 4401 4402 4393
-3 4402 4400 4393
-3 4396 4395 3879
-3 4397 4404 4419
-3 4397 4398 4404
-3 4416 4404 4398
-3 3878 3882 4399
-3 4402 4405 4400
-3 4405 4402 4412
-3 3886 3885 4406
-3 3886 4407 3887
-3 4406 4407 3886
-3 4403 3874 3361
-3 4415 3362 4974
-3 3362 3876 4974
-3 4408 4419 4404
-3 4416 4409 4404
-3 4409 4408 4404
-3 4410 4400 4411
-3 4400 4405 4411
-3 4412 4413 4405
-3 4413 4411 4405
-3 4412 5012 4413
-3 4406 3893 4414
-3 3885 3893 4406
-3 4407 4414 3892
-3 4407 4406 4414
-3 4998 4990 4418
-3 3894 4415 3361
-3 3361 4415 4403
-3 3362 4415 3894
-3 3896 4416 3895
-3 3896 4409 4416
-3 3896 4408 4409
-3 4416 3900 3895
-3 4420 3900 4416
-3 4411 4417 4410
-3 3897 4417 4411
-3 3897 4411 4413
-3 4413 3904 3897
-3 4413 5021 3904
-3 4413 5012 5021
-3 3893 3892 4414
-3 4990 4425 4418
-3 3898 4419 4408
-3 3896 3898 4408
-3 3901 3900 5020
-3 3900 4420 5020
-3 5020 3902 3901
-3 4421 3902 5020
-3 3897 3910 4417
-3 4425 4424 4418
-3 4426 4427 4419
-3 4426 4419 3898
-3 3906 4428 4438
-3 3906 4439 4428
-3 3902 4421 3908
-3 4421 4429 3908
-3 3904 5021 5028
-3 4430 4431 4432
-3 4431 4433 4432
-3 4434 4423 4436
-3 4437 4424 4425
-3 5634 4426 4446
-3 3898 3909 4446
-3 4426 3898 4446
-3 3909 3906 4438
-3 3907 4449 4439
-3 3907 4439 3906
-3 3907 4440 4449
-3 3907 3908 4440
-3 3908 4429 4440
-3 3910 4441 4417
-3 5028 3910 3904
-3 4441 3910 5028
-3 4432 4442 4430
-3 4443 4442 4432
-3 4433 4443 4432
-3 4434 4444 4435
-3 4436 4444 4434
-3 4445 4437 4425
-3 4451 4445 4425
-3 3909 4447 4446
-3 4447 3909 4448
-3 3909 4438 4448
-3 4451 4450 4445
-3 4467 4451 4425
-3 4447 5634 4446
-3 3912 3911 5042
-3 3911 4452 5042
-3 4453 3912 5042
-3 4454 4456 4457
-3 4455 4456 4454
-3 4458 4445 4450
-3 4459 4445 4458
-3 4451 4460 4450
-3 4460 4458 4450
-3 4460 4451 4467
-3 3913 5075 3911
-3 3911 5075 4452
-3 3912 4453 3914
-3 4453 4473 3914
-3 4463 4455 4454
-3 4457 4464 4454
-3 4464 4463 4454
-3 4464 4457 4465
-3 4458 4466 4459
-3 4460 4466 4458
-3 4467 4466 4460
-3 4479 4461 4468
-3 4462 4469 4461
-3 4469 4468 4461
-3 4469 4462 4470
-3 4471 4472 3915
-3 3913 3916 5075
-3 3917 4474 4475
-3 4463 4476 5068
-3 4464 4477 4463
-3 4477 4476 4463
-3 4478 4464 4465
-3 4477 4464 4478
-3 4479 4468 4480
-3 4468 4469 4480
-3 4481 4469 4470
-3 4481 4482 4469
-3 4482 4480 4469
-3 4471 4482 4481
-3 4471 4483 4482
-3 3915 4483 4471
-3 4484 3915 4472
-3 4484 4472 4492
-3 3916 4485 4493
-3 3916 4493 5075
-3 4486 4473 4487
-3 3917 3918 4474
-3 3917 5067 5068
-3 3917 4475 5067
-3 5068 4476 3385
-3 3926 4476 4477
-3 5069 4477 4478
-3 4480 4488 4479
-3 3920 4488 4480
-3 3920 4480 4482
-3 3921 3920 4482
-3 3921 4482 4489
-3 4489 4482 4483
-3 4483 3915 4490
-3 4483 4490 4489
-3 3915 4484 4490
-3 4490 4484 4491
-3 4492 4491 4484
-3 3916 3929 4485
-3 4493 4485 4494
-3 4486 4493 4494
-3 4486 4494 3382
-3 3926 5069 5082
-3 4477 5069 3926
-3 3395 5088 4422
-3 4495 3924 4496
-3 4495 4488 3924
-3 4488 3920 3924
-3 4489 4495 3925
-3 4489 3925 3921
-3 3925 4495 4496
-3 4497 4489 4490
-3 4497 4490 4498
-3 4490 4491 4498
-3 4492 4498 4491
-3 4485 3929 4499
-3 4500 4501 4494
-3 4500 4494 4499
-3 4499 4494 4485
-3 4494 4502 3382
-3 4494 4501 4502
-3 4506 3382 4502
-3 4496 3924 4504
-3 4504 3924 4503
-3 3928 4504 5090
-3 3928 4496 4504
-3 3928 3925 4496
-3 3928 5090 3936
-3 4498 4505 4497
-3 5091 4498 4492
-3 4499 3929 3401
-3 4499 3401 4500
-3 3918 3390 4474
-3 4474 3390 5087
-3 3395 3926 5088
-3 5083 5095 3931
-3 3924 3935 4503
-3 3936 5090 4512
-3 4498 4507 4505
-3 5091 4507 4498
-3 4506 5094 3939
-3 3939 5094 5087
-3 3939 5087 3933
-3 3933 5087 3390
-3 3935 3931 5095
-3 3935 5095 5097
-3 5097 4503 3935
-3 5098 3944 4508
-3 5117 4500 3401
-3 5677 4237 2917
-3 4508 3943 3936
-3 3944 3943 4508
-3 3944 5104 4510
-3 3944 4510 3945
-3 3955 3945 4510
-3 3955 4510 4515
-3 3401 5130 5117
-3 3955 4515 5134
-3 4516 4517 5123
-3 3960 4518 4514
-3 3964 5129 5130
-3 4519 4517 4516
-3 4519 4516 4520
-3 4513 4521 3958
-3 4518 3960 4525
-3 3955 5134 3424
-3 3424 5134 4522
-3 5129 3964 4522
-3 4523 4519 4520
-3 4523 3966 4519
-3 3966 4523 2916
-3 4530 2916 4523
-3 4530 3962 2916
-3 3958 4521 3963
-3 4521 4524 3963
-3 4525 4524 4526
-3 4524 4525 3963
-3 4525 4526 4527
-3 3424 4522 3964
-3 4531 5643 5140
-3 4519 3966 4528
-3 3962 4530 2917
-3 5677 2917 4530
-3 4527 4524 4521
-3 4526 4524 4527
-3 3430 4529 4528
-3 4528 3966 3430
-3 4529 3965 4531
-3 3968 4536 3967
-3 4532 4533 3968
-3 3968 4533 4536
-3 4535 3969 3967
-3 4535 3967 4534
-3 4534 3967 4536
-3 4533 4532 4552
-3 4552 4532 3971
-3 4533 4552 4551
-3 4538 4537 4539
-3 4540 4541 5727
-3 5727 4541 4534
-3 4542 4534 4541
-3 4543 4534 4542
-3 4535 4534 4544
-3 4544 4534 4543
-3 3969 4535 4545
-3 4535 4544 4545
-3 4546 3970 4545
-3 4546 4547 3970
-3 3970 4547 4548
-3 4548 4560 3971
-3 4552 3971 4550
-3 4550 3971 4560
-3 4538 4554 4537
-3 4537 4554 4555
-3 4556 4537 4555
-3 4539 4537 4556
-3 5179 4541 4540
-3 5157 4541 5179
-3 4557 4541 5157
-3 4541 4557 4542
-3 4543 4542 4558
-3 4558 4542 4557
-3 4544 4543 4558
-3 4545 4544 4558
-3 4558 5159 4545
-3 4546 4545 5159
-3 4559 4548 4549
-3 4560 4548 4559
-3 4552 4550 4561
-3 4561 4550 4560
-3 4551 4552 4561
-3 4553 4551 4562
-3 4562 4551 4561
-3 4562 4563 4553
-3 4564 4565 4566
-3 5154 4556 4554
-3 4555 4554 4556
-3 4558 4557 5171
-3 5172 4558 5171
-3 4560 4559 4561
-3 4562 4561 4567
-3 4568 4562 4567
-3 4569 4563 4562
-3 4568 4569 4562
-3 5168 5177 4564
-3 5168 4570 5177
-3 4565 4564 5177
-3 4561 4559 4580
-3 4580 4567 4561
-3 4571 4568 4567
-3 4572 4573 4574
-3 4569 4568 4571
-3 4572 4574 4575
-3 4577 5174 4576
-3 4578 3972 4579
-3 5177 4570 5192
-3 4577 4576 4581
-3 4581 5187 4577
-3 5213 4579 4583
-3 5213 4582 4579
-3 4582 4578 4579
-3 3972 4583 4579
-3 3972 3974 4583
-3 3973 3974 3972
-3 4584 4586 4587
-3 4585 4584 4587
-3 4589 4590 4585
-3 4585 4590 4584
-3 4584 4590 4591
-3 4586 4584 4592
-3 4592 4584 4591
-3 4593 4587 4586
-3 4592 4593 4586
-3 3977 4600 4588
-3 4589 4594 3976
-3 3976 4595 4589
-3 4595 4590 4589
-3 4591 4590 4596
-3 4596 4590 4595
-3 4596 4592 4591
-3 4593 4592 4596
-3 4589 5235 4597
-3 4589 4597 4594
-3 4594 4597 4598
-3 3976 4594 4599
-3 4594 4598 4599
-3 3976 4599 4595
-3 4599 5238 4595
-3 5238 4596 4595
-3 4582 5213 5240
-3 4600 3977 3979
-3 3979 3980 4600
-3 4600 3980 4601
-3 4602 4597 5235
-3 4598 4597 4603
-3 4603 4597 4602
-3 4599 4598 5238
-3 5238 4598 4603
-3 4582 5240 3986
-3 4600 3981 4604
-3 4600 3982 3981
-3 3982 4600 4605
-3 4605 4600 4601
-3 5237 4605 4601
-3 5237 4601 2180
-3 4606 5235 4635
-3 5235 4606 4602
-3 4606 4603 4602
-3 5238 4603 4606
-3 4604 3984 4607
-3 3981 3984 4604
-3 4608 4604 4609
-3 4609 4604 4607
-3 4605 4608 4609
-3 5237 4608 4605
-3 4635 4610 4606
-3 4606 4610 4615
-3 3985 4607 3984
-3 4609 4607 4611
-3 4609 4611 4605
-3 4619 4612 5237
-3 4635 4613 4610
-3 4610 4613 4614
-3 4615 4610 4614
-3 5241 4606 4615
-3 4616 3986 5240
-3 4616 4617 3986
-3 3986 4617 3990
-3 3985 3991 4618
-3 4607 3985 4618
-3 4611 4607 4618
-3 4620 4612 4619
-3 5237 4051 4619
-3 4635 3994 4613
-3 4621 4613 3994
-3 4621 4614 4613
-3 4615 4614 5241
-3 5241 4614 4621
-3 4622 4616 5240
-3 4623 4616 4622
-3 3999 4623 3998
-3 3999 4617 4623
-3 4617 4616 4623
-3 4012 4617 3999
-3 4012 4624 4617
-3 3990 4617 4001
-3 4001 4617 4624
-3 3991 4625 4618
-3 4003 4625 4004
-3 4003 4611 4625
-3 4611 4618 4625
-3 4626 4627 4620
-3 4626 4619 4628
-3 4620 4619 4626
-3 4051 4628 4619
-3 4635 4006 3994
-3 4622 5240 4629
-3 4011 4629 4010
-3 4011 4622 4629
-3 4011 4623 4622
-3 3998 4623 4011
-3 4001 4624 4012
-3 4013 4625 3991
-3 4013 4630 4625
-3 4004 4625 4014
-3 4014 4625 4630
-3 4014 4631 4015
-3 4630 4631 4014
-3 4015 4631 4016
-3 4632 4627 4626
-3 4632 4626 4633
-3 4022 4642 4621
-3 4642 5241 4621
-3 4631 4630 4013
-3 4632 4634 4627
-3 4633 4634 4632
-3 4031 4006 4635
-3 4642 4022 4025
-3 4010 4629 4030
-3 4629 4032 4030
-3 4025 3462 4642
-3 4031 4635 3496
-3 4643 4647 4629
-3 4036 4039 5246
-3 4036 5246 4636
-3 5246 4637 4636
-3 4037 4638 4040
-3 4037 4636 4638
-3 4636 4637 4638
-3 5245 4637 5246
-3 4044 5245 4043
-3 4044 4637 5245
-3 4044 4638 4637
-3 4639 4046 5245
-3 4046 4043 5245
-3 4640 4039 4047
-3 4640 4641 4039
-3 4641 5246 4039
-3 4639 5249 4047
-3 4639 4047 4046
-3 4640 4047 5249
-3 4645 4644 4640
-3 4641 4640 4644
-3 5249 4645 4640
-3 4650 4644 4646
-3 4646 4644 4645
-3 4648 4649 4650
-3 4650 4646 4648
-3 4048 4651 4049
-3 4048 4652 4653
-3 4048 4049 4652
-3 4649 4653 4652
-3 4649 4648 4653
-3 4648 4656 4653
-3 4050 4647 4643
-3 4654 4655 4048
-3 4655 4651 4048
-3 4048 4653 4654
-3 4654 4653 4656
-3 4654 4657 4655
-3 4656 4657 4654
-3 5261 5256 4642
-3 4658 5261 4052
-3 5269 4050 5268
-3 5266 4659 4658
-3 4052 5266 4658
-3 4053 5269 5274
-3 5274 4660 4053
-3 4053 4660 4661
-3 4054 4053 4661
-3 4662 4660 5274
-3 4662 4661 4660
-3 4661 4061 4054
-3 4663 5285 4058
-3 4663 5292 5285
-3 4059 4055 4664
-3 4056 4060 4664
-3 4055 4056 4664
-3 4661 4662 4061
-3 4664 4665 4059
-3 4060 4062 4665
-3 4060 4665 4664
-3 4062 4061 4665
-3 4665 4061 4666
-3 4666 4061 4662
-3 5292 4663 4058
-3 4668 4064 4065
-3 4065 4066 4669
-3 4066 4059 4669
-3 4665 4670 4059
-3 5308 4670 4665
-3 5308 4665 4666
-3 5292 4058 4672
-3 4065 4669 4668
-3 4059 4670 4669
-3 4067 4671 5306
-3 5306 3551 4067
-3 5306 4070 3551
-3 4668 4673 4064
-3 4673 4676 4064
-3 4669 4674 4668
-3 4674 4673 4668
-3 4670 4677 4669
-3 4677 4674 4669
-3 4675 4677 4670
-3 4675 4670 5308
-3 4067 5316 4671
-3 5306 4679 4070
-3 4674 4677 4673
-3 5319 4677 4675
-3 4070 4679 5317
-3 4673 4077 4676
-3 4077 4673 4677
-3 4078 4680 4678
-3 4680 4681 4678
-3 4079 4678 4681
-3 4678 4079 4075
-3 5316 4080 5320
-3 4070 5317 5320
-3 4080 4070 5320
-3 4682 4683 4684
-3 5314 4682 4684
-3 4677 5327 4077
-3 4078 4685 4680
-3 4685 4686 4680
-3 4681 4680 4686
-3 4079 4681 4686
-3 4088 5320 4080
-3 5320 4088 4080
-3 4682 5324 4687
-3 4682 4687 4688
-3 4683 4682 4688
-3 5326 4076 5338
-3 4695 3592 4689
-3 3592 4690 4689
-3 4077 4696 4690
-3 4696 4077 5327
-3 4100 5327 5325
-3 5325 4697 4100
-3 4078 4091 4692
-3 4091 4691 4692
-3 4685 4078 4693
-3 4693 4078 4692
-3 4094 5331 4093
-3 4094 4685 5331
-3 4094 4686 4685
-3 4685 4693 5331
-3 4096 4095 5341
-3 4688 4687 4694
-3 4683 4688 4694
-3 4684 4683 3635
-3 4689 4722 4695
-3 3628 4697 4698
-3 4699 4091 4101
-3 4699 4700 4091
-3 4700 4691 4091
-3 4701 4699 4101
-3 4701 4101 5331
-3 4093 5331 4101
-3 4095 4111 5341
-3 5341 4103 4096
-3 5318 5298 4715
-3 4715 5298 4672
-3 5318 4715 4716
-3 4687 5324 4703
-3 4694 4687 4703
-3 4722 4721 4695
-3 4689 4705 4722
-3 4690 4706 4689
-3 4706 4690 4696
-3 3628 4698 4128
-3 4707 4708 4109
-3 4709 4700 4711
-3 4710 4700 4709
-3 4712 4699 4701
-3 4712 4711 4699
-3 4700 4699 4711
-3 4713 5341 4111
-3 4713 4110 5341
-3 4110 4103 5341
-3 4715 4672 4714
-3 4694 4703 4168
-3 4104 4733 4732
-3 4720 4719 4108
-3 4736 4722 4705
-3 4689 4723 4705
-3 4723 4736 4705
-3 4706 4723 4689
-3 4723 4706 4724
-3 4708 4725 4109
-3 4708 4726 4725
-3 4710 4709 4726
-3 4709 4727 4726
-3 4711 4728 4709
-3 4728 4727 4709
-3 4728 4711 4712
-3 4111 4110 4713
-3 4132 4741 4714
-3 4715 4714 4741
-3 4716 4715 4729
-3 4716 4729 4742
-3 4718 4717 4730
-3 4703 4718 4168
-3 4731 4104 4732
-3 4719 4141 4108
-3 4721 4734 4704
-3 4125 4721 4735
-3 4735 4721 4722
-3 4736 4785 4722
-3 4724 4738 4723
-3 4738 4737 4723
-3 4724 4749 4738
-3 4136 4750 4100
-3 4136 4100 4114
-3 4109 5374 4707
-3 4726 4752 4725
-3 4727 4739 4726
-3 4739 4752 4726
-3 4739 4728 4712
-3 4739 4727 4728
-3 4715 4741 4759
-3 4729 4715 4742
-3 4742 4715 4759
-3 4742 4761 4762
-3 4764 4730 4717
-3 4718 4730 4764
-3 4168 4718 4764
-3 4732 4745 4731
-3 4733 4745 4732
-3 4766 4122 4746
-3 4768 4719 4720
-3 4704 4769 4720
-3 4769 4768 4720
-3 4734 4769 4704
-3 4734 4125 4747
-3 4734 4747 4769
-3 4125 4735 4747
-3 4737 4738 4748
-3 4749 4748 4738
-3 4749 4750 4751
-3 4136 4751 4750
-3 4128 4771 4142
-3 4725 4752 4138
-3 4754 4755 4140
-3 4755 4756 4131
-3 4131 4756 4740
-3 4756 4757 4740
-3 4131 4776 4132
-3 4131 4740 4776
-3 4740 4757 4776
-3 4776 4758 4132
-3 4758 4777 4741
-3 4759 4741 4777
-3 4760 4742 4759
-3 4761 4742 4760
-3 4743 4763 4764
-3 4744 4743 4764
-3 4717 4744 4764
-3 5379 5338 3683
-3 4780 4731 4765
-3 4765 4731 4745
-3 4733 4780 4745
-3 4780 4765 4745
-3 4733 4133 4780
-3 4746 4781 4766
-3 4782 4169 4746
-3 4719 4767 4141
-3 4747 4770 4769
-3 4735 4770 4747
-3 4722 4785 4735
-3 4785 4770 4735
-3 4748 5372 4737
-3 4749 5372 4748
-3 5372 4749 4154
-3 4749 4751 4154
-3 4136 4154 4751
-3 4144 4772 4773
-3 4147 4144 4773
-3 4773 4753 4147
-3 4774 3660 4753
-3 3660 4147 4753
-3 4140 4150 4754
-3 4151 4754 4150
-3 4755 4754 4151
-3 4775 4755 4151
-3 4775 4756 4755
-3 4775 4757 4756
-3 4777 4758 4776
-3 4759 4778 4779
-3 4153 4779 4166
-3 4153 4760 4779
-3 4760 4759 4779
-3 4152 4760 4153
-3 4152 4762 4760
-3 4762 4761 4760
-3 4168 4764 4763
-3 4133 4134 4780
-3 4746 4169 4781
-3 4767 4783 4141
-3 4719 4784 4767
-3 4784 4783 4767
-3 4768 4784 4719
-3 5369 4784 4768
-3 5369 4768 4769
-3 4770 4798 4769
-3 4155 4771 4154
-3 4142 4771 4155
-3 4786 5394 5374
-3 4786 5374 4156
-3 4787 4788 4158
-3 5385 4788 4787
-3 4158 4788 4772
-3 4158 4772 4144
-3 4753 4789 4774
-3 4790 4775 4171
-3 4166 4779 4778
-3 4166 4778 4167
-3 4167 4778 4791
-3 4792 5354 4180
-3 4794 5354 4792
-3 4793 4794 4792
-3 4763 4794 4795
-3 4134 4803 4780
-3 4796 4803 4134
-3 4766 4796 4134
-3 4781 4796 4766
-3 4169 4796 4781
-3 6695 4169 4782
-3 6695 4782 4141
-3 4783 6695 4141
-3 4783 4784 4797
-3 5369 4804 4784
-3 4804 4797 4784
-3 4805 4804 5369
-3 5388 4798 4770
-3 4785 5388 4770
-3 4799 5385 4787
-3 4158 4800 4787
-3 4800 4799 4787
-3 4774 4789 4801
-3 4802 4774 4801
-3 4791 4171 4167
-3 4181 4792 4180
-3 4794 4793 4184
-3 4795 4794 4184
-3 5379 3683 4823
-3 4812 4803 4796
-3 4797 4804 4783
-3 4786 4806 5394
-3 4807 4816 5385
-3 5385 4799 4807
-3 4799 4808 4807
-3 4800 4809 4799
-3 4809 4808 4799
-3 4810 4809 4800
-3 4810 4800 4172
-3 4801 4789 4172
-3 4181 4183 4792
-3 4183 4793 4792
-3 4184 4793 4183
-3 4763 4795 4184
-3 4174 4811 4176
-3 4176 4811 4178
-3 4838 4780 4803
-3 4812 4838 4803
-3 3685 4813 4179
-3 4814 4179 4813
-3 5406 5394 4806
-3 4808 4817 4807
-3 4817 4816 4807
-3 4820 4817 4809
-3 4817 4808 4809
-3 4810 4820 4809
-3 4811 4174 4177
-3 4178 4811 4177
-3 3685 4818 4813
-3 4179 4814 4825
-3 4185 4825 4186
-3 4185 4179 4825
-3 4815 4827 4819
-3 4815 4187 4827
-3 4816 4189 4815
-3 4820 4189 4816
-3 4817 4820 4816
-3 4822 4192 4191
-3 4812 4824 4838
-3 3685 4835 4818
-3 4819 4826 5433
-3 4827 4826 4819
-3 4187 4198 4827
-3 4189 4820 4833
-3 4191 4199 4821
-3 4822 4199 4192
-3 4835 5430 4818
-3 4207 4186 4825
-3 4836 4207 4825
-3 4197 4207 4201
-3 4186 4207 4197
-3 5433 4829 5439
-3 5433 4826 4829
-3 4827 4830 4826
-3 4830 4829 4826
-3 4198 4831 4827
-3 4827 4831 4830
-3 4832 4831 4198
-3 5434 4838 4824
-3 5434 4824 4828
-3 4204 4834 4205
-3 4834 4206 4205
-3 4200 5437 4835
-3 4200 4836 5437
-3 4836 4200 4207
-3 4830 5439 4829
-3 4831 5439 4830
-3 4832 5439 4831
-3 4834 4841 4839
-3 4204 4841 4834
-3 4839 4206 4834
-3 4209 4211 4837
-3 4422 6658 1262
-3 4215 5445 4216
-3 5445 4217 4216
-3 4840 4217 5445
-3 4219 4849 6840
-3 5455 4212 4219
-3 5455 4219 6840
-3 4213 5455 3733
-3 4215 4221 5445
-3 5445 4221 5448
-3 4217 4840 4842
-3 4842 4222 4217
-3 5449 4222 4842
-3 4225 4849 4219
-3 3733 5455 4236
-3 4226 5448 4221
-3 4227 5449 4226
-3 4226 5449 5448
-3 5449 4227 4222
-3 4843 4841 4869
-3 4841 4223 4869
-3 4846 5462 4231
-3 4233 4848 4245
-3 4847 4848 4233
-3 4225 4235 4849
-3 4236 5455 4856
-3 4231 4239 4846
-3 4231 5462 4242
-3 5462 4859 4242
-3 4233 4244 4847
-3 4244 4851 4847
-3 4851 4848 4847
-3 4245 4848 4851
-3 4246 4245 4852
-3 4247 5468 4853
-3 4247 4246 5468
-3 4246 4852 5468
-3 5468 4854 4853
-3 4864 6882 4849
-3 4235 4248 4855
-3 4235 4855 4849
-3 4855 4248 4856
-3 4856 4248 4236
-3 4223 4228 4869
-3 4859 4256 4242
-3 4244 4250 4851
-3 4250 5468 4851
-3 4853 4250 4247
-3 4853 4854 4250
-3 4854 5468 4250
-3 4860 4861 4862
-3 4861 4863 4862
-3 4855 4864 4849
-3 4865 4858 4857
-3 4867 4857 4858
-3 4867 4866 4857
-3 4866 4865 4857
-3 4869 4239 4870
-3 4859 5482 4256
-3 4868 4860 4862
-3 4863 4868 4862
-3 4867 4865 4866
-3 5481 4870 4260
-3 4262 4256 5482
-3 4259 4276 4871
-3 4276 4873 4871
-3 4263 4871 4873
-3 4263 4265 4264
-3 4873 4265 4263
-3 5481 4260 4270
-3 5481 4270 5483
-3 4262 5482 5484
-3 4267 5484 4875
-3 4267 4262 5484
-3 3748 4872 4269
-3 4872 4876 4269
-3 4265 4881 4277
-3 4265 4873 4881
-3 4270 4879 5483
-3 5484 4879 4878
-3 5484 4878 4875
-3 4875 4878 4880
-3 4267 4880 4271
-3 4875 4880 4267
-3 5489 4876 3766
-3 4876 4872 3766
-3 4876 5491 4269
-3 4272 4269 5491
-3 4272 5491 4274
-3 4873 4276 5504
-3 4277 4881 5493
-3 4302 4277 5495
-3 4277 5493 5495
-3 5506 4874 3807
-3 4290 4883 5497
-3 5497 5486 4290
-3 4270 4293 4879
-3 4293 4878 4879
-3 4880 4878 4884
-3 4884 4878 4293
-3 4271 4884 4280
-3 4880 4884 4271
-3 4281 4898 5489
-3 3766 4281 5489
-3 4283 5491 4885
-3 4274 5491 4283
-3 4276 4299 4892
-3 4892 5504 4276
-3 3807 4894 5506
-3 3807 4350 4894
-3 4290 4289 4883
-3 4886 4290 5486
-3 5498 4887 5486
-3 4887 4886 5486
-3 5498 5507 4887
-3 4281 4304 4898
-3 4885 5491 4311
-3 4888 5518 4890
-3 4889 5518 4888
-3 4890 5518 4891
-3 4893 5495 5519
-3 4302 5495 4893
-3 4287 4882 3819
-3 4288 4895 4289
-3 4886 4895 4288
-3 4896 4895 4886
-3 4887 4912 4886
-3 4897 4887 5507
-3 4897 4912 4887
-3 4291 4292 5522
-3 3821 4291 5522
-3 3813 4899 4307
-3 4307 4899 4308
-3 4309 4899 3813
-3 4309 4900 4901
-3 4309 4901 4899
-3 4901 4900 4902
-3 4311 5491 5503
-3 4311 5503 4310
-3 4310 5503 5526
-3 4888 4903 4889
-3 4890 4903 4888
-3 4904 4903 4890
-3 4891 4904 4890
-3 4905 4904 4891
-3 5518 4905 4891
-3 4299 4313 4906
-3 4892 4299 4906
-3 5519 4892 4906
-3 4315 5519 4314
-3 5519 4315 4893
-3 3815 4893 4315
-3 3815 4907 4893
-3 4316 4893 4907
-3 4325 4921 4909
-3 5505 4911 4910
-3 5528 4911 5505
-3 4894 4350 5544
-3 4963 4877 4237
-3 4896 4886 4912
-3 4897 4913 4912
-3 4355 3821 5522
-3 4898 4914 5525
-3 5531 4327 4308
-3 4900 4328 4915
-3 4309 4328 4900
-3 4916 4902 4900
-3 4916 4900 4917
-3 4917 4900 4915
-3 4917 5526 4916
-3 4917 4310 5526
-3 4313 4322 4906
-3 4906 4314 5519
-3 3815 4918 4907
-3 4918 4316 4907
-3 4316 4918 4919
-3 4908 4317 4920
-3 4920 4317 4919
-3 4926 4921 4908
-3 4926 4908 4920
-3 4317 4908 4921
-3 4317 4921 4324
-3 4921 4325 4324
-3 4927 4325 4909
-3 4909 4910 4927
-3 4928 4927 4910
-3 5528 5532 4911
-3 4882 4336 3819
-3 4913 4922 4912
-3 4914 4898 4935
-3 4304 4924 4898
-3 4924 4935 4898
-3 4936 4924 4304
-3 4936 4304 4339
-3 5531 5550 4327
-3 4329 4915 4328
-3 4917 4915 4329
-3 4310 4917 4329
-3 4918 3815 4925
-3 4919 4918 4925
-3 4925 4926 4920
-3 4925 4920 4919
-3 4325 4927 4334
-3 4910 4335 4928
-3 4342 4911 4929
-3 4929 4911 5532
-3 4930 4931 5548
-3 5548 4932 4930
-3 4913 4923 4933
-3 3795 4952 4292
-3 4338 3821 4355
-3 4935 4924 4934
-3 4936 4934 4924
-3 4339 4937 4936
-3 4339 4938 4937
-3 4339 4327 5550
-3 5541 4925 4348
-3 4334 4927 4349
-3 4335 4363 4928
-3 4939 5554 4940
-3 4929 5532 4342
-3 4940 4941 4939
-3 4342 5544 4350
-3 4342 5532 5544
-3 4962 4336 4882
-3 3848 4336 4962
-3 4942 4931 4930
-3 4943 4931 4942
-3 4944 4930 4932
-3 4942 4930 4944
-3 4945 4922 4337
-3 4954 4935 4934
-3 4936 4946 4934
-3 4946 4954 4934
-3 4946 4936 4937
-3 4339 4947 4938
-3 5550 4947 4339
-3 4348 4948 5541
-3 4948 4348 4949
-3 4949 4333 4349
-3 4950 5553 4960
-3 5553 4950 5564
-3 4940 5554 4951
-3 4941 4940 4951
-3 4942 4944 4943
-3 3795 4352 4952
-3 4946 4955 4954
-3 4955 4946 5573
-3 4948 4959 4956
-3 4948 4949 4959
-3 4349 4959 4949
-3 4928 4363 4960
-3 4960 4363 4950
-3 4961 5564 4950
-3 3848 4962 4357
-3 4964 4945 4337
-3 4360 4346 4953
-3 5572 4954 4957
-3 4955 4958 4954
-3 4958 4957 4954
-3 4958 4955 5573
-3 4961 4950 4365
-3 4966 4945 4964
-3 4933 5592 4379
-3 4380 4952 4352
-3 4360 4953 4382
-3 4371 5577 4957
-3 4371 4957 4958
-3 4957 5577 5572
-3 4958 5573 4371
-3 5573 5577 4371
-3 4965 4961 4365
-3 3857 4965 4365
-3 4962 4971 4372
-3 4966 4964 4973
-3 4964 4967 4973
-3 4366 4377 4967
-3 4964 4366 4967
-3 4381 4952 4380
-3 4382 4953 4381
-3 4371 4383 5577
-3 5577 4383 5582
-3 4371 5577 4383
-3 5577 5582 4383
-3 4981 4968 4965
-3 3857 4981 4965
-3 3857 4394 4981
-3 4969 4970 4384
-3 4969 4384 4372
-3 4971 4969 4372
-3 4971 4972 4969
-3 4973 4385 4403
-3 4973 4386 4385
-3 4967 4387 4973
-3 4377 4387 4967
-3 5590 4974 4389
-3 4389 4975 5590
-3 4378 4975 4389
-3 4379 5592 4392
-3 5592 4985 4392
-3 4383 4393 5582
-3 5582 4393 5605
-3 4383 5582 4401
-3 5582 4986 4401
-3 4968 4978 4976
-3 4979 4978 4968
-3 4993 4968 4980
-3 4993 4979 4968
-3 4981 4980 4968
-3 4394 4396 4981
-3 4969 4994 4970
-3 4994 4969 4982
-3 4969 4972 4982
-3 4983 4972 4971
-3 4983 4984 4972
-3 4984 4982 4972
-3 4975 4378 4391
-3 4975 4391 5597
-3 5597 4391 4397
-3 4985 4416 4392
-3 4393 4400 5605
-3 4986 4402 4401
-3 5599 4402 4986
-3 4987 4988 4989
-3 4989 5600 4987
-3 4990 4977 4976
-3 4991 4990 4976
-3 4978 4992 4976
-3 4992 4991 4976
-3 4979 4992 4978
-3 4984 4995 4982
-3 4995 4994 4982
-3 5603 4984 4983
-3 4995 4984 5603
-3 5597 4397 4419
-3 5009 5597 4419
-3 4402 5599 4412
-3 4987 4997 4988
-3 5600 4997 4987
-3 4977 4990 4998
-3 4991 4999 4990
-3 4992 5000 4991
-3 5000 4999 4991
-3 5007 4979 4993
-3 5007 5000 4979
-3 5000 4992 4979
-3 4994 4995 5008
-3 5008 4995 5603
-3 4974 5590 4415
-3 5613 4416 4985
-3 4410 5605 4400
-3 4410 5001 5002
-3 4410 5002 5605
-3 4412 5001 5003
-3 4412 5599 5001
-3 5002 5001 5599
-3 4412 5003 5012
-3 5006 4996 5606
-3 5006 5005 4996
-3 5005 5004 4996
-3 4998 4418 4977
-3 5000 5007 4999
-3 4415 7464 4403
-3 5009 5010 5011
-3 4416 5010 5017
-3 4416 5613 5010
-3 5011 5010 5613
-3 4416 5017 4420
-3 4410 4417 5001
-3 4417 5012 5001
-3 5012 5003 5001
-3 5005 5013 5004
-3 5014 5013 5005
-3 5006 5014 5005
-3 4977 5015 5016
-3 4977 4418 5015
-3 4999 5007 4425
-3 4990 4999 4425
-3 4419 5025 5009
-3 5025 5010 5009
-3 5017 5010 5025
-3 4420 5017 5018
-3 5018 5019 4420
-3 5019 5020 4420
-3 5012 4417 5021
-3 5015 4434 5016
-3 5015 4423 4434
-3 4423 5015 5022
-3 5022 5015 4418
-3 4418 4424 5022
-3 5023 4427 4426
-3 5023 5024 4427
-3 4419 4427 5024
-3 4419 5024 5025
-3 4428 5025 4438
-3 4428 5018 5025
-3 5018 5017 5025
-3 4439 5018 4428
-3 4439 5026 5018
-3 5026 5019 5018
-3 5020 5019 5027
-3 5027 5019 5026
-3 4421 5027 4429
-3 5020 5027 4421
-3 5028 5021 4417
-3 4431 4430 5029
-3 5029 5030 4431
-3 4431 5030 4433
-3 5016 4434 5031
-3 5031 4434 4435
-3 5022 4436 4423
-3 5022 5033 4436
-3 5033 5032 4436
-3 4424 5033 5022
-3 4424 4437 5033
-3 4437 5034 5033
-3 5007 5628 4425
-3 5023 4426 5634
-3 5025 5024 4448
-3 4438 5025 4448
-3 4449 5026 4439
-3 4449 5027 5026
-3 4429 5027 4440
-3 4417 4441 5028
-3 4430 4442 5029
-3 4443 5029 4442
-3 5030 5029 4443
-3 4433 5030 4443
-3 4435 5035 5031
-3 4444 5035 4435
-3 4436 5032 4444
-3 4444 5032 5035
-3 4437 4445 5034
-3 5034 4445 5036
-3 4440 5027 4449
-3 4467 4425 5628
-3 5037 4447 4448
-3 5634 4447 5037
-3 5038 5046 5045
-3 5047 5046 5038
-3 4456 4455 5047
-3 4445 4459 5036
-3 4467 5036 4459
-3 5048 5041 5040
-3 5049 5041 5048
-3 4461 5050 5051
-3 4462 4461 5052
-3 4461 5051 5052
-3 5053 4462 5052
-3 4452 5075 5054
-3 5042 4452 5055
-3 5055 4452 5054
-3 4453 5055 4473
-3 5042 5055 4453
-3 5043 5044 5056
-3 5044 5067 5056
-3 5045 5058 5044
-3 5058 5067 5044
-3 5046 5058 5045
-3 5047 5059 5046
-3 5059 5058 5046
-3 4455 4463 5059
-3 5047 4455 5059
-3 4456 5047 5641
-3 5641 4457 4456
-3 5641 4465 4457
-3 4467 4459 4466
-3 5048 5060 5049
-3 5050 4461 4479
-3 5050 4479 5071
-3 4462 5053 4470
-3 5053 5061 4470
-3 5063 4471 5062
-3 5063 5640 4471
-3 4472 4471 5640
-3 5075 5064 5054
-3 5055 5054 5065
-3 5065 5054 5064
-3 5055 5065 4473
-3 4475 4474 5066
-3 5056 5066 5057
-3 5056 4475 5066
-3 5067 4475 5056
-3 5058 5068 5067
-3 4463 5068 5059
-3 5059 5068 5058
-3 4465 5641 4478
-3 5641 5069 4478
-3 4479 5070 5071
-3 4481 5070 5072
-3 4481 5061 5070
-3 4481 4470 5061
-3 5071 5070 5061
-3 4481 5062 4471
-3 4481 5072 5062
-3 5072 5073 5062
-3 5074 5063 5062
-3 5073 5074 5062
-3 5642 4472 5640
-3 4472 5642 4492
-3 4486 5064 5075
-3 4487 5064 4486
-3 5065 5064 4487
-3 4473 5065 4487
-3 5066 4474 5076
-3 4479 4488 5070
-3 4488 5077 5070
-3 5077 5072 5070
-3 5073 5072 5078
-3 5078 5072 5077
-3 5644 5074 5073
-3 5078 5644 5073
-3 5644 5079 5642
-3 4492 5642 5080
-3 5642 5079 5080
-3 4486 5075 4493
-3 4488 4495 5077
-3 4489 5077 4495
-3 5078 5077 4489
-3 5078 4489 5644
-3 4489 4497 5644
-3 4497 5084 5079
-3 4497 5079 5644
-3 5085 5647 5080
-3 5085 5080 5084
-3 5084 5080 5079
-3 5647 4492 5080
-3 4501 5086 4502
-3 4500 5086 4501
-3 4502 5086 4506
-3 5076 4474 5087
-3 5087 5081 5076
-3 3926 5082 5088
-3 5083 3931 5109
-3 5089 5083 5096
-3 4503 5090 4504
-3 5096 5090 4503
-3 4497 4505 5084
-3 5084 4505 5085
-3 5086 4500 5092
-3 5093 5086 5092
-3 4506 5086 5093
-3 4506 5093 5094
-3 5083 5089 5095
-3 5096 5097 5089
-3 5097 5095 5089
-3 5097 5096 4503
-3 5666 5090 5096
-3 5090 5666 4512
-3 5098 4505 4507
-3 5098 5654 4505
-3 5654 5085 4505
-3 4507 5091 5098
-3 5098 5091 5099
-3 5099 5091 5104
-3 5100 5101 5102
-3 5102 5103 5100
-3 5092 4500 5118
-3 5098 4508 5654
-3 4508 5659 5654
-3 5099 3944 5098
-3 3944 5099 5104
-3 4510 5104 5105
-3 5100 5108 5101
-3 5103 5108 5100
-3 5118 4500 5117
-3 5109 3952 4509
-3 3931 3952 5109
-3 3936 5666 5659
-3 5659 4508 3936
-3 4515 4510 5105
-3 4515 5105 5106
-3 5110 5106 5107
-3 5110 5111 5106
-3 5111 4515 5106
-3 5125 4511 4514
-3 5666 3936 4512
-3 4515 5111 5127
-3 5120 5119 5112
-3 5112 5672 5120
-3 5121 5674 5114
-3 5114 5113 5121
-3 5113 5122 5121
-3 5122 5113 5114
-3 4511 5125 4513
-3 5125 4514 4518
-3 5126 5125 4518
-3 5128 5681 5118
-3 5118 5117 5128
-3 5117 5129 5128
-3 5130 5129 5117
-3 5119 5131 5135
-3 5119 5120 5131
-3 5682 5120 5672
-3 5131 5120 5682
-3 5121 5686 5674
-3 5122 5686 5121
-3 5116 5115 5132
-3 5123 4517 5132
-3 5123 5132 5115
-3 5123 5124 4516
-3 5124 5133 4516
-3 4513 5125 5697
-3 4518 5680 5126
-3 5127 5134 4515
-3 5681 5129 4522
-3 5681 5128 5129
-3 5682 5135 5131
-3 4517 4519 5136
-3 5132 4517 5136
-3 4516 5133 4520
-3 5133 5137 4520
-3 4513 5697 4521
-3 5680 4518 5138
-3 5138 4518 4525
-3 5681 4522 5134
-3 4519 4528 5136
-3 4523 4520 5137
-3 4527 5138 4525
-3 4527 5139 5138
-3 4528 5712 5136
-3 4530 4523 5137
-3 5712 4530 5137
-3 5141 4527 4521
-3 4527 5141 5142
-3 4527 5142 5143
-3 5139 4527 5144
-3 5144 4527 5143
-3 5699 4531 5140
-3 5699 5708 4531
-3 5708 5715 4531
-3 4529 5145 4528
-3 4528 5145 5716
-3 5716 5712 4528
-3 4529 4531 5715
-3 4529 5715 5145
-3 4536 5146 4534
-3 5147 5146 4536
-3 4533 5148 4536
-3 5148 5147 4536
-3 5149 5148 4533
-3 4551 5152 4533
-3 5727 4539 4540
-3 4547 4546 5150
-3 4547 5150 5146
-3 4547 5146 5147
-3 4548 4547 5147
-3 4548 5147 5148
-3 5149 5160 5151
-3 5151 4549 5149
-3 5148 5149 4548
-3 4548 5149 4549
-3 4553 5152 4551
-3 5164 5152 4553
-3 5153 5154 4538
-3 4554 4538 5154
-3 4539 5155 4540
-3 5155 5156 4540
-3 5157 5158 4557
-3 5160 5150 4546
-3 5160 4546 5159
-3 5160 5159 5161
-3 5161 5162 5160
-3 5160 5162 5151
-3 5151 5162 5163
-3 4549 5163 4559
-3 5151 5163 4549
-3 5164 4563 5165
-3 5164 4553 4563
-3 5165 5166 5167
-3 5164 5165 5167
-3 5153 5168 4564
-3 4566 5153 4564
-3 5154 5153 4566
-3 4565 5154 4566
-3 4565 5169 5154
-3 4556 5154 5169
-3 5169 5155 4556
-3 4556 5155 4539
-3 5156 5155 5170
-3 4540 5156 5170
-3 5179 4540 5170
-3 4557 5158 5171
-3 5158 5157 5171
-3 4558 5172 5159
-3 5161 5159 5172
-3 5163 5162 5184
-3 5184 5162 5161
-3 5163 5184 4559
-3 5165 4569 5173
-3 4563 4569 5165
-3 5166 5165 5173
-3 5768 5167 5166
-3 5768 5166 5174
-3 5174 4577 5768
-3 5175 5176 5153
-3 5168 5153 5176
-3 5168 5176 4570
-3 4565 5177 5169
-3 5155 5169 5783
-3 5170 5155 5783
-3 5179 5170 5178
-3 5157 5179 5180
-3 5171 5157 5181
-3 5181 5157 5180
-3 5172 5171 5181
-3 5183 5172 5182
-3 5161 5172 5183
-3 5184 5161 5183
-3 4567 5185 4571
-3 4571 5173 4569
-3 4571 5185 5173
-3 4572 5173 4573
-3 4573 5173 5185
-3 4575 5173 4572
-3 4575 5186 5173
-3 5186 5166 5173
-3 5174 5186 4576
-3 5174 5166 5186
-3 4577 5187 5768
-3 5188 5189 5175
-3 5217 5188 5175
-3 5175 5189 5190
-3 5176 5175 5191
-3 5191 5175 5190
-3 4570 5176 5192
-3 5176 5191 5192
-3 5192 5193 5177
-3 5204 5177 5193
-3 5169 5177 5204
-3 5179 5178 5205
-3 5180 5179 5195
-3 5195 5179 5194
-3 5196 5180 5195
-3 5181 5180 5196
-3 5784 5183 5182
-3 5784 5197 5183
-3 5184 5183 5197
-3 4559 5184 5209
-3 5209 5184 5197
-3 4559 5209 4580
-3 4580 5198 4567
-3 5185 4567 5199
-3 5199 4567 5198
-3 4573 5199 4574
-3 4573 5185 5199
-3 4574 5186 4575
-3 4574 5199 5186
-3 5199 5212 5186
-3 4576 5186 4581
-3 5186 5212 4581
-3 5214 4583 3974
-3 5217 5200 5201
-3 5188 5217 5201
-3 5189 5188 5202
-3 5202 5188 5201
-3 5190 5189 5203
-3 5203 5189 5202
-3 5191 5190 5193
-3 5193 5190 5203
-3 5192 5191 5193
-3 5194 5179 5205
-3 5206 5195 5205
-3 5205 5195 5194
-3 5206 5824 5195
-3 5195 5824 5196
-3 5181 5196 5207
-3 5207 5196 5824
-3 5172 5181 5207
-3 5182 5172 5207
-3 5223 5182 5207
-3 5208 5784 5182
-3 5208 5182 5223
-3 4580 5209 5825
-3 5825 5198 4580
-3 5198 5210 5199
-3 5211 5199 5210
-3 5212 5199 5211
-3 4581 5212 5224
-3 4581 5224 5225
-3 5225 5187 4581
-3 5213 4583 5214
-3 4585 4587 5215
-3 5216 5218 5217
-3 5217 5218 5200
-3 5201 5200 5219
-3 5219 5200 5218
-3 5202 5201 5220
-3 5220 5201 5219
-3 5193 5203 5220
-3 5220 5203 5202
-3 5221 5207 5857
-3 5222 5207 5221
-3 5223 5207 5222
-3 5208 5223 5228
-3 5197 5208 5228
-3 5209 5197 5228
-3 5211 5210 5233
-3 5212 5211 5229
-3 5229 5211 5233
-3 5224 5212 5229
-3 5187 5225 5230
-3 5879 5214 3974
-3 5879 3974 4588
-3 5226 4589 4585
-3 5215 5226 4585
-3 5215 4587 4593
-3 5215 4593 5226
-3 5227 5226 4593
-3 5217 5226 5227
-3 5217 5227 5216
-3 5216 5227 5231
-3 5218 5216 5231
-3 5219 5218 5231
-3 5220 5219 5231
-3 5222 5221 5857
-3 5223 5222 5228
-3 5228 5222 5857
-3 5825 5209 5228
-3 5233 5210 5232
-3 5224 5229 5234
-3 5225 5224 5234
-3 5230 5225 5234
-3 5226 5235 4589
-3 4596 5227 4593
-3 5825 5228 5874
-3 5210 5825 5874
-3 5234 5229 5233
-3 4600 5879 4588
-3 5227 4596 5238
-3 5238 5231 5227
-3 5233 5232 5234
-3 5879 4600 5236
-3 5236 4600 4604
-3 4608 5236 4604
-3 4608 5239 5236
-3 5237 5239 4608
-3 5237 4612 5239
-3 5238 4606 5241
-3 4628 5242 4626
-3 5242 4628 4051
-3 5243 4620 4627
-3 5242 5244 5243
-3 5242 5243 4633
-3 5242 4633 4626
-3 4051 5244 5242
-3 4627 4634 5243
-3 4633 5243 4634
-3 5244 4051 5964
-3 4643 4629 6015
-3 4639 5245 5246
-3 4641 5247 5248
-3 4641 5248 5246
-3 6028 5249 5248
-3 5246 5248 5249
-3 5246 5249 4639
-3 5247 5250 5251
-3 4641 5250 5247
-3 4641 4644 5250
-3 4645 5249 6028
-3 5250 4644 4650
-3 4645 6028 5252
-3 4645 5252 4646
-3 4650 4649 5250
-3 4649 5253 5250
-3 4646 5252 4648
-3 4049 4651 5253
-3 5253 4652 4049
-3 5253 4649 4652
-3 4648 5252 4656
-3 5256 6052 4642
-3 4651 4655 5253
-3 5254 4655 4657
-3 5254 6064 4655
-3 6064 5253 4655
-3 4657 4656 5255
-3 5254 4657 5255
-3 4656 5258 5255
-3 4656 6066 5258
-3 5254 5257 6064
-3 5257 5258 5259
-3 5257 5254 5258
-3 5254 5255 5258
-3 6053 5256 5265
-3 5259 5258 5262
-3 5260 4051 1262
-3 5265 5256 5261
-3 5259 5262 5264
-3 5264 5262 5263
-3 4658 5265 5261
-3 4658 4659 5265
-3 5265 4659 5267
-3 5267 4659 5266
-3 5268 4050 6143
-3 4052 5267 5266
-3 5270 5275 5268
-3 5275 5269 5268
-3 5276 5275 5270
-3 5276 5277 5275
-3 5278 5271 5273
-3 5278 5277 5271
-3 5272 5271 5276
-3 5276 5271 5277
-3 5267 4052 5285
-3 5269 5279 5274
-3 5275 5280 5269
-3 5280 5279 5269
-3 5280 5277 5281
-3 5280 5275 5277
-3 5278 5281 5277
-3 5279 5282 5274
-3 5282 5287 5274
-3 5283 5279 5284
-3 5283 5282 5279
-3 5280 5284 5279
-3 5274 5286 4662
-3 5287 5286 5274
-3 5282 5288 5287
-3 5288 5282 5283
-3 4662 5286 6230
-3 6230 5286 5287
-3 6241 4662 6230
-3 6241 5289 4662
-3 5290 5289 6241
-3 5290 5291 5295
-3 4666 4662 5289
-3 4666 5289 5302
-3 5296 5302 5289
-3 5290 5293 5289
-3 5293 5296 5289
-3 5294 5293 5290
-3 5295 5294 5290
-3 6274 5295 5291
-3 5299 5285 5292
-3 4667 5296 5294
-3 5294 5296 5293
-3 4667 5294 5297
-3 5297 5294 5295
-3 5305 5295 6274
-3 5297 5295 5305
-3 4672 5298 5292
-3 5299 5292 5298
-3 5302 5308 4666
-3 4667 5304 5296
-3 5296 5304 5303
-3 4667 5305 5304
-3 4667 5297 5305
-3 5302 5309 5308
-3 5309 5302 5296
-3 5303 5309 5296
-3 5310 5309 5303
-3 5304 5310 5303
-3 5305 5310 5304
-3 4671 5316 5306
-3 5306 5311 4679
-3 5299 5298 5318
-3 5307 5300 5314
-3 5315 5307 5314
-3 6326 5315 4684
-3 5319 4675 5308
-3 5316 5317 5306
-3 4679 5311 5317
-3 5311 5306 5317
-3 5321 5299 5318
-3 5322 5299 5321
-3 4682 5300 5324
-3 5314 5300 4682
-3 4684 5315 5314
-3 5317 5316 5320
-3 6369 5322 5323
-3 5327 4677 5325
-3 5319 5325 4677
-3 5328 5325 5319
-3 6380 5328 5319
-3 5308 6380 5319
-3 5335 5321 5318
-3 5322 5321 5335
-3 5328 4697 5325
-3 4691 5330 4692
-3 5329 5330 4691
-3 4692 5331 4693
-3 5330 5331 4692
-3 5332 5333 5334
-3 5343 5333 5332
-3 5336 5322 5335
-3 5323 5322 5336
-3 6369 5323 5345
-3 5346 5324 6378
-3 5337 5326 6440
-3 5326 5338 6440
-3 4696 5327 5339
-3 5327 4100 5339
-3 4698 4697 5328
-3 4698 5328 6380
-3 5329 4700 5340
-3 4691 4700 5329
-3 5331 5340 4701
-3 5331 5330 5340
-3 5330 5329 5340
-3 5342 5343 5332
-3 5334 5344 5332
-3 5344 5342 5332
-3 4716 5335 5318
-3 4716 5336 5335
-3 5345 5354 6369
-3 4717 5324 5346
-3 4718 5324 4717
-3 4703 5324 4718
-3 5337 2279 5326
-3 4706 4696 5347
-3 5347 5339 5348
-3 5347 4696 5339
-3 5349 5348 5339
-3 5349 5339 4100
-3 5349 4100 5350
-3 4698 5351 4128
-3 4707 5352 6415
-3 4708 4707 6417
-3 4707 6415 6417
-3 4708 6417 5357
-3 4710 5353 4700
-3 5358 5353 4710
-3 4700 5353 5340
-3 4701 5340 4712
-3 4712 5340 5353
-3 5344 5343 5342
-3 5345 5323 5336
-3 5354 5345 5336
-3 6428 6369 5354
-3 4743 5346 6405
-3 4717 5346 5355
-3 5356 4724 5347
-3 4724 4706 5347
-3 5350 4100 6501
-3 4708 5357 4726
-3 5358 4710 4726
-3 5358 4726 5357
-3 6485 5353 5358
-3 6485 4712 5353
-3 4742 5336 4716
-3 4762 5336 4742
-3 5354 5336 4180
-3 6405 6465 4763
-3 4743 6405 4763
-3 5346 4743 4744
-3 5355 5346 4744
-3 4717 5355 4744
-3 5360 4736 4723
-3 4749 5356 4750
-3 4724 5356 4749
-3 6501 4100 4750
-3 4771 4128 5351
-3 5352 4707 5374
-3 4712 6485 4739
-3 4762 4180 5336
-3 4794 6465 5359
-3 4763 6465 4794
-3 3635 5361 4684
-3 4785 4736 5363
-3 5363 4736 5360
-3 5360 4723 5365
-3 4723 4737 5365
-3 5362 3635 2279
-3 6440 5338 5379
-3 4737 5372 5365
-3 5375 4138 4752
-3 4739 5375 4752
-3 4753 4773 5366
-3 4757 5367 4776
-3 4775 5367 4757
-3 6567 4776 5367
-3 4777 4776 5368
-3 4759 4777 5368
-3 4778 4759 5368
-3 5368 6598 4778
-3 4794 5359 5354
-3 4769 4798 5369
-3 5371 5370 5365
-3 5372 5371 5365
-3 4154 4771 5373
-3 4138 5375 6615
-3 4788 5385 6623
-3 4773 4772 4788
-3 4773 4788 6623
-3 5366 4773 6623
-3 4753 5366 5376
-3 5377 5376 5378
-3 5377 4753 5376
-3 4753 5377 4789
-3 5367 4775 4790
-3 4790 6567 5367
-3 6598 4791 4778
-3 5369 5386 4805
-3 5369 4798 5386
-3 4785 5363 5389
-3 5364 5389 5363
-3 5389 5364 6603
-3 5371 5381 5370
-3 5381 5380 5370
-3 5372 5382 5371
-3 5382 5381 5371
-3 5383 5382 5372
-3 5383 5372 4154
-3 5373 5383 4154
-3 5394 5384 5374
-3 4138 6615 4806
-3 5395 4172 5378
-3 5377 5378 4172
-3 5377 4172 4789
-3 4171 6660 4790
-3 4791 6660 4171
-3 6598 6660 4791
-3 4804 6695 4783
-3 4798 5387 5386
-3 5387 4798 5388
-3 5388 4785 5401
-3 4785 5389 5401
-3 6603 6680 5389
-3 5381 5390 5380
-3 5391 5390 5382
-3 5390 5381 5382
-3 5383 5391 5382
-3 6609 5392 5393
-3 5384 5393 5392
-3 5384 5394 5393
-3 4810 5395 5396
-3 4172 5395 4810
-3 5411 5399 5398
-3 4796 6676 4812
-3 4169 6676 4796
-3 6695 6676 4169
-3 6677 6695 4804
-3 4805 5386 5417
-3 5387 5417 5386
-3 5417 5388 5400
-3 5417 5387 5388
-3 5401 5400 5388
-3 6680 5402 5389
-3 5402 5401 5389
-3 5430 5370 5380
-3 4813 5380 5390
-3 5390 4814 4813
-3 5390 5391 4814
-3 5393 5404 6609
-3 5404 5403 6609
-3 5405 5404 5393
-3 5394 5405 5393
-3 5394 5406 5405
-3 5406 4806 5407
-3 5407 4806 6615
-3 4819 5385 4815
-3 5385 4816 4815
-3 4810 5396 4820
-3 4820 5396 5408
-3 4191 5409 6667
-3 5397 4191 6667
-3 5397 4822 4191
-3 5410 4822 5397
-3 5397 6692 5410
-3 5398 5413 5411
-3 5399 5413 5398
-3 5413 5399 5414
-3 5415 6677 5416
-3 6677 4804 5416
-3 4805 5416 4804
-3 5417 5416 4805
-3 5400 5401 5418
-3 5401 5402 5418
-3 6680 5419 5402
-3 5419 5418 5402
-3 6680 5430 5419
-3 5380 4818 5430
-3 4813 4818 5380
-3 4825 4814 5420
-3 5403 5404 5431
-3 5405 5421 5404
-3 5421 5431 5404
-3 5422 5421 5405
-3 5406 5423 5405
-3 5423 5422 5405
-3 5424 5423 5406
-3 5407 5425 5406
-3 5425 5424 5406
-3 5426 5425 5407
-3 5407 5427 5426
-3 5427 6707 4819
-3 5385 4819 6707
-3 4191 4821 5409
-3 5428 5410 6692
-3 4822 5410 5428
-3 5414 5411 5413
-3 4823 6720 5379
-3 4828 4824 4812
-3 6676 4828 4812
-3 5429 5415 5416
-3 5417 5429 5416
-3 5400 5418 5419
-3 5421 5422 5431
-3 5423 5431 5422
-3 5424 5432 5423
-3 5432 5431 5423
-3 5425 5432 5424
-3 5426 5432 5425
-3 5427 5433 5426
-3 5433 5432 5426
-3 4819 5433 5427
-3 4820 6739 4833
-3 5408 6739 4820
-3 4821 4199 5409
-3 4822 5428 4199
-3 4823 5444 6720
-3 5419 5435 5400
-3 5435 5419 5430
-3 4825 5438 4836
-3 5420 5438 4825
-3 5432 6757 5431
-3 5439 5432 5433
-3 4833 6739 6782
-3 4835 5436 5430
-3 5430 5436 5435
-3 5436 4835 5437
-3 5438 5437 4836
-3 5439 4832 5443
-3 6779 5443 4832
-3 6779 4832 5440
-3 4833 5440 4832
-3 5440 4833 6782
-3 5441 4206 4839
-3 5438 5436 5437
-3 5439 5442 6818
-3 5443 5442 5439
-3 4838 5434 4850
-3 5441 4839 4841
-3 5447 6818 5442
-3 5447 5442 5443
-3 5456 5444 4823
-3 4840 5449 4842
-3 4840 5445 5449
-3 5445 5448 5449
-3 5450 6815 5446
-3 5451 6815 5450
-3 4843 4844 5450
-3 4843 5450 5441
-3 5441 5450 5446
-3 4841 4843 5441
-3 6830 4846 4206
-3 5452 5453 5454
-3 6882 6840 4849
-3 4823 4237 5456
-3 4843 5451 5450
-3 4843 5450 4844
-3 5453 5457 5458
-3 5453 5452 5457
-3 5459 5457 5454
-3 5454 5457 5452
-3 5457 5460 5461
-3 5459 5460 5457
-3 4869 5451 4843
-3 5458 5463 5471
-3 5458 5457 5463
-3 5457 5461 5463
-3 5460 5464 5461
-3 5464 5463 5461
-3 5465 5466 5467
-3 4245 5468 4852
-3 4851 5468 4245
-3 4856 5455 4855
-3 4858 6890 4867
-3 4858 5478 6890
-3 6890 5470 4867
-3 4869 5479 5451
-3 5464 5471 5463
-3 5472 5473 4860
-3 5473 4861 4860
-3 5473 4863 4861
-3 5474 4863 5473
-3 5469 5477 5476
-3 5455 4864 4855
-3 4858 4865 5478
-3 5470 6949 4867
-3 4859 5480 5482
-3 5472 4860 6904
-3 4860 4868 6904
-3 5474 4868 4863
-3 6904 4868 5474
-3 5476 6926 5475
-3 5456 4237 6980
-3 6983 5478 4867
-3 4867 5478 4865
-3 4867 6949 6983
-3 4870 5479 4869
-3 5479 4870 6920
-3 4870 5482 5480
-3 4870 5480 6920
-3 4877 6980 4237
-3 5481 5482 4870
-3 6933 5496 4874
-3 4877 7000 6980
-3 5483 5482 5481
-3 5482 5483 5484
-3 4882 4874 5496
-3 5486 5488 5487
-3 5484 5483 4879
-3 5489 5490 4876
-3 5490 5491 4876
-3 4873 5504 5492
-3 4873 5492 4881
-3 5492 5493 4881
-3 5495 5493 5494
-3 5485 4874 5506
-3 5497 7032 5486
-3 5487 5499 5486
-3 5499 5498 5486
-3 5500 5499 5487
-3 5488 5508 5487
-3 5508 5500 5487
-3 5508 5488 5501
-3 5515 5489 4898
-3 5489 5515 7034
-3 5489 5502 5490
-3 5503 5490 5502
-3 5491 5490 5503
-3 4910 5485 5505
-3 5506 5505 5485
-3 4882 5496 4962
-3 5497 4883 4289
-3 5507 5498 5499
-3 5500 5507 5499
-3 5509 5512 5511
-3 5510 5512 5509
-3 5511 5512 5513
-3 5513 5514 5525
-3 5512 5514 5513
-3 4898 5514 5515
-3 4889 5517 5518
-3 5516 5517 4889
-3 5519 5504 4892
-3 4910 5527 5485
-3 5520 5505 5506
-3 5521 5520 5506
-3 5506 4894 5521
-3 4289 4895 5497
-3 5497 4895 4896
-3 5497 4896 5535
-3 4897 5507 5500
-3 5508 4913 5500
-3 4913 4897 5500
-3 5501 4913 5508
-3 5523 5510 5509
-3 5511 5524 5509
-3 5524 5523 5509
-3 5513 5530 5511
-3 5530 5524 5511
-3 5525 5530 5513
-3 5514 4898 5525
-3 5531 4308 4899
-3 7067 5531 4899
-3 4901 7067 4899
-3 5502 7067 4901
-3 4902 5502 4901
-3 4902 5526 5502
-3 5526 5503 5502
-3 4889 4903 5516
-3 4904 5516 4903
-3 5517 5516 4904
-3 4905 5517 4904
-3 5518 5517 4905
-3 4909 4921 5527
-3 4909 5527 4910
-3 5505 5520 5528
-3 5528 5520 5521
-3 4894 5544 5528
-3 5521 4894 5528
-3 5535 4896 4912
-3 5523 5524 5536
-3 5530 5529 5524
-3 5529 5536 5524
-3 5525 4914 5530
-3 4902 4916 5526
-3 4921 5543 7180
-3 4921 7180 5527
-3 5528 5544 5532
-3 7237 4373 4850
-3 4912 4922 5535
-3 4913 5501 4923
-3 5501 5558 4923
-3 4355 5522 5549
-3 5530 5536 5529
-3 4914 5536 5530
-3 5538 5537 5531
-3 5531 5537 5550
-3 4926 4925 5541
-3 4926 5541 4921
-3 5541 5542 4921
-3 5543 4921 5542
-3 7192 5533 5545
-3 5534 5545 5533
-3 5545 5546 5547
-3 5534 5546 5545
-3 7197 5535 4922
-3 4933 4923 5558
-3 4935 5559 4914
-3 4937 7169 7211
-3 4938 7169 4937
-3 5538 4938 5537
-3 5538 7169 4938
-3 4938 5550 5537
-3 5540 5551 5539
-3 4845 7220 5643
-3 5552 4927 5563
-3 5563 4927 4928
-3 5553 5554 5555
-3 4939 5555 5554
-3 5547 5556 5545
-3 5548 4943 5557
-3 4931 4943 5548
-3 4932 5557 4944
-3 5548 5557 4932
-3 4922 4945 7197
-3 4346 4355 5549
-3 5559 4935 5560
-3 5561 7211 7248
-3 5561 4946 7211
-3 4946 4937 7211
-3 4938 4947 5550
-3 5541 4948 5542
-3 5562 5542 4948
-3 4927 5552 4349
-3 4349 5552 7223
-3 5553 5555 4960
-3 5564 5554 5553
-3 5554 5565 4951
-3 5554 5564 5565
-3 4951 5565 5570
-3 4951 5570 4941
-3 4943 4944 5557
-3 4292 4952 5576
-3 5566 4953 4346
-3 7248 4954 5567
-3 7248 5560 4954
-3 5560 4935 4954
-3 7248 5567 5561
-3 5561 5567 5573
-3 5561 5573 4946
-3 4948 4956 5562
-3 5562 4956 5568
-3 5569 4349 7223
-3 5569 4959 4349
-3 5563 4928 4960
-3 5570 5565 5564
-3 5570 5564 4961
-3 4953 5566 5571
-3 4954 5572 5567
-3 5573 5567 5572
-3 5574 5587 5568
-3 4959 5575 5574
-3 4959 5574 5568
-3 4959 5568 4956
-3 4959 7302 5575
-3 4959 5569 7302
-3 5580 4933 5558
-3 5580 5592 4933
-3 5571 7361 4381
-3 4953 5571 4381
-3 5577 5573 5572
-3 5587 5574 5578
-3 5574 5579 5578
-3 7302 5579 5575
-3 5579 5574 5575
-3 4965 7344 4961
-3 7345 4971 4962
-3 4973 7464 4966
-3 7464 4945 4966
-3 4952 5581 5576
-3 4381 5581 4952
-3 7361 5581 4381
-3 5583 5584 5585
-3 5586 5587 5578
-3 5579 5588 5578
-3 5588 5586 5578
-3 5588 5579 7302
-3 7344 4965 4968
-3 7344 4968 4977
-3 5589 4384 4970
-3 7345 5596 4971
-3 4975 5591 5580
-3 4975 5580 5590
-3 5592 5580 5591
-3 4989 7402 5584
-3 5600 4989 5583
-3 5584 5583 4989
-3 5594 5587 5586
-3 5602 5587 5594
-3 5594 5586 5588
-3 4977 4968 4976
-3 7410 4993 4980
-3 7410 4980 5589
-3 5589 4980 4981
-3 4396 5589 4981
-3 5589 4396 4384
-3 4994 5589 4970
-3 4994 5595 5596
-3 4994 5596 5589
-3 4983 5596 5595
-3 4983 4971 5596
-3 4973 4403 7464
-3 5597 5591 4975
-3 5597 5592 5591
-3 4985 5592 5598
-3 5592 5597 5598
-3 4986 5582 5599
-3 5582 5605 5599
-3 5607 4996 5593
-3 7402 4988 5600
-3 4989 4988 7402
-3 5602 5594 5601
-3 4993 7410 5623
-3 4983 5595 5603
-3 5603 5595 4994
-3 5009 5604 5597
-3 5604 5598 5597
-3 5598 5604 4985
-3 5607 5606 4996
-3 4988 4997 5600
-3 5609 5602 5601
-3 5610 5601 5594
-3 5609 5601 5610
-3 5007 4993 5623
-3 5008 5603 4994
-3 7486 4415 5590
-3 5604 5009 5612
-3 4985 5604 5613
-3 5604 5612 5613
-3 5599 5605 5002
-3 4996 5004 5593
-3 5593 5004 5615
-3 5006 5606 5614
-3 5614 5606 5607
-3 5617 5607 7447
-3 5614 5607 5617
-3 4977 5619 7477
-3 5611 4977 7477
-3 5011 5612 5009
-3 5613 5612 5011
-3 5013 5615 5004
-3 5616 5615 5014
-3 5014 5615 5013
-3 5014 5617 5616
-3 5006 5617 5014
-3 5006 5614 5617
-3 5016 5618 5619
-3 4977 5016 5619
-3 5007 5623 5628
-3 5016 5620 5618
-3 5620 5621 5618
-3 5619 5618 5622
-3 5622 5618 5621
-3 5619 5622 7503
-3 4963 4237 5677
-3 5023 5625 5024
-3 5624 5625 5023
-3 5031 5620 5016
-3 5031 5626 5620
-3 5626 5627 5620
-3 5032 5621 5627
-3 5621 5620 5627
-3 5033 5621 5032
-3 5622 5621 5033
-3 5034 5622 5033
-3 5034 5628 5622
-3 5628 7503 5622
-3 5623 7503 5628
-3 5624 5023 7530
-3 5023 5634 7530
-3 7540 5625 5624
-3 4448 5625 7540
-3 4448 5024 5625
-3 5031 5035 5626
-3 5032 5626 5035
-3 5627 5626 5032
-3 5034 5036 5628
-3 5037 4448 7540
-3 5039 5630 5631
-3 5038 5630 5039
-3 5631 5038 5039
-3 5628 5036 4467
-3 5040 5041 5629
-3 5040 5629 5633
-3 5044 5043 7556
-3 5045 5044 5630
-3 5044 7556 5630
-3 5630 5038 5045
-3 5047 5038 5631
-3 7565 5049 5639
-3 7565 5632 5049
-3 5632 5041 5049
-3 5048 5040 5633
-3 5048 5633 5639
-3 5051 5050 5635
-3 5051 5636 5052
-3 5635 5636 5051
-3 5052 5636 5053
-3 5056 5057 5637
-3 5056 5637 5638
-3 5056 5638 5043
-3 5047 5631 5641
-3 5049 5060 5639
-3 5048 5639 5060
-3 5071 5635 5050
-3 5071 5636 5635
-3 5053 5071 5061
-3 5636 5071 5053
-3 5057 5066 5637
-3 5640 5074 5642
-3 5063 5074 5640
-3 5066 5076 5637
-3 5645 5638 5637
-3 5645 5637 5076
-3 5069 5641 5082
-3 5074 5644 5642
-3 5645 5076 5081
-3 5641 7610 5082
-3 4373 7616 3952
-3 5081 5087 5645
-3 5088 5082 7610
-3 3952 7616 4509
-3 5109 5652 5083
-3 5646 5096 5083
-3 5647 5085 5654
-3 4492 5648 5091
-3 4492 5647 5648
-3 5647 5654 5648
-3 5649 7640 7620
-3 7620 5650 5649
-3 5651 5093 5092
-3 5094 5093 5651
-3 5087 5094 5645
-3 5094 5651 5645
-3 5096 5646 5653
-3 7666 5096 5653
-3 5666 5096 7666
-3 5091 5648 5104
-3 5655 7640 5649
-3 5650 5656 5649
-3 5656 5655 5649
-3 5105 5656 5650
-3 5102 5101 5657
-3 5102 5657 5103
-3 5116 7680 5115
-3 5115 7680 5665
-3 5109 5658 5652
-3 5660 5648 5659
-3 5659 5648 5654
-3 5104 5648 5660
-3 5655 5104 5660
-3 5105 5104 5655
-3 5656 5105 5655
-3 5107 5662 5661
-3 5107 5106 5662
-3 5106 5105 5662
-3 5101 5108 5657
-3 5103 5657 5108
-3 5118 7671 5092
-3 5663 5664 5112
-3 5671 7680 5116
-3 5115 5665 5123
-3 7686 5109 4509
-3 7686 5658 5109
-3 5660 5659 5666
-3 5107 5661 5110
-3 5661 5111 5110
-3 5661 5662 5111
-3 5112 5673 5672
-3 5114 5667 5668
-3 5668 5669 5670
-3 5667 5669 5668
-3 5671 5670 5669
-3 7777 7761 4509
-3 7761 7686 4509
-3 5662 5127 5111
-3 5683 7724 5674
-3 5114 5674 7724
-3 5668 5675 5122
-3 5114 5668 5122
-3 5670 5676 5668
-3 5676 5675 5668
-3 5671 5116 5670
-3 5116 5676 5670
-3 5124 5123 5665
-3 5679 5678 5691
-3 5127 5693 5681
-3 5127 5662 5693
-3 5681 5693 5118
-3 5119 5135 5112
-3 5673 5695 5672
-3 5695 5682 5672
-3 5673 5683 5695
-3 5683 5674 5684
-3 5685 5684 5674
-3 5674 5686 5685
-3 5122 5675 5687
-3 5676 5688 5675
-3 5688 5687 5675
-3 5116 5132 5688
-3 5116 5688 5676
-3 5703 5137 5665
-3 5124 5137 5133
-3 5665 5137 5124
-3 5689 5678 5679
-3 5690 5689 5679
-3 5691 5678 5689
-3 5691 5689 5692
-3 5125 7784 5697
-3 5126 7784 5125
-3 5127 5681 5134
-3 5694 5135 5682
-3 5695 5694 5682
-3 5708 5695 5683
-3 5685 5700 5684
-3 5686 5696 5685
-3 5696 5686 5122
-3 5687 5696 5122
-3 5132 5136 5688
-3 7803 5689 5690
-3 5692 5689 7803
-3 5680 5138 7824
-3 5695 5699 5694
-3 5699 5698 5694
-3 5708 5699 5695
-3 5684 5708 5683
-3 5685 5701 5700
-3 5696 5702 5685
-3 5702 5701 5685
-3 5688 5136 5703
-3 5704 5703 5136
-3 5703 5704 5137
-3 5138 5705 7824
-3 5706 5705 5138
-3 5139 5707 5138
-3 5138 5707 5706
-3 7826 5707 5139
-3 5140 5643 5698
-3 5699 5140 5698
-3 5700 5708 5684
-3 5701 5709 5700
-3 5702 5710 5701
-3 5710 5709 5701
-3 5711 5710 5702
-3 5136 5712 5704
-3 5137 5704 5712
-3 5141 7840 5713
-3 7824 5705 5142
-3 7824 5142 5713
-3 5713 5142 5141
-3 5705 5706 5142
-3 5142 5706 5143
-3 5144 5143 5714
-3 5143 5706 5714
-3 7826 5139 5144
-3 5714 7826 5144
-3 5700 5715 5708
-3 5709 5715 5700
-3 5710 5715 5709
-3 5711 5145 5710
-3 5145 5715 5710
-3 5711 5716 5145
-3 5716 5717 5712
-3 5712 5717 4530
-3 5677 4530 5718
-3 5141 4521 7840
-3 5716 5718 5717
-3 4530 5717 5718
-3 4539 5719 5720
-3 4539 5721 5719
-3 4539 5722 5721
-3 4539 5723 5722
-3 4539 5724 5723
-3 4539 5725 5724
-3 5727 5726 4539
-3 4539 5726 5725
-3 5727 5729 5728
-3 5727 5730 5729
-3 5727 5731 5730
-3 4534 5732 5731
-3 4534 5731 5727
-3 5733 4534 5146
-3 5745 5733 5146
-3 5734 5749 5149
-3 5734 5149 4533
-3 4533 5735 5734
-3 5152 5736 4533
-3 4533 5736 5735
-3 5152 5737 5736
-3 4538 5738 5739
-3 4538 5740 5738
-3 4539 5741 4538
-3 4538 5741 5740
-3 5741 4539 5720
-3 4534 5742 5732
-3 5743 5742 4534
-3 5744 5743 4534
-3 5733 5744 4534
-3 5746 5745 5146
-3 5150 5747 5746
-3 5146 5150 5746
-3 5149 5748 5160
-3 5149 5749 5748
-3 5152 5750 5737
-3 5751 5750 5152
-3 5152 5759 5751
-3 5152 5164 5759
-3 5153 5752 5753
-3 4538 5754 5153
-3 5153 5754 5752
-3 5754 4538 5739
-3 5150 5755 5747
-3 5150 5160 5755
-3 5160 5756 5755
-3 5160 5757 5756
-3 5748 5758 5160
-3 5758 5757 5160
-3 5760 5761 5759
-3 5164 5760 5759
-3 5164 5167 5762
-3 5760 5164 5762
-3 5153 5763 5764
-3 5763 5153 5753
-3 5765 5761 5760
-3 5766 5761 5765
-3 5762 5767 5760
-3 5767 5765 5760
-3 5167 5767 5762
-3 5167 5768 5767
-3 5768 5769 5767
-3 5771 5770 5768
-3 5175 5772 5773
-3 5153 5774 5175
-3 5175 5774 5772
-3 5774 5153 5764
-3 5776 5766 5765
-3 5775 5766 5776
-3 5767 5776 5765
-3 5777 5767 5769
-3 5776 5767 5777
-3 5768 5778 5771
-3 5779 5778 5768
-3 5780 5217 5781
-3 5175 5782 5217
-3 5217 5782 5781
-3 5782 5175 5773
-3 5170 5783 5178
-3 5198 5785 5786
-3 5787 5198 5786
-3 5776 5788 5775
-3 5788 5789 5790
-3 5788 5776 5789
-3 5791 5776 5777
-3 5789 5776 5791
-3 5792 5779 5187
-3 5779 5768 5187
-3 5792 5187 5793
-3 5795 5794 5217
-3 5780 5795 5217
-3 5204 5817 5169
-3 5817 5818 5169
-3 5819 5169 5818
-3 5796 5797 5783
-3 5796 5783 5819
-3 5819 5783 5169
-3 5798 5783 5797
-3 5799 5783 5798
-3 5800 5783 5799
-3 5801 5783 5800
-3 5802 5783 5801
-3 5820 5802 5803
-3 5178 5802 5820
-3 5178 5783 5802
-3 5820 5205 5178
-3 5197 5784 5208
-3 5198 5825 5804
-3 5198 5804 5785
-3 5210 5198 5805
-3 5805 5198 5787
-3 5789 5806 5790
-3 5791 5806 5789
-3 5807 5793 5187
-3 5214 5808 5809
-3 5213 5214 5809
-3 5214 5810 5808
-3 5214 5811 5810
-3 5812 5811 5214
-3 5217 5814 5813
-3 5814 5217 5794
-3 5835 5838 5193
-3 5815 5816 5204
-3 5815 5204 5838
-3 5838 5204 5193
-3 5817 5204 5816
-3 5821 5205 5820
-3 5205 5821 5822
-3 5823 5205 5822
-3 5205 5823 5206
-3 5823 5840 5206
-3 5824 5206 5840
-3 5824 5857 5207
-3 5826 5804 5210
-3 5210 5804 5825
-3 5805 5826 5210
-3 5827 5807 5187
-3 5213 5809 5240
-3 5809 5828 5240
-3 5214 5829 5812
-3 5829 5214 5879
-3 5830 5829 5879
-3 5831 5226 5832
-3 5226 5833 5832
-3 5850 5833 5226
-3 5226 5834 5850
-3 5226 5217 5834
-3 5217 5813 5834
-3 5220 5868 5193
-3 5835 5193 5868
-3 5836 5837 5835
-3 5838 5835 5837
-3 5840 5823 5839
-3 5841 5824 5840
-3 5841 5842 5824
-3 5854 5824 5842
-3 5857 5824 5854
-3 5187 5230 5843
-3 5843 5827 5187
-3 5828 5844 5240
-3 5879 5845 5830
-3 5879 5846 5845
-3 5847 5846 5879
-3 5226 5849 5235
-3 5849 5848 5235
-3 5831 5849 5226
-3 5868 5220 5231
-3 5851 5852 5835
-3 5851 5835 5868
-3 5836 5835 5852
-3 5854 5842 5853
-3 5855 5857 5854
-3 5855 5856 5857
-3 5230 5234 5858
-3 5230 5858 5859
-3 5230 5859 5843
-3 5240 5844 5860
-3 5861 5240 5860
-3 5879 5862 5847
-3 5879 5863 5862
-3 5235 5864 5865
-3 5864 5235 5848
-3 5866 5867 5231
-3 5866 5231 5885
-3 5868 5231 5867
-3 5857 5856 5869
-3 5870 5857 5869
-3 5871 5857 5870
-3 5872 5857 5871
-3 5872 5873 5857
-3 5857 5873 5228
-3 5228 5873 5874
-3 5874 5232 5210
-3 5234 5893 5875
-3 5234 5875 5876
-3 5234 5876 5858
-3 5861 5877 5240
-3 5879 5878 5863
-3 5880 5879 5236
-3 5235 5865 5881
-3 5882 5883 5231
-3 5884 5231 5883
-3 5885 5231 5884
-3 5874 5873 5886
-3 5887 5874 5886
-3 5888 5874 5887
-3 5889 5874 5888
-3 5890 5874 5889
-3 5890 5891 5874
-3 5904 5874 5891
-3 5232 5874 5905
-3 5905 5874 5904
-3 5234 5232 5909
-3 5909 5232 5908
-3 5910 5234 5909
-3 5892 5234 5910
-3 5892 5893 5234
-3 5240 5877 5894
-3 5895 5240 5894
-3 5236 5896 5880
-3 5236 5897 5896
-3 5897 5236 5898
-3 5900 5899 5235
-3 5881 5900 5235
-3 5238 5901 5231
-3 5901 5902 5231
-3 5902 5882 5231
-3 5904 5891 5903
-3 5906 5232 5905
-3 5907 5232 5906
-3 5908 5232 5907
-3 5911 5892 5910
-3 5895 5912 5240
-3 5236 5913 5898
-3 5236 5239 5913
-3 5239 5914 5913
-3 5915 5914 5239
-3 5235 5916 5917
-3 5916 5235 5899
-3 5919 5920 5901
-3 5919 5901 5918
-3 5918 5901 5238
-3 5902 5901 5920
-3 5921 5902 5920
-3 5922 5240 5912
-3 5239 5923 5915
-3 4612 5923 5239
-3 5924 5923 4612
-3 5925 5235 5917
-3 5926 5927 5918
-3 5926 5918 5935
-3 5935 5918 5238
-3 5919 5918 5927
-3 5240 5928 5929
-3 5240 5922 5928
-3 5930 4620 5931
-3 5930 5924 4620
-3 5924 4612 4620
-3 5925 5932 5235
-3 5241 5944 5933
-3 5241 5933 5934
-3 5241 5934 5238
-3 5935 5238 5934
-3 5240 5929 5936
-3 5936 5937 5240
-3 5931 4620 5938
-3 5939 5931 5938
-3 5939 5938 5940
-3 5235 5941 5942
-3 5941 5235 5932
-3 5241 5943 5944
-3 5937 5945 5240
-3 4620 5243 5938
-3 5244 5938 5243
-3 5938 5946 5940
-3 5938 5244 5946
-3 5947 5946 5244
-3 5948 5235 5942
-3 5949 5943 5241
-3 5945 5950 5240
-3 5244 5951 5947
-3 5952 5951 5244
-3 5235 5953 4635
-3 5235 5948 5953
-3 5241 5954 5955
-3 5241 5955 5949
-3 5956 5240 5950
-3 5952 5244 5957
-3 4635 5958 5959
-3 4635 5959 3496
-3 5953 5958 4635
-3 5241 4642 5960
-3 5960 5954 5241
-3 5961 5240 5956
-3 5961 5962 5240
-3 5244 5963 5957
-3 5964 5963 5244
-3 5965 3496 5959
-3 4642 5966 5967
-3 4642 5967 5960
-3 5240 5962 4629
-3 5962 5968 4629
-3 5964 4051 5969
-3 5965 5970 3496
-3 5971 5966 4642
-3 5972 4629 5968
-3 5973 5974 5975
-3 5975 5976 5973
-3 4051 5977 5969
-3 5978 5977 4051
-3 5979 3496 5970
-3 5980 5971 4642
-3 5972 5981 4629
-3 5982 5974 5973
-3 5983 5974 5982
-3 5984 5973 5976
-3 5982 5973 5984
-3 5985 5978 4051
-3 5979 5986 3496
-3 4642 5987 5988
-3 4642 5988 5980
-3 4629 5981 5989
-3 5982 5990 5983
-3 5984 5990 5982
-3 5991 5985 4051
-3 5991 4051 5992
-3 5986 5993 3496
-3 5994 5987 4642
-3 4629 6000 6015
-3 5995 4629 5989
-3 6000 4629 5995
-3 5992 4051 5996
-3 3496 5997 5998
-3 5997 3496 5993
-3 5999 5994 4642
-3 6001 5996 4051
-3 5998 6002 3496
-3 6003 5999 4642
-3 6009 6003 4642
-3 6000 6004 6015
-3 6005 6001 4051
-3 6005 4051 6006
-3 6002 6007 3496
-3 6009 4642 6008
-3 6004 6010 6015
-3 6006 4051 6011
-3 3496 6012 6013
-3 6012 3496 6007
-3 4642 6014 6008
-3 6016 6011 4051
-3 6013 6017 3496
-3 6018 6014 4642
-3 6015 6019 4643
-3 5248 5247 6027
-3 5248 6027 6028
-3 6020 6016 4051
-3 6020 4051 6021
-3 6017 6022 3496
-3 6023 6018 4642
-3 6019 6024 4643
-3 5251 6025 6026
-3 5250 6025 5251
-3 6027 5247 5251
-3 6027 5251 6026
-3 6029 6021 4051
-3 3496 6022 6030
-3 6031 6023 4642
-3 6024 6032 4643
-3 6025 5250 6033
-3 5252 6028 6034
-3 6035 6029 4051
-3 3496 6036 6037
-3 6030 6036 3496
-3 4642 6052 6053
-3 6038 6031 4642
-3 6053 6038 4642
-3 6032 6039 4643
-3 5250 5253 6033
-3 6033 5253 6040
-3 6041 5252 6034
-3 6042 6035 4051
-3 6042 4051 6043
-3 6037 6044 3496
-3 6045 6038 6053
-3 4643 6039 6046
-3 5253 6047 6048
-3 6048 6040 5253
-3 6041 6049 5252
-3 6050 6043 4051
-3 4702 3496 6051
-3 3496 6044 6051
-3 6054 6045 6053
-3 6055 4643 6046
-3 6062 4643 6055
-3 5253 6056 6047
-3 6049 6057 4656
-3 5252 6049 4656
-3 4051 6058 6050
-3 4702 6059 6060
-3 6051 6059 4702
-3 6053 6052 5256
-3 6061 6054 6053
-3 6065 6056 5253
-3 6064 6065 5253
-3 4656 6067 6066
-3 4656 6057 6067
-3 6058 4051 6068
-3 6060 6069 4702
-3 6070 6061 6053
-3 6062 6063 4643
-3 6063 6071 4643
-3 6064 5257 5259
-3 6064 5259 6065
-3 6065 5259 6072
-3 6066 6073 5258
-3 6068 4051 6074
-3 4702 6075 6087
-3 4702 6069 6075
-3 6070 6053 6076
-3 4050 4643 6077
-3 6077 4643 6071
-3 5259 6078 6079
-3 6079 6072 5259
-3 6073 6093 5258
-3 6080 6094 6073
-3 6094 6093 6073
-3 6080 6081 6094
-3 6082 6083 6084
-3 6084 6085 6082
-3 5260 6086 4051
-3 6086 6074 4051
-3 6087 6088 4702
-3 6089 5265 6090
-3 6089 6076 5265
-3 6076 6053 5265
-3 6077 6091 4050
-3 5264 6092 5259
-3 5259 6092 6078
-3 5258 6093 5262
-3 6095 6094 6081
-3 6096 6097 6098
-3 6096 6083 6099
-3 6098 6083 6096
-3 6100 6082 6101
-3 6100 6099 6082
-3 6083 6082 6099
-3 6085 6101 6082
-3 5260 6102 6086
-3 6088 6103 4702
-3 6090 5265 6104
-3 6091 6105 4050
-3 6092 5264 6106
-3 5263 6107 6122
-3 5262 6107 5263
-3 5262 6093 6107
-3 6094 6107 6093
-3 6108 6107 6094
-3 6095 6108 6094
-3 6109 6097 6096
-3 6110 6097 6109
-3 6099 6111 6096
-3 6111 6109 6096
-3 6112 6099 6100
-3 6111 6099 6112
-3 6102 5260 6113
-3 4702 6103 6114
-3 6104 5265 6115
-3 4050 6116 6117
-3 6116 4050 6105
-3 6118 6106 5264
-3 6119 6106 6118
-3 5264 6120 6118
-3 5264 5263 6120
-3 6120 6121 6118
-3 6122 6120 5263
-3 6123 6124 6125
-3 6110 6123 6125
-3 6110 6109 6123
-3 6109 6126 6123
-3 6127 6111 6128
-3 6127 6126 6111
-3 6126 6109 6111
-3 6112 6128 6111
-3 6129 6113 5260
-3 6114 6130 4702
-3 5265 5267 6115
-3 5267 6131 6115
-3 4050 6117 6143
-3 6117 6132 6143
-3 6133 6119 6118
-3 6134 6119 6133
-3 6135 6118 6121
-3 6133 6118 6135
-3 6136 6124 6123
-3 6137 6124 6136
-3 6138 6126 6139
-3 6138 6136 6126
-3 6136 6123 6126
-3 6127 6139 6126
-3 5260 6140 6129
-3 6130 6141 4702
-3 6131 5267 6142
-3 6133 6144 6134
-3 6135 6144 6133
-3 6136 6145 6137
-3 6138 6145 6136
-3 6140 5260 6146
-3 6141 6147 4702
-3 6148 5267 6149
-3 6148 6142 5267
-3 6143 6154 5268
-3 6143 6150 6154
-3 6146 5260 6151
-3 6147 6152 4702
-3 5267 6153 6149
-3 6154 6155 5268
-3 6151 5260 6156
-3 6152 6157 4702
-3 5267 6159 6158
-3 5267 6158 6153
-3 6155 6160 5268
-3 6161 6162 6163
-3 6161 6164 6165
-3 6163 6164 6161
-3 6165 6166 6167
-3 6164 6166 6165
-3 6167 6168 6169
-3 6166 6168 6167
-3 6168 6170 6169
-3 6171 6156 5260
-3 6157 6172 4702
-3 5267 6173 6159
-3 6174 5270 5268
-3 6174 5268 6160
-3 5271 6175 6176
-3 5272 6175 5271
-3 5273 6177 6178
-3 5273 5271 6177
-3 5271 6176 6177
-3 6177 6179 6178
-3 6178 6180 6181
-3 6179 6180 6178
-3 6182 6161 6183
-3 6182 6181 6161
-3 6162 6161 6180
-3 6180 6161 6181
-3 6165 6183 6161
-3 6184 6183 6165
-3 6167 6184 6165
-3 6185 6184 6167
-3 6169 6185 6167
-3 6186 6185 6169
-3 6170 6186 6169
-3 5260 6187 6171
-3 6172 6188 4702
-3 6189 6173 5267
-3 6189 5267 6190
-3 5284 6191 6192
-3 6191 5284 6193
-3 6194 6174 6195
-3 5276 6174 6194
-3 5276 5270 6174
-3 5273 6197 5278
-3 5276 6194 5272
-3 5272 6194 6196
-3 5272 6196 6175
-3 5273 6198 6197
-3 5273 6178 6198
-3 6198 6208 6199
-3 6198 6178 6208
-3 6200 6181 6201
-3 6200 6208 6181
-3 6208 6178 6181
-3 6182 6201 6181
-3 6187 5260 6202
-3 6188 6203 4702
-3 5285 6190 5267
-3 5285 6204 6190
-3 6205 5284 6192
-3 6206 6193 5284
-3 6206 5284 5280
-3 6195 6206 5280
-3 6194 6195 5280
-3 6194 5280 5281
-3 6194 6207 6196
-3 6194 5281 6207
-3 6197 6207 5278
-3 5278 6207 5281
-3 6202 5260 6209
-3 6203 6210 4702
-3 5285 6212 6211
-3 5285 6211 6204
-3 5283 6213 6214
-3 6205 6213 5283
-3 5284 6205 5283
-3 6209 5260 6215
-3 6210 6216 4702
-3 5285 6217 6212
-3 5288 5283 6214
-3 6218 5288 6214
-3 6215 5260 6219
-3 6216 6220 4702
-3 5285 6221 6217
-3 6221 5285 6222
-3 6238 6223 6224
-3 6223 6238 6225
-3 6238 6226 6227
-3 6225 6238 6227
-3 6227 6226 6228
-3 5287 6229 6230
-3 6218 6229 5288
-3 6229 5287 5288
-3 5260 6231 6219
-3 6220 6232 4702
-3 5285 6233 6222
-3 6233 5285 6234
-3 6235 6236 6237
-3 6235 6238 6239
-3 6236 6235 6239
-3 6224 6239 6238
-3 6240 6228 6226
-3 6242 6241 6230
-3 6242 5291 6241
-3 6242 6243 5291
-3 5260 6244 6231
-3 6232 6245 4702
-3 6246 6247 6248
-3 6248 6249 6246
-3 5285 6251 6234
-3 6251 5285 6252
-3 6253 6235 6237
-3 6254 6253 6237
-3 6238 6235 6268
-3 6268 6235 6253
-3 6255 6238 6268
-3 6226 6238 6256
-3 6256 6238 6255
-3 6257 6240 6226
-3 6256 6257 6226
-3 5291 5290 6241
-3 5291 6243 6258
-3 6244 5260 6259
-3 6245 6260 4702
-3 6261 6247 6246
-3 6249 6262 6246
-3 6262 6261 6246
-3 6263 6249 6250
-3 6262 6249 6263
-3 5285 6264 6252
-3 6253 6266 6267
-3 6254 6266 6253
-3 6255 6268 6269
-3 6256 6255 6270
-3 6270 6255 6269
-3 6271 6257 6256
-3 6271 6256 6272
-3 6272 6256 6270
-3 6273 5291 6258
-3 6273 6274 5291
-3 6259 5260 6275
-3 6260 6276 4702
-3 6277 6278 6279
-3 6277 6261 6278
-3 6261 6262 6278
-3 6280 6262 6263
-3 6278 6262 6280
-3 5285 5299 6264
-3 5299 6281 6265
-3 5299 6265 6264
-3 6283 6284 6285
-3 6267 6284 6283
-3 6267 6283 6253
-3 6253 6283 6286
-3 6287 6253 6286
-3 6268 6253 6287
-3 6288 6268 6287
-3 6269 6268 6288
-3 6270 6269 6288
-3 6272 6270 6289
-3 6289 6270 6288
-3 6290 6272 6291
-3 6291 6272 6289
-3 6290 6291 6292
-3 6274 6294 5305
-3 6275 5260 6295
-3 6276 6296 4702
-3 6278 6297 6279
-3 6297 6278 6316
-3 6298 6316 6280
-3 6280 6316 6278
-3 6298 6299 6316
-3 5299 6300 6282
-3 5299 6282 6281
-3 6300 5299 6301
-3 6303 6283 6285
-3 6304 6303 6285
-3 6286 6283 6305
-3 6305 6283 6303
-3 6287 6286 6306
-3 6306 6286 6305
-3 5300 6287 6306
-3 6288 6287 5300
-3 5307 6288 5300
-3 5307 6307 6288
-3 6307 6289 6288
-3 5301 6291 6307
-3 6291 6289 6307
-3 5301 6308 6291
-3 6308 6292 6291
-3 6309 6293 6292
-3 6309 6292 6310
-3 6310 6292 6308
-3 5305 6311 6312
-3 6311 5305 6294
-3 6295 5260 6313
-3 6296 6314 4702
-3 6297 6316 6315
-3 6317 6316 6299
-3 5322 6301 5299
-3 6319 6302 6301
-3 6319 6301 5322
-3 6319 5322 6320
-3 6304 6324 6303
-3 6303 6324 5324
-3 6305 6303 5324
-3 6306 6305 5324
-3 5300 6306 5324
-3 6307 5307 6325
-3 5301 6307 6326
-3 6307 6325 6326
-3 5301 6326 6308
-3 6310 6308 6327
-3 6327 6308 6326
-3 6327 6328 6310
-3 6329 6348 5309
-3 6329 5309 6330
-3 6330 5309 5310
-3 5310 6331 6330
-3 6312 5310 5305
-3 6331 5310 6312
-3 6313 5260 6332
-3 6314 6333 4702
-3 6334 6315 5313
-3 5312 5313 6316
-3 6316 5313 6315
-3 5312 6316 6317
-3 6335 6317 6318
-3 6335 5312 6317
-3 6335 6336 5312
-3 6337 6320 5322
-3 6337 5322 6338
-3 6339 6340 6341
-3 6340 6339 6342
-3 6342 6362 6343
-3 6322 6343 6362
-3 6322 6362 6321
-3 6321 6362 5324
-3 6323 6321 5324
-3 6324 6323 5324
-3 5307 5315 6325
-3 6326 6325 5315
-3 6327 6326 4684
-3 6327 4684 6328
-3 6328 4684 6344
-3 5308 6345 6346
-3 5309 6347 5308
-3 5308 6347 6345
-3 6348 6347 5309
-3 6332 5260 6349
-3 6333 6350 4702
-3 5313 6351 6334
-3 6353 6352 6351
-3 5312 6353 6351
-3 5312 6351 5313
-3 5312 6354 6353
-3 6355 6354 5312
-3 6336 6355 5312
-3 5322 6356 6338
-3 6356 5322 6357
-3 6358 6359 6360
-3 6341 6359 6358
-3 6341 6358 6339
-3 6339 6358 6361
-3 6342 6339 6362
-3 6362 6339 6361
-3 5324 6362 6378
-3 6363 6344 4684
-3 6364 5308 6365
-3 6365 5308 6346
-3 6349 5260 6366
-3 6350 6367 4702
-3 6353 6368 6352
-3 6369 6370 6357
-3 6369 6357 5322
-3 6370 6369 6371
-3 6373 6374 6375
-3 6374 6373 6376
-3 6376 6378 6377
-3 6360 6377 6378
-3 6360 6378 6358
-3 6361 6358 6378
-3 6362 6361 6378
-3 6363 4684 6379
-3 6380 5308 6381
-3 6381 5308 6364
-3 6366 5260 6382
-3 6367 6383 4702
-3 6384 6372 6371
-3 6384 6371 6369
-3 6384 6369 6385
-3 6388 6386 6387
-3 6375 6386 6388
-3 6375 6388 6373
-3 6376 6373 6388
-3 6378 6376 5346
-3 5346 6376 6388
-3 6379 4684 6389
-3 6381 6391 6380
-3 6391 6390 6380
-3 6391 6381 6392
-3 5343 6393 6394
-3 5333 5343 6395
-3 5343 6394 6395
-3 6395 5334 5333
-3 6396 5334 6395
-3 6397 6382 5260
-3 6383 6398 4702
-3 6399 6385 6369
-3 6399 6369 6400
-3 6400 6402 6401
-3 6403 6404 6405
-3 6387 6406 6388
-3 6407 6389 4684
-3 6390 6408 4698
-3 6380 6390 4698
-3 6391 6409 6390
-3 6409 6408 6390
-3 6410 6391 6392
-3 6410 6411 6391
-3 6411 6409 6391
-3 6411 6412 6413
-3 6410 6412 6411
-3 6412 6414 6413
-3 6416 6417 6415
-3 6419 6420 6421
-3 6419 6421 6393
-3 6419 6393 5343
-3 6422 5344 6396
-3 5344 5334 6396
-3 1262 6397 5260
-3 6424 6397 1262
-3 6398 6425 4702
-3 6369 6428 6400
-3 6402 6400 6428
-3 6426 6402 6428
-3 6426 6428 6427
-3 6432 6465 6433
-3 6433 6465 6434
-3 6465 6404 6435
-3 6434 6465 6435
-3 6388 6406 6405
-3 5346 6388 6405
-3 4684 6436 6407
-3 6436 4684 6437
-3 6438 6472 2279
-3 6438 2279 6439
-3 6439 2279 5337
-3 6440 6441 6439
-3 6440 6439 5337
-3 5347 5348 6442
-3 5349 6443 5348
-3 5348 6443 6442
-3 6443 5349 5350
-3 6444 6443 5350
-3 4698 6408 5351
-3 6409 6445 6408
-3 6411 6445 6409
-3 6446 6413 6447
-3 6446 6445 6413
-3 6445 6411 6413
-3 6414 6447 6413
-3 6415 6448 6449
-3 6415 5352 6448
-3 6417 6418 6450
-3 6417 6450 5357
-3 6451 5357 6450
-3 6452 6453 6454
-3 6452 6420 6455
-3 6454 6420 6452
-3 6420 6419 6455
-3 6419 6456 6455
-3 5343 6456 6419
-3 5343 6457 6456
-3 6457 6458 6456
-3 6423 5344 6422
-3 6423 6457 5344
-3 6457 5343 5344
-3 6459 6424 1262
-3 6425 6460 4702
-3 6461 6428 5359
-3 5359 6428 5354
-3 6461 5359 6462
-3 6462 5359 6463
-3 6463 5359 6464
-3 5359 6465 6466
-3 6464 5359 6466
-3 6466 6465 6467
-3 6467 6465 6468
-3 6430 6468 6465
-3 6430 6465 6429
-3 6431 6429 6465
-3 6432 6431 6465
-3 6404 6465 6405
-3 6495 6469 4684
-3 6469 6437 4684
-3 2279 6471 6470
-3 6472 6471 2279
-3 6473 6441 6440
-3 5356 6474 6475
-3 6442 5356 5347
-3 6474 5356 6442
-3 5350 6501 6444
-3 6444 6501 6476
-3 6477 6445 6478
-3 6477 6408 6445
-3 6479 6478 6445
-3 6446 6479 6445
-3 6480 6448 5352
-3 6480 5352 6481
-3 6482 5357 6483
-3 6483 5357 6451
-3 5357 6484 5358
-3 6482 6484 5357
-3 6484 6485 5358
-3 6486 6487 6488
-3 6453 6486 6488
-3 6453 6452 6486
-3 6452 6489 6486
-3 6455 6490 6452
-3 6490 6489 6452
-3 6491 6456 6492
-3 6491 6490 6456
-3 6490 6455 6456
-3 6458 6492 6456
-3 6493 6459 1262
-3 6460 6494 4702
-3 6541 6496 6495
-3 4684 6541 6495
-3 4684 5361 6541
-3 2279 6497 6498
-3 6497 2279 6470
-3 6499 6473 6440
-3 4750 5356 6500
-3 6500 5356 6475
-3 6501 6502 6476
-3 4771 5351 6503
-3 6503 5351 6408
-3 6503 6408 6477
-3 5352 5374 6481
-3 6481 5374 6504
-3 6482 6483 6505
-3 6505 6506 6507
-3 6505 6507 6482
-3 6482 6507 6484
-3 6485 6507 4739
-3 6485 6484 6507
-3 6508 6509 6510
-3 6487 6508 6510
-3 6487 6486 6508
-3 6486 6511 6508
-3 6489 6512 6486
-3 6512 6511 6486
-3 6513 6490 6514
-3 6513 6512 6490
-3 6512 6489 6490
-3 6491 6514 6490
-3 6515 6493 1262
-3 6494 6516 4702
-3 6539 6496 6541
-3 6517 6496 6539
-3 6518 2279 6519
-3 2279 6520 6519
-3 6520 2279 6498
-3 6440 6521 6499
-3 5363 5360 6523
-3 6522 5363 6523
-3 4750 6500 6524
-3 6557 6524 6525
-3 4750 6524 6557
-3 4750 6557 6526
-3 4750 6526 6527
-3 4750 6527 6501
-3 6502 6501 6527
-3 6503 6528 4771
-3 5374 6529 6530
-3 6530 6504 5374
-3 4739 6507 6506
-3 4739 6506 6531
-3 6532 6509 6508
-3 6533 6509 6532
-3 6511 6534 6508
-3 6534 6532 6508
-3 6535 6512 6536
-3 6535 6534 6512
-3 6534 6511 6512
-3 6513 6536 6512
-3 6537 6515 1262
-3 1262 6595 6537
-3 4702 6516 4845
-3 6516 6538 4845
-3 6540 6539 6541
-3 6542 6541 5361
-3 6542 5361 6543
-3 6544 5362 6545
-3 5362 6546 6545
-3 5362 6547 6546
-3 6547 2279 6548
-3 6548 2279 6549
-3 6549 2279 6550
-3 2279 6551 6550
-3 6518 6551 2279
-3 6553 6521 5379
-3 5379 6521 6440
-3 5364 5363 6522
-3 5364 6522 6554
-3 6523 6555 6522
-3 6555 6554 6522
-3 5360 6556 6523
-3 6556 6555 6523
-3 5360 5365 6556
-3 6528 6558 4771
-3 5374 6559 6560
-3 6560 6529 5374
-3 6561 5375 6562
-3 6562 5375 4739
-3 6562 4739 6531
-3 6532 6563 6533
-3 6534 6563 6532
-3 6564 6563 6534
-3 6535 6564 6534
-3 6538 6566 4845
-3 4776 6568 5368
-3 6567 6568 4776
-3 6568 6569 5368
-3 5368 6569 6570
-3 6598 5368 6571
-3 5368 6570 6571
-3 6598 6571 6572
-3 6572 6573 6598
-3 5361 6575 6543
-3 3635 6576 5361
-3 5361 6576 6575
-3 5362 6577 3635
-3 6577 6576 3635
-3 6544 6577 5362
-3 5362 2279 6547
-3 5379 6552 6553
-3 5379 6578 6552
-3 5364 6554 6603
-3 6555 6579 6554
-3 6579 6603 6554
-3 6556 6580 6555
-3 6580 6579 6555
-3 5365 5370 6580
-3 6556 5365 6580
-3 5373 6581 6582
-3 6581 5373 6583
-3 6558 5373 4771
-3 6583 5373 6558
-3 5374 6584 6585
-3 6585 6559 5374
-3 5375 6586 6615
-3 6587 5375 6561
-3 6586 5375 6587
-3 6623 6588 5366
-3 6588 6589 5366
-3 6590 6591 5366
-3 6590 5366 6589
-3 6591 6592 6593
-3 6591 6593 5366
-3 5366 6594 5376
-3 5366 6593 6594
-3 5376 6594 5378
-3 6595 6565 6537
-3 6566 6596 4845
-3 4790 6597 6567
-3 6597 6568 6567
-3 6599 6573 6574
-3 6599 6598 6573
-3 6599 6600 6598
-3 5379 6601 6602
-3 5379 6602 6578
-3 6603 6579 6604
-3 6604 6580 6605
-3 6604 6579 6580
-3 5383 5373 6606
-3 6607 6606 5373
-3 5373 6582 6608
-3 6607 5373 6609
-3 6609 5373 6610
-3 6610 5373 6608
-3 6609 6611 5392
-3 6610 6611 6609
-3 6611 6612 5392
-3 5392 5374 5384
-3 5392 6612 5374
-3 6612 6613 5374
-3 6613 6584 5374
-3 6586 6614 6615
-3 6616 6614 6586
-3 6587 6616 6586
-3 6618 6619 5385
-3 5385 6619 6620
-3 6623 5385 6621
-3 6621 5385 6620
-3 6621 6622 6623
-3 6625 6626 6588
-3 6625 6588 6624
-3 6624 6588 6623
-3 6626 6627 6628
-3 6626 6628 6588
-3 6588 6628 6589
-3 6629 6590 6589
-3 6629 6589 6630
-3 6630 6589 6628
-3 6592 6629 6630
-3 6593 6592 6630
-3 6593 6630 5395
-3 5378 6593 5395
-3 6594 6593 5378
-3 6631 6595 1262
-3 6596 6632 4845
-3 6597 4790 6633
-3 4790 6660 6633
-3 6660 6634 6633
-3 6660 6598 6635
-3 6598 6636 6635
-3 6637 6636 6598
-3 6600 6637 6598
-3 5379 6638 6601
-3 6638 5379 6639
-3 6603 6640 6680
-3 6641 6605 6580
-3 6580 5370 6641
-3 5391 6642 6643
-3 5383 6644 5391
-3 5391 6644 6642
-3 6645 6644 5383
-3 6606 6645 5383
-3 6646 6645 6606
-3 6647 6646 6606
-3 6647 6648 6649
-3 6647 6606 6648
-3 6606 6607 6648
-3 6609 6648 6607
-3 5385 6651 6652
-3 6652 6653 5385
-3 6617 6618 5385
-3 6617 5385 6653
-3 6654 6623 6622
-3 6624 6623 6655
-3 6655 6623 6654
-3 6656 6625 6624
-3 6656 6624 6657
-3 6657 6624 6655
-3 6627 6656 6657
-3 6628 6627 6657
-3 6628 6657 5396
-3 6628 5396 5395
-3 6630 6628 5395
-3 1262 6658 6631
-3 6659 4845 6632
-3 6661 6660 6635
-3 6662 6661 6635
-3 6663 6664 6665
-3 6665 6666 6663
-3 5397 6667 6668
-3 5397 6668 6669
-3 6669 6670 5397
-3 6670 6671 5411
-3 6671 6672 5411
-3 5399 5411 6673
-3 5411 6672 6673
-3 6674 5399 6673
-3 6675 6639 5379
-3 5417 5400 6700
-3 6678 6700 5400
-3 6679 6680 6640
-3 6641 6680 6679
-3 6641 5430 6680
-3 6641 5370 5430
-3 4814 6681 6682
-3 4814 6643 6681
-3 4814 5391 6643
-3 6683 6649 6648
-3 6609 5403 6648
-3 6615 6650 5407
-3 5407 6650 6684
-3 6685 6686 5385
-3 6651 5385 6686
-3 5408 6654 6687
-3 6655 6654 5408
-3 5396 6655 5408
-3 6657 6655 5396
-3 6659 6689 4845
-3 6663 6690 6664
-3 6666 6690 6663
-3 5409 6691 6667
-3 6692 5397 6670
-3 5411 5412 6692
-3 5411 6692 6670
-3 5399 6674 5414
-3 6674 6693 5414
-3 6694 6675 5379
-3 6724 6723 6676
-3 6695 6724 6676
-3 6728 6727 6695
-3 6677 6729 6695
-3 6729 6728 6695
-3 6677 5415 6729
-3 5417 6696 6697
-3 5417 6698 6696
-3 6699 6698 5417
-3 6700 6699 5417
-3 5400 6701 6678
-3 5400 6702 6701
-3 5420 4814 6682
-3 6703 5420 6682
-3 6648 6704 6683
-3 5403 6705 6704
-3 5403 6704 6648
-3 5407 6684 6706
-3 5407 6706 5427
-3 6707 5427 6706
-3 5385 6707 6708
-3 5385 6708 6709
-3 6685 5385 6709
-3 5408 6710 6711
-3 6710 5408 6687
-3 6688 6658 6712
-3 6689 6713 4845
-3 6714 5409 6715
-3 6714 6691 5409
-3 6692 6716 5428
-3 5412 6716 6692
-3 5412 6717 6716
-3 5412 5411 6717
-3 6745 6717 5411
-3 6718 6745 5411
-3 6718 5411 6719
-3 6719 5411 5414
-3 6719 5414 6693
-3 5379 6720 6694
-3 6676 6722 6721
-3 6723 6722 6676
-3 6725 6724 6695
-3 6726 6725 6695
-3 6727 6726 6695
-3 6729 5415 6730
-3 5415 5429 6730
-3 6731 5429 6732
-3 6732 5429 5417
-3 6732 5417 6697
-3 5400 6733 6702
-3 5400 6734 6733
-3 6735 5420 6703
-3 5403 6736 6705
-3 5403 5431 6736
-3 5431 6737 6736
-3 5431 6738 6737
-3 5408 6711 6739
-3 6712 6658 6740
-3 6713 6741 4845
-3 6715 5409 6742
-3 5409 4199 6742
-3 5428 6743 4199
-3 4199 6743 6742
-3 6716 6744 5428
-3 6744 6743 5428
-3 6717 6744 6716
-3 5444 6746 6720
-3 6676 6747 4828
-3 6747 6676 6721
-3 6766 6749 6748
-3 5429 6766 6748
-3 5429 6748 6730
-3 6766 5429 6767
-3 6750 5429 6731
-3 6767 5429 6750
-3 5400 6751 6734
-3 5435 6752 6751
-3 5435 6751 5400
-3 6753 5420 6735
-3 6753 6754 5420
-3 5431 6755 6738
-3 6771 6756 6755
-3 5431 6771 6755
-3 6771 5431 6757
-3 6758 6774 5432
-3 5439 6758 5432
-3 6782 6739 6759
-3 6740 6658 6760
-3 6741 6761 4845
-3 6763 6746 5444
-3 4828 6765 6764
-3 4828 6747 6765
-3 5435 6768 6752
-3 6768 5435 6769
-3 5420 6754 5438
-3 6754 6770 5438
-3 6772 6771 6757
-3 5432 6772 6757
-3 6773 6772 5432
-3 6774 6773 5432
-3 5439 6775 6758
-3 6775 5439 6776
-3 5443 6777 6778
-3 5443 6779 6777
-3 6780 6779 5440
-3 6759 6781 6782
-3 6783 6760 4422
-3 4422 6760 6658
-3 6761 6784 4845
-3 5444 6785 6786
-3 6762 5444 6786
-3 6763 5444 6762
-3 5434 4828 6787
-3 6788 4828 6764
-3 6787 4828 6788
-3 6789 6791 5446
-3 6790 6791 6789
-3 5446 6792 5441
-3 6791 6792 5446
-3 6792 6793 5441
-3 4206 5441 6794
-3 5441 6793 6794
-3 4206 6794 6795
-3 6796 4206 6795
-3 5435 6797 6769
-3 5436 6797 5435
-3 6798 5436 6799
-3 6799 5436 5438
-3 6799 5438 6770
-3 6800 6776 5439
-3 6801 5443 6802
-3 6802 5443 6778
-3 5440 6803 6780
-3 5440 6804 6803
-3 6804 5440 6782
-3 4422 6805 6783
-3 6784 6806 4845
-3 6807 6808 6809
-3 6809 6810 6807
-3 5444 6811 6785
-3 6787 6827 5434
-3 6812 6787 6788
-3 6812 6813 6787
-3 6813 6827 6787
-3 6812 6814 6813
-3 5446 6815 6789
-3 6816 4206 6796
-3 5436 6817 6797
-3 6798 6817 5436
-3 5439 6818 6800
-3 6819 6818 5447
-3 5443 6801 5447
-3 5447 6801 6820
-3 6805 4422 6821
-3 6822 4845 6806
-3 6807 6823 6808
-3 6810 6823 6807
-3 5456 6824 6825
-3 6811 5444 5456
-3 6825 6811 5456
-3 6826 6846 6827
-3 6846 5434 6827
-3 6828 6827 6813
-3 6814 6828 6813
-3 6815 5451 6829
-3 6816 6830 4206
-3 5447 6831 6819
-3 6831 5447 6820
-3 5454 5453 6832
-3 6821 4422 6833
-3 6822 6834 4845
-3 6858 6835 6836
-3 6836 6837 6858
-3 6882 6838 6839
-3 6882 6839 6840
-3 6840 6841 5455
-3 5456 6842 6843
-3 5456 6843 6844
-3 6844 6824 5456
-3 5434 6846 6845
-3 5451 6847 6829
-3 6848 6847 5451
-3 6849 4846 6830
-3 6850 4846 6849
-3 5459 6832 6851
-3 5459 5454 6832
-3 6851 6832 6852
-3 5453 5458 6832
-3 6852 6832 5458
-3 5460 5459 6853
-3 5459 6851 6853
-3 5460 6853 6854
-3 6854 6855 5460
-3 6833 4422 6856
-3 6834 6857 4845
-3 6859 6835 6858
-3 6860 6858 6837
-3 6860 6861 6858
-3 6882 6862 6863
-3 6863 6838 6882
-3 6864 5455 6841
-3 6864 6865 5455
-3 5456 6866 6842
-3 5434 6868 6867
-3 5434 6845 6868
-3 5451 6869 6848
-3 6870 4846 6871
-3 6871 4846 6850
-3 6870 5462 4846
-3 6872 6852 5458
-3 5458 5471 6872
-3 5460 6855 5464
-3 6855 6873 5464
-3 5467 5466 6874
-3 5467 6874 5465
-3 6875 6856 4422
-3 6857 6876 4845
-3 6878 6879 5475
-3 6879 6880 5475
-3 6880 6859 5475
-3 6858 5475 6859
-3 6858 5476 5475
-3 6858 5469 5476
-3 5469 6858 6927
-3 6927 6858 6861
-3 6927 6861 6881
-3 6882 6883 6884
-3 6862 6882 6884
-3 6885 5455 6865
-3 6866 5456 6886
-3 5434 6887 4850
-3 5434 6888 6887
-3 6867 6888 5434
-3 6889 6890 5478
-3 5470 6891 6892
-3 5470 6890 6891
-3 5451 6893 6869
-3 6893 5451 5479
-3 6894 6893 5479
-3 6895 6870 6871
-3 6896 6895 6871
-3 6897 6870 6895
-3 5462 6870 6897
-3 5462 6898 4859
-3 5462 6897 6898
-3 5471 6900 6899
-3 5471 6899 6872
-3 5464 6901 5471
-3 6873 6901 5464
-3 5466 5465 6874
-3 4422 6902 6875
-3 6876 6903 4845
-3 5473 5472 6904
-3 5473 6904 5474
-3 5475 6877 6878
-3 5475 5474 6877
-3 5474 6905 6877
-3 5469 6927 5477
-3 6906 6927 6881
-3 6906 6907 6927
-3 6882 6908 6909
-3 6883 6882 6909
-3 4864 6910 6911
-3 6885 6910 4864
-3 6885 4864 5455
-3 5456 6912 6913
-3 6913 6886 5456
-3 6887 6914 4850
-3 6889 5478 6915
-3 6892 6949 5470
-3 6892 6916 6949
-3 5479 6917 6894
-3 6918 5479 6919
-3 6896 5479 6895
-3 6896 6919 5479
-3 5479 6920 6895
-3 6920 6897 6895
-3 5480 6898 6920
-3 6898 6897 6920
-3 4859 6898 5480
-3 5471 6921 6900
-3 6922 6921 5471
-3 6901 6922 5471
-3 6902 4422 6923
-3 6903 6924 4845
-3 5474 6925 6905
-3 5475 6925 5474
-3 6926 6925 5475
-3 5476 5477 6927
-3 6928 6927 6907
-3 6928 6929 6927
-3 6928 6930 6929
-3 4874 6931 6932
-3 6932 6933 4874
-3 6934 6935 6936
-3 6936 6937 6938
-3 6935 6937 6936
-3 6937 6939 6938
-3 6882 6940 6908
-3 6941 6940 6882
-3 6942 6941 6882
-3 6882 6943 6942
-3 4864 6944 6882
-3 6882 6944 6943
-3 6911 6944 4864
-3 6980 6945 6946
-3 6980 6946 6912
-3 6980 6912 5456
-3 6914 6947 4850
-3 6948 6915 5478
-3 5479 6950 6917
-3 6951 6950 5479
-3 6918 6951 5479
-3 6952 6953 6954
-3 6954 6955 6952
-3 4422 6956 6957
-3 4422 6957 6923
-3 6924 6958 4845
-3 6926 6959 6925
-3 6960 6959 6926
-3 5476 6960 6926
-3 6961 6960 5476
-3 6927 6961 5476
-3 6962 6961 6927
-3 6963 6962 6927
-3 6964 6963 6927
-3 6929 6964 6927
-3 6965 6964 6929
-3 6965 6966 6967
-3 6965 6929 6966
-3 6968 6966 6930
-3 6930 6966 6929
-3 6968 6969 6966
-3 6970 6971 6972
-3 6970 6973 6974
-3 6972 6973 6970
-3 6973 6975 6974
-3 5485 6976 6977
-3 6931 4874 6977
-3 6977 4874 5485
-3 6936 6933 6934
-3 6938 6978 6936
-3 6979 6938 6939
-3 6978 6938 6979
-3 4850 6947 6981
-3 5478 6982 6948
-3 6983 6982 5478
-3 6985 6986 6987
-3 6986 6988 6987
-3 6952 6989 6953
-3 6955 6989 6952
-3 4422 6990 6956
-3 6991 4845 6958
-3 6966 6992 6967
-3 6969 6992 6966
-3 6993 6971 6970
-3 6994 6971 6993
-3 6974 6995 6970
-3 6995 6993 6970
-3 6996 6974 6975
-3 6995 6974 6996
-3 5485 6997 6998
-3 5485 6998 6976
-3 6936 5496 6933
-3 5496 6936 6978
-3 6999 6978 6979
-3 5496 6978 6999
-3 7001 4850 6981
-3 7028 4850 7001
-3 7002 7003 7004
-3 7002 7005 7006
-3 7004 7005 7002
-3 7005 7007 7006
-3 7008 7009 5488
-3 6984 5488 7009
-3 6985 5488 6984
-3 6987 5488 6985
-3 5488 7010 7011
-3 5488 6988 7010
-3 5488 6987 6988
-3 6990 4422 7012
-3 6991 7013 4845
-3 5494 7014 7015
-3 7015 7016 5494
-3 7016 7017 5494
-3 7018 7017 7019
-3 7020 6993 7021
-3 7020 7018 6993
-3 6994 6993 7019
-3 7019 6993 7018
-3 6995 7021 6993
-3 7022 7021 6995
-3 6996 7022 6995
-3 7024 7025 5485
-3 7025 6997 5485
-3 7026 5496 6999
-3 7000 4877 7027
-3 7028 7029 4850
-3 7002 7030 7003
-3 7030 7002 7031
-3 7002 7006 7031
-3 7007 7032 7006
-3 7032 7031 7006
-3 5486 7032 7008
-3 7008 7032 7007
-3 5488 5486 7008
-3 5488 7011 5501
-3 5501 7011 7033
-3 7034 7035 7036
-3 7036 7037 7034
-3 7037 7038 7034
-3 7040 7012 4422
-3 7013 7041 4845
-3 5493 7042 7043
-3 5492 7042 5493
-3 7014 5494 7043
-3 7043 5494 5493
-3 5494 7017 5495
-3 5495 7017 7018
-3 7044 7018 7020
-3 5495 7018 7044
-3 5485 7045 7046
-3 7046 7047 5485
-3 7023 5485 7047
-3 7024 5485 7023
-3 7048 5496 7026
-3 4877 7049 7050
-3 7050 7027 4877
-3 4850 7029 7051
-3 7052 7031 5497
-3 7031 7032 5497
-3 7053 5501 7033
-3 7054 7056 7081
-3 7055 7056 7054
-3 7081 7057 5512
-3 7056 7057 7081
-3 7057 7058 5512
-3 7058 7059 5512
-3 7059 7060 5512
-3 7060 7061 5512
-3 5515 7062 7063
-3 5515 7063 7064
-3 5515 7064 7065
-3 5515 7065 7035
-3 7035 7034 5515
-3 7034 7038 7066
-3 7034 7066 5489
-3 7067 7066 7068
-3 7067 5489 7066
-3 5489 7067 5502
-3 7040 4422 7039
-3 4422 7069 7039
-3 7070 4845 7041
-3 7071 7072 5504
-3 7072 5492 5504
-3 7072 7042 5492
-3 5495 7073 5519
-3 7073 5495 7044
-3 5485 7074 7075
-3 7045 5485 7075
-3 5496 7048 4962
-3 4962 7048 7076
-3 7049 4877 7077
-3 7051 7078 4850
-3 7052 5497 7079
-3 7080 5501 7053
-3 7082 7054 7081
-3 5512 5510 7081
-3 5512 7061 7083
-3 5512 7083 5514
-3 5514 7083 7084
-3 5514 7084 7085
-3 5514 7114 5515
-3 7086 7114 5514
-3 7087 7088 5515
-3 7088 7062 5515
-3 7067 7068 7089
-3 7067 7089 5531
-3 7070 7093 4845
-3 5519 7094 7071
-3 5519 7071 5504
-3 7094 5519 7095
-3 5519 7096 7123
-3 5519 7097 7096
-3 5519 7073 7097
-3 7098 7100 5527
-3 7099 7100 7098
-3 5527 7100 5485
-3 7100 7074 5485
-3 4962 7101 7102
-3 7101 4962 7076
-3 7077 4877 7103
-3 7078 7104 4850
-3 5497 5535 7079
-3 7079 5535 7105
-3 7080 7106 5501
-3 5522 7107 7108
-3 4292 7107 5522
-3 5522 7108 7109
-3 5522 7109 7110
-3 7111 5522 7110
-3 5523 7082 7081
-3 7112 7082 5523
-3 7081 5510 5523
-3 5514 7085 7113
-3 7086 5514 7113
-3 7115 5515 7114
-3 7087 5515 7115
-3 7116 5531 7117
-3 7090 5531 7089
-3 7090 7117 5531
-3 4422 7091 7092
-3 4422 7118 7091
-3 7069 4422 7092
-3 7119 4845 7093
-3 7119 7120 4845
-3 7095 5519 7121
-3 5519 7122 7121
-3 7123 7122 5519
-3 7145 7124 5527
-3 7098 5527 7124
-3 7102 7125 4962
-3 4963 7129 7130
-3 7103 4877 4963
-3 7130 7103 4963
-3 4850 7131 7154
-3 4850 7104 7131
-3 7132 7105 5535
-3 5501 7106 5558
-3 7106 7133 5558
-3 7107 4292 7134
-3 5522 7111 7135
-3 5549 7135 7136
-3 5549 5522 7135
-3 5523 7137 7112
-3 7162 7138 7137
-3 5523 7162 7137
-3 5523 5536 7162
-3 7139 7171 5538
-3 7139 5538 7140
-3 7140 5538 5531
-3 5531 7141 7140
-3 7142 7141 5531
-3 7116 7142 5531
-3 7118 4422 7143
-3 7120 7144 4845
-3 7180 7145 5527
-3 7146 7124 7145
-3 4962 7147 7148
-3 7147 4962 7125
-3 7192 7149 7150
-3 7126 7192 7150
-3 7127 7192 7126
-3 7127 5533 7192
-3 5533 7151 5534
-3 5533 7128 7151
-3 5533 7127 7128
-3 7151 7152 5534
-3 7129 4963 7153
-3 7154 7155 4850
-3 5535 7156 7132
-3 7156 5535 7157
-3 7133 7158 5558
-3 7159 7134 4292
-3 5549 7136 7160
-3 5549 7160 7161
-3 5536 7163 7162
-3 7164 7163 5536
-3 7164 5536 4914
-3 7167 7169 7168
-3 7169 5538 7170
-3 7171 7170 5538
-3 5539 7172 7173
-3 7173 7174 5539
-3 5540 5539 7175
-3 5539 7174 7175
-3 7176 5540 7175
-3 4422 7177 7143
-3 7144 7178 4845
-3 5543 7179 7180
-3 7145 7180 7181
-3 7182 7146 7145
-3 7182 7145 7183
-3 7183 7145 7181
-3 7182 7183 7184
-3 7186 5555 4939
-3 7186 4939 7187
-3 7188 7187 4939
-3 7148 7189 4962
-3 7192 7190 7191
-3 7149 7192 7191
-3 5534 7193 5546
-3 5534 7152 7193
-3 5546 7193 5547
-3 7153 4963 7194
-3 4850 7195 7237
-3 4850 7155 7195
-3 5535 7196 7157
-3 7197 7196 5535
-3 7198 5558 7158
-3 7200 7159 4292
-3 7200 4292 7201
-3 5549 7202 7203
-3 5549 7161 7202
-3 7204 7205 5549
-3 7206 5549 7205
-3 7208 7207 7164
-3 4914 7208 7164
-3 7209 7208 4914
-3 4914 5559 7209
-3 5559 7210 7209
-3 7211 7165 7166
-3 7212 7211 7166
-3 7167 7165 7211
-3 7169 7167 7211
-3 7213 7214 7215
-3 7172 7213 7215
-3 7172 5539 7213
-3 5539 7216 7213
-3 5539 5551 7217
-3 5539 7217 7216
-3 7218 7217 5551
-3 7218 5551 5540
-3 7218 5540 7176
-3 7177 4422 7219
-3 7178 7220 4845
-3 7179 5542 7221
-3 5543 5542 7179
-3 7180 7179 7222
-3 7222 7179 7221
-3 7181 7180 7223
-3 7223 7180 7222
-3 5552 7181 7223
-3 7183 7181 5552
-3 5563 7183 5552
-3 7184 7183 5563
-3 5563 7224 7185
-3 5563 7185 7184
-3 5563 7226 7225
-3 7224 5563 7225
-3 5555 7227 7228
-3 7186 7227 5555
-3 7229 7188 4941
-3 7188 4939 4941
-3 7229 4941 7230
-3 7189 7231 4962
-3 7192 7232 7190
-3 7233 7232 7192
-3 7192 5545 7233
-3 5545 7234 7233
-3 5556 7235 5545
-3 5545 7235 7234
-3 7193 7235 5556
-3 5547 7193 5556
-3 7194 4963 7236
-3 7239 7197 4945
-3 7239 4945 7240
-3 7241 7198 7199
-3 7242 7241 7199
-3 7198 7241 5558
-3 4292 7243 7201
-3 5549 7203 7244
-3 7204 5549 7244
-3 5549 7206 7245
-3 7246 5549 7245
-3 5559 7247 7210
-3 5560 7248 7249
-3 5560 7249 5559
-3 5559 7249 7247
-3 7212 7249 7248
-3 7211 7212 7248
-3 7250 7251 7252
-3 7214 7250 7252
-3 7214 7213 7250
-3 7213 7253 7250
-3 7254 7253 7216
-3 7253 7213 7216
-3 7217 7254 7216
-3 7255 7254 7217
-3 7218 7255 7217
-3 4422 7256 7219
-3 7220 7257 5643
-3 5542 5562 7258
-3 5542 7258 7221
-3 7258 7259 7221
-3 7223 7259 5569
-3 7223 7222 7259
-3 7222 7221 7259
-3 7260 7226 4960
-3 4960 7226 5563
-3 7260 4960 7261
-3 7228 4960 5555
-3 7261 4960 7228
-3 4941 5570 7262
-3 7262 7230 4941
-3 7231 7263 4962
-3 7236 4963 7264
-3 7237 7238 4373
-3 7238 7265 4373
-3 7266 7240 4945
-3 7241 7242 7267
-3 7267 5558 7241
-3 7267 7268 5558
-3 4292 5576 7243
-3 7243 5576 7269
-3 4346 7270 7271
-3 4346 7246 7270
-3 4346 5549 7246
-3 7250 7272 7251
-3 7253 7272 7250
-3 7273 7272 7253
-3 7254 7273 7253
-3 7256 4422 7274
-3 5643 7257 7275
-3 7276 5643 7275
-3 7258 7277 7278
-3 7258 5562 7277
-3 5562 5568 7277
-3 5569 7258 7279
-3 5569 7259 7258
-3 7258 7278 7279
-3 5570 4961 7280
-3 5570 7280 7281
-3 5570 7281 7262
-3 4962 7263 7282
-3 7283 4962 7282
-3 7264 4963 7284
-3 4373 7285 7286
-3 7285 4373 7265
-3 7287 7266 4945
-3 7316 7287 4945
-3 7268 7288 5558
-3 7289 7269 5576
-3 4346 7271 7290
-3 7290 5566 4346
-3 7290 7291 5566
-3 7291 5571 5566
-3 4422 7292 7274
-3 7276 7293 5643
-3 7295 7297 7298
-3 7296 7297 7295
-3 7297 7299 7298
-3 5568 7300 7301
-3 5587 7300 5568
-3 7301 7277 5568
-3 5569 7279 7302
-3 4961 7303 7304
-3 7280 4961 7304
-3 4962 7283 7305
-3 7306 4962 7305
-3 7284 4963 7307
-3 7286 7308 4373
-3 7309 7310 7311
-3 7309 7312 7313
-3 7311 7312 7309
-3 7312 7314 7313
-3 7316 4945 7315
-3 5580 5558 7317
-3 7317 5558 7288
-3 5576 7319 7318
-3 5576 7318 7289
-3 7320 5581 7322
-3 7322 5581 7323
-3 7361 5571 7324
-3 5571 7291 7324
-3 7325 7326 7327
-3 7327 7328 7325
-3 7330 7331 7332
-3 7331 7333 7332
-3 4422 7334 7335
-3 7335 7292 4422
-3 7293 7336 5643
-3 5585 7337 7338
-3 7294 5585 7338
-3 7294 7295 5585
-3 7295 7339 5585
-3 7340 7298 7341
-3 7340 7339 7298
-3 7339 7295 7298
-3 7299 7341 7298
-3 5587 7342 7300
-3 7302 7343 7377
-3 4961 7344 7303
-3 7345 4962 7346
-3 7346 4962 7306
-3 7307 4963 7347
-3 7308 7348 4373
-3 7309 7349 7310
-3 7313 7349 7309
-3 7350 7349 7313
-3 7314 7350 7313
-3 7464 7351 7352
-3 7315 4945 7464
-3 7352 7315 7464
-3 5580 7317 7353
-3 5576 7355 7319
-3 5576 7356 7355
-3 5576 7357 7356
-3 7321 5581 7320
-3 7321 7357 5581
-3 7357 5576 5581
-3 5581 7358 7323
-3 5581 7359 7358
-3 7361 7360 5581
-3 7362 7326 7325
-3 7363 7326 7362
-3 7364 7325 7328
-3 7364 7365 7325
-3 7365 7362 7325
-3 7364 7366 7365
-3 7367 7329 7330
-3 7368 7329 7367
-3 7369 7367 7332
-3 7367 7330 7332
-3 7333 7369 7332
-3 7334 4422 7370
-3 7371 5643 7336
-3 5585 5584 7337
-3 5584 7372 7337
-3 5583 5585 7373
-3 7373 5585 7339
-3 7374 7339 7375
-3 7374 7373 7339
-3 7340 7375 7339
-3 7342 5587 7376
-3 7377 7378 7302
-3 7302 7378 5588
-3 7379 7380 4977
-3 7380 7344 4977
-3 5589 7381 7382
-3 5589 7383 7381
-3 5589 7384 7385
-3 5589 7385 7383
-3 7346 7385 7384
-3 7346 7384 7345
-3 7345 7384 7386
-3 7345 7386 5596
-3 7347 4963 7387
-3 7348 7388 4373
-3 7464 7389 7390
-3 7390 7351 7464
-3 5590 7353 7354
-3 5590 7354 7391
-3 5580 7353 5590
-3 5581 7392 7359
-3 7360 7392 5581
-3 7362 7393 7363
-3 7393 5593 7394
-3 7393 7362 5593
-3 7362 7365 5593
-3 5593 7365 7366
-3 5593 7366 7395
-3 5593 7396 5607
-3 5593 7395 7396
-3 7396 7397 5607
-3 7367 7398 7368
-3 7369 7398 7367
-3 4422 7399 7400
-3 7400 7370 4422
-3 7371 7401 5643
-3 5584 7402 7372
-3 7372 7402 7403
-3 5600 5583 7402
-3 7403 7402 5583
-3 7373 7404 5583
-3 7404 7403 5583
-3 7374 7404 7373
-3 5602 7405 7406
-3 5602 7406 7376
-3 5602 7376 5587
-3 5588 7407 7408
-3 5594 5588 7408
-3 7407 5588 7378
-3 4977 7409 7379
-3 7410 7411 7412
-3 7410 5589 7411
-3 7411 5589 7413
-3 5589 7414 7413
-3 5589 7415 7414
-3 7416 5589 7417
-3 7417 5589 7382
-3 5596 7384 5589
-3 7386 7384 5596
-3 7387 4963 7418
-3 7388 7419 4373
-3 7389 7464 7420
-3 5590 7421 7422
-3 7421 5590 7391
-3 5593 7423 7394
-3 5607 7424 7447
-3 5607 7397 7424
-3 7424 7425 7447
-3 7425 7426 7428
-3 7426 7427 7428
-3 7427 7429 7428
-3 7399 4422 7430
-3 7431 5643 7401
-3 5602 7433 7405
-3 5594 7408 7434
-3 7409 7435 7436
-3 7409 4977 7435
-3 4977 5611 7435
-3 7410 7437 7438
-3 7412 7437 7410
-3 5589 7439 7415
-3 7416 7439 5589
-3 4963 7461 7440
-3 4963 7440 7418
-3 7441 4373 7419
-3 7464 7442 7443
-3 7464 7443 7420
-3 5590 7422 7486
-3 7422 7444 7486
-3 5593 7445 7423
-3 7446 7445 5593
-3 5608 7447 7425
-3 5608 7425 7428
-3 7448 7428 7449
-3 7448 5608 7428
-3 7429 7449 7428
-3 4422 7450 7430
-3 5643 7431 7451
-3 7452 5643 7451
-3 7453 7432 7433
-3 7454 7432 7453
-3 5602 5609 7453
-3 7433 5602 7453
-3 5594 7455 5610
-3 7455 5594 7434
-3 5611 7456 7457
-3 7457 7435 5611
-3 7410 7458 7459
-3 7438 7458 7410
-3 7461 4963 7460
-3 7462 4373 7441
-3 7462 7463 4373
-3 7465 7442 7464
-3 7466 7486 7444
-3 5593 5615 7446
-3 7446 5615 7467
-3 7447 7493 5617
-3 7447 5608 7468
-3 7447 7468 7493
-3 7468 5608 7469
-3 7469 5608 7448
-3 7450 4422 7470
-3 7452 7471 5643
-3 7472 7454 7453
-3 7473 7454 7472
-3 5609 7474 7453
-3 7453 7474 7472
-3 5609 7475 7474
-3 5610 7475 5609
-3 5610 7476 7475
-3 5610 7455 7476
-3 7477 7478 5611
-3 5611 7478 7456
-3 7410 7459 7480
-3 7410 7480 5623
-3 4963 7507 7481
-3 4963 7481 7460
-3 7463 7482 4373
-3 7464 7483 7465
-3 7464 7484 7483
-3 4415 7485 7464
-3 7464 7485 7484
-3 7487 7486 7466
-3 7487 7488 7486
-3 7487 7489 7488
-3 5615 7490 7467
-3 5617 7491 7492
-3 7493 7491 5617
-3 7494 7493 7468
-3 7469 7494 7468
-3 7495 7494 7469
-3 4422 7496 7497
-3 7497 7470 4422
-3 5643 7471 7498
-3 7499 5643 7498
-3 7472 7500 7473
-3 7474 7500 7472
-3 7501 7500 7474
-3 7475 7501 7474
-3 5619 7502 7477
-3 7502 7503 7477
-3 7504 7478 7477
-3 7504 7477 7505
-3 7505 7477 7503
-3 7479 7504 7505
-3 7479 7505 5623
-3 7480 7479 5623
-3 7507 4963 7506
-3 4963 5677 7506
-3 7508 4373 7482
-3 4415 7509 7485
-3 4415 7510 7509
-3 4415 7486 7522
-3 7511 7522 7488
-3 7522 7486 7488
-3 7489 7511 7488
-3 5615 7512 7490
-3 5616 7512 5615
-3 7492 5616 5617
-3 7512 5616 7492
-3 7496 4422 7513
-3 5643 7499 7514
-3 7515 5643 7514
-3 7503 7502 5619
-3 5623 7505 7503
-3 7506 5677 7516
-3 4373 7508 7517
-3 7517 7518 4373
-3 7519 7510 4415
-3 7520 7510 7519
-3 7521 7519 7522
-3 7519 4415 7522
-3 4422 7523 7513
-3 5088 7523 4422
-3 7524 5643 7515
-3 5677 7525 7516
-3 7526 4373 7518
-3 7527 7520 7519
-3 7528 7519 7521
-3 7528 7529 7519
-3 7530 7540 5624
-3 5088 7531 7532
-3 7532 7523 5088
-3 7524 7533 5643
-3 5677 7534 7535
-3 5677 7535 7525
-3 4373 7526 7536
-3 7536 7537 4373
-3 5629 7527 7519
-3 5629 5041 7527
-3 5041 7538 7527
-3 5629 7519 7529
-3 5629 7529 7539
-3 5634 7540 7530
-3 7542 5631 5630
-3 7542 7543 5631
-3 7544 5631 7543
-3 5088 7545 7546
-3 7546 7531 5088
-3 5643 7533 7547
-3 7548 5643 7547
-3 5677 7549 7550
-3 7534 5677 7550
-3 7551 4373 7537
-3 5041 5632 7538
-3 7538 5632 7552
-3 5633 7553 7567
-3 5629 7553 5633
-3 5629 7539 7553
-3 7553 7554 7567
-3 5037 7540 5634
-3 5043 7555 7556
-3 7541 7542 5630
-3 7541 5630 7556
-3 7557 5631 7544
-3 5088 7558 7559
-3 7559 7545 5088
-3 5643 7548 7560
-3 7561 5643 7560
-3 5677 7562 7549
-3 4373 7551 7563
-3 7563 7564 4373
-3 5632 7565 7552
-3 7566 7565 5639
-3 5633 7567 5639
-3 5043 5638 7555
-3 7555 5638 7568
-3 5641 7569 7570
-3 5641 7557 7569
-3 5641 5631 7557
-3 5088 7571 7572
-3 7572 7558 5088
-3 5643 7561 7573
-3 7574 5643 7573
-3 5677 7575 7576
-3 5677 7576 7562
-3 7577 4373 7564
-3 5639 7578 7566
-3 7567 7579 5639
-3 7579 7578 5639
-3 7580 5638 7581
-3 7580 7568 5638
-3 5641 7582 7583
-3 5641 7570 7582
-3 5088 7584 7585
-3 7585 7571 5088
-3 5643 7574 7586
-3 7587 5643 7586
-3 5677 7588 7589
-3 7575 5677 7589
-3 4373 7577 7590
-3 7591 7592 7593
-3 7593 7594 7591
-3 5638 5645 7581
-3 7581 5645 7595
-3 5641 7583 7596
-3 7596 7597 5641
-3 5088 7598 7599
-3 7599 7584 5088
-3 5643 7587 7600
-3 7601 5643 7600
-3 5677 7602 7588
-3 4373 7590 7603
-3 7604 7592 7591
-3 7605 7591 7594
-3 7605 7606 7591
-3 7606 7604 7591
-3 7605 7607 7606
-3 7595 5645 7609
-3 7597 7610 5641
-3 5088 7611 7612
-3 7610 7611 5088
-3 7612 7598 5088
-3 5643 7601 7613
-3 7614 5643 7613
-3 5677 7615 7602
-3 4373 7603 7616
-3 7618 7604 7617
-3 7606 7619 7604
-3 7619 7617 7604
-3 7607 7620 7606
-3 7620 7619 7606
-3 7621 7607 7608
-3 7621 7620 7607
-3 7623 7624 5645
-3 7624 7609 5645
-3 5643 7614 7625
-3 5643 7625 7626
-3 5677 7627 7615
-3 7616 7628 7629
-3 7630 7631 7632
-3 7630 7633 7634
-3 7632 7633 7630
-3 7633 7635 7634
-3 5083 5652 7636
-3 5646 5083 7636
-3 5646 7636 7637
-3 7638 5646 7637
-3 7617 7639 7618
-3 7639 7640 7641
-3 7639 7617 7640
-3 7617 7619 7640
-3 7620 7640 7619
-3 7621 5650 7620
-3 5650 7622 7642
-3 5650 7621 7622
-3 7642 7643 5650
-3 5651 5092 7644
-3 7644 7645 5651
-3 5651 7645 7646
-3 5645 5651 7647
-3 5651 7646 7647
-3 7648 5645 7647
-3 7623 5645 7648
-3 5643 7626 7649
-3 5643 7649 7650
-3 7651 5643 7650
-3 5677 7652 7627
-3 7616 7629 7653
-3 7616 7653 7654
-3 7630 7655 7631
-3 7655 7656 7657
-3 7655 7630 7656
-3 7630 7634 7656
-3 7658 7634 7635
-3 7658 7659 7634
-3 7659 7656 7634
-3 7658 7660 7659
-3 7636 5652 7661
-3 5646 7638 7662
-3 5653 5646 7663
-3 5646 7662 7663
-3 7666 5653 7664
-3 5653 7663 7664
-3 7666 7664 7665
-3 7668 7641 7640
-3 7640 5655 7668
-3 5650 7669 5105
-3 5650 7643 7669
-3 7669 7670 5105
-3 5092 7671 7644
-3 5643 7651 7672
-3 7673 5643 7672
-3 5664 7674 7675
-3 5664 7676 7677
-3 7675 7676 5664
-3 7678 7679 7680
-3 5665 7680 7681
-3 5677 7682 7652
-3 4509 7683 7684
-3 4509 7654 7683
-3 4509 7616 7654
-3 7656 7685 7657
-3 7685 7686 7687
-3 7685 7656 7686
-3 7656 7659 7686
-3 5658 7659 7688
-3 5658 7686 7659
-3 7660 7688 7659
-3 7689 5658 7688
-3 5652 5658 7712
-3 5652 7712 7690
-3 5652 7690 7661
-3 5666 7666 7667
-3 5666 7667 7691
-3 7691 7692 5666
-3 5660 7693 7694
-3 7668 5660 7694
-3 5655 5660 7668
-3 5105 7670 7695
-3 5105 7695 5662
-3 5662 7696 7697
-3 5662 7695 7696
-3 7671 5118 7698
-3 5643 7673 7699
-3 7700 5643 7699
-3 5664 5663 7674
-3 5663 7701 7674
-3 7677 7702 5664
-3 5664 7702 5112
-3 7703 5112 7702
-3 5671 7704 7678
-3 7680 5671 7678
-3 5665 7681 7705
-3 7705 7706 5665
-3 5677 7707 7682
-3 4509 7684 7708
-3 7686 7709 7687
-3 5658 7689 7710
-3 5658 7710 7711
-3 7712 5658 7711
-3 5660 5666 7713
-3 5666 7692 7713
-3 7713 7693 5660
-3 5662 7697 7714
-3 7698 5118 7715
-3 5643 7700 7716
-3 5643 7716 7717
-3 7718 5643 7717
-3 5663 7719 7701
-3 5112 7719 5663
-3 7720 7719 5112
-3 5112 7703 7721
-3 5673 5112 7722
-3 5112 7721 7722
-3 5114 7724 7726
-3 7724 7725 7726
-3 7727 5667 7726
-3 5667 5114 7726
-3 7727 7728 5667
-3 7728 5669 5667
-3 7704 5671 5669
-3 7728 7704 5669
-3 7706 7729 5665
-3 5677 7730 7707
-3 4509 7708 7731
-3 4509 7731 7777
-3 7686 7761 7709
-3 7709 7761 7732
-3 5662 7714 7736
-3 7736 7737 5662
-3 7738 7739 5118
-3 7715 5118 7740
-3 7740 5118 7739
-3 5643 7718 7741
-3 5643 7741 7742
-3 7743 5643 7742
-3 5112 7744 7720
-3 5112 7746 7745
-3 5112 7745 7744
-3 5673 7723 7747
-3 5673 7722 7723
-3 7747 7748 5673
-3 7750 7751 5683
-3 7751 7752 5683
-3 7752 7753 5683
-3 7724 5683 7754
-3 5683 7753 7754
-3 5665 7755 7756
-3 7755 5665 7729
-3 5677 7757 7758
-3 7730 5677 7758
-3 7777 7731 7759
-3 7777 7759 7760
-3 7777 7778 7761
-3 5679 5691 7779
-3 5126 7762 7763
-3 5126 7764 7762
-3 7734 5126 7733
-3 7734 7764 5126
-3 7733 5126 5680
-3 7733 5680 7735
-3 7735 5680 7765
-3 5662 7737 7766
-3 5662 7766 5693
-3 7767 5693 7766
-3 5118 7768 7769
-3 7738 5118 7769
-3 5643 7743 7770
-3 5698 5643 7770
-3 7771 5698 7770
-3 5112 5135 7746
-3 5135 5694 7772
-3 5135 7772 7746
-3 5683 5673 7748
-3 7749 5683 7748
-3 7750 5683 7749
-3 5665 7756 5703
-3 7756 7773 5703
-3 5677 7774 7775
-3 5677 7775 7776
-3 7776 7757 5677
-3 7779 7780 5679
-3 5679 7780 5690
-3 5691 7781 7779
-3 5692 7783 7782
-3 5692 7782 5691
-3 5691 7782 7781
-3 7785 7784 5126
-3 7785 5126 7763
-3 7765 5680 7786
-3 5693 7767 7787
-3 5693 7787 7788
-3 5118 5693 7789
-3 7789 5693 7788
-3 7768 5118 7789
-3 5698 7771 7790
-3 5698 7790 7791
-3 7792 5698 7791
-3 7772 5694 5698
-3 5698 7793 7772
-3 5696 7794 7795
-3 5687 7796 5696
-3 5696 7796 7794
-3 7797 7796 5688
-3 5688 7796 5687
-3 5688 5703 7797
-3 7798 5703 7773
-3 5677 7800 7801
-3 7801 7774 5677
-3 7802 5690 7780
-3 7803 7783 5692
-3 7803 7804 7783
-3 7784 7806 5697
-3 7806 7805 5697
-3 7786 5680 7807
-3 5698 7792 7808
-3 7809 5698 7808
-3 7810 7793 5698
-3 7810 5698 7811
-3 7811 7812 7813
-3 7810 7811 7813
-3 7813 7812 7814
-3 5696 7795 5702
-3 7795 7815 5702
-3 5703 7816 7797
-3 5703 7817 7816
-3 7799 5703 7798
-3 7799 7817 5703
-3 7818 7819 5677
-3 7819 7800 5677
-3 5690 7802 7820
-3 7803 5690 7820
-3 7821 7803 7820
-3 7804 7803 7821
-3 7822 7804 7821
-3 7805 7823 5697
-3 7824 7825 5680
-3 7825 7807 5680
-3 5706 5707 7826
-3 5698 7809 7827
-3 5698 7827 7828
-3 7829 5698 7828
-3 7829 7830 5698
-3 7830 7831 5698
-3 7832 5698 7831
-3 7811 5698 7832
-3 7833 7811 7832
-3 7812 7811 7833
-3 7834 7812 7833
-3 7814 7812 7834
-3 5702 7815 7835
-3 5711 5702 7835
-3 7836 5711 7835
-3 5677 7837 7838
-3 7818 5677 7838
-3 7839 4521 7823
-3 4521 5697 7823
-3 5713 7825 7824
-3 5713 7840 7825
-3 7826 5714 5706
-3 5711 7836 7841
-3 5716 7841 7842
-3 5716 5711 7841
-3 5718 7843 5677
-3 7843 7844 5677
-3 7837 5677 7844
-3 4521 7839 7845
-3 4521 7845 7846
-3 4521 7846 7847
-3 4521 7847 7840
-3 5716 7842 7848
-3 5716 7848 7849
-3 7850 7851 5718
-3 7852 5718 7851
-3 7843 5718 7852
-3 5716 7849 7853
-3 5716 7853 5718
-3 5718 7853 7854
-3 7855 5718 7854
-3 5718 7855 7856
-3 5718 7856 7857
-3 5718 7857 7858
-3 5718 7858 7859
-3 7850 5718 7859
-
-CELL_DATA 13733
-POINT_DATA 7860
-NORMALS normals float
--0.133614 -0.057263 -0.989378 -0.0307275 -0.537162 -0.842919 -0.864861 -0.161839 -0.47521
--0.0591288 -0.790848 -0.60915 -0.72247 0.175378 -0.66879 0.236808 -0.629513 -0.740024
-0.197983 -0.368125 -0.908453 0.355323 -0.801092 -0.48166 0.285198 -0.791312 -0.540821
--0.618792 -0.400138 -0.676007 -0.398669 -0.360336 -0.843339 0 -0.0860472 -0.996291
-0.65077 -0.224068 -0.72546 -0.616992 0.576954 -0.535205 0.303636 -0.510558 -0.804448
-0.0991771 0.682572 -0.724058 0.372129 0.614105 -0.695985 -0.490425 0.764772 -0.41786
-0.0313472 0.583987 -0.811158 0.399766 -0.323516 -0.857627 0.216481 0.546615 -0.808918
-0.390625 0.179303 -0.902919 -0.088772 0.773204 -0.627914 -0.161114 0.301929 -0.939618
-0.336389 -0.421911 -0.841922 -0.529158 -0.497371 -0.687469 -0.448965 -0.270927 -0.851486
-0.456537 0.204655 -0.865847 -0.370621 0.853657 -0.365937 -0.188935 0.739997 -0.645529
-0.0329652 -0.212296 -0.976649 -0.149265 -0.468952 -0.870519 0.135512 0.597534 -0.79031
--0.431091 0.395359 -0.811081 -0.313014 -0.35348 -0.881518 0.208532 0.181332 -0.961058
-0.440965 0.440965 -0.781728 0.381019 0.634407 -0.672571 -0.260464 0.83826 -0.479039
-0 0.637398 -0.770535 0.253912 -0.463967 -0.848683 -0.745225 -0.1198 -0.655963
--0.819732 -0.123691 -0.559232 0.351087 -0.152592 -0.923826 0.299891 -0.766145 -0.568407
--0.0578228 -0.708329 -0.70351 -0.298115 -0.407947 -0.862964 0.626218 0.27526 -0.72944
--0.428964 0 -0.903322 -0.840707 0.309226 -0.444512 0.612134 -0.612134 -0.500582
-0.778143 0.124987 -0.615526 0.298546 0.138859 -0.94424 -0.483754 0.68549 -0.544138
-0.150583 0.282344 -0.947421 0.318835 -0.670203 -0.670203 -0.447214 0 -0.894427
--0.557993 -0.557993 -0.614238 -0.350425 -0.313294 -0.882638 0.678742 0.132751 -0.722279
-0.184754 -0.606401 -0.773398 -0.555685 -0.412346 -0.721932 -0.54253 -0.19323 -0.817511
--0.454534 -0.307546 -0.835951 0.309976 0.302415 -0.901366 0.791268 0.485184 -0.372145
--0.601158 0 -0.79913 -0.195297 0.328291 -0.924167 0.561633 0.64151 -0.522527
--0.430992 0.549168 -0.716003 0.450158 -0.054019 -0.891313 -0.0141727 -0.37479 -0.927001
--0.483179 0.180464 -0.856721 -0.327193 0.433721 -0.839542 0.334286 0.754839 -0.564332
-0.671316 0.671909 -0.312846 0.344796 0.158164 -0.925257 0.22389 0.743178 -0.630524
--0.553661 0.562312 -0.614218 -0.166154 -0.166154 -0.972001 -0.0172758 -0.302326 -0.953048
-0.591926 0.484469 -0.644137 -0.687459 0.261533 -0.677496 -0.505059 0.325209 -0.799471
-0.166733 0.45256 -0.876008 0.588363 0.588363 -0.55467 -0.406719 0.382316 -0.829707
-0.473568 -0.163299 -0.865486 0.720113 -0.256824 -0.644577 0.236649 -0.191878 -0.95246
-0.413754 0.227159 -0.881593 -0.417457 -0.790013 -0.449009 0.124878 -0.405854 -0.905366
--0.39225 -0.851721 -0.347435 -0.239402 -0.729666 -0.640527 -0.0931752 -0.0931752 -0.99128
-0.123225 0.432494 -0.893177 -0.249097 -0.886882 -0.389089 0.217978 -0.743821 -0.631836
-0.732431 0.259049 -0.629634 -0.737644 -0.569222 -0.363137 -0.669417 -0.68991 -0.275509
-0.821447 -0.111914 -0.559196 -0.924616 0.233679 -0.300798 -0.731344 -0.200835 -0.651768
--0.487093 0.295284 -0.821917 0.119911 -0.875437 -0.468222 -0.0338245 -0.717313 -0.69593
--0.0261782 0.279234 -0.959866 -0.0250979 0.633721 -0.773154 0.119187 0.815737 -0.566011
-0.879941 0.148971 -0.451122 0.201057 -0.61231 -0.764626 -0.220722 -0.715565 -0.662758
--0.919569 -0.0491032 -0.389849 -0.835811 -0.311849 -0.451853 0.523791 0.363162 -0.770555
-0.492487 -0.363645 -0.790708 -0.236316 -0.379469 -0.894516 0.285703 -0.82894 -0.480866
--0.603185 -0.603185 -0.521857 0.582435 0.465226 -0.666584 -0.634173 0.76534 -0.109907
--0.584343 -0.235207 -0.776673 -0.0678275 -0.131887 -0.988941 -0.269185 -0.72255 -0.636757
--0.634909 -0.317455 -0.704353 0.0535556 -0.444923 -0.893966 0.512611 -0.367788 -0.775862
-0.341278 -0.713496 -0.611925 -0.487268 -0.603938 -0.630736 -0.378509 -0.485634 -0.787966
-0.0320423 0.339926 -0.939906 -0.550019 0.821907 -0.148148 0.0585813 -0.422704 -0.904372
-0.382161 0.543608 -0.747291 0.500733 0.646371 -0.575734 0.0850264 0.786494 -0.611717
--0.159823 -0.820268 -0.549196 0.365676 -0.424613 -0.828242 0.0242708 -0.651266 -0.758462
--0.507728 0.237573 -0.828113 0.60161 -0.6034 -0.523425 -0.809091 0.35261 -0.470147
-0.216092 -0.520584 -0.826012 -0.357151 -0.0957722 -0.929124 -0.846672 0.235721 -0.477055
-0.660332 -0.623161 -0.419085 -0.68403 -0.523612 -0.507872 -0.923242 0.314121 -0.22125
--0.0158154 -0.661987 -0.749348 0.647451 -0.716615 -0.259365 -0.887292 0.0362983 -0.459778
--0.880705 0.414627 -0.229004 -0.880691 0.463666 -0.09694 0.854087 -0.349399 -0.385299
-0.591791 -0.197264 -0.781582 -0.69874 0.685205 -0.205562 -0.644528 0.34271 -0.683472
-0.519893 -0.777214 -0.354472 -0.588419 -0.588419 -0.55455 -0.814164 0.524526 -0.249018
-0.666706 -0.72418 -0.176256 -0.767549 0.610615 -0.194978 0.596127 -0.675259 -0.434347
--0.568865 0.667022 -0.481118 0.468899 -0.549215 -0.691735 -0.673848 -0.595175 -0.43783
--0.37961 -0.541691 -0.749978 0.649603 -0.356158 -0.67169 0.467638 -0.171231 -0.867176
-0.197129 0.824751 -0.530025 -0.315227 0.736623 -0.598347 -0.189691 -0.331959 -0.924024
--0.432596 -0.884943 -0.172444 -0.653129 0.0762328 -0.753399 -0.196901 -0.798542 -0.568824
-0.595899 0.595899 -0.538339 -0.0833766 -0.90672 -0.413409 0.244745 -0.840249 -0.483819
--0.0411872 0.720775 -0.691944 -0.346388 -0.148984 -0.926185 0.262214 -0.510627 -0.818843
--0.32034 -0.0488322 -0.946043 0.0269138 -0.558461 -0.829094 -0.231713 -0.311614 -0.921524
-0.415067 -0.105914 -0.903605 0.113699 0.437303 -0.892098 0.687616 -0.181196 -0.703102
--0.730426 -0.191407 -0.655623 -0.0673477 -0.43776 -0.896566 0.587931 -0.355209 -0.726749
-0.407993 0.710211 -0.573709 0.0627344 -0.643028 -0.763269 -0.716044 -0.492216 -0.494979
--0.625571 -0.657112 -0.420552 -0.125133 -0.871118 -0.474864 -0.513312 0.500792 -0.696935
-0.205739 -0.154691 -0.966303 0.139194 -0.63921 -0.756331 -0.183705 -0.7983 -0.573558
-0.129194 -0.79939 -0.586758 0.395605 -0.699374 -0.595292 0 -0.714057 -0.700088
-0.0821513 -0.670499 -0.737348 0 -0.947723 -0.319096 0 -0.424893 -0.905244
-0.232035 0.261205 -0.93698 -0.26748 0.823524 -0.500263 -0.505771 0.579733 -0.638831
--0.302437 0.55059 -0.778064 -0.0322538 0.628948 -0.776778 0.216548 0.804992 -0.552353
--0.0276135 0.796846 -0.603551 0.0606424 0.818673 -0.571049 0.42076 0.688839 -0.590307
-0.442564 0.636671 -0.631495 0.0703097 0.953021 -0.294631 -0.393632 0.883207 -0.254949
-0 0.842439 -0.538792 0.247275 0.851023 -0.463265 -0.53666 -0.712685 -0.451749
-0.330773 -0.301587 -0.894223 -0.311853 -0.648992 -0.693943 -0.0186271 -0.614693 -0.788546
-0.778019 0.198507 -0.596055 -0.721324 -0.65162 -0.234698 -0.244691 -0.700758 -0.670123
-0.722534 0.148377 -0.675225 -0.94044 -0.111906 -0.321012 -0.414019 -0.785113 -0.460636
-0.578245 -0.302339 -0.757776 0.804844 0.371467 -0.462859 -0.215747 -0.449986 -0.866583
-0.873669 0 -0.486522 -0.796789 -0.150159 -0.585304 0.577632 -0.654494 -0.48783
--0.919215 0.189644 -0.345078 -0.815376 0.574037 -0.0751172 0.94216 -0.314825 -0.114973
--0.526794 0.237428 -0.816159 0.367513 -0.929476 0.0317603 -0.438774 0.371842 -0.818053
-0.647808 -0.0398651 -0.76076 0.204368 -0.978894 -0.000987286 0.26964 -0.955995 -0.115618
-0.631516 -0.66722 -0.394976 -0.501994 0.643066 -0.578332 0.464369 0.337251 -0.818916
-0.953793 -0.124408 -0.2735 -0.151531 0.567922 -0.809013 0.764898 -0.642514 0.0458939
-0.2831 -0.886154 -0.366858 0.607346 -0.764806 0.214946 0.270611 -0.704715 -0.655855
-0.401862 -0.438789 -0.803723 -0.434244 -0.672652 -0.599143 0.726992 -0.275329 -0.629028
-0.592987 -0.393762 -0.702366 -0.474079 -0.574123 -0.667557 -0.503787 -0.440437 -0.743111
--0.457974 -0.673915 -0.57974 -0.588721 0.792639 -0.158528 0.0695623 -0.890398 -0.449836
-0.457902 -0.737537 -0.496352 0.970729 0.0507571 -0.234752 0.707754 -0.540756 -0.454606
--0.697492 -0.656992 -0.286122 -0.725648 -0.563773 -0.394455 0.985733 -0.147733 -0.0806586
--0.550024 -0.829022 -0.100971 0.512143 -0.857839 -0.0426786 0.322015 -0.946725 -0.00429354
--0.522973 -0.852252 0.0129129 -0.649531 -0.759452 0.0366402 0.14246 -0.939007 -0.313002
--0.280881 -0.853879 -0.438175 -0.0711379 -0.995931 0.0553295 -0.548838 0.804265 -0.227891
--0.74702 0 -0.664801 0.0171827 -0.326472 -0.945051 0.410419 -0.679111 -0.608575
--0.364289 0.167455 -0.916107 0.246603 -0.332377 -0.910336 0.451961 -0.335743 -0.826443
-0.144032 -0.882629 -0.44746 -0.38057 -0.225126 -0.896931 -0.575825 0.465475 -0.67213
-0.112 0.0263529 -0.993359 0.281641 -0.345346 -0.895217 -0.652357 -0.588712 -0.477334
--0.0965727 -0.915831 -0.389778 0.660328 -0.660328 -0.357678 -0.279956 0.36428 -0.888214
--0.100151 -0.0166918 -0.994832 -0.887081 -0.100325 -0.450581 0.76069 0.544434 -0.353471
--0.402301 0.504888 -0.763702 -0.349163 0.311494 -0.883774 0.441792 0.834495 -0.329298
--0.559507 -0.808386 -0.182932 -0.138395 -0.827316 -0.544421 -0.631133 -0.746974 -0.209046
--0.173925 -0.780433 -0.600562 0.767655 -0.0383828 -0.639713 -0.453607 -0.685278 -0.569767
-0.551526 -0.14722 -0.821063 0.826474 0.363649 -0.429767 0.8577 0.388891 -0.336325
-0.823711 0.279248 -0.493478 0.333318 -0.754251 -0.565689 0.0406417 -0.746792 -0.663815
-0.015947 -0.534225 -0.845192 -0.520495 0.0208198 -0.853611 0.661244 -0.495308 -0.563406
-0.913519 0.321215 -0.249607 -0.747552 0.00807074 -0.664154 0.461353 -0.53233 -0.709773
-0.292762 -0.56131 -0.774094 0.190724 -0.486347 -0.852696 -0.888497 0.430483 -0.158928
-0.994314 -0.0509905 0.0934825 0.986835 -0.131761 0.0937882 0.90288 -0.379832 0.201332
-0.619007 -0.75584 0.213394 0.869212 -0.160118 -0.467796 0.824087 -0.222516 -0.52093
-0.60237 0.798086 -0.0144975 -0.0559393 -0.964954 -0.256389 -0.379812 0.634713 -0.672965
-0.648721 -0.131186 -0.749634 0.977478 -0.153099 0.145248 -0.681476 -0.526052 -0.508782
-0.253505 -0.869394 -0.424134 -0.295363 0.210974 -0.9318 0.771082 -0.571005 0.281756
--0.520388 -0.81452 -0.256423 -0.932492 -0.332476 0.141129 -0.387589 0.66745 -0.635834
-0.72924 0.447094 -0.517992 0.490614 0.598931 -0.632913 0.554927 0.541393 -0.631625
--0.0398377 -0.632976 0.773146 0.833643 0.0106877 0.5522 0.277725 -0.55545 -0.783801
--0.428552 -0.68747 0.586284 0.232916 -0.842788 -0.485241 -0.207499 -0.735837 -0.644584
--0.128406 -0.342416 -0.930733 -0.160642 0.973546 -0.162488 -0.986898 0.0986898 0.127639
-0.451855 -0.636122 -0.62544 0.64379 0.539243 -0.542911 0.593303 0.25522 -0.763449
-0.234245 -0.669273 -0.705126 0.35794 0.188615 -0.914496 -0.643042 0.270755 -0.716372
-0.521396 -0.109909 -0.846207 0.91988 -0.041365 -0.390013 -0.946342 0.288601 -0.145419
-0.72821 0.682613 -0.0612429 -0.346952 -0.919119 -0.186664 0.0326775 -0.980326 -0.19466
-0.297089 -0.871314 -0.390576 0 -0.849343 -0.527841 0.0658001 -0.870586 -0.487596
-0.74046 0.64113 -0.20167 -0.540906 0.801701 -0.254355 0.833497 -0.00766434 -0.552471
-0.72087 -0.493227 -0.486903 -0.912475 -0.382435 0.14537 0.254155 -0.914959 -0.313458
--0.66355 -0.737278 0.126976 -0.327662 0.703275 -0.630905 -0.471757 -0.36856 -0.801005
-0.245787 -0.825896 -0.50743 -0.79949 0.588196 -0.121827 -0.554541 -0.831811 0.0239616
--0.0360758 0.742401 -0.668984 -0.522275 0.838219 0.156897 0.317629 -0.923394 0.215534
-0.290532 0.576195 -0.763931 -0.77193 0.604489 -0.196766 -0.130676 -0.659232 -0.740498
--0.459006 -0.442006 -0.770677 -0.374676 -0.769072 -0.517827 -0.376284 0.430038 -0.820657
-0.222776 -0.879965 -0.419562 -0.48734 0.46584 -0.738575 -0.249152 -0.738395 -0.626654
--0.706638 0.0936891 -0.701345 -0.382983 0.718093 -0.581091 0.0830439 -0.110725 -0.990376
-0.260005 -0.913991 -0.311476 0 0.999101 0.0423861 0.444728 -0.690636 -0.570298
-0.0428856 0.950631 -0.307347 0.815639 0.577103 0.0410385 0.942857 0.171429 0.285714
--0.728315 0.662105 0.176561 -0.722965 -0.690103 -0.032862 -0.910416 0.0343553 -0.412264
--0.128238 0.881635 -0.454175 -0.186605 0.92473 -0.331742 -0.486271 0.75559 -0.43889
--0.746592 0.409132 -0.524605 -0.67561 -0.275249 -0.683951 0.959044 0.280696 0.0380109
--0.551393 0.600772 -0.578826 0.682383 0.720548 -0.123144 -0.129602 -0.931015 -0.341196
-0.899206 0.0372805 -0.435934 -0.865383 -0.397797 -0.304745 0.355155 -0.856956 -0.373486
--0.121418 -0.689481 -0.714054 0.723358 -0.632815 -0.276221 -0.226561 -0.696637 -0.680711
-0.511263 -0.723072 -0.464519 -0.911951 -0.130058 -0.38914 0.937919 -0.290078 -0.190162
-0.760164 0.550687 -0.344809 0.766852 0.546222 -0.337015 0.934208 -0.3242 -0.148829
--0.982977 0.174299 -0.0580998 0.177826 -0.98367 -0.0277619 -0.728453 -0.67903 0.0909671
-0.778298 -0.598196 -0.190822 0.504274 0.784427 -0.361085 0.313858 -0.859187 -0.404092
-0.818402 -0.572881 -0.0450121 0.902922 0.409137 -0.131676 -0.0824148 0.970663 -0.225878
-0.26844 -0.96313 -0.017896 0.954296 0.149554 -0.258752 0.698362 -0.101079 -0.708572
--0.990127 -0.0735905 0.119306 -0.519702 0.814759 0.257057 -0.661742 0.672771 0.330871
--0.106395 -0.984152 0.14186 0.586209 0.768585 -0.256195 -0.0510752 -0.752508 -0.6566
-0.534006 -0.738057 -0.412444 -0.746554 0.590949 -0.305673 0.951414 0.0126434 0.307655
--0.405861 -0.900274 0.157425 0.402726 -0.836431 0.371747 -0.48941 -0.870062 0.0589104
-0.786062 -0.550243 -0.281672 0.894147 0.108601 0.434404 0.931719 -0.0291162 0.362012
--0.46618 -0.884546 -0.0159378 -0.294639 -0.837308 -0.460547 -0.0271759 0.570694 -0.820713
--0.646277 0.656016 -0.389832 0.838007 0.164315 0.520331 -0.451493 -0.799787 0.395594
--0.694515 -0.0292427 -0.718884 0.0571292 0.956915 -0.284694 0.463583 -0.86278 0.201745
--0.527545 -0.83658 0.147754 -0.53086 -0.812675 0.240307 0.703842 0.703842 0.0959785
-0.14104 0.967135 -0.211561 -0.0949207 -0.976327 -0.194361 0.902432 -0.258894 -0.344371
--0.166339 -0.970311 0.17558 -0.960289 0.0561572 -0.273299 0.431889 -0.431889 -0.791797
-0.629445 0.769322 0.109279 -0.972387 -0.233373 0 -0.707308 0.579529 -0.404799
-0.575168 -0.692435 -0.435564 -0.722346 0.685303 -0.0926085 0.403399 0.576284 0.71075
--0.838388 0.540438 0.0709405 0.618425 -0.531767 -0.578597 0.666068 -0.609667 -0.429721
--0.591621 0.591621 -0.547694 -0.571101 0.598297 -0.562036 -0.522678 0.709348 -0.472899
-0.248187 -0.849265 0.465997 0.749401 0.343811 -0.565856 0.327269 0.139263 -0.934613
-0.470209 -0.798609 -0.37567 -0.448116 0.426572 0.785639 -0.355483 -0.891999 0.27923
--0.816525 -0.199965 -0.541573 0.626849 -0.690813 -0.360331 0.932835 0.339604 0.120366
-0.750775 0.459982 -0.474081 -0.84453 0.341834 -0.412211 0.573251 -0.473762 -0.66853
-0.278974 -0.852913 -0.441264 0.0873541 -0.762893 -0.640597 -0.983169 0.172055 0.0614481
--0.602585 -0.71815 0.348069 -0.297116 0.847331 -0.440172 0.303829 0.717405 -0.626911
-0.653544 -0.308205 -0.691296 -0.201612 -0.632644 -0.74774 -0.279857 0.612659 -0.739141
--0.068935 -0.0771416 -0.994634 0.33931 -0.819482 -0.461863 -0.883753 -0.45613 0.10453
--0.254414 0.166439 0.952666 -0.249208 0.320836 -0.913761 -0.207199 0.148716 -0.966929
-0.304056 -0.33407 -0.892159 -0.170821 0.134216 -0.976118 0 -0.311641 -0.9502
-0.694672 -0.709144 0.120603 0.859581 -0.509036 -0.0447504 -0.781435 0.407462 0.472582
--0.647169 -0.392224 0.653706 -0.886995 0.0490504 0.459166 -0.497468 0.297268 -0.814958
-0.0882852 0.0294284 -0.99566 -0.269897 -0.304247 -0.913559 -0.719314 0.401156 -0.567152
--0.133211 -0.793344 -0.594021 0.102573 -0.981767 -0.160036 -0.479456 0.76713 -0.426184
-0.53753 0.808457 0.239703 -0.402972 0.914818 0.0268648 0.917997 -0.396562 0.00452816
-0.980883 0.0779716 0.178295 0.883936 0.441968 0.152713 -0.716192 -0.695922 -0.0525508
--0.0555452 0.864653 -0.499289 -0.243071 0.729213 -0.63966 0.952863 -0.276809 0.124209
--0.211241 -0.977383 -0.00998402 -0.540551 0.390592 -0.745146 -0.458135 0.823741 -0.33401
-0.369622 -0.870401 -0.325241 -0.146564 -0.840301 -0.521931 0.72583 -0.672963 -0.142449
--0.29592 -0.883917 -0.362107 0.647963 -0.416547 -0.637678 -0.149366 -0.852922 -0.500214
--0.746148 -0.662663 -0.0643531 0.855179 -0.117505 -0.504838 0.794308 0.21938 -0.566522
-0.239602 0.339436 -0.909601 -0.318953 0.134296 -0.938208 0.472654 -0.759727 -0.446557
-0.496001 -0.807052 -0.320392 0.576018 -0.62402 -0.528017 -0.116539 0.773139 -0.623438
-0.71045 0.333298 -0.619817 -0.105028 -0.992996 0.0541056 0.693252 -0.683712 -0.227904
--0.66256 -0.603026 0.444267 -0.0633257 -0.909588 0.410658 0.278523 -0.960424 -0.00320141
-0.329474 -0.929344 0.166631 0.23583 -0.946032 0.222277 0.17609 0.440225 0.880451
--0.741536 -0.670913 0 -0.757684 -0.651961 0.0293676 0.915488 -0.0938963 -0.391234
-0.0657912 -0.997833 0 -0.0423798 0.720457 -0.692204 0.548646 0.759664 -0.349139
--0.393073 -0.917171 -0.0655122 0.721223 0.523468 -0.453672 0.517381 0.776071 -0.360599
--0.928473 -0.295423 -0.225084 0.710282 -0.701925 -0.0529229 0.698377 0.704904 -0.124011
--0.95902 -0.139857 -0.246415 0.898349 -0.431207 -0.0838459 -0.724146 0.599293 0.341264
-0.740475 -0.598136 -0.306481 -0.762629 -0.635902 -0.11843 0.104777 -0.681047 -0.724704
-0.638241 -0.769309 0.0284929 0.994249 -0.0887288 0.0599629 0.17609 -0.968496 0.17609
-0.513226 -0.856379 -0.0566906 0.296071 0.911897 0.284228 -0.735612 0.559065 0.382518
--0.730931 0.608526 0.308926 0.89569 -0.432749 0.102317 0.124686 -0.992063 -0.0162633
--0.417759 -0.908461 -0.0132622 0.323677 -0.921233 -0.215784 -0.965722 -0.259028 0.0168931
--0.982888 -0.182016 -0.0283136 0.299775 0.930552 -0.210259 0.301131 0 0.953583
-0.976112 0.208611 -0.0607151 -0.890387 0.0460545 0.452869 0.813767 0.48358 0.322387
-0.839341 0.453698 0.299441 0.0112225 0.864131 0.503141 -0.860695 0.43913 0.257623
-0.01133 -0.940393 -0.339901 0.361886 -0.882096 -0.301571 -0.283706 -0.831774 -0.477141
-0.753653 -0.0519761 -0.655214 0.558975 -0.264243 -0.785953 0.586881 -0.8031 -0.102962
--0.895676 0.422393 0.139101 0.200534 -0.968295 0.148968 0.755142 -0.655406 0.014248
--0.409691 -0.872821 0.265211 -0.722956 0.690464 -0.0243693 -0.790186 0.603615 0.10609
--0.369077 0.918116 0.144377 -0.19593 0.979651 -0.04354 -0.218537 0.967805 0.124878
--0.13994 0.965583 0.219239 -0.102463 0.973399 0.204926 -0.297193 0.934035 0.198129
--0.522716 -0.678668 -0.515924 0.578153 -0.140245 -0.803785 -0.691431 0.718024 0.0797805
-0.435884 -0.89158 -0.12284 -0.606334 -0.785479 -0.124023 0.730789 0.501956 0.462587
-0.829482 0.47399 0.295454 0.692996 0.679921 0.239716 0 0.462566 0.886585
-0.186443 0.865288 0.465312 0.908919 -0.398649 -0.122252 -0.651332 0.195812 0.733092
-0.0958325 0.972015 0.214482 0.576707 0.527885 0.623495 -0.783524 0.547223 0.29434
--0.713561 0.5622 0.418046 -0.813596 0.355572 0.460033 -0.637132 -0.58963 -0.496385
-0.252222 0.252222 -0.934221 0.71509 0.659113 -0.232844 0.250099 -0.701892 -0.666932
-0.830773 0.288001 0.47631 0.196129 0.442546 0.875035 -0.926488 0.188352 0.325798
-0.654477 -0.711388 -0.2561 -0.433262 -0.753876 0.493919 0.660852 -0.189307 0.726249
--0.48085 -0.824314 0.298814 0.983296 -0.150169 -0.102855 0.520532 -0.753605 -0.401405
--0.491369 -0.728328 -0.477592 0.358962 0.243277 -0.90109 0.689078 0.689078 -0.224374
--0.717496 0.573997 -0.394623 0.264013 0.940669 -0.213166 -0.529192 0.797988 0.288395
--0.261115 -0.821228 0.507349 -0.680331 -0.684186 0.262753 -0.218519 -0.963269 -0.156085
-0.652871 -0.748414 0.116774 0.203874 -0.974064 -0.0981614 0.205266 -0.173687 0.963171
--0.171388 0.0507816 0.983894 -0.350738 -0.85736 0.376719 -0.855798 -0.474442 0.206192
--0.475789 -0.836182 0.272809 -0.135139 0.844618 0.518032 0.84978 0.186952 0.492872
--0.486418 0.856759 0.171352 0.307937 -0.865918 -0.394159 -0.438607 -0.758597 -0.481824
-0.659006 0.110713 -0.743945 0.69225 0.686197 -0.223436 0.231633 -0.146029 0.96178
-0.539235 0.550958 0.636923 -0.383801 -0.733736 0.56065 0.893078 -0.435089 -0.114497
-0.506432 -0.350607 0.787783 -0.604419 0.36457 0.708354 -0.873243 -0.169356 0.456909
-0.688789 -0.439653 0.576433 -0.885817 0.117133 0.449009 0 -0.999061 0.0433356
-0.871587 0.0901642 -0.481878 -0.511752 -0.0261691 -0.858735 -0.53265 -0.764754 -0.362539
--0.489831 -0.473503 -0.732025 0.450223 0.452841 -0.769568 0.769039 0.607173 -0.199799
--0.378939 0.801186 -0.463148 -0.718397 -0.689075 0.0952976 0.184114 0.97763 0.101694
--0.382269 0.888214 0.254846 0.867466 -0.485462 -0.108765 -0.560007 -0.222072 0.798171
--0.913832 -0.290254 0.284012 0.560901 -0.780385 0.276386 -0.368434 -0.846421 -0.384483
--0.38097 -0.881165 -0.280018 -0.210366 -0.839178 -0.501525 0.0851775 -0.00967926 -0.996319
-0.52573 0.738864 -0.421531 0.541798 0.823036 -0.170489 -0.601124 0.743495 -0.293029
-0.0634667 0.335467 -0.939912 -0.164716 -0.973322 -0.159725 0.874235 0.298474 0.382919
-0.975442 0.177995 0.129729 -0.932739 -0.328536 0.148533 -0.310257 -0.810372 -0.497028
-0.620221 0.334651 -0.709461 0.587911 0.732468 -0.343294 -0.74274 0.275875 -0.610107
-0.239939 0.945067 0.221985 -0.192387 0.902738 0.384774 0.908868 -0.0873912 -0.407825
--0.9459 0.169696 0.276542 -0.940466 0.175983 0.290781 0.36958 -0.90952 -0.19022
--0.460918 -0.800411 -0.383272 0.572474 0.677593 -0.461672 0.223733 -0.968343 0.110701
--0.216985 0.278012 0.935749 0.791297 0.238404 0.563038 0.79788 -0.555363 -0.234433
-0.0708869 -0.992416 0.100423 -0.555622 -0.807224 0.199185 -0.868642 -0.414275 0.271729
-0.142525 -0.891428 -0.430166 -0.668659 0.260825 -0.696323 -0.486004 0.602064 -0.633497
-0.123554 0.809965 -0.573316 0.22312 -0.80881 0.5441 0.509371 -0.709386 0.487147
--0.85552 -0.392807 0.337326 0.128324 -0.991598 0.0163322 0.04847 0.981518 0.185129
--0.160852 0.97798 0.132971 -0.783356 -0.0257743 -0.621039 0.396049 -0.203525 -0.895389
-0.800749 -0.0250234 -0.598477 0.197399 0.540055 -0.818153 -0.0079445 0.897728 -0.440478
-0.373377 0.886251 -0.274134 0.141833 -0.921916 0.360493 -0.929152 0.349305 -0.121092
--0.978305 0.142402 -0.150472 0.148585 0.728276 -0.668982 0.644562 0.528742 -0.552242
-0.41021 0.876547 -0.251779 0.329187 -0.938472 -0.104435 -0.419297 -0.898714 -0.128461
--0.403814 0.779454 -0.478942 -0.155245 0.851859 -0.500235 -0.654974 0.664606 -0.359594
-0.623948 -0.263531 -0.73569 -0.91542 -0.191728 -0.353903 0.556984 -0.718688 -0.41624
--0.299696 -0.775301 -0.555958 0.0263015 -0.836387 -0.547509 0.329968 -0.532663 -0.779353
--0.871129 -0.454099 -0.186891 0.610586 0.732157 -0.301878 0.682646 0.626428 -0.376273
-0.656219 0.686047 -0.31419 -0.702782 -0.649801 -0.289579 0.909282 -0.357218 -0.213544
--0.956792 0.278167 -0.0846846 0.741177 -0.626202 -0.241926 0.680638 -0.686146 -0.25678
-0.558265 -0.197035 -0.805927 -0.586108 -0.0572744 -0.808206 0.867414 0 -0.497587
-0.522385 -0.700066 -0.486848 0.374142 0.363513 -0.853157 0.431889 -0.431889 -0.791797
-0.831385 -0.356979 -0.42587 0.766349 0.569701 -0.2969 -0.78086 -0.496911 -0.378599
--0.0498854 -0.997708 -0.0457283 0.898977 -0.433004 -0.0659396 0.886174 -0.43135 -0.169214
--0.19776 -0.939362 -0.280161 -0.457524 0.481138 -0.747782 0.475591 -0.744403 -0.468698
-0.0990088 -0.964033 -0.246653 -0.601644 0.595687 0.532147 0.683818 0.683818 0.254532
--0.524195 0.725137 0.446537 -0.752249 -0.451349 -0.480006 0.15757 -0.601632 -0.783077
-0.290014 -0.913545 -0.285181 0.220903 -0.965483 -0.138 -0.794953 -0.539432 0.277603
--0.326052 -0.846725 -0.420413 0.903413 -0.171776 -0.392858 0.338093 0.899623 -0.276355
--0.34795 -0.394343 -0.850544 -0.548044 -0.631898 -0.548044 -0.724555 -0.169577 -0.66803
--0.0188745 -0.968891 -0.246767 -0.64358 -0.64358 -0.414258 0.356294 -0.456056 -0.815517
--0.648772 -0.689441 -0.322127 -0.465801 -0.237753 -0.852351 0.741325 0.585257 -0.328499
--0.779814 -0.582047 -0.23046 0.928625 0.19967 -0.312711 0.874323 -0.483668 -0.0403057
--0.0607823 -0.850952 -0.521715 -0.118168 -0.948487 -0.293953 -0.308258 -0.703795 -0.640039
-0.753462 0.453637 -0.475929 0.0160721 -0.962033 -0.272461 -0.830418 0.553612 -0.0626109
-0.968504 -0.141732 0.204724 0.79849 -0.598867 0.0614223 0 -0.848336 -0.529458
--0.82896 -0.524195 -0.195049 0.844479 0.52011 -0.12783 0.767202 -0.627521 -0.132732
--0.353643 0.640381 -0.681798 0.25207 -0.930719 -0.264996 0.305425 -0.916274 -0.259148
--0.384486 0.90221 0.195415 0.822951 0.565779 -0.0514344 -0.152098 -0.221233 -0.963287
--0.354471 -0.16953 -0.91957 -0.196067 0.980334 -0.0224076 0.133009 0.975401 -0.17579
-0.542551 -0.613318 -0.574003 0.0839211 -0.917138 -0.389634 0.710839 0.690135 0.135727
-0.732502 -0.138581 -0.666511 0.629762 0.414389 -0.657025 0.528107 0.55369 -0.64384
--0.491848 0.86233 -0.1203 0.379547 0.919673 -0.100726 -0.167817 0.976388 0.136033
-0.431277 -0.782524 -0.449062 -0.662868 -0.224902 -0.714161 0.22194 0.887761 -0.403264
-0.0235352 0.0823732 -0.996324 0.420952 -0.762634 -0.491111 -0.752994 0.648856 -0.109478
--0.92798 0.107075 0.356915 -0.701876 0.694926 -0.156358 -0.392322 0.603572 0.694107
--0.618742 -0.563607 0.547271 0.184252 0.982043 -0.0405227 -0.792281 0.313923 0.523205
-0.519907 0.854133 -0.0123787 -0.790345 -0.451626 0.41399 0.994274 0.0994274 0.0391684
-0.758853 -0.649703 -0.0450461 -0.771996 -0.571631 -0.277958 -0.395817 -0.918132 0.0190427
-0.108157 -0.973417 0.201894 0.375903 -0.884477 -0.276399 0.468316 -0.81339 -0.345075
-0.460938 0.784575 -0.414704 0.570948 0.741135 -0.353183 -0.572372 -0.803757 -0.162375
-0.662022 -0.165505 0.730982 0.820325 -0.392329 -0.416107 0.185374 0.98164 -0.0449392
--0.345809 0.912937 -0.216707 -0.95324 -0.300571 -0.0314884 -0.947779 -0.31749 -0.0302372
--0.0734306 -0.996558 0.0384637 -0.888005 -0.186481 -0.420323 -0.38819 -0.916742 0.094306
-0.549025 0.695432 0.463622 0.676753 -0.728811 0.104116 -0.717518 0.391374 0.576189
-0.585463 -0.712237 -0.387236 0.335432 0.934417 -0.119797 -0.371232 0.877457 0.303735
--0.662085 0.0827606 0.744845 0.848308 0.0614716 -0.525923 0.905197 -0.201155 -0.374372
--0.596285 -0.745356 0.298142 0.286282 -0.866402 -0.409134 0.135725 -0.841956 -0.522197
--0.616898 -0.663344 -0.423571 0.533046 -0.78434 -0.31729 0.637231 0.756711 -0.146032
--0.991192 0.052168 0.121725 0.384619 -0.915758 -0.115996 0.311161 -0.889033 -0.335857
--0.926151 -0.139271 -0.350498 0.98582 -0.167403 0.0116252 -0.938026 -0.343943 -0.0425586
--0.748222 -0.407409 0.523625 -0.670201 0.736762 0.0895131 0.75071 0.619153 0.230399
-0.48915 0.850043 -0.195342 0.504961 0.844554 -0.178164 -0.536778 0.782554 -0.315402
-0.688318 0.51766 -0.508179 0.294609 -0.922464 -0.249532 0.864722 0.502097 -0.0123975
-0.605492 0.749313 -0.268159 0.839586 0.529429 0.121658 0.217879 0.917911 -0.331615
-0.757777 0.277496 0.590568 0.864994 0.445953 0.230024 -0.388816 0.772288 -0.502388
-0.65577 0.733198 -0.179964 -0.415453 -0.127365 -0.900654 -0.314221 -0.287478 -0.904777
--0.449256 0.256718 -0.855725 0.106878 -0.299781 -0.948002 -0.267316 0.169883 -0.948515
-0.305573 -0.672644 -0.673925 -0.328982 -0.769959 -0.546749 -0.948924 -0.141738 -0.281875
-0.817136 -0.548751 -0.176527 -0.677952 -0.623459 -0.389462 0.685388 -0.292848 -0.666696
-0.838632 -0.00618156 -0.544664 0.843287 -0.130996 -0.521255 -0.204589 -0.7573 -0.620193
-0.357737 -0.829122 -0.429628 -0.638917 -0.610451 -0.468118 0.469127 0.69267 -0.547839
--0.268075 0.842522 -0.467217 -0.550732 -0.483631 -0.680291 0.826703 0.40761 -0.387836
-0.907922 -0.344613 -0.238578 0.0448372 -0.941581 -0.333788 -0.486454 -0.758296 -0.433993
-0.394619 -0.841407 -0.369202 -0.664798 -0.47826 -0.573857 0.276694 -0.122975 -0.953057
--0.883592 0.465557 -0.0502072 0.462115 -0.777194 -0.427106 0.603159 -0.356707 -0.713414
-0.820164 0.340068 -0.460092 0.952035 0.0115749 -0.30577 -0.0800304 0.98323 -0.163872
--0.814202 0.576286 0.0704937 0.282028 -0.568795 -0.772614 0.903205 0.418662 -0.0945708
-0.376086 0.621111 -0.687591 -0.637916 0.0609773 -0.767688 -0.57735 -0.57735 -0.57735
-0.276421 -0.900183 -0.336545 0.35853 -0.90913 -0.211988 0.30702 0.846952 -0.434063
--0.452599 -0.243188 -0.857912 -0.765682 -0.566025 -0.305526 0.66924 0.547077 -0.502816
--0.0733032 0.704525 -0.705883 -0.897898 -0.242961 -0.367082 0.770579 -0.597782 -0.221055
--0.311776 0.770271 -0.556307 0.541317 -0.589939 -0.599123 -0.485384 -0.654705 -0.579451
-0.467348 -0.233674 -0.852632 0.344958 0.936315 -0.0657063 0.905647 -0.416108 0.0815898
-0.204546 -0.920458 -0.333043 0.828805 -0.214514 -0.516784 0.493847 0.823079 -0.280457
-0.417315 -0.602789 -0.680069 -0.715093 -0.666336 -0.211277 -0.486664 -0.811107 -0.324443
--0.668648 -0.728751 -0.147754 -0.98481 -0.171271 -0.0285452 -0.583193 -0.770648 -0.256883
-0.724062 0.395093 -0.565363 0.431021 0.636194 -0.639905 0.453626 0.583736 -0.673406
-0.38199 -0.273335 -0.88282 -0.114376 0.564731 -0.817311 -0.620628 0.639645 -0.453514
--0.457017 0.888877 0.0321449 0.87115 0.195564 0.450391 -0.912988 0.300749 0.275687
-0.633054 -0.296257 -0.715174 0.571811 -0.62993 -0.525567 0 0.0634628 -0.997984
-0.649847 -0.361026 -0.668849 -0.781651 0.586238 -0.21295 -0.783687 0.391844 -0.481968
--0.898908 -0.437864 0.015454 0.714292 0.479267 -0.509989 -0.399538 -0.762754 -0.508503
--0.814241 -0.425626 -0.394784 0.3771 -0.627326 -0.681365 0.646204 -0.427328 -0.632307
--0.779839 -0.241456 -0.577538 -0.0748111 -0.654597 -0.752267 -0.176038 0.909527 -0.376525
-0.331348 0.649953 -0.683937 -0.0898383 -0.235826 -0.967634 -0.468896 -0.805914 -0.36144
-0.5891 0.0632205 -0.805583 -0.956807 -0.264417 -0.12085 -0.651873 0.641186 -0.404897
-0.00783244 -0.871638 -0.490087 0.156549 -0.834926 -0.527627 0.416594 -0.505777 -0.755407
--0.199523 -0.737045 -0.645721 0.278518 0.875341 -0.39523 -0.415601 0.373479 -0.82933
-0.857881 0.0504636 -0.511364 -0.19959 -0.471758 -0.858841 -0.0649442 -0.828039 -0.556897
-0.140919 -0.79407 -0.591265 0.517987 -0.426577 -0.741432 -0.527934 0 -0.849285
-0.901637 0.324026 -0.286458 -0.339653 -0.915176 -0.217 0.984734 -0.0364716 -0.170201
-0.885734 -0.207594 -0.415188 -0.858898 0.458079 0.229039 0.803824 -0.506112 -0.312598
--0.27654 -0.72098 -0.635384 0.0623288 -0.849938 -0.523184 -0.166814 -0.925299 -0.34058
-0.292642 -0.899488 -0.324473 -0.318389 -0.833989 -0.450655 -0.978475 -0.070904 -0.193804
--0.0285972 -0.972306 -0.231955 0.117531 -0.919095 -0.3761 -0.957871 -0.133723 -0.254168
--0.823829 -0.457683 -0.334414 0.398265 0.792466 -0.461933 0.428799 -0.227011 -0.874413
--0.170514 -0.882662 -0.437987 -0.309645 0.945233 0.103215 0.299377 0.94349 -0.142128
--0.686641 0.672336 0.276564 0.79082 0.39394 0.468417 0.198386 0.839325 0.506139
--0.599515 0.792319 0.113188 -0.505675 0.852423 0.13292 0.686569 0.473733 -0.551544
--0.317313 -0.463766 -0.827184 -0.885988 -0.437782 -0.152876 -0.462528 -0.886512 -0.012848
--0.895062 0.401235 -0.194616 0.978544 -0.144845 0.146529 -0.920899 0.327367 -0.211603
-0.872236 0.208885 -0.442234 0.262363 0.910983 -0.318237 0.856852 -0.509602 0.078169
-0.452362 0.876452 0.164924 0.258517 0.939418 -0.225084 -0.577073 -0.146094 -0.803519
-0.907065 -0.420878 0.00967536 -0.680325 0.255122 -0.687074 -0.0663093 0.582048 -0.810446
-0.241924 0.836654 -0.491408 -0.214169 0.938494 -0.270853 -0.510582 0.807553 -0.295235
--0.504783 -0.261739 -0.82261 0.188695 -0.677906 -0.71052 0.477558 -0.586803 -0.653911
--0.263785 -0.338687 -0.903166 -0.75132 0.0655221 -0.656677 0.727267 -0.595036 -0.342074
-0.126841 -0.692484 -0.710196 -0.89961 0.188291 -0.394015 0.971484 -0.139854 -0.191466
-0.937898 -0.346129 -0.0232614 -0.411939 0.56794 -0.712566 0.98726 0.13226 -0.088458
-0.84923 -0.36028 -0.386014 0.289955 -0.849693 -0.440395 -0.275267 -0.572488 -0.772324
--0.634616 0.0475962 -0.771361 -0.768179 0.303905 -0.563509 0.409018 -0.553643 -0.725385
--0.332772 -0.181342 -0.925407 0.972512 -0.230689 -0.0316632 -0.461936 0.14838 -0.874413
--0.41959 0.13741 -0.897253 0.525532 -0.586224 -0.616569 0.917388 -0.391152 -0.0734801
--0.786912 0.208901 -0.580629 0.946439 -0.259633 -0.191951 0.975783 0.118072 -0.184137
--0.0359614 0.471647 -0.881054 0.00288181 0.370312 -0.928903 -0.282292 0.341722 -0.896402
--0.530768 0 -0.847517 0.714956 -0.492864 -0.495906 0.257836 -0.699282 -0.666727
--0.389729 0.167027 -0.905656 -0.259181 0.610927 -0.74806 0.184859 0.0591548 -0.980983
--0.792411 -0.113653 -0.599307 -0.0431343 -0.197422 -0.979369 -0.533551 0.568348 -0.626342
--0.166914 -0.926267 -0.337888 -0.555622 -0.65112 -0.517037 -0.967191 -0.0541803 -0.248204
-0.355469 -0.823079 -0.442925 -0.443465 -0.518587 -0.731031 -0.962629 -0.172669 -0.208642
--0.897661 -0.368472 -0.241728 0.111658 -0.899335 -0.422764 -0.985853 0.131067 -0.104474
-0.84965 -0.515126 -0.112876 -0.31059 0.148658 -0.938848 -0.546689 -0.81886 -0.17493
-0.0932093 -0.0955993 -0.991046 0.873465 -0.11493 -0.473127 -0.570436 -0.371767 -0.732388
-0.709737 0.415677 -0.568758 -0.392645 -0.208593 -0.895722 0.867856 0.3632 -0.338986
-0.142514 0.0729142 -0.987103 0.837133 -0.107522 -0.536328 0.486846 -0.699546 -0.523084
-0.571804 0.507796 -0.644347 -0.324074 0.544199 -0.773837 0.587523 -0.587523 -0.556447
-0.988308 -0.0515375 -0.143497 0.917428 0.397619 0.0150234 -0.835169 -0.378436 -0.399098
-0.756881 -0.47434 -0.449592 0.557993 -0.557993 -0.614238 0.645238 -0.737415 -0.199717
--0.536173 -0.632409 -0.559086 -0.0521256 -0.79926 -0.598721 0.334866 -0.837718 -0.431384
-0.79371 0.163781 -0.585833 -0.655386 -0.573462 -0.491539 -0.865591 -0.0748042 -0.495132
-0.43624 -0.833989 -0.337872 -0.0930372 -0.868347 -0.487153 -0.227076 -0.866197 -0.445129
--0.221386 -0.854474 -0.469961 -0.381018 -0.847195 -0.37025 -0.570541 0.0691565 0.818352
-0.98138 -0.160694 -0.105216 -0.247 0.968627 0.0274444 -0.885824 0.420198 0.19685
--0.531494 0.341675 -0.775095 0.421847 0.888099 -0.182554 -0.0482555 0.965109 -0.257362
--0.942078 0.285478 -0.176045 0.583927 -0.237896 -0.776166 0.419812 0.257826 -0.87022
-0.35965 -0.0384092 -0.932296 0.799879 -0.131939 -0.585479 -0.56129 -0.799013 -0.215712
-0.725606 -0.0846922 -0.682878 -0.315342 -0.386549 -0.866683 -0.271599 -0.364468 -0.890728
--0.537244 -0.672859 -0.508556 -0.911339 0.0233079 0.410996 0.499059 -0.767783 -0.401807
-0.0522273 -0.377777 -0.924422 -0.117719 -0.375663 -0.919249 -0.181005 -0.837847 -0.515024
--0.158557 -0.372608 -0.914343 0.980312 -0.121694 -0.155498 -0.219502 -0.969891 0.105497
--0.903913 -0.18403 0.386102 -0.136131 -0.658635 -0.740046 0.227687 -0.607165 -0.761256
-0.0231565 -0.708202 -0.70563 0.348935 -0.747719 -0.564943 -0.147009 -0.65104 -0.744671
--0.42495 -0.459539 -0.779898 0.594258 0.556527 -0.580633 -0.325345 -0.945592 0.0025368
--0.188083 -0.442548 -0.876799 0.0850369 -0.357863 -0.929894 -0.389308 -0.448572 -0.804501
-0.670611 0.63708 0.380013 0.909109 0.37532 0.18071 -0.646918 -0.752538 0.123223
-0.255233 -0.478561 -0.84014 0.411 -0.135232 -0.901549 0.375551 -0.187775 -0.90758
--0.656132 -0.549009 -0.517764 -0.3431 -0.740116 -0.578369 -0.168283 -0.501845 -0.848429
-0.232733 0.806808 -0.543044 -0.114145 -0.984498 -0.133169 0.0698558 0.878187 0.47319
-0.960232 0.0751202 0.268908 0.511673 -0.473514 -0.71692 0.132824 -0.136849 -0.981647
--0.887468 -0.320718 -0.33097 0.193703 -0.830886 -0.52164 -0.903527 -0.172972 -0.392071
-0.658512 0.70729 -0.257104 -0.180472 0.789563 -0.586532 0.285217 0.918699 0.273208
-0.58228 0.804605 0.116456 -0.738717 -0.110808 0.664845 0.939025 -0.222655 0.262024
--0.464892 0.858465 0.216597 0.317284 -0.784144 -0.533339 0.135133 -0.713777 -0.687213
-0.199732 0.965371 -0.16783 -0.591054 -0.797923 0.118211 -0.895819 0.422518 -0.137792
--0.976474 0.205573 -0.0650983 -0.985232 0.168897 -0.0281495 0.830002 -0.536817 0.15141
-0.881484 0.336567 0.331224 -0.934465 -0.271554 -0.230288 0.493791 -0.841532 -0.219076
--0.714548 -0.519671 -0.468363 0.429581 -0.801884 -0.415261 0.437341 -0.799514 -0.411716
--0.968303 -0.162936 -0.189316 -0.0718217 -0.655373 -0.751883 0.103111 0.523737 -0.845617
-0.719326 -0.31275 -0.620288 -0.118581 0.783188 -0.610372 -0.500901 0.712981 -0.490669
-0.928063 -0.326783 -0.178641 -0.574786 -0.0334178 -0.817621 -0.35944 0.86132 -0.359069
--0.252345 -0.400784 -0.880735 -0.499005 0.483651 -0.719079 -0.210502 0.834124 -0.50983
--0.40673 0.777216 -0.480111 -0.00439597 0.84073 -0.541437 0.291792 0.827992 -0.478839
-0.302693 0.91365 -0.27133 -0.130404 0.891094 -0.43468 0.0603017 0.983449 -0.170855
--0.186761 -0.832641 -0.521373 -0.679514 -0.434134 -0.591429 0.420585 -0.723185 -0.547825
--0.245572 -0.0731492 -0.966614 -0.661545 0.340598 -0.668095 0.629657 -0.553173 -0.545465
--0.358405 -0.248571 -0.899866 0.891806 -0.452011 -0.0191974 -0.754601 0.0855841 -0.650578
-0.356064 -0.715145 -0.601486 0.995831 -0.0142262 -0.090099 -0.58215 0.429977 -0.690087
--0.724248 0.347639 -0.595493 -0.801478 0.281976 -0.527373 -0.779075 0.302749 -0.548985
--0.898627 0.149771 -0.412357 0.914188 -0.148247 -0.377205 0.992642 -0.0428094 0.113266
-0.0517198 -0.947414 -0.315805 -0.927056 0.0902244 -0.363905 -0.559794 -0.737206 -0.378363
--0.958316 -0.180477 -0.221494 -0.714704 -0.565303 -0.411863 0.646173 0.396238 -0.652269
-0.892075 0.079219 -0.444889 -0.800266 -0.561011 -0.211754 -0.996918 0.0657309 -0.0428246
--0.189974 -0.93027 -0.313859 0.290537 -0.646816 -0.705136 0.490444 -0.759708 -0.426975
-0.901897 0.167689 -0.398073 0.890305 0.39509 -0.22641 0.724946 -0.54371 -0.422885
-0.793386 -0.288132 -0.536207 -0.776237 -0.292262 -0.558605 0.976611 0.213166 0.0281372
-0.842339 0.304002 -0.445025 0.814105 0.306631 -0.493164 0.305038 0.0938579 -0.947704
-0.710796 -0.527646 -0.465143 0.374728 -0.498793 -0.781527 0.242357 -0.73988 -0.627568
--0.867817 0.0565968 -0.49365 0.726207 0.6205 -0.295979 0.927935 0.371065 -0.0353137
-0.652765 -0.293271 -0.698491 0.696431 -0.115888 -0.708204 -0.302605 0.048315 -0.951891
-0.520128 0.779495 -0.349076 0.488382 -0.586761 -0.645906 0.327712 -0.0121375 -0.9447
-0.457791 -0.3689 -0.808913 -0.00402853 -0.739235 -0.673436 0.868894 -0.408891 -0.278983
--0.641868 -0.421128 -0.640825 0.986782 0.150123 -0.0610255 -0.779776 -0.320574 -0.537756
-0.651451 -0.138391 -0.745962 -0.869597 0.0763549 -0.487823 0.710504 0.617323 -0.337781
-0.220767 -0.0229966 -0.975055 -0.0934787 -0.933175 -0.347053 0.0896729 -0.174364 -0.98059
-0.501089 -0.418718 -0.757354 0.172447 -0.172447 -0.969806 0.171111 -0.841528 -0.512397
-0.556848 -0.556848 -0.616312 0.180093 0 -0.98365 -0.244977 -0.792573 -0.558404
--0.269363 -0.778844 -0.566432 0.378509 -0.485634 -0.787966 0.286378 -0.266507 -0.920305
-0.217689 0.0473238 -0.97487 0.200596 -0.351042 -0.914621 -0.101472 -0.854825 -0.508898
-0.178932 -0.178932 -0.967454 -0.0207192 -0.361976 -0.931957 0.498923 -0.507459 -0.702539
-0.483004 -0.509034 -0.712455 0.76903 0.587655 0.251507 -0.301348 0.919499 0.252411
--0.0384775 -0.577162 -0.815723 0.082675 -0.277205 -0.957247 0.238274 -0.201616 -0.95004
--0.765755 -0.402021 -0.501995 -0.69594 -0.510917 -0.504609 -0.13824 -0.984957 0.10368
--0.502977 -0.863808 0.0291581 0.545883 -0.745784 0.381862 -0.953289 0.223045 0.203694
--0.850018 0.525734 0.032756 0.409694 -0.594898 -0.691554 -0.674859 -0.503077 0.539887
--0.0078526 -0.753849 -0.657001 0.737376 -0.63715 0.224315 -0.474709 -0.833032 0.284092
-0.279673 -0.619451 -0.733528 0.172541 -0.366033 -0.914467 0.157571 -0.0555251 -0.985945
-0 0.320807 -0.947145 -0.113267 -0.550789 -0.826923 -0.258576 -0.430959 -0.86453
--0.347626 -0.61694 -0.706075 -0.394927 0.668337 0.630364 0.862274 0.485029 -0.145708
-0.210028 0.977087 0.0344973 -0.499032 0.738152 0.453981 -0.786821 0.236416 0.570106
-0.695176 0.283864 -0.660417 -0.176292 0.557082 -0.81153 -0.534678 -0.0379013 -0.844205
-0 -0.542159 -0.840276 -0.302755 -0.513602 -0.802841 -0.291386 -0.388514 -0.874157
-0.278614 -0.767009 -0.577989 -0.228 -0.182875 -0.956333 -0.754886 -0.310732 -0.577575
-0.269663 -0.910112 0.314607 0.833897 -0.551655 -0.0171056 -0.727183 -0.650326 0.219731
-0.930932 0.241584 -0.273865 -0.529984 0.711485 0.461417 -0.849591 0 0.527442
--0.230759 0 0.973011 0.0269059 0.666241 0.745251 -0.281486 0.910101 0.304109
--0.327088 -0.727603 -0.602998 -0.0227522 -0.712902 -0.700894 0.66698 -0.618231 -0.415847
-0.478994 -0.319329 -0.817676 -0.427317 -0.0899615 -0.899615 -0.0149172 -0.615334 -0.788125
-0.0405642 -0.699732 -0.713253 0.329685 0.576949 -0.747287 -0.29226 0.670479 -0.68194
--0.0274813 -0.659552 -0.751156 -0.135381 -0.631778 -0.763235 -0.185869 -0.430745 -0.883126
--0.888935 -0.146262 -0.434054 0.968516 0.0131871 0.248601 0.562413 -0.788051 -0.250335
--0.161129 -0.986917 -0.00559477 -0.547542 -0.752558 0.365861 0.74427 0.0636547 0.664838
--0.488658 0.730359 0.477273 0.614369 -0.78882 -0.0176979 -0.570599 -0.570599 -0.59062
--0.380847 -0.914032 -0.139644 0.861457 -0.267811 -0.431473 -0.909721 0.1077 -0.40101
--0.128373 -0.826398 -0.548258 0.714629 -0.691576 0.105017 -0.0867184 -0.552259 0.82915
--0.997986 0.0608753 0.0178322 0.459158 -0.880053 0.121167 0.313637 -0.947183 0.0669092
--0.357703 -0.933826 0.00422068 0.561474 -0.827436 -0.00985042 0.911792 -0.293076 -0.287649
-0.102258 0.2876 0.952276 0.641782 -0.187839 0.743527 -0.586427 -0.662095 -0.466619
--0.970237 -0.222192 -0.0962831 0.213508 0.781899 0.585703 0.713906 0.695119 0.0845415
--0.381851 0.575194 0.723423 -0.309021 0.0457809 0.949953 -0.393099 0.48295 -0.782453
-0.634537 -0.625066 0.454594 0.953295 -0.120956 0.276763 0.873406 0.291135 0.390386
--0.280131 0.931437 0.232276 0.204539 0.562482 0.801111 -0.097859 0.831801 -0.546379
-0.907674 0 -0.419677 0.819948 0.571479 -0.0331292 -0.720129 -0.49272 0.488509
--0.537713 -0.778958 0.322628 0.668143 -0.348287 0.657481 -0.687771 0.723042 0.0646623
--0.0484929 0.994104 0.0969857 0.808223 -0.528712 -0.259305 -0.791052 0.566536 -0.230811
-0.752408 -0.165439 0.637583 -0.824815 -0.045823 0.563543 -0.940138 -0.197126 0.277998
-0.772106 -0.292395 -0.564231 0.667928 0.742142 -0.0556606 -0.836563 0.497088 0.230358
-0.186484 -0.959063 -0.213125 0.0693341 -0.990487 -0.118858 0.472632 0.836734 0.276577
--0.0268747 -0.698743 -0.714868 0.924193 -0.370082 0.0943742 -0.969623 -0.102912 0.221904
-0.248282 -0.910366 0.331042 0.948932 -0.199775 -0.24417 -0.365232 0.896478 -0.250866
--0.738858 -0.577498 -0.347254 -0.693041 -0.713791 -0.100982 -0.624894 -0.621727 -0.472189
-0.695174 -0.695174 -0.18294 -0.991053 -0.125374 -0.0457715 0.58828 -0.788073 -0.181294
--0.595792 -0.746726 -0.295689 -0.759902 -0.597864 -0.255163 0.591665 0.792456 -0.148139
--0.137568 -0.792204 -0.594548 -0.176128 -0.401005 -0.898985 0.393653 -0.719251 -0.572465
-0.55508 -0.80699 -0.201625 -0.0898359 0.285728 -0.954091 0.0976536 -0.19194 -0.976536
-0.427482 -0.61799 -0.659809 0.578262 -0.813487 -0.0620733 -0.255468 -0.271109 -0.928028
--0.523024 0.156704 -0.837789 0.683384 -0.416816 -0.599375 -0.395116 0.531363 -0.749358
--0.301731 0.484682 -0.821001 0.845864 -0.510983 -0.153006 0.819229 -0.569405 0.0681339
-0.709237 0.164138 -0.685596 0.207528 0.6127 -0.762581 0.923431 -0.310708 -0.225245
--0.162754 0.787458 -0.594492 0.652019 0.0197582 -0.757945 0.768873 -0.253047 -0.587198
--0.621695 0.321359 -0.714299 0.591213 -0.564986 -0.57555 -0.160851 0.0419611 -0.986086
-0.628373 -0.265136 -0.731334 0.729737 -0.367285 -0.576702 0.112827 -0.126101 -0.98558
--0.664376 0.408847 -0.625659 -0.410122 0.31638 -0.855397 -0.337348 0.363297 -0.868454
-0.685398 -0.602109 -0.409504 -0.697605 0.379467 -0.607743 -0.0654955 -0.688832 -0.721956
--0.871567 -0.0234853 -0.489713 0.670593 -0.741681 -0.0146125 -0.865168 0.146297 -0.479668
--0.8769 0.10167 -0.469798 -0.847356 -0.194703 -0.494043 -0.829636 0.173678 -0.530603
--0.901618 -0.0424442 -0.430445 -0.886804 -0.0928051 -0.452732 -0.811178 -0.0201535 -0.584451
--0.85455 0.278911 -0.438125 -0.661704 0.676585 -0.323081 -0.429258 -0.520739 -0.737949
--0.422608 -0.808144 -0.410251 -0.777924 0.0138915 -0.628205 -0.868429 0.0315543 -0.494808
--0.761754 -0.364631 -0.535514 0.807114 -0.417473 -0.417473 -0.609969 -0.738179 -0.288149
--0.949876 -0.0166645 -0.312182 -0.959867 0.157535 -0.232029 0.883655 -0.294552 -0.363858
--0.758329 -0.262279 -0.59678 -0.711843 -0.4919 -0.501312 -0.153665 -0.881345 -0.446786
-0.652715 -0.141231 -0.744324 -0.298263 -0.742896 -0.599287 -0.894969 0.444145 -0.0420212
--0.424483 -0.849683 -0.312815 -0.0522991 -0.780217 -0.623319 0.73675 -0.0437674 -0.674747
-0.845535 0.431687 -0.314192 -0.801317 0.489281 -0.34423 -0.927278 0.161833 -0.337588
-0.754098 0.324301 -0.571109 0.756034 0.574219 -0.314142 -0.459049 -0.86686 -0.194495
-0.776158 -0.0757228 -0.625975 -0.960802 0.277236 0 -0.725056 -0.28665 -0.6262
-0.717335 -0.531622 -0.450343 -0.812963 -0.0150549 -0.582121 -0.792509 -0.074795 -0.605256
--0.644503 -0.245979 -0.723954 -0.565292 0.0699885 -0.821916 -0.480075 -0.801048 -0.357561
-0.508248 -0.512954 -0.691782 -0.871898 -0.272468 -0.406886 0.520541 -0.362801 -0.772924
-0.522675 -0.441918 -0.729053 -0.662861 -0.628622 -0.406755 -0.758493 -0.204926 -0.618623
--0.537976 -0.37459 -0.755158 0.932353 0.346853 -0.10203 -0.816905 -0.00464811 -0.576753
--0.383825 0.119945 -0.915583 -0.292393 -0.247722 -0.923656 -0.475811 -0.254623 -0.841885
-0.943693 0.321587 0.0776246 -0.0446794 -0.854494 -0.517537 0.238988 0.942297 0.234436
--0.780142 0.61709 0.102848 0.825891 -0.560899 0.0574149 0.0991213 0.429526 0.897598
--0.964809 -0.244802 0.0960009 0.411222 -0.712785 -0.568185 0.242342 -0.693802 -0.678167
--0.163558 -0.906226 -0.389877 0.260388 -0.698313 -0.666751 -0.564163 -0.57856 -0.589057
--0.00563318 0.9982 0.0597117 -0.996706 -0.0699794 -0.0409879 -0.368071 0.926019 -0.0837409
-0.21344 -0.649488 -0.729801 -0.420871 -0.899368 -0.118338 0.97701 0.212449 -0.0178101
-0.214514 -0.477185 -0.85222 0.0847024 -0.0889375 -0.992429 -0.450341 -0.378696 -0.808568
--0.172528 -0.73739 -0.653062 -0.80767 -0.560697 0.182449 -0.302778 0.43692 -0.847011
--0.29517 -0.361763 -0.884309 -0.716899 0.109357 -0.688547 -0.00174721 -0.676172 -0.736742
-0.111441 0.984393 0.136205 0.677331 0.727815 -0.107279 0.523706 0.851896 -0.00232758
--0.55464 0.741248 0.378054 -0.961 0.0864778 0.262681 0.572965 -0.791734 -0.211823
--0.625792 -0.727271 -0.281888 -0.366019 -0.524073 -0.76901 0.299987 -0.784325 -0.542994
-0.0899026 -0.70124 -0.707234 -0.726774 -0.34349 -0.594823 -0.540466 -0.493469 -0.681458
--0.100363 -0.451634 -0.886541 0.908532 0.345828 -0.23446 -0.889587 -0.167233 0.425051
-0.111754 -0.621633 -0.775295 -0.349217 -0.133035 -0.92755 0.236301 0.843931 0.481603
-0.512517 0.772843 0.374219 -0.999969 -0.00476176 0.00634901 0.567379 -0.756505 -0.32524
--0.532288 -0.846394 -0.0169279 -0.476215 -0.878352 -0.0414483 0.632215 0.12772 0.764193
--0.0429579 0.948003 0.31535 0.956566 -0.206483 -0.205781 0.873818 0.484142 -0.0452653
--0.636874 0.770953 0.00474862 -0.506477 0.569787 -0.647166 -0.0814436 -0.977323 0.195465
--0.141925 -0.978539 -0.149395 0.415453 -0.909612 0.00232467 0.9282 -0.330592 0.170745
-0.882775 0.396348 0.252222 -0.809829 0.583077 0.0647864 -0.910695 0.395136 0.120423
-0.862701 0.38634 0.326326 0.988963 -0.0830152 0.122718 0.381722 0.819996 0.426492
--0.702105 0.706334 0.0902303 -0.635553 -0.566701 -0.524331 0.188958 0.6771 0.711218
-0.93302 0.0222148 0.359139 0.675939 -0.692629 0.251739 -0.72403 0.686661 0.0653963
--0.915396 0.349515 0.199723 -0.48367 -0.860083 -0.162235 0.862666 0.342529 0.37213
--0.851916 0.523678 -0.000835212 0.808312 -0.5819 0.0895773 0.618689 -0.471382 0.628509
--0.749072 0.650357 0.1262 0.10313 0.980641 0.166456 0.682158 -0.731202 -0.00222927
--0.951088 -0.118595 -0.285249 0.77083 -0.632254 0.0779491 0.211129 0.889759 0.404664
--0.542737 0.839349 0.0305026 0.789355 -0.612946 -0.0348831 -0.802624 -0.526311 -0.280699
-0.696452 -0.712102 -0.0886867 -0.972939 -0.023615 -0.229853 -0.531443 0.77455 0.342988
-0.590401 -0.801961 -0.0910202 0.868927 0.463428 -0.173785 0.981048 -0.151578 -0.120701
--0.80975 0.563304 -0.164297 0.649936 -0.747776 -0.135695 -0.919676 -0.326727 -0.217818
-0.832367 -0.542793 -0.111985 -0.887132 -0.3314 -0.321203 -0.919632 0.386829 -0.0681209
--0.918796 0.350723 0.181125 0.186736 -0.982362 0.00968799 -0.859083 0.501132 0.104131
--0.961772 0.225352 0.1556 0.277818 -0.884901 -0.373854 0.662087 -0.735246 -0.145098
--0.650969 -0.754723 -0.0814409 -0.647192 -0.616373 -0.448583 0.804875 -0.593398 -0.00736487
-0.120998 0.992372 0.0236056 -0.193053 0.978683 0.0700657 -0.676753 0.104116 -0.728811
--0.239465 -0.810878 -0.533979 -0.580163 0.463296 -0.669901 -0.60503 0.537085 -0.587774
--0.518402 0.439682 -0.733443 -0.562085 0.436355 -0.702606 -0.608176 0.351391 -0.711791
--0.683912 0.254025 -0.683912 -0.479149 0.199326 -0.854801 -0.272635 0.576555 -0.77023
--0.215907 0.663423 -0.716418 -0.394579 0.506252 -0.766823 -0.406585 0.609878 -0.680248
-0.297571 0.732482 -0.612309 -0.0874499 0.911977 -0.400812 -0.522842 0.692766 -0.4967
--0.814067 0.323509 -0.482323 0.826154 -0.56344 0.00224542 -0.489245 0.462437 -0.739453
-0.77798 -0.430456 -0.457661 -0.566856 0.474453 -0.673475 -0.708262 0.397687 -0.583275
-0.806212 -0.58939 0.0514062 -0.817192 0.498769 -0.288835 -0.679102 0.469527 -0.564239
--0.773952 0.348278 -0.528867 -0.910986 0.0700759 -0.40644 -0.978773 -0.13328 -0.155691
--0.78692 0.041236 -0.615676 0.955127 -0.267503 0.127183 -0.70305 0.212241 -0.67873
--0.572229 0.171218 -0.802022 -0.407421 0 -0.913241 -0.531609 -0.182043 -0.827195
--0.770144 0.0738629 -0.633579 -0.823196 -0.00460744 -0.567739 -0.800541 0.198299 -0.56552
--0.464681 0.52922 -0.709929 -0.445637 0.728326 -0.520527 -0.844319 0.360537 -0.396407
--0.803115 -0.473484 -0.361689 -0.760715 -0.41624 -0.498053 -0.900008 0.133334 -0.414979
-0.525763 -0.126183 -0.84122 -0.747258 0.161173 -0.644693 -0.551081 -0.76919 -0.323507
--0.572163 -0.754913 -0.320525 -0.897505 -0.110123 -0.427034 0.742705 -0.553222 -0.377274
--0.167768 -0.894763 -0.413828 0.59585 -0.546195 -0.588756 -0.554865 -0.615994 -0.559175
--0.566758 -0.775831 -0.277257 -0.204349 -0.819952 -0.534714 0.666597 -0.367943 -0.64828
-0.812309 0.445752 -0.376111 -0.420328 -0.754858 -0.503501 0.492021 0.00531915 -0.870567
-0.852066 0.41589 -0.317834 0.792062 0.517678 -0.323493 0.593697 -0.521295 -0.613005
--0.705055 -0.236478 -0.668562 -0.620622 0.404258 -0.671866 -0.822447 0.568842 0
-0.11671 0.729157 -0.674322 -0.331979 0.799635 -0.500373 -0.803889 0.500019 -0.322092
-0.798379 -0.0523527 -0.599875 0.369866 0.156217 -0.915858 -0.619742 0.236812 -0.748225
-0.147107 0.249524 -0.95713 -0.94483 -0.181092 -0.272951 0.797186 -0.028269 -0.603072
-0.656777 -0.402486 -0.637691 0.314249 -0.196992 -0.928677 0.42417 -0.24661 -0.871357
--0.3767 0.219742 -0.899895 0.149819 -0.301842 -0.941512 -0.636536 -0.642656 -0.426397
-0.392456 -0.364706 -0.844374 0.453076 -0.372224 -0.810044 -0.601956 -0.566373 -0.562913
--0.769846 -0.60387 -0.206587 -0.648616 -0.253806 -0.717551 -0.482492 0.516685 -0.707275
-0.579276 -0.177645 -0.795539 -0.416049 0.462771 -0.782781 -0.664953 0.31518 -0.677125
--0.309773 -0.937782 -0.156861 -0.28769 -0.939543 -0.185724 -0.654088 -0.735849 -0.175202
-0.821154 0.186192 -0.539479 -0.743262 -0.408794 -0.529574 0.532575 -0.282284 -0.797922
--0.264237 -0.397348 -0.878802 0.0706018 -0.600115 -0.796792 -0.778534 -0.257697 -0.572256
--0.0263625 -0.254837 -0.966624 0.156417 -0.449142 -0.879662 -0.72083 -0.511382 -0.46786
--0.449142 -0.156417 -0.879662 -0.55333 0.166757 -0.816099 -0.372586 -0.62904 -0.682267
--0.165314 -0.521468 -0.837104 -0.0278004 -0.185336 -0.982282 -0.2608 0.587367 -0.766148
-0.411074 -0.88683 -0.211069 0 0.211055 -0.977474 0.40504 0.495825 -0.76818
-0.272106 0.705253 -0.654658 0.880827 0.463391 0.0970186 -0.901997 0.43139 -0.0174299
--0.100298 0.254602 -0.961831 0.712622 -0.698888 0.0610383 -0.762781 -0.642749 0.0709864
-0.542105 -0.496929 -0.677631 -0.506658 -0.608718 -0.610541 -0.1159 -0.321207 -0.93989
-0.477504 0.187591 -0.85837 0.384429 -0.242307 -0.890787 0.598357 -0.295391 -0.74479
--0.294199 -0.501868 -0.813373 0.663932 0.165983 -0.729139 0.814149 0.32566 -0.480736
--0.721139 -0.655581 -0.22399 0.247493 -0.489361 0.836226 0.87133 -0.483522 -0.0836124
--0.163022 0.984484 -0.0649265 -0.905469 0.347303 0.243939 -0.847847 0.520966 0.0987452
-0.292962 -0.404503 -0.866343 0.0265558 -0.68455 -0.728482 0 -0.73366 -0.679517
--0.26173 -0.628348 -0.732582 -0.00576413 -0.201744 -0.979421 0.782567 -0.146079 -0.605185
-0.677627 -0.511417 -0.528464 0.53679 -0.84314 -0.0311772 0.00518468 -0.995459 0.0950525
--0.18027 -0.755749 -0.62956 0.131033 -0.512738 -0.848487 0 -0.263428 -0.964679
-0.0960711 -0.148345 -0.984258 0.242487 -0.664796 -0.706573 -0.196046 -0.844506 -0.498373
-0.125768 -0.440786 -0.888758 -0.244309 -0.745455 -0.620169 -0.228088 -0.740599 -0.632051
--0.122469 0.35652 -0.926226 0.257634 -0.434757 -0.862908 0.00588786 -0.812524 -0.582898
--0.25625 -0.318246 -0.912719 0.02465 0 -0.999696 0.686449 0.171612 -0.706638
--0.77205 0.353728 -0.528029 0.409933 -0.625121 -0.664213 0.471881 -0.434815 -0.766984
--0.0935671 -0.340244 -0.935671 0.13288 0 -0.991132 0.225659 0.0569847 -0.972538
-0.166533 -0.313345 -0.934923 0.463903 -0.746279 -0.477349 -0.807694 0.472775 -0.352298
-0.616546 0.784695 0.0642236 0.0344266 -0.496727 -0.867224 0.226224 -0.690792 -0.686752
-0.00989547 -0.951202 -0.308409 -0.668022 -0.276926 -0.690694 0.255987 0.252662 0.933077
-0.455952 0.237345 0.857773 -0.265447 0.245028 0.932469 -0.0574943 0.767959 0.637913
-0.904957 -0.0530101 0.422187 0.654389 0.75029 0.0940213 0.150119 -0.850672 -0.503807
-0.34337 0.587598 0.732684 0.0545363 -0.96711 0.248443 -0.830342 0.556603 0.0269394
-0.674611 0.732767 0.0891727 0.819487 0.569374 0.0652255 0.891889 -0.445384 -0.0785311
--0.482966 -0.0817328 -0.871816 -0.975184 -0.0872116 0.203494 -0.0860946 0.941769 0.325051
-0.805688 -0.591934 0.0219235 0.343258 0.86368 0.369094 -0.966533 0.250162 0.0568549
-0.591278 0.743866 0.311534 0.743494 0.650557 0.154895 0.943002 0.189716 -0.273415
-0.874134 -0.277382 -0.398683 0.67779 -0.550704 -0.487161 0.33154 0.754817 0.565979
-0.626842 -0.676591 0.386386 -0.598319 0.800793 0.0272997 0 -0.871576 -0.490261
-0.0722282 -0.967055 -0.244105 -0.139767 -0.941485 -0.306711 0.828475 0.555684 -0.0696009
-0.903477 -0.424268 -0.0610457 -0.954305 0.183792 -0.235631 -0.946472 -0.165543 -0.277104
-0.62114 0.763484 0.176852 -0.669754 0.740255 0.0587504 -0.827886 0.454002 -0.329374
-0.854212 -0.51096 0.0961315 0.763126 0.457875 0.456058 -0.639139 0.768489 0.0304352
--0.726498 0.687076 -0.0112635 0.827618 -0.529078 0.187416 -0.0556839 0.997249 0.0489344
-0.238792 0.878661 0.413442 -0.898035 0.436249 -0.0567479 0.0794507 -0.979177 -0.186817
-0.477464 -0.878192 -0.0284204 0.248372 -0.931394 0.266113 -0.953889 -0.0260367 -0.299027
-0.065624 -0.976008 -0.20761 -0.4787 -0.656139 -0.583376 0.793964 -0.53758 -0.283952
-0.870715 -0.477104 -0.119276 -0.904923 0.3541 -0.236067 0.971278 -0.182912 0.152191
-0.823809 -0.566067 0.03011 0.796188 -0.60419 0.0322235 -0.974865 -0.162277 -0.152661
-0.970984 0.192592 0.141769 0.931307 0.347631 -0.108724 -0.205526 0.976251 0.0685088
--0.798314 -0.434083 0.417452 -0.417846 -0.473559 -0.775337 0.78154 -0.623635 -0.0165593
-0.828034 -0.520319 -0.208873 -0.473877 -0.880563 -0.00707279 -0.745437 -0.64853 0.154057
-0.550147 -0.696653 -0.460449 -0.926113 0.356864 -0.122326 -0.863385 0.400411 -0.306981
--0.864079 0.29614 -0.407023 0.347919 -0.748956 -0.56393 0.167435 -0.771399 -0.61393
--0.879002 0.355188 0.318115 -0.536021 -0.716349 -0.446684 0.645486 -0.761253 -0.0619761
-0.403714 -0.847329 -0.345034 -0.246641 -0.44043 -0.863243 -0.693521 0.709105 -0.127275
--0.825708 -0.324556 -0.461378 0.982818 0.0530375 -0.176792 0.746583 -0.584152 -0.318403
--0.510715 -0.2293 -0.828608 0.906152 0.247132 -0.34324 0.122792 -0.960899 -0.248184
-0.310242 0.916184 0.253688 -0.708175 -0.465174 -0.531132 0.978202 -0.145819 -0.147844
--0.945683 0.282989 -0.160002 -0.494376 -0.861905 -0.112752 -0.539 -0.842296 0.00404395
-0.449857 0.878736 -0.159535 0.528707 0.827357 0.189603 0.537905 0.815755 0.212607
-0.064815 0.914355 0.399693 0.0703927 0.240253 0.968155 0.493916 0.631321 0.597898
--0.61754 -0.782218 -0.0823387 -0.810859 0.548522 -0.20404 -0.36257 0.611997 -0.702854
--0.778382 0.555209 -0.293027 -0.353858 0.234048 -0.905542 -0.697202 0.312684 -0.645088
--0.3748 0.3748 -0.847968 0.0431331 0.539164 -0.841096 -0.116571 0.657874 -0.744052
--0.249592 0.660891 -0.707762 0.0597491 0.336768 -0.93969 -0.577712 0.659838 -0.480483
--0.60388 0.530683 -0.594731 -0.150688 0.539966 -0.828088 -0.369478 -0.383689 -0.846326
--0.707931 0.353966 -0.611181 -0.306082 0.83371 -0.459609 -0.465637 0.456639 -0.758066
-0.153931 0.262965 -0.952447 0.213066 0.319599 -0.923287 -0.309679 0.424909 -0.850618
--0.0362285 -0.00905712 -0.999303 -0.771425 0.115714 -0.625711 -0.810519 0.0457551 -0.583922
--0.451093 0.663373 -0.597035 -0.312808 0.904909 -0.288603 -0.799353 0.583714 -0.14252
--0.593688 -0.604582 -0.531051 -0.716216 -0.648564 -0.257681 0.389333 -0.449012 -0.804243
-0.574993 0.146991 -0.804846 -0.631734 -0.539535 -0.556609 0.696127 0.126568 -0.706674
--0.661887 0.625641 -0.412891 0.134114 -0.560673 -0.817104 0.833614 0 -0.552348
--0.890851 0.234503 -0.389092 -0.912051 -0.343773 -0.223569 -0.879735 -0.149288 -0.45142
-0.516374 0.344249 -0.784124 -0.539225 -0.644543 -0.542034 -0.555452 -0.336169 -0.760567
--0.551223 0.045306 -0.833127 0.344184 -0.251519 -0.904586 -0.379469 0.236316 -0.894516
--0.0505197 0.523332 -0.85063 -0.428999 0.712708 -0.554983 -0.423668 0.738436 -0.524612
-0.414105 -0.164673 -0.895209 -0.699193 0 -0.714933 -0.503052 0.220748 -0.835589
--0.193854 0.693313 -0.694073 -0.749304 -0.194264 -0.633092 -0.559887 0.352447 -0.749872
-0.121946 0.858652 -0.497842 -0.782248 -0.349631 -0.515603 0.913806 -0.214453 -0.344917
--0.997963 0 -0.0637986 -0.934474 0.254436 -0.249039 -0.970636 0.23386 -0.0563426
--0.615577 -0.685302 -0.389135 -0.560925 -0.362052 -0.744501 0.307347 -0.53607 -0.786236
--0.669301 0 -0.742992 0.401257 -0.517128 -0.756023 0.395116 -0.531363 -0.749358
--0.632136 -0.102429 -0.768058 0.805925 -0.0215323 -0.591627 0.519204 -0.705333 -0.482631
--0.672804 -0.067374 -0.736747 0.553892 0.568681 -0.608116 -0.71218 0.0727614 -0.698216
--0.363524 -0.813978 -0.453088 0.561699 -0.27675 -0.779682 0.404642 -0.617612 -0.674404
-0.542029 -0.496095 -0.678302 0.17444 -0.0847279 -0.981016 -0.570814 -0.32865 -0.752436
--0.303507 0.360772 -0.881888 -0.410297 -0.776689 -0.477923 0.407867 -0.210306 -0.888491
-0.372813 0.135367 -0.917979 -0.317082 0.018119 -0.948225 -0.831034 0.0494128 -0.554023
-0.55003 -0.523838 -0.650432 -0.305021 -0.570503 -0.762554 -0.833039 -0.183966 -0.521731
--0.421117 -0.197667 -0.885205 -0.902386 -0.374105 -0.213882 -0.347955 -0.665913 -0.659914
--0.960518 -0.274434 -0.0457389 -0.968183 -0.212205 0.132628 0.238512 -0.0226325 -0.970876
-0.422694 -0.422694 -0.801661 0.380996 -0.627881 -0.678681 -0.864546 -0.364306 0.346181
--0.330467 -0.165233 -0.929241 -0.290911 -0.661823 -0.690914 0.0875772 -0.860865 -0.50124
-0.683175 -0.704524 -0.192143 -0.564599 -0.793711 0.226385 0 0.175069 -0.984556
--0.37607 -0.75214 -0.541162 -0.455337 -0.610873 -0.64769 -0.578046 -0.611896 -0.539857
--0.454739 0 -0.890625 0.321236 0.470648 -0.821766 0.309639 0.379102 -0.872012
--0.174146 0.245853 -0.953535 0.270138 -0.433858 -0.85953 0.0202675 0.668827 -0.743141
-0.0359715 0.373359 -0.926989 -0.315727 -0.315727 -0.894781 -0.380819 -0.635748 -0.671417
--0.423972 0.527501 -0.7362 -0.641047 -0.166119 -0.749308 -0.54974 -0.66345 -0.507562
--0.87643 -0.316259 -0.363112 0.256253 -0.169224 -0.951682 -0.82949 -0.49722 -0.254398
-0.660376 -0.23983 -0.711607 -0.115367 -0.195076 -0.973979 0.00509622 -0.225508 -0.974228
--0.23051 -0.669224 -0.706403 -0.501724 -0.666412 -0.551514 0.495783 -0.452462 -0.741268
-0.156365 -0.721412 -0.674621 -0.133386 -0.306152 -0.942592 -0.356597 -0.662251 -0.658986
-0.735799 0.674674 -0.0584333 -0.63828 0.760538 -0.119082 -0.172447 -0.172447 -0.969806
--0.492528 -0.379489 -0.783201 0.325622 0.842744 -0.428664 0.107415 0.747668 -0.655328
--0.81243 -0.183011 -0.553593 -0.983947 -0.178461 0 -0.172447 -0.172447 -0.969806
-0.082675 -0.277205 -0.957247 -0.14805 -0.345451 -0.926685 0.536267 0.701781 -0.468958
-0.312591 0.842878 -0.437999 -0.0678658 0.729558 -0.680544 -0.83351 -0.176319 -0.523615
--0.0240081 -0.970826 0.23858 -0.976271 -0.21639 0.00838721 0.121592 -0.688336 -0.715128
-0.253107 -0.523776 -0.813385 -0.221956 -0.635875 -0.739188 -0.0115213 -0.724692 -0.688976
-0.386263 0.920088 -0.0651006 0.222209 0.96929 -0.105358 -0.0538851 0.948377 -0.312533
--0.515738 0.055012 -0.854979 -0.427164 -0.768895 -0.475743 0.872329 -0.187977 -0.45134
--0.696362 0.666457 -0.266298 0.378509 -0.485634 -0.787966 -0.135512 -0.597534 -0.79031
--0.12771 -0.989754 -0.0638551 -0.14718 -0.987332 -0.0592808 -0.18581 -0.854396 -0.485264
-0.170756 -0.282894 -0.943829 -0.260393 -0.791765 -0.552542 -0.388232 0.522619 0.759042
-0.638935 -0.0418974 0.768119 -0.537887 0.758559 0.367786 0.00162546 -0.831423 -0.555637
-0.697849 0.536807 -0.474179 0.509548 -0.774121 0.375629 0.502088 -0.793742 -0.343339
-0.761545 -0.598772 -0.248035 0.718602 -0.617745 -0.319378 -0.655845 -0.139119 -0.741966
--0.526761 -0.325527 -0.78521 -0.760006 0.313617 -0.569241 0.792057 0.243343 0.559848
-0.27298 0.961115 0.0417052 -0.135909 0.96431 0.227235 -0.455563 0.754413 0.472571
-0.0211604 0.921441 -0.387941 -0.545395 0.253523 -0.798918 -0.807688 -0.264334 -0.527037
--0.401322 0.825934 0.395947 0.974495 -0.0417342 0.220496 0.984002 -0.127601 0.124329
-0.689761 0.720147 0.074952 0.398757 0.806309 0.436873 0.399496 0.559294 0.726356
-0.105949 0.994286 -0.0130398 0.676602 0.67255 0.299811 -0.109824 0.93223 -0.344797
--0.850381 -0.390716 -0.35241 0.274537 0.137269 0.951728 0.747409 0 0.664364
-0.944553 0.280813 -0.17019 -0.691431 -0.718024 -0.0797805 0.412394 -0.830269 0.374945
-0.0349829 -0.988267 0.148677 -0.17372 -0.978318 0.112766 -0.550285 -0.822469 -0.143981
-0.597449 0.74922 0.285876 0.700209 -0.65902 0.274592 -0.284758 0.801629 0.525646
--0.542715 -0.50395 0.671933 0.934404 -0.0133486 -0.355964 -0.610997 -0.73741 -0.287941
-0.936698 0.342018 -0.0749769 0.852352 -0.437889 -0.285919 -0.499767 0.866067 -0.0126647
--0.971465 0.124172 0.202084 0.603574 0.720053 0.342378 0.888564 -0.458445 -0.0167852
-0.955239 -0.114 0.272988 -0.278246 0.924176 0.261684 0.348285 0.868507 0.352693
--0.375022 0.912919 0.16105 -0.6494 -0.684822 -0.330604 0.754167 -0.270397 -0.598429
--0.16011 -0.936841 -0.310957 -0.564127 -0.798593 -0.209785 -0.838848 0.522174 0.153845
-0.509181 -0.86066 -0.000343577 0.56089 -0.820125 0.113121 -0.749457 0.356538 0.557848
-0.757747 -0.652537 0.00394044 -0.855023 0.510462 0.0914577 0.317331 -0.769286 0.554527
--0.641643 0.641643 0.420224 0.706267 -0.462727 -0.535789 -0.0413064 -0.888088 -0.457813
--0.275058 -0.933038 0.231911 -0.854788 -0.518817 0.012922 0.153124 -0.922995 -0.353035
-0.577741 -0.812855 -0.0740391 0.396683 -0.895789 0.200509 0.70818 -0.682192 0.181918
-0.428481 -0.895219 0.122423 -0.476731 0.800909 0.362316 -0.473672 0.879163 -0.0520321
-0.258292 0.926072 0.275092 0.25796 -0.51592 -0.816874 -0.742338 0.652228 -0.153402
--0.631057 0.308815 -0.711618 0.759959 -0.643043 0.094647 -0.43105 0.826179 -0.3628
-0.781053 -0.574353 -0.245103 0.325906 -0.422797 -0.845593 -0.145221 -0.875773 -0.460361
--0.250892 -0.802855 -0.540812 0.972572 -0.0342254 -0.230071 0.25179 -0.795428 -0.551268
--0.129511 -0.647553 -0.750934 0.485874 -0.85679 -0.172735 -0.682432 -0.554476 -0.476281
-0.944536 0.277064 0.176313 -0.862268 0.22419 0.454128 -0.964739 0.0639285 0.255327
--0.931844 -0.362605 -0.013577 -0.594279 -0.772562 -0.223562 0.840345 -0.541131 0.0315954
-0.337175 -0.937691 -0.083952 -0.196653 0.947336 0.252749 0.567186 0.823586 0.00258989
--0.154528 0.881383 0.446415 -0.151051 0.868543 0.472034 0.219365 0.877462 -0.426544
-0.668805 0.622144 -0.406986 -0.600171 0.493881 0.629187 0.237233 0.964443 0.116487
--0.864581 0.432291 -0.256172 0.743713 0.131362 0.655465 0.987282 -0.0806346 0.137013
--0.110199 0.539397 0.834809 -0.184052 0.94071 -0.28494 -0.806674 -0.235797 0.541919
--0.824177 0.524476 0.213675 -0.79624 0.498977 -0.342088 0.18834 0.690065 -0.698813
--0.0866422 0.880174 -0.466676 -0.647615 0.674422 -0.354612 0.766549 -0.618904 0.171349
--0.874694 0.35783 -0.326906 0.500186 0.0218937 -0.865641 -0.428552 0.220262 -0.876258
--0.633891 0.465654 -0.617534 0.317038 0.462008 -0.828273 0.45888 0.209489 -0.863449
--0.172331 0.623042 -0.762969 -0.436479 0.421808 -0.79471 -0.436819 0.422177 -0.794327
--0.204932 0.63529 -0.744587 -0.551799 0.469195 -0.689474 -0.0814733 0.537724 -0.839175
-0.0705667 0.650782 -0.755978 0.0268041 0.830926 -0.555737 -0.403932 0.580653 -0.706881
--0.45241 0.407383 -0.793325 -0.706872 -0.115358 -0.697872 0.312871 0.368741 -0.875295
--0.781045 0.292892 -0.551528 -0.643803 0.366898 -0.671493 -0.55345 0.675872 -0.486713
--0.674034 0.26364 -0.690052 -0.620867 0.46565 -0.630629 -0.648835 0.511203 -0.563635
-0.414562 0.910015 -0.00337042 -0.370703 0 -0.928751 -0.160067 0.101506 -0.981873
-0.535569 -0.494819 -0.684339 0.619153 -0.755367 -0.21464 -0.649905 -0.400235 -0.646093
-0.720422 -0.432253 -0.542355 0.408888 -0.713695 -0.568726 -0.712135 -0.577994 -0.39848
-0.83064 -0.139465 -0.539061 -0.202699 -0.719788 -0.663942 0.873608 -0.0513887 -0.48391
--0.943873 -0.330306 -0.00130685 0.917684 0 -0.397311 -0.936431 -0.211366 -0.280038
--0.635925 0.236485 -0.734626 -0.786572 -0.0172602 -0.617258 -0.806092 0.307588 -0.505575
--0.625074 0 -0.780565 -0.0319201 0.516273 -0.855829 -0.0713707 0.0356854 -0.996811
--0.537102 -0.559349 -0.631387 -0.3801 0.471936 -0.795488 -0.749884 -0.326389 -0.575451
--0.735108 -0.385716 -0.557529 -0.736127 0.114607 -0.66707 -0.65306 -0.483595 -0.582794
-0.477285 0.369327 -0.797369 -0.747115 -0.0498077 -0.662826 -0.205603 0.699771 -0.68414
--0.364781 0.674051 -0.642331 -0.522794 -0.459039 -0.71831 0.185773 0 -0.982593
--0.882847 0.0509335 -0.46689 0.671071 0.0447381 -0.740042 -0.52554 -0.21146 -0.824071
--0.497897 -0.342304 -0.796823 -0.436782 -0.288301 -0.852117 0 -0.185408 -0.982662
--0.723993 -0.00559789 -0.689784 -0.454739 0 -0.890625 -0.297124 0 -0.954839
-0.22072 0.839394 -0.496689 -0.258042 0.642919 -0.721158 -0.402083 0.467097 -0.787496
-0.133029 0.768613 -0.62573 0.131468 0.821464 -0.5549 -0.278108 0.661446 -0.696523
--0.835613 -0.33955 -0.431807 -0.151789 -0.893317 -0.423019 -0.863961 -0.2239 -0.451044
--0.839578 -0.423524 -0.340199 0.867114 -0.00530345 -0.498082 -0.904054 0.138161 -0.404472
-0.180169 -0.750704 -0.635596 0.0305688 -0.730056 -0.682704 -0.423027 -0.687823 -0.58987
--0.492764 0.236527 -0.8374 0.822643 -0.364328 -0.43649 0.0683147 -0.959512 -0.273259
--0.997079 -0.0487461 0.0587908 0.0222418 -0.578286 -0.815531 -0.76425 -0.390849 -0.51299
--0.5314 -0.442833 -0.722159 -0.177164 -0.500682 -0.847308 0.547588 -0.305631 -0.778933
-0.474633 -0.870765 -0.128421 0.397145 -0.723829 -0.564223 -0.0380044 -0.547264 -0.836097
-0.395116 -0.531363 -0.749358 -0.11476 -0.774954 -0.621511 0.0101811 -0.897637 -0.440617
-0.883631 -0.239682 -0.402181 0.978105 -0.204513 0.0385314 -0.435043 -0.791438 -0.429375
--0.333969 0.0811067 -0.939088 0.428472 -0.265245 -0.863746 -0.508177 0.182626 -0.841668
--0.772113 -0.15745 -0.615672 -0.470757 0.262312 -0.842366 0.0920962 0.446937 -0.889812
--0.0210331 0.57922 -0.8149 -0.634238 0.27247 -0.723535 0 -0.180093 -0.98365
-0.621395 -0.517209 -0.588527 -0.127733 0.58088 -0.803905 -0.261064 0.124687 -0.957235
--0.713487 -0.249232 -0.654844 -0.919597 -0.038546 -0.390967 -0.826018 -0.0225278 -0.563194
--0.636143 -0.373933 -0.674904 0.519706 -0.377321 -0.766508 -0.0341066 0.0341066 -0.998836
-0.177046 -0.481884 -0.858162 0.488382 -0.586761 -0.645906 -0.387423 -0.819548 -0.422191
--0.628337 0.7181 -0.299208 -0.97997 -0.0544428 -0.191558 0.288155 -0.288155 -0.9132
--0.328004 -0.770429 -0.546674 -0.319041 -0.738927 -0.593464 0.0421692 -0.685708 -0.726655
-0.598082 -0.642938 -0.478465 0.354843 -0.593661 -0.722255 -0.11671 -0.786079 -0.607008
-0.925631 -0.0970419 -0.365773 0.492707 0.854026 0.166973 -0.557297 0.827398 -0.0695197
-0.46927 -0.210363 -0.857632 0.570595 -0.423409 -0.703666 -0.117946 -0.451565 -0.884408
-0 -0.179487 -0.98376 0.846403 -0.50626 -0.165238 -0.644232 -0.759273 0.0920331
-0.812889 -0.452536 0.366638 -0.509134 -0.83879 0.192909 0.218713 -0.132745 -0.966718
--0.200509 -0.200509 -0.958954 0.192226 -0.973665 -0.122579 -0.516551 -0.856214 0.00846805
--0.0354702 -0.986073 0.162488 0.409464 0.394299 -0.82272 0.13231 -0.573343 -0.808561
--0.490945 -0.499693 -0.713638 -0.106641 -0.00784122 -0.994267 -0.409572 -0.253756 -0.876276
-0.625638 -0.687389 -0.368882 0.494146 -0.484163 -0.722085 -0.3461 -0.359944 -0.866404
--0.172447 -0.172447 -0.969806 -0.318335 -0.695493 -0.644167 -0.224632 -0.703848 -0.673897
-0 -0.587764 -0.809032 0.153572 -0.661029 -0.734477 0.00854327 -0.341731 -0.939759
--0.575751 -0.589459 -0.566612 0.488449 -0.636069 -0.597355 -0.30195 -0.433514 -0.849054
-0 -0.175069 -0.984556 0.230173 -0.0886227 -0.969106 0.451094 0.263138 -0.852803
--0.256417 0.682522 -0.684408 -0.349964 -0.817377 -0.457625 0.509858 -0.509858 -0.692884
-0.0929787 0.0929787 -0.991317 0.735538 0.465457 -0.492274 -0.726582 -0.59617 0.341556
-0.785634 -0.583274 -0.206328 0.139874 0.963575 0.227943 -0.602536 -0.763212 0.233363
--0.279498 -0.792159 -0.542554 -0.210776 -0.321124 -0.923284 -0.19265 -0.17179 -0.966113
-0.0960711 -0.148345 -0.984258 0.349424 -0.255216 -0.901536 0.644899 -0.12441 -0.754074
-0.858479 -0.280656 -0.429239 -0.82493 -0.434405 -0.361638 0.731604 -0.491344 -0.472585
--0.141882 -0.141882 -0.979663 0.208143 -0.976118 -0.0622036 0.728672 -0.613151 -0.305094
--0.340743 -0.908647 -0.241359 -0.0150653 -0.858722 -0.51222 -0.184493 -0.798436 -0.573117
-0 -0.185408 -0.982662 -0.423191 -0.423191 -0.801136 0.423718 -0.501943 0.754
-0.914698 -0.0531801 0.400624 -0.0418217 0.888712 0.456554 -0.968621 0.0284889 0.246903
-0.0250435 -0.751305 0.659479 -0.358429 0.907385 -0.219503 -0.996783 0.0419208 -0.0683153
--0.119944 -0.420374 -0.899388 0.934608 -0.142688 0.325805 -0.0671048 -0.971254 0.228392
-0.502134 0.819272 0.276866 0.616506 0.616506 0.489735 -0.0298865 0.999538 0.00553454
-0.289798 0.955825 -0.049147 -0.747094 0.516174 -0.418825 0.275001 -0.910122 0.309922
--0.299544 -0.948843 0.0998479 0.710932 -0.640053 0.291389 0.798598 -0.466295 0.38054
--0.0722302 -0.996777 -0.0349113 -0.268286 -0.960636 -0.0721198 -0.0161611 -0.985825 0.166998
-0.622713 0.178399 0.761842 -0.271273 0.883079 0.38286 0.113325 0.869937 -0.479965
-0.531963 0.0115144 0.846689 -0.354269 0.919412 0.170808 -0.784283 0.61792 0.0554544
--0.976588 0.151139 0.153076 -0.972625 0.196841 -0.123508 -0.72475 0.102208 0.681389
-0.828698 -0.510537 -0.229372 -0.790963 -0.0903958 0.60515 0.894124 0.0286272 0.446903
--0.275851 0.927108 0.253727 -0.542035 0.832958 0.111265 0.729044 -0.557877 0.396572
--0.639486 -0.689102 0.340876 -0.924675 -0.377418 0.0503224 -0.219365 -0.731218 -0.645909
-0.891443 0.432647 -0.134707 -0.142372 0.968598 0.203833 -0.235422 0.881707 0.408864
--0.814427 0 0.580265 -0.470187 -0.606294 0.641352 0.645084 -0.763198 0.0373523
--0.763394 0.643827 0.0521193 0.716086 0.461247 0.5239 0.849921 -0.449344 -0.275179
--0.914794 -0.333429 0.227986 0.963175 -0.157253 0.218095 0.969073 0.199515 0.145225
--0.0623225 0.996256 0.0599139 0.674192 -0.244272 0.696991 0.371349 0.516538 0.771549
--0.569795 0.776663 -0.268566 -0.718254 0.64363 -0.264293 -0.718274 0.517692 -0.464841
-0.480531 -0.835574 0.266282 0 0.890064 0.455835 0.365912 0.643118 0.672687
-0.832113 0.421851 0.360041 0.954546 0.130835 0.267813 -0.72099 0.674474 0.158928
-0.476716 -0.762746 -0.43699 -0.21813 -0.916637 -0.334956 0.858905 0.394416 0.326678
--0.816859 0.315719 0.482766 0.417419 -0.849571 0.322477 -0.454239 -0.883701 -0.112871
--0.561202 -0.810967 -0.165483 0.394132 0.878868 -0.268795 0.964523 -0.0595029 0.257206
-0.964573 -0.123663 0.233036 -0.769838 0.620974 0.147446 -0.859744 0.510178 0.0236194
--0.424986 -0.786224 -0.448596 0.89496 0.356203 -0.268636 -0.693899 0.696463 0.182875
--0.0058703 -0.817929 -0.57529 -0.113789 -0.785143 -0.608771 -0.773993 0.456103 0.43921
-0.312699 0.799121 0.513445 -0.111902 0.973338 0.200228 -0.576003 0.805213 -0.1409
--0.982313 -0.133382 0.131417 0.395951 -0.905306 -0.153767 0.498366 -0.835842 0.230216
--0.220191 0.790099 0.572066 0.624134 0.271363 0.732679 -0.419525 0.483477 0.768277
-0.632047 0.765289 0.121854 0.196978 0.875974 0.440305 -0.79877 -0.26753 0.538883
-0.297715 -0.952687 0.0612688 -0.580683 -0.763926 0.281468 -0.0227317 -0.941743 -0.335564
--0.601703 -0.791714 -0.105562 0.100041 -0.969632 -0.223169 -0.721377 0.55087 -0.41971
-0.985732 0.0490414 0.161019 -0.556792 0.82601 0.0876998 -0.596851 -0.750327 0.284215
-0.878503 0.459525 -0.130649 0.059197 -0.980263 -0.188628 -0.371376 0.00884229 -0.92844
-0.57772 -0.804488 -0.137981 0.107465 -0.0179108 -0.994048 -0.686893 0.482398 -0.543572
--0.240862 0.51314 0.823816 -0.926045 0.37362 -0.0533743 -0.412635 -0.909913 0.0423215
-0.906899 -0.378443 -0.185244 0.48306 -0.852947 -0.197825 -0.943578 0.229741 0.238493
-0.536044 -0.838564 -0.0973017 -0.818782 -0.438633 -0.370401 0.867657 -0.495804 -0.0367262
-0.569369 -0.765426 -0.299904 -0.202798 0.916731 0.344205 0.446501 0.788353 0.423246
--0.736485 0.675257 0.0402355 0.984051 0.140318 0.109339 0.943237 0.210987 0.256494
--0.579521 0.788357 0.206516 -0.71773 0.239243 0.653932 -0.987262 -0.0239204 0.157295
-0.0166855 -0.920734 -0.389833 -0.751227 0.659395 0.0292666 0.516148 0.842823 -0.152449
--0.329945 0.942416 0.0546615 0.970761 0.142024 -0.193528 -0.0254645 0.96765 0.251007
-0.98907 0.121111 -0.0841046 0.723093 0.61011 -0.323886 -0.933481 -0.283745 -0.21932
--0.798414 0.562519 -0.214725 -0.441277 0.375903 -0.814845 -0.242647 -0.0808824 -0.966737
--0.853984 0.204956 -0.478231 0.989226 -0.0613474 -0.132919 -0.277813 0.909421 -0.309472
--0.0427886 0.996974 -0.064896 -0.568726 0.820137 -0.0626494 0.181231 0.9834 -0.00891299
--0.461182 -0.733552 0.499212 -0.987359 0.0658239 0.144186 -0.90507 -0.318266 0.282053
--0.993195 0.116088 -0.00931568 0.0815103 0.151376 -0.98511 -0.949476 0.291748 -0.115663
--0.0710296 0.756256 -0.650408 0.114096 0.932051 -0.343895 -0.480534 0.439512 -0.758891
--0.736143 0.313542 -0.59982 -0.234798 0.626128 -0.743527 -0.412541 0.164372 -0.895987
--0.925036 0.143975 -0.351538 0.66157 0.0374474 -0.748948 -0.185527 0.272833 -0.944003
-0.5317 0.745858 -0.401237 0.0477638 0.987686 -0.148977 -0.505042 0.603245 -0.617274
--0.0350279 0.612227 -0.789905 0.6321 0.330034 -0.70109 0.771794 0.00627475 -0.635841
--0.650412 0.459625 -0.604739 -0.0762216 -0.70505 -0.70505 -0.496523 -0.553814 -0.668397
--0.165255 -0.694072 -0.700682 -0.792172 0.433567 -0.429515 -0.423179 0.215207 -0.880117
-0.0894459 0.673826 -0.733456 -0.895594 0.0334801 -0.443612 -0.887991 0.426662 -0.171554
--0.144472 -0.764993 -0.627626 -0.664857 -0.441506 -0.602526 -0.766713 -0.606981 -0.209104
--0.857561 -0.0751252 -0.508867 -0.282113 0.408106 -0.868252 0.0240754 -0.214672 -0.976389
-0.542341 0.198275 -0.816427 0.629121 0.351881 -0.693099 0.361147 -0.208119 -0.908988
-0.157398 -0.724033 -0.671567 -0.371133 -0.871357 -0.320932 0.406464 -0.468768 -0.784247
-0.312422 -0.551724 -0.7733 -0.455835 -0.0267213 -0.889663 -0.228108 -0.409086 -0.883525
--0.497743 -0.617619 -0.608932 -0.409339 -0.7567 -0.509752 -0.729704 -0.508382 -0.457252
-0.656527 0.025579 -0.753869 0.760126 0.302839 -0.574889 -0.842957 -0.469264 -0.263088
-0.54045 -0.237798 -0.807072 -0.629224 -0.641809 -0.438359 0.827071 0.109236 -0.551381
--0.373767 -0.289837 -0.881075 0.893271 0.0915583 -0.440096 -0.311345 0.166368 -0.935621
--0.205981 -0.137321 -0.968873 -0.694872 0.0534517 -0.717144 -0.448149 0.0206045 -0.893722
--0.499994 0.314238 -0.807007 -0.392693 0.145716 -0.908052 -0.767328 -0.00537847 -0.641233
--0.138503 -0.246228 -0.959265 -0.100131 0.807082 -0.581887 -0.816115 0.0429534 -0.576292
--0.830445 -0.337487 -0.443241 -0.335017 0.00744482 -0.942183 -0.423305 -0.100787 -0.900364
--0.297061 -0.0206124 -0.954636 0.718451 0.0671799 -0.692326 0.797564 0.118416 -0.591498
--0.604608 -0.763446 -0.227155 -0.186032 -0.677774 -0.711347 0.324318 -0.746686 -0.580756
--0.450544 -0.0813013 -0.889044 -0.457855 -0.848157 -0.266456 -0.287508 -0.713168 -0.639321
-0.401061 -0.749153 -0.527181 0.178405 -0.766553 -0.616902 0.147486 -0.516902 -0.843244
-0.332688 -0.266844 -0.904496 -0.480452 0.182781 -0.857763 0.699503 -0.14626 -0.699503
--0.652521 -0.756581 0.0424404 0 0 -1 0.574039 -0.732031 -0.366893
-0.0215465 0.797221 -0.603303 -0.366363 0.838326 -0.403718 0.540566 -0.0766156 -0.837806
-0.293806 -0.321788 -0.900073 0 -0.805683 -0.592347 0.58472 -0.577319 -0.569917
--0.643565 0.213155 -0.735112 -0.759482 -0.165432 -0.629142 -0.483722 0.668977 -0.564342
--0.206678 0.792266 -0.574106 -0.0288845 0.788133 -0.614827 -0.55797 0.52973 -0.638792
-0.759035 0.185262 -0.624135 0.363141 0.276421 -0.889786 0.481804 0.0161499 -0.87613
--0.942707 -0.306703 0.13129 0.0975776 -0.780621 -0.617341 0.408642 -0.207282 -0.888845
--0.362616 0.442157 -0.82037 0.172079 0.465394 -0.868215 0.544485 0.69033 -0.476425
--0.365771 -0.802035 -0.472177 -0.13498 -0.781247 -0.609454 -0.589435 -0.63244 -0.502579
-0.365376 0.152051 -0.918358 0.857891 -0.0919169 -0.505543 0.483016 -0.438554 -0.75787
-0.479833 -0.125979 -0.868268 0.428564 -0.767844 -0.476182 -0.669657 -0.685368 -0.286061
--0.584652 -0.733349 -0.346961 -0.630364 0.775832 0.0269386 0.702414 0.702414 -0.115015
-0.587823 -0.182105 -0.788227 0.762597 -0.0649019 -0.64361 0.574273 -0.19292 -0.795608
-0.452318 -0.452318 -0.768646 -0.568191 -0.409674 -0.71367 -0.552606 -0.566003 -0.611774
--0.552647 -0.82897 -0.0859673 0.761816 0.128864 -0.634847 0.379944 0.293593 -0.877181
--0.825219 0.5639 0.0320919 -0.449142 -0.156417 -0.879662 0.72444 -0.10363 -0.681503
-0.324992 -0.181527 -0.928131 -0.540602 -0.422114 -0.727715 0.51775 -0.285291 -0.806563
--0.554546 -0.284383 -0.782052 -0.133974 -0.173529 -0.975673 -0.330467 -0.165233 -0.929241
--0.244907 0.379966 -0.89199 -0.024013 -0.515648 -0.856464 0.0603724 -0.603724 -0.794904
-0.561852 -0.494688 -0.663028 -0.432075 0.0652188 -0.899476 -0.757459 0.269319 -0.594746
--0.188802 0.0917038 -0.977724 -0.253825 0.779287 -0.572961 0.263356 -0.784216 0.561826
-0.60898 -0.750797 0.255827 0.276018 0.552036 0.78681 -0.513996 0.747631 0.420542
--0.532352 -0.760503 0.371801 -0.133219 -0.666095 -0.733873 -0.589831 0.518208 -0.619322
-0.124862 -0.264413 -0.956293 0.165416 -0.478328 -0.862461 -0.875574 0.149034 -0.459521
--0.543368 0.123027 -0.830431 -0.497284 0.0252588 -0.86722 0.764705 -0.0791655 -0.6395
-0.607932 -0.645026 -0.46299 -0.581591 0.803149 -0.129242 -0.424753 0.817144 0.389694
-0.83265 0.550926 0.0563447 -0.270036 0.938696 0.214314 0.149199 -0.0239454 -0.988517
-0.194734 -0.301523 -0.933361 -0.110504 0 -0.993876 -0.256578 -0.843645 -0.471625
--0.400846 -0.754534 -0.519616 0.786517 -0.32386 -0.525837 0.555913 -0.526654 -0.643115
--0.261925 -0.641027 -0.721443 -0.612827 0.779962 -0.126898 0.514418 -0.163678 0.841774
--0.0646994 -0.139931 -0.988045 0.646157 -0.332785 -0.68683 0.913205 -0.145859 -0.380502
-0.0755444 -0.522145 -0.849504 -0.806435 0.280012 -0.520823 -0.354884 0 -0.93491
--0.181037 -0.929324 -0.321844 0.445548 -0.661135 -0.603645 -0.208956 0.46676 0.859344
--0.704145 0.631129 0.325356 0.109766 -0.259888 -0.95938 -0.788177 -0.498977 -0.360276
--0.401809 -0.385644 -0.830559 0.568719 -0.290243 -0.769622 0.549939 -0.46946 -0.690778
--0.363265 -0.690573 -0.625418 0.910828 -0.27297 -0.309644 -0.142386 0.987209 -0.0717203
-0.699557 -0.679852 0.220049 -0.853627 0.284542 0.436298 0.324002 -0.616962 -0.717203
--0.582605 -0.543416 -0.604376 -0.0985291 0.239285 -0.965937 0.0603236 -0.475492 -0.877649
--0.25542 0 -0.96683 0.481442 -0.813153 -0.327104 -0.518022 -0.84937 -0.101115
--0.971218 -0.194552 -0.137422 0.461727 -0.887022 -0.000247841 -0.175985 -0.984321 -0.0119312
--0.151461 -0.731338 -0.664984 -0.408019 -0.848249 -0.337629 0.0300072 -0.49762 -0.866876
-0 -0.25542 -0.96683 0.232757 -0.411802 -0.881047 -0.362132 -0.641275 -0.676482
-0.606449 -0.741216 0.287783 0.293729 -0.917009 0.269849 -0.160886 -0.326504 -0.931403
--0.535961 -0.375173 -0.756301 -0.408275 -0.898718 0.160057 0.104298 -0.208596 -0.972425
--0.271329 -0.407547 -0.871944 0.235196 -0.0306778 -0.971464 -0.0768463 0.922156 0.379109
--0.694839 0.191197 0.693284 -0.629876 -0.404648 0.66296 0.171286 -0.236777 -0.956346
-0.16836 -0.274186 -0.946825 0 -0.724005 -0.689795 -0.0958648 -0.636026 -0.76569
--0.0688492 0.907334 -0.414734 0.0720212 0.916019 -0.394616 -0.300483 0.832339 -0.465749
-0.445947 -0.876246 -0.182551 0.0776202 -0.993539 -0.0827949 -0.548156 -0.754604 0.360691
-0.0170736 0.273177 -0.961812 -0.335984 -0.0912549 -0.937437 -0.441987 -0.338543 -0.830684
-0.126111 -0.693611 -0.709225 0.635762 0.771252 0.031267 -0.163299 0.701899 -0.693304
--0.387619 0.113702 -0.914781 -0.6267 -0.586958 -0.512569 0.636046 0.158279 -0.755244
-0.482455 0.0331458 -0.875293 0.714132 -0.0892666 -0.694296 0.779214 -0.25568 0.572235
--0.418474 -0.89534 -0.152467 0.292683 -0.097561 -0.951219 -0.206772 -0.935644 -0.286035
-0.134147 0.972568 -0.190042 0.0410159 0.750004 0.66016 0.200766 0.790517 0.578597
-0.325909 0.678978 0.657854 0.209063 0.928485 -0.306933 0.890858 -0.206446 0.404663
-0.839116 0.427626 0.336184 0.129066 0.530605 0.837735 0.801616 0.248904 0.543561
-0.290777 0.717249 0.633247 -0.555659 0.782755 0.280246 -0.981049 0.178373 0.0756732
-0.535912 -0.602901 0.591024 -0.613857 -0.371237 0.696679 -0.868085 -0.0190788 0.496049
-0.637757 -0.699839 0.3217 0.715899 0.166664 0.678021 -0.941787 -0.0425323 -0.333508
--0.390771 0.882853 -0.260514 -0.660552 0.590438 -0.46374 0.623763 0.733839 0.269074
-0.0144218 -0.973473 0.228346 -0.923465 -0.259298 -0.282802 0.602693 0.609244 0.515346
-0.646749 -0.729533 0.222482 -0.389103 -0.915112 -0.105682 -0.557366 -0.804395 -0.20565
-0.0460165 -0.966347 0.253091 0.473718 0.702629 0.530946 -0.36819 0.911494 0.183346
-0.920294 -0.0626903 0.386172 0.566078 0.649209 0.508019 -0.400389 0.883808 0.242017
-0.107032 0.791103 0.602246 0.851886 -0.387471 0.352357 -0.698937 0.712301 -0.0641472
-0.436605 0.703781 -0.560418 0.827097 -0.232813 0.511575 0.00514209 0.742175 0.670186
--0.97065 0.0500804 -0.235226 -0.994384 0.057813 -0.0886466 -0.805787 0.401439 0.435377
-0.0855229 0.958325 0.27258 -0.829449 0.32249 0.456086 -0.105929 0.658274 0.745288
--0.670837 0.213448 0.710223 0.937375 0.124064 0.325478 0.88404 0.276743 0.376678
--0.463262 0.8165 0.344551 0.76058 -0.645527 0.0693831 0.982153 -0.0637072 -0.176965
-0.710444 -0.647925 -0.274705 -0.120542 -0.98945 0.0803614 -0.340571 -0.84512 0.412048
-0.745192 0.628883 -0.2218 -0.892643 -0.241861 0.380384 0.497432 0.834363 0.237485
-0.792949 0.109914 -0.599292 0.509942 0.747914 -0.424951 -0.0398567 0.99841 -0.0398567
--0.185057 0.981606 0.0469347 0.215159 0.66063 0.719218 0.924525 -0.365326 0.108587
--0.919617 -0.391427 0.0330119 -0.0499747 -0.998357 0.0280161 -0.249731 -0.968003 0.0245767
-0.726701 -0.0641207 -0.683954 0.208396 -0.968932 -0.133201 0.171561 -0.981113 -0.0893546
-0.983822 -0.168166 -0.0617616 0.645454 0.368348 0.66911 -0.449547 0.877687 0.166053
--0.137044 -0.939732 -0.313244 0.663553 -0.744598 -0.0726025 -0.421637 -0.737865 -0.527046
-0.942883 0.0574669 0.328129 0.905207 -0.373301 0.203091 -0.257075 0.956559 0.137505
--0.129518 0.979908 0.151673 0.757905 -0.606733 -0.239697 -0.864204 -0.251266 -0.435909
--0.279377 0.95525 0.0971923 0.164566 0.919298 0.357505 0.416017 0.886297 0.203487
--0.505457 0.315911 0.80294 -0.466701 0.132768 0.874393 0.656575 -0.366616 0.659168
-0.272729 0.873174 0.403962 -0.829695 -0.140709 0.540191 -0.801073 -0.563995 0.200476
-0.857995 -0.472093 -0.202419 -0.908661 0.147067 0.390777 -0.0739412 -0.985882 0.15023
--0.906681 0.0546992 -0.418256 -0.676726 0.502087 -0.53847 0.909123 0.284535 -0.304198
--0.69733 -0.686764 0.205149 -0.554284 -0.832311 0.00531262 0.766618 -0.622362 -0.157995
--0.0734825 -0.981516 0.176708 -0.18421 -0.97222 -0.144412 0.578781 -0.720523 0.381916
-0.980987 -0.158048 -0.112632 -0.663863 0.743847 -0.0773174 0.00736467 -0.979502 -0.201301
-0.974387 0.111722 -0.19516 -0.563754 -0.317517 -0.762472 0.821896 -0.115656 0.557773
-0.840799 -0.450428 0.300285 -0.653473 0.756901 -0.00861895 -0.647625 0.761127 0.0356083
-0.422265 0.777187 0.466555 -0.721025 0.675819 0.152945 -0.692976 0.702392 0.162573
-0.722882 -0.684516 0.0942304 0.541656 -0.0492415 0.839157 0.713851 -0.695309 0.0834371
-0.879118 0.295715 0.37377 0.96499 -0.236752 0.112882 0.730211 -0.683181 -0.00742588
--0.870976 0.491082 0.0154428 -0.918998 0.370755 -0.134103 -0.95269 -0.0790501 -0.293485
-0.950151 0.160415 0.267358 -0.632724 0.764542 0.12303 0.371687 -0.877865 -0.301995
--0.746607 -0.411175 -0.522985 -0.996271 0.0379532 0.0774877 -0.973645 0.216366 -0.0721218
-0.496914 -0.819696 -0.284912 -0.945534 -0.280158 -0.16576 0.13028 0.70514 0.696997
-0.188894 -0.554088 0.810744 -0.868409 -0.169371 0.466026 0.190266 -0.874654 0.445846
--0.409669 0.718718 0.561797 -0.249379 0.892778 0.375177 -0.286159 0.950614 0.120193
-0.368298 0.909472 -0.192918 0.309305 0.565341 0.76467 -0.153646 -0.171722 0.97309
-0.920076 -0.26439 0.289066 0.866675 0.454878 -0.204843 -0.161646 0.971446 -0.173678
--0.313982 0.921559 -0.228351 0.540462 0.808422 0.23314 -0.935596 -0.165529 0.311865
--0.315534 0.919775 -0.23335 0.123151 0.985211 -0.119136 0.423102 -0.883142 0.202597
--0.814527 -0.550356 0.183452 -0.870338 0.490779 0.040604 0.635008 0.759741 0.139853
-0.346862 0.923006 0.166572 0.138148 0.989628 -0.0393882 -0.835204 -0.528989 0.150352
-0.256576 -0.837052 0.483231 0.41113 -0.828846 0.379456 0.339057 -0.856564 0.389023
-0.0881929 -0.264579 0.960323 0.89914 -0.167889 0.404178 0.0615907 0.588961 0.805811
--0.126984 0.991592 0.0248987 -0.87468 0.471182 0.113674 0.250648 -0.943617 0.216246
--0.214176 -0.942376 0.257012 -0.975106 0.0286796 0.219877 -0.713099 0.693524 0.102537
--0.907426 0.36297 0.211733 -0.70946 0.701444 0.0681402 0.0514998 -0.885796 0.461209
-0.477187 -0.827124 0.296916 -0.717137 0.358569 0.597614 0.403604 -0.861021 0.309429
--0.291659 0.556803 -0.777757 -0.986657 -0.130252 0.0976888 0.69208 0.0768978 -0.717713
--0.666319 -0.0888426 -0.740355 0 0.999989 0.00476185 -0.22439 0.940992 -0.253344
--0.717168 0.649934 -0.251507 -0.514956 0.836804 -0.185956 -0.407553 -0.584159 -0.701897
--0.847143 -0.331942 -0.414927 0.0431467 0.848553 -0.527349 -0.519903 0.852641 -0.0519903
--0.10897 0.796083 -0.595296 0.329238 -0.93284 -0.146328 -0.280591 -0.795009 -0.5378
-0.391983 0.744768 -0.540065 -0.525994 0.713849 -0.462332 -0.187814 -0.77597 -0.602159
-0.557839 0.424072 -0.713427 -0.844915 -0.455553 -0.28034 0.0729597 -0.496126 -0.86518
--0.00704243 0.640861 -0.767625 -0.481616 0.854254 -0.195693 -0.703482 0.572602 -0.420999
--0.484667 -0.274155 -0.830624 0.204732 0.584948 -0.784806 -0.816358 -0.19948 -0.542004
-0.313793 -0.926031 -0.209764 -0.685239 -0.711043 -0.157691 0.803183 -0.274421 -0.528762
-0.877625 0.0706135 -0.474119 -0.798958 -0.510612 -0.317714 0.00539076 0 -0.999985
--0.0771935 -0.439117 -0.895107 0.183726 -0.110869 -0.976705 0.668356 0.200917 -0.716193
-0.604408 -0.304476 -0.736196 -0.869006 -0.025559 -0.494141 0.623928 0.0605303 -0.779134
--0.941095 0.218178 -0.25834 -0.743661 0.40669 -0.530633 -0.294724 -0.854699 -0.427349
--0.873177 0.311768 -0.374649 0.782583 -0.0622195 -0.619429 -0.843976 -0.53427 0.047538
--0.628695 0.603547 -0.490382 0.762248 -0.31208 -0.567083 -0.861042 -0.315841 -0.398561
--0.778741 -0.507254 -0.369128 -0.42219 0.509539 -0.74975 0.172483 0.172483 -0.969793
-0.553028 -0.563979 -0.613259 0.420491 -0.591386 -0.688077 -0.59626 0.59626 -0.537538
-0 -0.143589 -0.989637 0 -0.432897 -0.901444 -0.042924 -0.126906 -0.990986
--0.556175 -0.498639 -0.664852 -0.586204 -0.103807 -0.803486 -0.5199 -0.0879433 -0.849688
--0.313539 0 -0.949575 -0.579962 -0.297416 -0.758411 -0.469937 -0.16366 -0.867396
--0.155191 -0.39592 -0.905076 -0.427715 -0.427715 -0.796316 -0.298438 -0.235307 -0.924968
--0.25542 0 -0.96683 -0.423431 0 -0.905928 -0.132191 0 -0.991224
--0.707368 -0.485599 -0.513638 -0.330467 -0.165233 -0.929241 -0.674422 -0.513411 -0.530626
-0 0.230805 -0.973 -0.0597167 0.17915 -0.982008 -0.586297 -0.377836 -0.716586
--0.172447 -0.172447 -0.969806 0.175069 0 -0.984556 -0.133423 0.222371 -0.965789
-0.643257 0.757345 0.112469 0.665527 0.744119 0.0579688 -0.947659 -0.299019 -0.11194
-0.0212536 0.17503 -0.984334 -0.0969803 0.562486 -0.8211 -0.455376 -0.885453 0.0927618
-0.982315 -0.0605536 0.177175 -0.61987 -0.783887 0.0358197 0.626527 0 -0.7794
-0 -0.195557 -0.980692 -0.498237 0.486937 -0.717393 -0.845802 -0.127289 -0.518089
-0.501584 0 -0.865109 0 -0.0480727 -0.998844 0.247475 0.247475 -0.936756
-0.171035 -0.95851 0.228047 -0.544173 -0.229125 -0.80708 0.521558 0.462619 -0.716911
--0.675914 -0.667248 0.312923 0.52245 -0.8127 0.258 -0.195557 0 -0.980692
--0.984739 -0.0599483 0.163388 0.472562 -0.836072 0.278691 0.411622 -0.886571 0.211088
--0.218638 -0.881923 0.417624 0.694576 -0.694576 0.187425 0.232311 -0.546207 -0.804791
-0.111943 -0.567709 -0.815583 0.655627 0.109967 -0.747034 -0.561904 -0.275844 -0.779855
--0.149572 0.202363 -0.967821 0.0857304 0.0857304 -0.992623 -0.296679 0.941633 0.159089
--0.446721 0.887487 0.113169 0.856361 -0.324379 -0.401775 0.576977 0.0940259 -0.81133
-0.0688846 0.251578 -0.965382 -0.172447 0.172447 -0.969806 0.300108 0.200072 -0.932688
--0.738603 0.281173 -0.612705 0.0425635 -0.998883 0.0205271 0.229846 -0.919382 0.31923
-0.126139 -0.986587 0.103614 0.124193 -0.989536 0.0734473 0.452953 0.0654266 -0.88913
--0.00508037 0 -0.999987 0.538409 0.198361 -0.819004 -0.865946 0.382366 -0.322387
--0.789659 0.0535362 -0.611205 0.93286 -0.237879 -0.270529 0.620645 -0.746713 -0.239207
-0.599293 0.724146 -0.341264 -0.732201 -0.666237 -0.141456 -0.430444 -0.901882 -0.0364397
-0.0901019 -0.95508 0.282319 0.682593 0.0374693 -0.729837 0.815201 0 -0.579178
-0.0259785 -0.929042 -0.36906 -0.71174 0.652429 -0.260312 -0.231655 -0.817109 -0.527892
-0.0174929 -0.552483 -0.833341 0.74628 -0.564577 -0.35259 0.726239 -0.0264488 -0.686933
--0.927635 0.334059 0.167029 -0.0436685 -0.375549 -0.925773 0.219376 -0.383615 -0.897058
--0.425108 0.242417 -0.872076 0.329003 0.310726 -0.891743 0.109489 0 -0.993988
-0.397227 -0.687096 -0.608366 -0.546354 -0.714462 -0.437083 0.583549 0.12799 -0.801928
-0.655027 0.154953 -0.739547 0.817504 0.099876 -0.567197 -0.278014 0.636506 -0.719422
-0.424149 0.678248 -0.600064 -0.635402 -0.394892 -0.66357 -0.390559 -0.386314 -0.835599
-0.739463 0.225398 -0.634343 0.722494 -0.125552 -0.679882 0.804525 -0.496023 -0.326649
-0.545706 -0.36951 -0.752108 0 0.132589 -0.991171 0.605665 0.223876 -0.763577
--0.284537 -0.785047 -0.550218 0.294689 -0.678677 -0.672723 0.149357 0.460874 -0.874807
-0.687954 0 -0.725754 -0.299843 -0.465393 -0.832768 0.598635 -0.603424 -0.526798
-0.731639 -0.529377 -0.429494 0.602229 -0.356157 -0.714473 0.333962 0.305576 -0.89168
--0.242339 0.314525 -0.917794 -0.497679 -0.130162 -0.857539 -0.294744 -0.126319 -0.94719
--0.428243 0.817554 0.384986 0.622071 -0.429014 -0.654962 0.326843 -0.362795 -0.87267
--0.3676 -0.197415 -0.908789 0.822263 -0.369475 -0.432865 -0.35897 0.166963 -0.918294
-0.725959 -0.436415 0.531531 0.798561 -0.293901 0.525284 0 -0.676436 0.736502
--0.604206 0.609241 0.513575 -0.231295 -0.762899 -0.603728 0.449134 -0.691834 -0.56537
--0.0518748 0.10375 -0.99325 0.602678 0.0827511 -0.793682 -0.530196 0.151803 -0.834175
-0.165497 -0.803841 0.571358 -0.444921 -0.289552 0.847469 0.783503 0.383416 0.488995
-0.483077 -0.634039 0.603847 0.163302 0.969816 0.181077 -0.1954 0.98043 0.0239965
--0.389313 0.908397 -0.152481 0.299667 -0.466149 -0.832409 0.137031 -0.236868 -0.961829
-0.601839 -0.0947777 -0.792974 -0.161495 -0.77245 -0.614199 -0.183883 -0.348838 -0.918966
--0.280702 0.573879 -0.769331 -0.487241 0.648067 -0.585325 0.643089 -0.749384 0.157672
-0.565406 -0.824767 -0.00864536 -0.911609 0.104184 -0.397635 -0.891602 -0.253777 -0.375025
-0.517288 -0.660717 -0.543936 0.525293 -0.233464 -0.818267 0.676675 0.0424282 -0.735059
--0.306654 -0.403031 -0.862282 0 -0.278157 -0.960536 0.10493 -0.314791 -0.943343
--0.172439 -0.623969 -0.762186 0.668872 -0.536069 -0.515015 0.726475 0.152053 -0.670159
--0.84123 -0.387913 -0.376637 0.59115 0.698632 -0.403057 0.823398 0.385968 -0.415987
-0.106888 0.956368 -0.271909 0.47685 0.541508 -0.692375 -0.136187 -0.00567446 -0.990667
--0.661598 -0.497522 -0.561035 0 -0.285738 -0.958308 0.843392 -0.526448 -0.107438
-0.274146 -0.609214 -0.744112 -0.468236 -0.717962 -0.515059 0.751858 0.273403 -0.599967
-0.954202 -0.148505 -0.2597 -0.734667 -0.0192657 -0.678154 0.155893 -0.568552 -0.807741
--0.430524 -0.527604 -0.732314 -0.704419 -0.351344 -0.616727 -0.941018 -0.27882 -0.191689
-0.562007 -0.589422 -0.580284 0.556402 -0.525144 -0.643926 0.979045 -0.0559454 -0.195809
--0.916496 -0.212826 -0.338733 -0.910914 -0.179862 -0.371328 0.54976 -0.326371 -0.768925
-0.823957 -0.324067 -0.46484 0.0953891 -0.317964 -0.943292 -0.738019 0.546491 -0.395823
-0.329136 -0.738063 -0.58901 0.495584 -0.650275 -0.575794 -0.760372 -0.230097 -0.607363
-0.972335 -0.152681 0.176788 -0.247391 0.965624 -0.0798036 0.227384 -0.968006 0.106113
-0.901801 -0.332075 0.276552 -0.0711611 -0.947658 0.311257 0.140252 -0.918653 0.369331
--0.621543 -0.779547 0.0774018 0.91459 0.250573 -0.317392 0.804573 -0.378622 -0.457502
-0.671444 -0.400009 -0.623824 0.293508 0.905397 -0.306774 -0.14704 0.974141 -0.171547
--0.769258 -0.415815 0.485118 -0.813039 0.492103 0.31113 -0.745524 0.635176 0.201857
-0.0947376 -0.720748 -0.686692 0.334992 -0.937977 -0.0893311 -0.0170181 -0.991306 0.130472
-0.186891 0.409954 -0.892754 0.298121 0.95278 -0.0577442 -0.564954 0.695328 -0.444237
--0.285975 -0.222425 -0.932065 0.833103 0.484642 0.266575 0.559668 0.822328 0.102707
-0.82239 0.216711 0.526033 -0.859304 -0.394815 -0.325142 0.870448 0.387098 0.304099
-0.326204 -0.820714 0.469062 -0.272914 -0.94649 0.172265 -0.307926 -0.835799 0.454557
--0.377904 -0.920267 0.101474 0.379991 0.923864 0.0456229 0.27047 0.959923 0.0734368
--0.907951 0.36318 0.209104 -0.54294 -0.827151 -0.145045 -0.567032 -0.808855 -0.155656
-0.860864 0.479826 -0.16935 -0.656845 0.749181 -0.0853409 0.339534 0.881557 0.327985
-0.0530097 0.689127 0.722699 -0.67747 0.164435 0.716935 -0.790441 -0.234205 0.565995
-0.0322058 0.955438 -0.29343 -0.590012 0.590012 -0.551156 0.884118 -0.463081 -0.0623758
--0.67414 0.735736 -0.0650186 -0.91007 0.201826 0.361991 -0.414751 0.582894 0.698725
-0.775483 -0.178623 0.605574 0.1426 0.901463 0.408692 -0.895211 0.0354038 0.444234
-0.494864 0.345619 0.797281 0.151667 0.933473 0.325 0.494524 0.450187 0.743491
--0.11886 0.984361 -0.13002 -0.742923 0.309996 -0.593269 -0.826573 -0.275524 -0.490778
--0.713162 -0.665618 -0.219892 0.107999 -0.862893 0.493712 -0.668426 -0.42153 0.612796
-0.732081 0.0170251 0.681005 -0.761813 0.627981 0.158997 -0.60463 0.763136 0.228136
-0.814006 -0.0307172 0.580043 0.886447 0.0448204 0.460654 0.430911 -0.899216 0.0756766
--0.834017 -0.476581 -0.278006 -0.764471 -0.420901 0.488289 0.924827 -0.288031 0.248461
-0.450952 0.742645 0.495097 0.305142 0.933735 0.187154 -0.0974951 0.822038 0.561025
--0.171133 0.677401 0.715431 0.820962 -0.56521 0.0809879 0.790612 -0.611033 0.0396472
--0.853855 0.492772 -0.167656 0.646857 0.757603 -0.0872544 -0.877944 0.231183 0.419248
-0.781429 0.603208 0.159713 0.123034 0.954677 0.271024 -0.602238 0.663367 0.444132
-0.34682 0.829648 0.437492 -0.613503 0.560385 0.556402 -0.930951 -0.131847 0.340508
-0.912091 -0.165588 0.375061 -0.143247 0.962328 0.231093 0.527443 0.704356 0.475065
--0.73662 0.673403 -0.0626066 0.625738 -0.779689 0.0231755 -0.976936 0.0585186 -0.205357
--0.89319 -0.443772 0.0726446 -0.912663 -0.0641022 0.403654 -0.90457 -0.120245 0.409015
--0.965814 -0.207253 0.155725 0.858966 -0.460974 0.222893 0.701885 -0.712257 0.00691512
--0.0340011 -0.827361 -0.560641 -0.77167 -0.338782 -0.538287 -0.920225 -0.319336 -0.226298
--0.732257 -0.679953 -0.0382439 -0.334789 -0.932627 -0.134624 0.981843 0.0730674 -0.175057
-0.983404 0.0459665 -0.175508 0.718093 0.695021 0.0358886 0.456378 0.889457 0.0242122
--0.1093 0.976869 0.183793 0.556377 -0.828232 0.0669081 0.797056 -0.599337 -0.0741447
--0.275749 0.624835 -0.730441 0.548589 -0.822883 -0.148032 -0.300049 -0.862642 -0.40721
--0.0534147 -0.986391 -0.155496 0.823127 0.469235 0.319814 0.476461 0.682057 0.554783
-0.120242 0.901814 0.415057 -0.969943 -0.0365535 0.240573 0.530243 0.845 -0.0694078
-0.963615 0.235028 -0.127307 -0.222518 -0.971662 -0.0797357 0.242703 0.955643 -0.166858
-0.707656 0.647572 0.282617 0.86375 0.462908 0.199128 0.730136 0.380012 0.567884
--0.908267 0.17841 0.378445 0.897266 0.327638 0.295917 0.62797 0.65202 0.424882
--0.969913 -0.13204 -0.204533 0.309728 0.939509 -0.14626 -0.584816 0.811083 -0.0116035
--0.992025 0.114754 0.0521341 -0.201264 0.967781 -0.151305 -0.487205 0.867834 -0.097441
-0.836936 0.531264 -0.131514 0.742367 0.667217 -0.060933 -0.217208 -0.87413 0.434416
-0.306422 -0.94591 0.106581 0.252596 -0.8055 0.536064 0.24317 -0.940582 0.23701
-0.939034 0.195763 -0.282652 -0.749052 0.542011 -0.380979 0.921365 0.165175 -0.351857
-0.740634 -0.384329 -0.551138 -0.363888 -0.907528 -0.209711 0.17328 -0.958524 -0.226288
--0.30323 -0.952143 0.0384092 0.880712 -0.439715 -0.176057 0.661341 -0.740603 -0.118893
-0.101353 -0.994637 0.0206142 0.161383 -0.981749 -0.100616 -0.2495 -0.842061 -0.478208
--0.145196 -0.923357 -0.355428 -0.868831 -0.186722 -0.45855 0.810466 -0.25963 -0.525107
--0.265396 -0.940805 -0.210834 0.648096 -0.363566 -0.669172 0.960941 -0.0105021 -0.276555
--0.946306 -0.226291 0.230862 -0.652514 0.00526221 0.757758 -0.0437809 -0.718007 0.694657
--0.938791 -0.336283 0.0747297 -0.2118 -0.969823 -0.120763 -0.275402 -0.950996 -0.14057
--0.440281 -0.522193 0.730388 -0.718678 0.327717 0.613272 0.672565 -0.325607 0.664558
--0.907898 0.41903 -0.0116397 -0.970987 -0.18132 -0.15591 0.48366 -0.870587 0.0902831
-0.525126 -0.0145868 0.850899 0.749726 -0.646576 0.140888 0.598312 0.444461 0.666691
--0.655326 -0.6746 -0.339799 0.823216 0.128127 0.553081 -0.154807 0.877656 0.453601
--0.895835 0.440452 0.0590113 -0.84036 0.503562 -0.200553 -0.708394 0.702903 -0.0640667
-0.921436 -0.36737 0.126472 0.864675 -0.498321 0.063357 -0.975243 -0.019477 -0.220276
--0.503076 -0.416689 -0.757155 0.674162 -0.732531 -0.0943632 -0.904376 0.222616 -0.364069
-0.868548 -0.388027 -0.308316 -0.747161 0.633011 -0.202603 -0.053242 0.298155 -0.953031
-0.605262 -0.671463 -0.427545 -0.961025 0.187517 -0.203144 0.899104 0.422028 0.116211
-0.801056 0.585719 -0.12346 -0.403295 0.88985 0.213356 -0.565497 0.759382 0.321795
-0.987215 0.0881084 0.13283 -0.949529 0.170702 0.263165 -0.934238 -0.356579 0.00713159
--0.299684 0.789167 0.536101 0.361516 0.893748 0.265558 -0.195447 0.951177 0.23888
-0.833412 -0.507814 0.218061 -0.258731 -0.668066 0.697672 0.698858 -0.624862 0.348059
--0.148604 0.652564 0.743019 0.14157 -0.37752 0.915116 -0.37459 0 0.927191
--0.768366 0.555973 0.317029 0.919919 0.215046 0.327879 -0.990085 0.119177 -0.0743582
-0.950314 -0.266088 0.161553 -0.239335 -0.73077 0.639291 0.260221 -0.785937 0.560881
-0.491809 -0.412485 0.766799 0.378423 0.6775 0.630706 0.380476 0.88647 0.263457
-0.756507 -0.65393 0.0085481 -0.326836 -0.884379 -0.333244 0.708466 0.655496 0.261536
-0.492276 0.868449 0.0588254 0.345989 0.851543 0.393911 0.407102 -0.693581 0.594318
--0.576904 -0.457104 0.676932 0.847669 0.337882 0.409015 0.742929 0.611445 0.272381
-0.700824 -0.712007 -0.0434908 0.475483 0.832095 0.285541 0.658145 0.658145 0.365636
-0.832426 0.0582116 0.55107 0.788202 0.0297435 0.614698 0.651707 0.465797 0.59859
--0.0346193 0.979726 0.19733 -0.147418 0.967433 0.205771 -0.718491 -0.694857 0.030725
--0.938765 0.235545 -0.251475 0.691282 -0.628592 0.356372 0.780483 -0.537356 0.319523
--0.572271 -0.45088 0.684991 -0.841616 0.255035 0.476066 0.463893 0.884295 0.0531544
-0.771709 0.6288 0.0952727 -0.100257 0.989198 0.10694 -0.166482 0.965594 0.199778
-0.387115 0.883912 0.262378 -0.480241 0.865153 -0.144492 -0.626087 0.779017 -0.0338703
--0.202675 0.97863 -0.0347442 -0.282004 0.952066 -0.118506 -0.425091 0.902906 -0.0637087
-0.5488 0.832523 0.0756593 -0.222703 0.960615 -0.166196 0.404422 0.913358 0.0471237
--0.440282 -0.87416 0.204931 0.172043 -0.927122 0.332936 0.582501 -0.701441 0.410699
-0.338416 -0.0273719 0.940598 0.223578 -0.91511 0.33554 0.337478 0.826822 0.449971
-0.951425 -0.214495 0.220867 -0.720844 -0.503891 0.475897 -0.772683 -0.576238 0.266292
-0.157717 -0.97259 -0.17086 -0.847561 0.530647 -0.0073701 0.441633 -0.883266 -0.157482
--0.707635 0.70381 0.0624759 0.566219 -0.724761 0.392579 0.507093 0.169031 0.845154
--0.379071 0.324918 0.866449 -0.934703 0.354203 0.0295169 0.8 0.6 0
--0.968274 -0.0305771 0.248014 0.323587 -0.846305 0.423153 0.923508 -0.382918 0.0225246
--0.945638 0.3199 0.0585897 -0.92389 -0.148236 0.352779 -0.821489 0.410744 0.395532
-0.567814 0.786203 -0.243869 -0.797812 -0.602791 0.0118194 0.663011 0.279608 -0.694432
--0.630759 -0.608627 0.481369 -0.875577 -0.430516 0.219137 0.123613 -0.988903 0.0824086
-0.571771 0.177228 -0.801042 -0.77956 -0.625426 -0.0335932 -0.87093 -0.45754 0.17927
-0.354707 -0.36259 -0.861807 0.030052 -0.957909 -0.285494 -0.839178 0.342522 -0.422444
-0.566257 -0.452559 -0.688871 -0.369468 -0.385142 -0.845671 -0.461181 -0.0272888 -0.886886
--0.407831 0.480728 -0.776257 -0.387238 -0.741126 -0.548433 0.35976 0.299397 -0.883705
-0.0221855 0.192274 -0.98109 -0.167261 0.957948 0.233151 0.0790021 0.974359 0.210672
-0.0416105 0.970912 0.235793 -0.619476 -0.77877 -0.0988212 0.717143 -0.250568 -0.650325
-0.757263 -0.028576 -0.652485 -0.912356 -0.36374 0.187882 -0.0381181 0.0889423 -0.995307
--0.311458 -0.934374 -0.173032 0.817402 0.19659 -0.541486 -0.223864 0.466699 -0.855615
-0.809424 -0.57816 0.102784 0.748834 -0.157649 -0.643735 -0.487377 -0.433224 -0.758143
--0.9674 -0.107489 -0.22931 0.539375 -0.353275 0.764377 0.524331 0.635553 0.566701
--0.666895 -0.611321 0.426072 -0.990641 0.130815 -0.0389483 0.391348 -0.535529 0.748368
--0.157112 -0.843336 -0.513908 -0.912871 -0.365148 0.182574 -0.749074 -0.0995502 -0.654964
-0.322788 0.0370075 -0.945748 -0.263274 0.614305 -0.743852 -0.453511 0.717401 -0.528833
-0.839846 0.311148 -0.444798 -0.965111 -0.161247 -0.206301 -0.735422 0.0232851 -0.677209
--0.862863 0.21461 -0.457613 -0.0959334 0.419003 -0.902903 0.319076 -0.0299134 -0.947257
--0.730122 0.540831 -0.417642 -0.655516 0.460633 -0.598429 -0.76833 -0.18568 -0.61253
--0.851079 -0.499786 -0.160866 -0.676383 -0.697941 -0.235342 0.28543 0.924404 -0.252995
--0.865371 -0.397553 -0.305099 -0.85425 -0.470042 -0.222078 -0.643708 -0.743483 -0.181311
--0.320134 -0.147363 -0.935841 -0.795769 -0.51946 -0.311308 -0.632008 -0.0574552 -0.772829
--0.183694 0.671357 -0.718009 -0.592225 -0.744157 0.309032 -0.0817317 -0.687508 0.721563
-0.143158 -0.823156 0.549472 -0.133221 -0.717342 -0.683866 -0.336195 -0.770448 -0.541648
--0.0824786 -0.412393 -0.907265 -0.813482 -0.171921 -0.5556 -0.777154 -0.16239 -0.607997
-0.107518 -0.295676 0.949219 0.478444 -0.722357 0.499291 0.411476 -0.257172 -0.874386
--0.564649 -0.0996439 -0.819294 0.651038 0.421969 -0.630945 -0.645161 -0.415147 0.641421
--0.109675 -0.250687 0.961836 0.281709 -0.888291 0.362738 -0.155999 -0.189428 -0.969423
-0.293346 -0.258835 -0.9203 0.263598 -0.263598 -0.927918 0.0433038 0.158781 -0.986364
-0.810293 0.23402 -0.53727 -0.0708804 -0.432877 -0.898662 0.142177 -0.277062 -0.950275
-0 0.253012 0.967463 -0.379967 -0.287542 0.879173 -0.660942 -0.710266 -0.242236
--0.00861109 -0.999963 -0.000717591 0.461757 -0.799194 -0.384797 0.388164 -0.659411 -0.643822
--0.75955 -0.379775 -0.528068 -0.502656 -0.677047 -0.537535 0.175132 0.916075 0.360742
-0.283368 0.902466 0.324436 0.715145 -0.552612 -0.428004 0.236102 -0.681105 0.693074
-0.19549 0 0.980706 0 -0.706566 0.707647 0.618815 -0.374817 0.690348
--0.866634 -0.312135 -0.389251 -0.873185 -0.478844 0.0908622 -0.31719 -0.261072 -0.911719
-0.619827 0.216219 -0.754363 0.388103 0.388103 -0.835914 -0.85118 -0.275382 -0.446831
-0.133732 -0.105788 -0.985355 0.441379 0.891117 0.105329 0.533347 -0.478644 -0.697453
-0.399762 -0.261913 0.878403 0.647459 0.00130273 0.762099 -0.587672 0.402092 0.702114
--0.626249 0.0447321 0.778338 0 -0.501806 0.86498 -0.39884 0.16758 -0.901579
-0.835364 0.271903 -0.477741 0 0.423036 -0.906113 0.360268 0.838057 -0.409717
-0.40156 -0.558507 0.725824 -0.179132 -0.569009 0.802584 0.00613572 -0.654477 0.756057
-0 -0.652141 0.758097 0 -0.724005 0.689795 0.311837 -0.623673 0.716791
-0.39968 -0.325454 0.856934 0.150796 0.552918 -0.819477 -0.138478 -0.553913 -0.820978
--0.31691 -0.636168 -0.703462 -0.715076 0.667754 -0.206811 0.343255 -0.899886 0.269038
--0.058261 -0.802942 0.593203 -0.552275 -0.591443 0.587526 -0.359813 -0.768692 0.528817
--0.0479092 -0.910276 0.411221 0.0980957 -0.972334 0.212002 -0.500128 -0.823847 -0.266735
--0.434547 -0.880381 -0.189997 -0.73962 0.325635 -0.589003 -0.274968 0 -0.961453
--0.0337316 -0.464146 -0.885116 0.837203 0.141188 -0.528353 -0.00184239 0.182397 -0.983223
-0.963078 0.266531 0.0379815 -0.880658 -0.470216 -0.0577807 -0.345702 -0.888949 0.300432
-0.496918 0.175992 -0.849764 -0.263281 -0.623355 0.736282 0.405375 -0.585225 0.70227
--0.138413 -0.989816 -0.0332621 -0.156821 -0.374803 -0.913745 0.704014 -0.179153 -0.687218
--0.160456 -0.677765 -0.717558 0.996562 0.0683127 0.0468813 0.801537 -0.0716319 -0.593639
-0.379186 0.315167 -0.869993 -0.1138 -0.710198 -0.694744 0.218208 -0.293741 -0.930646
-0.394224 0.194032 -0.898298 0.167283 0.683469 -0.710553 0 0.760034 -0.649884
--0.0681252 0.346465 -0.935586 -0.30227 -0.0259089 -0.95287 -0.455913 -0.644806 -0.613489
-0.215119 0.225875 -0.950108 0.630857 -0.376284 -0.67855 0.929806 0.170964 -0.325932
--0.779166 0.35014 -0.519905 -0.35576 0 -0.934577 0.355314 0.87052 -0.34051
-0.220674 -0.299486 -0.92823 -0.799715 -0.336722 -0.497066 0.0233819 -0.140291 -0.989834
--0.243373 0.491565 -0.836142 -0.519122 0.849473 -0.0943858 0.491325 0.164189 -0.855361
-0.199089 -0.170648 -0.965009 -0.216983 -0.760268 -0.6123 0.334149 -0.942425 -0.0134376
-0.949603 -0.279794 -0.14131 -0.584431 -0.652191 -0.482791 -0.027351 -0.537903 -0.842563
-0.189589 0.108735 -0.975824 0.740397 0.498254 -0.451171 0.777968 0.563356 -0.278201
-0.597671 -0.605605 -0.525387 0.362821 0.571128 -0.736324 0.922932 -0.229862 -0.308805
-0.385831 -0.90522 -0.178076 -0.602383 -0.761838 -0.238197 0.582575 -0.588123 -0.560998
-0.266404 -0.133202 -0.954613 0.314997 -0.0633957 -0.946973 0.850919 0.33429 -0.4052
--0.987785 -0.104239 -0.115821 0.622746 -0.404558 -0.669717 -0.375952 -0.621059 -0.68771
-0.813313 -0.240297 -0.529886 -0.244476 -0.700173 -0.670812 -0.277144 -0.705624 -0.65214
-0.73243 0.0415295 -0.679574 0.986537 0.0544296 0.154217 0.615961 0.733768 0.286663
-0.616041 0.773443 0.149261 0.70385 -0.0454097 -0.708896 -0.587203 -0.268107 -0.763748
-0.843237 -0.527389 0.103983 -0.866153 0.278655 -0.414886 -0.767205 0.639724 0.0463568
--0.694629 0.7113 0.107436 -0.313249 -0.865523 -0.390827 -0.638247 -0.707328 -0.303856
-0.512049 -0.753581 0.412215 0.0742819 -0.909603 0.408784 -0.433559 0.872504 -0.225307
-0.736309 -0.412988 -0.535994 0.183294 -0.843305 -0.505213 -0.0189262 -0.480949 -0.876544
-0.1776 -0.350125 -0.919712 -0.0818006 -0.96252 -0.258581 -0.219074 -0.955087 -0.199537
--0.527875 -0.842354 -0.10857 0.247274 -0.931592 -0.266443 -0.542872 -0.67582 -0.498556
-0.294744 -0.126319 -0.94719 -0.234806 -0.712455 -0.661267 0.820648 0.562414 -0.101129
-0.191893 0.965237 -0.177465 0.796596 0.411286 0.443034 -0.642803 0.653822 0.39915
--0.732479 0.644874 0.218203 0.916885 0.216487 0.335342 0.678735 0.709587 0.189223
--0.923451 0.383319 0.0174236 0.490758 -0.457144 -0.741739 -0.236099 -0.607113 -0.75873
--0.399497 0.916087 0.0344394 0.949939 -0.0436419 -0.309373 -0.68483 -0.249029 0.68483
-0.352752 0.647048 -0.67594 0.478836 -0.85027 0.218534 -0.74563 0.664583 0.0486281
-0.563337 0.826227 0 0.720216 -0.330099 0.610183 -0.187108 0.982319 -0.00623695
--0.315064 0.933941 -0.168785 0.245169 -0.964484 0.0982987 0.119944 -0.420374 -0.899388
-0 -0.589777 -0.807566 0 -0.699193 -0.714933 -0.378538 -0.614196 -0.692439
-0.965134 0.23815 0.10863 0.971272 0.129503 -0.19965 -0.111979 0.993081 -0.0353619
--0.886187 -0.158973 0.435201 -0.937662 0.317595 0.141153 -0.866843 -0.298306 0.399496
--0.877954 0.45548 0.147426 0.90494 -0.397534 0.151822 -0.999671 0 -0.0256326
--0.271329 -0.407547 -0.871944 0.245978 -0.70176 -0.668601 0.155893 -0.568552 -0.807741
--0.557396 -0.405064 -0.72473 0.390873 0.870007 -0.30051 0.811941 -0.582687 -0.0350249
--0.298246 -0.898246 0.322807 0.649004 -0.7604 0.0242166 -0.68699 -0.610088 0.394763
-0.452039 -0.880077 0.145346 -0.802921 -0.00613586 0.596055 -0.964678 0.15152 -0.215495
-0.0744809 -0.9757 0.206064 -0.356966 -0.474504 0.804625 -0.188334 -0.867437 -0.460525
-0.719104 -0.563221 0.407028 -0.982481 -0.104459 -0.154336 0.242026 -0.892469 0.380686
--0.564821 -0.800404 0.200825 0.627277 -0.466811 -0.623387 0.637568 0 -0.770394
--0.142326 0.906669 -0.397107 0.159465 0.955366 -0.248689 -0.76274 -0.290672 -0.577701
-0.74587 0.617038 -0.250883 -0.81045 -0.479654 -0.336309 0.402746 -0.684668 0.607475
-0.658069 -0.731188 -0.17975 0.159197 0.987019 -0.0212262 -0.608463 0.571842 0.550245
-0.81123 0.504278 0.295989 -0.931872 -0.337191 0.133854 0.361893 0.932219 0.000763488
--0.760264 0.410953 -0.503107 -0.299494 0.861957 0.409064 0.258938 0.490132 0.832299
--0.601025 0.758216 0.252739 -0.60909 0.673264 0.419195 0.330928 0.931923 0.148347
-0.370937 0.928658 4.67317e-018 -0.737688 -0.436198 0.515313 -0.717518 -0.0326145 0.695776
--0.411705 0.799192 -0.437941 -0.832317 -0.392603 -0.391294 0.807314 -0.438668 0.394733
--0.167761 -0.0524254 0.984433 0.883076 0.0169618 0.468924 0.398877 0.656771 0.63996
--0.550062 0.741453 0.38429 0.269297 0.96283 -0.0209044 -0.780604 -0.483975 0.395506
--0.406482 -0.269789 0.872918 0.439425 -0.0298928 0.897782 0.20025 0.810206 0.550878
-0.71028 0.325003 0.6244 0.163913 0.980285 0.11034 0.706998 -0.255723 0.659363
--0.681199 0.618602 0.391536 -0.0740353 0.329794 0.941146 -0.43931 0.761009 0.47736
--0.435495 0.899894 0.0231236 0.805272 0.368949 -0.464127 -0.0156035 0.915408 -0.402225
-0.781356 -0.612276 0.120833 0.814023 -0.260067 0.519357 0.473539 0.796306 0.376374
-0.298136 0.951485 0.076104 -0.445801 -0.655864 0.609183 -0.273077 -0.109231 0.955771
-0.314567 -0.56075 0.765903 -0.202444 0.91642 0.345239 -0.145551 0.836917 0.527622
-0.345219 -0.455689 0.82047 0.109863 -0.576781 0.809477 -0.291199 0 0.956663
--0.689988 0.605675 0.396327 -0.779207 0.611971 -0.135381 -0.947068 0 -0.321033
-0.905529 -0.405661 -0.124326 -0.957779 0.191881 -0.214105 0.570971 0.401648 0.71601
--0.609188 -0.793025 -0.00120155 0.22393 -0.453529 0.862651 -0.298246 -0.561404 0.77193
--0.016947 -0.995634 0.091796 0.114627 -0.984316 -0.134102 0.76324 0.626272 0.158896
--0.780768 -0.0803318 0.619635 -0.0273474 -0.683685 0.729264 0.852852 0.497026 0.160027
-0.764328 0.60805 0.214659 -0.785482 0.607238 -0.119501 -0.798365 -0.10563 -0.592837
-0.424906 -0.465741 0.776235 0.275393 -0.768981 0.576912 -0.912551 0.323436 -0.250278
--0.691563 -0.720303 -0.053888 0.814957 0.568197 0.114 0.938593 -0.152877 0.309309
--0.0306653 0.967137 0.252399 0 0.999012 0.0444406 -0.122325 0.960364 0.250475
--0.575306 -0.815582 0.0620429 0.542611 -0.663519 0.515088 -0.614936 0.786501 0.0571884
-0.309303 0.662791 0.681938 0.453619 -0.857548 -0.242571 0.325035 -0.787823 -0.523152
--0.36419 -0.582704 -0.726513 -0.753345 0.120135 -0.646559 -0.0994293 -0.867548 0.487313
-0.192513 -0.941751 -0.275761 -0.768165 0.584621 -0.26104 -0.515661 0.515661 -0.684242
--0.632944 0.637947 0.438641 -0.568495 0.59692 0.566127 -0.648077 0.761306 0.0202524
-0.159836 -0.82674 -0.539402 -0.908765 0.024747 -0.416574 0.145153 -0.79507 -0.588892
--0.802954 -0.370481 -0.466914 -0.734038 -0.250939 0.631045 -0.621609 0.359879 0.695766
--0.632406 -0.213986 0.744494 0.182029 0.923914 0.336525 0.799461 0.572663 -0.181438
-0.862405 -0.311735 0.398847 -0.388229 0.915205 0.108064 -0.31451 0.904216 -0.288925
--0.371498 -0.894791 0.247665 0.204669 0.96003 0.190926 -0.483809 0.743171 0.462196
-0.469073 0.835769 -0.285415 0.993743 -0.106441 -0.0338403 0.553575 0.609784 0.567202
-0.544186 0.493953 0.678139 -0.369926 0.908427 -0.194719 -0.441629 0.612082 -0.655987
-0.949654 0.260179 -0.174537 0.626501 -0.750153 -0.211582 -0.0895616 -0.993198 -0.0744118
--0.689787 0.338757 0.639874 -0.765414 -0.634917 -0.104983 0.668823 0.412376 -0.618564
--0.238575 0.865341 -0.440758 0.758853 -0.457257 0.463743 0.778364 -0.333329 0.532016
--0.474954 -0.633272 -0.611052 -0.785467 0.499843 -0.364964 0.0092984 -0.920542 -0.390533
--0.527143 -0.811955 0.250699 0.858022 -0.269183 -0.437423 -0.486986 0.872854 0.031162
--0.660371 -0.609574 -0.438554 -0.678026 -0.620321 -0.394313 -0.5705 0.801753 0.178105
-0.977199 0.068692 -0.200906 0.903148 -0.401399 -0.152326 -0.701963 0.447823 0.553808
--0.567391 0.769922 0.292039 -0.532566 0.790644 0.302086 0.649099 -0.74896 -0.133149
--0.538312 -0.820533 -0.192213 0.472901 -0.858963 0.196334 0.599272 -0.414755 0.684727
--0.0792451 -0.871696 -0.483598 0.136622 -0.914773 -0.380165 -0.835916 0.0272952 -0.548179
-0.789339 0.592004 0.162715 0.638063 0.749724 0.175467 0.172341 0.982346 -0.0727664
--0.449201 -0.711235 0.540705 0.119806 -0.907281 -0.403097 0.505122 -0.842952 -0.185157
--0.675275 -0.369933 -0.638086 -0.253837 -0.930737 0.263239 0.313045 -0.922659 0.225173
--0.515346 -0.804469 -0.295377 -0.0862739 0.901083 0.424979 0.724233 0.485998 0.489175
-0.257861 0.759646 0.597031 0.932992 0.115541 0.340845 0.215433 -0.0615522 0.974577
--0.360523 0.733178 0.576605 -0.246761 0.856111 0.454074 -0.418989 0.80354 0.422815
-0.40057 0.35215 0.845893 -0.927404 0.345937 0.1423 -0.343669 -0.862136 0.372308
--0.351982 -0.854814 0.381314 -0.286761 -0.742204 0.605724 -0.469965 -0.724208 0.504634
--0.533947 -0.158207 0.830585 -0.0396385 -0.87771 0.47755 0.486597 0.71118 0.507392
--0.78616 0.54793 0.285876 0.749396 0.659043 -0.0637784 -0.843981 0.279303 0.457915
-0.0431624 0.156464 0.98674 0.917384 0.352563 -0.184676 0.0663639 0.859781 0.506332
-0.982786 -0.133659 0.127544 0.330211 0.749706 0.573499 0.407645 0.733761 0.543526
--0.325328 0.325328 0.887875 0.691598 0.296399 -0.658665 -0.0286735 0.93189 0.361605
-0.811029 0.575569 0.104649 -0.835007 0.544827 0.0769864 -0.605674 0.795532 -0.0169357
-0.526432 -0.723844 -0.446005 -0.858721 0.511499 0.0311131 0.95516 -0.294414 -0.0314641
-0.654318 -0.752291 -0.0769786 -0.184002 0.950676 0.249717 -0.766319 0.484996 0.421348
-0.814556 -0.30927 0.490766 0.747596 -0.142399 0.648708 0.150572 0.983936 0.0959089
--0.707383 0.697349 -0.115389 -0.0524396 -0.830294 0.554853 -0.422703 -0.329105 0.8444
--0.0389351 0.49591 0.867501 -0.367122 -0.453782 0.811975 -0.39595 -0.444575 0.803478
-0.325111 -0.0237886 0.945377 -0.222089 0.888354 0.401875 -0.013383 0.843126 0.537549
-0.059459 0.959272 0.276154 0.465452 -0.717806 0.517792 0.500189 -0.180068 0.846987
--0.137309 0.52635 0.839108 -0.337721 0.621407 0.706963 -0.0715918 0.8342 0.546795
-0.437739 0.835922 0.331087 -0.313847 0.936785 0.154704 -0.316154 0.839023 0.442818
-0.826227 0.338002 0.450669 -0.363858 0.909645 -0.200385 0.509167 0.737621 0.443468
--0.889945 -0.0778334 -0.449378 -0.639379 0.715837 -0.280664 0.0616832 0.953938 -0.293593
-0.916946 -0.16374 -0.363867 0.805817 0.351409 -0.476624 -0.421712 0.822072 -0.382566
-0.659112 0.483905 -0.57568 0.0866908 0.99413 0.0647366 -0.620591 0.663146 -0.418456
-0.596674 0.769434 0.227927 -0.306038 -0.889423 -0.339511 -0.198727 -0.817677 -0.540288
--0.16199 0.241365 -0.956819 -0.0259789 0.777923 -0.627823 0.128085 0.577638 -0.806182
-0.241196 -0.952135 0.187785 0.615898 -0.784377 0.0736399 0.490558 -0.865848 -0.0982902
-0.397915 -0.862814 0.311793 -0.076443 0.0955537 -0.992485 0.344402 -0.593367 0.727532
-0.304721 0.557874 -0.77196 0.34759 -0.385168 0.854884 0.350881 -0.818723 0.454504
-0.719072 0.694651 0.0198988 -0.409496 0.834609 0.368431 0.669983 0.736982 -0.0893311
-0.771905 0.500695 -0.391748 0.851906 0.377427 -0.363049 -0.718531 0.695165 -0.0214196
--0.673618 0.721355 0.16089 -0.340565 0.936554 -0.0829582 -0.703328 0.708697 -0.0554788
--0.62385 0.779813 0.0519875 0.904023 -0.420476 0.0770872 -0.274518 -0.877431 -0.39339
-0.664087 -0.193795 -0.722102 -0.277649 -0.771865 -0.571957 -0.855761 0.403953 0.323256
--0.980981 -0.161503 0.107669 -0.329698 -0.941995 -0.0627997 -0.318638 -0.88094 -0.349877
--0.913812 0 -0.406138 -0.843795 0.281265 -0.457056 -0.809858 -0.0449921 -0.584898
-0.642086 -0.713429 -0.280615 -0.677066 -0.112844 -0.727219 -0.479839 -0.221464 -0.848945
--0.593281 -0.741602 -0.313121 -0.810737 -0.585093 -0.0192656 0.700229 -0.0479288 -0.712308
-0.868324 0.183022 -0.460996 -0.990763 0.0176472 0.134455 -0.989301 -0.058887 0.133477
--0.596471 -0.796965 -0.0952348 0.0651251 -0.716376 -0.694668 0.432176 -0.85327 -0.291811
--0.16173 -0.549883 -0.819434 -0.808247 -0.153567 -0.568467 -0.739123 -0.558113 -0.377104
--0.00482716 -0.391 -0.920378 0.751728 0.381391 -0.538001 -0.782525 0.595786 0.180811
--0.0433646 0.520375 -0.852836 -0.72194 -0.469261 -0.508524 0.8223 0.441605 -0.358898
--0.558705 -0.649001 0.516379 -0.122262 -0.217176 -0.968445 0.771176 0.396563 -0.498021
--0.485481 -0.729729 0.48146 -0.739498 -0.372247 -0.560869 -0.753035 -0.637183 0.164123
--0.384129 -0.85523 0.34789 -0.408185 -0.910361 0.0680309 -0.890682 -0.435701 -0.129811
--0.417446 -0.834891 0.358742 0.569232 0.182244 -0.801724 0.0217289 0.999528 -0.0217289
-0.293995 0.930985 0.216413 0.428122 0.887267 -0.171662 -0.571268 0.736852 -0.361527
-0.899559 0.311847 0.30585 0.779239 0.618808 -0.0993148 -0.939353 0.139904 -0.313118
-0.797465 -0.194225 0.57125 -0.280294 -0.779216 0.560587 -0.90969 -0.414222 -0.0297458
--0.962264 -0.226415 -0.150943 0.418821 -0.732937 0.536091 -0.672912 -0.716482 0.183962
--0.159153 -0.925074 0.344831 -0.363915 0.166424 0.916444 -0.284834 0.575146 0.766861
--0.922282 0.372087 0.104631 0.922211 -0.269318 0.277479 0.807698 -0.0695976 -0.585474
--0.481251 -0.704689 0.521355 -0.756467 -0.550158 0.353673 -0.442581 -0.785225 0.433063
--0.539279 -0.41483 0.732867 0.747241 -0.314455 -0.585448 0.842745 -0.256488 -0.473281
--0.677798 -0.551429 0.48633 0.0859382 -0.880866 0.465499 -0.52058 -0.77123 0.366334
--0.0380571 -0.938742 0.342514 0.713643 -0.198685 -0.671743 -0.350684 -0.769412 0.533878
--0.138461 -0.860866 0.48963 -0.592205 -0.572016 0.56753 0.298066 0.938909 -0.172066
-0.292737 0.360292 -0.885717 -0.609509 -0.0156955 -0.792624 -0.975401 -0.220289 -0.00809461
-0.226415 -0.509434 -0.830189 -0.63785 -0.494817 0.590172 0.277409 -0.569419 0.773826
-0.681484 -0.453204 0.574618 -0.446719 0.824045 -0.348412 0.51393 -0.765361 0.387425
--0.84761 -0.081501 0.524323 0.783492 0.61996 0.042307 -0.827831 -0.477595 -0.294276
--0.441068 -0.866097 0.235236 -0.551845 0 0.833947 0.175069 0 0.984556
-0 -0.454739 0.890625 0.17378 -0.568735 0.803953 -0.493062 -0.571798 0.655696
-0.940981 0.209107 0.266136 0.451165 -0.892154 0.0226148 -0.892489 -0.435089 0.118999
-0 -0.195557 0.980692 0.751783 0.573536 0.325388 0.752332 0.596134 0.280393
-0.197539 0.395078 0.897157 -0.561401 -0.800219 0.210897 -0.246252 -0.969016 -0.0191884
-0.809813 0.524227 0.263417 0.910246 0.379269 0.166156 -0.759757 0.291306 0.5813
--0.172447 -0.172447 0.969806 -0.196671 -0.763545 0.615078 0.959401 0.266693 0.0917839
-0.4073 -0.492154 0.769345 0.80829 0.11547 0.57735 -0.990492 -0.137568 0
--0.281662 -0.537523 0.794818 -0.280577 -0.542448 0.79185 0.121636 -0.429782 0.894702
-0.132161 0.0213975 0.990997 -0.507118 -0.507118 0.696895 0.0118686 0.999929 0.00098905
--0.0506589 -0.905106 0.422158 0.932648 0.185624 0.309373 -0.673277 -0.0968744 0.733016
-0.945484 0.297152 0.133268 0.919568 0.33984 0.197241 -0.868611 -0.38537 -0.311456
-0.368731 -0.538557 -0.757624 -0.0650865 0.0735761 -0.995163 0.337086 0.204659 -0.91896
-0.314574 -0.340888 -0.885911 -0.876715 0.23123 0.421787 -0.0176222 -0.418527 0.908033
--0.135326 -0.582698 0.801342 0.540635 -0.138302 0.829811 -0.499233 0.0274447 0.866033
--0.159867 -0.188933 0.968889 0.947565 0.0485338 0.315855 -0.782687 -0.538732 0.311719
--0.904768 0.392635 0.165021 0.363733 0.544511 -0.755781 0.0826539 0.870818 -0.484608
--0.0118038 0.755442 -0.65511 0.385896 -0.0110256 -0.922476 0.569415 -0.251897 0.782505
-0.0355019 -0.443773 0.895436 -0.180905 -0.671932 0.718179 0.787789 -0.342626 0.511855
-0.656553 -0.632645 0.410729 -0.982679 -0.0289023 0.183048 0.56552 0.557749 -0.607538
-0.489065 0.619483 -0.614049 -0.449277 -0.587709 0.672866 -0.210012 -0.926893 0.31107
-0.562404 0.778392 0.278941 0.605463 0.762982 0.226433 -0.0221856 0.321691 0.946585
--0.27345 0.626657 0.729744 -0.143918 0.949248 0.279671 0.882628 -0.233014 -0.408256
-0.583178 -0.479771 -0.655532 -0.0129257 -0.843399 -0.537133 0.313224 -0.792495 -0.523299
-0.137234 -0.772338 -0.620211 0.129915 -0.75587 -0.641702 0.529696 -0.815144 0.23444
--0.376512 -0.909517 0.176119 0.867327 -0.412509 0.278532 0.433694 -0.501216 0.748794
-0.882248 0.0577171 0.467234 0 -0.689184 0.724587 0.620613 -0.297554 0.725466
-0.673255 0.290017 0.68016 0.684599 0.489865 0.539775 0.648062 -0.539542 -0.537504
-0.024134 -0.877121 -0.479664 -0.377302 -0.747617 -0.546545 -0.405857 -0.789166 -0.460973
--0.270585 -0.947047 -0.172874 -0.309803 -0.727292 -0.612428 -0.370652 -0.833377 0.409999
-0.449384 -0.755973 -0.475983 -0.0992201 -0.988232 -0.116418 0.163172 -0.979035 0.121923
-0.965393 0.0546449 0.25501 0.955532 -0.241761 0.168849 0.268769 0.761512 0.589799
--0.717536 0.694877 -0.0478357 -0.878072 -0.435326 0.1987 -0.918316 -0.395168 0.0232011
--0.201291 0.978272 0.0496517 0.217787 -0.745062 -0.630437 0.247182 -0.72645 -0.641226
--0.0932922 -0.713411 -0.694508 -0.124591 -0.662302 -0.738805 -0.126111 -0.693611 -0.709225
--0.819069 0.565132 -0.0987529 -0.93673 0.326121 -0.12721 0.80039 -0.0188981 0.599181
-0.773185 -0.036082 0.633153 -0.974482 -0.214048 0.0675941 -0.118932 -0.793781 -0.596462
-0.660087 0.660087 0.358566 -0.683426 0.729604 0.024628 0.825296 0.293417 -0.482486
-0.400152 0.639933 -0.656022 -0.330778 0.873827 -0.356389 0.728524 -0.414529 0.54536
--0.993146 0.0522708 -0.104542 0.42005 -0.725105 0.545692 0.53976 -0.725303 0.42731
-0.480591 -0.756341 0.443825 -0.920498 0.114466 -0.373605 -0.37285 0.915915 -0.1486
-0 0.80975 -0.586775 0.279475 0.784908 -0.553003 0.0700335 0.964906 -0.253084
--0.229426 0.964466 -0.131031 0.0737118 -0.986604 -0.145533 0.840993 -0.434513 -0.322381
-0.52657 -0.182274 -0.830361 0.312081 -0.92946 -0.196747 -0.334275 -0.315173 -0.888215
-0.27134 0.943793 -0.188759 -0.401074 0.860683 -0.313632 -0.378267 0.342242 0.860107
-0.976251 -0.205526 -0.0685088 -0.122878 0.988872 0.0838688 -0.872789 0.417421 0.252982
-0.976102 0.0377658 0.214006 0.651681 0.75762 -0.0363829 0.364101 -0.7756 0.51563
-0.742195 -0.656862 0.13296 -0.871366 -0.309023 0.381085 0.146872 -0.78273 0.604783
-0.877004 -0.372166 0.303901 0.957069 0.0118614 0.289617 0.558115 -0.796969 0.230971
--0.82509 -0.437877 0.357057 -0.399533 -0.528 0.749392 -0.730739 0.540921 0.416443
-0 0.845299 0.534293 0.134867 0.990863 0.000917466 0.606041 0.795429 0.00252517
-0.836213 0.470829 -0.28119 -0.445512 0.860086 0.248538 0.423396 -0.729626 0.537012
--0.305044 -0.934501 0.183457 0.806679 0.590989 0.000539224 0.342321 -0.222509 0.912856
-0.241416 0.64858 0.721846 0.200802 0.312538 0.928439 -0.535649 -0.204807 0.819228
--0.982708 0.1121 0.147371 -0.0159597 -0.877784 0.478791 0.67601 -0.720258 -0.155687
--0.49998 0.862466 0.0785683 -0.533904 0.782134 0.321267 -0.826654 0.296921 0.477997
-0.226547 -0.841459 0.490534 -0.495535 -0.31297 0.810244 -0.299892 -0.886638 0.352048
-0.54181 -0.725035 0.425165 0.245359 -0.500156 0.830447 0.363325 0.835104 -0.413033
--0.590006 0.548805 -0.592204 -0.116529 0.169081 0.978689 -0.706242 0.684456 0.180948
--0.309995 0.476063 -0.822962 0.95009 -0.19489 -0.243613 0.475945 0.655064 -0.586828
-0.728125 -0.630945 0.267849 -0.0407481 0.890951 0.452267 -0.582969 0.80907 0.0745233
--0.0549774 0.923621 -0.379344 -0.513722 0.834798 -0.197997 -0.557588 0.811228 -0.176081
-0.765321 0.26353 0.587227 -0.675956 0.731082 -0.0927525 -0.58211 0.40905 0.702727
--0.594237 0.801932 -0.0615391 0.723883 -0.685921 -0.0742002 -0.896904 0.294657 -0.329758
--0.638909 0.729387 -0.244521 -0.666179 0.460368 -0.586743 -0.678242 0.413304 -0.607592
-0.960313 0.122187 0.250738 0.913422 0.404416 0.0459035 -0.4968 0.867295 0.0314359
-0.876056 0.259828 -0.40622 -0.341332 0.898593 -0.275723 -0.872526 -0.119972 -0.473609
-0.584025 0.805516 0.100298 0.222134 -0.456384 0.861609 -0.311531 -0.914709 -0.2574
-0 -0.983582 -0.180463 -0.174272 -0.894402 -0.411915 0.0946618 0.636816 0.765183
--0.989303 -0.0594693 -0.133204 -0.20138 -0.47599 0.856084 0.892971 0.140995 0.427462
-0.222449 0.826241 0.517535 0.530197 0.745678 -0.403554 0.774297 0.526993 -0.350347
-0.494518 -0.85912 -0.131778 0.620653 -0.776792 -0.106695 -0.426685 -0.694779 -0.578983
-0.764098 0.363617 0.532858 0.361256 -0.794763 0.487695 -0.622033 -0.551448 0.55586
-0.959018 0 -0.283346 -0.194219 -0.920341 0.339488 0.208337 -0.876339 0.434311
--0.928985 0.364538 0.0640229 -0.707637 0.435469 0.556432 0.714521 0.136193 0.68623
-0.608432 -0.0612033 0.791242 -0.74959 -0.617309 -0.23884 -0.597472 -0.792565 -0.121933
--0.501535 -0.844691 -0.186976 0.84596 -0.484014 0.223791 -0.862354 -0.505442 -0.029558
--0.879617 -0.473284 -0.0477132 0.92322 0.0869844 -0.374296 0.78666 -0.248249 -0.565277
--0.44754 -0.888317 0.102961 -0.342413 -0.924516 -0.167402 -0.0276609 0.874084 -0.484987
--0.325084 0.945244 -0.0288963 0.774788 -0.615273 0.145408 -0.424469 -0.859505 0.28474
-0.873828 0.160835 -0.458865 0.630084 -0.422443 -0.651564 0.195384 -0.784541 -0.58849
--0.508922 0.675479 0.533597 -0.0545349 0.974688 0.216818 -0.177901 0.899011 0.400164
--0.476704 0.727146 0.493976 -0.908257 -0.416233 0.0426587 0.751682 -0.652623 0.0951742
--0.435742 -0.86247 0.257439 0.507963 -0.736138 -0.447297 0.0781703 -0.906776 -0.414303
--0.335164 -0.918402 -0.210247 -0.596191 -0.122268 0.793478 -0.649051 0.102482 0.75381
-0.888894 0.165376 0.427221 -0.918033 -0.393443 -0.0491803 0.527496 0.805815 0.269091
--0.929075 0.360048 0.0847665 -0.633245 -0.697642 0.335107 -0.17146 -0.925188 0.338568
--0.377802 -0.763377 0.523947 -0.278163 0.960533 0.00144877 0.636431 -0.383329 0.669338
-0.354603 -0.839506 0.411687 -0.952117 0.07129 0.297306 0.0171572 0.998693 0.0481355
-0 -0.974802 -0.22307 0.271945 -0.960733 -0.055124 -0.334501 -0.836773 0.433497
-0.599162 0.800444 -0.0171635 0.212221 -0.88361 0.417367 0.677376 -0.693698 0.244835
-0.0219415 -0.727446 0.685814 -0.269743 0.351839 0.896352 -0.34553 0.8828 0.318234
--0.0328036 0.880377 0.47314 -0.689033 0.714695 -0.120185 0.605622 -0.175543 0.776149
-0.535361 0.414935 0.735675 -0.885942 0.3648 -0.286406 -0.277827 0.845221 -0.456524
--0.169461 0.782128 -0.599632 0.584915 -0.779887 -0.222825 0.302739 -0.930641 -0.205563
-0.185381 -0.975458 0.118806 0.976954 -0.144377 0.157211 0.631576 -0.672323 0.386125
--0.86472 -0.0238269 -0.50169 -0.64589 -0.25329 -0.720188 -0.557171 0.78004 0.284777
--0.708727 0.590606 0.385863 -0.848634 -0.494632 0.187508 -0.969816 0.231324 -0.0771081
-0.194631 0.915417 -0.352322 -0.327382 0.944849 -0.00897883 0.605589 -0.789899 0.0965432
-0.629575 -0.198813 0.751072 -0.554213 -0.810811 0.188235 -0.943854 0.328847 0.0316199
-0.365393 -0.917264 0.158477 0.149393 -0.953978 -0.260014 -0.0996518 -0.866971 -0.488294
-0.950321 0.10182 0.294147 -0.357663 -0.925321 0.125933 0.733973 0.53509 -0.418286
-0.137962 0.984228 -0.110729 0.0876307 0.820962 0.564219 -0.561393 0.773908 0.293093
-0 -0.914429 0.404747 0 -0.62788 0.77831 0.495251 -0.839773 0.222504
--0.757878 0.611192 0.228178 0.891005 -0.18472 0.414716 0.665947 -0.745266 -0.0330495
-0.63056 -0.677268 -0.379081 -0.0272008 -0.994528 -0.100869 0.815211 -0.490259 0.308346
--0.553932 0.658963 0.50885 -0.667498 -0.451267 -0.592287 0.84932 -0.116523 0.514857
--0.91859 0.380106 0.108225 -0.871966 0.38644 0.300564 0.768589 -0.638718 0.0361996
-0.619813 0.215587 0.754555 -0.34832 0.34832 0.870257 0 0.863779 -0.503871
--0.889261 -0.370525 -0.26819 0.879936 -0.288775 0.377255 -0.163912 0.861059 0.481363
-0.802858 -0.539062 0.254621 0.810407 -0.476505 0.340858 -0.870374 0.486587 -0.0753867
--0.746696 0.662248 0.0622247 -0.460255 -0.887635 -0.0164377 -0.127855 -0.990877 -0.0426184
--0.76004 0.649094 -0.0318809 0.763761 -0.609075 -0.213767 0.33931 0.0657978 0.938371
-0.995588 -0.060645 0.0715948 -0.249263 0.926948 -0.280421 -0.60159 0.767546 -0.221275
-0.749145 0.649551 0.129868 -0.317376 0.372175 0.872214 0.563123 -0.412957 0.715792
--0.501663 0.0876942 0.860607 0.907507 0.380871 0.177113 0.947121 0.282254 0.152627
--0.154801 -0.942629 -0.295781 -0.95041 -0.256197 -0.176308 0.892504 -0.0263146 0.450272
--0.0551289 0.98707 0.150511 -0.670795 0.585071 0.455769 -0.92149 0.356335 0.154539
-0.67505 0.319615 0.664947 0.838591 0.268349 0.474083 -0.525761 -0.467343 0.710751
-0.819567 -0.402838 0.407469 -0.579188 -0.780295 -0.235966 0.778029 -0.602345 -0.178473
--0.389986 -0.91729 0.0805604 -0.365704 -0.683289 -0.631962 0.744031 -0.644087 0.177679
-0 -0.993263 0.115881 0.112211 -0.94756 0.29923 0.879996 0.118177 0.460046
-0.693532 -0.704541 0.150449 -0.725772 -0.652632 0.217544 -0.815089 -0.565128 0.127516
--0.168956 -0.92926 0.328526 0.816034 0.1515 0.557796 -0.935008 -0.189282 0.299887
-0.575748 0.663926 -0.477197 -0.710934 0.680731 -0.176572 0.946574 0.153445 0.28364
-0.446711 0.893423 0.0473785 -0.685454 0.697804 -0.2079 0.604175 -0.648929 0.462455
-0.847875 -0.529405 0.0289518 0.86957 -0.48236 -0.105723 -0.817904 -0.505664 0.274477
-0.655328 0.602811 0.455153 -0.665534 0.543604 0.511428 0.719596 0.474341 0.507131
--0.725722 0.302971 0.617686 -0.974869 0.141911 0.171733 0.815892 -0.565685 -0.119664
--0.642664 -0.731708 0.227126 0.92752 -0.209047 0.30985 -0.608522 0.0747307 0.790011
--0.394443 0.661272 0.63807 -0.295373 0.945194 0.139154 -0.78874 0.613802 0.0337069
--0.385115 0.135504 -0.912866 -0.221351 0.544863 -0.808782 -0.0461717 0.998767 0.0182257
-0.416136 0.808493 0.416136 -0.826732 0.300275 0.475761 -0.963011 -0.249362 0.10212
-0.886783 -0.446581 0.119088 0.854321 -0.0678032 0.515305 0.224021 0.950944 0.213353
-0.46955 0.812992 0.344336 0.641377 0.408994 0.649123 -0.8007 0.402122 0.444046
-0.902565 0.357773 -0.239532 -0.307914 -0.902323 -0.301667 -0.241942 -0.957545 -0.156751
-0.958194 -0.283909 -0.0354887 -0.498761 -0.546262 0.672931 0.166099 -0.861342 0.480105
--0.0416921 -0.481354 0.875534 -0.920533 0.38377 -0.0730684 0.612958 -0.290349 -0.734833
--0.343579 -0.343579 -0.874017 -0.511089 -0.584102 -0.630565 -0.609956 -0.43874 -0.659894
-0.603958 -0.795944 -0.0413304 -0.917812 -0.12132 0.378026 0.931316 -0.334376 -0.144373
-0.674781 0.687675 -0.267907 0.537652 0.752712 -0.379941 -0.560346 0.828218 -0.00820018
-0.586744 0.757878 -0.285223 -0.714804 -0.0238268 -0.698919 0.790435 -0.59912 0.127544
--0.562124 0.811274 0.160782 0.154868 -0.542037 0.825961 0.668151 0.70991 0.222717
--0.240452 0.951187 -0.193456 -0.429097 0.894287 0.126991 -0.335591 -0.929912 -0.150475
--0.210184 0.97459 -0.0774362 -0.760155 -0.305761 -0.573301 0.479909 -0.87477 0.0668227
--0.721273 0.656607 -0.220527 -0.357147 0.664399 0.656521 0.28204 0.378991 0.881374
-0.702879 -0.711184 -0.0133378 0.713275 0.394178 0.579536 -0.685865 0.727432 -0.0207838
--0.568874 0.733732 -0.37151 0.371274 0.85945 0.351429 -0.715244 0.694207 -0.0806402
--0.175969 0.907842 -0.380601 0.698151 -0.713006 -0.0648637 0.389244 0.758469 -0.522699
-0.953043 -0.0914082 -0.28871 0.636914 0.756475 0.148613 0.00965772 0.950078 -0.311864
--0.274688 0.864996 -0.419915 -0.161561 0.98637 0.0311784 0.659398 -0.67938 -0.321928
-0.535644 -0.84238 0.0590073 -0.347294 -0.88035 -0.323064 -0.607834 -0.487768 -0.626594
--0.154945 -0.985868 0.0636907 -0.615443 -0.553899 -0.560737 -0.464606 -0.872205 -0.152968
-0.359253 0.146086 -0.921735 0.0444477 0.112427 -0.992665 -0.355045 -0.0730133 -0.931994
-0.0674104 0.269642 -0.960598 -0.191121 0.210233 -0.958788 -0.228765 0.591634 -0.773069
-0.00978398 0.743583 -0.668572 0.437264 0.896952 -0.0654027 0.415123 0.909468 -0.0232384
--0.538665 0.819915 -0.193856 -0.551434 0.797567 -0.244556 0.595659 -0.0374086 -0.802366
-0.414913 -0.827079 -0.379192 0.30393 -0.649204 -0.697252 0.542147 -0.715456 -0.44068
--0.522983 0.298517 -0.798359 -0.0838339 0.854366 -0.512866 0.257119 0.817507 -0.515337
--0.301512 0.819938 -0.486612 0.115936 0.830872 -0.544253 -0.568658 0.434602 -0.69839
--0.129469 0 -0.991583 0 -0.286888 -0.957964 0.396823 -0.235874 -0.887071
-0.455331 -0.659765 -0.597816 -0.0958466 -0.443734 -0.891018 0.492498 0.357252 -0.79361
--0.245426 -0.47449 -0.845355 0.115963 0.552531 -0.825386 0.419206 0.375752 -0.826484
-0.693484 -0.1517 -0.70432 -0.116862 0.629659 -0.768032 -0.205244 0.840999 -0.500595
-0.576685 0.0678454 -0.814144 -0.199622 0.829201 -0.522089 0.0382157 0.636928 -0.769975
--0.132784 0.708183 -0.69343 -0.509512 0.445823 -0.735962 0.551977 -0.296608 -0.779324
--0.621821 -0.74489 0.241819 0.173984 -0.951112 0.255176 0.0641335 0.689436 -0.721502
-0.384586 0.590081 -0.709858 -0.977292 0.141508 0.157723 -0.254904 -0.892165 0.372915
--0.299088 -0.94711 -0.116312 -0.326407 -0.940819 0.0912019 0.633746 -0.660714 -0.402272
-0.768 -0.6 -0.224 0.26906 -0.858646 0.436272 -0.570063 -0.819726 -0.0554806
--0.399285 -0.613471 -0.681341 0.514472 0.35586 -0.780181 0.833419 0.44824 -0.323255
-0.84591 0.422955 -0.324878 -0.745351 -0.643481 -0.174311 0.507703 0.58509 -0.632382
-0.641742 0.647196 -0.411466 -0.846289 -0.531477 -0.0364195 -0.0377937 0.259517 -0.964999
-0.474143 0.720697 -0.505752 0.811386 -0.298932 0.502287 0.319102 -0.78366 0.532964
--0.326634 0.0130654 -0.945061 0.480956 0.775735 -0.408554 0.816645 0.576703 -0.0224507
--0.831019 -0.250951 0.496417 -0.490006 -0.601371 -0.631068 0.893498 0.0845509 -0.441036
-0.763268 -0.637292 -0.106215 -0.0642451 -0.936143 -0.3457 -0.431452 -0.748863 -0.503044
--0.796918 -0.446582 -0.4068 0.886277 -0.276366 0.371665 -0.426638 -0.781221 -0.455712
-0.607777 0.00542658 -0.794089 0.802224 0.36572 -0.471896 -0.869659 0.49359 0.00783477
--0.71059 0.688726 -0.14394 0.885195 -0.42083 -0.198322 0.587107 -0.569098 0.575701
-0.561558 0.505402 0.65515 0.815869 0.273909 -0.509247 -0.98744 0.143628 0.0658293
--0.773334 -0.559509 -0.298167 -0.643952 -0.13365 -0.753302 -0.0106825 -0.758459 -0.651634
--0.0861221 0.5844 0.806882 0.89086 0.222715 0.395938 0.414513 -0.612759 0.672834
--0.933702 0.322464 0.155617 0.403577 -0.828969 -0.387216 -0.589968 -0.543392 -0.597213
-0.0960738 0.288221 0.952732 -0.759953 -0.595639 0.260164 0.058722 -0.998274 0
--0.823847 -0.561068 0.0804908 -0.0323125 0.972067 -0.23247 -0.555582 0.694477 -0.457198
--0.971022 -0.0357431 -0.236302 -0.924955 -0.295986 -0.238433 -0.22434 -0.931012 0.287903
-0.933969 0.324859 0.148894 0.851205 0.206353 -0.482564 -0.753044 -0.331278 0.568489
-0.750727 -0.034124 0.65973 -0.625343 -0.606951 0.490465 -0.446065 -0.592582 0.670725
--0.923537 -0.0157474 0.383186 -0.341077 0.420397 0.840793 0.207583 0.928019 0.309339
-0.548625 0.648375 0.527844 0.970118 0.191682 -0.148761 0.246795 0.943394 0.221585
--0.805546 0.109847 0.582262 -0.0574128 -0.80059 0.596456 0.939336 -0.34205 -0.0254657
--0.611717 -0.694063 0.379578 0.00944936 -0.982733 0.184787 0.837139 -0.335124 -0.432309
-0.867052 -0.144121 -0.476917 -0.62838 -0.583709 0.51422 -0.814936 -0.382599 0.435313
--0.762198 -0.396171 0.51196 0.666667 -0.133333 -0.733333 0.0066872 -0.595161 0.803579
--0.264305 -0.816942 0.512591 -0.624136 -0.289599 0.725663 0.322258 -0.314065 0.893036
--0.396763 -0.523727 0.75385 0.0234246 -0.726164 0.687123 0.174694 -0.744069 0.644859
-0.699113 0.636239 -0.326253 0.710531 -0.4222 -0.562933 -0.492213 -0.118658 0.862349
--0.155189 -0.731085 0.664403 -0.310017 -0.75782 0.574106 -0.852302 -0.171869 0.494006
--0.0637487 -0.812796 0.57905 0.22359 0.941931 -0.250547 -0.644618 -0.738952 -0.196006
-0.506935 0.76695 -0.393452 -0.467142 0.27479 -0.840398 -0.200632 -0.72536 -0.658483
--0.191611 -0.8191 -0.540704 0.358312 -0.879151 -0.314177 0.143058 0.839276 -0.524548
--0.461237 -0.864036 -0.201748 -0.550213 -0.431616 -0.714824 -0.269224 -0.423066 -0.865179
-0.0698754 -0.635866 0.76863 0.172456 -0.426183 0.888047 0.66742 0.725401 -0.168358
-0.386712 0.858631 -0.336461 -0.576683 0.384455 -0.720854 -0.435259 -0.0423404 -0.899309
--0.155511 -0.459672 0.874367 -0.433461 -0.791066 0.431655 -0.604078 0.745775 0.280909
--0.996926 -0.0772811 -0.0128802 -0.060117 -0.865685 0.496967 0.6506 0.74819 -0.13012
--0.50084 -0.797035 -0.337483 -0.98064 0.0492949 0.189512 0.0126828 -0.674 -0.738622
-0.6305 -0.339879 0.697819 0 -0.472408 0.88138 -0.445054 -0.376861 0.812344
-0.573308 0.806359 0.145269 -0.317861 0.946014 0.063428 0.555598 0.811046 0.183071
-0.554127 0.829097 0.0744419 -0.390133 -0.23242 0.890942 -0.908379 -0.416506 -0.0370227
--0.768679 -0.361731 -0.527525 0.404002 -0.404002 -0.820709 0.513144 -0.372556 -0.77323
-0.542005 -0.527357 -0.654313 -0.347528 -0.538328 -0.767742 -0.286044 -0.618654 -0.731741
--0.156417 -0.449142 0.879662 0.284843 -0.0931216 0.95404 -0.397439 0.228527 0.888717
--0.152511 0.0538274 0.986835 -0.258021 -0.488103 0.833775 -0.840079 0.294433 0.455606
--0.931626 0.2465 0.267042 0.473692 0.68183 0.557426 0.225875 -0.309977 0.923523
--0.779569 -0.550896 0.297969 0.389904 -0.322095 -0.862687 -0.457239 -0.452489 -0.765628
--0.769422 -0.129357 0.625505 0 -0.454739 0.890625 0.712958 -0.235879 0.660343
-0.590895 -0.401198 0.699916 -0.692747 0.161911 0.70277 -0.347437 -0.820281 0.454341
-0.488719 -0.57264 0.658207 -0.153549 0.472832 0.867671 -0.243055 -0.884449 0.39834
--0.0845631 0.819611 -0.566645 0.735378 0.1329 -0.664498 0.241294 -0.487415 -0.839168
--0.343322 -0.672138 -0.656019 -0.365424 -0.637432 -0.67834 -0.0832131 0.254534 0.963477
-0.120501 -0.271127 0.954971 0.309647 -0.465699 0.829001 0.604564 -0.310033 0.733745
-0.325999 -0.10161 0.939894 0.338341 0.931664 0.132394 0.71773 -0.118145 0.686225
--0.242618 -0.679331 0.692565 0.516544 0.843397 -0.147862 0.484088 0.633273 -0.603842
-0.661233 0.418971 -0.622281 0.31461 0.750833 -0.58075 -0.206203 0.904889 -0.372366
-0.0224029 0.847576 -0.530201 -0.190866 0.438992 -0.877984 0.275766 -0.529172 -0.802453
-0.31833 -0.48339 -0.815475 0.0705311 -0.712364 -0.698257 -0.131773 -0.779013 -0.613004
--0.193575 -0.71323 -0.67367 -0.489911 0.553631 0.67341 -0.276104 -0.516582 0.810499
--0.285549 -0.095183 0.953626 -0.0892342 0 0.996011 0.539156 -0.589431 0.601566
--0.474298 -0.380462 0.793908 -0.986091 -0.152084 0.0670476 0.420109 0.904591 -0.0722769
-0.441151 0.893024 -0.0888429 -0.43675 0.780551 -0.447202 0.415877 -0.883738 -0.214603
--0.188738 0.924816 -0.330292 0.121147 0.987349 -0.102302 -0.779696 0.60643 0.155939
--0.48517 -0.749809 -0.449885 -0.381799 0 0.924245 0.494724 -0.169152 0.852429
--0.456887 -0.45452 0.764635 0.0189 -0.7686 0.63945 -0.305122 0 0.952313
--0.883178 -0.0334176 0.467846 0.975461 0.0248701 0.218765 0.696289 0.690828 0.194779
-0.443242 0.89612 -0.0224833 -0.369419 -0.181656 -0.911335 0.451936 -0.885795 -0.105452
--0.72774 -0.610632 0.312287 0 -0.61519 -0.788379 0.133662 -0.61917 -0.773798
-0.113717 -0.760903 -0.638824 -0.369801 -0.665642 -0.648204 -0.0342371 -0.725827 0.687025
--0.167154 -0.297295 0.94004 0.16328 -0.569211 0.805815 0.743706 0.424975 0.516041
-0.490768 -0.208642 0.84594 0.287294 -0.721474 -0.63003 -0.742765 -0.427652 -0.515184
--0.676961 0.132552 0.723985 -0.164613 -0.420322 0.892318 -0.572824 -0.329707 0.750444
-0.272078 -0.743681 0.610665 0.659524 0.544182 0.51855 0.339597 0.25412 0.905592
--0.245284 -0.531449 0.810801 -0.310388 -0.843483 0.438401 -0.955175 -0.212261 -0.206365
--0.783488 0 0.621407 -0.31772 0.926235 0.202838 -0.397139 0.917528 0.0205417
-0.400384 0.85243 0.336236 0.123878 0.916698 0.379893 -0.310369 -0.846462 0.432636
-0.845257 0.432523 0.313791 0.655033 0.74668 0.115764 -0.407329 -0.878302 0.250337
-0.991945 -0.101338 0.0760036 -0.997329 0 0.0730367 0.898404 0.431997 0.0790521
--0.727004 0.2812 0.626412 -0.975467 -0.00950748 -0.21994 0.728168 0.102717 0.677658
-0.59963 -0.237136 0.764337 -0.766545 0.178928 0.61676 0.568873 -0.644363 0.511057
--0.0122066 -0.772068 0.635422 -0.331944 -0.881242 0.336491 -0.0746191 -0.983867 0.162596
--0.859657 -0.459269 0.223746 0.799719 0.517609 -0.304188 0.646401 -0.609812 0.458579
--0.432498 -0.900382 -0.0475093 -0.364245 0.610786 -0.70304 -0.915037 -0.174293 0.36377
-0.824065 0.560746 -0.0804965 -0.489021 0.789957 -0.3699 0.975721 -0.136391 0.171363
--0.853388 0.426694 -0.299434 0.608354 -0.01767 0.793469 0.659089 0.0063374 0.752038
--0.948889 0.289914 0.124741 -0.314891 0.944674 0.0918433 0.831238 0.465312 -0.304185
-0.094667 0.9493 -0.299779 0.809295 -0.012302 0.587273 -0.845043 -0.423074 0.326971
-0.808137 -0.493278 -0.321855 -0.129371 0.954112 -0.270062 -0.873153 0.293771 0.388975
--0.916029 0.373197 -0.147017 -0.573422 -0.798089 0.185045 -0.728867 -0.684582 -0.0100463
-0.662043 0.367159 0.65337 0.0576586 0.897827 0.436558 -0.932517 0.345674 -0.104506
-0.773286 -0.594163 0.221355 -0.160785 0.920046 0.3573 -0.652284 -0.489828 0.578441
--0.719465 -0.527608 0.451664 -0.197394 -0.958769 0.204443 0.625048 -0.644351 0.440598
--0.450171 -0.467825 0.760583 -0.681206 -0.390797 0.619061 -0.269787 -0.926849 0.261084
-0.488812 -0.852821 0.183738 0.24203 -0.96812 0.0645413 0.152247 0.792952 -0.589956
--0.1013 0.964653 -0.243274 0.36482 0.781757 -0.505729 0.120654 0.890714 0.43826
--0.750137 0.641055 -0.162306 -0.300564 0.826551 -0.475893 0.889031 0.457648 0.0135305
-0.0175601 -0.807767 -0.589241 -0.627992 -0.250176 -0.736912 -0.832573 -0.0101197 -0.553822
--0.180239 0.959128 -0.218146 -0.975822 0.203105 0.0807432 0.446144 0.892288 0.0691209
--0.18645 -0.849383 -0.493747 -0.47971 -0.830184 -0.284029 -0.873968 -0.0771149 0.479826
--0.812278 0.330308 0.48073 0.642143 0.762545 0.0785956 0.685601 0.713303 -0.145431
-0.293974 0.551202 0.780869 -0.42041 -0.371525 0.827783 0.728482 0.0466762 -0.683473
--0.891428 -0.445714 -0.0818219 0.916834 -0.00274091 0.399259 0.532432 -0.846287 -0.0177477
-0.494079 -0.868381 0.0424209 -0.487983 0.486076 0.724985 0.620801 0.558721 0.549942
-0.311032 -0.948301 -0.0631279 0.699592 -0.699592 -0.145405 0.584159 -0.767357 -0.264427
-0.425544 -0.830331 -0.35981 0.464224 -0.858815 -0.216638 -0.188658 -0.981024 -0.044719
--0.659388 -0.746212 -0.0915165 0.771295 -0.290089 -0.566527 0.48177 0.404687 -0.777256
--0.194547 0.960578 -0.1986 -0.0345892 0.992606 0.116346 0.330335 0.739792 0.586163
--0.554409 0.671126 0.492159 0.104307 0.382459 0.918066 -0.464886 0.757472 0.458385
-0.696904 -0.420772 0.580754 0.82618 -0.563304 -0.0107296 -0.701191 -0.643716 -0.306531
--0.637416 -0.762623 -0.11003 0.58002 0.305686 -0.755071 0.385464 0.566682 -0.72821
-0.488593 0.576477 -0.654944 0.232487 0.854254 -0.464974 0.864582 0.27765 0.418818
--0.717908 0.683609 0.131478 0.481512 -0.502773 0.71789 0.654403 -0.364243 -0.662634
-0.566525 0.446772 -0.692419 -0.334364 -0.675893 0.656787 0.383583 -0.280166 0.879984
--0.82266 0.558234 0.107729 0.157532 0.984574 0.0761404 0.0894869 0.995541 0.029829
--0.456209 0.82688 -0.328851 -0.873372 0.487054 0 0.61682 0.106348 0.779887
-0.906605 -0.215459 0.362829 -0.735083 -0.479402 0.479402 -0.697206 -0.681626 0.222015
-0.337685 -0.92096 -0.194425 -0.78914 -0.39457 -0.470715 -0.451943 0.795246 -0.404142
-0.423041 0.867963 -0.260146 0.0770327 -0.99661 0.0288872 0.182021 -0.982915 0.0273032
--0.406562 -0.877078 -0.255814 0.998458 -0.0264492 0.0488051 -0.985628 -0.0467954 0.162321
--0.225258 -0.946086 -0.232767 0.908438 -0.417071 -0.0281424 0.19366 -0.937125 0.290332
-0.384013 -0.776411 -0.49972 0.370627 0.688307 -0.623594 0.881539 -0.467803 0.0636275
--0.935347 0.289678 -0.203008 0.930651 -0.101641 0.351509 -0.990077 0.12673 0.0607247
-0.505532 -0.767014 0.395129 0.780537 -0.617513 -0.0971554 -0.87798 0.432438 0.205299
-0.0433967 -0.902651 0.42818 0.291171 -0.934174 0.206246 0.979034 -0.19221 0.067442
--0.933366 0.35779 -0.0285195 0.978478 0.181628 -0.0979368 0.976701 0.111094 0.183614
-0.722059 -0.499788 0.478375 0.726421 0.682865 0.0775144 0.275503 0.771407 0.573611
-0.117289 0.640673 0.758803 0.217482 -0.931812 0.290565 0.109131 -0.992576 0.0536996
--0.850588 0.514502 0.108571 -0.755283 0.422272 0.501233 0.795559 0.595362 -0.112382
--0.965902 0.0616179 0.251468 0.393091 -0.91277 -0.111043 0.627833 0.623675 0.465677
-0.815527 0.547 0.188964 -0.129827 0.536618 0.833778 -0.629313 0.0646238 0.77446
--0.627186 -0.677179 0.384795 0.142175 -0.95994 0.241455 0.838717 -0.279572 0.467325
--0.828097 0.559978 -0.0260671 -0.793616 0.605257 0.0619489 -0.732389 0.642249 -0.226102
--0.919556 0.276615 -0.279107 -0.80546 0.577246 0.134243 0.85064 -0.515539 -0.103108
--0.529412 0.705882 0.470588 0.204655 0.708985 0.674875 -0.0936265 0.206624 0.973931
--0.430175 -0.0977054 0.897442 -0.87821 -0.40941 0.247247 0.817799 -0.572902 0.0546677
-0.274368 -0.00783907 0.961593 0.468355 0.212223 0.857674 -0.867086 -0.412898 -0.278706
-0.333247 0.773089 0.539704 -0.738222 0.0025812 0.674553 -0.729397 -0.388927 0.562775
--0.0345494 -0.958747 -0.282154 -0.759089 -0.498152 -0.41908 -0.883272 0.430186 -0.186469
-0.782948 -0.445471 0.434221 -0.702032 0.226257 0.675247 -0.818275 0.221564 0.53041
--0.759455 -0.607564 0.232583 0.038568 -0.994504 -0.0973383 0.741072 -0.553145 -0.380582
--0.402702 -0.434919 -0.805405 -0.591824 -0.313319 -0.742681 0.179559 -0.193371 -0.964555
-0.779622 -0.507457 0.366984 -0.0705151 -0.564121 0.822676 0.555662 0.789844 0.259586
-0.701905 0.712266 -0.00259006 -0.393066 -0.426583 -0.814571 -0.638362 -0.0640302 -0.767069
--0.156625 0.86731 -0.472485 -0.154957 0.923893 -0.349871 -0.566104 0.299702 -0.767923
--0.0540124 -0.900207 0.432099 0.717203 0.646973 0.258931 0.0387284 0.96821 -0.247124
--0.852252 0.233952 -0.467903 0.770828 -0.513885 -0.376492 -0.433293 0.0772538 -0.897936
--0.441542 -0.532343 -0.722254 0.586711 0.369167 -0.720754 -0.597891 -0.0128579 -0.801474
-0.817247 0.0674791 -0.572323 -0.284468 -0.924521 -0.253651 -0.0394122 -0.992603 -0.114831
-0.586584 -0.782685 -0.208143 0.210896 -0.723071 -0.657793 0.784555 -0.564991 -0.255458
--0.985826 0.125934 -0.110848 0.428532 0.836033 0.342651 0.544306 0.834603 0.0846699
--0.0273532 0.877789 0.478266 0.213399 0.87769 0.429093 -0.616112 0.724439 -0.309184
-0.725074 0.623471 0.292493 0.158607 0.929215 0.33377 0.241388 0.836883 0.491283
-0.277472 0.501692 0.819337 -0.586161 0.806416 0.0781548 -0.76939 0.377436 0.515346
-0.999076 0 -0.042971 0.901624 -0.276498 -0.332599 0.674453 0.551825 -0.490511
--0.302206 0.910816 -0.28122 -0.823832 0.322169 -0.466378 0.54395 0.390528 -0.742701
--0.786183 0.293769 -0.543706 0.923501 0.340491 0.17667 0.972855 0.221754 0.0661684
-0.249189 0.386672 0.887913 0.461058 0.675504 0.57543 -0.07817 -0.986144 -0.146318
--0.251057 -0.502114 -0.827558 0.781083 0.414068 -0.467395 0.162452 0.699794 -0.695628
-0.389264 -0.528137 -0.754682 -0.636464 -0.603463 -0.48036 0.922692 0.168944 -0.346551
--0.218208 0.877029 0.428024 0.0545856 0.846076 0.53026 -0.968434 -0.220467 -0.11632
-0.783573 -0.602749 -0.150687 0.166574 -0.760448 -0.627672 0.318941 0.528531 -0.786722
-0.707104 -0.335421 -0.622493 0.531772 -0.335856 -0.777444 0.705496 -0.264561 -0.657483
-0.90796 -0.0974804 -0.407561 0.141996 -0.812534 -0.565355 0.12281 -0.973037 -0.195237
--0.830287 -0.0919985 -0.549691 -0.907136 0.412125 -0.0851879 0.813701 0.28835 -0.504723
--0.980578 0.155423 0.119629 -0.21579 0.951074 0.221118 0.884389 -0.365954 -0.289714
-0.175323 0.91001 -0.375692 -0.294649 0.955378 -0.0208338 0.803538 0.583107 -0.119636
--0.0328396 0.97026 0.239828 -0.762362 0.39702 0.511057 -0.644103 0.644103 -0.412629
--0.861474 0.501651 0.0787934 0.757674 0.631395 -0.165134 -0.173715 0.98398 -0.0400881
-0.0590994 0.98105 0.184521 -0.485725 0.794409 0.364672 -0.601819 0.71081 0.364093
-0.0892751 0.982026 0.166297 0.755531 -0.458715 0.46771 -0.778652 0.593134 0.204679
-0.253929 0.948003 0.191858 0.253345 0.957082 0.140747 -0.01281 0.999179 0.03843
--0.784161 0.61138 -0.106327 -0.472775 0.8678 0.152994 -0.20039 0.901035 0.384682
--0.450055 0.725713 0.520376 -0.466501 0.641439 0.609043 -0.307698 -0.946762 -0.0946762
-0.606794 0.794186 0.0327193 -0.768634 0.409112 0.491761 -0.83657 0.375603 0.398841
-0.0107634 0.8826 0.470002 -0.305333 0.395137 0.866394 0.0352067 0.95058 0.308477
-0.69164 0.332688 0.641056 0.845559 0.383356 0.371575 0.673364 -0.424423 0.605348
-0.810594 0.583705 0.0471877 0.558877 0.0745169 0.825896 -0.753087 0.423041 0.503881
-0.457134 -0.0489787 0.888048 -0.556414 -0.529127 0.640647 -0.88778 0.333531 0.317181
--0.997911 0.0636821 -0.0108395 -0.0206386 -0.97591 0.217196 0.576738 -0.814743 -0.059724
--0.688388 0.697176 0.20017 0.46534 0.850908 0.24375 0.204143 0.74805 0.631464
-0.620335 0.592866 0.513512 -0.0176425 -0.970336 0.241114 0.792424 -0.255187 0.554025
--0.988113 -0.0306392 -0.150643 -0.291551 0.892875 0.34318 0.188902 -0.981878 0.0152229
-0.992506 0.0577038 0.107714 -0.903829 0.0703452 -0.422071 0.506059 -0.857637 0.0914458
-0.888234 -0.41419 -0.198715 0.0314464 0.993183 0.112246 0.0985576 0.995086 -0.00950994
-0.00309445 0.996412 0.0845815 0.0966845 0.995281 0.00821502 0.970079 -0.0928306 -0.22434
-0.0858495 0.985225 0.148193 0.459898 -0.813099 0.356881 0.420206 -0.452529 0.786539
--0.67743 -0.658185 0.328451 -0.603843 -0.738414 0.300196 0.538519 -0.817208 0.20535
--0.856362 0.486709 -0.172505 0.440858 -0.896412 0.0457186 -0.496167 -0.857016 -0.139077
--0.493412 -0.695837 -0.521878 0.121931 0.738758 -0.66285 0 0.69568 -0.718351
-0.117862 0.833876 -0.53922 -0.301478 0.836417 -0.457731 0.415422 0.671664 -0.613427
-0.431768 -0.895729 0.106048 0.732543 0.0261622 -0.680218 -0.0326107 -0.605627 -0.79508
--0.827311 -0.15551 -0.539791 0.779259 -0.610771 0.140407 0.529982 -0.714323 -0.457013
-0.54406 -0.746676 -0.382718 0.444184 -0.895533 -0.026866 -0.612625 -0.722253 -0.321001
-0.471829 0.688978 -0.55017 -0.223669 0.688465 -0.689919 -0.13129 0.774159 -0.619226
-0.0911533 0.299504 -0.949731 0.892607 -0.318788 -0.318788 0.0223457 -0.938521 -0.344497
--0.444963 -0.874583 -0.192647 -0.60169 -0.575867 -0.553486 0.342074 0.724872 -0.597951
--0.270215 0.628249 -0.72958 0.121069 0.407716 -0.905047 -0.23157 0.605852 -0.76113
--0.342352 0.569403 -0.747379 0.117507 0.568803 -0.814036 0.023847 0.7614 -0.647843
--0.526226 0.585519 -0.616648 -0.231181 0.854087 -0.46593 -0.784243 0.54556 -0.295512
-0.9009 -0.345628 -0.262526 -0.35482 -0.906762 -0.227786 -0.227612 -0.699695 -0.677215
-0.202606 0.162084 -0.965753 0.331769 0.539125 -0.774128 0.330417 0.788996 -0.517987
-0.22223 0.864528 -0.450783 -0.0817823 0.324208 -0.942444 0.112184 0.518025 -0.847977
--0.129178 0.172871 -0.976437 -0.715707 0.486015 -0.50155 0.0109128 0.979177 -0.202714
--0.10432 0.799788 -0.591148 -0.33193 -0.86539 -0.375397 0.188744 0.0330303 -0.981471
-0.475564 0.466758 -0.745638 0.464235 0.714406 -0.523554 0.182576 0.845068 -0.50252
-0.0765634 0.796955 -0.599166 -0.168661 0.748856 -0.640912 -0.0476265 0.483069 -0.874286
-0.356329 -0.344451 -0.868552 -0.390794 0.256037 -0.884152 -0.696654 0.171308 -0.696654
--0.126787 0.235461 -0.963578 -0.803303 0.087633 -0.589089 -0.98186 -0.11417 0.151381
--0.191918 -0.967673 0.163636 -0.00956072 -0.984755 0.173686 -0.389125 0.243203 -0.888501
--0.574119 -0.812714 0.0994146 0.00366827 0.201755 -0.979429 0.243627 0.705803 -0.665198
-0.427219 0.759135 -0.491119 -0.337822 0.445311 -0.829201 0.186444 0.445845 -0.875477
-0.329095 0.329095 -0.885095 -0.285756 0.417995 -0.862336 0.312529 0.659652 -0.683509
--0.428604 -0.898519 0.0946715 0.889324 0.0896797 -0.448398 -0.474634 0.443728 -0.76015
-0 -0.241626 -0.970369 0.664454 0.45961 -0.589287 0.0151411 0.847901 -0.529938
-0.101695 0.38983 -0.915254 0.0947333 0.271776 -0.957686 0.334016 0.513871 -0.79017
--0.798846 -0.589048 0.121934 0.652356 -0.753425 -0.0823527 0.478811 -0.806061 0.34786
-0.552936 0.535923 -0.638003 0.430075 -0.900803 0.0599109 -0.812626 0.58231 -0.0235386
-0.739027 0.451547 -0.499944 0.0858603 -0.932198 0.351618 0.592979 -0.662741 -0.45733
-0.229178 -0.965324 -0.125006 -0.865837 0.151789 -0.476745 -0.290488 0.544665 -0.786738
-0.566408 0.82264 0.0494483 0.238092 0.965783 -0.102838 -0.931211 0.271112 -0.243608
-0.913181 0.391363 0.11373 0.844132 0.522029 0.122177 -0.85241 -0.522741 -0.0118208
-0.773164 0.629435 -0.0776468 0.42169 -0.901543 0.0969401 -0.40193 -0.818801 0.409899
-0.877593 -0.00566189 -0.479373 0.996265 -0.0797012 -0.0332089 -0.630452 -0.302759 0.71475
-0.469776 -0.058722 0.88083 0.885716 -0.36621 0.285303 0.806559 -0.12566 -0.577644
--0.0478107 -0.273204 0.960767 -0.125909 -0.924588 0.359562 0.739254 -0.576042 0.348825
-0.810052 -0.236301 -0.536635 0.851356 -0.0949053 -0.515931 0.8308 -0.200538 -0.519187
--0.981549 0.0885608 0.169468 -0.779176 0.446306 0.440108 -0.266874 0.951168 0.155106
--0.220171 0.798397 0.560435 -0.198288 0.925346 0.323137 -0.313712 0.686775 0.655686
--0.669239 -0.540294 0.5101 -0.528226 0.136947 0.837988 -0.711376 0.643626 0.282292
--0.868 -0.432311 0.244301 -0.64222 -0.725087 0.248601 0.0137037 -0.986669 0.162161
--0.429028 -0.899734 0.0800853 -0.796435 -0.584053 0.156759 -0.930467 -0.266065 0.251875
--0.928756 -0.321726 0.184132 -0.459829 -0.887945 -0.0105708 0.65052 -0.359335 -0.669106
--0.595695 -0.689505 0.411983 -0.592954 -0.67838 0.433828 -0.932875 -0.201208 0.298764
--0.548243 0.146952 0.823307 -0.124359 0.683972 0.71883 -0.622472 0.77809 0.0842931
-0.294561 -0.13105 -0.946604 0.434018 0.648209 0.625663 0.560395 0.557255 0.612719
--0.768221 0 0.640184 -0.0907617 0.0819377 0.992496 -0.794135 -0.560566 0.234767
-0.744918 -0.157802 -0.648225 0.267261 -0.455916 -0.848947 -0.2543 -0.736411 -0.626921
-0.195894 -0.138278 -0.970827 -0.435293 -0.114005 0.893041 0.0790537 -0.837969 0.539961
--0.345503 -0.877873 0.331611 -0.773505 -0.630704 0.0624754 -0.194607 0.7914 -0.579495
-0.463032 -0.40981 -0.785912 -0.53091 -0.3492 0.772136 -0.48301 -0.802979 0.34918
--0.373332 -0.919782 0.120931 -0.691705 -0.620847 -0.368909 -0.378586 0.107728 0.919276
-0.772425 0 0.635105 0.311129 -0.677475 -0.666503 0 -0.913276 -0.407341
-0.69236 0.437533 -0.573761 -0.426071 -0.809534 -0.403879 0.51719 -0.292749 -0.804247
--0.275126 -0.776825 0.566435 -0.641663 -0.278551 -0.714617 0.420445 -0.544391 -0.725855
-0 -0.352946 -0.935644 0.399175 -0.536822 -0.743291 -0.378509 -0.485634 -0.787966
--0.564532 0.0903252 0.820454 0.00265338 -0.934652 0.355553 -0.0899031 -0.611341 0.786244
--0.8985 -0.252409 0.359149 0.673672 0.688717 -0.26802 -0.294485 -0.0631039 -0.95357
--0.830727 -0.420057 -0.365301 0.658488 0.719872 0.219496 -0.213353 0.963834 0.159703
--0.627803 0.700068 0.340248 0.546366 -0.561496 -0.621456 0.397347 -0.397347 -0.827182
--0.363614 -0.886822 0.285187 0.898894 -0.254554 0.356641 0.506943 -0.699884 0.50316
--0.573804 -0.538189 -0.617334 -0.483412 -0.0303714 -0.874866 0.598451 -0.619825 0.507615
-0.832499 0.445981 0.328705 -0.691032 -0.707291 0.149046 0.172447 -0.172447 -0.969806
--0.147857 -0.535454 -0.831521 -0.796696 -0.534456 0.282193 -0.197786 -0.928159 0.315279
-0.780603 -0.617143 0.0989653 0.820248 -0.568277 0.0652267 -0.973758 -0.0226455 0.226455
-0.919315 0.315586 0.235088 -0.600009 0.695182 -0.395868 0.307166 -0.557185 -0.771488
--0.357909 -0.586027 -0.726962 -0.991927 0.0148882 0.12593 -0.0436156 0.992255 -0.116308
-0.112852 0.94439 -0.308857 0 -0.699193 -0.714933 0.425581 -0.816792 0.389526
-0.554604 -0.805184 0.209984 -0.249555 -0.960203 0.125428 -0.907917 -0.0466872 0.416542
--0.819624 -0.015762 0.572686 0.897071 -0.135263 0.420675 -0.184387 0.964488 -0.189115
-0.785175 0.141838 -0.602812 -0.138233 0.990354 -0.00946802 -0.189037 -0.578924 0.793166
-0.80907 0.367141 0.458926 0.712364 0.274947 0.64571 -0.0772307 -0.724038 0.685423
--0.537326 -0.828757 0.156341 0.644661 0.764466 0.00190166 -0.633842 -0.741595 0.219732
--0.918632 -0.260508 -0.29707 -0.7758 -0.123306 -0.618813 -0.869091 -0.364103 -0.334829
-0.974566 -0.0251501 0.222683 0.856428 0.260562 0.445689 0 0.286582 0.958056
--0.622242 -0.656182 0.426896 -0.357277 -0.849524 0.388152 0.37847 0.879466 0.288617
-0.498339 0.839761 0.215544 -0.144164 -0.677962 0.720822 0.23215 -0.747922 0.621868
--0.0706076 -0.723728 0.686463 -0.717444 0.105168 0.688631 -0.689846 0.489349 0.533526
--0.731974 -0.671632 0.114562 0.0533486 0.906926 0.417897 0.494058 0.56507 0.660759
-0.729844 0.00793309 0.683568 -0.482697 -0.848026 -0.218757 -0.419436 -0.885477 -0.200009
--0.00301935 0.960153 0.279458 0.440196 0.752001 0.490635 -0.518201 0.782381 0.345467
--0.205353 -0.966659 0.152971 0.211218 -0.766884 0.606033 -0.834638 0.244123 0.493745
-0.799797 -0.307182 0.515716 0.527763 -0.0232623 0.849073 0.32594 -0.211257 0.921484
--0.274095 -0.713168 0.645185 -0.883103 -0.186223 0.43064 -0.551854 -0.827781 -0.101173
-0.968937 0.238534 0.0652922 -0.743488 0.529791 0.408102 0.545829 -0.433453 0.71707
--0.0797452 0 0.996815 0.391437 -0.669001 0.631834 -0.994407 -0.0678005 0.0809839
-0.652413 -0.609865 0.449913 -0.0276256 -0.910692 0.412161 -0.462232 -0.850126 0.252242
-0.270156 -0.689204 0.672319 -0.107629 0.522768 0.845654 -0.85372 0.357847 -0.378295
-0.362319 -0.687358 0.629495 0.0133976 -0.697707 0.716258 0.0683529 -0.772767 0.630998
-0.0312361 -0.777431 0.628192 -0.367265 -0.477998 0.797894 -0.38953 0.174335 0.904364
--0.158268 0.939195 0.304735 -0.657367 -0.734704 0.167564 0.338555 -0.63728 0.692283
-0.862128 0.00451376 0.50667 0.623929 -0.736236 0.26205 0.290356 -0.758885 0.582912
-0.778424 -0.346822 0.523231 -0.606172 -0.589621 0.533762 0.75355 -0.58685 0.29626
-0.246752 -0.809346 0.532984 -0.52009 -0.821074 0.235252 -0.709675 -0.68583 0.161238
-0.724845 -0.50997 0.463175 -0.916951 -0.395842 0.0501066 0.676329 0.736447 -0.0150295
-0.767536 -0.167899 0.618626 -0.726525 -0.676171 0.122286 0.807047 0.590411 -0.00949268
-0.536529 0.75552 -0.375935 0.189109 0.866118 0.462686 0.442605 -0.872192 0.208285
-0.762131 -0.568369 -0.31002 -0.913272 -0.258988 -0.31442 0.69705 -0.0279752 0.716477
-0.789299 -0.613216 0.0311944 0.605487 -0.630201 0.486037 0.760199 -0.612195 0.21752
--0.0822578 0.740321 0.667202 -0.856848 0.386508 -0.341209 0.413355 0.908883 0.0554045
-0.863375 -0.234283 0.446873 0.839448 -0.395966 0.372208 0.172774 0.777482 0.604708
--0.370247 0.887797 0.273373 -0.0265889 0.868572 0.49485 -0.703839 0.614933 -0.355624
-0.703157 -0.559768 0.438439 -0.295777 -0.371963 0.879863 -0.402732 -0.826118 0.394127
-0.751439 -0.644091 0.143131 -0.202927 0.96954 -0.137164 0.159409 0.299785 -0.940594
--0.345135 0.446563 0.825508 -0.755784 0.644915 0.113472 -0.0127457 -0.939996 0.340948
-0.554481 -0.73529 -0.389744 0.0383201 0.996322 -0.0766402 0 -0.993884 0.110432
-0.0623914 0.0594204 0.996281 -0.198595 -0.0379667 0.979346 -0.552502 -0.357105 0.753139
-0.95364 -0.283515 0.100948 0.0788381 -0.996887 -0.00103734 -0.623823 -0.516158 -0.586879
-0.619117 -0.711247 -0.332898 -0.587694 0.350116 -0.729407 0.425525 -0.633559 -0.646167
--0.792719 0.125052 -0.596623 0.549647 0.682485 0.48177 0.284613 0.868068 0.406759
-0.125081 0.646252 0.752803 -0.482884 0.46248 0.743596 0.0495907 0.963994 -0.261258
--0.220279 0.885436 -0.409244 -0.769262 -0.210159 -0.603382 0.463245 0.863706 -0.198534
-0.457551 0.889148 0.00801034 0.106283 0.978284 0.177943 -0.824598 0.385214 0.414305
--0.970146 -0.233118 0.0668742 0.99625 0.0510898 -0.0698227 -0.35326 0.855806 0.377895
--0.221715 0.565373 0.794478 -0.193881 0.320325 0.927255 -0.925243 0.0155069 0.379057
--0.843303 0.0018575 -0.537435 -0.894793 -0.13778 -0.424691 0.799902 0.47053 -0.372503
--0.316261 0.67903 0.662493 0.597121 0.11642 0.793658 -0.584023 0.460358 0.668572
--0.651687 0.267705 0.709675 0.730825 0.375507 0.56999 0.678212 0.452142 0.579306
-0.440507 0.652459 0.616645 -0.343026 0.883311 0.319524 0.00573542 0.81443 0.580234
--0.074976 0.995877 -0.0510706 0.256632 0.946919 -0.193609 0.713131 0.671647 -0.200836
-0.233665 0.826294 -0.512483 -0.883754 0.0489375 -0.465386 0.536882 -0.649454 -0.538486
--0.412153 0.527015 0.743226 0.47761 0.365454 0.798957 -0.198993 0.979813 0.0191922
-0.83459 -0.316449 0.45091 0.520414 0.122544 0.845075 0.585649 0.151293 0.79632
--0.742989 -0.398677 -0.53761 0.250072 0.953478 0.168357 -0.0907066 0.379318 0.920809
-0.0711989 -0.750327 0.657221 0.238656 -0.765445 0.59761 -0.858499 -0.505471 -0.086474
--0.148188 0.254037 0.955775 0.230954 0.798552 0.555855 -0.227606 0.878812 0.419385
-0.830754 -0.527494 0.177759 0.483491 -0.84246 0.237692 -0.547495 -0.79833 -0.250835
--0.596855 -0.778153 -0.195557 0.657571 0.553195 0.511444 -0.588348 0.784465 0.196116
-0.751382 -0.253756 -0.609125 0.69777 0.279108 -0.659709 0.569258 0.597721 -0.564514
-0.57905 0.539268 0.611466 0.355506 -0.0334594 0.934075 -0.695148 0.718065 0.0339511
-0.258622 0.862073 0.435826 -0.32263 0.897752 -0.299919 -0.594266 0.779492 -0.198089
--0.906621 -0.139084 -0.398364 0.426953 -0.760511 0.489218 -0.229504 -0.944247 -0.236062
--0.527683 -0.828512 -0.187401 -0.532891 -0.444664 -0.719932 -0.352344 -0.932926 -0.0741776
--0.257656 -0.96621 -0.00715711 -0.25711 -0.939012 -0.228365 -0.969541 0.153364 -0.19097
-0.799125 -0.599344 0.0467573 0.777426 -0.628471 0.025166 -0.966318 -0.256574 -0.0199928
-0.894109 0.296593 -0.335562 0.690268 -0.711399 -0.132067 0.686383 -0.11969 -0.717323
-0.713259 0.632277 -0.302469 -0.712278 0.651226 -0.261847 0.255656 -0.941177 -0.220965
-0.828486 0.555535 0.0706461 -0.666811 -0.742253 -0.0665188 0.837255 0.52587 -0.149886
--0.935068 -0.289133 -0.205059 0.703161 -0.689533 -0.173519 -0.949556 -0.0091597 -0.313465
-0.590602 0.309984 0.74505 -0.830706 -0.480177 0.281704 0.508962 -0.840972 0.18364
-0.259785 0 -0.965666 0.837165 0.429937 0.338096 -0.454403 -0.495712 0.740126
--0.77485 -0.478956 -0.412563 -0.0814985 -0.995301 0.0522949 0.714269 0.236299 -0.658774
--0.634238 -0.369972 0.678869 0.781088 0.618361 0.0867875 0.474481 0.800686 0.365746
-0.520859 -0.129625 0.843744 0.90976 0.304175 0.282514 -0.746589 -0.603824 0.279288
-0.126534 -0.989943 -0.063267 -0.503895 -0.852012 -0.142002 0.410782 -0.898505 -0.15475
--0.356862 -0.172444 -0.918103 0.655409 0.607867 0.448259 -0.46487 -0.542042 0.700061
-0.00422915 -0.90081 -0.434193 -0.191351 -0.867457 -0.459242 0.821086 -0.454422 -0.345425
--0.546042 0.58859 -0.596154 -0.93058 0.113535 -0.348038 -0.753609 -0.628008 -0.194111
-0.438023 0.109506 0.892269 0.777655 0.330412 0.534866 -0.889174 -0.0967962 -0.447213
-0.160625 -0.103259 -0.981599 -0.0679258 -0.666908 -0.742038 -0.728188 0.305994 0.613279
--0.833474 -0.0123217 0.552422 -0.107566 0.0759289 0.991294 -0.180939 -0.719548 0.670456
--0.350117 -0.73456 0.58124 0.775063 0.60803 -0.171976 0.547788 -0.620137 -0.561568
--0.852937 -0.0140401 -0.521824 -0.941919 -0.217366 0.256009 0.682862 -0.72604 0.0810265
-0.226125 -0.767773 0.599494 -0.77116 -0.632747 0.0703052 0.881302 0.375022 -0.287517
-0.886711 0.28195 -0.366398 0.880522 0.266924 -0.391705 0.329377 -0.838118 -0.434821
--0.0988595 -0.97384 -0.204605 -0.467157 -0.647056 -0.602564 0.463428 0.868927 -0.173785
--0.538635 0.817571 -0.203591 0.504489 -0.246379 -0.827519 -0.159358 -0.830206 -0.534194
--0.520467 -0.546931 -0.655729 0.395295 0.796767 0.45706 -0.168681 0.984547 0.0470471
--0.256167 0.966621 0.004627 0.989896 -0.134516 0.0448385 -0.826469 0.373294 0.421427
-0.343333 -0.924358 -0.166385 0.844812 -0.0808081 -0.528926 -0.666903 0.283434 -0.689134
-0.999991 -0.00306746 -0.00306746 0.970461 -0.206424 -0.124882 -0.19123 -0.956151 0.221827
--0.207602 0.851885 -0.480826 -0.936313 0.317231 -0.150605 0.106412 -0.127695 -0.986088
--0.680817 0.732192 -0.0195712 0.139002 -0.914116 -0.380882 0.911713 0.363804 -0.190858
--0.0763092 0.985661 -0.150499 -0.0643992 0.965988 -0.250441 -0.532559 0.817202 -0.220369
-0.0588725 0.408645 0.910793 -0.376454 0.792696 0.479494 0.564532 0.8054 -0.18065
-0.888415 0.376903 -0.262037 0.042241 0.995884 -0.0801862 0.978205 -0.0670004 -0.196534
-0.558875 0.62795 0.541607 0.362945 0.798117 0.480917 -0.342674 0.920935 -0.185615
-0.686221 0.721715 0.0907074 0.728373 0.681881 -0.067155 0.296334 0.931334 -0.211667
--0.560047 0.665716 0.493123 -0.728108 0.6721 0.134687 0.809224 0.325276 0.489237
-0.26383 0.906776 0.328863 -0.983703 0.14414 0.107479 -0.429642 0.839754 0.331996
--0.563812 0.82589 0.00459786 -0.812234 0.54149 0.216943 0.298822 0.914343 0.273281
-0.258055 0.918501 0.299606 0.892747 0.334366 0.301996 -0.85362 0.219279 0.472493
--0.700469 0.62234 0.349337 0.724669 0.537697 0.430972 -0.851145 -0.338675 0.401063
-0.452102 0.322536 0.83161 0.640457 0.751488 -0.158367 -0.418052 -0.8813 -0.220325
--0.341742 -0.93979 -0.00251281 0.932318 -0.334771 -0.136788 -0.147033 0.952039 0.268335
--0.43836 -0.769566 0.464337 0.170428 0.806892 0.565579 0.381367 0.560659 0.734998
-0.368843 -0.319411 0.872887 -0.24938 -0.798426 0.54802 -0.0984517 -0.950836 0.293628
-0.66899 -0.561804 0.48665 -0.573497 0.517834 -0.634783 -0.934294 0.219331 -0.281048
-0.566153 -0.781677 -0.261631 0.839666 -0.138027 -0.525271 -0.312362 0.94996 0.00261234
-0.910303 -0.40317 0.0938195 0.401091 -0.0668485 0.913596 -0.754771 -0.55993 0.341759
--0.994941 0.0826658 -0.0570787 0.725394 0.6883 0.00686926 0.265795 0.9093 0.320198
-0 -0.185408 0.982662 -0.368689 -0.345428 0.862988 -0.823699 -0.0296295 0.566252
--0.706004 -0.644612 -0.293316 -0.313848 -0.849235 -0.424617 0.157286 0.259059 0.952969
--0.568035 0.0908856 0.817971 0.897795 -0.439829 0.0226716 -0.304582 0.64458 0.701246
--0.241642 0.283963 0.927887 -0.393831 0.65717 0.64267 -0.384949 0.88418 0.264652
-0.501991 -0.00994041 -0.864816 0.892835 0.275335 0.356421 0.996713 0.0228604 0.0777253
-0.235249 0.88545 0.400794 0.0265536 0.862992 -0.504519 -0.461695 0.619809 -0.634567
-0.015591 0.930263 -0.366562 -0.279485 -0.960092 0.0105233 -0.274154 -0.961669 0.00568194
--0.201044 -0.979353 0.0211785 -0.0885584 -0.996071 0 0 -1 0
-0 -0.999816 -0.0191892 -0.0667311 -0.997587 -0.0191465 -0.0785018 -0.996512 -0.0283222
-0 -0.999901 -0.014081 0.111426 -0.993624 -0.0171897 0.182745 -0.983081 0.0124766
-0.14425 -0.988923 0.0349697 0.209281 -0.975923 0.061447 0.20126 -0.977087 0.0692509
-0 -0.995197 0.0978883 -0.10444 -0.974769 0.197275 0 -0.983175 0.182666
-0 -0.990057 0.140664 0.0975198 -0.991451 0.0866843 -0.446082 -0.894992 0
--0.465128 -0.885243 0 -0.308237 -0.951157 -0.0170229 -0.263313 -0.964684 0.00718127
-0.1499 -0.983638 0.0999335 0.0198833 -0.994163 0.106044 -0.0851522 -0.991866 0.0946136
-0.354005 -0.919619 0.170241 0.608501 -0.760931 0.22519 0.607536 -0.761714 0.225149
--0.682813 -0.716331 0.143649 -0.43741 -0.874004 0.211633 0.30826 -0.943021 0.12525
-0.695662 -0.664041 0.274049 -0.564745 -0.825265 0 -0.610299 -0.792104 0.0102787
--0.46671 -0.884401 -0.00408499 0.430166 -0.866834 0.252104 0.146086 -0.980865 0.128695
--0.235457 -0.963758 0.125423 -0.698113 -0.704852 0.125786 0.796187 -0.442326 0.412837
-0.73523 -0.487031 0.471421 0.825203 -0.255697 0.503645 0.0075539 -0.89136 0.453234
--0.712932 -0.697357 0.0736295 -0.669195 -0.738447 0.0829133 0.863017 -0.249821 0.439079
-0.924922 -0.0660658 0.374373 -0.725353 0.565463 0.392574 -0.532116 -0.821564 0.20466
--0.668001 -0.705112 0.237892 0.336973 -0.937546 0.0863569 0.399804 -0.914306 0.0648134
--0.328104 -0.944567 0.0118388 -0.388972 -0.92125 0 -0.437541 -0.898948 0.0212141
-0.842528 -0.454397 0.289257 -0.919454 -0.060292 0.388549 -0.916877 -0.297229 0.266443
-0.614886 -0.788568 0.0086409 0.769212 -0.638913 -0.0101843 -0.489603 -0.870405 0.0518098
--0.517831 -0.854646 0.0378242 -0.475235 -0.879761 -0.0131553 -0.454792 0.773371 -0.441658
-0.457439 0.470894 -0.754327 0.637711 0.755443 -0.150434 0.195588 0.97794 -0.0733455
--0.351294 0.91877 -0.180151 0.569061 -0.803759 0.173612 -0.73254 -0.656961 0.17829
-0.15325 -0.973776 0.168149 -0.661326 -0.726081 0.188294 0.883769 -0.459398 -0.0889158
-0.908735 -0.400459 -0.117617 -0.487417 -0.870388 0.0696311 -0.486002 -0.872009 0.05833
-0.30655 0.892601 -0.330593 0.287824 0.897735 -0.33351 0.198127 0.936202 -0.290295
-0.140983 0.94177 -0.305276 0.0184246 0.95071 -0.309534 -0.266425 0.916503 -0.298396
--0.439484 0.867163 -0.23427 -0.453132 0.863108 -0.22297 0.928792 -0.271056 -0.252733
--0.708115 -0.624926 -0.328695 -0.366922 -0.927089 0.0766459 0.975779 -0.110088 -0.18904
--0.515842 -0.851813 0.0912198 -0.894821 -0.434946 0.100591 0.168938 -0.985625 0.00180683
-0.610801 -0.790751 0.0404458 0.62596 -0.778972 0.0370939 -0.679775 -0.722261 0.127458
--0.474595 -0.877109 0.0737466 0.460456 0.850674 -0.253641 0.29013 0.924335 -0.24785
-0.180154 0.948812 -0.259422 0.165823 0.939665 -0.299219 0.282149 0.900644 -0.330502
--0.455763 0.862374 -0.220434 -0.311262 0.92517 -0.217201 -0.24785 0.95001 -0.189871
--0.214222 0.959033 -0.185375 -0.184099 0.796646 -0.575728 0.589037 -0.674199 -0.445523
--0.0897068 -0.937437 -0.336401 0.961929 0.166077 -0.217051 -0.987045 0.150574 0.0554062
-0.604209 -0.796135 0.0331723 0.544451 -0.83808 0.0345683 -0.28431 -0.948035 0.142823
--0.222907 -0.964731 0.140025 0.149932 -0.97456 0.166591 -0.448672 -0.88538 0.12164
-0.327741 0.853608 -0.404893 0.356679 0.857281 -0.37128 0.427049 0.847627 -0.314894
-0.479715 0.839502 -0.255168 -0.180057 0.964724 -0.19206 -0.17241 0.949471 -0.262258
--0.401497 0.867562 -0.293492 -0.390424 0.877381 -0.278874 0.879973 0.436878 -0.186507
--0.8848 0.465867 0.00985042 0.536194 -0.843495 0.0318177 0.605344 -0.794767 0.0436388
-0.616143 -0.78655 0.0413109 -0.609367 -0.781239 0.135415 -0.454729 -0.878828 0.144508
--0.333345 -0.935307 0.118666 0.596007 0.736388 -0.320169 0.359282 0.851087 -0.382842
--0.381715 0.880964 -0.279637 -0.388603 0.850528 -0.354387 -0.421969 0.843939 -0.331223
--0.430517 0.844565 -0.318378 -0.111816 0.901373 -0.418359 0.764673 0.614553 -0.193905
-0.875611 0.446136 -0.185119 -0.87505 0.483939 0.009489 -0.87991 0.475038 0.00987847
-0.583376 -0.811049 0.043256 0.455673 -0.888468 0.0546554 -0.784014 -0.607878 0.125727
--0.812292 -0.56948 0.125995 0.52514 0.8029 -0.2821 0.470129 0.831596 -0.295679
-0.588126 0.743735 -0.317752 -0.329969 0.889279 -0.316708 -0.0609368 0.962802 -0.263247
--0.0487821 0.963446 -0.263423 -0.26952 0.919791 -0.285207 -0.465079 0.84739 -0.256188
--0.106709 0.895169 -0.432764 0.619572 0.756938 -0.207787 0.687799 0.699214 -0.195019
--0.90749 0.418979 -0.0303091 0.398396 -0.915758 0.051644 0.452701 -0.891031 0.0335334
-0.526696 -0.849625 0.02701 -0.846911 -0.50641 0.162144 0.632236 0.632236 -0.447834
-0.0810448 0.921649 -0.379466 0.311677 0.885447 -0.344734 0.533229 0.797007 -0.283632
--0.467859 0.846086 -0.255435 -0.257223 0.932138 -0.254863 -0.105308 0.967076 -0.231677
--0.149137 0.955078 -0.256094 -0.234589 0.927496 -0.291064 -0.210937 0.922849 -0.322265
-0.462607 0.856168 -0.230153 0.607283 0.764151 -0.217441 -0.915423 0.401011 -0.0345132
--0.917805 0.394702 -0.0429383 0.545751 -0.837912 0.00765966 0.536292 -0.837903 -0.101538
-0.514291 -0.852072 -0.0973555 -0.438949 -0.893575 0.0940605 -0.643464 -0.747248 0.166055
-0.331179 0.804293 -0.49339 0.652385 0.671787 -0.350849 -0.167097 0.925588 -0.339655
--0.139846 0.929562 -0.341113 -0.277767 0.902352 -0.329555 -0.162397 0.924959 -0.343624
-0.042895 0.93654 -0.347926 0.197486 0.895271 -0.399361 0.0469726 0.935839 -0.349284
-0.206169 0.91721 -0.34091 0.452113 0.861337 -0.231715 -0.906546 0.412737 -0.0884435
-0.478404 -0.874821 -0.0762803 0.525524 -0.849231 -0.0512869 0.582049 -0.812504 -0.0325002
--0.674652 -0.73764 0.0270694 -0.745972 -0.665709 0.0188854 0.565346 0.785774 -0.250884
-0.545339 0.80327 -0.239507 0.336209 0.906564 -0.255159 0.504298 0.800663 -0.323452
--0.863022 0.501553 -0.0603085 0.674282 -0.738209 -0.019787 0.792273 -0.607985 -0.0515567
--0.83483 -0.548247 0.0498406 0.640116 0.735073 -0.223426 0.569923 0.786184 -0.238962
--0.860948 0.505315 -0.058522 -0.828601 0.553486 -0.0841081 0.847111 -0.511494 -0.144143
-0.838008 -0.525074 -0.148458 -0.845244 -0.528173 0.0812146 0.607048 0.767285 -0.2068
-0.56719 0.795933 -0.211626 0.637268 0.737754 -0.222729 -0.873019 0.481051 -0.0801752
--0.889695 0.44926 -0.0812946 0.720579 -0.633612 -0.281605 0.559646 -0.819889 -0.12074
-0.563916 -0.818588 -0.109145 -0.846393 -0.523492 0.097849 -0.838657 -0.535475 0.0996064
-0.778682 0.597046 -0.192849 0.722873 0.660975 -0.201412 -0.944739 0.320337 -0.0696634
-0.635403 -0.769735 -0.0614203 0.706902 -0.706216 -0.0393486 -0.747686 -0.657963 0.0897223
-0.84117 0.510537 -0.178283 -0.985739 0.165025 -0.0329462 0.82516 -0.564333 0.0252922
-0.842692 -0.537594 0.0293678 -0.766405 -0.637963 0.0750128 0.879043 0.439522 -0.184673
-0.843606 0.506872 -0.177228 -0.98623 0.1627 -0.029661 0.892631 -0.450742 -0.00643918
--0.787627 -0.611447 0.0759991 -0.844881 -0.529365 0.0771261 0.879973 0.436878 -0.186507
--0.987768 0.15465 -0.0199549 -0.985775 0.165093 0.0315033 0.901295 -0.433181 -0.00465786
-0.906341 -0.422545 -0.0011836 -0.894208 -0.440431 0.0800783 0.917305 0.346811 -0.195637
-0.882356 0.432583 -0.185256 -0.996776 -0.0190001 0.0779493 0.860584 -0.507798 0.0391984
--0.875593 -0.477047 0.0759135 0.914808 0.347158 -0.206418 -0.918262 -0.375653 0.125218
--0.647596 0.627359 0.432481 -0.574074 0.683601 0.450698 -0.628074 0.664893 0.404278
--0.658946 0.629894 0.411126 0.833918 -0.547733 0.0675979 0.840194 -0.537841 0.0692894
--0.895805 -0.441217 0.0534809 0.914241 0.355832 -0.19377 -0.958697 -0.265429 0.102213
--0.485848 -0.696872 0.527562 -0.374688 -0.745019 0.551866 -0.538516 -0.66768 0.514008
-0.915806 -0.384406 0.116326 -0.911935 -0.4079 0.0446234 0.946198 0.252955 -0.201799
-0.916367 0.351076 -0.192397 -0.980923 -0.115036 0.156704 -0.462568 -0.72496 0.510357
-0.938309 -0.327317 0.11153 0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338
-0.951038 0.208849 -0.227835 -0.973728 -0.156552 0.165366 0.935161 -0.334447 0.116703
--0.947121 -0.318063 0.0424084 -0.946323 -0.320875 0.0388939 0.939721 0.268262 -0.21204
--0.970249 -0.173227 0.169145 0.937562 -0.330556 0.108213 -0.940597 -0.336391 0.0460259
-0.938056 0.283766 -0.198817 -0.970969 -0.173905 0.164244 0.942445 -0.316493 0.107842
-0.94166 -0.319294 0.106431 -0.942007 -0.332123 0.0481338 0.965795 0.178257 -0.188318
-0.94359 0.267626 -0.194972 -0.958271 -0.238916 0.156961 0.932844 -0.333618 0.136021
--0.955365 -0.292313 0.0427776 -0.964187 -0.262245 0.0396281 0.977703 0.0987872 -0.185307
--0.927979 -0.331878 0.169444 0.934909 -0.329621 0.131511 -0.967903 -0.24577 0.0525545
-0.982451 0.085296 -0.165878 -0.9542 -0.24866 0.166347 0.939229 -0.315413 0.135511
-0.937489 -0.317879 0.141657 -0.968373 -0.243346 0.0550971 0.983436 0.0874351 -0.158771
--0.970969 -0.173905 0.164244 0.951928 0.306221 -0.00782675 0.744662 0.667362 0.0103067
--0.447367 0.858657 -0.250141 -0.920055 0.277962 -0.276109 0.930883 -0.332917 0.150409
--0.959368 -0.259522 0.11073 0.980586 0.0876947 -0.175389 -0.984588 -0.0919425 0.148774
-0.972924 0.205659 -0.105466 -0.939769 -0.284404 -0.189602 0.91166 -0.378968 0.158931
--0.95251 -0.284331 0.108994 -0.94166 -0.319294 0.106431 0.976638 0.0810446 -0.199021
--0.960915 -0.208065 0.182621 0.807409 0.585228 -0.0748237 -0.999142 -0.0344532 0.0229688
-0.907595 -0.389554 0.156585 0.898921 -0.414243 0.14263 -0.935161 -0.334447 0.116703
-0.968309 -0.00756491 -0.249642 -0.943049 -0.298862 0.146083 0.827908 0.551939 -0.0996556
-0.829409 0.553701 -0.0741315 -0.988999 0.0766979 0.126484 0.923209 -0.350874 0.156754
--0.938228 -0.330791 0.101521 0.81747 0 -0.575971 0.886783 -0.136041 -0.441712
-0.953334 -0.135022 -0.270043 -0.914936 -0.375234 0.148631 0.979671 0.163446 -0.116317
--0.963879 -0.205729 0.169155 0.970969 -0.173905 0.164244 -0.942445 -0.316493 0.107842
--0.94166 -0.319294 0.106431 0.940581 -0.229456 -0.250316 -0.915144 -0.379766 0.135234
--0.912054 -0.39573 0.107493 0.975988 -0.184472 -0.115832 0.994562 -0.07154 -0.0756873
--0.924056 -0.334353 0.185281 -0.96241 -0.212743 0.168844 0.973323 -0.159799 0.164642
--0.932844 -0.333618 0.136021 0.958965 -0.188685 -0.211623 -0.929024 -0.353084 0.110664
-0.981489 0.19151 0.00177324 -0.914695 0.195669 0.353619 0.927322 -0.339685 0.157127
--0.942986 -0.305259 0.132647 0.967742 -0.176726 -0.179562 -0.944318 -0.324169 0.0563772
-0.778301 0.622885 -0.0791354 0.799704 0.595128 -0.0793504 -0.8851 0.366684 0.286604
--0.827431 0.48322 0.286107 -0.5688 -0.724941 0.388494 0.558626 0.791388 0.248278
-0.034426 0.998353 0.0459013 -0.617527 -0.693453 0.371191 0.920138 -0.349707 0.176216
--0.936023 -0.320393 0.145633 -0.927877 -0.338893 0.155552 0.979754 -0.101184 -0.172753
-0.981068 -0.085914 -0.173564 -0.938781 -0.343883 0.0208414 0.886292 0.462413 -0.0256896
--0.678384 -0.345007 0.648664 -0.819457 -0.320657 0.475047 -0.940819 -0.210288 0.26578
-0.686347 0.630996 0.361624 0.751684 0.602857 0.267457 0.706789 0.660391 0.25364
--0.819705 0.102463 0.563547 -0.8922 -0.181026 0.413774 -0.627888 -0.689446 0.361138
-0.933945 -0.320608 0.157981 -0.918705 -0.372095 0.13239 0.981989 -0.0742681 -0.173727
--0.917171 -0.398376 0.00965761 0.947075 0.290642 0.136296 -0.226875 -0.948751 0.22
--0.557122 -0.793708 0.244218 0.587346 0.306441 0.749079 0.874185 0.417752 0.247557
--0.906806 -0.303399 0.292664 -0.913171 -0.31716 0.255985 0.927322 -0.339685 0.157127
--0.956602 -0.274784 0.0969827 0.94461 -0.272176 -0.183391 -0.933106 -0.359366 0.0130463
--0.943618 -0.330819 0.0119795 0.368099 -0.609268 0.70235 0.913666 0.201007 0.353284
--0.66647 -0.719787 0.194228 -0.65525 -0.721163 0.224879 -0.297492 -0.946762 0.12305
-0.898269 0.175236 0.402994 0.92303 0.26147 0.282221 0.910131 0.340691 0.23578
--0.414276 -0.659075 0.627691 -0.768872 -0.586989 0.253535 -0.867554 -0.438009 0.23558
-0.920138 -0.349707 0.176216 -0.982641 -0.175995 0.0586652 0.91092 -0.365516 -0.19137
--0.969412 -0.230631 0.0839648 -0.755723 -0.432203 0.49202 0.948314 0.0278916 0.316105
--0.785132 -0.42864 0.44703 0.556362 -0.568725 0.605816 0.656064 -0.498123 0.566969
-0.276547 -0.769146 0.576139 -0.543138 -0.78524 0.297319 0.970969 -0.173905 0.164244
--0.982995 -0.179131 0.0404011 0.929544 -0.325885 -0.172474 -0.928036 -0.356484 0.108025
--0.781546 -0.390773 0.486295 0.32972 -0.74187 0.583879 0.982172 -0.0879557 0.166139
--0.984305 -0.174911 0.0234358 0.925966 -0.337834 -0.168689 0.922301 -0.342488 -0.17906
--0.840928 -0.522527 0.140736 0.960749 -0.239534 0.139946 -0.995476 -0.0885055 0.0345593
-0.893041 -0.408998 -0.187614 -0.8376 -0.529841 0.133024 -0.899114 -0.436794 0.0283632
-0.935161 -0.334447 0.116703 -0.997618 0 0.0689857 0.843606 -0.506872 -0.177228
-0.84233 -0.508536 -0.178528 -0.994726 -0.101503 -0.014764 0.344364 0.0153051 0.938711
-0.384816 0.25161 0.888037 0.45747 0.0714796 0.886348 0.334283 -0.276146 0.90111
-0.388453 -0.371265 0.843367 -0.0610664 0.692086 0.719227 0.341072 -0.259577 0.903488
--0.531593 0.607067 0.590659 -0.487994 -0.350143 0.799538 -0.848697 -0.414609 0.328348
-0.963556 -0.255241 0.0800755 -0.994649 0 0.103311 0.886275 -0.419608 -0.196078
--0.437057 0.874115 -0.211907 0.405084 0.914226 0.00991031 0.488817 0.86761 0.091162
-0.210173 0.928038 0.307526 -0.469168 0.310748 0.82663 0.0414232 0.925119 0.377412
--0.66882 0.299209 0.680554 -0.802416 0.0272005 0.596145 -0.797353 -0.246454 0.550898
-0.144292 -0.272552 0.95126 0.319219 -0.520209 0.792137 0.0466797 -0.855794 0.515206
--0.598057 -0.628148 0.497754 0.994258 -0.089038 0.0593587 -0.994649 0 0.103311
-0.816194 -0.5454 -0.190699 0.813785 -0.548357 -0.192508 -0.67218 -0.640671 -0.371099
--0.557019 -0.768686 -0.314406 -0.0780157 -0.84517 -0.528773 -0.740772 -0.666695 0.082308
-0 -0.853639 -0.520865 0 -0.999504 0.0314805 0 -0.994853 0.101328
-0 -0.909398 0.415926 0 -0.934997 0.354654 -0.147687 -0.912182 0.382248
--0.837426 -0.233381 0.494218 0.995086 0 0.0990135 -0.994649 0 0.103311
-0.835057 -0.518216 -0.184747 -0.926832 -0.344868 -0.148485 -0.0234658 -0.863541 -0.503732
--0.00729327 -0.99772 0.0670981 0.0127155 -0.925688 0.378074 0.995086 0 0.0990135
--0.994649 0 0.103311 0.820178 -0.547229 -0.166876 0.811536 -0.559388 -0.168805
--0.956952 -0.264351 -0.119839 -0.982107 -0.175595 -0.0680601 0.995086 0 0.0990135
--0.994649 0 0.103311 0.803754 -0.56963 -0.17176 -0.932644 -0.351766 -0.0802274
-0.994258 0.089038 0.0593587 -0.994649 0 0.103311 0.797774 -0.57796 -0.171809
-0.754661 -0.632201 -0.175526 -0.297991 -0.736701 -0.60702 -0.39539 -0.691932 -0.604067
-0.0430287 -0.774517 -0.631088 0.48321 -0.683083 -0.547637 0.485352 -0.7371 -0.470232
-0.578083 -0.662522 -0.476323 -0.928843 -0.368139 -0.0415336 -0.975413 -0.220063 0.0118953
-0.98126 0.175193 0.0802233 -0.994649 0 0.103311 0.718864 -0.672108 -0.177497
-0.695091 -0.695091 -0.183567 -0.551784 -0.551784 -0.625355 -0.58159 -0.63064 -0.513855
--0.626391 -0.584163 -0.516128 0 -0.40364 -0.914918 -0.245541 -0.613852 -0.750264
-0.773549 -0.0521494 -0.631587 -0.627189 -0.137893 0.766564 -0.935451 0.350794 0.0433079
--0.898769 0.436471 0.0413227 0.982812 0.158012 0.0954571 -0.994649 0 0.103311
-0.185375 0.17796 0.96642 0.857402 -0.483663 0.175877 -0.338906 0.897994 0.280623
--0.712029 0.66542 0.224121 -0.780361 0.588177 0.212333 0.695091 -0.695091 -0.183567
-0.695091 -0.695091 -0.183567 -0.40364 0 -0.914918 -0.613852 -0.245541 -0.750264
-0 0 -1 0.382859 -0.316729 -0.867814 0.6379 -0.38274 -0.668276
--0.837997 0.535257 -0.106115 0.979643 0.159679 0.12166 -0.994649 0 0.103311
-0.738928 -0.627898 0.244395 -0.713958 -0.294895 0.63506 -0.909343 0.239301 0.340339
-0.695091 -0.695091 -0.183567 0.673365 -0.714803 -0.188773 -0.564888 -0.451911 -0.690419
--0.522083 -0.540085 -0.660104 0 -0.342852 -0.939389 -0.229748 -0.742263 -0.629493
-0.0276674 -0.774687 -0.631739 0.58132 -0.72818 -0.36307 0.529586 -0.781548 -0.329728
--0.912074 0.372537 -0.171281 -0.961153 0.247659 -0.121864 0.973547 0.173 0.149255
--0.994649 0 0.103311 0.748742 -0.614416 0.248752 0.635278 -0.541163 0.550967
-0.674978 -0.528131 0.51525 0.4346 -0.39114 0.811253 0.647272 -0.736992 -0.194632
-0.592917 -0.77952 -0.201986 -0.374299 -0.374299 -0.848411 -0.522083 -0.540085 -0.660104
--0.484928 -0.464723 -0.740863 0 0 -1 -0.32432 -0.32432 -0.888613
--0.15923 -0.641385 -0.750514 0.129084 -0.619922 -0.773973 0.547381 -0.800591 -0.243777
-0.437088 -0.782692 -0.443111 0.570316 -0.795567 -0.204483 0.571862 -0.794706 -0.20351
--0.940204 -0.335531 -0.0586132 0.971269 0.176995 0.15909 -0.991959 -0.073494 0.103032
-0.890045 0.193488 0.412774 -0.601734 0.657157 0.45394 -0.559559 0.742089 0.36905
-0.593383 -0.776323 -0.212648 0.690387 -0.682013 -0.241294 0.695867 -0.676604 -0.240784
--0.334529 -0.559575 -0.758265 -0.351027 -0.604546 -0.715055 -0.229748 -0.742263 -0.629493
--0.511382 -0.665985 -0.543095 0 0.208691 -0.977982 0.576997 -0.552269 -0.601726
-0.695706 -0.683943 -0.219579 0.765076 -0.601888 -0.228887 -0.88332 -0.466227 -0.04877
--0.696474 -0.717474 0.012444 0.982172 0.0879557 0.166139 -0.991745 -0.0846403 0.0963246
-0.80803 0.512788 0.290062 -0.0340272 0.782625 0.621563 -0.650659 0.679684 0.338633
--0.575574 0.698237 0.425652 0.573936 -0.783507 -0.238148 0.570736 -0.786242 -0.23682
--0.304518 -0.790296 -0.531697 -0.352924 -0.764669 -0.53919 -0.269052 -0.739894 -0.616578
--0.336836 -0.759934 -0.555916 0.22181 -0.208763 -0.95248 -0.201876 -0.232063 -0.951521
-0.689665 -0.515507 -0.508541 0.911446 -0.334489 -0.239547 -0.32526 -0.94218 0.0806431
--0.310025 -0.947492 0.0783771 -0.513201 -0.857889 0.0255324 0.985993 0 0.166785
--0.995816 0 0.0913839 0.922812 -0.350879 0.159065 -0.769477 -0.246993 0.588982
--0.680666 -0.490079 0.544533 0.607283 -0.764151 -0.217441 0.598502 -0.772542 -0.21207
--0.266017 -0.752103 -0.602972 -0.278994 -0.80958 -0.516471 -0.404761 -0.769046 -0.494708
--0.0803889 -0.840429 -0.535926 -0.334393 -0.759983 -0.557321 0.968851 -0.186702 -0.162698
--0.442193 -0.895896 0.0428444 -0.484923 -0.87324 0.0479871 -0.375434 -0.9257 0.0461502
--0.346325 -0.934029 0.0874559 0.985993 0 0.166785 -0.991745 0.0846403 0.0963246
-0.492928 -0.860757 0.126966 0.0776973 -0.99064 0.112229 -0.0571247 -0.991282 0.11873
--0.493055 -0.84793 0.19471 -0.653859 -0.553454 0.515904 0.590372 -0.780377 -0.20609
-0.572871 -0.793442 -0.205594 -0.324841 -0.593574 -0.736307 -0.45913 -0.688695 -0.561159
--0.404494 -0.674157 -0.617977 -0.281767 -0.569727 -0.772022 -0.350017 -0.725961 -0.592004
-0.985853 -0.159009 -0.0530029 -0.864813 -0.480157 0.146788 -0.692506 -0.714244 0.101443
-0.983335 -0.0733832 0.166335 -0.991959 0.073494 0.103032 0.00402836 -0.993661 0.112346
-0.587596 -0.69129 -0.420535 0.58271 -0.785392 -0.208824 0.56284 -0.791292 -0.238892
-0.562033 -0.79094 -0.241935 -0.226493 -0.82773 -0.513385 -0.241248 -0.861599 -0.446595
--0.365597 -0.8165 -0.446841 -0.0694331 -0.883694 -0.462887 -0.292104 -0.823202 -0.48684
--0.431539 -0.721202 -0.541887 0.961957 -0.269611 0.0441523 -0.73451 -0.576341 0.358227
--0.952994 -0.155379 0.260117 0.970003 -0.163404 0.179981 -0.994649 0 0.103311
-0.521358 -0.801554 -0.292741 0.471267 -0.826425 -0.308107 -0.517718 -0.711862 -0.474575
--0.457399 -0.73991 -0.493274 -0.350017 -0.725961 -0.592004 0.938158 -0.332209 0.097448
--0.711954 -0.561604 0.421571 -0.738749 -0.211071 0.640077 -0.776984 0.365639 0.512449
-0.526008 0.850448 0.00736319 0.561594 0.827147 -0.0209819 -0.398197 0.911999 -0.0984787
--0.996499 -0.0379831 -0.0744768 0.973268 -0.0957941 0.20874 -0.994649 0 0.103311
-0.432317 -0.845277 -0.314021 0.277767 -0.902352 -0.329555 0.29672 -0.896508 -0.328984
-0.30655 -0.892601 -0.330593 -0.211224 -0.895818 -0.391017 -0.246372 -0.893097 -0.376401
--0.19087 -0.90133 -0.388809 -0.380769 -0.826024 -0.415571 0.91681 -0.368812 0.153092
--0.574699 -0.549468 0.606471 0.00420699 -0.37863 0.925539 -0.202648 0.572181 0.794696
-0 0.447214 0.894427 -0.630304 0.467218 0.620019 -0.614424 0.384409 0.688995
--0.597018 0.447763 0.665641 0.345204 0.927614 0.14271 0.219501 0.969407 0.109858
--0.229929 0.965862 0.119341 -0.518612 0.842456 0.14598 0.761176 0.567208 0.314463
-0.480353 0.857773 0.182992 0.412654 0.903095 0.118895 -0.83391 -0.525598 -0.168348
--0.73334 -0.668785 -0.122223 0.977765 0 0.209704 -0.990783 0.0880882 0.102909
-0.318775 -0.888499 -0.330079 0.414728 -0.854726 -0.312161 0.393909 -0.871766 -0.291306
--0.167097 -0.925588 -0.339655 -0.210937 -0.922849 -0.322265 0 -0.938787 -0.344499
--0.123661 -0.931581 -0.341855 -0.122384 -0.945694 -0.301139 -0.20314 -0.91973 -0.335902
--0.28152 -0.89949 -0.334162 0.896953 -0.419203 0.140515 0.871755 -0.470252 0.137501
--0.268549 -0.960267 0.0759533 0.175164 -0.967724 0.181186 0.856429 -0.394109 0.333477
-0.445689 -0.869571 0.212622 -0.336085 -0.93357 0.124476 0.0232069 -0.999117 -0.0350139
-0.373427 -0.908543 -0.187355 0 -0.357789 0.933803 -0.323885 -0.689561 0.647769
--0.677957 0.0739589 0.731372 0.94085 -0.210308 0.265652 0.847716 0.493216 0.195232
--0.82378 0.554737 0.116848 -0.850412 0.525255 0.0301072 0.724963 0.626742 0.285698
-0.717732 0.67434 0.173569 0.683848 0.706168 0.183517 0.425656 0.243232 0.871582
--0.379604 -0.827626 0.413445 -0.799874 -0.599905 0.017775 -0.784501 -0.613566 0.0899658
-0.97202 -0.108245 0.208472 -0.980301 0.1742 0.0930774 0.342227 -0.896509 -0.28134
-0.149137 -0.955078 -0.256094 0.0528742 -0.971123 -0.232647 0 -0.972483 -0.232972
-0 -0.90031 -0.435249 -0.0528742 -0.971123 -0.232647 -0.149137 -0.955078 -0.256094
--0.234589 -0.927496 -0.291064 0.78306 -0.599178 0.166741 -0.502994 -0.864119 0.0171964
--0.441164 -0.896792 0.0337502 -0.327019 -0.94308 0.0604809 0.970338 -0.188498 0.15137
--0.82888 -0.559316 0.0110834 -0.893176 -0.448092 -0.0380928 0.963121 0.216896 -0.159229
--0.759243 -0.172095 0.627641 -0.150614 -0.506612 0.848917 -0.326814 -0.673139 0.663383
-0.987592 -0.127364 0.091869 0.984198 -0.176688 0.0116819 -0.391963 0.905571 -0.162192
--0.806214 0.586434 -0.0781912 -0.444323 0.654278 -0.611962 -0.927756 -0.0655707 -0.367382
-0.601259 0.720474 0.345551 0.73298 0.662853 0.152857 0.686924 0.703664 0.18164
--0.284726 -0.260999 0.922394 -0.571962 -0.784995 0.237995 -0.573067 -0.796486 0.192884
--0.621233 -0.762161 0.182152 0.938767 -0.287472 0.18994 -0.981345 0.178831 0.0705833
-0.803877 -0.572697 0.160625 0.832671 -0.512363 0.210101 -0.544894 -0.838298 0.0186288
--0.480725 -0.876849 0.00632533 0.994235 0.0699282 0.081284 -0.973598 0.122971 -0.192316
-0.738164 0.649585 -0.182081 0.860037 0.474696 -0.187086 -0.991592 -0.0517088 0.118626
-0.961565 0.272979 -0.0295963 -0.799181 0.592106 -0.103538 -0.967347 0.190745 -0.166901
--0.911891 -0.333191 -0.239664 0.860748 0.472624 0.189049 0.865778 0.469974 0.171908
-0.863642 0.474633 0.169839 0.114888 0.0774826 0.990352 -0.7072 -0.65397 0.268685
--0.693397 -0.690052 0.207434 -0.602114 -0.772772 0.200705 0.965312 -0.182386 0.186835
--0.994258 0.089038 0.0593587 0.750582 -0.592685 0.292147 -0.397157 -0.917569 -0.0182601
--0.388419 -0.921292 -0.0187255 -0.450752 -0.892649 0 0.929841 0.356706 0.0903121
--0.39972 -0.799439 0.448466 -0.0508834 -0.85371 0.518257 -0.692984 0.694726 -0.192689
-0.0248318 0.980858 -0.193137 0.162674 0.967991 -0.191129 0.662743 0.717365 -0.214845
--0.984132 -0.176639 0.0168228 0.856534 0.514883 -0.0352879 0.936277 0.349317 -0.0369269
--0.942913 -0.331188 0.035067 0.403378 0.541117 0.737887 0.994668 0.0219412 0.100767
--0.704075 -0.656962 0.26959 -0.603306 -0.784298 0.14456 -0.724981 -0.660808 0.194253
-0.981579 0.0849699 0.17112 -0.998223 0 0.0595954 0.727857 -0.618455 0.296204
-0.0147027 -0.940973 0.338162 0.0770382 -0.969719 0.231757 0.582397 -0.804078 0.119466
-0.66045 -0.737666 0.140195 -0.582227 -0.812493 0.0294295 -0.179542 -0.980125 -0.0843751
-0.229626 -0.971496 -0.0588786 0.08238 -0.99386 -0.073869 -0.01356 -0.997112 -0.0747306
--0.00279177 -0.997221 -0.0744473 -0.178722 -0.983813 -0.0130727 -0.416589 -0.909073 0.00627838
-0.765165 0.633543 0.114658 0.792715 0.598654 0.114961 -0.575386 -0.405201 0.710453
--0.0360068 -0.711135 0.702133 0.631299 -0.26971 0.72713 0.13398 0.973679 -0.184389
--0.786589 -0.587223 -0.190908 0.683335 0.729251 -0.0352922 0.72863 0.683751 -0.0397755
--0.798233 -0.578233 0.168732 -0.866879 -0.482376 0.125837 0.323581 -0.942908 0.0788656
--0.502939 -0.858277 0.102046 0.973728 0.156552 0.165366 -0.998223 0 0.0595954
-0.777952 0.529219 -0.3387 0.749279 0.613653 -0.249019 0.309423 0.948679 -0.0653135
-0.20013 0.979296 0.0304582 0.089334 0.982674 0.162392 -0.235125 0.953014 0.190998
--0.546514 0.805437 0.229332 -0.568801 0.78387 0.249027 0.485678 -0.857445 0.170016
--0.159158 -0.968464 0.191691 -0.636435 -0.766822 0.0832775 0.799041 0.585829 0.135416
--0.0232585 -0.424468 0.905144 0.756611 0.346981 0.554206 -0.707849 -0.671763 -0.218369
--0.847774 -0.51472 -0.127839 -0.656344 -0.725433 -0.207267 0.407615 0.912807 0.0251809
-0.530167 0.847803 -0.012388 -0.558937 -0.792326 0.24456 -0.621979 -0.753065 0.214559
-0.322649 0.875361 -0.360058 0.278898 0.756639 -0.591366 -0.26714 0.252299 -0.930044
--0.327934 0.213539 -0.92025 -0.509336 -0.0836223 -0.856495 -0.744883 -0.440047 -0.501506
--0.865884 -0.368839 -0.337938 0.974931 0.158911 0.155747 -0.998223 0 0.0595954
-0.886257 -0.418595 -0.198309 -0.819473 -0.281649 0.499138 -0.916385 -0.078894 0.392447
--0.898507 -0.211238 0.384791 0.989082 -0.0196767 0.146045 0.938853 0.309822 0.150217
--0.784379 -0.182088 0.592953 0 -0.471215 0.882018 0.604551 -0.453413 0.654931
--0.170221 -0.958912 0.226962 0.340323 0.850809 0.400381 0.0535363 0.963654 0.261733
-0.322316 0.799344 0.507111 0.240544 0.955847 0.168803 0.119379 0.967217 0.224141
-0.0841203 0.96101 0.263407 0.242414 0.965428 0.0958381 -0.667303 -0.696589 0.263574
--0.78311 -0.594693 0.181875 -0.583646 -0.781176 0.221631 0.418615 0.897032 0.141753
-0.409875 0.900101 0.147717 0.327479 0.936939 0.122079 -0.0806806 0.996095 0.035858
--0.478523 0.849237 -0.223185 -0.616534 0.561904 -0.551498 -0.560483 0.552552 -0.616884
-0.43921 0.380418 -0.813865 0.323313 0.0668923 -0.943925 0.281222 0.55646 -0.781836
--0.414636 -0.763803 -0.494653 -0.560148 -0.737139 -0.37797 -0.491984 -0.242527 -0.836141
--0.484683 -0.846938 -0.218583 0.972022 0.172729 0.159181 -0.982641 0.175995 0.0586652
-0.524648 -0.851137 -0.0176141 0.283137 -0.958311 0.0383739 -0.286332 -0.94321 0.16843
--0.486938 -0.844547 0.222782 -0.889608 -0.255526 0.378556 0.959574 -0.242135 0.143488
-0.882036 -0.450006 0.139671 -0.742364 0.593891 0.310143 0.918054 0.0612036 0.391703
--0.299391 -0.953943 -0.0189158 -0.408799 -0.907228 -0.0991028 -0.149332 -0.981512 0.119729
--0.188888 -0.969078 0.158775 -0.214925 -0.965081 0.149754 -0.06556 -0.971108 0.22946
-0.891861 0.0964174 0.441913 0.942344 -0.105825 0.317474 -0.98989 0.00856306 0.141576
-0.574859 0.817835 0.0261383 0.550082 0.833389 0.0536054 0.453329 0.880641 0.137707
--0.874919 -0.271263 -0.401164 -0.337804 -0.855989 -0.391372 -0.25232 -0.820983 -0.512173
--0.290521 -0.933019 -0.212304 0.972073 0.177141 0.153934 -0.929024 0.353084 0.110664
-0.180625 -0.981099 0.0694205 0.0125628 -0.995155 0.0975114 -0.158983 -0.977415 0.139228
--0.314324 0.679726 0.662701 0.0455877 0.747638 0.662541 -0.27552 0.74046 0.613032
--0.470453 0.623969 0.623969 0.852567 0.518954 0.0617802 0.078002 0.972492 0.219486
--0.282537 0.936832 0.206202 0.0781423 0.967762 0.239436 0.290705 0.935707 0.19986
-0.162957 0.972994 0.163484 -0.649065 0.740365 0.174855 -0.859571 0.508927 0.0461662
-0.938298 -0.295476 0.179694 -0.323151 -0.799539 0.506271 0.539562 -0.756329 0.369918
-0.0591047 -0.990004 0.12806 -0.447683 0.826491 0.34131 -0.372896 0.864362 0.337382
--0.623361 -0.749652 -0.222359 -0.841719 -0.497379 -0.210055 0.923711 -0.300417 0.237713
--0.747978 0.635781 0.190556 0.615968 0.782256 -0.0930588 0.645985 0.760378 -0.0672901
--0.924648 -0.344908 -0.161446 0.982172 0.0879557 0.166139 -0.93006 0.340688 0.137551
--0.468715 0.338517 0.815912 0.998236 -0.0576002 -0.0143583 -0.338731 0.193561 0.920758
--0.981036 -0.193008 -0.0177724 0.970405 -0.193783 0.144095 -0.191495 -0.833568 0.518164
--0.464684 -0.883052 0.0654866 -0.676968 -0.734808 0.0421014 -0.0893582 -0.994723 0.0504072
--0.0905864 -0.990233 0.10598 -0.180049 -0.978796 0.0976737 0.527412 -0.846036 0.0778419
-0.750225 -0.653257 0.102071 -0.877754 0.455368 -0.148952 0.615922 -0.74676 0.250977
-0.408844 -0.906834 0.102467 -0.738009 0.654412 0.164583 -0.228873 0.972709 -0.0381454
-0.337487 0.935758 -0.102269 0.581949 0.807511 -0.0962396 -0.913794 -0.406131 -0.0061535
--0.90515 -0.419733 0.0672855 0.985993 0 0.166785 -0.973323 0.159799 0.164642
-0.893689 -0.438371 -0.0956583 0.734908 -0.666249 -0.126582 -0.34802 -0.912492 0.215037
-0 -0.9837 0.179816 -0.256757 -0.960868 0.103963 -0.534985 -0.841855 0.0712107
-0.992076 0.0888426 0.0888426 -0.77454 -0.580905 0.250276 -0.731025 -0.629021 0.264453
--0.151516 -0.925564 0.346949 0.144294 -0.945232 0.292771 0.0801606 -0.921847 0.379173
--0.0369768 -0.90593 0.421809 -0.288508 -0.601059 0.745313 -0.0283629 -0.855615 0.516835
-0.630647 -0.667527 0.395845 0.752454 -0.620057 0.222132 -0.859289 -0.492892 0.136672
--0.858604 -0.506671 0.0779977 0.78356 -0.609436 0.12092 0.773686 -0.613753 0.157216
--0.83706 0.506832 -0.206039 0.397346 -0.914024 0.0817053 0.640441 -0.765318 0.0642225
-0.626561 -0.775742 0.0751431 -0.904265 -0.368404 0.215833 0.985993 0 0.166785
--0.985993 0 0.166785 0.127883 -0.989553 -0.0665629 -0.234956 -0.971224 0.0389789
--0.222632 -0.960744 0.165547 -0.0664783 -0.986728 0.148152 0.854386 0.515038 0.0689927
--0.883359 -0.419596 0.208844 0.746926 -0.630354 0.211557 0.391488 -0.897001 0.205246
--0.644467 -0.731907 0.221299 0.74956 -0.643764 0.154037 0.728101 -0.667812 0.154586
--0.84479 0.495855 -0.20114 -0.939313 0.337442 -0.0618315 0.577231 -0.812488 0.0816531
-0.54668 -0.829782 0.112265 0.0757077 -0.791146 0.606924 0.122598 -0.98078 0.151787
--0.935367 -0.344489 0.0801019 0.982172 0.0879557 0.166139 -0.991737 0 0.128284
-0.698525 0.709022 0.0966993 0.709161 0.698746 0.0940498 -0.921047 -0.292973 0.256591
--0.924892 -0.296325 0.238257 0.433101 -0.880099 0.194548 -0.605116 -0.759848 0.237625
-0.759829 -0.631018 0.156451 0.772156 -0.617008 0.151905 -0.968309 -0.239311 0.0714704
-0.526635 -0.840004 0.130571 0.163394 -0.972194 0.167751 -0.29119 -0.934755 0.203569
--0.25437 -0.951374 0.173732 0.796281 -0.566678 0.21169 0.828117 -0.516914 0.216846
--0.183889 -0.981474 0.0537944 -0.320398 -0.946777 0.0309718 0.2411 -0.966844 0.0841678
-0.233528 -0.969895 0.069054 -0.903472 -0.428388 0.0148887 -0.611621 -0.79001 -0.0424737
-0.95884 0.249869 0.134877 -0.995086 0 0.0990135 0.842244 0.527974 0.108947
-0.749169 0.654664 0.100806 -0.763318 -0.501609 0.407103 -0.924073 -0.100311 0.368819
-0.925196 0.201129 0.321807 0.380651 0.827094 0.413547 -0.0736462 0.97213 0.222575
--0.113333 0.988034 0.104615 0.125218 0.990362 0.059194 0.0616862 0.99647 -0.0569411
--0.604642 0.77921 -0.165047 -0.654665 0.737226 -0.167066 0.595467 -0.782614 0.181476
--0.473794 -0.85559 0.208531 -0.6647 -0.724096 0.184008 0.840159 -0.507061 0.192413
--0.64744 -0.761694 -0.0253898 -0.490858 -0.871197 0.00863829 0.167001 -0.983267 0.0727743
--0.236405 -0.971655 0 0.932844 0.333618 0.136021 -0.982641 0.175995 0.0586652
--0.39749 0.0709803 0.914857 0.80754 0.13459 0.574251 -0.39443 0.302396 0.867745
--0.663323 0.151617 0.732813 0.89597 0.443798 0.0167471 -0.912339 -0.180567 0.36747
--0.861592 -0.292516 0.414841 -0.899625 -0.282235 0.333194 0.886292 -0.462413 0.0256896
--0.841918 0.528263 -0.110055 -0.0856621 -0.980355 0.177669 0.73686 -0.653738 0.172233
--0.147438 -0.989063 0.0040955 -0.406043 -0.912823 -0.043394 0.960749 0.239534 0.139946
--0.929024 0.353084 0.110664 -0.320564 0.0674871 0.94482 0.39365 0.919182 -0.0119893
-0.726182 0.68718 -0.0210488 -0.724245 -0.654157 0.218052 -0.449876 -0.736161 0.505646
--0.84227 -0.409501 0.350558 0.746128 -0.664265 -0.0452199 -0.848602 0.516435 -0.114763
--0.352292 -0.935056 -0.0395094 0.922438 -0.359595 0.140711 0.987849 0.0884641 0.127781
--0.934583 0.342345 0.096723 0.257508 0.835331 0.485707 0.0494662 0.831032 0.554021
--0.217452 0.848061 0.483226 0.322634 0.939848 0.112221 0.0790893 0.996705 0.0179748
--0.180111 0.978306 -0.102358 -0.333222 0.928936 -0.161372 0.916886 0.387913 0.0940396
-0.161262 0.983526 0.0816756 0.238774 0.971075 0 -0.777287 -0.606089 0.168764
--0.74616 -0.633307 0.205349 0.776905 -0.629617 -0.00107903 0.762229 -0.64725 0.00859036
--0.872436 0.473766 -0.120006 -0.863423 0.485162 -0.13827 0.901675 0.430157 -0.0441187
-0.983641 0.178108 -0.026986 -0.213526 0.97368 0.0797165 -0.264783 0.957141 0.117354
--0.398744 0.886098 0.236293 0.992076 0.0888426 0.0888426 -0.964809 0.244802 0.0960009
-0.195266 0.78616 0.586365 0.747579 0.615653 0.249193 -0.883377 0.376598 0.278961
--0.841635 0.479792 0.247892 0.631517 0.758482 0.16091 0.509108 0.846123 0.157752
--0.73302 0.640187 -0.229873 -0.985746 0.0789435 -0.148572 0.94526 0.322741 0.0481914
--0.707235 -0.681672 0.18746 -0.749768 -0.638475 0.173774 0.745203 -0.66536 0.0443573
--0.561706 0.6366 -0.528419 -0.843485 0.316307 -0.434147 0.907987 -0.404496 0.109285
--0.869999 -0.39875 0.29 -0.80228 0.566315 -0.188772 0.965174 0.25152 0.0719457
--0.98126 0.175193 0.0802233 0.420999 0.90047 0.109148 0.214094 0.961517 0.172189
-0.177858 0.966364 0.185763 0.289185 0.937659 0.19279 -0.887417 0.371686 0.272656
-0.867886 0.286595 0.405756 0.879213 0.432113 0.200654 0.713733 0.678553 0.173641
--0.743582 -0.659084 -0.112664 0.796122 0.601769 0.0637452 -0.783658 -0.602979 0.149319
--0.730793 -0.660824 0.171037 0.560643 0.824475 -0.076951 0.0938288 0.995588 0.000955
--0.771634 0.635276 0.031711 -0.801444 0.59723 0.031681 0.727177 -0.677801 0.108628
-0.717909 -0.686696 0.11426 -0.403455 -0.14483 -0.903464 -0.754303 -0.258618 -0.603443
--0.739379 -0.285893 -0.609577 -0.902111 0.0674808 -0.426194 0.898344 -0.425962 0.107401
-0.530778 -0.836912 0.133612 -0.654043 -0.744256 0.135319 0.935161 0.334447 0.116703
--0.968373 0.243346 0.0550971 0.271817 -0.888631 -0.369392 0.905576 -0.424178 -0.00248785
--0.898645 0.246485 0.362881 -0.878041 0.269225 0.395679 0.942709 0.00771658 0.333528
-0.944479 0.0718895 0.320611 -0.532907 -0.836714 -0.126171 -0.418588 -0.906668 -0.0523235
-0.688407 0.716801 0.110871 0.762943 0.642586 0.0707184 -0.90686 -0.392522 0.153399
-0.998228 -0.0462258 0.0374804 -0.997735 -0.057916 0.0342231 0.491553 -0.849046 0.193642
--0.451911 -0.891608 0.0284989 -0.72445 -0.678208 -0.123311 -0.154193 -0.90974 -0.385483
-0.521877 -0.84215 0.135751 0.0316642 -0.987177 0.156458 0.94166 0.319294 0.106431
--0.945479 0.321611 0.051337 0.504367 -0.852206 0.139136 0.0773271 -0.947258 0.311004
--0.270119 -0.764532 0.585257 -0.393708 0.51711 0.759994 -0.337067 0.41068 0.847188
--0.511949 0.500043 0.698473 0.749796 0.644924 0.147914 0.372719 0.873962 0.311884
--0.27968 0.925729 0.254567 -0.387366 0.867965 0.31078 -0.209284 0.863295 0.459262
--0.221396 0.846047 0.484962 -0.225881 0.797226 0.55983 -0.22643 0.769375 0.597321
--0.370753 0.750334 0.547303 0.936041 -0.0744578 0.343924 0.22259 -0.926929 0.302087
--0.0853507 -0.971545 0.220943 -0.27938 -0.954058 0.108262 -0.394411 -0.91891 -0.00662875
-0.899368 0.412949 0.143561 0.751775 0.647856 0.122955 -0.938592 -0.319268 0.130814
-0.733675 -0.669384 0.116817 -0.938927 -0.333841 0.0834602 0.137194 -0.968931 0.205791
--0.146459 -0.97814 0.147622 -0.020719 -0.80804 0.588764 0.150539 -0.784057 0.602156
-0.0168332 -0.52183 0.852883 -0.249279 -0.807447 0.534686 0.937562 0.330556 0.108213
-0.942445 0.316493 0.107842 -0.93994 0.336695 0.0561158 0.236437 -0.956391 0.171506
-0.0787831 -0.982312 0.169871 -0.0329484 -0.98484 0.170308 -0.0917315 -0.974491 0.204825
--0.187575 -0.935656 0.298936 -0.22054 -0.803395 0.5531 -0.0340662 0.0170331 0.999274
--0.393818 -0.393818 0.830551 0.120903 -0.70527 0.698553 -0.70527 0.120903 0.698553
--0.671994 -0.186091 0.716794 0.954748 0.168736 0.244917 0.953272 0.197675 0.228465
-0.935294 0.277849 0.219148 -0.580904 0.783082 0.22211 -0.792735 0.0468434 0.607764
--0.94386 0.152858 0.292854 0.667641 0.731633 0.137727 0.784931 0.605469 0.131491
--0.600932 0.348833 0.719164 -0.714862 0.194962 0.671537 0.987926 0.0177048 0.153913
--0.960602 -0.241393 0.137742 0.729484 -0.66932 0.140939 0.173191 -0.899037 0.402166
-0.424978 0.882816 0.200076 0.39292 0.894521 0.21318 -0.103486 0.952782 0.285478
--0.21034 0.893083 0.397692 -0.539139 0.787489 0.298648 -0.0822085 -0.829234 0.552823
-0.935161 0.334447 0.116703 -0.944881 0.32297 0.0537605 -0.223261 -0.458925 0.859967
-0.784895 -0.242509 0.570201 0.829037 -0.138173 0.541854 -0.661083 -0.669713 0.338309
--0.687977 -0.651833 0.319062 0.573134 0.807597 0.138941 0.65065 0.744605 0.149055
--0.9574 -0.109048 0.267382 0.991783 0.117286 0.0510981 -0.951919 -0.257508 0.165949
-0.895763 0.0453551 0.442212 0.912843 0.0370907 0.406624 0.882829 -0.0764655 0.463428
--0.517766 0.534577 0.667941 -0.0185995 0.658955 0.751953 -0.034456 0.955934 0.291551
-0.343907 0.910341 0.230234 0.45066 0.870621 0.197292 -0.777171 0.564647 0.277809
--0.92431 0.299776 0.236187 0.915302 0.380062 0.133326 -0.945479 0.321611 0.051337
-0.61184 0.772478 0.170087 0.0868562 0.959366 0.268465 -0.18378 0.966933 0.176819
--0.0796151 0.987227 0.138 -0.133291 0.911708 0.388616 -0.0562991 0.925181 0.375327
--0.264587 0.841867 0.470376 0.609402 -0.370421 0.701012 -0.666254 -0.674645 0.317743
-0.299222 0.933099 0.199481 0.18655 0.967198 0.172417 0.474731 0.864116 0.167134
--0.969563 -0.217657 0.112126 0.949223 0.314029 0.019032 -0.946577 -0.28256 0.155408
--0.937489 -0.317879 0.141657 0.902487 -0.0638929 0.425952 0.83711 -0.413388 0.358269
-0.403713 0.858964 0.314954 -0.982239 0.010807 0.187322 0.170172 0.96184 0.214256
-0.322634 0.939848 0.112221 0.235282 0.957355 0.167672 -0.251342 0.952172 0.173767
--0.650482 0.757175 0.0596562 0.890888 0.428295 0.151266 0.907316 0.395497 0.142689
--0.916348 0.396628 0.0547073 0.79735 0.601228 -0.0525137 0.816542 0.569431 0.0949051
--0.936468 -0.248335 0.247703 0.622716 0.770025 0.138877 0.639269 0.757837 0.130452
-0.328412 0.921155 0.208854 -0.90309 -0.429338 -0.00986984 0.962071 0.272799 0
-0.952346 0.304588 0.0162447 -0.900467 -0.409868 0.145494 0.882518 -0.468838 -0.0367716
--0.984232 -0.0461571 0.170751 0.756585 0.596597 0.267678 0.734355 0.622262 0.271132
-0.230891 0.935931 0.265936 0.189247 0.96344 0.189657 0.189054 0.962454 0.194782
--0.189464 0.964546 0.183723 -0.487393 0.856514 0.169799 -0.391319 0.904234 0.170972
-0.734944 0.673608 -0.0781624 0.68022 0.730716 -0.0579226 0.216172 0.976324 0.00774349
-0.0927428 0.99513 0.0333874 -0.705545 0.70769 0.0371716 -0.849536 0.263464 -0.457029
--0.909507 0.196297 -0.36642 0.898921 0.414243 0.14263 -0.907331 0.412992 0.0786651
-0.972589 0.00495136 -0.232478 0.963906 0.19031 -0.18619 -0.849418 -0.501891 0.163079
-0.479853 0.870845 0.106634 0.620652 0.778636 0.0922828 -0.847093 -0.529328 -0.0473859
-0.936479 0.350724 0 -0.886935 -0.436849 0.150029 0.979753 -0.188784 -0.0666717
--0.98167 0.0994456 0.162586 0.905524 0.109557 0.409908 0.967228 0.00614113 0.253834
--0.430995 0.889658 0.150838 -0.4468 0.880649 0.157567 -0.423661 0.90028 -0.100031
--0.290129 0.928414 -0.232104 0.462084 0.873942 -0.15068 0.625276 0.769006 -0.132889
--0.676037 -0.730851 -0.0939666 -0.627252 -0.774974 -0.0772701 0.915704 0.380649 0.12881
-0.910762 0.390913 0.133042 -0.94485 0.320375 0.0679584 0.935441 -0.261671 -0.237653
-0.463751 -0.879528 -0.106609 -0.646283 -0.752002 0.129656 -0.833262 -0.528879 0.161124
-0.556124 0.826158 0.0904978 0.545323 0.831994 0.102023 0.496161 0.858403 0.130261
--0.84961 -0.52248 -0.0719597 -0.829593 -0.549583 -0.0986588 0.922822 0.385228 0
--0.904864 -0.404737 0.131941 0.979963 -0.199179 0 -0.988907 0.0111331 0.148118
-0.950273 0.291417 0.109809 0.32035 0.944621 0.0711888 -0.209442 0.977802 -0.00608843
--0.334132 0.942514 0.00479042 -0.417537 0.908529 0.0154643 0.876575 -0.443532 0.186803
--0.372264 0.908099 -0.191772 -0.0882881 0.975584 -0.201101 0.304687 0.935642 -0.178157
--0.435788 -0.896981 0.0742598 -0.528449 -0.84741 0.0513582 0.904864 0.404737 0.131941
--0.94561 0.317556 0.0705679 -0.940309 0.331525 0.0768753 0.328661 -0.943846 0.0337088
--0.130234 -0.985437 0.109332 -0.613055 -0.778677 0.133517 0.737178 0.641024 -0.213675
--0.941726 -0.325287 -0.0856723 0.0731249 0.967077 0.24375 0.0333514 0.9682 0.247945
--0.0491532 0.966679 0.251227 0.950925 0.309421 0 0.935084 0.354427 0
--0.915704 -0.380649 0.12881 0.957916 -0.280314 0.0618193 -0.986087 -0.143278 0.084281
-0.961897 -0.242722 0.125856 -0.567532 0.82305 0.0222562 -0.790305 0.609033 -0.0670562
-0.832218 -0.523935 0.181399 0.668505 -0.724698 0.167072 -0.336249 -0.939275 0.0685467
--0.373255 -0.914115 0.158351 -0.308917 -0.940954 0.13848 -0.346823 -0.931835 0.106756
-0.891109 0.438905 0.115268 -0.909999 0.407034 0.0788965 0.655354 0.472465 -0.589311
-0.715155 0.131873 -0.686413 -0.970202 -0.240965 0.0253648 -0.980567 -0.182926 0.0709014
-0.55495 0.793739 0.249016 0.564847 0.796469 0.215836 -0.74402 0.6392 0.194569
--0.795926 0.597597 0.0968449 0.987001 0.160715 0 -0.910762 -0.390913 0.133042
--0.898921 -0.414243 0.14263 0.9271 -0.356142 0.11683 0.855212 -0.493465 0.158443
--0.966198 -0.256732 -0.0234648 0.835548 -0.538439 0.109282 -0.752948 0.649358 -0.106788
--0.63996 0.734769 -0.224867 0.644276 -0.746059 0.168239 0.421389 -0.893143 0.157251
-0.302968 -0.939202 0.161583 -0.0432635 -0.822006 -0.567833 -0.730952 -0.472755 -0.49215
--0.00879051 -0.959924 -0.280124 -0.0714231 -0.975179 -0.209583 -0.187769 -0.964695 -0.18468
--0.312614 -0.94709 -0.0727582 -0.331391 -0.941849 0.0556724 0.69814 0.679073 0.226847
-0.704182 0.678293 0.209874 0.136649 0.976065 0.169185 -0.782013 0.616988 0.0882119
--0.962902 0.26848 0.0271878 0.87301 0.47564 0.1078 -0.894208 0.440431 0.0800783
-0.58504 0.645561 -0.490896 0.565425 0.565425 -0.60049 0.345295 0 -0.938494
-0.183808 -0.76865 -0.612692 0 -0.87317 -0.487416 0.256686 -0.81284 -0.52288
-0.369262 -0.812376 -0.45132 -0.324628 -0.945655 -0.018819 0.125901 -0.99192 -0.0155877
-0.279469 -0.958763 -0.051678 -0.979733 -0.139762 0.143489 0.842539 -0.401381 0.359194
-0.816503 0.468688 0.337126 0.656996 -0.399171 0.639546 -0.987105 0.151862 -0.0506207
-1 0 0 -0.872008 -0.466563 0.148061 0.62707 -0.777092 0.0539647
-0.618165 -0.784549 0.0485288 -0.925432 -0.311053 -0.216385 -0.912262 -0.334167 -0.236878
-0.834184 -0.540728 0.108402 0.871034 -0.478699 0.110216 -0.603543 0.766511 -0.219538
--0.219701 0.957567 -0.186539 -0.164018 0.973854 -0.157183 -0.109557 0.99348 -0.031539
--0.307155 0.950999 0.035441 0.17421 -0.968971 0.175348 0.166698 -0.972992 0.15968
-0.353095 -0.920885 0.165211 0.54846 -0.822689 0.14958 -0.77583 -0.573902 -0.262153
--0.890532 -0.287568 -0.352502 0.620804 0.64591 0.444301 0.626694 0.663362 0.408907
-0.618814 0.673415 0.404453 0.726395 -0.333287 0.601057 0.229135 -0.910085 0.345316
--0.682228 -0.730959 0.0162435 0.894208 0.440431 0.0800783 -0.907331 0.412992 0.0786651
-0.681032 0.376741 -0.627902 -0.241627 -0.638585 -0.730634 -0.366851 -0.791307 -0.489135
-0.567982 -0.743976 -0.351989 0.601696 -0.75212 -0.268843 0.561811 -0.783055 -0.266819
--0.544378 -0.838636 -0.0185274 -0.466562 -0.881284 -0.0752192 0.821962 -0.557699 -0.115544
-0.99236 -0.0870827 -0.0874017 -0.994794 0.0306877 0.0971778 0.779985 -0.548672 0.300969
-0.314976 -0.926439 0.206159 0.0796151 -0.987227 0.138 -0.118885 -0.990709 0.0660473
-1 0 0 -0.866056 -0.478626 0.144445 -0.876693 -0.463248 0.129658
-0.692094 -0.711521 -0.12142 0.673143 -0.641088 -0.368626 -0.840155 0.228775 -0.491734
--0.794007 0.174681 -0.582271 0.904379 -0.415125 0.0988393 -0.188828 0.964867 -0.182688
--0.540485 0.83688 0.0866467 -0.750966 0.659385 -0.0355224 0.472117 -0.881286 0.020983
--0.689591 -0.678858 -0.252224 -0.76161 -0.58942 -0.269323 0.690456 0.0470766 0.721841
-0.844057 0.19916 0.497899 0.776658 0.44287 0.44796 -0.227808 -0.672703 0.703971
--0.686188 -0.648067 0.330387 -0.470251 -0.853687 0.223791 0.865962 0.49676 0.0577907
--0.94485 0.320375 0.0679584 0.810314 0.450174 -0.375145 -0.385487 -0.416151 -0.82354
--0.124783 -0.945051 -0.302172 -0.435675 -0.89242 -0.117358 0.845825 0.506554 -0.167283
--0.90183 0.432091 -0.00038614 1 0 0 -0.89611 -0.430805 0.106743
-0.933381 0.285803 -0.217065 -0.863862 0.284682 -0.41557 -0.920171 0.288747 -0.264404
-0.909999 -0.407034 0.0788965 -0.76547 0.642157 -0.0411043 -0.682768 0.720467 -0.121474
-0.487663 -0.624719 0.609845 -0.232717 -0.867757 0.439137 0.87627 0.474048 0.0861905
--0.946459 0.317841 0.056505 -0.942007 0.332123 0.0481338 0.477676 0.877509 0.0424601
-0.0474296 0.986536 -0.156518 -0.909538 0.400197 -0.112176 0.665187 0.741896 -0.0843615
-0.837273 0.520343 -0.16798 -0.897915 0.440169 0.000488263 -0.814913 0.579494 0.0102154
-1 0 0 -0.946887 -0.315629 0.0615072 -0.964187 -0.262245 0.0396281
-0.913814 0.396829 -0.0864277 -0.982288 0.0762009 -0.171185 0.88096 -0.463637 0.0945998
--0.765014 0.639602 -0.0752473 -0.938451 0.345317 -0.00812512 0.802708 0.596364 -0.00310001
--0.911935 0.4079 0.0446234 0.405731 0.894223 0.189072 0.330252 0.920704 0.207937
-0.0132112 0.95121 0.308262 -0.855886 0.109428 0.505455 -0.880425 0 0.474186
--0.894675 -0.0378345 0.445112 0.784203 0.615061 0.0820082 0.523255 0.850394 0.0550795
--0.978238 -0.19341 0.0751261 0.748462 0.656814 0.0916485 0.683425 0.727721 -0.0579108
--0.84381 0.536501 -0.0122825 -0.875652 0.482762 -0.0132554 1 0 0
--0.998383 -0.0380227 0.0422474 0.68437 -0.28888 0.669467 0.756813 -0.24925 0.604242
-0.701308 -0.137098 0.699551 -0.622639 0.437793 0.648582 -0.623985 0.339192 0.703983
--0.666768 0.35864 0.653298 0.78887 0.613957 -0.0272198 0.909601 0.407789 -0.0795857
--0.964919 -0.225766 -0.134017 0.874059 -0.476451 0.0949511 0.466345 -0.875391 0.12733
--0.191218 -0.978682 -0.0749441 -0.18324 -0.980797 -0.0667926 0.185905 -0.979727 -0.0746564
-0.206426 -0.976194 -0.0665889 -0.91413 -0.36041 0.185666 -0.392605 0.326002 0.859991
--0.111041 0.142767 0.983508 -0.441563 0.454179 0.773786 -0.493862 0.409681 0.766982
-0.804592 0.572029 0.159418 0.789212 0.592309 0.162218 -0.696034 0.685325 0.214164
--0.671285 0.706616 0.223762 -0.817155 0.547715 0.179627 0.754161 0.651321 0.0837957
-0.77317 0.634173 0.00579153 -0.896946 0.441779 0.0178497 0.862379 0.493586 0.112583
-0.599199 0.783999 0.162192 -0.452839 0.251577 0.855363 -0.832275 -0.488101 0.262824
--0.89702 -0.0967048 0.431281 0.883359 0.462319 0.0770532 -0.887349 -0.450996 0.0959912
-0.627455 0.778103 0.029252 -0.944143 0.328398 -0.0273665 -0.993313 0.0180057 -0.114036
-0.999408 0 -0.0344137 -0.998955 -0.0284287 0.0357992 0.670098 -0.383875 0.635302
--0.640411 0.15137 0.752968 0.682656 0.730145 0.0294609 0.709228 0.704913 -0.00970806
--0.862109 -0.49602 -0.103594 -0.793538 -0.602136 -0.0879165 0.320821 -0.937495 0.13482
-0.0602766 -0.997713 0.0305881 -0.110478 -0.993817 0.0110316 0.467763 -0.883552 0.0230994
-0.402916 -0.895479 0.189144 0.238213 -0.944344 0.226869 -0.786527 -0.566171 0.246628
-0.857732 -0.219715 0.464781 0.859164 -0.271201 0.433921 -0.390518 0.836011 0.385462
--0.0214505 0.87782 0.478511 -0.315553 0.930052 0.188225 0.940861 0.0775968 0.329786
-0.966406 -0.211753 0.145674 -0.816968 -0.576683 0 0.934871 0.354583 0.0169167
--0.877317 0.477987 0.0429295 0.995081 0.0990068 -0.003342 -0.506055 -0.815438 0.281014
--0.580456 -0.792608 0.186665 -0.702755 -0.679441 0.210938 0.873762 0.479722 0.0800368
--0.879136 -0.467433 0.0928828 -0.839357 -0.533423 0.104593 0.792351 0.598665 -0.117385
-0.608994 0.793169 -0.00289584 -0.386139 -0.91992 -0.0681422 -0.501173 -0.864928 -0.0269448
-0.0353772 -0.995515 -0.0877355 0.225014 -0.964347 -0.139295 0.131541 -0.978663 -0.157849
--0.92299 -0.301215 -0.239498 0.994016 0.0808006 -0.0735061 -0.999674 0.0237077 -0.00948307
-0.786206 0.614147 0.0685787 0.745826 0.664091 0.0522191 -0.827312 -0.561551 0.0146811
-0.398312 -0.895884 0.196823 0.890365 -0.257455 0.375455 0.947689 -0.238664 0.211953
--0.311313 0.939372 0.143747 -0.421666 0.893895 0.152152 -0.474223 0.868607 0.143646
-0.783056 -0.613877 0.099896 0.955642 0.293845 0.0201067 0.948216 0.31657 0.0258831
--0.869706 0.493266 0.0173076 0.397071 -0.887569 -0.233571 -0.210322 -0.974072 0.0833535
--0.42977 -0.883827 0.184791 0.817617 0.557814 0.142637 0.870774 0.484908 0.0813462
--0.896909 -0.426012 0.118609 -0.899513 -0.419499 0.122055 0.838843 0.514054 -0.17914
--0.46401 -0.882192 -0.0801993 -0.427994 -0.899229 -0.0905994 -0.449055 -0.888681 -0.0927182
-0.0184781 -0.999355 0.0307968 0.203288 -0.969071 0.139911 0.141264 -0.979215 0.145544
--0.374923 -0.917243 0.134529 -0.648587 -0.760662 0.0269943 0.963864 0.247301 -0.0990371
--0.991303 0.122134 -0.0490118 0.903905 0.418992 0.086033 -0.941562 -0.336377 0.0176268
--0.999317 -0.03624 0.00724799 0.927754 -0.36205 0.0905126 -0.511409 0.843703 0.163175
--0.212154 0.960347 0.180896 -0.00765895 0.967216 0.253839 -0.178031 0.922856 0.341529
--0.812055 0.165164 0.559721 -0.928033 -0.164527 0.334195 0.912076 0.407963 -0.0410359
--0.83404 0.551393 0.0185342 0.893366 0.421589 0.155434 0.885165 0.440939 0.148513
--0.926284 -0.338503 0.165572 0.822803 0.530898 -0.202835 0.843827 0.497414 -0.201334
--0.687959 -0.713822 -0.13104 -0.695958 -0.70123 -0.154657 -0.211188 -0.96277 0.168743
-0.9139 0.395713 -0.0905412 -0.966118 0.249114 -0.0675129 0.943885 0.305949 0.124405
-0.911594 0.4008 0.0914105 -0.933941 0.352142 0.061242 0.919684 -0.392399 0.0143062
-0.916233 -0.400521 0.0100402 -0.471059 -0.203593 0.858285 -0.915223 -0.345325 0.207646
--0.919381 -0.326333 0.219647 0.869706 0.493266 -0.0173076 -0.856248 0.516528 0.00617672
--0.863412 0.5045 0 0.949901 0 0.312551 0.966694 0.133233 0.218522
--0.829007 -0.531972 0.172494 0.854524 0.481433 -0.194963 0.840974 0.507777 -0.186883
--0.696513 -0.697582 -0.168075 -0.691162 -0.703023 -0.167489 0.904852 0.419322 -0.0735652
-0.913292 0.397282 -0.089807 -0.965403 0.252157 -0.0664415 -0.943215 0.327134 -0.0577045
-0.881904 -0.386588 0.269806 0.893837 -0.441355 0.0791225 -0.844528 0.50902 0.166346
-0.886347 -0.463017 0.0020044 -0.0828959 -0.828959 0.553133 -0.804999 -0.542142 0.240952
-0.808104 0.58812 -0.0329227 -0.837432 0.546542 0 0.534473 -0.749104 0.391386
-0.728828 -0.596314 0.336482 -0.379356 -0.895194 0.233918 -0.453989 -0.868649 0.198353
--0.766829 -0.616239 0.179505 0.801561 0.389275 -0.453834 0.674657 -0.500177 -0.542827
--0.273896 -0.903855 -0.328675 -0.502434 -0.846655 -0.175317 0.943631 0.313417 -0.106444
--0.965631 0.253008 -0.0595312 0.480927 -0.874065 0.0687038 0.33854 -0.939856 0.0453944
-0.457787 -0.884002 0.0947145 -0.792912 -0.448754 0.412202 -0.873995 0.430419 0.225547
--0.914481 0.145486 0.37757 -0.924688 0.260226 0.277912 0.705414 -0.705414 0.0691582
--0.559827 -0.828604 -0.00296991 -0.535111 -0.844212 -0.0310209 0.0216605 -0.982702 0.183924
-0.0438133 -0.986753 0.156204 -0.478183 -0.847161 0.231646 0.792308 0.609598 0.0252596
-0.806769 0.590681 -0.014824 -0.821657 0.569983 0 -0.758782 0.651344 0
-0.419925 -0.835832 0.353621 -0.381501 -0.902954 0.197816 0.369933 -0.494845 -0.786307
-0.147043 -0.735215 -0.661693 0.364599 -0.798177 -0.479563 0.0134744 -0.881226 -0.472503
-0.937113 0.329655 -0.114662 0.942484 0.315008 -0.111777 -0.943881 0.312655 -0.106472
-0.708104 -0.689293 0.153176 0.666982 -0.698981 0.257993 -0.652166 -0.652166 0.386469
--0.195227 -0.980728 -0.00765596 0.810902 0.584913 0.0177246 -0.759496 0.650492 -0.00500152
--0.788524 0.61494 -0.00882193 0.902719 0.410994 -0.127212 -0.930072 0.35149 -0.106866
--0.899866 0.424305 -0.101025 0.436202 0.00411512 0.899839 0.534324 0.0360218 0.844512
-0.235431 -0.0692444 0.969421 -0.599185 -0.607869 0.52103 0.812685 0.582424 -0.0180597
--0.835147 0.548455 -0.0415496 0.88482 0.44965 -0.122098 -0.878117 0.462348 -0.123063
-0.806244 0.35495 0.473267 -0.785754 0.522178 0.331542 -0.769256 0.56541 0.297584
-0.924872 -0.305423 -0.226558 0.725795 0.687257 -0.0299738 0.785491 0.618516 -0.0210092
--0.786373 0.615992 -0.0465999 0.851665 0.50546 -0.138482 0.884147 0.450915 -0.122307
--0.869551 0.480897 -0.112332 -0.87569 0.47276 -0.0983109 0.931887 -0.298993 0.2054
--0.774241 0.584113 0.243645 -0.309426 -0.618853 -0.721995 0.376057 0.924474 0.0626762
-0.143217 0.984764 0.0986342 -0.452387 0.891597 0.0200085 -0.542807 0.839708 0.0158348
-0.687566 0.726122 0 0.707008 0.707008 -0.0166846 -0.762011 0.646569 -0.0358951
--0.725795 0.687257 -0.0299738 0.794815 0.590631 -0.13937 0.806362 0.57469 -0.139682
--0.878117 0.462348 -0.123063 0.818428 -0.574589 0.00482848 -0.889982 0.389367 0.237329
--0.942235 0.240827 0.232799 0.949207 0.244655 -0.197863 0.743874 0.66668 -0.0467846
--0.70665 0.698237 -0.114503 0.632487 0.773272 0.0448425 0.666306 0.745471 0.0175922
--0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846 0.799405 0.586597 -0.129831
--0.850808 0.513854 -0.109911 -0.824838 0.555611 -0.104586 0.793489 -0.607421 -0.0376137
-0.702593 -0.711259 -0.0217755 -0.953977 -0.0681412 0.292034 0.968046 -0.154887 -0.197223
--0.70948 0.695059 -0.116324 -0.750326 0.641609 -0.159214 0.780173 0.619123 0.0895342
-0.649066 0.758225 0.0617139 -0.706805 0.706805 -0.0291896 -0.706805 0.706805 -0.0291896
-0.836657 0.530563 -0.136042 0.811074 0.570608 -0.128706 -0.733792 0.668275 -0.122299
-0.567254 -0.815787 0.11276 -0.496535 -0.722233 0.481489 0.915373 -0.377906 -0.138846
-0.909728 -0.394216 -0.130341 -0.77009 0.621238 -0.145001 -0.809467 0.575253 -0.117678
-0.794994 0.605489 0.0369765 0.819705 0.568624 0.0689241 -0.706805 0.706805 -0.0291896
--0.706805 0.706805 -0.0291896 0.789101 0.598476 -0.138368 0.806362 0.57469 -0.139682
--0.702247 0.702247 -0.117041 0.381865 0.816705 0.432633 0.468256 0.784886 0.405822
-0.374228 0.83328 0.406938 0.15149 0.908938 0.388435 0.976021 -0.206743 -0.0681131
--0.837875 0.54286 -0.0571733 -0.825293 0.564318 -0.0209006 0.699576 0.714556 -0.00188929
-0.726079 0.687511 0.011738 -0.707008 0.707008 -0.0166846 -0.707008 0.707008 -0.0166846
-0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662 0.972209 0.0920126 0.215275
--0.431596 0.868096 0.245225 0.0797681 0.765773 0.638144 -0.566086 0.804585 0.179415
--0.589585 0.787992 0.177364 0.973088 0.221881 -0.0621977 -0.458034 0.883862 0.0948273
-0.0732056 0.995596 0.0585645 0.532326 0.846239 -0.022555 -0.687257 0.725795 -0.0299738
--0.64644 0.761859 -0.0410583 0.702247 0.702247 -0.117041 -0.699976 0.699976 -0.141662
-0.959724 0.0239931 0.279919 0.982839 -0.150106 0.107219 0.432905 0.132964 0.891579
--0.388253 0.745925 0.541161 -0.619265 0.76639 0.170755 -0.615557 0.769446 0.170418
-0.510862 0.849929 -0.128996 0.719484 0.682962 -0.126123 -0.631207 0.773877 -0.05188
--0.62591 0.777172 -0.0651199 0.702247 0.702247 -0.117041 -0.598023 0.788504 -0.143633
--0.57469 0.806362 -0.139682 0.805703 -0.523707 0.276721 0.81319 -0.521513 0.258352
-0.547421 0.646952 0.530833 -0.510677 0.805299 0.301169 -0.276292 0.621658 0.732942
--0.797498 0.531665 0.285184 0.834017 0.476581 -0.278006 -0.433011 0.899851 -0.0526229
--0.42302 0.905901 -0.0199538 0.968 -0.23474 0.0887333 0.915018 -0.223407 0.335903
-0.963438 -0.255693 0.0800511 -0.675917 0.724073 0.137311 -0.672087 0.729168 0.128893
-0.952642 0.156456 -0.26076 0.458781 0.873746 -0.161518 0.00928327 0.99994 0.00574678
--0.0698733 0.996454 -0.0468715 0.215983 0.970446 -0.107639 -0.625859 0.77732 -0.0638284
--0.597383 0.801148 -0.0360066 -0.580015 0.813834 -0.0354454 0.702247 0.702247 -0.117041
--0.525649 0.839674 -0.136532 -0.570557 0.811923 -0.123471 0.806603 -0.531971 0.257679
-0.7963 -0.482163 0.365275 0.754212 -0.612311 0.237149 -0.828484 0.49962 0.252972
--0.778659 0.562949 0.27709 -0.803751 0.547575 0.232693 0.972897 0.201475 -0.113487
--0.440032 0.897903 -0.0118928 0.0335315 0.997962 -0.0542891 0.309552 0.950768 0.0147406
--0.0730282 0.994077 0.08048 -0.472144 0.872894 0.123031 -0.445174 0.890348 0.0953944
-0.918071 0.367722 0.148076 -0.607681 0.791702 0.0627037 -0.542928 0.837084 0.0672356
-0.96818 0.142503 -0.205721 -0.504826 0.862411 -0.0373945 -0.512535 0.858496 -0.0170845
-0.629993 0.760337 0.158102 0.146781 0.974779 0.168109 -0.405681 0.901513 0.150658
--0.420219 0.89516 0.148677 0.722843 0.687674 0.0678445 0.702802 0.708286 0.0663365
--0.13555 0.988715 -0.0637881 -0.511905 0.856869 -0.0610642 0.702247 0.702247 -0.117041
--0.593961 0.795024 -0.123073 -0.702247 0.702247 -0.117041 0.831794 -0.521423 0.190361
-0.814657 0.569062 0.111816 0.96461 -0.208999 0.160768 -0.468793 0.882546 0.0366937
--0.254913 0.96691 0.0102551 0.324573 0.933702 -0.151171 -0.396089 0.902252 0.170454
--0.36321 0.928204 0.0807134 0.41152 0.909894 -0.0523878 0.74245 0.669215 -0.0303041
--0.431545 0.896854 0.0970712 -0.647366 0.745287 0.159575 -0.754312 0.641948 0.137538
-0.965728 0.181539 -0.185507 -0.547652 0.836428 -0.0215729 -0.509393 0.860512 -0.00614652
-0.893389 -0.447659 0.0381625 -0.683946 0.72111 0.110537 -0.640153 0.766706 0.0486504
-0.888531 0.45377 0.0678611 -0.708849 0.702835 -0.0596345 -0.974618 0.223189 0.017505
-0.702247 0.702247 -0.117041 -0.702247 0.702247 -0.117041 0.996896 0.0750352 0.0238207
--0.238509 0.971074 0.0113576 0.0596535 0.997654 -0.033598 0.243225 0.957762 -0.153403
-0.0867785 0.995858 -0.0271308 -0.789815 0.600173 0.126428 0.871693 0.460363 -0.167982
--0.500058 0.865992 0 -0.468148 0.88365 0 -0.449818 0.893022 0.01323
-0.678991 -0.734044 -0.0122341 0.542535 -0.837459 -0.065714 -0.5071 0.86187 0.00534493
--0.438332 0.895684 0.0749286 -0.42997 0.899028 0.0829143 0.322186 0.946591 0.0127059
-0.307146 0.950664 -0.0435743 -0.181453 0.967752 -0.174733 -0.14762 0.984136 -0.0984136
-0.673835 0.737049 0.0520059 -0.858604 -0.512637 -0.00168354 0.702247 0.702247 -0.117041
--0.665916 0.731202 -0.147981 0.982715 0.181589 -0.0360245 -0.0643781 -0.981086 -0.182556
--0.1195 -0.979236 -0.163759 0.113419 -0.975399 -0.189031 -0.793613 0.595728 0.123635
--0.709686 0.695789 0.11056 0.563008 0.811297 -0.157541 0.528451 0.835585 -0.150126
-0.814319 0.555351 -0.168733 -0.457502 0.888747 0.0286436 -0.550553 0.834103 0.0340962
--0.574767 0.817704 0.0316554 0.534635 -0.840508 -0.0878206 0.649105 -0.740743 -0.173095
-0.737686 -0.658186 -0.150372 -0.363244 0.915201 0.174532 -0.412962 0.880654 0.232187
--0.105526 0.972834 0.206056 0.169772 0.969818 0.175016 0.204462 0.965997 0.158256
-0.15206 0.975996 0.155917 0.173893 0.978574 0.110246 0.292003 0.955725 0.0363921
--0.856901 -0.512676 -0.0537089 -0.812914 -0.577504 -0.0752371 0.479499 0.871225 -0.10511
-0.562478 0.818834 -0.114587 -0.616715 0.771145 -0.158106 -0.535488 0.82647 -0.173781
-0.670118 0.713468 -0.204708 -0.473457 -0.880601 0.0195039 -0.495026 -0.867695 0.0453174
--0.321311 -0.943506 -0.0809718 0.993584 0.111048 -0.0214302 -0.695781 0.712525 0.0905384
--0.599816 0.800085 -0.00925335 0.682727 0.717103 -0.14017 0.673821 0.719973 -0.166148
--0.626889 0.778445 0.0321482 -0.537073 0.843487 0.00904544 0.858828 -0.496212 -0.127234
--0.915686 -0.391304 -0.0916567 0.624353 0.77943 -0.0516923 0.441226 0.896205 -0.0462237
-0.312499 0.946568 -0.0797052 -0.158298 0.966672 -0.201214 0.624981 0.752234 -0.208669
--0.385295 -0.917935 0.0945696 -0.920835 -0.381253 -0.0819083 0.188245 -0.982101 0.00645411
-0.925438 -0.37178 -0.0731078 0.944088 -0.322686 -0.0676105 -0.653123 -0.748006 0.117973
--0.576251 -0.81473 0.0644219 0.99542 0.0704722 0.0645995 -0.58365 0.811376 -0.0319472
--0.227703 0.961412 -0.154397 0.478233 0.861316 -0.171546 -0.497727 0.867334 0
--0.392374 0.919676 0.0154814 -0.397157 0.917569 0.0182601 0.772741 -0.624267 -0.11473
--0.860065 -0.500567 0.0985965 -0.945583 -0.301323 0.12279 0.36121 -0.916403 0.17243
-0.454101 -0.876765 0.158353 -0.887808 -0.448053 -0.105099 -0.717029 -0.691722 -0.0859632
-0.74326 0.66433 -0.0789303 0.727248 0.684071 -0.0561823 -0.679343 0.71428 -0.168218
-0.160269 0.910797 -0.380476 0.884122 0.424657 -0.194924 -0.856608 -0.48949 0.163163
--0.681658 -0.718998 0.13559 0.989926 0 0.141587 -0.478352 0.878168 0
--0.397157 0.917569 -0.0182601 0.75075 -0.637123 -0.174499 0.685822 0.636443 -0.35297
-0.99177 -0.0627702 -0.111592 0.979575 -0.171037 -0.105732 0.986894 -0.119791 -0.108119
--0.917159 0.374499 0.136269 0.443643 -0.887287 0.126107 -0.12786 -0.991428 -0.0268939
-0.64434 0.759385 -0.090338 0.704894 0.704894 -0.0790535 -0.42833 0.888728 -0.163391
--0.0259677 0.969837 -0.242365 0.850593 0.47778 -0.219586 -0.962319 0.271423 0.0164499
-0.909347 0.199221 0.365238 0.965527 0.200753 0.165701 0.992061 0.0646997 0.107833
--0.321976 0.946552 -0.0192389 -0.326273 0.945081 -0.0192006 -0.175995 0.982641 -0.0586652
-0.0976805 0.993085 -0.0651203 0.183147 0.976783 -0.11114 0.0580726 0.97562 -0.211643
-0.265251 0.89973 -0.346594 0.990571 -0.0466412 -0.128819 -0.910502 0.391643 0.132668
--0.784732 0.617641 0.0521165 0.499462 0.85805 -0.119529 0.615386 0.781235 -0.104747
--0.493157 0.867277 -0.0680217 0.662902 0.745765 0.0662903 -0.800862 0.597836 -0.0348297
--0.82467 0.555207 -0.108002 0.394016 0.910313 -0.12681 0.47473 0.87152 -0.122816
--0.207983 0.974714 -0.0817076 0 0.99922 -0.0394837 0.217662 0.976024 0
--0.78792 0.597133 -0.150381 -0.738577 0.656931 -0.151476 0.335756 0.93732 -0.0932657
-0.325028 0.941474 -0.0893519 0.319809 0.940182 -0.117386 -0.312036 0.934975 -0.168689
-0.0745504 0.984242 -0.160342 0.158075 0.973779 -0.163606 0.0663259 0.99153 -0.111663
-0 0.995211 -0.0977514 0.0882513 0.992617 -0.0832084 0.254057 0.962565 -0.0944677
-
diff --git a/Modules/Segmentation/Testing/Data/testNrrd.ascii b/Modules/Segmentation/Testing/Data/testNrrd.ascii
deleted file mode 100644
index f78381e84b..0000000000
--- a/Modules/Segmentation/Testing/Data/testNrrd.ascii
+++ /dev/null
@@ -1,8 +0,0 @@
-2 2
-2 2
-2 2
-2 2
-1 1
-1 1
-1 1
-1 1
\ No newline at end of file
diff --git a/Modules/Segmentation/Testing/Data/testNrrd.nhdr b/Modules/Segmentation/Testing/Data/testNrrd.nhdr
deleted file mode 100644
index d62bdcaba6..0000000000
--- a/Modules/Segmentation/Testing/Data/testNrrd.nhdr
+++ /dev/null
@@ -1,20 +0,0 @@
-NRRD0005
-content: SomeIDNumber42
-type: short
-dimension: 4
-space: right-anterior-superior
-sizes: 2 2 2 2
-thicknesses: NaN NaN 2.5 NaN
-space directions: (2,0,0) (0,2.5,0) (0,0,2) none
-centerings: cell cell cell none
-kinds: space space space list
-endian: little
-encoding: ascii
-space units: "mm" "mm" "mm"
-space origin: (0,0,0)
-data file: testNrrd.ascii
-measurement frame: (1,0,0) (0,0,1) (0,1,0)
-modality:=DWMRI
-DWMRI_b-value:=1000
-DWMRI_gradient_0000:= 0 0 0
-DWMRI_gradient_0001:= 1 0 1
\ No newline at end of file
diff --git a/Modules/Segmentation/Testing/Data/testimage.dcm b/Modules/Segmentation/Testing/Data/testimage.dcm
deleted file mode 100644
index ecf7b12d33..0000000000
Binary files a/Modules/Segmentation/Testing/Data/testimage.dcm and /dev/null differ
diff --git a/Modules/Segmentation/Testing/Data/vtkUnstructuredGrid.vtk b/Modules/Segmentation/Testing/Data/vtkUnstructuredGrid.vtk
deleted file mode 100644
index 392ef94c61..0000000000
Binary files a/Modules/Segmentation/Testing/Data/vtkUnstructuredGrid.vtk and /dev/null differ
diff --git a/Modules/Segmentation/Testing/mitkOverwriteSliceFilterObliquePlaneTest.cpp b/Modules/Segmentation/Testing/mitkOverwriteSliceFilterObliquePlaneTest.cpp
index 02184e6764..12226baf69 100644
--- a/Modules/Segmentation/Testing/mitkOverwriteSliceFilterObliquePlaneTest.cpp
+++ b/Modules/Segmentation/Testing/mitkOverwriteSliceFilterObliquePlaneTest.cpp
@@ -1,282 +1,282 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkExtractSliceFilter.h>
#include <mitkVtkImageOverwrite.h>
#include <mitkImageCast.h>
#include <mitkGeometry3D.h>
#include <mitkRotationOperation.h>
#include <mitkInteractionConst.h>
#include <mitkImagePixelReadAccessor.h>
#include <itkImage.h>
#include <itkImageRegionIterator.h>
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
int ObliquePlaneTestVolumeSize = 128;
static void OverwriteObliquePlaneTest(mitk::Image* workingImage, mitk::Image* refImg)
{
/*==============TEST WITHOUT MITK CONVERTION=============================*/
/* ============= setup plane ============*/
int sliceindex = (int)(ObliquePlaneTestVolumeSize /2);//rand() % 32;
bool isFrontside = true;
bool isRotated = false;
mitk::PlaneGeometry::Pointer obliquePlane = mitk::PlaneGeometry::New();
obliquePlane->InitializeStandardPlane(workingImage->GetGeometry(), mitk::PlaneGeometry::Axial, sliceindex, isFrontside, isRotated);
mitk::Point3D origin = obliquePlane->GetOrigin();
mitk::Vector3D normal;
normal = obliquePlane->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
obliquePlane->SetOrigin(origin);
mitk::Vector3D rotationVector = obliquePlane->GetAxisVector(0);
rotationVector.Normalize();
float degree = 45.0;
mitk::RotationOperation* op = new mitk::RotationOperation(mitk::OpROTATE, obliquePlane->GetCenter(), rotationVector, degree);
obliquePlane->ExecuteOperation(op);
delete op;
/* ============= extract slice ============*/
mitk::ExtractSliceFilter::Pointer slicer = mitk::ExtractSliceFilter::New();
slicer->SetInput(workingImage);
slicer->SetWorldGeometry(obliquePlane);
slicer->SetVtkOutputRequest(true);
slicer->Modified();
slicer->Update();
vtkSmartPointer<vtkImageData> slice = vtkSmartPointer<vtkImageData>::New();
slice = slicer->GetVtkOutput();
/* ============= overwrite slice ============*/
vtkSmartPointer<mitkVtkImageOverwrite> resliceIdx = vtkSmartPointer<mitkVtkImageOverwrite>::New();
mitk::ExtractSliceFilter::Pointer overwriter = mitk::ExtractSliceFilter::New(resliceIdx);
resliceIdx->SetOverwriteMode(true);
resliceIdx->SetInputSlice(slice);
resliceIdx->Modified();
overwriter->SetInput(workingImage);
overwriter->SetWorldGeometry(obliquePlane);
overwriter->SetVtkOutputRequest(true);
overwriter->Modified();
overwriter->Update();
typedef mitk::ImagePixelReadAccessor< unsigned short, 3 > ReadAccessorType;
ReadAccessorType refImgReadAccessor( refImg );
ReadAccessorType workingImgReadAccessor( workingImage );
/* ============= check ref == working ============*/
bool areSame = true;
itk::Index<3> id;
id[0] = id[1] = id[2] = 0;
for (int x = 0; x < ObliquePlaneTestVolumeSize ; ++x){
id[0] = x;
for (int y = 0; y < ObliquePlaneTestVolumeSize ; ++y){
id[1] = y;
for (int z = 0; z < ObliquePlaneTestVolumeSize ; ++z){
id[2] = z;
areSame = refImgReadAccessor.GetPixelByIndex(id) == workingImgReadAccessor.GetPixelByIndex(id);
if(!areSame)
goto stop;
}
}
}
stop:
MITK_TEST_CONDITION(areSame,"comparing images (no mitk convertion) [oblique]");
/*==============TEST WITH MITK CONVERTION=============================*/
/* ============= extract slice ============*/
mitk::ExtractSliceFilter::Pointer slicer2 = mitk::ExtractSliceFilter::New();
slicer2->SetInput(workingImage);
slicer2->SetWorldGeometry(obliquePlane);
slicer2->Modified();
slicer2->Update();
mitk::Image::Pointer sliceInMitk = slicer2->GetOutput();
vtkSmartPointer<vtkImageData> slice2 = vtkSmartPointer<vtkImageData>::New();
slice2 = sliceInMitk->GetVtkImageData();
/* ============= overwrite slice ============*/
vtkSmartPointer<mitkVtkImageOverwrite> resliceIdx2 = vtkSmartPointer<mitkVtkImageOverwrite>::New();
mitk::ExtractSliceFilter::Pointer overwriter2 = mitk::ExtractSliceFilter::New(resliceIdx2);
resliceIdx2->SetOverwriteMode(true);
resliceIdx2->SetInputSlice(slice2);
resliceIdx2->Modified();
overwriter2->SetInput(workingImage);
overwriter2->SetWorldGeometry(obliquePlane);
overwriter2->SetVtkOutputRequest(true);
overwriter2->Modified();
overwriter2->Update();
/* ============= check ref == working ============*/
areSame = true;
id[0] = id[1] = id[2] = 0;
for (int x = 0; x < ObliquePlaneTestVolumeSize ; ++x){
id[0] = x;
for (int y = 0; y < ObliquePlaneTestVolumeSize ; ++y){
id[1] = y;
for (int z = 0; z < ObliquePlaneTestVolumeSize ; ++z){
id[2] = z;
areSame = refImgReadAccessor.GetPixelByIndex(id) == workingImgReadAccessor.GetPixelByIndex(id);
if(!areSame)
goto stop2;
}
}
}
stop2:
MITK_TEST_CONDITION(areSame,"comparing images (with mitk convertion) [oblique]");
/*==============TEST EDIT WITHOUT MITK CONVERTION=============================*/
/* ============= edit slice ============*/
int idX = std::abs(ObliquePlaneTestVolumeSize -59);
int idY = std::abs(ObliquePlaneTestVolumeSize -23);
int idZ = 0;
int component = 0;
double val = 33.0;
slice->SetScalarComponentFromDouble(idX,idY,idZ,component,val);
mitk::Vector3D indx;
indx[0] = idX; indx[1] = idY; indx[2] = idZ;
sliceInMitk->GetGeometry()->IndexToWorld(indx, indx);
/* ============= overwrite slice ============*/
vtkSmartPointer<mitkVtkImageOverwrite> resliceIdx3 = vtkSmartPointer<mitkVtkImageOverwrite>::New();
resliceIdx3->SetOverwriteMode(true);
resliceIdx3->SetInputSlice(slice);
mitk::ExtractSliceFilter::Pointer overwriter3 = mitk::ExtractSliceFilter::New(resliceIdx3);
overwriter3->SetInput(workingImage);
overwriter3->SetWorldGeometry(obliquePlane);
overwriter3->SetVtkOutputRequest(true);
overwriter3->Modified();
overwriter3->Update();
/* ============= check ============*/
areSame = true;
int x,y,z;
for ( x = 0; x < ObliquePlaneTestVolumeSize ; ++x){
id[0] = x;
for ( y = 0; y < ObliquePlaneTestVolumeSize ; ++y){
id[1] = y;
for ( z = 0; z < ObliquePlaneTestVolumeSize ; ++z){
id[2] = z;
areSame = refImgReadAccessor.GetPixelByIndex(id) == workingImgReadAccessor.GetPixelByIndex(id);
if(!areSame)
goto stop3;
}
}
}
stop3:
//MITK_INFO << "index: [" << x << ", " << y << ", " << z << "]";
//MITK_INFO << indx;
MITK_TEST_CONDITION(x==idX && y==z,"overwrited the right index [oblique]");
}
/*================ #BEGIN test main ================*/
-int mitkOverwriteSliceFilterObliquePlaneTest(int argc, char* argv[])
+int mitkOverwriteSliceFilterObliquePlaneTest(int , char* [])
{
MITK_TEST_BEGIN("mitkOverwriteSliceFilterObliquePlaneTest")
typedef itk::Image<unsigned short, 3> ImageType;
typedef itk::ImageRegionConstIterator< ImageType > ImageIterator;
ImageType::Pointer image = ImageType::New();
ImageType::IndexType start;
start[0] = start[1] = start[2] = 0;
ImageType::SizeType size;
size[0] = size[1] = size[2] = ObliquePlaneTestVolumeSize ;
ImageType::RegionType imgRegion;
imgRegion.SetSize(size);
imgRegion.SetIndex(start);
image->SetRegions(imgRegion);
image->SetSpacing(1.0);
image->Allocate();
ImageIterator imageIterator( image, image->GetLargestPossibleRegion() );
imageIterator.GoToBegin();
unsigned short pixelValue = 0;
//fill the image with distinct values
while ( !imageIterator.IsAtEnd() )
{
image->SetPixel(imageIterator.GetIndex(), pixelValue);
++imageIterator;
++pixelValue;
}
/* end setup itk image */
mitk::Image::Pointer refImage;
CastToMitkImage(image, refImage);
mitk::Image::Pointer workingImg;
CastToMitkImage(image, workingImg);
OverwriteObliquePlaneTest(workingImg, refImage);
MITK_TEST_END()
}
diff --git a/Modules/Segmentation/Testing/mitkOverwriteSliceFilterTest.cpp b/Modules/Segmentation/Testing/mitkOverwriteSliceFilterTest.cpp
index 36f9f1a528..ae61e53f0b 100644
--- a/Modules/Segmentation/Testing/mitkOverwriteSliceFilterTest.cpp
+++ b/Modules/Segmentation/Testing/mitkOverwriteSliceFilterTest.cpp
@@ -1,205 +1,205 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkExtractSliceFilter.h>
#include <mitkVtkImageOverwrite.h>
#include <mitkImageCast.h>
#include <mitkGeometry3D.h>
#include <mitkRotationOperation.h>
#include <mitkInteractionConst.h>
#include <mitkImagePixelReadAccessor.h>
#include <itkImage.h>
#include <itkImageRegionIterator.h>
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
int VolumeSize = 128;
/*================ #BEGIN test main ================*/
-int mitkOverwriteSliceFilterTest(int argc, char* argv[])
+int mitkOverwriteSliceFilterTest(int, char* [])
{
MITK_TEST_BEGIN("mitkOverwriteSliceFilterTest")
typedef itk::Image<unsigned short, 3> ImageType;
typedef itk::ImageRegionConstIterator< ImageType > ImageIterator;
ImageType::Pointer image = ImageType::New();
ImageType::IndexType start;
start[0] = start[1] = start[2] = 0;
ImageType::SizeType size;
size[0] = size[1] = size[2] = VolumeSize;
ImageType::RegionType imgRegion;
imgRegion.SetSize(size);
imgRegion.SetIndex(start);
image->SetRegions(imgRegion);
image->SetSpacing(1.0);
image->Allocate();
ImageIterator imageIterator( image, image->GetLargestPossibleRegion() );
imageIterator.GoToBegin();
unsigned short pixelValue = 0;
//fill the image with distinct values
while ( !imageIterator.IsAtEnd() )
{
image->SetPixel(imageIterator.GetIndex(), pixelValue);
++imageIterator;
++pixelValue;
}
/* end setup itk image */
mitk::Image::Pointer referenceImage;
CastToMitkImage(image, referenceImage);
mitk::Image::Pointer workingImage;
CastToMitkImage(image, workingImage);
typedef mitk::ImagePixelReadAccessor< unsigned short, 3 > ReadAccessorType;
ReadAccessorType refImgReadAccessor( referenceImage );
ReadAccessorType workingImgReadAccessor( workingImage );
/* ============= setup plane ============*/
int sliceindex = 55;//rand() % 32;
bool isFrontside = true;
bool isRotated = false;
mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
plane->InitializeStandardPlane(workingImage->GetGeometry(), mitk::PlaneGeometry::Axial, sliceindex, isFrontside, isRotated);
mitk::Point3D origin = plane->GetOrigin();
mitk::Vector3D normal;
normal = plane->GetNormal();
normal.Normalize();
origin += normal * 0.5;//pixelspacing is 1, so half the spacing is 0.5
plane->SetOrigin(origin);
/* ============= extract slice ============*/
vtkSmartPointer<mitkVtkImageOverwrite> resliceIdx = vtkSmartPointer<mitkVtkImageOverwrite>::New();
mitk::ExtractSliceFilter::Pointer slicer = mitk::ExtractSliceFilter::New(resliceIdx);
slicer->SetInput(workingImage);
slicer->SetWorldGeometry(plane);
slicer->SetVtkOutputRequest(true);
slicer->Modified();
slicer->Update();
vtkSmartPointer<vtkImageData> slice = vtkSmartPointer<vtkImageData>::New();
slice = slicer->GetVtkOutput();
/* ============= overwrite slice ============*/
resliceIdx->SetOverwriteMode(true);
resliceIdx->Modified();
slicer->Modified();
slicer->Update();//implicit overwrite
/* ============= check ref == working ============*/
bool areSame = true;
itk::Index<3> id;
id[0] = id[1] = id[2] = 0;
for (int x = 0; x < VolumeSize; ++x){
id[0] = x;
for (int y = 0; y < VolumeSize; ++y){
id[1] = y;
for (int z = 0; z < VolumeSize; ++z){
id[2] = z;
areSame = refImgReadAccessor.GetPixelByIndex( id ) == workingImgReadAccessor.GetPixelByIndex( id );
if(!areSame)
goto stop;
}
}
}
stop:
MITK_TEST_CONDITION(areSame,"test overwrite unmodified slice");
/* ============= edit slice ============*/
int idX = std::abs(VolumeSize-59);
int idY = std::abs(VolumeSize-23);
int idZ = 0;
int component = 0;
double val = 33.0;
slice->SetScalarComponentFromDouble(idX,idY,idZ,component,val);
/* ============= overwrite slice ============*/
vtkSmartPointer<mitkVtkImageOverwrite> resliceIdx2 = vtkSmartPointer<mitkVtkImageOverwrite>::New();
resliceIdx2->SetOverwriteMode(true);
resliceIdx2->SetInputSlice(slice);
mitk::ExtractSliceFilter::Pointer slicer2 = mitk::ExtractSliceFilter::New(resliceIdx2);
slicer2->SetInput(workingImage);
slicer2->SetWorldGeometry(plane);
slicer2->SetVtkOutputRequest(true);
slicer2->Modified();
slicer2->Update();
/* ============= check ============*/
areSame = true;
int xx,yy,zz;
for ( xx = 0; xx < VolumeSize; ++xx){
id[0] = xx;
for ( yy = 0; yy < VolumeSize; ++yy){
id[1] = yy;
for ( zz = 0; zz < VolumeSize; ++zz){
id[2] = zz;
areSame = refImgReadAccessor.GetPixelByIndex( id ) == workingImgReadAccessor.GetPixelByIndex( id );
if(!areSame)
goto stop2;
}
}
}
stop2:
//MITK_INFO << "index: [" << x << ", " << y << ", " << z << "]";
MITK_TEST_CONDITION(xx==idX && yy==idY && zz==sliceindex,"test overwrite modified slice");
MITK_TEST_END()
}
diff --git a/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp b/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp
index 405ce365d0..a658d39a3d 100644
--- a/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp
+++ b/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp
@@ -1,159 +1,218 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkTestingConfig.h>
#include <mitkTestFixture.h>
#include <mitkIOUtil.h>
#include <mitkInteractionTestHelper.h>
#include <mitkStandaloneDataStorage.h>
#include <mitkToolManager.h>
#include <mitkGlobalInteraction.h>
#include <mitkDataNode.h>
+#include <vtkDebugLeaks.h>
class mitkToolInteractionTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkToolInteractionTestSuite);
+
+ /// \todo Fix VTK memory leaks. Bug 18098.
+ vtkDebugLeaks::SetExitError(0);
+
/* ####### example ######
- MITK_TEST(AddToolInteractionTest);
+
MITK_TEST(AddToolInteraction_4D_Test);
#########################*/
+ MITK_TEST(AddToolInteractionTest);
+ MITK_TEST(SubtractToolInteractionTest);
+ MITK_TEST(PaintToolInteractionTest);
+ MITK_TEST(WipeToolInteractionTest);
+ MITK_TEST(RegionGrowingToolInteractionTest);
+ MITK_TEST(CorrectionToolInteractionTest);
+ MITK_TEST(EraseToolInteractionTest);
+ MITK_TEST(FillToolInteractionTest);
+
CPPUNIT_TEST_SUITE_END();
private:
- mitk::DataStorage* m_DataStorage;
+ mitk::DataStorage::Pointer m_DataStorage;
mitk::ToolManager::Pointer m_ToolManager;
public:
int GetToolIdByToolName (const std::string& toolName)
{
//find tool from toolname
int numberOfTools = m_ToolManager->GetTools().size();
int toolId = 0;
for(; toolId < numberOfTools; ++toolId)
{
mitk::Tool* currentTool = m_ToolManager->GetToolById(toolId);
if(toolName.compare( currentTool->GetNameOfClass() ) == 0)
{
return toolId;
+
}
}
+
return -1;
}
void RunTestWithParameters(const std::string& patientImagePath,
const std::string& referenceSegmentationImage,
const std::string& toolName,
const std::string& interactionPattern,
- unsigned int timestep=0)
+ unsigned int timestep=0,
+ const std::string& preSegmentationImagePath = std::string())
{
//Create test helper to initialize all necessary objects for interaction
mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionPattern));
//Use data storage of test helper
m_DataStorage = interactionTestHelper.GetDataStorage().GetPointer();
//create ToolManager
m_ToolManager = mitk::ToolManager::New(m_DataStorage);
m_ToolManager->InitializeTools();
m_ToolManager->RegisterClient();//This is needed because there must be at least one registered. Otherwise tools can't be activated.
//Load patient image
mitk::Image::Pointer patientImage = mitk::IOUtil::LoadImage(GetTestDataFilePath(patientImagePath));
CPPUNIT_ASSERT(patientImage.IsNotNull());
mitk::DataNode::Pointer patientImageNode = mitk::DataNode::New();
patientImageNode->SetData(patientImage);
//Activate tool to work with
int toolID = GetToolIdByToolName(toolName);
mitk::Tool* tool = m_ToolManager->GetToolById(toolID);
CPPUNIT_ASSERT(tool != NULL);
//Create empty segmentation working image
mitk::DataNode::Pointer workingImageNode = mitk::DataNode::New();
const std::string organName = "test";
mitk::Color color;//actually it dosn't matter which color we are using
color.SetRed(1); //but CreateEmptySegmentationNode expects a color parameter
color.SetGreen(0);
color.SetBlue(0);
- workingImageNode = tool->CreateEmptySegmentationNode(patientImage, organName, color);
+ if(preSegmentationImagePath.empty())
+ {
+ workingImageNode = tool->CreateEmptySegmentationNode(patientImage, organName, color);
+ }
+ else
+ {
+ mitk::Image::Pointer preSegmentation = mitk::IOUtil::LoadImage(GetTestDataFilePath(preSegmentationImagePath));
+ workingImageNode = tool->CreateSegmentationNode(preSegmentation, organName, color);
+ }
CPPUNIT_ASSERT(workingImageNode.IsNotNull());
CPPUNIT_ASSERT(workingImageNode->GetData() != NULL);
//add images to datastorage
interactionTestHelper.AddNodeToStorage(patientImageNode);
interactionTestHelper.AddNodeToStorage(workingImageNode);
//set reference and working image
m_ToolManager->SetWorkingData(workingImageNode);
m_ToolManager->SetReferenceData(patientImageNode);
//set time step
interactionTestHelper.SetTimeStep(timestep);
//load interaction events
m_ToolManager->ActivateTool(toolID);
CPPUNIT_ASSERT(m_ToolManager->GetActiveTool() != NULL);
//Start Interaction
interactionTestHelper.PlaybackInteraction();
//load reference segmentation image
mitk::Image::Pointer segmentationReferenceImage = mitk::IOUtil::LoadImage(GetTestDataFilePath(referenceSegmentationImage));
mitk::Image::Pointer currentSegmentationImage = mitk::Image::New();
currentSegmentationImage = dynamic_cast<mitk::Image*>(workingImageNode->GetData());
//compare reference with interaction result
MITK_ASSERT_EQUAL(segmentationReferenceImage, currentSegmentationImage, "Reference equals interaction result." );
}
void setUp()
{
}
void tearDown()
{
m_ToolManager->ActivateTool(-1);
m_ToolManager = NULL;
}
-/*############ example ###################
void AddToolInteractionTest()
{
- RunTestWithParameters("Pic3D.nrrd", "Segmentation/ReferenceSegmentations/AddTool.nrrd", "AddContourTool", "Segmentation/InteractionPatterns/AddTool.xml");
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_AddTool.nrrd", "AddContourTool", "InteractionTestData/Interactions/SegmentationInteractor_AddTool.xml");
+ }
+
+ void SubtractToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_SubtractTool.nrrd", "SubtractContourTool", "InteractionTestData/Interactions/SegmentationInteractor_SubtractTool.xml");
+ }
+
+ void PaintToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_PaintTool.nrrd", "DrawPaintbrushTool", "InteractionTestData/Interactions/SegmentationInteractor_PaintTool.xml");
}
+ void WipeToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_WipeTool.nrrd", "ErasePaintbrushTool", "InteractionTestData/Interactions/SegmentationInteractor_WipeTool.xml");
+ }
+ void RegionGrowingToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_RegionGrowingTool.nrrd", "RegionGrowingTool", "InteractionTestData/Interactions/SegmentationInteractor_RegionGrowingTool.xml");
+ }
+
+ void CorrectionToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_CorrectionTool.nrrd", "CorrectorTool2D", "InteractionTestData/Interactions/SegmentationInteractor_CorrectionTool.xml");
+ }
+
+ void EraseToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_EraseTool.nrrd", "EraseRegionTool", "InteractionTestData/Interactions/SegmentationInteractor_EraseTool.xml", 0, "InteractionTestData/ReferenceData/SegmentationInteractor_AddTool.nrrd");
+ }
+
+ void FillToolInteractionTest()
+ {
+ RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_FillTool.nrrd", "FillRegionTool", "InteractionTestData/Interactions/SegmentationInteractor_FillTool.xml", 0, "InteractionTestData/InputData/SegmentationInteractor_FillTool_input.nrrd");
+ }
+
+/*############ example ###################
void AddToolInteraction_4D_Test()
{
RunTestWithParameters("US4DCyl.nrrd", "Segmentation/ReferenceSegmentations/AddTool_4D.nrrd", "AddContourTool", "Segmentation/InteractionPatterns/AddTool_4D.xml", 1);
}
#########################################*/
};
MITK_TEST_SUITE_REGISTRATION(mitkToolInteraction)
diff --git a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp
index e4d6db1064..3ad4067cf2 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp
@@ -1,165 +1,173 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkOtsuTool3DGUI.h"
#include "QmitkConfirmSegmentationDialog.h"
#include <qlabel.h>
#include <qspinbox.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qlistwidget.h>
#include <QMessageBox>
MITK_TOOL_GUI_MACRO(MitkSegmentationUI_EXPORT, QmitkOtsuTool3DGUI, "")
QmitkOtsuTool3DGUI::QmitkOtsuTool3DGUI()
:QmitkToolGUI(),
m_NumberOfRegions(0)
{
m_Controls.setupUi(this);
connect( m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnSpinboxValueAccept()));
connect(m_Controls.m_selectionListWidget, SIGNAL(itemSelectionChanged()),
- this, SLOT(OnItemSelectionChanged()));
+ this, SLOT(OnRegionSelectionChanged()));
+ connect( m_Controls.m_Spinbox, SIGNAL(valueChanged(int)), this, SLOT(OnRegionSpinboxChanged(int)) );
connect( m_Controls.m_ConfSegButton, SIGNAL(clicked()), this, SLOT(OnSegmentationRegionAccept()));
connect( this, SIGNAL(NewToolAssociated(mitk::Tool*)), this, SLOT(OnNewToolAssociated(mitk::Tool*)) );
connect(m_Controls.advancedSettingsButton, SIGNAL(toggled(bool)), this, SLOT(OnAdvancedSettingsButtonToggled(bool)));
this->OnAdvancedSettingsButtonToggled(false);
}
QmitkOtsuTool3DGUI::~QmitkOtsuTool3DGUI()
{
}
-void QmitkOtsuTool3DGUI::OnItemSelectionChanged()
+void QmitkOtsuTool3DGUI::OnRegionSpinboxChanged(int numberOfRegions)
+{
+ //we have to change to minimum number of histogram bins accordingly
+ int curBinValue = m_Controls.m_BinsSpinBox->value();
+ if (curBinValue<numberOfRegions) m_Controls.m_BinsSpinBox->setValue(numberOfRegions);
+}
+
+void QmitkOtsuTool3DGUI::OnRegionSelectionChanged()
{
m_SelectedItems = m_Controls.m_selectionListWidget->selectedItems();
if (m_SelectedItems.size() == 0)
{
m_Controls.m_ConfSegButton->setEnabled( false );
m_OtsuTool3DTool->ShowMultiLabelResultNode(true);
return;
}
if (m_OtsuTool3DTool.IsNotNull())
{
// update preview of region
QList<QListWidgetItem *>::Iterator it;
std::vector<int> regionIDs;
for (it = m_SelectedItems.begin(); it != m_SelectedItems.end(); ++it)
regionIDs.push_back((*it)->text().toInt());
m_OtsuTool3DTool->UpdateBinaryPreview(regionIDs);
m_Controls.m_ConfSegButton->setEnabled( true );
}
}
void QmitkOtsuTool3DGUI::OnAdvancedSettingsButtonToggled(bool toggled)
{
m_Controls.m_ValleyCheckbox->setVisible(toggled);
m_Controls.binLabel->setVisible(toggled);
m_Controls.m_BinsSpinBox->setVisible(toggled);
}
void QmitkOtsuTool3DGUI::OnNewToolAssociated(mitk::Tool* tool)
{
m_OtsuTool3DTool = dynamic_cast<mitk::OtsuTool3D*>( tool );
}
void QmitkOtsuTool3DGUI::OnSegmentationRegionAccept()
{
QmitkConfirmSegmentationDialog dialog;
QString segName = QString::fromStdString(m_OtsuTool3DTool->GetCurrentSegmentationName());
dialog.SetSegmentationName(segName);
int result = dialog.exec();
switch(result)
{
case QmitkConfirmSegmentationDialog::CREATE_NEW_SEGMENTATION:
m_OtsuTool3DTool->SetOverwriteExistingSegmentation(false);
break;
case QmitkConfirmSegmentationDialog::OVERWRITE_SEGMENTATION:
m_OtsuTool3DTool->SetOverwriteExistingSegmentation(true);
break;
case QmitkConfirmSegmentationDialog::CANCEL_SEGMENTATION:
return;
}
if (m_OtsuTool3DTool.IsNotNull() && m_Controls.m_selectionListWidget->currentItem() != NULL)
{
m_OtsuTool3DTool->ConfirmSegmentation();
}
}
void QmitkOtsuTool3DGUI::OnSpinboxValueAccept()
{
if( m_NumberOfRegions == m_Controls.m_Spinbox->value() &&
m_UseValleyEmphasis == m_Controls.m_ValleyCheckbox->isChecked() &&
m_NumberOfBins == m_Controls.m_BinsSpinBox->value() )
return;
if (m_OtsuTool3DTool.IsNotNull())
{
try
{
m_NumberOfRegions = m_Controls.m_Spinbox->value();
m_UseValleyEmphasis = m_Controls.m_ValleyCheckbox->isChecked();
m_NumberOfBins = m_Controls.m_BinsSpinBox->value();
int proceed;
QMessageBox* messageBox = new QMessageBox(QMessageBox::Question, NULL, "The otsu segmentation computation may take several minutes depending on the number of Regions you selected. Proceed anyway?", QMessageBox::Ok | QMessageBox::Cancel);
if (m_NumberOfRegions >= 5)
{
proceed = messageBox->exec();
if (proceed != QMessageBox::Ok) return;
}
this->setCursor(Qt::WaitCursor);
m_OtsuTool3DTool->RunSegmentation( m_NumberOfRegions, m_UseValleyEmphasis, m_NumberOfBins );
this->setCursor(Qt::ArrowCursor);
}
catch( ... )
{
this->setCursor(Qt::ArrowCursor);
QMessageBox* messageBox = new QMessageBox(QMessageBox::Critical, NULL, "itkOtsuFilter error: image dimension must be in {2, 3} and no RGB images can be handled.");
messageBox->exec();
delete messageBox;
return;
}
//insert regions into widget
QString itemName;
QListWidgetItem* item;
m_Controls.m_selectionListWidget->clear();
for(int i=0; i<m_Controls.m_Spinbox->value(); ++i)
{
itemName = QString::number(i);
item = new QListWidgetItem(itemName);
m_Controls.m_selectionListWidget->addItem(item);
}
//deactivate 'confirm segmentation'-button
m_Controls.m_ConfSegButton->setEnabled(false);
}
}
void QmitkOtsuTool3DGUI::OnVolumePreviewChecked(int state)
{
if (state == 1)
{
}
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h
index c855b7dd7f..c6126cd698 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h
@@ -1,86 +1,88 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QmitkOtsuTool3DGUI_h_Included
#define QmitkOtsuTool3DGUI_h_Included
#include "QmitkToolGUI.h"
#include <MitkSegmentationUIExports.h>
#include "mitkOtsuTool3D.h"
#include <QListWidget>
#include <QPushButton>
#include "ui_QmitkOtsuToolWidgetControls.h"
class QSpinBox;
class QLabel;
/**
\ingroup org_mitk_gui_qt_interactivesegmentation_internal
\brief GUI for mitk::.
\sa mitk::
This GUI shows ...
Last contributor: $Author$
*/
class MitkSegmentationUI_EXPORT QmitkOtsuTool3DGUI : public QmitkToolGUI
{
Q_OBJECT
public:
mitkClassMacro(QmitkOtsuTool3DGUI, QmitkToolGUI);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
signals:
public slots:
protected slots:
void OnNewToolAssociated(mitk::Tool*);
void OnSpinboxValueAccept();
void OnSegmentationRegionAccept();
- void OnItemSelectionChanged();
+ void OnRegionSelectionChanged();
+
+ void OnRegionSpinboxChanged(int);
void OnVolumePreviewChecked(int);
private slots:
void OnAdvancedSettingsButtonToggled(bool toggled);
protected:
QmitkOtsuTool3DGUI();
virtual ~QmitkOtsuTool3DGUI();
mitk::OtsuTool3D::Pointer m_OtsuTool3DTool;
Ui_QmitkOtsuToolWidgetControls m_Controls;
int m_NumberOfRegions;
bool m_UseValleyEmphasis;
int m_NumberOfBins;
QList<QListWidgetItem *> m_SelectedItems;
};
#endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.cpp b/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.cpp
index 8b6767c953..fef5292321 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.cpp
@@ -1,236 +1,236 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkToolReferenceDataSelectionBox.h"
#include "QmitkDataStorageComboBox.h"
//#include "QmitkPropertyListPopup.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateNot.h"
#include "mitkRenderingManager.h"
#include "mitkToolManagerProvider.h"
-QmitkToolReferenceDataSelectionBox::QmitkToolReferenceDataSelectionBox(QWidget* parent, mitk::DataStorage* storage)
+QmitkToolReferenceDataSelectionBox::QmitkToolReferenceDataSelectionBox(QWidget* parent)
:QWidget(parent),
m_SelfCall(false),
m_DisplayMode(ListDataIfAnyToolMatches ),
m_ToolGroupsForFiltering("default")
{
m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
m_Layout = new QVBoxLayout( this );
this->setLayout( m_Layout );
m_ReferenceDataSelectionBox = new QmitkDataStorageComboBox( this );
m_Layout->addWidget(m_ReferenceDataSelectionBox);
connect( m_ReferenceDataSelectionBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),
this, SLOT(OnReferenceDataSelected(const mitk::DataNode*)) );
m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkToolReferenceDataSelectionBox>( this, &QmitkToolReferenceDataSelectionBox::OnToolManagerReferenceDataModified );
}
QmitkToolReferenceDataSelectionBox::~QmitkToolReferenceDataSelectionBox()
{
m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkToolReferenceDataSelectionBox>( this, &QmitkToolReferenceDataSelectionBox::OnToolManagerReferenceDataModified );
}
mitk::DataStorage* QmitkToolReferenceDataSelectionBox::GetDataStorage()
{
return m_ToolManager->GetDataStorage();
}
void QmitkToolReferenceDataSelectionBox::SetDataStorage(mitk::DataStorage& storage)
{
m_ToolManager->SetDataStorage(storage);
}
void QmitkToolReferenceDataSelectionBox::Initialize(mitk::DataStorage* storage )
{
m_ReferenceDataSelectionBox->SetDataStorage( storage );
UpdateDataDisplay();
}
mitk::ToolManager* QmitkToolReferenceDataSelectionBox::GetToolManager()
{
return m_ToolManager;
}
void QmitkToolReferenceDataSelectionBox::SetToolManager(mitk::ToolManager& newManager) // no NULL pointer allowed here, a manager is required
{
m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkToolReferenceDataSelectionBox>( this, &QmitkToolReferenceDataSelectionBox::OnToolManagerReferenceDataModified );
m_ToolManager = &newManager;
m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkToolReferenceDataSelectionBox>( this, &QmitkToolReferenceDataSelectionBox::OnToolManagerReferenceDataModified );
UpdateDataDisplay();
}
void QmitkToolReferenceDataSelectionBox::UpdateDataDisplay()
{
m_ReferenceDataSelectionBox->SetPredicate( GetAllPossibleReferenceImagesPredicate().GetPointer() );
EnsureOnlyReferenceImageIsVisibile();
}
void QmitkToolReferenceDataSelectionBox::OnReferenceDataSelected(const mitk::DataNode* selectedNode)
{
emit ReferenceNodeSelected(selectedNode);
m_SelfCall = true;
m_ToolManager->SetReferenceData( const_cast< mitk::DataNode*>(selectedNode)); // maybe NULL
m_SelfCall = false;
EnsureOnlyReferenceImageIsVisibile();
}
void QmitkToolReferenceDataSelectionBox::EnsureOnlyReferenceImageIsVisibile()
{
mitk::DataNode* selectedNode = m_ToolManager->GetReferenceData(0);
mitk::DataStorage::SetOfObjects::ConstPointer allImageNodes = GetAllPossibleReferenceImages();
for ( mitk::DataStorage::SetOfObjects::const_iterator nodeIter = allImageNodes->begin();
nodeIter != allImageNodes->end();
++nodeIter )
{
mitk::DataNode* currentNode = (*nodeIter).GetPointer();
currentNode->SetVisibility( currentNode == selectedNode ); // only the selected one is visible, everything else is invisible
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkToolReferenceDataSelectionBox::OnToolManagerReferenceDataModified()
{
if (m_SelfCall) return;
const mitk::DataNode* node = m_ToolManager->GetReferenceData(0);
emit ReferenceNodeSelected(node);
UpdateDataDisplay();
}
mitk::NodePredicateBase::ConstPointer QmitkToolReferenceDataSelectionBox::GetAllPossibleReferenceImagesPredicate()
{
/**
* Build up predicate:
* - ask each tool that is displayed for a predicate (indicating the type of data that this tool will work with)
* - connect all predicates using AND or OR, depending on the parameter m_DisplayMode (ListDataIfAllToolsMatch or ListDataIfAnyToolMatches)
* \sa SetDisplayMode
*/
std::vector< mitk::NodePredicateBase::ConstPointer > m_Predicates;
m_Predicates.clear();
mitk::NodePredicateBase::ConstPointer completePredicate = NULL;
const mitk::ToolManager::ToolVectorTypeConst allTools = m_ToolManager->GetTools();
for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allTools.begin();
iter != allTools.end();
++iter )
{
const mitk::Tool* tool = *iter;
if ( (m_ToolGroupsForFiltering.empty()) || ( m_ToolGroupsForFiltering.find( tool->GetGroup() ) != std::string::npos ) ||
( m_ToolGroupsForFiltering.find( tool->GetName() ) != std::string::npos )
)
{
if (completePredicate)
{
if ( m_DisplayMode == ListDataIfAnyToolMatches )
{
m_Predicates.push_back( mitk::NodePredicateOr::New( completePredicate, tool->GetReferenceDataPreference() ).GetPointer() );
}
else
{
m_Predicates.push_back( mitk::NodePredicateAnd::New( completePredicate, tool->GetReferenceDataPreference() ).GetPointer() );
}
completePredicate = m_Predicates.back();
}
else
{
completePredicate = tool->GetReferenceDataPreference();
}
}
}
return completePredicate;
}
mitk::DataStorage::SetOfObjects::ConstPointer QmitkToolReferenceDataSelectionBox::GetAllPossibleReferenceImages()
{
mitk::DataStorage* dataStorage = m_ToolManager->GetDataStorage();
if (!dataStorage)
{
return mitk::DataStorage::SetOfObjects::New().GetPointer();
}
mitk::NodePredicateBase::ConstPointer completePredicate = GetAllPossibleReferenceImagesPredicate();
mitk::DataStorage::SetOfObjects::ConstPointer allObjects;
/**
* display everything matching the predicate
*/
if (completePredicate.IsNotNull())
{
allObjects = dataStorage->GetSubset( completePredicate );
}
else
{
allObjects = dataStorage->GetAll();
}
mitk::ToolManager::DataVectorType resultVector;
for ( mitk::DataStorage::SetOfObjects::const_iterator objectIter = allObjects->begin();
objectIter != allObjects->end();
++objectIter )
{
mitk::DataNode* node = (*objectIter).GetPointer();
resultVector.push_back( node );
}
mitk::DataStorage::SetOfObjects::ConstPointer sceneImages = dataStorage->GetSubset( completePredicate );
return sceneImages;
}
void QmitkToolReferenceDataSelectionBox::SetToolGroupsForFiltering(const std::string& groups)
{
m_ToolGroupsForFiltering = groups;
UpdateDataDisplay();
}
void QmitkToolReferenceDataSelectionBox::SetDisplayMode( QmitkToolReferenceDataSelectionBox::DisplayMode mode )
{
if (m_DisplayMode != mode)
{
m_DisplayMode = mode;
UpdateDataDisplay();
}
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.h b/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.h
index b0abd11981..083700775e 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkToolReferenceDataSelectionBox.h
@@ -1,128 +1,128 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QmitkToolReferenceDataSelectionBox_h_Included
#define QmitkToolReferenceDataSelectionBox_h_Included
#include "mitkToolManager.h"
#include <MitkSegmentationUIExports.h>
#include "mitkDataStorage.h"
#include <QWidget>
#include <QVBoxLayout>
class QmitkDataStorageComboBox;
/**
\brief Display the data selection of a ToolManager.
\sa mitk::ToolManager
\sa mitk::DataStorage
\ingroup ToolManagerEtAl
\ingroup Widgets
There is a separate page describing the general design of QmitkInteractiveSegmentation: \ref QmitkInteractiveSegmentationTechnicalPage
Shows the reference data of a ToolManager in a segmentation setting.
The reference image can be selected from a combobox, where all images of the scene are listed.
$Author: maleike $
*/
class MitkSegmentationUI_EXPORT QmitkToolReferenceDataSelectionBox : public QWidget
{
Q_OBJECT
public:
/**
* \brief What kind of items should be displayed.
*
* Every mitk::Tool holds a NodePredicateBase object, telling the kind of data that this
* tool will successfully work with. There are two ways that this list box deals with
* these predicates.
*
* DEFAULT is: list data if ANY one of the displayed tools' predicate matches.
* Other option: list data if ALL one of the displayed tools' predicate matches
*/
enum DisplayMode { ListDataIfAllToolsMatch, ListDataIfAnyToolMatches};
- QmitkToolReferenceDataSelectionBox(QWidget* parent = 0, mitk::DataStorage* storage = 0);
+ QmitkToolReferenceDataSelectionBox(QWidget* parent = 0);
virtual ~QmitkToolReferenceDataSelectionBox();
mitk::DataStorage* GetDataStorage();
void SetDataStorage(mitk::DataStorage& storage);
/// initialization with a data storage object
void Initialize(mitk::DataStorage*);
void UpdateDataDisplay();
mitk::ToolManager* GetToolManager();
void SetToolManager(mitk::ToolManager&); // no NULL pointer allowed here, a manager is required
void OnToolManagerReferenceDataModified();
/**
* \brief No brief description.
*
* Should be called to restrict the number of tools that are
* evaluated to build up the list. Default is to ask all tools for their predicate, by
* setting the 'groups' string this can be restricted to certain groups of tools
* or single tools.
*/
void SetToolGroupsForFiltering(const std::string& groups);
/**
* \brief How the list contents is determined.
*
* See also documentation of DisplayMode.
*
* \sa DisplayMode
*/
void SetDisplayMode( DisplayMode mode );
signals:
void ReferenceNodeSelected(const mitk::DataNode*);
protected slots:
void OnReferenceDataSelected(const mitk::DataNode* node);
void EnsureOnlyReferenceImageIsVisibile();
protected:
mitk::DataStorage::SetOfObjects::ConstPointer GetAllPossibleReferenceImages();
mitk::NodePredicateBase::ConstPointer GetAllPossibleReferenceImagesPredicate();
mitk::ToolManager::Pointer m_ToolManager;
QmitkDataStorageComboBox* m_ReferenceDataSelectionBox;
bool m_SelfCall;
DisplayMode m_DisplayMode;
std::string m_ToolGroupsForFiltering;
QVBoxLayout* m_Layout;
};
#endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.cpp b/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.cpp
index 141456760f..fb91ee9a14 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.cpp
@@ -1,298 +1,298 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkToolWorkingDataSelectionBox.h"
#include "mitkToolManagerProvider.h"
-QmitkToolWorkingDataSelectionBox::QmitkToolWorkingDataSelectionBox(QWidget* parent, mitk::DataStorage* storage)
+QmitkToolWorkingDataSelectionBox::QmitkToolWorkingDataSelectionBox(QWidget* parent)
:QListWidget(parent),
m_SelfCall(false),
m_LastSelectedReferenceData(NULL),
m_ToolGroupsForFiltering("default"),
m_DisplayOnlyDerivedNodes(true)
{
m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); // this widget should be placeable from designer so it can't take other than the defaul parameters
QListWidget::setSelectionMode( QListWidget::MultiSelection );
QListWidget::setDragDropMode(QListWidget::InternalMove);
connect( this, SIGNAL(itemSelectionChanged()), this, SLOT(OnWorkingDataSelectionChanged()) );
m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkToolWorkingDataSelectionBox>( this, &QmitkToolWorkingDataSelectionBox::OnToolManagerReferenceDataModified );
m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkToolWorkingDataSelectionBox>( this, &QmitkToolWorkingDataSelectionBox::OnToolManagerWorkingDataModified );
}
QmitkToolWorkingDataSelectionBox::~QmitkToolWorkingDataSelectionBox()
{
}
mitk::DataStorage* QmitkToolWorkingDataSelectionBox::GetDataStorage()
{
return m_ToolManager->GetDataStorage();
}
void QmitkToolWorkingDataSelectionBox::SetDataStorage(mitk::DataStorage& storage)
{
m_ToolManager->SetDataStorage(storage);
}
mitk::ToolManager* QmitkToolWorkingDataSelectionBox::GetToolManager()
{
return m_ToolManager;
}
void QmitkToolWorkingDataSelectionBox::SetToolManager(mitk::ToolManager& newManager) // no NULL pointer allowed here, a manager is required
{
m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkToolWorkingDataSelectionBox>( this, &QmitkToolWorkingDataSelectionBox::OnToolManagerReferenceDataModified );
m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<QmitkToolWorkingDataSelectionBox>( this, &QmitkToolWorkingDataSelectionBox::OnToolManagerWorkingDataModified );
m_ToolManager = &newManager;
m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkToolWorkingDataSelectionBox>( this, &QmitkToolWorkingDataSelectionBox::OnToolManagerReferenceDataModified );
m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkToolWorkingDataSelectionBox>( this, &QmitkToolWorkingDataSelectionBox::OnToolManagerWorkingDataModified );
UpdateDataDisplay();
}
void QmitkToolWorkingDataSelectionBox::OnWorkingDataSelectionChanged()
{
static mitk::ToolManager::DataVectorType previouslySelectedNodes;
mitk::ToolManager::DataVectorType selection = this->GetSelectedNodes();
previouslySelectedNodes = selection;
if (selection.size() >0)
{
const mitk::DataNode* node = selection[0];
emit WorkingNodeSelected(node);
}
else
{
emit WorkingNodeSelected(NULL);
}
m_SelfCall = true;
m_ToolManager->SetWorkingData( selection ); // maybe empty
m_SelfCall = false;
}
void QmitkToolWorkingDataSelectionBox::OnToolManagerWorkingDataModified()
{
if (m_SelfCall) return;
const mitk::DataNode* node = m_ToolManager->GetWorkingData(0);
emit WorkingNodeSelected(node);
UpdateDataDisplay();
}
void QmitkToolWorkingDataSelectionBox::OnToolManagerReferenceDataModified()
{
if ( m_ToolManager->GetReferenceData(0) != m_LastSelectedReferenceData )
{
m_ToolManager->SetWorkingData(NULL);
UpdateDataDisplay();
m_LastSelectedReferenceData = m_ToolManager->GetReferenceData(0);
}
}
void QmitkToolWorkingDataSelectionBox::UpdateDataDisplay()
{
// clear all
QListWidget::clear();
m_Node.clear();
// rebuild contents
mitk::ToolManager::DataVectorType allObjects = GetAllNodes( false );
for ( mitk::ToolManager::DataVectorType::const_iterator objectIter = allObjects.begin();
objectIter != allObjects.end();
++objectIter)
{
mitk::DataNode* node = *objectIter;
if (node) // delete this check when datastorage is really used
{
// get name and color
std::string name = node->GetName();
float rgb[3]; rgb[0] = 1.0; rgb[1] = 0.0; rgb[2] = 0.0;
node->GetColor(rgb);
QRgb qrgb = qRgb( (int)(rgb[0]*255.0), (int)(rgb[1]*255.0), (int)(rgb[2]*255.0) );
QPixmap pixmap(25,18);
pixmap.fill(QColor(qrgb));
// create a list item
QListWidgetItem* newItem = new QListWidgetItem();
QString qname = QString::fromLocal8Bit(name.c_str());
//set name and color
newItem->setText(qname);
newItem->setIcon(QIcon(pixmap));
this->addItem(newItem);
m_Node.insert( std::make_pair( newItem, node ) );
}
}
}
mitk::ToolManager::DataVectorType QmitkToolWorkingDataSelectionBox::GetSelectedNodes()
{
mitk::ToolManager::DataVectorType result;
QList<QListWidgetItem *> items;
for (int j=0; j<this->count(); j++)
{
if (this->item(j)->isSelected())
items.append(this->item(j));
}
for (int i=0; i<items.size();++i)
{
QListWidgetItem* item = items.at(i);
if (item)
{
ItemNodeMapType::iterator it = m_Node.find(item);
if (it != m_Node.end())
{
mitk::DataNode::Pointer node = it->second;
if (node)
result.push_back(node);
}
}
}
return result;
}
mitk::DataNode* QmitkToolWorkingDataSelectionBox::GetSelectedNode()
{
QListWidgetItem* item = QListWidget::selectedItems().first();
if (item)
{
ItemNodeMapType::iterator iter = m_Node.find(item);
if ( iter != m_Node.end() )
{
return iter->second;
}
}
return NULL;
}
mitk::ToolManager::DataVectorType QmitkToolWorkingDataSelectionBox::GetAllNodes( bool onlyDerivedFromOriginal )
{
mitk::DataStorage* dataStorage = m_ToolManager->GetDataStorage();
if (!dataStorage)
{
return mitk::ToolManager::DataVectorType();
}
/**
* Build up predicate:
* - ask each tool that is displayed for a predicate (indicating the type of data that this tool will work with)
* - connect all predicates using AND or OR, depending on the parameter m_DisplayMode (ListDataIfAllToolsMatch or ListDataIfAnyToolMatches)
* \sa SetDisplayMode
*/
std::vector< mitk::NodePredicateBase::ConstPointer > m_Predicates;
mitk::NodePredicateBase::ConstPointer completePredicate = NULL;
bool rebuildNeeded = true;
if (rebuildNeeded)
{
m_Predicates.clear();
const mitk::ToolManager::ToolVectorTypeConst allTools = m_ToolManager->GetTools();
for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allTools.begin();
iter != allTools.end();
++iter )
{
const mitk::Tool* tool = *iter;
if ( (m_ToolGroupsForFiltering.empty()) || ( m_ToolGroupsForFiltering.find( tool->GetGroup() ) != std::string::npos ) ||
( m_ToolGroupsForFiltering.find( tool->GetName() ) != std::string::npos )
)
{
if (completePredicate.IsNotNull())
{
m_Predicates.push_back( mitk::NodePredicateOr::New( completePredicate, tool->GetWorkingDataPreference()).GetPointer() );
completePredicate = m_Predicates.back();
}
else
{
completePredicate = tool->GetWorkingDataPreference();
}
}
}
}
// TODO delete all m_Predicates
mitk::DataStorage::SetOfObjects::ConstPointer allObjects;
/**
* Two modes here:
* - display only nodes below reference data from ToolManager (onlyDerivedFromOriginal == true)
* - display everything matching the predicate (else)
*/
if ( onlyDerivedFromOriginal )
{
mitk::DataNode* sourceNode( m_ToolManager->GetReferenceData(0) );
if (sourceNode)
{
allObjects = dataStorage->GetDerivations( sourceNode, completePredicate, false );
}
else
{
allObjects = mitk::DataStorage::SetOfObjects::New();
}
}
else
{
if (completePredicate)
{
allObjects = dataStorage->GetSubset( completePredicate );
}
else
{
allObjects = dataStorage->GetAll();
}
}
m_Predicates.clear();
completePredicate = NULL;
mitk::ToolManager::DataVectorType resultVector;
for ( mitk::DataStorage::SetOfObjects::const_iterator objectIter = allObjects->begin();
objectIter != allObjects->end();
++objectIter )
{
mitk::DataNode* node = (*objectIter).GetPointer();
resultVector.push_back( node );
}
return resultVector;
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.h b/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.h
index d2ca79ef0c..51b419fd18 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkToolWorkingDataSelectionBox.h
@@ -1,142 +1,142 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QmitkToolWorkingDataSelectionListBox_h_Included
#define QmitkToolWorkingDataSelectionListBox_h_Included
// mmueller
#include <QListWidget>
#include <MitkSegmentationUIExports.h>
#include "mitkToolManager.h"
#include "mitkProperties.h"
/**
\brief Display the data selection of a ToolManager.
\sa mitk::ToolManager
\sa mitk::DataStorage
\ingroup Widgets
There is a separate page describing the general design of QmitkInteractiveSegmentation: \ref QmitkInteractiveSegmentationTechnicalPage
Shows the working data of a ToolManager in a segmentation setting. By default only the segmentation name is shown.
The working images (segmentations) are listed in a QListView, each row telling the color and name
of a single segmentation. One or several segmentations can be selected to be the "active" segmentations.
$Author: maleike $
*/
class MitkSegmentationUI_EXPORT QmitkToolWorkingDataSelectionBox : public QListWidget
{
Q_OBJECT
public:
/**
* \brief What kind of items should be displayed.
*
* Every mitk::Tool holds a NodePredicateBase object, telling the kind of data that this
* tool will successfully work with. There are two ways that this list box deals with
* these predicates.
*
* DEFAULT is: list data if ANY one of the displayed tools' predicate matches.
* Other option: list data if ALL one of the displayed tools' predicate matches
*/
enum DisplayMode { ListDataIfAllToolsMatch, ListDataIfAnyToolMatches};
- QmitkToolWorkingDataSelectionBox(QWidget* parent = 0, mitk::DataStorage* storage = 0);
+ QmitkToolWorkingDataSelectionBox(QWidget* parent = 0);
virtual ~QmitkToolWorkingDataSelectionBox();
mitk::DataStorage* GetDataStorage();
void SetDataStorage(mitk::DataStorage& storage);
/**
\brief Can be called to trigger an update of the list contents.
*/
void UpdateDataDisplay();
/**
\brief Returns the associated mitk::ToolManager.
*/
mitk::ToolManager* GetToolManager();
/**
\brief Tell this object to listen to another ToolManager.
*/
void SetToolManager(mitk::ToolManager&); // no NULL pointer allowed here, a manager is required
/**
* \brief A list of all displayed DataNode objects.
* This method might be convenient for program modules that want to display
* additional information about these nodes, like a total volume of all segmentations, etc.
*/
mitk::ToolManager::DataVectorType GetAllNodes( bool onlyDerivedFromOriginal = true );
/**
* \brief A list of all selected DataNode objects.
* This method might be convenient for program modules that want to display
* additional information about these nodes, like a total volume of all segmentations, etc.
*/
mitk::ToolManager::DataVectorType GetSelectedNodes();
/**
* \brief Like GetSelectedNodes(), but will only return one object.
* Will only return what QListView gives as selected object (documentation says nothing is returned if list is in Single selection mode).
*/
mitk::DataNode* GetSelectedNode();
/**
* \brief Callback function, no need to call it.
* This is used to observe and react to changes in the mitk::ToolManager object.
*/
void OnToolManagerWorkingDataModified();
/**
* \brief Callback function, no need to call it.
* This is used to observe and react to changes in the mitk::ToolManager object.
*/
void OnToolManagerReferenceDataModified();
signals:
void WorkingNodeSelected(const mitk::DataNode*);
protected slots:
void OnWorkingDataSelectionChanged();
protected:
typedef std::map< QListWidgetItem*, mitk::DataNode* > ItemNodeMapType;
mitk::ToolManager::Pointer m_ToolManager;
ItemNodeMapType m_Node;
bool m_SelfCall;
mitk::DataNode* m_LastSelectedReferenceData;
std::string m_ToolGroupsForFiltering;
bool m_DisplayOnlyDerivedNodes;
};
#endif
diff --git a/Modules/Simulation/CMakeLists.txt b/Modules/Simulation/CMakeLists.txt
index 55e9c80660..78ebb99392 100644
--- a/Modules/Simulation/CMakeLists.txt
+++ b/Modules/Simulation/CMakeLists.txt
@@ -1,11 +1,11 @@
if(MITK_USE_SOFA)
MITK_CREATE_MODULE(
- DEPENDS MitkCore
+ DEPENDS MitkSceneSerializationBase
PACKAGE_DEPENDS Boost GLUT GLEW SOFA
)
if(MSVC)
list(APPEND module_compile_flags /wd4250 4251 4267 4275)
set_target_properties(${MODULE_TARGET} PROPERTIES COMPILE_FLAGS "${module_compile_flags}")
endif()
endif()
diff --git a/Modules/Simulation/Resources/Interactions/Simulation.xml b/Modules/Simulation/Resources/Interactions/Simulation.xml
new file mode 100644
index 0000000000..c0bad251b8
--- /dev/null
+++ b/Modules/Simulation/Resources/Interactions/Simulation.xml
@@ -0,0 +1,45 @@
+<statemachine>
+ <state name="start" startstate="true">
+ <!-- MousePress -->
+ <transition event_class="MousePressEvent" event_variant="ShiftKeyLeftButtonPressed" target="start">
+ <action name="startPrimaryInteraction" />
+ </transition>
+ <transition event_class="MousePressEvent" event_variant="ShiftKeyRightButtonPressed" target="start">
+ <action name="startSecondaryInteraction" />
+ </transition>
+ <!-- MouseMove -->
+ <transition event_class="MouseMoveEvent" event_variant="ShiftKeyLeftButtonMoved" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="executeInteraction" />
+ </transition>
+ <transition event_class="MouseMoveEvent" event_variant="LeftButtonMoved" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="executeInteraction" />
+ </transition>
+ <transition event_class="MouseMoveEvent" event_variant="ShiftKeyRightButtonMoved" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="executeInteraction" />
+ </transition>
+ <transition event_class="MouseMoveEvent" event_variant="RightButtonMoved" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="executeInteraction" />
+ </transition>
+ <!-- MouseRelease -->
+ <transition event_class="MouseReleaseEvent" event_variant="ShiftKeyLeftButtonReleased" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="stopInteraction" />
+ </transition>
+ <transition event_class="MouseReleaseEvent" event_variant="LeftButtonReleased" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="stopInteraction" />
+ </transition>
+ <transition event_class="MouseReleaseEvent" event_variant="ShiftKeyRightButtonReleased" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="stopInteraction" />
+ </transition>
+ <transition event_class="MouseReleaseEvent" event_variant="RightButtonReleased" target="start">
+ <condition name="isInteractionPerformerNotNull" />
+ <action name="stopInteraction" />
+ </transition>
+ </state>
+</statemachine>
\ No newline at end of file
diff --git a/Modules/Simulation/Resources/Interactions/SimulationConfig.xml b/Modules/Simulation/Resources/Interactions/SimulationConfig.xml
new file mode 100644
index 0000000000..224f082a55
--- /dev/null
+++ b/Modules/Simulation/Resources/Interactions/SimulationConfig.xml
@@ -0,0 +1,40 @@
+<config>
+ <!-- Shift + LMB -->
+ <event_variant class="MousePressEvent" name="ShiftKeyLeftButtonPressed">
+ <attribute name="EventButton" value="LeftMouseButton" />
+ <attribute name="Modifiers" value="shift" />
+ </event_variant>
+ <event_variant class="MouseMoveEvent" name="ShiftKeyLeftButtonMoved">
+ <attribute name="ButtonState" value="LeftMouseButton" />
+ <attribute name="Modifiers" value="shift" />
+ </event_variant>
+ <event_variant class="MouseMoveEvent" name="LeftButtonMoved">
+ <attribute name="ButtonState" value="LeftMouseButton" />
+ </event_variant>
+ <event_variant class="MouseReleaseEvent" name="ShiftKeyLeftButtonReleased">
+ <attribute name="EventButton" value="LeftMouseButton" />
+ <attribute name="Modifiers" value="shift" />
+ </event_variant>
+ <event_variant class="MouseReleaseEvent" name="LeftButtonReleased">
+ <attribute name="EventButton" value="LeftMouseButton" />
+ </event_variant>
+ <!-- Shift + RMB -->
+ <event_variant class="MousePressEvent" name="ShiftKeyRightButtonPressed">
+ <attribute name="EventButton" value="RightMouseButton" />
+ <attribute name="Modifiers" value="shift" />
+ </event_variant>
+ <event_variant class="MouseMoveEvent" name="ShiftKeyRightButtonMoved">
+ <attribute name="ButtonState" value="RightMouseButton" />
+ <attribute name="Modifiers" value="shift" />
+ </event_variant>
+ <event_variant class="MouseMoveEvent" name="RightButtonMoved">
+ <attribute name="ButtonState" value="RightMouseButton" />
+ </event_variant>
+ <event_variant class="MouseReleaseEvent" name="ShiftKeyRightButtonReleased">
+ <attribute name="EventButton" value="RightMouseButton" />
+ <attribute name="Modifiers" value="shift" />
+ </event_variant>
+ <event_variant class="MouseReleaseEvent" name="RightButtonReleased">
+ <attribute name="EventButton" value="RightMouseButton" />
+ </event_variant>
+</config>
\ No newline at end of file
diff --git a/Modules/Simulation/files.cmake b/Modules/Simulation/files.cmake
index d106dec8b4..7f49b08378 100644
--- a/Modules/Simulation/files.cmake
+++ b/Modules/Simulation/files.cmake
@@ -1,15 +1,30 @@
set(CPP_FILES
mitkGetSimulationService.cpp
+ mitkExportMitkVisitor.cpp
mitkIndexROI.cpp
mitkISimulationService.cpp
+ mitkRoundRobinSchedulingAlgorithm.cpp
mitkSetVtkRendererVisitor.cpp
+ mitkSchedulableProcess.cpp
+ mitkScheduler.cpp
+ mitkSchedulingAlgorithmBase.cpp
mitkSimulation.cpp
mitkSimulationActivator.cpp
+ mitkSimulationInteractor.cpp
mitkSimulationIOFactory.cpp
mitkSimulationObjectFactory.cpp
mitkSimulationReader.cpp
+ mitkSimulationSerializer.cpp
mitkSimulationService.cpp
mitkSimulationVtkMapper3D.cpp
+ mitkSimulationWriter.cpp
+ mitkSimulationWriterFactory.cpp
mitkVtkModel.cpp
mitkVtkSimulationPolyDataMapper.cpp
+ mitkWeightedRoundRobinSchedulingAlgorithm.cpp
+)
+
+set(RESOURCE_FILES
+ Interactions/Simulation.xml
+ Interactions/SimulationConfig.xml
)
diff --git a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.cpp b/Modules/Simulation/mitkExportMitkVisitor.cpp
similarity index 80%
rename from Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.cpp
rename to Modules/Simulation/mitkExportMitkVisitor.cpp
index 121e383aac..4d9ef80592 100644
--- a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.cpp
+++ b/Modules/Simulation/mitkExportMitkVisitor.cpp
@@ -1,204 +1,230 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#include "internal/mitkGetDataStorage.h"
-#include "internal/mitkGetSimulationDataNode.h"
#include "mitkExportMitkVisitor.h"
+#include <mitkNodePredicateDataType.h>
+#include <mitkSimulation.h>
#include <mitkSurface.h>
#include <sofa/component/visualmodel/VisualModelImpl.h>
#include <vtkCellArray.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
static void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material& material)
{
using sofa::defaulttype::Vec4f;
if (dataNode.IsNull() || dynamic_cast<mitk::Surface*>(dataNode->GetData()) == NULL)
return;
if (material.useDiffuse)
dataNode->SetFloatProperty("opacity", material.diffuse[3]);
Vec4f ambient = material.useAmbient ? material.ambient : Vec4f();
Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f();
Vec4f specular = material.useSpecular ? material.specular : Vec4f();
float shininess = material.useShininess ? std::min(material.shininess, 128.0f) : 45.0f;
if (shininess == 0.0f)
{
specular.clear();
shininess = 1.0f;
}
dataNode->SetFloatProperty("material.ambientCoefficient", 1.0f);
dataNode->SetProperty("material.ambientColor", mitk::ColorProperty::New(material.ambient.elems));
dataNode->SetFloatProperty("material.diffuseCoefficient", 1.0f);
dataNode->SetProperty("color", mitk::ColorProperty::New(material.diffuse.elems));
dataNode->SetFloatProperty("material.specularCoefficient", 1.0f);
dataNode->SetProperty("material.specularColor", mitk::ColorProperty::New(specular.elems));
dataNode->SetFloatProperty("material.specularPower", shininess);
}
-mitk::ExportMitkVisitor::ExportMitkVisitor(const sofa::core::ExecParams* params)
- : Visitor(params)
+static mitk::DataNode::Pointer GetSimulationDataNode(mitk::DataStorage::Pointer dataStorage, sofa::core::objectmodel::BaseNode::SPtr rootNode)
+{
+ if (dataStorage.IsNull())
+ return NULL;
+
+ if (!rootNode)
+ return NULL;
+
+ mitk::TNodePredicateDataType<mitk::Simulation>::Pointer predicate = mitk::TNodePredicateDataType<mitk::Simulation>::New();
+ mitk::DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate);
+
+ for (mitk::DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it)
+ {
+ mitk::DataNode::Pointer dataNode = it.Value();
+ mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(dataNode->GetData());
+
+ if (simulation->GetRootNode() == rootNode)
+ return dataNode;
+ }
+
+ return NULL;
+}
+
+
+mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params)
+ : Visitor(params),
+ m_DataStorage(dataStorage)
{
}
-mitk::ExportMitkVisitor::ExportMitkVisitor(const std::string& visualModelName, const sofa::core::ExecParams* params)
+mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params)
: Visitor(params),
+ m_DataStorage(dataStorage),
m_VisualModelName(visualModelName)
{
}
mitk::ExportMitkVisitor::~ExportMitkVisitor()
{
}
sofa::simulation::Visitor::Result mitk::ExportMitkVisitor::processNodeTopDown(sofa::simulation::Node* node)
{
- for_each(this, node, node->visualModel, &ExportMitkVisitor::processVisualModel);
- return RESULT_CONTINUE;
+ if (m_DataStorage.IsNotNull())
+ {
+ for_each(this, node, node->visualModel, &ExportMitkVisitor::processVisualModel);
+ return RESULT_CONTINUE;
+ }
+
+ return RESULT_PRUNE;
}
void mitk::ExportMitkVisitor::processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel)
{
using sofa::defaulttype::ResizableExtVector;
typedef sofa::component::visualmodel::VisualModelImpl::VecCoord VecCoord;
typedef sofa::component::visualmodel::VisualModelImpl::Triangle Triangle;
typedef sofa::component::visualmodel::VisualModelImpl::Quad Quad;
typedef sofa::component::visualmodel::VisualModelImpl::Deriv Deriv;
typedef sofa::component::visualmodel::VisualModelImpl::VecTexCoord VecTexCoord;
sofa::component::visualmodel::VisualModelImpl* visualModelImpl = dynamic_cast<sofa::component::visualmodel::VisualModelImpl*>(visualModel);
if (visualModelImpl == NULL)
return;
if (!m_VisualModelName.empty() && m_VisualModelName != visualModelImpl->name.getValue())
return;
- DataStorage::Pointer dataStorage = GetDataStorage();
-
- if (dataStorage.IsNull())
- return;
-
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
const VecCoord& vertices = visualModelImpl->m_vertices2.getValue().empty()
? visualModelImpl->m_positions.getValue()
: visualModelImpl->m_vertices2.getValue();
size_t numPoints = vertices.size();
points->SetNumberOfPoints(numPoints);
for (size_t i = 0; i < numPoints; ++i)
points->SetPoint(i, vertices[i].elems);
polyData->SetPoints(points);
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
const ResizableExtVector<Triangle>& triangles = visualModelImpl->m_triangles.getValue();
if (!triangles.empty())
{
ResizableExtVector<Triangle>::const_iterator trianglesEnd = triangles.end();
for (ResizableExtVector<Triangle>::const_iterator it = triangles.begin(); it != trianglesEnd; ++it)
{
const Triangle& triangle = *it;
polys->InsertNextCell(3);
polys->InsertCellPoint(triangle[0]);
polys->InsertCellPoint(triangle[1]);
polys->InsertCellPoint(triangle[2]);
}
}
const ResizableExtVector<Quad>& quads = visualModelImpl->m_quads.getValue();
if (!quads.empty())
{
ResizableExtVector<Quad>::const_iterator quadsEnd = quads.end();
for (ResizableExtVector<Quad>::const_iterator it = quads.begin(); it != quadsEnd; ++it)
{
const Quad& quad = *it;
polys->InsertNextCell(4);
polys->InsertCellPoint(quad[0]);
polys->InsertCellPoint(quad[1]);
polys->InsertCellPoint(quad[2]);
polys->InsertCellPoint(quad[3]);
}
}
polyData->SetPolys(polys);
const ResizableExtVector<Deriv>& normals = visualModelImpl->m_vnormals.getValue();
if (!normals.empty())
{
size_t numNormals = normals.size();
vtkSmartPointer<vtkFloatArray> vtkNormals = vtkSmartPointer<vtkFloatArray>::New();
vtkNormals->SetNumberOfComponents(3);
vtkNormals->SetNumberOfTuples(numNormals);
for (size_t i = 0; i < numNormals; ++i)
vtkNormals->SetTuple(i, normals[i].elems);
polyData->GetPointData()->SetNormals(vtkNormals);
}
const VecTexCoord& texCoords = visualModelImpl->m_vtexcoords.getValue();
if (!texCoords.empty())
{
size_t numTexCoords = texCoords.size();
vtkSmartPointer<vtkFloatArray> vtkTexCoords = vtkSmartPointer<vtkFloatArray>::New();
vtkTexCoords->SetNumberOfComponents(2);
vtkTexCoords->SetNumberOfTuples(numTexCoords);
for (size_t i = 0; i < numTexCoords; ++i)
vtkTexCoords->SetTuple(i, texCoords[i].elems);
polyData->GetPointData()->SetTCoords(vtkTexCoords);
}
Surface::Pointer surface = Surface::New();
surface->SetVtkPolyData(polyData);
DataNode::Pointer dataNode = DataNode::New();
dataNode->SetName(visualModelImpl->name.getValue());
dataNode->SetData(surface);
ApplyMaterial(dataNode, visualModelImpl->material.getValue());
- DataNode::Pointer parentDataNode = GetSimulationDataNode(node->getRoot());
+ DataNode::Pointer parentDataNode = GetSimulationDataNode(m_DataStorage, node->getRoot());
if (parentDataNode.IsNotNull())
surface->SetGeometry(parentDataNode->GetData()->GetGeometry());
- dataStorage->Add(dataNode, parentDataNode);
+ m_DataStorage->Add(dataNode, parentDataNode);
}
diff --git a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.h b/Modules/Simulation/mitkExportMitkVisitor.h
similarity index 66%
rename from Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.h
rename to Modules/Simulation/mitkExportMitkVisitor.h
index 44729ba2ec..fb89e0ee35 100644
--- a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.h
+++ b/Modules/Simulation/mitkExportMitkVisitor.h
@@ -1,44 +1,46 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkExportMitkVisitor_h
#define mitkExportMitkVisitor_h
+#include <mitkDataStorage.h>
#include <sofa/simulation/common/Visitor.h>
-#include <org_mitk_simulation_Export.h>
+#include <MitkSimulationExports.h>
namespace mitk
{
- class SIMULATION_INIT_EXPORT ExportMitkVisitor : public sofa::simulation::Visitor
+ class MitkSimulation_EXPORT ExportMitkVisitor : public sofa::simulation::Visitor
{
public:
- explicit ExportMitkVisitor(const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance());
- explicit ExportMitkVisitor(const std::string& visualModelName, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance());
+ explicit ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance());
+ ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance());
~ExportMitkVisitor();
Result processNodeTopDown(sofa::simulation::Node* node);
private:
ExportMitkVisitor(const ExportMitkVisitor&);
ExportMitkVisitor& operator=(const ExportMitkVisitor&);
void processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel);
+ DataStorage::Pointer m_DataStorage;
std::string m_VisualModelName;
};
}
#endif
diff --git a/Modules/Simulation/mitkISimulationService.h b/Modules/Simulation/mitkISimulationService.h
index 4a077feb18..3406ce7827 100644
--- a/Modules/Simulation/mitkISimulationService.h
+++ b/Modules/Simulation/mitkISimulationService.h
@@ -1,44 +1,47 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkISimulationService_h
#define mitkISimulationService_h
#include <mitkSimulation.h>
#include <usServiceInterface.h>
#include <MitkSimulationExports.h>
namespace mitk
{
+ class Scheduler;
+
class MitkSimulation_EXPORT ISimulationService
{
public:
- virtual Simulation::Pointer GetSimulation() const = 0;
- virtual void SetSimulation(Simulation::Pointer simulation) = 0;
+ virtual Simulation::Pointer GetActiveSimulation() const = 0;
+ virtual void SetActiveSimulation(Simulation::Pointer activeSimulation) = 0;
+ virtual Scheduler* GetScheduler() = 0;
protected:
ISimulationService();
virtual ~ISimulationService();
private:
ISimulationService(const ISimulationService&);
ISimulationService& operator=(const ISimulationService&);
};
}
US_DECLARE_SERVICE_INTERFACE(mitk::ISimulationService, "org.mitk.ISimulationService");
#endif
diff --git a/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.cpp b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.cpp
new file mode 100644
index 0000000000..e5adae66b6
--- /dev/null
+++ b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.cpp
@@ -0,0 +1,44 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkSchedulableProcess.h"
+#include "mitkRoundRobinSchedulingAlgorithm.h"
+
+mitk::RoundRobinSchedulingAlgorithm::RoundRobinSchedulingAlgorithm()
+{
+}
+
+mitk::RoundRobinSchedulingAlgorithm::~RoundRobinSchedulingAlgorithm()
+{
+}
+
+mitk::SchedulableProcess* mitk::RoundRobinSchedulingAlgorithm::GetNextProcess(std::vector<SchedulableProcess*>& processQueue)
+{
+ size_t numProcesses = processQueue.size();
+
+ if (numProcesses == 0)
+ return NULL;
+
+ mitk::SchedulableProcess* process = processQueue[0];
+
+ if (numProcesses > 1)
+ {
+ processQueue.erase(processQueue.begin());
+ processQueue.push_back(process);
+ }
+
+ return process;
+}
diff --git a/Modules/Ext/DataManagement/mitkObjectObserver.h b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.h
similarity index 58%
rename from Modules/Ext/DataManagement/mitkObjectObserver.h
rename to Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.h
index 6abfba797c..4cf617d51f 100644
--- a/Modules/Ext/DataManagement/mitkObjectObserver.h
+++ b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.h
@@ -1,35 +1,34 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef MITKOBJECTOBSERVER_H
-#define MITKOBJECTOBSERVER_H
-#include <itkObject.h>
-#include "mitkSetObserver.h"
+#ifndef mitkRoundRobinSchedulingAlgorithm_h
+#define mitkRoundRobinSchedulingAlgorithm_h
+
+#include "mitkSchedulingAlgorithmBase.h"
namespace mitk
{
-
- ///
- /// Abstract interface for classes
- /// that want to be informed when an
- /// itk object was modified or deleted
- ///
- struct ObjectObserver: public SetObserver<itk::Object*>
+ class RoundRobinSchedulingAlgorithm : public SchedulingAlgorithmBase
{
+ public:
+ RoundRobinSchedulingAlgorithm();
+ ~RoundRobinSchedulingAlgorithm();
+
+ SchedulableProcess* GetNextProcess(std::vector<SchedulableProcess*>& processQueue);
};
}
-#endif // MITKOBJECTOBSERVER_H
+#endif
diff --git a/Modules/Simulation/mitkSchedulableProcess.cpp b/Modules/Simulation/mitkSchedulableProcess.cpp
new file mode 100644
index 0000000000..0849942deb
--- /dev/null
+++ b/Modules/Simulation/mitkSchedulableProcess.cpp
@@ -0,0 +1,53 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkSchedulableProcess.h"
+#include <algorithm>
+
+mitk::SchedulableProcess::SchedulableProcess(int priority)
+ : m_Priority(priority)
+{
+}
+
+mitk::SchedulableProcess::~SchedulableProcess()
+{
+}
+
+int mitk::SchedulableProcess::GetPriority() const
+{
+ return m_Priority;
+}
+
+boost::chrono::nanoseconds mitk::SchedulableProcess::GetTotalElapsedTime() const
+{
+ return m_TotalElapsedTime;
+}
+
+void mitk::SchedulableProcess::ResetTotalElapsedTime(boost::chrono::nanoseconds carryover)
+{
+ m_TotalElapsedTime = carryover;
+}
+
+boost::chrono::nanoseconds mitk::SchedulableProcess::GetElapsedTime() const
+{
+ return m_ElapsedTime;
+}
+
+void mitk::SchedulableProcess::SetElapsedTime(boost::chrono::nanoseconds elapsedTime)
+{
+ m_TotalElapsedTime += elapsedTime;
+ m_ElapsedTime = elapsedTime;
+}
diff --git a/Modules/Simulation/mitkSchedulableProcess.h b/Modules/Simulation/mitkSchedulableProcess.h
new file mode 100644
index 0000000000..4c26c26022
--- /dev/null
+++ b/Modules/Simulation/mitkSchedulableProcess.h
@@ -0,0 +1,49 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef mitkSchedulableProcess_h
+#define mitkSchedulableProcess_h
+
+#include <boost/chrono.hpp>
+#include <MitkSimulationExports.h>
+
+namespace mitk
+{
+ class MitkSimulation_EXPORT SchedulableProcess
+ {
+ public:
+ explicit SchedulableProcess(int priority = 0);
+ virtual ~SchedulableProcess();
+
+ int GetPriority() const;
+ boost::chrono::nanoseconds GetTotalElapsedTime() const;
+ void ResetTotalElapsedTime(boost::chrono::nanoseconds carryover = boost::chrono::nanoseconds::zero());
+ boost::chrono::nanoseconds GetElapsedTime() const;
+
+ protected:
+ void SetElapsedTime(boost::chrono::nanoseconds elapsedTime);
+
+ private:
+ SchedulableProcess(const SchedulableProcess&);
+ SchedulableProcess& operator=(const SchedulableProcess&);
+
+ int m_Priority;
+ boost::chrono::nanoseconds m_TotalElapsedTime;
+ boost::chrono::nanoseconds m_ElapsedTime;
+ };
+}
+
+#endif
diff --git a/Modules/Simulation/mitkScheduler.cpp b/Modules/Simulation/mitkScheduler.cpp
new file mode 100644
index 0000000000..bad6487f6a
--- /dev/null
+++ b/Modules/Simulation/mitkScheduler.cpp
@@ -0,0 +1,90 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkRoundRobinSchedulingAlgorithm.h"
+#include "mitkSchedulableProcess.h"
+#include "mitkScheduler.h"
+#include "mitkWeightedRoundRobinSchedulingAlgorithm.h"
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+struct mitk::Scheduler::Impl
+{
+ std::vector<SchedulableProcess*> processQueue;
+ SchedulingAlgorithmBase* algorithm;
+};
+
+mitk::Scheduler::Scheduler(SchedulingAlgorithm::Enum algorithm)
+ : m_Impl(new Impl)
+{
+ switch (algorithm)
+ {
+ case mitk::SchedulingAlgorithm::RoundRobin:
+ m_Impl->algorithm = new mitk::RoundRobinSchedulingAlgorithm;
+ break;
+
+ case mitk::SchedulingAlgorithm::WeightedRoundRobin:
+ m_Impl->algorithm = new mitk::WeightedRoundRobinSchedulingAlgorithm;
+ break;
+
+ default:
+ assert(false && "Unknown scheduling algorithm!");
+ }
+}
+
+mitk::Scheduler::~Scheduler()
+{
+ delete m_Impl->algorithm;
+ delete m_Impl;
+}
+
+void mitk::Scheduler::AddProcess(SchedulableProcess* process)
+{
+ if (process == NULL)
+ return;
+
+ if (std::find(m_Impl->processQueue.begin(), m_Impl->processQueue.end(), process) == m_Impl->processQueue.end())
+ m_Impl->processQueue.push_back(process);
+}
+
+void mitk::Scheduler::RemoveProcess(SchedulableProcess* process)
+{
+ if (process == NULL)
+ return;
+
+ std::vector<SchedulableProcess*>::iterator it = std::find(m_Impl->processQueue.begin(), m_Impl->processQueue.end(), process);
+
+ if (it != m_Impl->processQueue.end())
+ m_Impl->processQueue.erase(it);
+}
+
+bool mitk::Scheduler::IsEmpty() const
+{
+ return m_Impl->processQueue.empty();
+}
+
+mitk::SchedulableProcess* mitk::Scheduler::GetCurrentProcess()
+{
+ return !m_Impl->processQueue.empty()
+ ? m_Impl->processQueue[0]
+ : NULL;
+}
+
+mitk::SchedulableProcess* mitk::Scheduler::GetNextProcess()
+{
+ return m_Impl->algorithm->GetNextProcess(m_Impl->processQueue);
+}
diff --git a/Modules/Simulation/mitkScheduler.h b/Modules/Simulation/mitkScheduler.h
new file mode 100644
index 0000000000..da68a33848
--- /dev/null
+++ b/Modules/Simulation/mitkScheduler.h
@@ -0,0 +1,57 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef mitkScheduler_h
+#define mitkScheduler_h
+
+#include <MitkSimulationExports.h>
+
+namespace mitk
+{
+ class SchedulableProcess;
+ class SchedulingAlgorithmBase;
+
+ namespace SchedulingAlgorithm
+ {
+ enum Enum
+ {
+ RoundRobin,
+ WeightedRoundRobin
+ };
+ }
+
+ class MitkSimulation_EXPORT Scheduler
+ {
+ public:
+ explicit Scheduler(SchedulingAlgorithm::Enum algorithm = SchedulingAlgorithm::RoundRobin);
+ ~Scheduler();
+
+ void AddProcess(SchedulableProcess* process);
+ void RemoveProcess(SchedulableProcess* process);
+ bool IsEmpty() const;
+ SchedulableProcess* GetCurrentProcess();
+ SchedulableProcess* GetNextProcess();
+
+ private:
+ Scheduler(const Scheduler&);
+ Scheduler& operator=(const Scheduler&);
+
+ struct Impl;
+ Impl* m_Impl;
+ };
+}
+
+#endif
diff --git a/Modules/Ext/DataManagement/mitkObjectSet.h b/Modules/Simulation/mitkSchedulingAlgorithmBase.cpp
similarity index 72%
rename from Modules/Ext/DataManagement/mitkObjectSet.h
rename to Modules/Simulation/mitkSchedulingAlgorithmBase.cpp
index a851faf6af..0a1586c71a 100644
--- a/Modules/Ext/DataManagement/mitkObjectSet.h
+++ b/Modules/Simulation/mitkSchedulingAlgorithmBase.cpp
@@ -1,26 +1,26 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef MITKObjectSet_H
-#define MITKObjectSet_H
-#include <mitkSet.h>
+#include "mitkSchedulableProcess.h"
+#include "mitkSchedulingAlgorithmBase.h"
-namespace mitk
+mitk::SchedulingAlgorithmBase::SchedulingAlgorithmBase()
{
- typedef mitk::Set<itk::Object*> ObjectSet;
}
-#endif // MITKObjectSet_H
+mitk::SchedulingAlgorithmBase::~SchedulingAlgorithmBase()
+{
+}
diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkSchedulingAlgorithmBase.h
similarity index 55%
copy from Modules/Simulation/mitkSimulationService.h
copy to Modules/Simulation/mitkSchedulingAlgorithmBase.h
index c8c3803fb8..3f39462171 100644
--- a/Modules/Simulation/mitkSimulationService.h
+++ b/Modules/Simulation/mitkSchedulingAlgorithmBase.h
@@ -1,38 +1,40 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef mitkSimulationService_h
-#define mitkSimulationService_h
+#ifndef mitkSchedulingAlgorithmBase_h
+#define mitkSchedulingAlgorithmBase_h
-#include <mitkISimulationService.h>
+#include <vector>
namespace mitk
{
- class SimulationService : public ISimulationService
+ class SchedulableProcess;
+
+ class SchedulingAlgorithmBase
{
public:
- SimulationService();
- ~SimulationService();
+ SchedulingAlgorithmBase();
+ virtual ~SchedulingAlgorithmBase();
- Simulation::Pointer GetSimulation() const;
- void SetSimulation(Simulation::Pointer simulation);
+ virtual SchedulableProcess* GetNextProcess(std::vector<SchedulableProcess*>& processQueue) = 0;
private:
- Simulation::Pointer m_Simulation;
+ SchedulingAlgorithmBase(const SchedulingAlgorithmBase&);
+ SchedulingAlgorithmBase& operator=(const SchedulingAlgorithmBase&);
};
}
#endif
diff --git a/Modules/Simulation/mitkSimulation.cpp b/Modules/Simulation/mitkSimulation.cpp
index 68dfa9cf54..99f7518c1c 100644
--- a/Modules/Simulation/mitkSimulation.cpp
+++ b/Modules/Simulation/mitkSimulation.cpp
@@ -1,158 +1,169 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSimulation.h"
#include <sofa/simulation/tree/TreeSimulation.h>
#include "mitkGeometry3D.h"
static sofa::simulation::Simulation::SPtr CreateSimulation()
{
const std::string key = "MultiMappingObject";
if (sofa::simulation::xml::BaseElement::NodeFactory::HasKey(key))
sofa::simulation::xml::BaseElement::NodeFactory::ResetEntry(key);
return sofa::core::objectmodel::New<sofa::simulation::tree::TreeSimulation>();
}
mitk::Simulation::Simulation()
- : m_Simulation(CreateSimulation())
+ : m_SOFASimulation(CreateSimulation())
{
}
mitk::Simulation::~Simulation()
{
if (m_RootNode)
{
- if (m_Simulation)
- m_Simulation->unload(m_RootNode);
+ if (m_SOFASimulation)
+ m_SOFASimulation->unload(m_RootNode);
}
}
void mitk::Simulation::Animate()
{
- if (!m_RootNode || !m_Simulation)
+ if (!m_RootNode || !m_SOFASimulation)
return;
- m_Simulation->animate(m_RootNode.get(), m_RootNode->getDt());
+ boost::chrono::high_resolution_clock::time_point t0 = boost::chrono::high_resolution_clock::now();
+ m_SOFASimulation->animate(m_RootNode.get(), m_RootNode->getDt());
+ this->SetElapsedTime(boost::chrono::high_resolution_clock::now() - t0);
+
+ this->UpdateOutputInformation();
}
sofa::core::visual::DrawTool* mitk::Simulation::GetDrawTool()
{
return &m_DrawTool;
}
sofa::simulation::Node::SPtr mitk::Simulation::GetRootNode() const
{
return m_RootNode;
}
-sofa::simulation::Simulation::SPtr mitk::Simulation::GetSimulation() const
+sofa::simulation::Simulation::SPtr mitk::Simulation::GetSOFASimulation() const
{
- return m_Simulation;
+ return m_SOFASimulation;
}
void mitk::Simulation::Reset()
{
- if (!m_RootNode || !m_Simulation)
+ if (!m_RootNode || !m_SOFASimulation)
return;
- m_Simulation->reset(m_RootNode.get());
+ m_SOFASimulation->reset(m_RootNode.get());
m_RootNode->setTime(0.0);
- m_Simulation->updateContext(m_RootNode.get());
+ m_SOFASimulation->updateContext(m_RootNode.get());
+}
+
+bool mitk::Simulation::GetAnimationFlag() const
+{
+ return m_RootNode
+ ? m_RootNode->getContext()->getAnimate()
+ : false;
}
void mitk::Simulation::SetAnimationFlag(bool animate)
{
if (m_RootNode)
m_RootNode->getContext()->setAnimate(animate);
}
void mitk::Simulation::SetDt(double dt)
{
if (m_RootNode)
m_RootNode->setDt(dt);
}
void mitk::Simulation::SetRootNode(sofa::simulation::Node::SPtr rootNode)
{
m_RootNode = rootNode;
}
bool mitk::Simulation::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
void mitk::Simulation::SetRequestedRegion(const itk::DataObject*)
{
}
void mitk::Simulation::SetRequestedRegionToLargestPossibleRegion()
{
}
void mitk::Simulation::UpdateOutputInformation()
{
using sofa::defaulttype::BoundingBox;
using sofa::defaulttype::Vector3;
if (this->GetSource().IsNotNull())
this->GetSource()->UpdateOutputInformation();
if (m_RootNode)
{
const BoundingBox& boundingBox = m_RootNode->f_bbox.getValue();
mitk::Geometry3D::BoundsArrayType bounds;
if (boundingBox.isValid())
{
const Vector3& min = boundingBox.minBBox();
const Vector3& max = boundingBox.maxBBox();
bounds[0] = static_cast<mitk::Geometry3D::BoundsArrayType::ValueType>(min.x());
bounds[1] = static_cast<mitk::Geometry3D::BoundsArrayType::ValueType>(max.x());
bounds[2] = static_cast<mitk::Geometry3D::BoundsArrayType::ValueType>(min.y());
bounds[3] = static_cast<mitk::Geometry3D::BoundsArrayType::ValueType>(max.y());
bounds[4] = static_cast<mitk::Geometry3D::BoundsArrayType::ValueType>(min.z());
bounds[5] = static_cast<mitk::Geometry3D::BoundsArrayType::ValueType>(max.z());
}
else
{
bounds.Fill(0.0f);
}
mitk::BaseGeometry::Pointer geometry = this->GetGeometry();
if (geometry.IsNull())
{
geometry = Geometry3D::New();
geometry->SetBounds(bounds);
this->SetGeometry(geometry);
}
else
{
geometry->SetBounds(bounds);
}
}
this->GetTimeGeometry()->Update();
}
bool mitk::Simulation::VerifyRequestedRegion()
{
return true;
}
diff --git a/Modules/Simulation/mitkSimulation.h b/Modules/Simulation/mitkSimulation.h
index f9618de21d..de440818c4 100644
--- a/Modules/Simulation/mitkSimulation.h
+++ b/Modules/Simulation/mitkSimulation.h
@@ -1,59 +1,61 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkSimulation_h
#define mitkSimulation_h
#include <mitkBaseData.h>
+#include <mitkSchedulableProcess.h>
#include <sofa/core/visual/DrawToolGL.h>
#include <sofa/simulation/common/Simulation.h>
#include <MitkSimulationExports.h>
namespace mitk
{
- class MitkSimulation_EXPORT Simulation : public BaseData
+ class MitkSimulation_EXPORT Simulation : public BaseData, public SchedulableProcess
{
public:
mitkClassMacro(Simulation, BaseData);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
void Animate();
sofa::core::visual::DrawTool* GetDrawTool();
sofa::simulation::Node::SPtr GetRootNode() const;
- sofa::simulation::Simulation::SPtr GetSimulation() const;
+ sofa::simulation::Simulation::SPtr GetSOFASimulation() const;
void Reset();
+ bool GetAnimationFlag() const;
void SetAnimationFlag(bool animate);
void SetDt(double dt);
void SetRootNode(sofa::simulation::Node::SPtr rootNode);
bool RequestedRegionIsOutsideOfTheBufferedRegion();
void SetRequestedRegion(const itk::DataObject*);
void SetRequestedRegionToLargestPossibleRegion();
void UpdateOutputInformation();
bool VerifyRequestedRegion();
private:
Simulation();
~Simulation();
- sofa::simulation::Simulation::SPtr m_Simulation;
+ sofa::simulation::Simulation::SPtr m_SOFASimulation;
sofa::simulation::Node::SPtr m_RootNode;
sofa::core::visual::DrawToolGL m_DrawTool;
};
}
#endif
diff --git a/Modules/Simulation/mitkSimulationInteractor.cpp b/Modules/Simulation/mitkSimulationInteractor.cpp
new file mode 100644
index 0000000000..1b989d4f0c
--- /dev/null
+++ b/Modules/Simulation/mitkSimulationInteractor.cpp
@@ -0,0 +1,526 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkInteractionPositionEvent.h>
+#include <sofa/component/collision/AttachBodyPerformer.h>
+#include <sofa/component/collision/ComponentMouseInteraction.h>
+#include <sofa/component/collision/FixParticlePerformer.h>
+#include <sofa/component/collision/RayContact.h>
+#include <sofa/component/collision/RayModel.h>
+#include <sofa/component/container/MechanicalObject.h>
+#include <sofa/simulation/common/CollisionVisitor.h>
+#include <sofa/simulation/common/DeleteVisitor.h>
+#include <sofa/simulation/common/MechanicalVisitor.h>
+#include <sofa/simulation/common/Node.h>
+#include <vtkCamera.h>
+#include "mitkSimulation.h"
+#include "mitkSimulationInteractor.h"
+
+using sofa::component::collision::AttachBodyPerformer;
+using sofa::component::collision::BaseRayContact;
+using sofa::component::collision::BodyPicked;
+using sofa::component::collision::ComponentMouseInteraction;
+using sofa::component::collision::FixParticlePerformerConfiguration;
+using sofa::component::collision::InteractionPerformer;
+using sofa::component::collision::Ray;
+using sofa::component::collision::RayModel;
+using sofa::component::container::MechanicalObject;
+using sofa::core::behavior::BaseMechanicalState;
+using sofa::core::collision::DetectionOutput;
+using sofa::core::collision::Pipeline;
+using sofa::core::objectmodel::BaseContext;
+using sofa::core::CollisionElementIterator;
+using sofa::core::ExecParams;
+using sofa::core::MechanicalParams;
+using sofa::core::VecCoordId;
+using sofa::defaulttype::dot;
+using sofa::defaulttype::Vec3d;
+using sofa::defaulttype::Vec3Types;
+using sofa::helper::vector;
+using sofa::simulation::CollisionVisitor;
+using sofa::simulation::DeleteVisitor;
+using sofa::simulation::MechanicalPickParticlesVisitor;
+using sofa::simulation::MechanicalPropagatePositionVisitor;
+using sofa::simulation::Node;
+
+namespace mitk
+{
+ class SimulationInteractor::Impl
+ {
+ public:
+ Impl();
+ ~Impl();
+
+ void Initialize(Node::SPtr rootNode);
+ void Uninitialize();
+ void AttachMouseNode();
+ void DetachMouseNode();
+ bool IsInteractionPerformerNotNull() const;
+ void UpdatePickRay(InteractionPositionEvent* event);
+ void FindCollision();
+ void AttachCompatibleInteraction();
+ void DetachInteraction(bool setNull);
+ void StartInteraction(const std::string& type);
+ void ExecuteInteraction();
+ void StopInteraction();
+
+ private:
+ Impl(const Impl&);
+ Impl& operator=(const Impl&);
+
+ BodyPicked FindCollisionUsingPipeline();
+ BodyPicked FindCollisionUsingBruteForce();
+ void ConfigureInteractionPerformer();
+
+ Node::SPtr m_RootNode;
+ Node::SPtr m_MouseNode;
+ MechanicalObject<Vec3Types>::SPtr m_PickRayContainer;
+ RayModel::SPtr m_PickRayModel;
+ std::vector<ComponentMouseInteraction*> m_InteractionComponents;
+ ComponentMouseInteraction* m_Interaction;
+ std::auto_ptr<InteractionPerformer> m_InteractionPerformer;
+ bool m_IsMouseNodeAttached;
+ bool m_UseCollisionPipeline;
+ BodyPicked m_LastBodyPicked;
+ };
+}
+
+mitk::SimulationInteractor::Impl::Impl()
+ : m_Interaction(NULL),
+ m_IsMouseNodeAttached(false),
+ m_UseCollisionPipeline(true)
+{
+}
+
+mitk::SimulationInteractor::Impl::~Impl()
+{
+ this->Uninitialize();
+}
+
+void mitk::SimulationInteractor::Impl::Initialize(const Node::SPtr rootNode)
+{
+ this->Uninitialize();
+
+ m_RootNode = rootNode;
+
+ m_PickRayContainer = sofa::core::objectmodel::New<MechanicalObject<Vec3Types> >();
+ m_PickRayContainer->setName("MousePosition");
+ m_PickRayContainer->resize(1);
+
+ m_PickRayModel = sofa::core::objectmodel::New<RayModel>();
+ m_PickRayModel->setName("MouseCollisionModel");
+ m_PickRayModel->setNbRay(1);
+
+ m_MouseNode = rootNode->createChild("Mouse");
+ m_MouseNode->addObject(m_PickRayContainer);
+ m_MouseNode->addObject(m_PickRayModel);
+
+ m_MouseNode->init(ExecParams::defaultInstance());
+ m_PickRayContainer->init();
+ m_PickRayModel->init();
+
+ typedef ComponentMouseInteraction::ComponentMouseInteractionFactory Factory;
+ const Factory* factory = Factory::getInstance();
+
+ for (Factory::const_iterator it = factory->begin(); it != factory->end(); ++it)
+ m_InteractionComponents.push_back(it->second->createInstance(NULL));
+
+ m_MouseNode->detachFromGraph();
+
+ Pipeline* collisionPipeline;
+ rootNode->getContext()->get(collisionPipeline, BaseContext::SearchRoot);
+
+ m_UseCollisionPipeline = collisionPipeline != NULL;
+}
+
+void mitk::SimulationInteractor::Impl::Uninitialize()
+{
+ this->DetachMouseNode();
+
+ if (!m_InteractionComponents.empty())
+ {
+ for (std::vector<ComponentMouseInteraction*>::iterator it = m_InteractionComponents.begin(); it != m_InteractionComponents.end(); ++it)
+ delete *it;
+
+ m_InteractionComponents.clear();
+ m_Interaction = NULL;
+ }
+
+ if (m_MouseNode)
+ {
+ m_MouseNode->execute<DeleteVisitor>(ExecParams::defaultInstance());
+
+ m_PickRayModel.reset();
+ m_PickRayContainer.reset();
+ m_MouseNode.reset();
+ m_RootNode.reset();
+ }
+}
+
+void mitk::SimulationInteractor::Impl::AttachMouseNode()
+{
+ if (!m_IsMouseNodeAttached)
+ {
+ m_RootNode->addChild(m_MouseNode);
+ m_IsMouseNodeAttached = true;
+ }
+}
+
+void mitk::SimulationInteractor::Impl::DetachMouseNode()
+{
+ if (m_IsMouseNodeAttached)
+ {
+ this->DetachInteraction(false);
+ m_MouseNode->detachFromGraph();
+ m_IsMouseNodeAttached = false;
+ }
+}
+
+bool mitk::SimulationInteractor::Impl::IsInteractionPerformerNotNull() const
+{
+ return m_InteractionPerformer.get() != NULL;
+}
+
+void mitk::SimulationInteractor::Impl::UpdatePickRay(InteractionPositionEvent* event)
+{
+ if (!m_IsMouseNodeAttached)
+ return;
+
+ vtkCamera* camera = event->GetSender()->GetVtkRenderer()->GetActiveCamera();
+
+ Vec3d cameraOrigin(camera->GetPosition());
+ Vec3d pickedPosition(event->GetPositionInWorld().GetDataPointer());
+ Vec3d pickRayDirection(pickedPosition - cameraOrigin);
+ Vec3d focalPoint(camera->GetFocalPoint());
+
+ Vec3d cameraDirection(focalPoint - cameraOrigin);
+ cameraDirection.normalize();
+
+ std::pair<double, double> clippingRange;
+ camera->GetClippingRange(clippingRange.first, clippingRange.second);
+
+ double dotProduct = dot(cameraDirection, pickRayDirection);
+ double norm = pickRayDirection.norm();
+
+ clippingRange.first = clippingRange.first / dotProduct * norm;
+ clippingRange.second = clippingRange.second / dotProduct * norm;
+
+ pickRayDirection.normalize();
+
+ Ray pickRay = m_PickRayModel->getRay(0);
+ pickRay.setOrigin(cameraOrigin + pickRayDirection * clippingRange.first);
+ pickRay.setDirection(pickRayDirection);
+ pickRay.setL(clippingRange.second - clippingRange.first);
+
+ MechanicalPropagatePositionVisitor(MechanicalParams::defaultInstance(), 0, VecCoordId::position(), true)
+ .execute(m_PickRayModel->getContext());
+
+ MechanicalPropagatePositionVisitor(MechanicalParams::defaultInstance(), 0, VecCoordId::freePosition(), true)
+ .execute(m_PickRayModel->getContext());
+}
+
+void mitk::SimulationInteractor::Impl::FindCollision()
+{
+ CollisionVisitor(ExecParams::defaultInstance()).execute(m_RootNode->getContext());
+
+ if (m_UseCollisionPipeline)
+ {
+ m_LastBodyPicked = this->FindCollisionUsingPipeline();
+
+ if (m_LastBodyPicked.body != NULL)
+ return;
+ }
+
+ m_LastBodyPicked = this->FindCollisionUsingBruteForce();
+}
+
+BodyPicked mitk::SimulationInteractor::Impl::FindCollisionUsingPipeline()
+{
+ BodyPicked bodyPicked;
+
+ Ray ray = m_PickRayModel->getRay(0);
+ const Vec3d& origin = ray.origin();
+ const Vec3d& direction = ray.direction();
+ const double length = ray.l();
+
+ const std::set<BaseRayContact*>& contacts = m_PickRayModel->getContacts();
+
+ for (std::set<BaseRayContact*>::const_iterator contact = contacts.begin(); contact != contacts.end(); ++contact)
+ {
+ const vector<DetectionOutput*>& detectionOutputs = (*contact)->getDetectionOutputs();
+
+ for (vector<DetectionOutput*>::const_iterator detectionOutput = detectionOutputs.begin(); detectionOutput != detectionOutputs.end(); ++detectionOutput)
+ {
+ CollisionElementIterator collisionElement;
+ int pointIndex;
+
+ if ((*detectionOutput)->elem.first.getCollisionModel() == m_PickRayModel)
+ {
+ collisionElement = (*detectionOutput)->elem.second;
+ pointIndex = 1;
+ }
+ else if ((*detectionOutput)->elem.second.getCollisionModel() == m_PickRayModel)
+ {
+ collisionElement = (*detectionOutput)->elem.first;
+ pointIndex = 0;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!collisionElement.getCollisionModel()->isSimulated())
+ continue;
+
+ const double t = ((*detectionOutput)->point[pointIndex] - origin) * direction;
+
+ if (t < 0.0 || t > length)
+ continue;
+
+ if (bodyPicked.body == NULL || t < bodyPicked.rayLength)
+ {
+ bodyPicked.body = collisionElement.getCollisionModel();
+ bodyPicked.indexCollisionElement = collisionElement.getIndex();
+ bodyPicked.point = (*detectionOutput)->point[pointIndex];
+ bodyPicked.dist = ((*detectionOutput)->point[1] - (*detectionOutput)->point[0]).norm();
+ bodyPicked.rayLength = t;
+ }
+ }
+ }
+
+ return bodyPicked;
+}
+
+BodyPicked mitk::SimulationInteractor::Impl::FindCollisionUsingBruteForce()
+{
+ BodyPicked bodyPicked;
+
+ Ray ray = m_PickRayModel->getRay(0);
+ const Vec3d& origin = ray.origin();
+ const Vec3d& direction = ray.direction();
+ const double length = ray.l();
+
+ MechanicalPickParticlesVisitor pickVisitor(ExecParams::defaultInstance(), origin, direction, length);
+ pickVisitor.execute(m_RootNode->getContext());
+
+ if (!pickVisitor.particles.empty())
+ {
+ bodyPicked.mstate = pickVisitor.particles.begin()->second.first;
+ bodyPicked.indexCollisionElement = pickVisitor.particles.begin()->second.second;
+ bodyPicked.point[0] = bodyPicked.mstate->getPX(bodyPicked.indexCollisionElement);
+ bodyPicked.point[1] = bodyPicked.mstate->getPY(bodyPicked.indexCollisionElement);
+ bodyPicked.point[2] = bodyPicked.mstate->getPZ(bodyPicked.indexCollisionElement);
+ bodyPicked.dist = 0;
+ bodyPicked.rayLength = (bodyPicked.point - origin) * direction;
+ }
+
+ return bodyPicked;
+}
+
+void mitk::SimulationInteractor::Impl::AttachCompatibleInteraction()
+{
+ BaseContext* context;
+
+ if (m_LastBodyPicked.body == NULL)
+ {
+ context = m_LastBodyPicked.mstate != NULL
+ ? m_LastBodyPicked.mstate->getContext()
+ : NULL;
+ }
+ else
+ {
+ context = m_LastBodyPicked.body->getContext();
+ }
+
+ if (context != NULL)
+ {
+ if (m_Interaction == NULL || !m_Interaction->isCompatible(context))
+ {
+ bool foundCompatibleInteractor = false;
+
+ for (std::vector<ComponentMouseInteraction*>::const_iterator it = m_InteractionComponents.begin(); it != m_InteractionComponents.end(); ++it)
+ {
+ if (*it != m_Interaction && (*it)->isCompatible(context))
+ {
+ this->DetachInteraction(false);
+ m_Interaction = *it;
+ m_Interaction->attach(m_MouseNode.get());
+
+ foundCompatibleInteractor = true;
+ break;
+ }
+ }
+
+ if (!foundCompatibleInteractor)
+ this->DetachInteraction(true);
+ }
+ }
+ else
+ {
+ this->DetachInteraction(true);
+ }
+
+ if (m_Interaction != NULL)
+ {
+ m_Interaction->mouseInteractor->setMouseRayModel(m_PickRayModel.get());
+ m_Interaction->mouseInteractor->setBodyPicked(m_LastBodyPicked);
+ }
+}
+
+void mitk::SimulationInteractor::Impl::DetachInteraction(bool setNull)
+{
+ if (m_Interaction != NULL)
+ {
+ m_Interaction->detach();
+
+ if (setNull)
+ m_Interaction = NULL;
+ }
+}
+
+void mitk::SimulationInteractor::Impl::StartInteraction(const std::string& type)
+{
+ if (m_Interaction == NULL)
+ return;
+
+ InteractionPerformer::InteractionPerformerFactory* factory = InteractionPerformer::InteractionPerformerFactory::getInstance();
+ m_InteractionPerformer.reset(factory->createObject(type, m_Interaction->mouseInteractor.get()));
+
+ if (m_InteractionPerformer.get() != NULL)
+ {
+ this->ConfigureInteractionPerformer();
+ m_Interaction->mouseInteractor->addInteractionPerformer(m_InteractionPerformer.get());
+ m_InteractionPerformer->start();
+ }
+}
+
+void mitk::SimulationInteractor::Impl::ConfigureInteractionPerformer()
+{
+ AttachBodyPerformer<Vec3Types>* attachBodyPerformer = dynamic_cast<AttachBodyPerformer<Vec3Types>*>(m_InteractionPerformer.get());
+
+ if (attachBodyPerformer != NULL)
+ {
+ attachBodyPerformer->setStiffness(1000);
+ attachBodyPerformer->setArrowSize(0);
+ attachBodyPerformer->setShowFactorSize(1);
+ return;
+ }
+
+ FixParticlePerformerConfiguration* fixParticlePerformer = dynamic_cast<FixParticlePerformerConfiguration*>(m_InteractionPerformer.get());
+
+ if (fixParticlePerformer != NULL)
+ fixParticlePerformer->setStiffness(10000);
+}
+
+void mitk::SimulationInteractor::Impl::ExecuteInteraction()
+{
+ if (m_InteractionPerformer.get() == NULL)
+ return;
+
+ m_InteractionPerformer->execute();
+}
+
+void mitk::SimulationInteractor::Impl::StopInteraction()
+{
+ if (m_InteractionPerformer.get() == NULL)
+ return;
+
+ AttachBodyPerformer<Vec3Types>* attachBodyPerformer = dynamic_cast<AttachBodyPerformer<Vec3Types>*>(m_InteractionPerformer.get());
+
+ if (attachBodyPerformer != NULL)
+ attachBodyPerformer->clear();
+
+ m_Interaction->mouseInteractor->removeInteractionPerformer(m_InteractionPerformer.get());
+ m_InteractionPerformer.release();
+}
+
+mitk::SimulationInteractor::SimulationInteractor()
+ : m_Impl(new Impl)
+{
+}
+
+mitk::SimulationInteractor::~SimulationInteractor()
+{
+}
+
+void mitk::SimulationInteractor::ConnectActionsAndFunctions()
+{
+ CONNECT_FUNCTION("startPrimaryInteraction", StartPrimaryInteraction);
+ CONNECT_FUNCTION("startSecondaryInteraction", StartSecondaryInteraction);
+ CONNECT_FUNCTION("stopInteraction", StopInteraction);
+ CONNECT_FUNCTION("executeInteraction", ExecuteInteraction);
+ CONNECT_CONDITION("isInteractionPerformerNotNull", IsInteractionPerformerNotNull);
+}
+
+void mitk::SimulationInteractor::DataNodeChanged()
+{
+ this->ResetToStartState();
+
+ NodeType dataNode = this->GetDataNode();
+
+ if (dataNode.IsNotNull())
+ {
+ Simulation::Pointer simulation = dynamic_cast<Simulation*>(dataNode->GetData());
+
+ if (simulation.IsNotNull())
+ {
+ m_Impl->Initialize(simulation->GetRootNode());
+ return;
+ }
+ }
+
+ m_Impl->Uninitialize();
+}
+
+void mitk::SimulationInteractor::StartInteraction(const std::string& type, InteractionPositionEvent* event)
+{
+ m_Impl->AttachMouseNode();
+ m_Impl->UpdatePickRay(event);
+ m_Impl->FindCollision();
+ m_Impl->AttachCompatibleInteraction();
+ m_Impl->StartInteraction(type);
+}
+
+bool mitk::SimulationInteractor::StartPrimaryInteraction(StateMachineAction*, InteractionEvent* event)
+{
+ this->StartInteraction("AttachBody", dynamic_cast<InteractionPositionEvent*>(event));
+ return true;
+}
+
+bool mitk::SimulationInteractor::StartSecondaryInteraction(StateMachineAction*, InteractionEvent* event)
+{
+ this->StartInteraction("FixParticle", dynamic_cast<InteractionPositionEvent*>(event));
+ return true;
+}
+
+bool mitk::SimulationInteractor::StopInteraction(StateMachineAction*, InteractionEvent*)
+{
+ m_Impl->StopInteraction();
+ m_Impl->DetachMouseNode();
+ return true;
+}
+
+bool mitk::SimulationInteractor::ExecuteInteraction(StateMachineAction*, InteractionEvent* event)
+{
+ m_Impl->UpdatePickRay(dynamic_cast<InteractionPositionEvent*>(event));
+ m_Impl->ExecuteInteraction();
+ return true;
+}
+
+bool mitk::SimulationInteractor::IsInteractionPerformerNotNull(const InteractionEvent*)
+{
+ return m_Impl->IsInteractionPerformerNotNull();
+}
diff --git a/Modules/Simulation/mitkSimulationInteractor.h b/Modules/Simulation/mitkSimulationInteractor.h
new file mode 100644
index 0000000000..6e838d86f7
--- /dev/null
+++ b/Modules/Simulation/mitkSimulationInteractor.h
@@ -0,0 +1,54 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef mitkSimulationInteractor_h
+#define mitkSimulationInteractor_h
+
+#include <mitkDataInteractor.h>
+#include <MitkSimulationExports.h>
+
+namespace mitk
+{
+ class InteractionPositionEvent;
+
+ class MitkSimulation_EXPORT SimulationInteractor : public DataInteractor
+ {
+ public:
+ mitkClassMacro(SimulationInteractor, DataInteractor);
+ itkFactorylessNewMacro(Self);
+ itkCloneMacro(Self);
+
+ protected:
+ void ConnectActionsAndFunctions();
+ void DataNodeChanged();
+
+ private:
+ SimulationInteractor();
+ ~SimulationInteractor();
+
+ void StartInteraction(const std::string& type, InteractionPositionEvent* event);
+ bool StartPrimaryInteraction(StateMachineAction* action, InteractionEvent* event);
+ bool StartSecondaryInteraction(StateMachineAction* action, InteractionEvent* event);
+ bool ExecuteInteraction(StateMachineAction* action, InteractionEvent* event);
+ bool StopInteraction(StateMachineAction* action, InteractionEvent* event);
+ bool IsInteractionPerformerNotNull(const InteractionEvent* event);
+
+ class Impl;
+ std::auto_ptr<Impl> m_Impl;
+ };
+}
+
+#endif
diff --git a/Modules/Simulation/mitkSimulationObjectFactory.cpp b/Modules/Simulation/mitkSimulationObjectFactory.cpp
index f1bbee1116..320009f7bc 100644
--- a/Modules/Simulation/mitkSimulationObjectFactory.cpp
+++ b/Modules/Simulation/mitkSimulationObjectFactory.cpp
@@ -1,135 +1,143 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkIndexROI.h"
#include "mitkSimulation.h"
#include "mitkSimulationObjectFactory.h"
#include "mitkSimulationVtkMapper3D.h"
+#include "mitkSimulationWriter.h"
#include "mitkVtkModel.h"
#include <mitkCoreObjectFactory.h>
#include <sofa/helper/system/glut.h>
#include <sofa/component/init.h>
#include <sofa/core/ObjectFactory.h>
+#include <sofa/core/visual/VisualParams.h>
#include <sofa/simulation/common/xml/initXml.h>
static void InitializeSofa()
{
int argc = 0;
glutInit(&argc, NULL);
sofa::component::init();
sofa::simulation::xml::initXml();
+
+ sofa::core::visual::VisualParams::defaultInstance()->setSupported(sofa::core::visual::API_OpenGL);
}
static void RegisterSofaClasses()
{
using sofa::core::ObjectFactory;
using sofa::core::RegisterObject;
int IndexROIClass = RegisterObject("").add<mitk::IndexROI>();
int VtkModelClass = RegisterObject("").add<mitk::VtkModel>();
ObjectFactory::AddAlias("VisualModel", "VtkModel", true);
ObjectFactory::AddAlias("OglModel", "VtkModel", true);
}
mitk::SimulationObjectFactory::SimulationObjectFactory()
- : m_SimulationIOFactory(SimulationIOFactory::New())
+ : m_SimulationIOFactory(SimulationIOFactory::New()),
+ m_SimulationWriterFactory(SimulationWriterFactory::New())
{
itk::ObjectFactoryBase::RegisterFactory(m_SimulationIOFactory);
+ itk::ObjectFactoryBase::RegisterFactory(m_SimulationWriterFactory);
+
+ m_FileWriters.push_back(SimulationWriter::New().GetPointer());
std::string description = "SOFA Scene Files";
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.scn", description));
- m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.xml", description));
InitializeSofa();
RegisterSofaClasses();
}
mitk::SimulationObjectFactory::~SimulationObjectFactory()
{
+ itk::ObjectFactoryBase::UnRegisterFactory(m_SimulationWriterFactory);
itk::ObjectFactoryBase::UnRegisterFactory(m_SimulationIOFactory);
}
mitk::Mapper::Pointer mitk::SimulationObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId slotId)
{
Mapper::Pointer mapper;
if (dynamic_cast<Simulation*>(node->GetData()) != NULL)
{
if (slotId == BaseRenderer::Standard3D)
mapper = mitk::SimulationVtkMapper3D::New();
if (mapper.IsNotNull())
mapper->SetDataNode(node);
}
return mapper;
}
const char* mitk::SimulationObjectFactory::GetDescription() const
{
return "Simulation Object Factory";
}
const char* mitk::SimulationObjectFactory::GetFileExtensions()
{
std::string fileExtensions;
this->CreateFileExtensions(m_FileExtensionsMap, fileExtensions);
return fileExtensions.c_str();
}
mitk::CoreObjectFactoryBase::MultimapType mitk::SimulationObjectFactory::GetFileExtensionsMap()
{
return m_FileExtensionsMap;
}
const char* mitk::SimulationObjectFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* mitk::SimulationObjectFactory::GetSaveFileExtensions()
{
std::string saveFileExtensions;
this->CreateFileExtensions(m_FileExtensionsMap, saveFileExtensions);
return saveFileExtensions.c_str();
}
mitk::CoreObjectFactoryBase::MultimapType mitk::SimulationObjectFactory::GetSaveFileExtensionsMap()
{
return m_SaveFileExtensionsMap;
}
void mitk::SimulationObjectFactory::SetDefaultProperties(mitk::DataNode* node)
{
if (node == NULL)
return;
if (dynamic_cast<Simulation*>(node->GetData()) != NULL)
SimulationVtkMapper3D::SetDefaultProperties(node);
}
void mitk::RegisterSimulationObjectFactory()
{
static bool alreadyRegistered = false;
if (!alreadyRegistered)
{
mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(mitk::SimulationObjectFactory::New());
alreadyRegistered = true;
}
}
diff --git a/Modules/Simulation/mitkSimulationObjectFactory.h b/Modules/Simulation/mitkSimulationObjectFactory.h
index c27cb57a43..49d4f23752 100644
--- a/Modules/Simulation/mitkSimulationObjectFactory.h
+++ b/Modules/Simulation/mitkSimulationObjectFactory.h
@@ -1,52 +1,54 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkSimulationObjectFactory_h
#define mitkSimulationObjectFactory_h
#include "mitkSimulationIOFactory.h"
+#include "mitkSimulationWriterFactory.h"
#include <mitkCoreObjectFactoryBase.h>
namespace mitk
{
class MitkSimulation_EXPORT SimulationObjectFactory : public CoreObjectFactoryBase
{
public:
mitkClassMacro(SimulationObjectFactory, CoreObjectFactoryBase);
itkFactorylessNewMacro(Self);
Mapper::Pointer CreateMapper(DataNode* node, MapperSlotId slotId);
const char* GetDescription() const;
const char* GetFileExtensions();
MultimapType GetFileExtensionsMap();
const char* GetITKSourceVersion() const;
const char* GetSaveFileExtensions();
MultimapType GetSaveFileExtensionsMap();
void SetDefaultProperties(DataNode* node);
private:
SimulationObjectFactory();
~SimulationObjectFactory();
SimulationIOFactory::Pointer m_SimulationIOFactory;
+ SimulationWriterFactory::Pointer m_SimulationWriterFactory;
MultimapType m_FileExtensionsMap;
MultimapType m_SaveFileExtensionsMap;
};
MitkSimulation_EXPORT void RegisterSimulationObjectFactory();
}
#endif
diff --git a/Modules/Simulation/mitkSimulationReader.cpp b/Modules/Simulation/mitkSimulationReader.cpp
index 4b035bafef..2738134cdd 100644
--- a/Modules/Simulation/mitkSimulationReader.cpp
+++ b/Modules/Simulation/mitkSimulationReader.cpp
@@ -1,128 +1,159 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkGetSimulationService.h"
#include "mitkISimulationService.h"
#include "mitkSimulation.h"
#include "mitkSimulationReader.h"
+#include <mitkStringProperty.h>
#include <sofa/helper/system/SetDirectory.h>
#include <algorithm>
bool mitk::SimulationReader::CanReadFile(const std::string& filename, const std::string&, const std::string&)
{
std::string::size_type length = filename.length();
if (length < 5)
return false;
std::string ext = filename.substr(length - 4);
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
if (ext == ".scn" || ext == ".xml")
return true;
return false;
}
mitk::SimulationReader::SimulationReader()
{
mitk::Simulation::Pointer output = mitk::Simulation::New();
this->SetNumberOfRequiredOutputs(1);
this->SetNthOutput(0, output.GetPointer());
}
mitk::SimulationReader::~SimulationReader()
{
}
void mitk::SimulationReader::GenerateData()
{
Simulation::Pointer simulation = static_cast<mitk::Simulation*>(this->GetOutput());
- sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation();
+ sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSOFASimulation();
ISimulationService* simulationService = GetSimulationService();
- Simulation::Pointer currentSimulation = simulationService->GetSimulation();
+ Simulation::Pointer lastActiveSimulation = simulationService->GetActiveSimulation();
- simulationService->SetSimulation(simulation);
+ simulationService->SetActiveSimulation(simulation);
+
+ std::ifstream scnFile(m_FileName.c_str());
+ std::string content = std::string((std::istreambuf_iterator<char>(scnFile)), std::istreambuf_iterator<char>());
+ scnFile.close();
+
+ std::istringstream stream(content);
+ std::string firstLine;
+
+ if (!std::getline(stream, firstLine).good())
+ mitkThrow() << "Could not load '" << m_FileName << "'!";
+
+ std::string originalPath;
+
+ if (firstLine.size() > 21 && firstLine.substr(0, 21) == "<!-- ORIGINAL_PATH = ")
+ {
+ originalPath = firstLine.substr(21);
+ sofa::helper::system::DataRepository.addFirstPath(originalPath);
+ }
std::string path = sofa::helper::system::SetDirectory::GetParentDir(m_FileName.c_str());
sofa::helper::system::DataRepository.addFirstPath(path);
sofa::simulation::Node::SPtr rootNode = sofa::core::objectmodel::SPtr_dynamic_cast<sofa::simulation::Node>(sofaSimulation->load(m_FileName.c_str()));
if (!rootNode)
{
sofa::helper::system::DataRepository.removePath(path);
mitkThrow() << "Could not load '" << m_FileName << "'!";
}
simulation->SetRootNode(rootNode);
sofaSimulation->init(rootNode.get());
sofaSimulation->reset(rootNode.get());
simulation->UpdateOutputInformation();
sofa::helper::system::DataRepository.removePath(path);
- simulationService->SetSimulation(currentSimulation);
+ if (!originalPath.empty())
+ {
+ sofa::helper::system::DataRepository.removePath(originalPath);
+ simulation->SetProperty("Path", StringProperty::New(originalPath));
+ }
+ else
+ {
+ simulation->SetProperty("Path", StringProperty::New(path));
+ }
+
+ simulation->SetProperty("Scene File", StringProperty::New(content));
+
+ simulationService->SetActiveSimulation(lastActiveSimulation);
}
void mitk::SimulationReader::GenerateOutputInformation()
{
}
const char* mitk::SimulationReader::GetFileName() const
{
return m_FileName.c_str();
}
void mitk::SimulationReader::SetFileName(const char* aFileName)
{
m_FileName = aFileName;
}
const char* mitk::SimulationReader::GetFilePattern() const
{
return m_FilePattern.c_str();
}
void mitk::SimulationReader::SetFilePattern(const char* aFilePattern)
{
m_FilePattern = aFilePattern;
}
const char* mitk::SimulationReader::GetFilePrefix() const
{
return m_FilePrefix.c_str();
}
void mitk::SimulationReader::SetFilePrefix(const char* aFilePrefix)
{
m_FilePrefix = aFilePrefix;
}
mitk::BaseDataSource::DataObjectPointer mitk::SimulationReader::MakeOutput(DataObjectPointerArraySizeType)
{
return mitk::Simulation::New().GetPointer();
}
mitk::BaseDataSource::DataObjectPointer mitk::SimulationReader::MakeOutput(const DataObjectIdentifierType& name)
{
return this->IsIndexedOutputName(name)
? this->MakeOutput(this->MakeIndexFromOutputName(name))
: mitk::Simulation::New().GetPointer();
}
diff --git a/Modules/Simulation/mitkSimulationSerializer.cpp b/Modules/Simulation/mitkSimulationSerializer.cpp
new file mode 100644
index 0000000000..d68fa48fa8
--- /dev/null
+++ b/Modules/Simulation/mitkSimulationSerializer.cpp
@@ -0,0 +1,61 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkSimulation.h"
+#include "mitkSimulationSerializer.h"
+#include "mitkSimulationWriter.h"
+
+MITK_REGISTER_SERIALIZER(SimulationSerializer)
+
+mitk::SimulationSerializer::SimulationSerializer()
+{
+}
+
+mitk::SimulationSerializer::~SimulationSerializer()
+{
+}
+
+std::string mitk::SimulationSerializer::Serialize()
+{
+ const Simulation* simulation = dynamic_cast<const Simulation*>(m_Data.GetPointer());
+
+ if (simulation == NULL)
+ {
+ MITK_ERROR << " Invalid simulation object cannot be serialized!";
+ return "";
+ }
+
+ std::string filename(this->GetUniqueFilenameInWorkingDirectory());
+ filename += "_" + m_FilenameHint + ".scn";
+
+ std::string fullPath = m_WorkingDirectory;
+ fullPath += "/" + filename;
+
+ try
+ {
+ SimulationWriter::Pointer writer = SimulationWriter::New();
+ writer->SetFileName(fullPath.c_str());
+ writer->SetInput(const_cast<Simulation*>(simulation));
+ writer->Write();
+ }
+ catch (const std::exception& e)
+ {
+ MITK_ERROR << " Error serializing simulation object to " << fullPath << ": " << e.what();
+ return "";
+ }
+
+ return filename;
+}
diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkSimulationSerializer.h
similarity index 55%
copy from Modules/Simulation/mitkSimulationService.h
copy to Modules/Simulation/mitkSimulationSerializer.h
index c8c3803fb8..1b6b573c1c 100644
--- a/Modules/Simulation/mitkSimulationService.h
+++ b/Modules/Simulation/mitkSimulationSerializer.h
@@ -1,38 +1,40 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef mitkSimulationService_h
-#define mitkSimulationService_h
+#ifndef mitkSimulationSerializer_h
+#define mitkSimulationSerializer_h
-#include <mitkISimulationService.h>
+#include <mitkBaseDataSerializer.h>
+#include <MitkSimulationExports.h>
namespace mitk
{
- class SimulationService : public ISimulationService
+ class MitkSimulation_EXPORT SimulationSerializer : public BaseDataSerializer
{
public:
- SimulationService();
- ~SimulationService();
+ mitkClassMacro(SimulationSerializer, BaseDataSerializer);
+ itkFactorylessNewMacro(Self);
+ itkCloneMacro(Self);
- Simulation::Pointer GetSimulation() const;
- void SetSimulation(Simulation::Pointer simulation);
+ std::string Serialize();
- private:
- Simulation::Pointer m_Simulation;
+ protected:
+ SimulationSerializer();
+ ~SimulationSerializer();
};
}
#endif
diff --git a/Modules/Simulation/mitkSimulationService.cpp b/Modules/Simulation/mitkSimulationService.cpp
index 41afd915cc..280870de9f 100644
--- a/Modules/Simulation/mitkSimulationService.cpp
+++ b/Modules/Simulation/mitkSimulationService.cpp
@@ -1,52 +1,62 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSimulationService.h"
#include <sofa/core/visual/VisualParams.h>
-mitk::SimulationService::SimulationService()
-{
-}
-
-mitk::SimulationService::~SimulationService()
-{
-}
-
-mitk::Simulation::Pointer mitk::SimulationService::GetSimulation() const
-{
- return m_Simulation;
-}
-
-void mitk::SimulationService::SetSimulation(Simulation::Pointer simulation)
+static void SwitchSimuluationContext(mitk::Simulation::Pointer activeSimulation)
{
- if (simulation.IsNull())
+ if (activeSimulation.IsNull())
{
sofa::simulation::setSimulation(NULL);
sofa::core::visual::VisualParams::defaultInstance()->drawTool() = NULL;
}
else
{
- sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation();
+ sofa::simulation::Simulation::SPtr sofaSimulation = activeSimulation->GetSOFASimulation();
if (sofaSimulation != sofa::simulation::getSimulation())
{
sofa::simulation::setSimulation(sofaSimulation.get());
- sofa::core::visual::VisualParams::defaultInstance()->drawTool() = simulation->GetDrawTool();
+ sofa::core::visual::VisualParams::defaultInstance()->drawTool() = activeSimulation->GetDrawTool();
}
}
+}
- m_Simulation = simulation;
+mitk::SimulationService::SimulationService()
+ : m_Scheduler(SchedulingAlgorithm::WeightedRoundRobin)
+{
+}
+
+mitk::SimulationService::~SimulationService()
+{
+}
+
+mitk::Simulation::Pointer mitk::SimulationService::GetActiveSimulation() const
+{
+ return m_ActiveSimulation;
+}
+
+void mitk::SimulationService::SetActiveSimulation(Simulation::Pointer activeSimulation)
+{
+ SwitchSimuluationContext(activeSimulation);
+ m_ActiveSimulation = activeSimulation;
+}
+
+mitk::Scheduler* mitk::SimulationService::GetScheduler()
+{
+ return &m_Scheduler;
}
diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkSimulationService.h
index c8c3803fb8..9c0796d728 100644
--- a/Modules/Simulation/mitkSimulationService.h
+++ b/Modules/Simulation/mitkSimulationService.h
@@ -1,38 +1,41 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkSimulationService_h
#define mitkSimulationService_h
#include <mitkISimulationService.h>
+#include <mitkScheduler.h>
namespace mitk
{
class SimulationService : public ISimulationService
{
public:
SimulationService();
~SimulationService();
- Simulation::Pointer GetSimulation() const;
- void SetSimulation(Simulation::Pointer simulation);
+ Simulation::Pointer GetActiveSimulation() const;
+ void SetActiveSimulation(Simulation::Pointer activeSimulation);
+ Scheduler* GetScheduler();
private:
- Simulation::Pointer m_Simulation;
+ Simulation::Pointer m_ActiveSimulation;
+ Scheduler m_Scheduler;
};
}
#endif
diff --git a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp
index ceb433bfec..718e58a7ba 100644
--- a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp
+++ b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp
@@ -1,160 +1,159 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSetVtkRendererVisitor.h"
#include "mitkSimulation.h"
#include "mitkSimulationVtkMapper3D.h"
#include "mitkVtkSimulationPolyDataMapper.h"
#include <sofa/component/visualmodel/VisualStyle.h>
#include <sofa/core/visual/VisualParams.h>
mitk::SimulationVtkMapper3D::LocalStorage::LocalStorage()
: m_Actor(vtkSmartPointer<vtkActor>::New())
{
-
}
mitk::SimulationVtkMapper3D::LocalStorage::~LocalStorage()
{
}
void mitk::SimulationVtkMapper3D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer, bool overwrite)
{
if (node != NULL)
{
Simulation* simulation = dynamic_cast<Simulation*>(node->GetData());
if (simulation != NULL)
{
sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode();
sofa::component::visualmodel::VisualStyle::SPtr visualStyle;
rootNode->get(visualStyle);
if (!visualStyle)
{
visualStyle = sofa::core::objectmodel::New<sofa::component::visualmodel::VisualStyle>();
sofa::core::visual::DisplayFlags* displayFlags = visualStyle->displayFlags.beginEdit();
displayFlags->setShowVisualModels();
visualStyle->displayFlags.endEdit();
rootNode->addObject(visualStyle);
}
const sofa::core::visual::DisplayFlags& displayFlags = visualStyle->displayFlags.getValue();
node->AddProperty("Simulation.Behavior.Behavior Models", BoolProperty::New(displayFlags.getShowBehaviorModels()), renderer, overwrite);
node->AddProperty("Simulation.Behavior.Force Fields", BoolProperty::New(displayFlags.getShowForceFields()), renderer, overwrite);
node->AddProperty("Simulation.Behavior.Interactions", BoolProperty::New(displayFlags.getShowInteractionForceFields()), renderer, overwrite);
node->AddProperty("Simulation.Collision.Bounding Trees", BoolProperty::New(displayFlags.getShowBoundingCollisionModels()), renderer, overwrite);
node->AddProperty("Simulation.Collision.Collision Models", BoolProperty::New(displayFlags.getShowCollisionModels()), renderer, overwrite);
node->AddProperty("Simulation.Mapping.Mechanical Mappings", BoolProperty::New(displayFlags.getShowMechanicalMappings()), renderer, overwrite);
node->AddProperty("Simulation.Mapping.Visual Mappings", BoolProperty::New(displayFlags.getShowMappings()), renderer, overwrite);
node->AddProperty("Simulation.Options.Normals", BoolProperty::New(displayFlags.getShowNormals()), renderer, overwrite);
node->AddProperty("Simulation.Options.Wire Frame", BoolProperty::New(displayFlags.getShowWireFrame()), renderer, overwrite);
node->AddProperty("Simulation.Visual.Visual Models", BoolProperty::New(displayFlags.getShowVisualModels() != sofa::core::visual::tristate::false_value), renderer, overwrite);
}
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
}
mitk::SimulationVtkMapper3D::SimulationVtkMapper3D()
{
}
mitk::SimulationVtkMapper3D::~SimulationVtkMapper3D()
{
}
void mitk::SimulationVtkMapper3D::ApplyColorAndOpacityProperties(vtkActor*, BaseRenderer*)
{
}
void mitk::SimulationVtkMapper3D::ApplySimulationProperties(BaseRenderer* renderer)
{
DataNode* node = this->GetDataNode();
bool showBehaviorModels;
bool showForceFields;
bool showInteractionForceFields;
bool showBoundingCollisionModels;
bool showCollisionModels;
bool showMechanicalMappings;
bool showMappings;
bool showNormals;
bool showWireFrame;
bool showVisualModels;
node->GetBoolProperty("Simulation.Behavior.Behavior Models", showBehaviorModels, renderer);
node->GetBoolProperty("Simulation.Behavior.Force Fields", showForceFields, renderer);
node->GetBoolProperty("Simulation.Behavior.Interactions", showInteractionForceFields, renderer);
node->GetBoolProperty("Simulation.Collision.Bounding Trees", showBoundingCollisionModels, renderer);
node->GetBoolProperty("Simulation.Collision.Collision Models", showCollisionModels, renderer);
node->GetBoolProperty("Simulation.Mapping.Mechanical Mappings", showMechanicalMappings, renderer);
node->GetBoolProperty("Simulation.Mapping.Visual Mappings", showMappings, renderer);
node->GetBoolProperty("Simulation.Options.Normals", showNormals, renderer);
node->GetBoolProperty("Simulation.Options.Wire Frame", showWireFrame, renderer);
node->GetBoolProperty("Simulation.Visual.Visual Models", showVisualModels, renderer);
Simulation* simulation = static_cast<Simulation*>(this->GetData());
sofa::component::visualmodel::VisualStyle::SPtr visualStyle;
simulation->GetRootNode()->get(visualStyle);
sofa::core::visual::DisplayFlags* displayFlags = visualStyle->displayFlags.beginEdit();
displayFlags->setShowBehaviorModels(showBehaviorModels);
displayFlags->setShowForceFields(showForceFields);
displayFlags->setShowInteractionForceFields(showInteractionForceFields);
displayFlags->setShowBoundingCollisionModels(showBoundingCollisionModels);
displayFlags->setShowCollisionModels(showCollisionModels);
displayFlags->setShowMechanicalMappings(showMechanicalMappings);
displayFlags->setShowMappings(showMappings);
displayFlags->setShowNormals(showNormals);
displayFlags->setShowWireFrame(showWireFrame);
displayFlags->setShowVisualModels(showVisualModels);
visualStyle->displayFlags.endEdit();
}
void mitk::SimulationVtkMapper3D::GenerateDataForRenderer(BaseRenderer* renderer)
{
Simulation* simulation = static_cast<Simulation*>(this->GetData());
if (simulation != NULL)
{
LocalStorage* localStorage = m_LocalStorageHandler.GetLocalStorage(renderer);
if (localStorage->m_Mapper == NULL)
{
localStorage->m_Mapper = vtkSmartPointer<vtkSimulationPolyDataMapper>::New();
localStorage->m_Mapper->SetSimulation(simulation);
localStorage->m_Actor->SetMapper(localStorage->m_Mapper);
SetVtkRendererVisitor initVisitor(renderer->GetVtkRenderer());
simulation->GetRootNode()->executeVisitor(&initVisitor);
}
this->ApplySimulationProperties(renderer);
}
}
vtkProp* mitk::SimulationVtkMapper3D::GetVtkProp(BaseRenderer* renderer)
{
return m_LocalStorageHandler.GetLocalStorage(renderer)->m_Actor;
}
diff --git a/Modules/Simulation/mitkSimulationWriter.cpp b/Modules/Simulation/mitkSimulationWriter.cpp
new file mode 100644
index 0000000000..91d8bcbf27
--- /dev/null
+++ b/Modules/Simulation/mitkSimulationWriter.cpp
@@ -0,0 +1,152 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkExceptionMacro.h>
+#include <mitkStringProperty.h>
+#include "mitkSimulation.h"
+#include "mitkSimulationWriter.h"
+
+mitk::SimulationWriter::SimulationWriter()
+ : m_FileExtension(".scn"),
+ m_MIMEType("application/xml")
+{
+ this->SetNumberOfRequiredInputs(1);
+ this->SetNumberOfIndexedOutputs(0);
+}
+
+mitk::SimulationWriter::~SimulationWriter()
+{
+}
+
+void mitk::SimulationWriter::GenerateData()
+{
+ if (m_FileName.empty())
+ mitkThrow() << "Filename is empty!";
+
+ Simulation* simulation = dynamic_cast<Simulation*>(this->GetInput(0));
+
+ if (simulation == NULL)
+ mitkThrow() << "Invalid input!";
+
+ std::string originalPath = "<!-- ORIGINAL_PATH = ";
+ originalPath += simulation->GetProperty("Path")->GetValueAsString();
+ originalPath += "\n This comment is parsed by MITK. -->\n";
+
+ std::ofstream scnFile(m_FileName.c_str());
+ scnFile << originalPath << simulation->GetProperty("Scene File")->GetValueAsString();
+}
+
+mitk::Simulation* mitk::SimulationWriter::GetInput()
+{
+ if (this->GetNumberOfInputs() == 0)
+ return NULL;
+
+ return dynamic_cast<Simulation*>(this->GetInput(0));
+}
+
+void mitk::SimulationWriter::SetInput(Simulation *simulation)
+{
+ this->SetNthInput(0, simulation);
+}
+
+const char* mitk::SimulationWriter::GetFileName() const
+{
+ return m_FileName.c_str();
+}
+
+void mitk::SimulationWriter::SetFileName(const char* fileName)
+{
+ m_FileName = fileName;
+}
+
+const char* mitk::SimulationWriter::GetFilePrefix() const
+{
+ return m_FilePrefix.c_str();
+}
+
+void mitk::SimulationWriter::SetFilePrefix(const char* filePrefix)
+{
+ m_FilePrefix = filePrefix;
+}
+
+const char* mitk::SimulationWriter::GetFilePattern() const
+{
+ return m_FilePattern.c_str();
+}
+
+void mitk::SimulationWriter::SetFilePattern(const char* filePattern)
+{
+ m_FilePattern = filePattern;
+}
+
+std::string mitk::SimulationWriter::GetFileExtension()
+{
+ return m_FileExtension;
+}
+
+std::vector<std::string> mitk::SimulationWriter::GetPossibleFileExtensions()
+{
+ std::vector<std::string> possibleFileExtensions;
+ possibleFileExtensions.push_back(m_FileExtension);
+ return possibleFileExtensions;
+}
+
+std::string mitk::SimulationWriter::GetWritenMIMEType()
+{
+ return m_MIMEType;
+}
+
+bool mitk::SimulationWriter::CanWriteDataType(DataNode* dataNode)
+{
+ if (dataNode == NULL)
+ return false;
+
+ return this->CanWriteBaseDataType(dataNode->GetData());
+}
+
+const char* mitk::SimulationWriter::GetDefaultFilename()
+{
+ std::string defaultFilename = "Simulation" + m_FileExtension;
+ return defaultFilename.c_str();
+}
+
+const char* mitk::SimulationWriter::GetFileDialogPattern()
+{
+ std::string fileDialogPattern = "SOFA Scene Files (*" + m_FileExtension + ")";
+ return fileDialogPattern.c_str();
+}
+
+const char* mitk::SimulationWriter::GetDefaultExtension()
+{
+ return m_FileExtension.c_str();
+}
+
+bool mitk::SimulationWriter::CanWriteBaseDataType(BaseData::Pointer data)
+{
+ if (data.IsNull())
+ return false;
+
+ return dynamic_cast<mitk::Simulation*>(data.GetPointer()) != NULL;
+}
+
+void mitk::SimulationWriter::DoWrite(BaseData::Pointer data)
+{
+ if (this->CanWriteBaseDataType(data))
+ {
+ this->SetNthInput(0, dynamic_cast<itk::DataObject*>(data.GetPointer()));
+ this->Update();
+ }
+}
diff --git a/Modules/Simulation/mitkSimulationWriter.h b/Modules/Simulation/mitkSimulationWriter.h
new file mode 100644
index 0000000000..b94aa4e4be
--- /dev/null
+++ b/Modules/Simulation/mitkSimulationWriter.h
@@ -0,0 +1,77 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef mitkSimulationWriter_h
+#define mitkSimulationWriter_h
+
+#include <mitkFileWriterWithInformation.h>
+#include <MitkSimulationExports.h>
+
+namespace mitk
+{
+ class Simulation;
+
+ class MitkSimulation_EXPORT SimulationWriter : public FileWriterWithInformation
+ {
+ public:
+ mitkClassMacro(SimulationWriter, FileWriterWithInformation);
+ itkFactorylessNewMacro(Self);
+ itkCloneMacro(Self);
+
+ using Superclass::SetInput;
+ void SetInput(Simulation* simulation);
+
+ // mitk::FileWriter interface
+
+ mitkWriterMacro;
+ using Superclass::GetInput;
+ Simulation* GetInput();
+
+ const char* GetFileName() const;
+ void SetFileName(const char* fileName);
+ const char* GetFilePrefix() const;
+ void SetFilePrefix(const char* filePrefix);
+ const char* GetFilePattern() const;
+ void SetFilePattern(const char* filePattern);
+ std::string GetFileExtension();
+ std::vector<std::string> GetPossibleFileExtensions();
+ std::string GetWritenMIMEType();
+ bool CanWriteDataType(DataNode* dataNode);
+
+ // mitk::FileWriterWithInformation interface
+
+ const char* GetDefaultFilename();
+ const char* GetFileDialogPattern();
+ const char* GetDefaultExtension();
+ bool CanWriteBaseDataType(BaseData::Pointer data);
+ void DoWrite(BaseData::Pointer data);
+
+ protected:
+ SimulationWriter();
+ ~SimulationWriter();
+
+ void GenerateData();
+
+ private:
+ std::string m_FileName;
+ std::string m_FilePrefix;
+ std::string m_FilePattern;
+ std::string m_FileExtension;
+ std::string m_MIMEType;
+ };
+}
+
+#endif
diff --git a/Modules/Simulation/mitkSimulationWriterFactory.cpp b/Modules/Simulation/mitkSimulationWriterFactory.cpp
new file mode 100644
index 0000000000..eb0b7d9f4b
--- /dev/null
+++ b/Modules/Simulation/mitkSimulationWriterFactory.cpp
@@ -0,0 +1,70 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkSimulationWriterFactory.h"
+#include <itkVersion.h>
+#include <mitkSimulationWriter.h>
+
+namespace mitk
+{
+ template <class T>
+ class CreateSimulationWriterFunction : public itk::CreateObjectFunctionBase
+ {
+ public:
+ mitkClassMacro(CreateSimulationWriterFunction, itk::CreateObjectFunctionBase);
+ itkFactorylessNewMacro(Self);
+
+ itk::LightObject::Pointer CreateObject()
+ {
+ typename T::Pointer simulationWriter = T::New();
+ simulationWriter->Register();
+ return simulationWriter.GetPointer();
+ }
+
+ protected:
+ CreateSimulationWriterFunction()
+ {
+ }
+
+ ~CreateSimulationWriterFunction()
+ {
+ }
+ };
+}
+
+mitk::SimulationWriterFactory::SimulationWriterFactory()
+{
+ this->RegisterOverride(
+ "IOWriter",
+ "SimulationWriter",
+ "SOFA scene file writer",
+ true,
+ CreateSimulationWriterFunction<SimulationWriter>::New());
+}
+
+mitk::SimulationWriterFactory::~SimulationWriterFactory()
+{
+}
+
+const char* mitk::SimulationWriterFactory::GetITKSourceVersion() const
+{
+ return ITK_SOURCE_VERSION;
+}
+
+const char* mitk::SimulationWriterFactory::GetDescription() const
+{
+ return "SimulationWriterFactory";
+}
diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkSimulationWriterFactory.h
similarity index 51%
copy from Modules/Simulation/mitkSimulationService.h
copy to Modules/Simulation/mitkSimulationWriterFactory.h
index c8c3803fb8..53f8a36421 100644
--- a/Modules/Simulation/mitkSimulationService.h
+++ b/Modules/Simulation/mitkSimulationWriterFactory.h
@@ -1,38 +1,41 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef mitkSimulationService_h
-#define mitkSimulationService_h
+#ifndef mitkSimulationWriterFactory_h
+#define mitkSimulationWriterFactory_h
-#include <mitkISimulationService.h>
+#include <itkObjectFactoryBase.h>
+#include <mitkCommon.h>
+#include <MitkSimulationExports.h>
namespace mitk
{
- class SimulationService : public ISimulationService
+ class MitkSimulation_EXPORT SimulationWriterFactory : public itk::ObjectFactoryBase
{
public:
- SimulationService();
- ~SimulationService();
+ mitkClassMacro(SimulationWriterFactory, itk::ObjectFactoryBase);
+ itkFactorylessNewMacro(Self);
- Simulation::Pointer GetSimulation() const;
- void SetSimulation(Simulation::Pointer simulation);
+ const char* GetITKSourceVersion() const;
+ const char* GetDescription() const;
- private:
- Simulation::Pointer m_Simulation;
+ protected:
+ SimulationWriterFactory();
+ ~SimulationWriterFactory();
};
}
#endif
diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp
index 57da5bf2f0..27fdb4cd97 100644
--- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp
+++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp
@@ -1,66 +1,86 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkGetSimulationService.h"
#include "mitkISimulationService.h"
#include "mitkVtkSimulationPolyDataMapper.h"
#include <sofa/core/visual/VisualParams.h>
#include <vtkObjectFactory.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
namespace mitk
{
vtkStandardNewMacro(vtkSimulationPolyDataMapper);
}
mitk::vtkSimulationPolyDataMapper::vtkSimulationPolyDataMapper()
: m_SimulationService(GetSimulationService())
{
}
mitk::vtkSimulationPolyDataMapper::~vtkSimulationPolyDataMapper()
{
}
void mitk::vtkSimulationPolyDataMapper::Render(vtkRenderer* renderer, vtkActor* actor)
{
if (renderer->GetRenderWindow()->CheckAbortStatus())
return;
if (m_Simulation.IsNull())
return;
renderer->GetRenderWindow()->MakeCurrent();
- m_SimulationService->SetSimulation(m_Simulation);
+ m_SimulationService->SetActiveSimulation(m_Simulation);
sofa::core::visual::VisualParams* vParams = sofa::core::visual::VisualParams::defaultInstance();
- sofa::simulation::Simulation::SPtr sofaSimulation = m_Simulation->GetSimulation();
+ sofa::simulation::Simulation::SPtr sofaSimulation = m_Simulation->GetSOFASimulation();
sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode();
sofaSimulation->updateVisual(rootNode.get());
sofaSimulation->draw(vParams, rootNode.get());
}
void mitk::vtkSimulationPolyDataMapper::RenderPiece(vtkRenderer*, vtkActor*)
{
}
void mitk::vtkSimulationPolyDataMapper::SetSimulation(Simulation::Pointer simulation)
{
m_Simulation = simulation;
}
+
+double* mitk::vtkSimulationPolyDataMapper::GetBounds()
+{
+ if (m_Simulation.IsNull())
+ return Superclass::GetBounds();
+
+ sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode();
+ const sofa::defaulttype::BoundingBox& bbox = rootNode->f_bbox.getValue();
+ const sofa::defaulttype::Vector3& min = bbox.minBBox();
+ const sofa::defaulttype::Vector3& max = bbox.maxBBox();
+
+ Bounds[0] = min.x();
+ Bounds[1] = max.x();
+ Bounds[2] = min.y();
+ Bounds[3] = max.y();
+ Bounds[4] = min.z();
+ Bounds[5] = max.z();
+
+ return this->Bounds;
+}
diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h
index fbfa866325..1590536318 100644
--- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h
+++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h
@@ -1,47 +1,48 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkVtkSimulationPolyDataMapper_h
#define mitkVtkSimulationPolyDataMapper_h
#include <mitkSimulation.h>
#include <vtkPolyDataMapper.h>
#include <MitkSimulationExports.h>
namespace mitk
{
class ISimulationService;
class MitkSimulation_EXPORT vtkSimulationPolyDataMapper : public vtkPolyDataMapper
{
public:
static vtkSimulationPolyDataMapper* New();
vtkTypeMacro(vtkSimulationPolyDataMapper, vtkPolyDataMapper);
+ double* GetBounds();
void Render(vtkRenderer* renderer, vtkActor* actor);
void RenderPiece(vtkRenderer*, vtkActor*);
void SetSimulation(mitk::Simulation::Pointer simulation);
private:
vtkSimulationPolyDataMapper();
~vtkSimulationPolyDataMapper();
Simulation::Pointer m_Simulation;
ISimulationService* m_SimulationService;
};
}
#endif
diff --git a/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.cpp b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.cpp
new file mode 100644
index 0000000000..2dded5961b
--- /dev/null
+++ b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.cpp
@@ -0,0 +1,60 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "mitkSchedulableProcess.h"
+#include "mitkWeightedRoundRobinSchedulingAlgorithm.h"
+#include <algorithm>
+
+static bool CompareElapsedTime(mitk::SchedulableProcess* lhs, mitk::SchedulableProcess* rhs)
+{
+ return lhs->GetElapsedTime() < rhs->GetElapsedTime();
+}
+
+mitk::WeightedRoundRobinSchedulingAlgorithm::WeightedRoundRobinSchedulingAlgorithm()
+{
+}
+
+mitk::WeightedRoundRobinSchedulingAlgorithm::~WeightedRoundRobinSchedulingAlgorithm()
+{
+}
+
+mitk::SchedulableProcess* mitk::WeightedRoundRobinSchedulingAlgorithm::GetNextProcess(std::vector<SchedulableProcess*>& processQueue)
+{
+ const double threshold = 1.5;
+ size_t numProcesses = processQueue.size();
+
+ if (numProcesses == 0)
+ return NULL;
+
+ boost::chrono::nanoseconds maxElapsedTime = (*std::max_element(processQueue.begin(), processQueue.end(), CompareElapsedTime))->GetElapsedTime();
+ mitk::SchedulableProcess* process = processQueue[0];
+
+ if (numProcesses > 1)
+ {
+ boost::chrono::nanoseconds totalElapsedTime = process->GetTotalElapsedTime();
+ boost::chrono::nanoseconds elapsedTime = process->GetElapsedTime();
+
+ if (totalElapsedTime >= maxElapsedTime || totalElapsedTime + elapsedTime >= maxElapsedTime * threshold)
+ {
+ process->ResetTotalElapsedTime();
+
+ processQueue.erase(processQueue.begin());
+ processQueue.push_back(process);
+ }
+ }
+
+ return process;
+}
diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.h
similarity index 57%
copy from Modules/Simulation/mitkSimulationService.h
copy to Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.h
index c8c3803fb8..53af49ceca 100644
--- a/Modules/Simulation/mitkSimulationService.h
+++ b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.h
@@ -1,38 +1,34 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef mitkSimulationService_h
-#define mitkSimulationService_h
+#ifndef mitkWeightedRoundRobinSchedulingAlgorithm_h
+#define mitkWeightedRoundRobinSchedulingAlgorithm_h
-#include <mitkISimulationService.h>
+#include "mitkSchedulingAlgorithmBase.h"
namespace mitk
{
- class SimulationService : public ISimulationService
+ class WeightedRoundRobinSchedulingAlgorithm : public SchedulingAlgorithmBase
{
public:
- SimulationService();
- ~SimulationService();
+ WeightedRoundRobinSchedulingAlgorithm();
+ ~WeightedRoundRobinSchedulingAlgorithm();
- Simulation::Pointer GetSimulation() const;
- void SetSimulation(Simulation::Pointer simulation);
-
- private:
- Simulation::Pointer m_Simulation;
+ SchedulableProcess* GetNextProcess(std::vector<SchedulableProcess*>& processQueue);
};
}
#endif
diff --git a/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp
index 280234f504..3f8fccd63a 100644
--- a/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp
+++ b/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp
@@ -1,88 +1,94 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkImage.h>
#include <mitkIOUtil.h>
#include <mitkComputeContourSetNormalsFilter.h>
#include <mitkSurface.h>
#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>
#include <mitkExtractSliceFilter.h>
#include <mitkPlaneGeometry.h>
+#include <vtkDebugLeaks.h>
+
class mitkComputeContourSetNormalsFilterTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkComputeContourSetNormalsFilterTestSuite);
+
+ /// \todo Fix leaks of vtkObjects. Bug 18096.
+ vtkDebugLeaks::SetExitError(0);
+
MITK_TEST(TestComputeNormals);
MITK_TEST(TestComputeNormalsWithHole);
CPPUNIT_TEST_SUITE_END();
private:
mitk::ComputeContourSetNormalsFilter::Pointer m_ContourNormalsFilter;
public:
void setUp()
{
m_ContourNormalsFilter = mitk::ComputeContourSetNormalsFilter::New();
CPPUNIT_ASSERT_MESSAGE("Failed to initialize ReduceContourSetFilter", m_ContourNormalsFilter.IsNotNull());
}
// Compute the normals for a regular contour
void TestComputeNormals()
{
mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk"));
m_ContourNormalsFilter->SetInput(contour);
m_ContourNormalsFilter->Update();
// Get the computed normals (basically lines)
mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface();
// Get the actual surface object which has the contours stored as normals internally
mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput();
mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithNormals.vtk"));
mitk::Surface::Pointer referenceNormals = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourNormals.vtk"));
CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(*(contourWithNormals->GetVtkPolyData()), *(referenceContour->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(*(normals->GetVtkPolyData()), *(referenceNormals->GetVtkPolyData()), 0.000001, true));
}
// Reduce contours with Douglas Peucker
void TestComputeNormalsWithHole()
{
mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd"));
mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/ComputeNormals/ContourWithHoles.vtk"));
m_ContourNormalsFilter->SetInput(contour);
m_ContourNormalsFilter->SetSegmentationBinaryImage(segmentationImage);
m_ContourNormalsFilter->Update();
mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput();
mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface();
mitk::Surface::Pointer contourReference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithHolesWithNormals.vtk"));
mitk::Surface::Pointer normalsReference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/NormalsWithHoles.vtk"));
CPPUNIT_ASSERT_MESSAGE("Error computing normals", mitk::Equal(*(normals->GetVtkPolyData()), *(normalsReference->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Error computing normals",
contourWithNormals->GetVtkPolyData()->GetCellData()->GetNormals()->GetNumberOfTuples() == contourReference->GetVtkPolyData()->GetNumberOfPoints());
}
};
MITK_TEST_SUITE_REGISTRATION(mitkComputeContourSetNormalsFilter)
diff --git a/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp
index fd7bef3d2c..45a2b0a1b6 100644
--- a/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp
+++ b/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp
@@ -1,134 +1,137 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkImageAccessByItk.h>
#include <mitkCreateDistanceImageFromSurfaceFilter.h>
#include <mitkIOUtil.h>
#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>
#include <mitkComputeContourSetNormalsFilter.h>
+#include <vtkDebugLeaks.h>
+
class mitkCreateDistanceImageFromSurfaceFilterTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkCreateDistanceImageFromSurfaceFilterTestSuite);
+ vtkDebugLeaks::SetExitError(0);
MITK_TEST(TestCreateDistanceImageForLiver);
MITK_TEST(TestCreateDistanceImageForTube);
CPPUNIT_TEST_SUITE_END();
private:
std::vector<mitk::Surface::Pointer> contourList;
public:
void setUp()
{
}
template<typename TPixel, unsigned int VImageDimension>
void GetImageBase(itk::Image<TPixel, VImageDimension>* input, itk::ImageBase<3>::Pointer& result)
{
result->Graft(input);
}
// Interpolate the shape of a liver
void TestCreateDistanceImageForLiver()
{
// That's the number of available liver contours in MITK-Data
unsigned int NUMBER_OF_LIVER_CONTOURS = 18;
for (unsigned int i = 0; i <= NUMBER_OF_LIVER_CONTOURS; ++i)
{
std::stringstream s;
s << "SurfaceInterpolation/InterpolateLiver/LiverContourWithNormals_";
s << i;
s << ".vtk";
mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath(s.str()));
contourList.push_back(contour);
}
mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd"));
mitk::ComputeContourSetNormalsFilter::Pointer m_NormalsFilter = mitk::ComputeContourSetNormalsFilter::New();
mitk::CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter = mitk::CreateDistanceImageFromSurfaceFilter::New();
itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();
AccessFixedDimensionByItk_1( segmentationImage, GetImageBase, 3, itkImage );
m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() );
for (unsigned int j = 0; j < contourList.size(); j++)
{
m_NormalsFilter->SetInput(j, contourList.at(j));
m_InterpolateSurfaceFilter->SetInput(j, m_NormalsFilter->GetOutput(j));
}
m_InterpolateSurfaceFilter->Update();
mitk::Image::Pointer liverDistanceImage = m_InterpolateSurfaceFilter->GetOutput();
CPPUNIT_ASSERT(liverDistanceImage.IsNotNull());
mitk::Image::Pointer liverDistanceImageReference = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverDistanceImage.nrrd"));
CPPUNIT_ASSERT_MESSAGE("LiverDistanceImages are not equal!", mitk::Equal(*(liverDistanceImageReference), *(liverDistanceImage), 0.0001, true));
}
void TestCreateDistanceImageForTube()
{
// That's the number of available contours with holes in MITK-Data
unsigned int NUMBER_OF_TUBE_CONTOURS = 5;
for (unsigned int i = 0; i < NUMBER_OF_TUBE_CONTOURS; ++i)
{
std::stringstream s;
s << "SurfaceInterpolation/InterpolateWithHoles/ContourWithHoles_";
s << i;
s << ".vtk";
mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath(s.str()));
contourList.push_back(contour);
}
mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/SegmentationWithHoles.nrrd"));
mitk::ComputeContourSetNormalsFilter::Pointer m_NormalsFilter = mitk::ComputeContourSetNormalsFilter::New();
mitk::CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter = mitk::CreateDistanceImageFromSurfaceFilter::New();
m_NormalsFilter->SetSegmentationBinaryImage(segmentationImage);
itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();
AccessFixedDimensionByItk_1( segmentationImage, GetImageBase, 3, itkImage );
m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() );
for (unsigned int j = 0; j < contourList.size(); j++)
{
m_NormalsFilter->SetInput(j, contourList.at(j));
m_InterpolateSurfaceFilter->SetInput(j, m_NormalsFilter->GetOutput(j));
}
m_InterpolateSurfaceFilter->Update();
mitk::Image::Pointer holeDistanceImage = m_InterpolateSurfaceFilter->GetOutput();
CPPUNIT_ASSERT(holeDistanceImage.IsNotNull());
mitk::Image::Pointer holesDistanceImageReference = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/HolesDistanceImage.nrrd"));
CPPUNIT_ASSERT_MESSAGE("HolesDistanceImages are not equal!", mitk::Equal(*(holesDistanceImageReference), *(holeDistanceImage), 0.0001, true));
}
};
MITK_TEST_SUITE_REGISTRATION(mitkCreateDistanceImageFromSurfaceFilter)
diff --git a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp
index 2c1e6d4f6e..0fed5cca44 100644
--- a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp
+++ b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp
@@ -1,335 +1,344 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkSurfaceInterpolationController.h>
#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>
#include <vtkRegularPolygonSource.h>
+#include <vtkDebugLeaks.h>
class mitkSurfaceInterpolationControllerTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkSurfaceInterpolationControllerTestSuite);
MITK_TEST(TestSingleton);
MITK_TEST(TestSetCurrentInterpolationSession);
MITK_TEST(TestRemoveAllInterpolationSessions);
MITK_TEST(TestRemoveInterpolationSession);
MITK_TEST(TestOnSegmentationDeleted);
+
+ /// \todo Workaround for memory leak in TestAddNewContour. Bug 18096.
+ vtkDebugLeaks::SetExitError(0);
+
MITK_TEST(TestAddNewContour);
CPPUNIT_TEST_SUITE_END();
private:
mitk::SurfaceInterpolationController::Pointer m_Controller;
public:
mitk::Image::Pointer createImage(unsigned int *dimensions)
{
mitk::Image::Pointer newImage = mitk::Image::New();
mitk::PixelType p_type = mitk::MakeScalarPixelType<unsigned char>();
newImage->Initialize(p_type, 3, dimensions);
return newImage;
}
mitk::PlaneGeometry::Pointer createPlaneForContour(mitk::BaseGeometry* geo, vtkPolyData* contour, mitk::PlaneGeometry::PlaneOrientation orientation)
{
mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
mitk::Point3D p = contour->GetPoint(0);
geo->WorldToIndex(p,p);
unsigned int sliceIndex;
if (orientation == mitk::PlaneGeometry::Axial)
{
sliceIndex = p[2];
}
else if (orientation == mitk::PlaneGeometry::Sagittal)
{
sliceIndex = p[0];
}
else
{
sliceIndex = p[1];
}
plane->InitializeStandardPlane(geo, orientation, sliceIndex, true, false);
mitk::Point3D origin = plane->GetOrigin();
mitk::Vector3D normal;
normal = plane->GetNormal();
normal.Normalize();
origin += normal * 0.5;
plane->SetOrigin(origin);
return plane;
}
void setUp()
{
m_Controller = mitk::SurfaceInterpolationController::GetInstance();
vtkSmartPointer<vtkRegularPolygonSource> polygonSource = vtkSmartPointer<vtkRegularPolygonSource>::New();
polygonSource->SetRadius(100);
polygonSource->SetNumberOfSides(7);
polygonSource->Update();
mitk::Surface::Pointer surface = mitk::Surface::New();
surface->SetVtkPolyData(polygonSource->GetOutput());
}
void TestSingleton()
{
mitk::SurfaceInterpolationController::Pointer controller2 = mitk::SurfaceInterpolationController::GetInstance();
CPPUNIT_ASSERT_MESSAGE("SurfaceInterpolationController pointers are not equal!", m_Controller.GetPointer() == controller2.GetPointer());
}
void TestSetCurrentInterpolationSession()
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
unsigned int dimensions2[] = {20, 10, 30};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
// Test 1
m_Controller->SetCurrentInterpolationSession(segmentation_1);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
// Test 2
m_Controller->SetCurrentInterpolationSession(segmentation_2);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_2->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test 3
m_Controller->SetCurrentInterpolationSession(segmentation_1);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test 4
m_Controller->SetCurrentInterpolationSession(segmentation_1);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test 5
m_Controller->SetCurrentInterpolationSession(0);
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().IsNull());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
}
void TestRemoveAllInterpolationSessions()
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
unsigned int dimensions2[] = {20, 10, 30};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
// Test 1
m_Controller->SetCurrentInterpolationSession(segmentation_1);
m_Controller->SetCurrentInterpolationSession(segmentation_2);
m_Controller->RemoveAllInterpolationSessions();
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0);
}
void TestRemoveInterpolationSession()
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
unsigned int dimensions2[] = {20, 10, 30};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
// Test 1
m_Controller->SetCurrentInterpolationSession(segmentation_1);
m_Controller->SetCurrentInterpolationSession(segmentation_2);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test current segmentation should not be null if another one was removed
m_Controller->RemoveInterpolationSession(segmentation_1);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Current segmentation is null after another one was removed", m_Controller->GetCurrentSegmentation().IsNotNull());
m_Controller->SetCurrentInterpolationSession(segmentation_1);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test current segmentation should not be null if another one was removed
m_Controller->RemoveInterpolationSession(segmentation_1);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
CPPUNIT_ASSERT_MESSAGE("Current segmentation is not null after session was removed", m_Controller->GetCurrentSegmentation().IsNull());
}
void TestOnSegmentationDeleted()
{
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
m_Controller->SetCurrentInterpolationSession(segmentation_1);
}
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0);
}
void TestAddNewContour()
{
// Create segmentation image
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
mitk::BaseGeometry* geo_1 = segmentation_1->GetGeometry();
m_Controller->SetCurrentInterpolationSession(segmentation_1);
// Create some contours
vtkSmartPointer<vtkRegularPolygonSource> p_source = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source->SetNumberOfSides(20);
p_source->SetCenter(4.0,4.0,4.0);
p_source->SetRadius(4);
p_source->SetNormal(0,1,0);
p_source->Update();
vtkPolyData* poly_1 = p_source->GetOutput();
mitk::Surface::Pointer surf_1 = mitk::Surface::New();
surf_1->SetVtkPolyData(poly_1);
vtkSmartPointer<vtkRegularPolygonSource> p_source_2 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_2->SetNumberOfSides(80);
p_source_2->SetCenter(4.0,4.0,4.0);
p_source_2->SetRadius(4);
p_source_2->SetNormal(1, 0, 0);
p_source_2->Update();
vtkPolyData* poly_2 = p_source_2->GetOutput();
mitk::Surface::Pointer surf_2 = mitk::Surface::New();
surf_2->SetVtkPolyData(poly_2);
vtkSmartPointer<vtkRegularPolygonSource> p_source_3 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_3->SetNumberOfSides(10);
p_source_3->SetCenter(4.0,4.0,3.0);
p_source_3->SetRadius(4);
p_source_3->SetNormal(0,0,1);
p_source_3->Update();
vtkPolyData* poly_3 = p_source_3->GetOutput();
mitk::Surface::Pointer surf_3 = mitk::Surface::New();
surf_3->SetVtkPolyData(poly_3);
// Create planes for contours
mitk::PlaneGeometry::Pointer plane_1 = createPlaneForContour(geo_1, poly_1, mitk::PlaneGeometry::Frontal);
mitk::PlaneGeometry::Pointer plane_2 = createPlaneForContour(geo_1, poly_2, mitk::PlaneGeometry::Sagittal);
mitk::PlaneGeometry::Pointer plane_3 = createPlaneForContour(geo_1, poly_3, mitk::PlaneGeometry::Axial);
// Add contours
m_Controller->AddNewContour(surf_1, plane_1);
m_Controller->AddNewContour(surf_2, plane_2);
m_Controller->AddNewContour(surf_3, plane_3);
// Check if all contours are there
mitk::PlaneGeometry::Pointer plane_1_clone = plane_1->Clone();
mitk::PlaneGeometry::Pointer plane_2_clone = plane_2->Clone();
mitk::PlaneGeometry::Pointer plane_3_clone = plane_3->Clone();
mitk::Surface* contour_1 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_1_clone));
mitk::Surface* contour_2 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_2_clone));
mitk::Surface* contour_3 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_3_clone));
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3);
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_1->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_2->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_3->GetVtkPolyData()), 0.000001, true));
// Create another segmentation image
unsigned int dimensions2[] = {20, 20, 20};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
mitk::BaseGeometry* geo_2 = segmentation_2->GetGeometry();
m_Controller->SetCurrentInterpolationSession(segmentation_2);
// Create some contours
- p_source->SetNumberOfSides(8);
- p_source->SetCenter(10.0,10.0,10.0);
- p_source->SetRadius(5);
- p_source->SetNormal(0,1,0);
- p_source->Update();
- vtkPolyData* poly_4 = p_source->GetOutput();
+ vtkSmartPointer<vtkRegularPolygonSource> p_source_4 = vtkSmartPointer<vtkRegularPolygonSource>::New();
+ p_source_4->SetNumberOfSides(8);
+ p_source_4->SetCenter(10.0,10.0,10.0);
+ p_source_4->SetRadius(5);
+ p_source_4->SetNormal(0,1,0);
+ p_source_4->Update();
+ vtkPolyData* poly_4 = p_source_4->GetOutput();
mitk::Surface::Pointer surf_4 = mitk::Surface::New();
surf_4->SetVtkPolyData(poly_4);
- p_source_2->SetNumberOfSides(16);
- p_source_2->SetCenter(3.0,10.0,10.0);
- p_source_2->SetRadius(8);
- p_source_2->SetNormal(1, 0, 0);
- p_source_2->Update();
- vtkPolyData* poly_5 = p_source_2->GetOutput();
+ vtkSmartPointer<vtkRegularPolygonSource> p_source_5 = vtkSmartPointer<vtkRegularPolygonSource>::New();
+ p_source_5->SetNumberOfSides(16);
+ p_source_5->SetCenter(3.0,10.0,10.0);
+ p_source_5->SetRadius(8);
+ p_source_5->SetNormal(1, 0, 0);
+ p_source_5->Update();
+ vtkPolyData* poly_5 = p_source_5->GetOutput();
mitk::Surface::Pointer surf_5 = mitk::Surface::New();
surf_5->SetVtkPolyData(poly_5);
- p_source_3->SetNumberOfSides(100);
- p_source_3->SetCenter(10.0,10.0,3.0);
- p_source_3->SetRadius(5);
- p_source_3->SetNormal(0,0,1);
- p_source_3->Update();
- vtkPolyData* poly_6 = p_source_3->GetOutput();
+ vtkSmartPointer<vtkRegularPolygonSource> p_source_6 = vtkSmartPointer<vtkRegularPolygonSource>::New();
+ p_source_6->SetNumberOfSides(100);
+ p_source_6->SetCenter(10.0,10.0,3.0);
+ p_source_6->SetRadius(5);
+ p_source_6->SetNormal(0,0,1);
+ p_source_6->Update();
+ vtkPolyData* poly_6 = p_source_6->GetOutput();
mitk::Surface::Pointer surf_6 = mitk::Surface::New();
surf_6->SetVtkPolyData(poly_6);
// Create planes for contours
mitk::PlaneGeometry::Pointer plane_4 = createPlaneForContour(geo_2, poly_4, mitk::PlaneGeometry::Frontal);
mitk::PlaneGeometry::Pointer plane_5 = createPlaneForContour(geo_2, poly_5, mitk::PlaneGeometry::Sagittal);
mitk::PlaneGeometry::Pointer plane_6 = createPlaneForContour(geo_2, poly_6, mitk::PlaneGeometry::Axial);
// Add contours
m_Controller->AddNewContour(surf_4, plane_4);
m_Controller->AddNewContour(surf_5, plane_5);
m_Controller->AddNewContour(surf_6, plane_6);
// Check if all contours are there
mitk::PlaneGeometry::Pointer plane_4_clone = plane_4->Clone();
mitk::PlaneGeometry::Pointer plane_5_clone = plane_5->Clone();
mitk::PlaneGeometry::Pointer plane_6_clone = plane_6->Clone();
mitk::Surface* contour_4 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_4_clone));
mitk::Surface* contour_5 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_5_clone));
mitk::Surface* contour_6 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_6_clone));
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3);
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_4->GetVtkPolyData()), *(contour_4->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_5->GetVtkPolyData()), *(contour_5->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_6->GetVtkPolyData()), *(contour_6->GetVtkPolyData()), 0.000001, true));
// Modify some contours
- p_source_2->SetNumberOfSides(200);
- p_source_2->SetCenter(3.0,10.0,10.0);
- p_source_2->SetRadius(5);
- p_source_2->SetNormal(1, 0, 0);
- p_source_2->Update();
- vtkPolyData* poly_7 = p_source_2->GetOutput();
+ vtkSmartPointer<vtkRegularPolygonSource> p_source_7 = vtkSmartPointer<vtkRegularPolygonSource>::New();
+ p_source_7->SetNumberOfSides(200);
+ p_source_7->SetCenter(3.0,10.0,10.0);
+ p_source_7->SetRadius(5);
+ p_source_7->SetNormal(1, 0, 0);
+ p_source_7->Update();
+ vtkPolyData* poly_7 = p_source_7->GetOutput();
mitk::Surface::Pointer surf_7 = mitk::Surface::New();
surf_7->SetVtkPolyData(poly_7);
m_Controller->AddNewContour(surf_7, plane_5);
mitk::Surface* contour_7 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_5_clone));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_7->GetVtkPolyData()), *(contour_7->GetVtkPolyData()), 0.000001, true));
// Change session and test if all contours are available
m_Controller->SetCurrentInterpolationSession(segmentation_1);
mitk::Surface* contour_8 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_1_clone));
mitk::Surface* contour_9 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_2_clone));
mitk::Surface* contour_10 = const_cast<mitk::Surface*>(m_Controller->GetContour(plane_3_clone));
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3);
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_8->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_9->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_10->GetVtkPolyData()), 0.000001, true));
}
};
MITK_TEST_SUITE_REGISTRATION(mitkSurfaceInterpolationController)
diff --git a/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp b/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp
index 487bbf7af5..162bca4c8b 100644
--- a/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp
+++ b/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp
@@ -1,502 +1,502 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkReduceContourSetFilter.h"
mitk::ReduceContourSetFilter::ReduceContourSetFilter()
{
m_MaxSegmentLenght = 0;
m_StepSize = 10;
m_Tolerance = -1;
m_ReductionType = DOUGLAS_PEUCKER;
m_MaxSpacing = -1;
m_MinSpacing = -1;
this->m_UseProgressBar = false;
this->m_ProgressStepSize = 1;
m_NumberOfPointsAfterReduction = 0;
mitk::Surface::Pointer output = mitk::Surface::New();
this->SetNthOutput(0, output.GetPointer());
}
mitk::ReduceContourSetFilter::~ReduceContourSetFilter()
{
}
void mitk::ReduceContourSetFilter::GenerateData()
{
unsigned int numberOfInputs = this->GetNumberOfIndexedInputs();
unsigned int numberOfOutputs (0);
vtkSmartPointer<vtkPolyData> newPolyData;
vtkSmartPointer<vtkCellArray> newPolygons;
vtkSmartPointer<vtkPoints> newPoints;
//For the purpose of evaluation
// unsigned int numberOfPointsBefore (0);
m_NumberOfPointsAfterReduction=0;
for(unsigned int i = 0; i < numberOfInputs; i++)
{
mitk::Surface* currentSurface = const_cast<mitk::Surface*>( this->GetInput(i) );
vtkSmartPointer<vtkPolyData> polyData = currentSurface->GetVtkPolyData();
- newPolyData = vtkPolyData::New();
- newPolygons = vtkCellArray::New();
- newPoints = vtkPoints::New();
+ newPolyData = vtkSmartPointer<vtkPolyData>::New();
+ newPolygons = vtkSmartPointer<vtkCellArray>::New();
+ newPoints = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> existingPolys = polyData->GetPolys();
vtkSmartPointer<vtkPoints> existingPoints = polyData->GetPoints();
existingPolys->InitTraversal();
vtkIdType* cell (NULL);
vtkIdType cellSize (0);
for( existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);)
{
bool incorporatePolygon = this->CheckForIntersection(cell,cellSize,existingPoints, /*numberOfIntersections, intersectionPoints, */i);
if ( !incorporatePolygon ) continue;
vtkSmartPointer<vtkPolygon> newPolygon = vtkSmartPointer<vtkPolygon>::New();
if(m_ReductionType == NTH_POINT)
{
this->ReduceNumberOfPointsByNthPoint(cellSize, cell, existingPoints, newPolygon, newPoints);
if (newPolygon->GetPointIds()->GetNumberOfIds() != 0)
{
newPolygons->InsertNextCell(newPolygon);
}
}
else if (m_ReductionType == DOUGLAS_PEUCKER)
{
this->ReduceNumberOfPointsByDouglasPeucker(cellSize, cell, existingPoints, newPolygon, newPoints);
if (newPolygon->GetPointIds()->GetNumberOfIds() > 3)
{
newPolygons->InsertNextCell(newPolygon);
}
}
//Again for evaluation
// numberOfPointsBefore += cellSize;
m_NumberOfPointsAfterReduction += newPolygon->GetPointIds()->GetNumberOfIds();
}
if (newPolygons->GetNumberOfCells() != 0)
{
newPolyData->SetPolys(newPolygons);
newPolyData->SetPoints(newPoints);
newPolyData->BuildLinks();
this->SetNumberOfIndexedOutputs(numberOfOutputs + 1);
mitk::Surface::Pointer surface = mitk::Surface::New();
this->SetNthOutput(numberOfOutputs, surface.GetPointer());
surface->SetVtkPolyData(newPolyData);
numberOfOutputs++;
}
}
// MITK_INFO<<"Points before: "<<numberOfPointsBefore<<" ##### Points after: "<<numberOfPointsAfter;
this->SetNumberOfIndexedOutputs(numberOfOutputs);
//Setting progressbar
if (this->m_UseProgressBar)
mitk::ProgressBar::GetInstance()->Progress(this->m_ProgressStepSize);
}
void mitk::ReduceContourSetFilter::ReduceNumberOfPointsByNthPoint (vtkIdType cellSize, vtkIdType* cell, vtkPoints* points, vtkPolygon* reducedPolygon, vtkPoints* reducedPoints)
{
unsigned int newNumberOfPoints (0);
unsigned int mod = cellSize%m_StepSize;
if(mod == 0)
{
newNumberOfPoints = cellSize/m_StepSize;
}
else
{
newNumberOfPoints = ( (cellSize-mod)/m_StepSize )+1;
}
if (newNumberOfPoints <= 3)
{
return;
}
reducedPolygon->GetPointIds()->SetNumberOfIds(newNumberOfPoints);
reducedPolygon->GetPoints()->SetNumberOfPoints(newNumberOfPoints);
for (vtkIdType i = 0; i < cellSize; i++)
{
if (i%m_StepSize == 0)
{
double point[3];
points->GetPoint(cell[i], point);
vtkIdType id = reducedPoints->InsertNextPoint(point);
reducedPolygon->GetPointIds()->SetId(i/m_StepSize, id);
}
}
vtkIdType id = cell[0];
double point[3];
points->GetPoint(id, point);
id = reducedPoints->InsertNextPoint(point);
reducedPolygon->GetPointIds()->SetId(newNumberOfPoints-1, id);
}
void mitk::ReduceContourSetFilter::ReduceNumberOfPointsByDouglasPeucker(vtkIdType cellSize, vtkIdType* cell, vtkPoints* points,
vtkPolygon* reducedPolygon, vtkPoints* reducedPoints)
{
//If the cell is too small to obtain a reduced polygon with the given stepsize return
if (cellSize <= static_cast<vtkIdType>(m_StepSize*3))return;
/*
What we do now is (see the Douglas Peucker Algorithm):
1. Divide the current contour in two line segments (start - middle; middle - end), put them into the stack
2. Fetch first line segment and create the following vectors:
- v1 = (start;end)
- v2 = (start;currentPoint) -> for each point of the current line segment!
3. Calculate the distance from the currentPoint to v1:
a. Determine the length of the orthogonal projection of v2 to v1 by:
l = v2 * (normalized v1)
b. There a three possibilities for the distance then:
d = sqrt(lenght(v2)^2 - l^2) if l > 0 and l < length(v1)
d = lenght(v2-v1) if l > 0 and l > lenght(v1)
d = length(v2) if l < 0 because v2 is then pointing in a different direction than v1
4. Memorize the point with the biggest distance and create two new line segments with it at the end of the iteration
and put it into the stack
5. If the distance value D <= m_Tolerance, then add the start and end index and the corresponding points to the reduced ones
*/
//First of all set tolerance if none is specified
if(m_Tolerance < 0)
{
if(m_MaxSpacing > 0)
{
m_Tolerance = m_MinSpacing;
}
else
{
m_Tolerance = 1.5;
}
}
std::stack<LineSegment> lineSegments;
//1. Divide in line segments
LineSegment ls2;
ls2.StartIndex = cell[cellSize/2];
ls2.EndIndex = cell[cellSize-1];
lineSegments.push(ls2);
LineSegment ls1;
ls1.StartIndex = cell[0];
ls1.EndIndex = cell[cellSize/2];
lineSegments.push(ls1);
LineSegment currentSegment;
double v1[3];
double v2[3];
double tempV[3];
double lenghtV1;
double currentMaxDistance (0);
vtkIdType currentMaxDistanceIndex (0);
double l;
double d;
vtkIdType pointId (0);
//Add the start index to the reduced points. From now on just the end indices will be added
pointId = reducedPoints->InsertNextPoint(points->GetPoint(cell[0]));
reducedPolygon->GetPointIds()->InsertNextId(pointId);
while (!lineSegments.empty())
{
currentSegment = lineSegments.top();
lineSegments.pop();
//2. Create vectors
points->GetPoint(currentSegment.EndIndex, tempV);
points->GetPoint(currentSegment.StartIndex, v1);
v1[0] = tempV[0]-v1[0];
v1[1] = tempV[1]-v1[1];
v1[2] = tempV[2]-v1[2];
lenghtV1 = vtkMath::Norm(v1);
vtkMath::Normalize(v1);
int range = currentSegment.EndIndex - currentSegment.StartIndex;
for (int i = 1; i < abs(range); ++i)
{
points->GetPoint(currentSegment.StartIndex+i, tempV);
points->GetPoint(currentSegment.StartIndex, v2);
v2[0] = tempV[0]-v2[0];
v2[1] = tempV[1]-v2[1];
v2[2] = tempV[2]-v2[2];
//3. Calculate the distance
l = vtkMath::Dot(v2, v1);
d = vtkMath::Norm(v2);
if (l > 0 && l < lenghtV1)
{
d = sqrt((d*d-l*l));
}
else if (l > 0 && l > lenghtV1)
{
tempV[0] = lenghtV1*v1[0] - v2[0];
tempV[1] = lenghtV1*v1[1] - v2[1];
tempV[2] = lenghtV1*v1[2] - v2[2];
d = vtkMath::Norm(tempV);
}
//4. Memorize maximum distance
if (d > currentMaxDistance)
{
currentMaxDistance = d;
currentMaxDistanceIndex = currentSegment.StartIndex+i;
}
}
//4. & 5.
if (currentMaxDistance <= m_Tolerance)
{
//double temp[3];
int segmentLenght = currentSegment.EndIndex - currentSegment.StartIndex;
if (segmentLenght > (int)m_MaxSegmentLenght)
{
m_MaxSegmentLenght = (unsigned int)segmentLenght;
}
// MITK_INFO<<"Lenght: "<<abs(segmentLenght);
if (abs(segmentLenght) > 25)
{
unsigned int newLenght(segmentLenght);
while (newLenght > 25)
{
newLenght = newLenght*0.5;
}
unsigned int divisions = abs(segmentLenght)/newLenght;
// MITK_INFO<<"Divisions: "<<divisions;
for (unsigned int i = 1; i<=divisions; ++i)
{
// MITK_INFO<<"Inserting MIDDLE: "<<(currentSegment.StartIndex + newLenght*i);
pointId = reducedPoints->InsertNextPoint(points->GetPoint(currentSegment.StartIndex + newLenght*i));
reducedPolygon->GetPointIds()->InsertNextId(pointId);
}
}
// MITK_INFO<<"Inserting END: "<<currentSegment.EndIndex;
pointId = reducedPoints->InsertNextPoint(points->GetPoint(currentSegment.EndIndex));
reducedPolygon->GetPointIds()->InsertNextId(pointId);
}
else
{
ls2.StartIndex = currentMaxDistanceIndex;
ls2.EndIndex = currentSegment.EndIndex;
lineSegments.push(ls2);
ls1.StartIndex = currentSegment.StartIndex;
ls1.EndIndex = currentMaxDistanceIndex;
lineSegments.push(ls1);
}
currentMaxDistance = 0;
}
}
bool mitk::ReduceContourSetFilter::CheckForIntersection (vtkIdType* currentCell, vtkIdType currentCellSize, vtkPoints* currentPoints,/* vtkIdType numberOfIntersections, vtkIdType* intersectionPoints,*/ unsigned int currentInputIndex)
{
/*
If we check the current cell for intersections then we have to consider three possibilies:
1. There is another cell among all the other input surfaces which intersects the current polygon:
- That means we have to save the intersection points because these points should not be eliminated
2. There current polygon exists just because of an intersection of another polygon with the current plane defined by the current polygon
- That means the current polygon should not be incorporated and all of its points should be eliminated
3. There is no intersection
- That mean we can just reduce the current polygons points without considering any intersections
*/
for (unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++)
{
//Don't check for intersection with the polygon itself
if (i == currentInputIndex) continue;
//Get the next polydata to check for intersection
vtkSmartPointer<vtkPolyData> poly = const_cast<Surface*>( this->GetInput(i) )->GetVtkPolyData();
vtkSmartPointer<vtkCellArray> polygonArray = poly->GetPolys();
polygonArray->InitTraversal();
vtkIdType anotherInputPolygonSize (0);
vtkIdType* anotherInputPolygonIDs(NULL);
/*
The procedure is:
- Create the equation of the plane, defined by the points of next input
- Calculate the distance of each point of the current polygon to the plane
- If the maximum distance is not bigger than 1.5 of the maximum spacing AND the minimal distance is not bigger
than 0.5 of the minimum spacing then the current contour is an intersection contour
*/
for( polygonArray->InitTraversal(); polygonArray->GetNextCell(anotherInputPolygonSize, anotherInputPolygonIDs);)
{
//Choosing three plane points to calculate the plane vectors
double p1[3];
double p2[3];
double p3[3];
//The plane vectors
double v1[3];
double v2[3] = { 0 };
//The plane normal
double normal[3];
//Create first Vector
poly->GetPoint(anotherInputPolygonIDs[0], p1);
poly->GetPoint(anotherInputPolygonIDs[1], p2);
v1[0] = p2[0]-p1[0];
v1[1] = p2[1]-p1[1];
v1[2] = p2[2]-p1[2];
//Find 3rd point for 2nd vector (The angle between the two plane vectors should be bigger than 30 degrees)
double maxDistance (0);
double minDistance (10000);
for (vtkIdType j = 2; j < anotherInputPolygonSize; j++)
{
poly->GetPoint(anotherInputPolygonIDs[j], p3);
v2[0] = p3[0]-p1[0];
v2[1] = p3[1]-p1[1];
v2[2] = p3[2]-p1[2];
//Calculate the angle between the two vector for the current point
double dotV1V2 = vtkMath::Dot(v1,v2);
double absV1 = sqrt(vtkMath::Dot(v1,v1));
double absV2 = sqrt(vtkMath::Dot(v2,v2));
double cosV1V2 = dotV1V2/(absV1*absV2);
double arccos = acos(cosV1V2);
double degree = vtkMath::DegreesFromRadians(arccos);
//If angle is bigger than 30 degrees break
if (degree > 30) break;
}//for (to find 3rd point)
//Calculate normal of the plane by taking the cross product of the two vectors
vtkMath::Cross(v1,v2,normal);
vtkMath::Normalize(normal);
//Determine position of the plane
double lambda = vtkMath::Dot(normal, p1);
/*
Calculate the distance to the plane for each point of the current polygon
If the distance is zero then save the currentPoint as intersection point
*/
for (vtkIdType k = 0; k < currentCellSize; k++)
{
double currentPoint[3];
currentPoints->GetPoint(currentCell[k], currentPoint);
double tempPoint[3];
tempPoint[0] = normal[0]*currentPoint[0];
tempPoint[1] = normal[1]*currentPoint[1];
tempPoint[2] = normal[2]*currentPoint[2];
double temp = tempPoint[0]+tempPoint[1]+tempPoint[2]-lambda;
double distance = fabs(temp);
if (distance > maxDistance)
{
maxDistance = distance;
}
if (distance < minDistance)
{
minDistance = distance;
}
}//for (to calculate distance and intersections with currentPolygon)
if (maxDistance < 1.5*m_MaxSpacing && minDistance < 0.5*m_MinSpacing)
{
return false;
}
//Because we are considering the plane defined by the acual input polygon only one iteration is sufficient
//We do not need to consider each cell of the plane
break;
}//for (to traverse through all cells of actualInputPolyData)
}//for (to iterate through all inputs)
return true;
}
void mitk::ReduceContourSetFilter::GenerateOutputInformation()
{
Superclass::GenerateOutputInformation();
}
void mitk::ReduceContourSetFilter::Reset()
{
for (unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++)
{
this->PopBackInput();
}
this->SetNumberOfIndexedInputs(0);
this->SetNumberOfIndexedOutputs(0);
mitk::Surface::Pointer output = mitk::Surface::New();
this->SetNthOutput(0, output.GetPointer());
m_NumberOfPointsAfterReduction = 0;
}
void mitk::ReduceContourSetFilter::SetUseProgressBar(bool status)
{
this->m_UseProgressBar = status;
}
void mitk::ReduceContourSetFilter::SetProgressStepSize(unsigned int stepSize)
{
this->m_ProgressStepSize = stepSize;
}
diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
index 420dff55aa..a6e05165b8 100644
--- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
+++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
@@ -1,366 +1,367 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSurfaceInterpolationController.h"
#include "mitkMemoryUtilities.h"
#include "mitkImageAccessByItk.h"
#include "mitkImageCast.h"
#include "mitkImageToSurfaceFilter.h"
mitk::SurfaceInterpolationController::SurfaceInterpolationController()
:m_SelectedSegmentation(0)
{
m_ReduceFilter = ReduceContourSetFilter::New();
m_NormalsFilter = ComputeContourSetNormalsFilter::New();
m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New();
m_ReduceFilter->SetUseProgressBar(false);
m_NormalsFilter->SetUseProgressBar(false);
m_InterpolateSurfaceFilter->SetUseProgressBar(false);
m_Contours = Surface::New();
m_PolyData = vtkSmartPointer<vtkPolyData>::New();
- m_PolyData->SetPoints(vtkPoints::New());
+ vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
+ m_PolyData->SetPoints(points);
m_InterpolationResult = 0;
m_CurrentNumberOfReducedContours = 0;
}
mitk::SurfaceInterpolationController::~SurfaceInterpolationController()
{
//Removing all observers
std::map<mitk::Image*, unsigned long>::iterator dataIter = m_SegmentationObserverTags.begin();
for (; dataIter != m_SegmentationObserverTags.end(); ++dataIter )
{
(*dataIter).first->RemoveObserver( (*dataIter).second );
}
m_SegmentationObserverTags.clear();
}
mitk::SurfaceInterpolationController* mitk::SurfaceInterpolationController::GetInstance()
{
- static mitk::SurfaceInterpolationController* m_Instance;
+ static mitk::SurfaceInterpolationController::Pointer m_Instance;
- if ( m_Instance == 0)
+ if ( m_Instance.IsNull() )
{
- m_Instance = new SurfaceInterpolationController();
+ m_Instance = SurfaceInterpolationController::New();
}
return m_Instance;
}
void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour, PlaneGeometry::Pointer plane)
{
ContourPositionPair pair;
pair.contour = newContour;
pair.plane = plane;
this->AddToInterpolationPipeline(pair);
this->Modified();
}
void mitk::SurfaceInterpolationController::AddNewContours(ContourPositionPairList newContours)
{
for (unsigned int i = 0; i < newContours.size(); ++i)
{
this->AddToInterpolationPipeline(newContours.at(i));
}
this->Modified();
}
void mitk::SurfaceInterpolationController::AddToInterpolationPipeline(ContourPositionPair pair)
{
int pos (-1);
ContourPositionPairList currentContourList = m_ListOfInterpolationSessions[m_SelectedSegmentation];
mitk::PlaneGeometry* plane = pair.plane;
mitk::Surface* newContour = pair.contour;
for (unsigned int i = 0; i < currentContourList.size(); i++)
{
mitk::PlaneGeometry::Pointer planeFromList = currentContourList.at(i).plane;
if ( mitk::Equal(*plane, *planeFromList, mitk::eps, false) )
{
pos = i;
break;
}
}
//Don't save a new empty contour
if (pos == -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0)
{
m_ReduceFilter->SetInput(m_ListOfInterpolationSessions[m_SelectedSegmentation].size(), newContour);
m_ListOfInterpolationSessions[m_SelectedSegmentation].push_back(pair);
}
else if (pos != -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0)
{
m_ListOfInterpolationSessions[m_SelectedSegmentation].at(pos) = pair;
m_ReduceFilter->SetInput(pos, newContour);
}
m_ReduceFilter->Update();
m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();
for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
{
m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
}
}
const mitk::Surface* mitk::SurfaceInterpolationController::GetContour(mitk::PlaneGeometry::Pointer plane)
{
ContourPositionPairList contourList = m_ListOfInterpolationSessions[m_SelectedSegmentation];
for (unsigned int i = 0; i < contourList.size(); ++i)
{
ContourPositionPair pair = contourList.at(i);
if (mitk::Equal(*plane, *pair.plane, mitk::eps, false))
return pair.contour;
}
return 0;
}
unsigned int mitk::SurfaceInterpolationController::GetNumberOfContours()
{
return m_ListOfInterpolationSessions[m_SelectedSegmentation].size();
}
void mitk::SurfaceInterpolationController::Interpolate()
{
if (m_CurrentNumberOfReducedContours< 2)
{
//If no interpolation is possible reset the interpolation result
m_InterpolationResult = 0;
return;
}
//Setting up progress bar
/*
* Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation
*/
//mitk::ProgressBar::GetInstance()->AddStepsToDo(8);
// update the filter and get teh resulting distance-image
m_InterpolateSurfaceFilter->Update();
Image::Pointer distanceImage = m_InterpolateSurfaceFilter->GetOutput();
// create a surface from the distance-image
mitk::ImageToSurfaceFilter::Pointer imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New();
imageToSurfaceFilter->SetInput( distanceImage );
imageToSurfaceFilter->SetThreshold( 0 );
imageToSurfaceFilter->SetSmooth(true);
imageToSurfaceFilter->SetSmoothIteration(20);
imageToSurfaceFilter->Update();
m_InterpolationResult = imageToSurfaceFilter->GetOutput();
vtkSmartPointer<vtkAppendPolyData> polyDataAppender = vtkSmartPointer<vtkAppendPolyData>::New();
for (unsigned int i = 0; i < m_ReduceFilter->GetNumberOfOutputs(); i++)
{
polyDataAppender->AddInputData(m_ReduceFilter->GetOutput(i)->GetVtkPolyData());
}
polyDataAppender->Update();
m_Contours->SetVtkPolyData(polyDataAppender->GetOutput());
//Last progress step
/*
* Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation
*/
//mitk::ProgressBar::GetInstance()->Progress(8);
m_InterpolationResult->DisconnectPipeline();
}
mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult()
{
return m_InterpolationResult;
}
mitk::Surface* mitk::SurfaceInterpolationController::GetContoursAsSurface()
{
return m_Contours;
}
void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage::Pointer ds)
{
m_DataStorage = ds;
}
void mitk::SurfaceInterpolationController::SetMinSpacing(double minSpacing)
{
m_ReduceFilter->SetMinSpacing(minSpacing);
}
void mitk::SurfaceInterpolationController::SetMaxSpacing(double maxSpacing)
{
m_ReduceFilter->SetMaxSpacing(maxSpacing);
m_NormalsFilter->SetMaxSpacing(maxSpacing);
}
void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume)
{
m_InterpolateSurfaceFilter->SetDistanceImageVolume(distImgVolume);
}
void mitk::SurfaceInterpolationController::SetSegmentationImage(Image* /*workingImage*/)
{
// m_NormalsFilter->SetSegmentationBinaryImage(workingImage);
}
mitk::Image::Pointer mitk::SurfaceInterpolationController::GetCurrentSegmentation()
{
return m_SelectedSegmentation;
}
mitk::Image* mitk::SurfaceInterpolationController::GetImage()
{
return m_InterpolateSurfaceFilter->GetOutput();
}
double mitk::SurfaceInterpolationController::EstimatePortionOfNeededMemory()
{
double numberOfPointsAfterReduction = m_ReduceFilter->GetNumberOfPointsAfterReduction()*3;
double sizeOfPoints = pow(numberOfPointsAfterReduction,2)*sizeof(double);
double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam();
double percentage = sizeOfPoints/totalMem;
return percentage;
}
unsigned int mitk::SurfaceInterpolationController::GetNumberOfInterpolationSessions()
{
return m_ListOfInterpolationSessions.size();
}
template<typename TPixel, unsigned int VImageDimension>
void mitk::SurfaceInterpolationController::GetImageBase(itk::Image<TPixel, VImageDimension>* input, itk::ImageBase<3>::Pointer& result)
{
result->Graft(input);
}
void mitk::SurfaceInterpolationController::SetCurrentSegmentationInterpolationList(mitk::Image::Pointer segmentation)
{
this->SetCurrentInterpolationSession(segmentation);
}
void mitk::SurfaceInterpolationController::SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage)
{
if (currentSegmentationImage.GetPointer() == m_SelectedSegmentation)
return;
m_ReduceFilter->Reset();
m_NormalsFilter->Reset();
m_InterpolateSurfaceFilter->Reset();
if (currentSegmentationImage.IsNull())
{
m_SelectedSegmentation = 0;
return;
}
ContourListMap::iterator it = m_ListOfInterpolationSessions.find(currentSegmentationImage.GetPointer());
m_SelectedSegmentation = currentSegmentationImage.GetPointer();
itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();
AccessFixedDimensionByItk_1( m_SelectedSegmentation, GetImageBase, 3, itkImage );
m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() );
if (it == m_ListOfInterpolationSessions.end())
{
ContourPositionPairList newList;
m_ListOfInterpolationSessions.insert(std::pair<mitk::Image*, ContourPositionPairList>(m_SelectedSegmentation, newList));
m_InterpolationResult = 0;
m_CurrentNumberOfReducedContours = 0;
itk::MemberCommand<SurfaceInterpolationController>::Pointer command = itk::MemberCommand<SurfaceInterpolationController>::New();
command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted);
m_SegmentationObserverTags.insert( std::pair<mitk::Image*, unsigned long>( m_SelectedSegmentation, m_SelectedSegmentation->AddObserver( itk::DeleteEvent(), command ) ) );
}
else
{
for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++)
{
m_ReduceFilter->SetInput(i, m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour);
}
m_ReduceFilter->Update();
m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();
for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
{
m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
}
}
Modified();
}
void mitk::SurfaceInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation)
{
this->RemoveInterpolationSession(segmentation);
}
void mitk::SurfaceInterpolationController::RemoveInterpolationSession(mitk::Image::Pointer segmentationImage)
{
if (segmentationImage)
{
if (m_SelectedSegmentation == segmentationImage)
{
SetSegmentationImage(NULL);
m_SelectedSegmentation = 0;
}
m_ListOfInterpolationSessions.erase(segmentationImage);
// Remove observer
std::map<mitk::Image*, unsigned long>::iterator pos = m_SegmentationObserverTags.find(segmentationImage);
if (pos != m_SegmentationObserverTags.end())
{
segmentationImage->RemoveObserver((*pos).second);
m_SegmentationObserverTags.erase(pos);
}
}
}
void mitk::SurfaceInterpolationController::RemoveAllInterpolationSessions()
{
//Removing all observers
std::map<mitk::Image*, unsigned long>::iterator dataIter = m_SegmentationObserverTags.begin();
while (dataIter != m_SegmentationObserverTags.end())
{
mitk::Image* image = (*dataIter).first;
image->RemoveObserver((*dataIter).second);
++dataIter;
}
m_SegmentationObserverTags.clear();
m_SelectedSegmentation = 0;
m_ListOfInterpolationSessions.clear();
}
void mitk::SurfaceInterpolationController::OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &/*event*/)
{
mitk::Image* tempImage = dynamic_cast<mitk::Image*>(const_cast<itk::Object*>(caller));
if (tempImage)
{
if (m_SelectedSegmentation == tempImage)
{
SetSegmentationImage(NULL);
m_SelectedSegmentation = 0;
}
m_SegmentationObserverTags.erase(tempImage);
m_ListOfInterpolationSessions.erase(tempImage);
}
}
diff --git a/Modules/ToFProcessing/Testing/files.cmake b/Modules/ToFProcessing/Testing/files.cmake
index d95e12125e..56bcb0184b 100644
--- a/Modules/ToFProcessing/Testing/files.cmake
+++ b/Modules/ToFProcessing/Testing/files.cmake
@@ -1,11 +1,11 @@
set(MODULE_TESTS
mitkToFDistanceImageToPointSetFilterTest.cpp
mitkToFDistanceImageToSurfaceFilterTest.cpp
- #mitkToFCompositeFilterTest.cpp
+ mitkToFCompositeFilterTest.cpp
mitkToFProcessingCommonTest.cpp
)
set(MODULE_CUSTOM_TESTS
#mitkToFImageDownsamplingFilterTest.cpp
mitkKinectReconstructionTest.cpp
)
diff --git a/Modules/ToFProcessing/Testing/mitkToFCompositeFilterTest.cpp b/Modules/ToFProcessing/Testing/mitkToFCompositeFilterTest.cpp
index a04b4e4cf2..da3ef2995c 100644
--- a/Modules/ToFProcessing/Testing/mitkToFCompositeFilterTest.cpp
+++ b/Modules/ToFProcessing/Testing/mitkToFCompositeFilterTest.cpp
@@ -1,380 +1,350 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkToFCompositeFilter.h>
#include <mitkImage.h>
#include <mitkImageCast.h>
#include <itkBilateralImageFilter.h>
#include <mitkToFProcessingCommon.h>
#include <itkThresholdImageFilter.h>
#include <itkImageRegionIterator.h>
#include <itkMersenneTwisterRandomVariateGenerator.h>
#include <mitkToFCompositeFilter.h>
#include <itkMedianImageFilter.h>
#include <mitkImagePixelReadAccessor.h>
/**Documentation
* \brief test for the class "ToFCompositeFilter".
*
* Manually create filter pipeline and check if it is equivalent to composite filter
*/
typedef mitk::ToFProcessingCommon::ToFPoint2D ToFPoint2D;
-typedef mitk::ToFProcessingCommon::ToFScalarType ToFScalarType;
+typedef float ToFScalarType;
typedef itk::Image<ToFScalarType,2> ItkImageType_2D;
typedef itk::Image<ToFScalarType,3> ItkImageType_3D;
typedef itk::ImageRegionIterator<ItkImageType_2D> ItkImageRegionIteratorType2D;
typedef itk::ImageRegionIterator<ItkImageType_3D> ItkImageRegionIteratorType3D;
typedef itk::BilateralImageFilter<ItkImageType_2D,ItkImageType_2D> BilateralImageFilterType;
typedef itk::ThresholdImageFilter<ItkImageType_2D> ThresholdFilterType;
typedef itk::MedianImageFilter<ItkImageType_2D,ItkImageType_2D> MedianFilterType;
static bool ApplyTemporalMedianFilter(mitk::Image::Pointer& image, ItkImageType_2D::Pointer& itkImage2D)
{
//initialize ITK output image
unsigned int dimX = image->GetDimension(0);
unsigned int dimY = image->GetDimension(1);
unsigned int nbSlices = image->GetDimension(2);
ItkImageType_2D::SizeType size;
size[0] = dimX;
size[1] = dimY;
ItkImageType_2D::RegionType region;
region.SetSize(size);
ItkImageType_2D::SpacingType spacing;
spacing[0] = 1.0;
spacing[1] = 1.0;
itkImage2D->SetRegions( region );
itkImage2D->SetSpacing ( spacing );
itkImage2D->Allocate();
//initialize median filtering
std::vector<ToFScalarType> allDistances;
itk::Index<3> curIdx3D;
ItkImageType_2D::IndexType curIdx2D;
//compute median over time for each (x,y)
for(unsigned int i = 0; i<dimX; i++)
{
for(unsigned int j = 0; j < dimY; j++)
{
allDistances.clear();
curIdx3D[0] = i; curIdx3D[1] = j;
curIdx2D[0] = i; curIdx2D[1] = j;
//gather all distances for one pixel
mitk::ImagePixelReadAccessor<ToFScalarType,3> imageAcces(image, image->GetVolumeData());
for(unsigned int k = 0; k < nbSlices; k++)
{
curIdx3D[2] = k;
allDistances.push_back(imageAcces.GetPixelByIndex(curIdx3D));
}
//sort distances and compute median
std::sort(allDistances.begin(),allDistances.end());
unsigned int median_idx = nbSlices/2;
if(nbSlices%2 == 1) //i.e., there is an odd number of slices
{
itkImage2D->SetPixel(curIdx2D,allDistances[median_idx]);
} else
{
ToFScalarType upper = allDistances[median_idx];
ToFScalarType lower = allDistances[median_idx+1];
itkImage2D->SetPixel(curIdx2D,(upper+lower)/2.0);
}
}
}
return true;
}
-static bool CompareImages(mitk::Image::Pointer image1, mitk::Image::Pointer image2)
-{
-
- unsigned int dimX = image1->GetDimension(0);
- unsigned int dimY = image1->GetDimension(1);
-
- //make sure images have the same dimensions
- if((dimX != image1->GetDimension(0)) || (dimY != image1->GetDimension(1)))
- return false;
-
- //compare all pixel values
- mitk::ImagePixelReadAccessor<ToFScalarType,2> image1Acces(image1, image1->GetSliceData(0));
- mitk::ImagePixelReadAccessor<ToFScalarType,2> image2Acces(image2, image2->GetSliceData(0));
- for(unsigned int i = 0; i<dimX; i++)
- {
- for(unsigned int j = 0; j < dimY; j++)
- {
- itk::Index<2> idx;
- idx[0] = i; idx[1] = j;
- if(!(mitk::Equal(image1Acces.GetPixelByIndex(idx), image2Acces.GetPixelByIndex(idx))))
- {
- return false;
- }
-
- }
- }
-
- //all pixels have identical values
- return true;
-}
-
bool CreateRandomDistanceImage(unsigned int dimX, unsigned int dimY, ItkImageType_2D::Pointer& itkImage, mitk::Image::Pointer& mitkImage) //TODO warum ITK image?
{
//initialize ITK output image
ItkImageType_2D::IndexType start;
start[0] = 0;
start[1] = 0;
ItkImageType_2D::SizeType size;
size[0] = dimX;
size[1] = dimY;
ItkImageType_2D::RegionType region;
region.SetSize(size);
region.SetIndex( start);
ItkImageType_2D::SpacingType spacing;
spacing[0] = 1.0;
spacing[1] = 1.0;
itkImage->SetRegions( region );
itkImage->SetSpacing ( spacing );
itkImage->Allocate();
ItkImageRegionIteratorType2D imageIterator(itkImage,itkImage->GetLargestPossibleRegion());
imageIterator.GoToBegin();
itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
while (!imageIterator.IsAtEnd())
{
ToFScalarType pixelValue = randomGenerator->GetUniformVariate(0.0,1000.0);
imageIterator.Set(pixelValue);
++imageIterator;
}
mitk::CastToMitkImage(itkImage,mitkImage);
return true;
}
bool CreateRandomDistanceImageStack(unsigned int dimX, unsigned int dimY, unsigned int nbSlices, ItkImageType_3D::Pointer& itkImage, mitk::Image::Pointer& mitkImage)
{
//initialize ITK output image
ItkImageType_3D::IndexType start;
start[0] = 0;
start[1] = 0;
start[1] = 0;
ItkImageType_3D::SizeType size;
size[0] = dimX;
size[1] = dimY;
size[2] = nbSlices;
ItkImageType_3D::RegionType region;
region.SetSize(size);
region.SetIndex( start);
ItkImageType_3D::SpacingType spacing;
spacing[0] = 1.0;
spacing[1] = 1.0;
spacing[2] = 1.0;
itkImage->SetRegions( region );
itkImage->SetSpacing ( spacing );
itkImage->Allocate();
//assign random pixel values
ItkImageRegionIteratorType3D imageIterator(itkImage,itkImage->GetLargestPossibleRegion());
imageIterator.GoToBegin();
itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
while (!imageIterator.IsAtEnd())
{
ToFScalarType pixelValue = randomGenerator->GetUniformVariate(0.0,1000.0);
imageIterator.Set(pixelValue);
++imageIterator;
}
//cast to MITK image
mitk::CastToMitkImage(itkImage,mitkImage);
return true;
}
int mitkToFCompositeFilterTest(int /* argc */, char* /*argv*/[])
{
MITK_TEST_BEGIN("ToFCompositeFilter");
//initialize composite filter
mitk::ToFCompositeFilter::Pointer compositeFilter = mitk::ToFCompositeFilter::New();
//Initialize threshold filter
ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New();
int threshold_min = 5;
int threshold_max = 100;
thresholdFilter->SetOutsideValue(0.0);
thresholdFilter->SetLower(threshold_min);
thresholdFilter->SetUpper(threshold_max);
compositeFilter->SetThresholdFilterParameter(threshold_min, threshold_max);
//Initialize spatial median filter
MedianFilterType::Pointer medianFilter = MedianFilterType::New();
//Initialize bilateral filter
BilateralImageFilterType::Pointer bilateralFilter = BilateralImageFilterType::New();
float domainSigma = 4;
float rangeSigma = 50;
float kernelRadius = 3;
bilateralFilter->SetDomainSigma(domainSigma);
bilateralFilter->SetRangeSigma(rangeSigma);
bilateralFilter->SetRadius(kernelRadius);
compositeFilter->SetBilateralFilterParameter(domainSigma,rangeSigma,kernelRadius);
//Initialize pipeline
ItkImageType_2D::Pointer itkInputImage = ItkImageType_2D::New();
mitk::Image::Pointer mitkInputImage = mitk::Image::New();
CreateRandomDistanceImage(100,100,itkInputImage,mitkInputImage);
ItkImageType_2D::Pointer itkOutputImage;
compositeFilter->SetInput(mitkInputImage);
mitk::Image::Pointer mitkOutputImage = compositeFilter->GetOutput();
//-------------------------------------------------------------------------------------------------------
//Apply first filter only (threshold)
//standard variant
thresholdFilter->SetInput(itkInputImage);
itkOutputImage = thresholdFilter->GetOutput();
itkOutputImage->Update();
//variant with composite filter
compositeFilter->SetApplyThresholdFilter(true);
compositeFilter->SetApplyMedianFilter(false);
compositeFilter->SetApplyTemporalMedianFilter(false);
compositeFilter->SetApplyBilateralFilter(false);
mitkOutputImage->Update();
//compare output
mitk::Image::Pointer itkOutputImageConverted;
mitk::CastToMitkImage(itkOutputImage,itkOutputImageConverted);
- bool pipelineSuccess = CompareImages(itkOutputImageConverted,mitkOutputImage);
- MITK_TEST_CONDITION_REQUIRED(pipelineSuccess,"Test threshold filter in pipeline");
+ MITK_TEST_CONDITION_REQUIRED( mitk::Equal(itkOutputImageConverted,mitkOutputImage,mitk::eps,true),
+ "Test threshold filter in pipeline");
//-------------------------------------------------------------------------------------------------------
//Apply first and second filter
//standard variant
medianFilter->SetInput(thresholdFilter->GetOutput());
itkOutputImage = medianFilter->GetOutput();
itkOutputImage->Update();
//variant with composite filter
compositeFilter->SetApplyMedianFilter(true);
mitkOutputImage->Update();
//compare output
mitk::CastToMitkImage(itkOutputImage,itkOutputImageConverted);
- pipelineSuccess = CompareImages(itkOutputImageConverted,mitkOutputImage);
- MITK_TEST_CONDITION_REQUIRED(pipelineSuccess,"Test threshold and median filter in pipeline");
+ MITK_TEST_CONDITION_REQUIRED( mitk::Equal(itkOutputImageConverted,mitkOutputImage,mitk::eps,true),
+ "Test threshold and median filter in pipeline");
//-------------------------------------------------------------------------------------------------------
//Apply first three filters
//standard variant
bilateralFilter->SetInput(medianFilter->GetOutput());
itkOutputImage = bilateralFilter->GetOutput();
itkOutputImage->Update();
//variant with composite filter
compositeFilter->SetApplyBilateralFilter(true);
mitkOutputImage->Update();
//compare output
mitk::CastToMitkImage(itkOutputImage,itkOutputImageConverted);
- pipelineSuccess = CompareImages(itkOutputImageConverted,mitkOutputImage);
- MITK_TEST_CONDITION_REQUIRED(pipelineSuccess,"Test threshold filter, bilateral filter and temporal median filter in pipeline");
+ MITK_TEST_CONDITION_REQUIRED( mitk::Equal(itkOutputImageConverted,mitkOutputImage,mitk::eps,true),
+ "Test threshold filter, bilateral filter and temporal median filter in pipeline");
//-------------------------------------------------------------------------------------------------------
+ // TODO: Rewrite this. This don't make sense. the itk reference applies a median filter
+ // and threshold filter afterwards. The composite filter does it in the other directtion.
+ // also the input of random image stacks is never set into the composite filter
//Apply all filters
//generate image stack
- ItkImageType_3D::Pointer itkInputImage3D = ItkImageType_3D::New();
- mitk::Image::Pointer mitkImage3D = mitk::Image::New();
- CreateRandomDistanceImageStack(100,100,12,itkInputImage3D,mitkImage3D);
-
- //standard variant
- ItkImageType_2D::Pointer medianFilteredImage = ItkImageType_2D::New();
- ApplyTemporalMedianFilter(mitkImage3D,medianFilteredImage);
- thresholdFilter->SetInput(medianFilteredImage);
- itkOutputImage->Update();
-
- //variant with composite filter
- compositeFilter->SetApplyTemporalMedianFilter(true);
- mitkOutputImage->Update();
-
- //compare output
- mitk::CastToMitkImage(itkOutputImage,itkOutputImageConverted);
- pipelineSuccess = CompareImages(itkOutputImageConverted,mitkOutputImage);
- MITK_TEST_CONDITION_REQUIRED(pipelineSuccess,"Test all filters in pipeline");
+// ItkImageType_3D::Pointer itkInputImage3D = ItkImageType_3D::New();
+// mitk::Image::Pointer mitkImage3D = mitk::Image::New();
+// CreateRandomDistanceImageStack(100,100,12,itkInputImage3D,mitkImage3D);
+//
+// //standard variant
+// ItkImageType_2D::Pointer medianFilteredImage = ItkImageType_2D::New();
+// ApplyTemporalMedianFilter(mitkImage3D,medianFilteredImage);
+// thresholdFilter->SetInput(medianFilteredImage);
+// itkOutputImage->Update();
+//
+// //variant with composite filter
+// compositeFilter->SetApplyTemporalMedianFilter(true);
+// mitkOutputImage->Update();
+//
+// //compare output
+// mitk::CastToMitkImage(itkOutputImage,itkOutputImageConverted);
+// pipelineSuccess = CompareImages(itkOutputImageConverted,mitkOutputImage);
+// MITK_TEST_CONDITION_REQUIRED(pipelineSuccess,"Test all filters in pipeline");
//-------------------------------------------------------------------------------------------------------
//Check set/get functions
mitk::Image::Pointer newImage = mitk::Image::New();
mitk::Image::Pointer returnedImage;
compositeFilter->SetInput(newImage);
returnedImage = compositeFilter->GetInput();
MITK_TEST_CONDITION_REQUIRED(newImage == returnedImage,"Get/Set empty image");
compositeFilter->SetApplyTemporalMedianFilter(false);
MITK_TEST_CONDITION_REQUIRED(compositeFilter->GetApplyTemporalMedianFilter()==false,"Get/Set ApplyTemporalMedianFilter");
compositeFilter->SetApplyMedianFilter(false);
MITK_TEST_CONDITION_REQUIRED(compositeFilter->GetApplyMedianFilter()==false,"Get/Set ApplyMedianFilter");
compositeFilter->SetApplyThresholdFilter(false);
MITK_TEST_CONDITION_REQUIRED(compositeFilter->GetApplyThresholdFilter()==false,"Get/Set ApplyThresholdFilter");
compositeFilter->SetApplyBilateralFilter(false);
MITK_TEST_CONDITION_REQUIRED(compositeFilter->GetApplyBilateralFilter()==false,"Get/Set ApplyBilateralFilter");
//-------------------------------------------------------------------------------------------------------
MITK_TEST_END();
}
-
-
diff --git a/Modules/ToFUI/CMakeLists.txt b/Modules/ToFUI/CMakeLists.txt
index 30a3150377..c42c0e2e76 100644
--- a/Modules/ToFUI/CMakeLists.txt
+++ b/Modules/ToFUI/CMakeLists.txt
@@ -1,7 +1,7 @@
MITK_CREATE_MODULE(
SUBPROJECTS MITK-ToF
INCLUDE_DIRS Qmitk
- DEPENDS MitkToFHardware MitkToFProcessing MitkQtWidgetsExt MitkOverlays
+ DEPENDS MitkToFHardware MitkToFProcessing MitkQtWidgetsExt
GENERATED_CPP ${TOOL_GUI_CPPS} ${TOOL_CPPS}
)
diff --git a/Modules/ToFUI/Qmitk/QmitkToFPointSetWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFPointSetWidget.cpp
index 87a199a91f..4055497ed9 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFPointSetWidget.cpp
+++ b/Modules/ToFUI/Qmitk/QmitkToFPointSetWidget.cpp
@@ -1,437 +1,435 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkToFPointSetWidget.h"
-#include <QmitkTextOverlay.h>
-
#include <mitkGlobalInteraction.h>
#include <mitkVtkLayerController.h>
#include <vtkTextProperty.h>
const std::string QmitkToFPointSetWidget::VIEW_ID = "org.mitk.views.qmitktofpointsetwidget";
QmitkToFPointSetWidget::QmitkToFPointSetWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
, m_DataStorage(NULL)
, m_DistanceImage(NULL)
, m_CameraIntrinsics(NULL)
, m_VtkTextActor(NULL)
, m_ForegroundRenderer1(NULL)
, m_ForegroundRenderer2(NULL)
, m_ForegroundRenderer3(NULL)
, m_RenderWindow1(NULL)
, m_RenderWindow2(NULL)
, m_RenderWindow3(NULL)
, m_MeasurementPointSet2D(NULL)
, m_MeasurementPointSet3DNode(NULL)
, m_PointSet2D(NULL)
, m_PointSet3DNode(NULL)
, m_PointSetInteractor(NULL)
, m_MeasurementPointSetInteractor(NULL)
, m_MeasurementPointSetChangedObserverTag(0)
, m_PointSetChangedObserverTag(0)
, m_WindowHeight(0)
{
m_Controls = NULL;
CreateQtPartControl(this);
}
QmitkToFPointSetWidget::~QmitkToFPointSetWidget()
{
this->CleanUpWidget();
}
void QmitkToFPointSetWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkToFPointSetWidgetControls;
m_Controls->setupUi(parent);
this->CreateConnections();
}
}
void QmitkToFPointSetWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->measureButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnMeasurement()) );
connect( (QObject*)(m_Controls->pointSetButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPointSet()) );
}
}
void QmitkToFPointSetWidget::InitializeWidget(QHash<QString, QmitkRenderWindow*> renderWindowHashMap, mitk::DataStorage::Pointer dataStorage, mitk::CameraIntrinsics::Pointer cameraIntrinsics)
{
// initialize members
m_CameraIntrinsics = cameraIntrinsics;
m_DataStorage = dataStorage;
// m_RenderWindowPart = renderWindowPart;
m_RenderWindow1 = renderWindowHashMap.value("axial")->GetRenderWindow();
m_RenderWindow2 = renderWindowHashMap.value("sagittal")->GetRenderWindow();
m_RenderWindow3 = renderWindowHashMap.value("coronal")->GetRenderWindow();
m_RenderWindow4 = renderWindowHashMap.value("3d")->GetRenderWindow();
if ((m_RenderWindow1 != NULL) && (m_RenderWindow2 != NULL) && (m_RenderWindow3 != NULL) && (m_RenderWindow4 != NULL) && (dataStorage.IsNotNull()))
{
// enable buttons
m_Controls->pointSetButton->setEnabled(true);
m_Controls->measureButton->setEnabled(true);
// initialize overlays
this->m_VtkTextActor = vtkSmartPointer<vtkTextActor>::New();
this->m_VtkTextActor->SetInput("Choose measurement points with SHIFT+Click");
m_WindowHeight = renderWindowHashMap.value("axial")->GetRenderer()->GetSizeY();
this->m_VtkTextActor->SetDisplayPosition(10,m_WindowHeight-30);
this->m_VtkTextActor->GetTextProperty()->SetFontSize(16);
// this->m_VtkTextActor->GetTextProperty()->SetColor(1,0,0);
this->m_VtkTextActor->GetTextProperty()->BoldOn();
this->m_VtkTextActor->SetVisibility(0);
if (m_ForegroundRenderer1==NULL)
{
this->m_ForegroundRenderer1 = vtkSmartPointer<vtkRenderer>::New();
this->m_ForegroundRenderer1->AddActor(m_VtkTextActor);
mitk::VtkLayerController::GetInstance(m_RenderWindow1)->InsertForegroundRenderer(m_ForegroundRenderer1,true);
}
if (m_ForegroundRenderer2==NULL)
{
this->m_ForegroundRenderer2 = vtkSmartPointer<vtkRenderer>::New();
this->m_ForegroundRenderer2->AddActor(m_VtkTextActor);
mitk::VtkLayerController::GetInstance(m_RenderWindow2)->InsertForegroundRenderer(m_ForegroundRenderer2,true);
}
if (m_ForegroundRenderer3==NULL)
{
this->m_ForegroundRenderer3 =vtkSmartPointer<vtkRenderer>::New();
this->m_ForegroundRenderer3->AddActor(m_VtkTextActor);
mitk::VtkLayerController::GetInstance(m_RenderWindow3)->InsertForegroundRenderer(m_ForegroundRenderer3,true);
}
mitk::DataNode::Pointer measurementPointSet2DNode = dataStorage->GetNamedNode("Measurement PointSet 2D") ;
if(dataStorage->Exists(measurementPointSet2DNode))
{
dataStorage->Remove(measurementPointSet2DNode);
}
// initialize 2D measurement point set
m_MeasurementPointSet2D = mitk::PointSet::New();
measurementPointSet2DNode = mitk::DataNode::New();
measurementPointSet2DNode->SetName("Measurement PointSet 2D");
measurementPointSet2DNode->SetBoolProperty("helper object",true);
measurementPointSet2DNode->SetBoolProperty("show contour",true);
measurementPointSet2DNode->SetVisibility(false, renderWindowHashMap.value("3d")->GetRenderer());
measurementPointSet2DNode->SetData(m_MeasurementPointSet2D);
dataStorage->Add(measurementPointSet2DNode);
m_MeasurementPointSetInteractor = mitk::PointSetInteractor::New("pointsetinteractor",measurementPointSet2DNode,2);
// create observer for m_MeasurementPointSet2D
itk::SimpleMemberCommand<QmitkToFPointSetWidget>::Pointer measurementPointSetChangedCommand;
measurementPointSetChangedCommand = itk::SimpleMemberCommand<QmitkToFPointSetWidget>::New();
measurementPointSetChangedCommand->SetCallbackFunction(this, &QmitkToFPointSetWidget::MeasurementPointSetChanged);
m_MeasurementPointSetChangedObserverTag = m_MeasurementPointSet2D->AddObserver(itk::ModifiedEvent(), measurementPointSetChangedCommand);
// initialize 3D measurement PointSet
m_MeasurementPointSet3DNode = dataStorage->GetNamedNode("Measurement PointSet 3D");
if(dataStorage->Exists(m_MeasurementPointSet3DNode))
{
dataStorage->Remove(m_MeasurementPointSet3DNode);
}
m_MeasurementPointSet3DNode = mitk::DataNode::New();
m_MeasurementPointSet3DNode->SetName("Measurement PointSet 3D");
m_MeasurementPointSet3DNode->SetBoolProperty("helper object",true);
m_MeasurementPointSet3DNode->SetBoolProperty("show contour",true);
m_MeasurementPointSet3DNode->SetFloatProperty("pointsize",5.0f);
mitk::PointSet::Pointer measurementPointSet3D = mitk::PointSet::New();
m_MeasurementPointSet3DNode->SetData(measurementPointSet3D);
dataStorage->Add(m_MeasurementPointSet3DNode);
// initialize PointSets
mitk::DataNode::Pointer pointSet2DNode = dataStorage->GetNamedNode("ToF PointSet 2D") ;
if(dataStorage->Exists(pointSet2DNode))
{
dataStorage->Remove(pointSet2DNode);
}
m_PointSet2D = mitk::PointSet::New();
pointSet2DNode = mitk::DataNode::New();
pointSet2DNode->SetName("ToF PointSet 2D");
pointSet2DNode->SetVisibility(false, renderWindowHashMap.value("3d")->GetRenderer());
pointSet2DNode->SetData(m_PointSet2D);
dataStorage->Add(pointSet2DNode);
m_PointSetInteractor = mitk::PointSetInteractor::New("pointsetinteractor",pointSet2DNode);
// create observer for m_MeasurementPointSet2D
itk::SimpleMemberCommand<QmitkToFPointSetWidget>::Pointer pointSetChangedCommand;
pointSetChangedCommand = itk::SimpleMemberCommand<QmitkToFPointSetWidget>::New();
pointSetChangedCommand->SetCallbackFunction(this, &QmitkToFPointSetWidget::PointSetChanged);
m_PointSetChangedObserverTag = m_PointSet2D->AddObserver(itk::ModifiedEvent(), pointSetChangedCommand);
// initialize 3D point set
mitk::DataNode::Pointer pointSet3DNode = dataStorage->GetNamedNode("ToF PointSet 3D");
if(dataStorage->Exists(pointSet3DNode))
{
dataStorage->Remove(pointSet3DNode);
}
m_PointSet3DNode = mitk::DataNode::New();
m_PointSet3DNode->SetName("ToF PointSet 3D");
m_PointSet3DNode->SetFloatProperty("pointsize",5.0f);
mitk::PointSet::Pointer pointSet3D = mitk::PointSet::New();
m_PointSet3DNode->SetData(pointSet3D);
dataStorage->Add(m_PointSet3DNode);
}
}
void QmitkToFPointSetWidget::CleanUpWidget()
{
// toggle button state
if (m_Controls->measureButton->isChecked())
{
m_Controls->measureButton->setChecked(false);
this->OnMeasurement();
}
if (m_Controls->pointSetButton->isChecked())
{
m_Controls->pointSetButton->setChecked(false);
this->OnPointSet();
}
// remove observer
if (m_MeasurementPointSet2D.IsNotNull())
{
m_MeasurementPointSet2D->RemoveObserver(m_MeasurementPointSetChangedObserverTag);
}
if (m_PointSet2D.IsNotNull())
{
m_PointSet2D->RemoveObserver(m_PointSetChangedObserverTag);
}
// if (m_DistanceImage.IsNotNull())
// {
// m_DistanceImage->RemoveObserver(m_DistanceImageChangedObserverTag);
// }
// remove foreground renderer
if (m_ForegroundRenderer1&&m_RenderWindow1)
{
if (mitk::VtkLayerController::GetInstance(m_RenderWindow1))
{
mitk::VtkLayerController::GetInstance(m_RenderWindow1)->RemoveRenderer(m_ForegroundRenderer1);
}
m_ForegroundRenderer1 = NULL;
}
if (m_ForegroundRenderer2&&m_RenderWindow2)
{
if (mitk::VtkLayerController::GetInstance(m_RenderWindow2))
{
mitk::VtkLayerController::GetInstance(m_RenderWindow2)->RemoveRenderer(m_ForegroundRenderer2);
}
m_ForegroundRenderer2 = NULL;
}
if (m_ForegroundRenderer3&&m_RenderWindow3)
{
if (mitk::VtkLayerController::GetInstance(m_RenderWindow3))
{
mitk::VtkLayerController::GetInstance(m_RenderWindow3)->RemoveRenderer(m_ForegroundRenderer3);
}
m_ForegroundRenderer3 = NULL;
}
if (mitk::RenderingManager::GetInstance())
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkToFPointSetWidget::SetDistanceImage(mitk::Image::Pointer distanceImage)
{
// // remove existing observer
// if (m_DistanceImage.IsNotNull())
// {
// m_DistanceImage->RemoveObserver(m_DistanceImageChangedObserverTag);
// }
m_DistanceImage = distanceImage;
// // create observer for m_DistanceImage
// itk::SimpleMemberCommand<QmitkToFPointSetWidget>::Pointer distanceImageChangedCommand;
// distanceImageChangedCommand = itk::SimpleMemberCommand<QmitkToFPointSetWidget>::New();
// distanceImageChangedCommand->SetCallbackFunction(this, &QmitkToFPointSetWidget::MeasurementPointSetChanged);
// m_DistanceImageChangedObserverTag = m_DistanceImage->AddObserver(itk::ModifiedEvent(), distanceImageChangedCommand);
}
void QmitkToFPointSetWidget::SetCameraIntrinsics(mitk::CameraIntrinsics::Pointer cameraIntrinsics)
{
m_CameraIntrinsics = cameraIntrinsics;
}
void QmitkToFPointSetWidget::OnMeasurement()
{
// always show 2D PointSet in foreground
mitk::DataNode::Pointer pointSetNode = m_DataStorage->GetNamedNode("Measurement PointSet 2D");
if (pointSetNode.IsNotNull())
{
pointSetNode->SetIntProperty("layer",100);
}
if (m_Controls->measureButton->isChecked())
{
// disable point set interaction
if (m_Controls->pointSetButton->isChecked())
{
m_Controls->pointSetButton->setChecked(false);
// remove interactor
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor);
}
// show overlays
m_VtkTextActor->SetVisibility(1);
this->m_VtkTextActor->SetInput("Choose measurement points with SHIFT+Click");
// enable interactor
mitk::GlobalInteraction::GetInstance()->AddInteractor(m_MeasurementPointSetInteractor);
// initial update of measurement
this->MeasurementPointSetChanged();
}
else
{
// hide overlays
m_VtkTextActor->SetVisibility(0);
// disable interactor
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_MeasurementPointSetInteractor);
}
}
void QmitkToFPointSetWidget::OnPointSet()
{
// always show 2D PointSet in foreground
mitk::DataNode::Pointer pointSetNode = m_DataStorage->GetNamedNode("ToF PointSet 2D");
if (pointSetNode.IsNotNull())
{
pointSetNode->SetIntProperty("layer",100);
}
if (m_Controls->pointSetButton->isChecked())
{
// disable measurement
if (m_Controls->measureButton->isChecked())
{
m_Controls->measureButton->setChecked(false);
// remove interactor
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_MeasurementPointSetInteractor);
}
// show overlays
m_VtkTextActor->SetVisibility(1);
this->m_VtkTextActor->SetInput("Choose points with SHIFT+Click");
// enable interactor
mitk::GlobalInteraction::GetInstance()->AddInteractor(m_PointSetInteractor);
// initial update of PointSet
this->PointSetChanged();
}
else
{
// hide overlays
m_VtkTextActor->SetVisibility(0);
// disable interactor
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor);
}
}
void QmitkToFPointSetWidget::MeasurementPointSetChanged()
{
// replace text actor
this->m_VtkTextActor->SetDisplayPosition(10,m_WindowHeight-30);
if (m_MeasurementPointSet2D->GetSize()==2)
{
// check if points are inside the image range
int imageSizeX = m_DistanceImage->GetDimensions()[0];
int imageSizeY = m_DistanceImage->GetDimensions()[1];
mitk::Point3D point1 = m_MeasurementPointSet2D->GetPoint(0);
mitk::Point3D point2 = m_MeasurementPointSet2D->GetPoint(1);
if ((point1[0]>=0.0f)&&(point1[0]<imageSizeX)&&(point1[1]>=0)&&(point1[1]<imageSizeY)&&
(point2[0]>=0.0f)&&(point2[0]<imageSizeX)&&(point2[1]>=0)&&(point2[1]<imageSizeY))
{
// create PointSet filter
mitk::ToFDistanceImageToPointSetFilter::Pointer toFDistanceImageToPointSetFilter = mitk::ToFDistanceImageToPointSetFilter::New();
if (m_CameraIntrinsics.IsNotNull())
{
toFDistanceImageToPointSetFilter->SetCameraIntrinsics(m_CameraIntrinsics);
}
toFDistanceImageToPointSetFilter->SetInput(m_DistanceImage);
toFDistanceImageToPointSetFilter->SetSubset(m_MeasurementPointSet2D);
toFDistanceImageToPointSetFilter->Update();
mitk::PointSet::Pointer measurementPointSet3D = toFDistanceImageToPointSetFilter->GetOutput();
m_MeasurementPointSet3DNode->SetData(measurementPointSet3D);
// calculate distance between points
if (measurementPointSet3D->GetSize()==2)
{
mitk::Point3D point1 = measurementPointSet3D->GetPoint(0);
mitk::Point3D point2 = measurementPointSet3D->GetPoint(1);
float distance = point1.EuclideanDistanceTo(point2);
std::stringstream stream;
stream<<distance<<" mm";
this->m_VtkTextActor->SetInput(stream.str().c_str());
}
else
{
this->m_VtkTextActor->SetInput("Choose measurement points with SHIFT+Click");
}
}
else
{
this->m_VtkTextActor->SetInput("Measurement outside image range.");
}
}
else
{
// initialize 3D pointset empty
mitk::PointSet::Pointer pointSet3D = mitk::PointSet::New();
m_MeasurementPointSet3DNode->SetData(pointSet3D);
}
}
void QmitkToFPointSetWidget::PointSetChanged()
{
if (m_DistanceImage.IsNotNull())
{
int imageSizeX = m_DistanceImage->GetDimensions()[0];
int imageSizeY = m_DistanceImage->GetDimensions()[1];
int pointSetValid = 1;
for (int i=0; i<m_PointSet2D->GetSize(); i++)
{
mitk::Point3D currentPoint = m_PointSet2D->GetPoint(i);
if ((currentPoint[0]>=0.0f)&&(currentPoint[0]<imageSizeX)&&(currentPoint[1]>=0)&&(currentPoint[1]<imageSizeY))
{
pointSetValid*=1;
}
else
{
pointSetValid*=0;
}
}
if (m_PointSet2D->GetSize()>0)
{
if (pointSetValid)
{
// create PointSet filter
mitk::ToFDistanceImageToPointSetFilter::Pointer toFDistanceImageToPointSetFilter = mitk::ToFDistanceImageToPointSetFilter::New();
if (m_CameraIntrinsics.IsNotNull())
{
toFDistanceImageToPointSetFilter->SetCameraIntrinsics(m_CameraIntrinsics);
}
toFDistanceImageToPointSetFilter->SetInput(m_DistanceImage);
toFDistanceImageToPointSetFilter->SetSubset(m_PointSet2D);
toFDistanceImageToPointSetFilter->Update();
mitk::PointSet::Pointer pointSet3D = toFDistanceImageToPointSetFilter->GetOutput();
m_PointSet3DNode->SetData(pointSet3D);
this->m_VtkTextActor->SetInput("Choose points with SHIFT+Click"); }
else
{
this->m_VtkTextActor->SetInput("Point set outside image range.");
}
}
else
{
// initialize 3D pointset empty
mitk::PointSet::Pointer pointSet3D = mitk::PointSet::New();
m_PointSet3DNode->SetData(pointSet3D);
}
}
}
diff --git a/Modules/VtkShaders/mitkVtkShaderRepository.cpp b/Modules/VtkShaders/mitkVtkShaderRepository.cpp
index fab7320c52..08804b53f5 100644
--- a/Modules/VtkShaders/mitkVtkShaderRepository.cpp
+++ b/Modules/VtkShaders/mitkVtkShaderRepository.cpp
@@ -1,588 +1,635 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#define SR_INFO MITK_INFO("shader.repository")
#define SR_WARN MITK_WARN("shader.repository")
#define SR_ERROR MITK_ERROR("shader.repository")
#include "mitkVtkShaderRepository.h"
#include "mitkVtkShaderProgram.h"
#include "mitkShaderProperty.h"
#include "mitkProperties.h"
#include "mitkDataNode.h"
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkXMLMaterial.h>
#include <vtkXMLShader.h>
#include <vtkXMLDataElement.h>
#include <vtkXMLMaterialParser.h>
#include <vtkSmartPointer.h>
#include <mitkBaseRenderer.h>
#include <vtkShader2.h>
#include <vtkShaderProgram2.h>
#include <vtkShader2Collection.h>
#include <vtkUniformVariables.h>
#include <vtkOpenGLRenderWindow.h>
#include <vtkVersionMacros.h>
#include <itkDirectory.h>
#include <itksys/SystemTools.hxx>
int mitk::VtkShaderRepository::shaderId = 0;
const bool mitk::VtkShaderRepository::debug = false;
mitk::VtkShaderRepository::VtkShaderRepository()
{
LoadShaders();
}
mitk::VtkShaderRepository::~VtkShaderRepository()
{
}
mitk::IShaderRepository::ShaderProgram::Pointer mitk::VtkShaderRepository::CreateShaderProgram()
{
mitk::IShaderRepository::ShaderProgram::Pointer shaderProg = (mitk::VtkShaderProgram::New()).GetPointer();
return shaderProg;
}
void mitk::VtkShaderRepository::LoadShaders()
{
itk::Directory::Pointer dir = itk::Directory::New();
std::string dirPath = "./vtk_shader";
if( dir->Load( dirPath.c_str() ) )
{
int n = dir->GetNumberOfFiles();
for(int r=0;r<n;r++)
{
const char *filename = dir->GetFile( r );
std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
if(extension.compare(".xml")==0)
{
Shader::Pointer element=Shader::New();
element->SetName(itksys::SystemTools::GetFilenameWithoutExtension(filename));
std::string filePath = dirPath + std::string("/") + element->GetName() + std::string(".xml");
SR_INFO(debug) << "found shader '" << element->GetName() << "'";
std::ifstream fileStream(filePath.c_str());
element->LoadXmlShader(fileStream);
shaders.push_back(element);
}
}
}
}
mitk::VtkShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShaderImpl(const std::string &name) const
{
std::list<Shader::Pointer>::const_iterator i = shaders.begin();
while( i != shaders.end() )
{
if( (*i)->GetName() == name)
return (*i);
i++;
}
return Shader::Pointer();
}
int mitk::VtkShaderRepository::LoadShader(std::istream& stream, const std::string& filename)
{
Shader::Pointer element=Shader::New();
element->SetName(filename);
element->SetId(shaderId++);
element->LoadXmlShader(stream);
shaders.push_back(element);
SR_INFO(debug) << "found shader '" << element->GetName() << "'";
return element->GetId();
}
bool mitk::VtkShaderRepository::UnloadShader(int id)
{
for (std::list<Shader::Pointer>::iterator i = shaders.begin();
i != shaders.end(); ++i)
{
if ((*i)->GetId() == id)
{
shaders.erase(i);
return true;
}
}
return false;
}
mitk::VtkShaderRepository::Shader::Shader()
{
}
mitk::VtkShaderRepository::Shader::~Shader()
{
}
void mitk::VtkShaderRepository::Shader::SetVertexShaderCode(const std::string& code)
{
this->m_VertexShaderCode = code;
}
std::string mitk::VtkShaderRepository::Shader::GetVertexShaderCode() const
{
return this->m_VertexShaderCode;
}
void mitk::VtkShaderRepository::Shader::SetFragmentShaderCode(const std::string& code)
{
this->m_FragmentShaderCode = code;
}
std::string mitk::VtkShaderRepository::Shader::GetFragmentShaderCode() const
{
return this->m_FragmentShaderCode;
}
+void mitk::VtkShaderRepository::Shader::SetGeometryShaderCode(const std::string& code)
+{
+ this->m_GeometryShaderCode = code;
+}
+
+std::string mitk::VtkShaderRepository::Shader::GetGeometryShaderCode() const
+{
+ return this->m_GeometryShaderCode;
+}
+
std::list<mitk::VtkShaderRepository::Shader::Uniform::Pointer> mitk::VtkShaderRepository::Shader::GetUniforms() const
{
return uniforms;
}
void mitk::VtkShaderRepository::Shader::LoadXmlShader(std::istream& stream)
{
std::string content;
content.reserve(2048);
char buffer[2048];
while (stream.read(buffer, sizeof(buffer)))
{
content.append(buffer, sizeof(buffer));
}
content.append(buffer, static_cast<std::size_t>(stream.gcount()));
if (content.empty()) return;
this->SetMaterialXml(content);
vtkXMLMaterialParser* parser = vtkXMLMaterialParser::New();
vtkXMLMaterial* material = vtkXMLMaterial::New();
parser->SetMaterial(material);
parser->Parse(content.c_str());
parser->Delete();
if (material == NULL) return;
// Vertexshader uniforms
{
vtkXMLShader *s=material->GetVertexShader();
if (s)
{
SetVertexShaderCode(s->GetCode());
vtkXMLDataElement *x=s->GetRootElement();
int n=x->GetNumberOfNestedElements();
for(int r=0;r<n;r++)
{
vtkXMLDataElement *y=x->GetNestedElement(r);
if(strcmp(y->GetName(),"ApplicationUniform") == 0 ||
strcmp(y->GetName(), "Uniform") == 0)
{
Uniform::Pointer element=Uniform::New();
element->LoadFromXML(y);
uniforms.push_back(element);
}
}
}
}
// Fragmentshader uniforms
{
vtkXMLShader *s=material->GetFragmentShader();
if (s)
{
SetFragmentShaderCode(s->GetCode());
vtkXMLDataElement *x=s->GetRootElement();
int n=x->GetNumberOfNestedElements();
for(int r=0;r<n;r++)
{
vtkXMLDataElement *y=x->GetNestedElement(r);
if(strcmp(y->GetName(),"ApplicationUniform") == 0 ||
strcmp(y->GetName(), "Uniform") == 0)
{
Uniform::Pointer element=Uniform::New();
element->LoadFromXML(y);
uniforms.push_back(element);
}
}
}
}
+
+ // Geometryshader uniforms
+ {
+ vtkXMLShader *s=material->GetGeometryShader();
+ if (s)
+ {
+ SetGeometryShaderCode(s->GetCode());
+ vtkXMLDataElement *x=s->GetRootElement();
+ int n=x->GetNumberOfNestedElements();
+ for(int r=0;r<n;r++)
+ {
+ vtkXMLDataElement *y=x->GetNestedElement(r);
+ if(strcmp(y->GetName(),"ApplicationUniform") == 0 ||
+ strcmp(y->GetName(), "Uniform") == 0)
+ {
+ Uniform::Pointer element=Uniform::New();
+ element->LoadFromXML(y);
+ uniforms.push_back(element);
+ }
+ }
+ }
+ }
material->Delete();
}
mitk::VtkShaderRepository::Shader::Uniform::Uniform()
{
}
mitk::VtkShaderRepository::Shader::Uniform::~Uniform()
{
}
void mitk::VtkShaderRepository::Shader::Uniform::LoadFromXML(vtkXMLDataElement *y)
{
//MITK_INFO << "found uniform '" << y->GetAttribute("name") << "' type=" << y->GetAttribute("type");// << " default=" << y->GetAttribute("value");
name = y->GetAttribute("name");
const char *sType=y->GetAttribute("type");
if(!strcmp(sType,"float"))
type=glsl_float;
else if(!strcmp(sType,"vec2"))
type=glsl_vec2;
else if(!strcmp(sType,"vec3"))
type=glsl_vec3;
else if(!strcmp(sType,"vec4"))
type=glsl_vec4;
else if(!strcmp(sType,"int"))
type=glsl_int;
else if(!strcmp(sType,"ivec2"))
type=glsl_ivec2;
else if(!strcmp(sType,"ivec3"))
type=glsl_ivec3;
else if(!strcmp(sType,"ivec4"))
type=glsl_ivec4;
else
{
type=glsl_none;
SR_WARN << "unknown type for uniform '" << name << "'" ;
}
defaultFloat[0]=defaultFloat[1]=defaultFloat[2]=defaultFloat[3]=0;
const char *sDefault=y->GetAttribute("value");
if(sDefault)
{
switch(type)
{
case glsl_float:
sscanf(sDefault,"%f",&defaultFloat[0]);
break;
case glsl_vec2:
sscanf(sDefault,"%f %f",&defaultFloat[0],&defaultFloat[1]);
break;
case glsl_vec3:
sscanf(sDefault,"%f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2]);
break;
case glsl_vec4:
sscanf(sDefault,"%f %f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2],&defaultFloat[3]);
break;
case glsl_int:
sscanf(sDefault,"%d",&defaultInt[0]);
break;
case glsl_ivec2:
sscanf(sDefault,"%d %d",&defaultInt[0],&defaultInt[1]);
break;
case glsl_ivec3:
sscanf(sDefault,"%d %d %d",&defaultInt[0],&defaultInt[1],&defaultInt[2]);
break;
case glsl_ivec4:
sscanf(sDefault,"%d %d %d %d",&defaultInt[0],&defaultInt[1],&defaultInt[2],&defaultInt[3]);
break;
case glsl_none:
break;
}
}
}
void mitk::VtkShaderRepository::AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) const
{
node->AddProperty( "shader", mitk::ShaderProperty::New(), renderer, overwrite );
std::list<Shader::Pointer>::const_iterator i = shaders.begin();
while( i != shaders.end() )
{
std::list<Shader::Uniform::Pointer> uniforms = (*i)->GetUniforms();
std::string shaderName = (*i)->GetName();
std::list<Shader::Uniform::Pointer>::const_iterator j = uniforms.begin();
while( j != uniforms.end() )
{
std::string propertyName = "shader." + shaderName + "." + (*j)->name;
switch( (*j)->type )
{
case Shader::Uniform::glsl_float:
node->AddProperty( propertyName.c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_vec2:
node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_vec3:
node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_vec4:
node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite );
node->AddProperty( (propertyName+".w").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[3] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_int:
node->AddProperty( propertyName.c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_ivec2:
node->AddProperty( (propertyName+".x").c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::IntProperty::New( (*j)->defaultInt[1] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_ivec3:
node->AddProperty( (propertyName+".x").c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::IntProperty::New( (*j)->defaultInt[1] ), renderer, overwrite );
node->AddProperty( (propertyName+".z").c_str(), mitk::IntProperty::New( (*j)->defaultInt[2] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_ivec4:
node->AddProperty( (propertyName+".x").c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::IntProperty::New( (*j)->defaultInt[1] ), renderer, overwrite );
node->AddProperty( (propertyName+".z").c_str(), mitk::IntProperty::New( (*j)->defaultInt[2] ), renderer, overwrite );
node->AddProperty( (propertyName+".w").c_str(), mitk::IntProperty::New( (*j)->defaultInt[3] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_none:
break;
}
j++;
}
i++;
}
}
std::list<mitk::IShaderRepository::Shader::Pointer> mitk::VtkShaderRepository::GetShaders() const
{
std::list<mitk::IShaderRepository::Shader::Pointer> result;
for (std::list<Shader::Pointer>::const_iterator i = shaders.begin();
i != shaders.end(); ++i)
{
result.push_back(i->GetPointer());
}
return result;
}
mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(const std::string& name) const
{
for (std::list<Shader::Pointer>::const_iterator i = shaders.begin();
i != shaders.end(); ++i)
{
if ((*i)->GetName() == name) return i->GetPointer();
}
return IShaderRepository::Shader::Pointer();
}
mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(int id) const
{
for (std::list<Shader::Pointer>::const_iterator i = shaders.begin();
i != shaders.end(); ++i)
{
if ((*i)->GetId() == id) return i->GetPointer();
}
return IShaderRepository::Shader::Pointer();
}
void
mitk::VtkShaderRepository::UpdateShaderProgram(ShaderProgram* shaderProgram,
DataNode* node, BaseRenderer* renderer) const
{
VtkShaderProgram* mitkVtkShaderProgram = dynamic_cast<VtkShaderProgram*>(shaderProgram);
mitk::ShaderProperty *sep= dynamic_cast<mitk::ShaderProperty*>(node->GetProperty("shader",renderer));
if(!sep)
{
mitkVtkShaderProgram->SetVtkShaderProgram(0);
return;
}
Shader::Pointer s = GetShaderImpl(sep->GetValueAsString());
// Need update pipeline mode
if(sep->GetMTime() > mitkVtkShaderProgram->GetShaderTimestampUpdate().GetMTime())
{
if( s.IsNull() )
{
mitkVtkShaderProgram->SetVtkShaderProgram(0);
MITK_INFO << "disabling shader";
mitkVtkShaderProgram->GetShaderTimestampUpdate().Modified();
return;
}
vtkSmartPointer<vtkShaderProgram2> program = vtkSmartPointer<vtkShaderProgram2>::New();
#if ((VTK_MAJOR_VERSION < 6 ) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0) ))
program->SetContext(dynamic_cast<vtkOpenGLRenderWindow*>(renderer->GetRenderWindow()));
#else
program->SetContext(renderer->GetRenderWindow());
#endif
// The vertext shader
vtkShader2 *shader = vtkShader2::New();
shader->SetType(VTK_SHADER_TYPE_VERTEX);
shader->SetSourceCode(s->GetVertexShaderCode().c_str());
#if ((VTK_MAJOR_VERSION < 6 ) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0) ))
shader->SetContext(dynamic_cast<vtkOpenGLRenderWindow*>(renderer->GetRenderWindow()));
#else
shader->SetContext(renderer->GetRenderWindow());
#endif
program->GetShaders()->AddItem(shader);
shader->Delete();
// The fragment shader
shader = vtkShader2::New();
shader->SetType(VTK_SHADER_TYPE_FRAGMENT);
shader->SetSourceCode(s->GetFragmentShaderCode().c_str());
#if ((VTK_MAJOR_VERSION < 6 ) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0) ))
shader->SetContext(dynamic_cast<vtkOpenGLRenderWindow*>(renderer->GetRenderWindow()));
#else
shader->SetContext(renderer->GetRenderWindow());
#endif
program->GetShaders()->AddItem(shader);
shader->Delete();
+ if(s->GetGeometryShaderCode().size()>0)
+ {
+ // The Geometry shader
+ shader = vtkShader2::New();
+ shader->SetType(VTK_SHADER_TYPE_GEOMETRY);
+ shader->SetSourceCode(s->GetGeometryShaderCode().c_str());
+#if ((VTK_MAJOR_VERSION < 6 ) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0) ))
+ shader->SetContext(dynamic_cast<vtkOpenGLRenderWindow*>(renderer->GetRenderWindow()));
+#else
+ shader->SetContext(renderer->GetRenderWindow());
+#endif
+ program->GetShaders()->AddItem(shader);
+ shader->Delete();
+ }
+
program->Build();
mitkVtkShaderProgram->SetVtkShaderProgram(program);
mitkVtkShaderProgram->GetShaderTimestampUpdate().Modified();
}
if(s.IsNull())
return;
// update uniforms
vtkShaderProgram2 *p = mitkVtkShaderProgram->GetVtkShaderProgram();
if(!p)
return;
std::list<Shader::Uniform::Pointer>::const_iterator j = s->uniforms.begin();
while( j != s->uniforms.end() )
{
std::string propertyName = "shader." + s->GetName() + "." + (*j)->name;
// MITK_INFO << "querying property: " << propertyName;
// mitk::BaseProperty *p = node->GetProperty( propertyName.c_str(), renderer );
// if( p && p->GetMTime() > MTime.GetMTime() )
{
float fval[4];
int ival[4];
// MITK_INFO << "copying property " << propertyName << " ->->- " << (*j)->name << " type=" << (*j)->type ;
switch( (*j)->type )
{
case Shader::Uniform::glsl_float:
node->GetFloatProperty( propertyName.c_str(), fval[0], renderer );
p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 1, fval);
break;
case Shader::Uniform::glsl_vec2:
node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 2, fval);
break;
case Shader::Uniform::glsl_vec3:
node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer );
//p->SetUniform3f( (*j)->name.c_str(), fval );
p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 3, fval);
break;
case Shader::Uniform::glsl_vec4:
node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer );
node->GetFloatProperty( (propertyName+".w").c_str(), fval[3], renderer );
p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 4, fval);
break;
case Shader::Uniform::glsl_int:
node->GetIntProperty( propertyName.c_str(), ival[0], renderer );
p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 1, ival);
break;
case Shader::Uniform::glsl_ivec2:
node->GetIntProperty( (propertyName+".x").c_str(), ival[0], renderer );
node->GetIntProperty( (propertyName+".y").c_str(), ival[1], renderer );
p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 2, ival);
break;
case Shader::Uniform::glsl_ivec3:
node->GetIntProperty( (propertyName+".x").c_str(), ival[0], renderer );
node->GetIntProperty( (propertyName+".y").c_str(), ival[1], renderer );
node->GetIntProperty( (propertyName+".z").c_str(), ival[2], renderer );
//p->SetUniform3f( (*j)->name.c_str(), fval );
p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 3, ival);
break;
case Shader::Uniform::glsl_ivec4:
node->GetIntProperty( (propertyName+".x").c_str(), ival[0], renderer );
node->GetIntProperty( (propertyName+".y").c_str(), ival[1], renderer );
node->GetIntProperty( (propertyName+".z").c_str(), ival[2], renderer );
node->GetIntProperty( (propertyName+".w").c_str(), ival[3], renderer );
p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 4, ival);
break;
case Shader::Uniform::glsl_none:
break;
}
}
j++;
}
return;
}
diff --git a/Modules/VtkShaders/mitkVtkShaderRepository.h b/Modules/VtkShaders/mitkVtkShaderRepository.h
index e1c8f33407..a8ac7f456c 100644
--- a/Modules/VtkShaders/mitkVtkShaderRepository.h
+++ b/Modules/VtkShaders/mitkVtkShaderRepository.h
@@ -1,171 +1,175 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITKVTKSHADERREPOSITORY_H_
#define _MITKVTKSHADERREPOSITORY_H_
#include "mitkIShaderRepository.h"
#include <vtkShaderProgram2.h>
#include <vtkXMLShader.h>
class vtkXMLDataElement;
class vtkXMLMaterial;
class vtkProperty;
namespace mitk {
/**
* \brief Management class for vtkShader XML descriptions.
*
* Looks for all XML shader files in a given directory and adds default properties
* for each shader object (shader uniforms) to the specified mitk::DataNode.
*
* Additionally, it provides a utility function for applying properties for shaders
* in mappers.
*/
class VtkShaderRepository : public IShaderRepository
{
protected:
class Shader : public IShaderRepository::Shader
{
public:
mitkClassMacro( Shader, itk::Object )
itkFactorylessNewMacro( Self )
class Uniform : public itk::Object
{
public:
mitkClassMacro( Uniform, itk::Object )
itkFactorylessNewMacro( Self )
enum Type
{
glsl_none,
glsl_float,
glsl_vec2,
glsl_vec3,
glsl_vec4,
glsl_int,
glsl_ivec2,
glsl_ivec3,
glsl_ivec4
};
/**
* Constructor
*/
Uniform();
/**
* Destructor
*/
~Uniform();
Type type;
std::string name;
int defaultInt[4];
float defaultFloat[4];
void LoadFromXML(vtkXMLDataElement *e);
};
std::list<Uniform::Pointer> uniforms;
/**
* Constructor
*/
Shader();
/**
* Destructor
*/
~Shader();
void SetVertexShaderCode(const std::string& code);
std::string GetVertexShaderCode() const;
void SetFragmentShaderCode(const std::string& code);
std::string GetFragmentShaderCode() const;
+ void SetGeometryShaderCode(const std::string& code);
+ std::string GetGeometryShaderCode() const;
+
std::list<Uniform::Pointer> GetUniforms() const;
private:
friend class VtkShaderRepository;
std::string m_VertexShaderCode;
std::string m_FragmentShaderCode;
+ std::string m_GeometryShaderCode;
void LoadXmlShader(std::istream& stream);
};
void LoadShaders();
Shader::Pointer GetShaderImpl(const std::string& name) const;
private:
std::list<Shader::Pointer> shaders;
static int shaderId;
static const bool debug;
public:
/**
* Constructor
*/
VtkShaderRepository();
/**
* Destructor
*/
~VtkShaderRepository();
ShaderProgram::Pointer CreateShaderProgram();
std::list<IShaderRepository::Shader::Pointer> GetShaders() const;
IShaderRepository::Shader::Pointer GetShader(const std::string& name) const;
IShaderRepository::Shader::Pointer GetShader(int id) const;
/** \brief Adds all parsed shader uniforms to property list of the given DataNode;
* used by mappers.
*/
void AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) const;
/** \brief Applies shader and shader specific variables of the specified DataNode
* to the VTK object by updating the shader variables of its vtkProperty.
*/
int LoadShader(std::istream& stream, const std::string& name);
bool UnloadShader(int id);
void UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram* shaderProgram,
DataNode* node, BaseRenderer* renderer) const;
};
} //end of namespace mitk
#endif
diff --git a/Modules/VtkShaders/vtkXMLMaterial.cpp b/Modules/VtkShaders/vtkXMLMaterial.cpp
index 8baa6c615b..4aa45127bf 100644
--- a/Modules/VtkShaders/vtkXMLMaterial.cpp
+++ b/Modules/VtkShaders/vtkXMLMaterial.cpp
@@ -1,280 +1,305 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
/*=========================================================================
Program: Visualization Toolkit
Module: vtkXMLMaterial.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkXMLMaterial.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include "vtkXMLDataElement.h"
#include "vtkXMLMaterialParser.h"
#include "vtkXMLShader.h"
#include <vector>
#include <assert.h>
class vtkXMLMaterialInternals
{
public:
typedef std::vector<vtkXMLDataElement*> VectorOfElements;
typedef std::vector<vtkSmartPointer<vtkXMLShader> > VectorOfShaders;
VectorOfElements Properties;
VectorOfShaders VertexShaders;
VectorOfShaders FragmentShaders;
+ VectorOfShaders GeometryShaders;
VectorOfElements Textures;
void Initialize()
{
this->Properties.clear();
this->VertexShaders.clear();
this->FragmentShaders.clear();
+ this->GeometryShaders.clear();
this->Textures.clear();
}
};
vtkStandardNewMacro(vtkXMLMaterial);
//-----------------------------------------------------------------------------
vtkXMLMaterial::vtkXMLMaterial()
{
this->RootElement = 0;
this->Internals = new vtkXMLMaterialInternals;
}
//-----------------------------------------------------------------------------
vtkXMLMaterial::~vtkXMLMaterial()
{
this->SetRootElement(0);
delete this->Internals;
}
vtkXMLMaterial* vtkXMLMaterial::CreateInstance(const char* name)
{
if (!name)
{
return 0;
}
vtkXMLMaterialParser* parser = vtkXMLMaterialParser::New();
vtkXMLMaterial* material = vtkXMLMaterial::New();
parser->SetMaterial(material);
// First, look for material library files.
// Then, look for Repository files.
char* filename = vtkXMLShader::LocateFile(name);
if (filename)
{
parser->SetFileName( filename );
delete [] filename;
parser->Parse();
parser->Delete();
return material;
}
parser->Delete();
material->Delete();
return NULL;
}
//-----------------------------------------------------------------------------
void vtkXMLMaterial::SetRootElement(vtkXMLDataElement* root)
{
this->Internals->Initialize();
vtkSetObjectBodyMacro(RootElement, vtkXMLDataElement, root);
if (this->RootElement)
{
// Update the internal data structure to
// avoid repeated searches.
int numElems = this->RootElement->GetNumberOfNestedElements();
for (int i=0; i<numElems; i++)
{
vtkXMLDataElement* elem = this->RootElement->GetNestedElement(i);
const char* name = elem->GetName();
if (!name)
{
continue;
}
if (strcmp(name, "Property") == 0)
{
this->Internals->Properties.push_back(elem);
}
else if (strcmp(name, "Shader") == 0)
{
vtkXMLShader* shader = vtkXMLShader::New();
shader->SetRootElement(elem);
switch (shader->GetScope())
{
case vtkXMLShader::SCOPE_VERTEX:
this->Internals->VertexShaders.push_back(shader);
break;
case vtkXMLShader::SCOPE_FRAGMENT:
this->Internals->FragmentShaders.push_back(shader);
break;
+ case vtkXMLShader::SCOPE_GEOMETRY:
+ this->Internals->GeometryShaders.push_back(shader);
+ break;
default:
vtkErrorMacro("Invalid scope for shader: " << shader->GetName());
}
shader->Delete();
}
else if (strcmp(name, "Texture") == 0)
{
this->Internals->Textures.push_back(elem);
}
}
}
}
//-----------------------------------------------------------------------------
int vtkXMLMaterial::GetNumberOfProperties()
{
return static_cast<int>(this->Internals->Properties.size());
}
//-----------------------------------------------------------------------------
int vtkXMLMaterial::GetNumberOfTextures()
{
return static_cast<int>(this->Internals->Textures.size());
}
//-----------------------------------------------------------------------------
int vtkXMLMaterial::GetNumberOfVertexShaders()
{
return static_cast<int>(this->Internals->VertexShaders.size());
}
//-----------------------------------------------------------------------------
int vtkXMLMaterial::GetNumberOfFragmentShaders()
{
return static_cast<int>(this->Internals->FragmentShaders.size());
}
+int vtkXMLMaterial::GetNumberOfGeometryShaders()
+{
+ return static_cast<int>(this->Internals->GeometryShaders.size());
+}
+
//-----------------------------------------------------------------------------
vtkXMLDataElement* vtkXMLMaterial::GetProperty(int id)
{
if (id < this->GetNumberOfProperties())
{
return this->Internals->Properties[id];
}
return NULL;
}
//-----------------------------------------------------------------------------
vtkXMLDataElement* vtkXMLMaterial::GetTexture(int index)
{
if (index < this->GetNumberOfTextures())
{
return this->Internals->Textures[index];
}
return NULL;
}
//-----------------------------------------------------------------------------
vtkXMLShader* vtkXMLMaterial::GetVertexShader(int id)
{
if (id < this->GetNumberOfVertexShaders())
{
return this->Internals->VertexShaders[id].GetPointer();
}
return NULL;
}
//-----------------------------------------------------------------------------
vtkXMLShader* vtkXMLMaterial::GetFragmentShader(int id)
{
if (id < this->GetNumberOfFragmentShaders())
{
return this->Internals->FragmentShaders[id].GetPointer();
}
return NULL;
}
+
+vtkXMLShader* vtkXMLMaterial::GetGeometryShader(int id)
+{
+ if (id < this->GetNumberOfGeometryShaders())
+ {
+ return this->Internals->GeometryShaders[id].GetPointer();
+ }
+ return NULL;
+}
+
//----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Description:
// Get the style the shaders.
// \post valid_result: result==1 || result==2
int vtkXMLMaterial::GetShaderStyle()
{
int result = 1;
int vStyle = 0;
if (this->GetVertexShader())
{
vStyle = this->GetVertexShader()->GetStyle();
}
int fStyle = 0;
if (this->GetFragmentShader())
{
fStyle=this->GetFragmentShader()->GetStyle();
}
- if (vStyle!=0 && fStyle!=0 && vStyle!=fStyle)
+ int gStyle = 0;
+ if (this->GetGeometryShader())
+ {
+ gStyle=this->GetGeometryShader()->GetStyle();
+ }
+ if (vStyle!=0 && fStyle!=0 && !gStyle && vStyle!=fStyle )
{
vtkErrorMacro(<<"vertex shader and fragment shader style differ.");
}
else
{
if (vStyle!=0)
{
result = vStyle;
}
else
{
result = fStyle;
}
}
assert("post: valid_result" && (result==1 || result==2) );
return result;
}
//-----------------------------------------------------------------------------
void vtkXMLMaterial::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Number of Properties: " << this->GetNumberOfProperties()
<< endl;
os << indent << "Number of Vertex Shaders: "
<< this->GetNumberOfVertexShaders() << endl;
os << indent << "Number of Fragment Shaders: "
<< this->GetNumberOfFragmentShaders() << endl;
os << indent << "RootElement: ";
if (this->RootElement)
{
os << endl;
this->RootElement->PrintSelf(os, indent.GetNextIndent());
}
else
{
os << "(null)" << endl;
}
}
diff --git a/Modules/VtkShaders/vtkXMLMaterial.h b/Modules/VtkShaders/vtkXMLMaterial.h
index 6cf834632d..b561c09d7b 100644
--- a/Modules/VtkShaders/vtkXMLMaterial.h
+++ b/Modules/VtkShaders/vtkXMLMaterial.h
@@ -1,119 +1,122 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
/*=========================================================================
Program: Visualization Toolkit
Module: vtkXMLMaterial.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkXMLMaterial - encapsulates a VTK Material description.
// .SECTION Description
// vtkXMLMaterial encapsulates VTK Material description. It keeps a pointer
// to vtkXMLDataElement that defines the material and provides
// access to Shaders/Properties defined in it.
// .SECTION Thanks
// Shader support in VTK includes key contributions by Gary Templet at
// Sandia National Labs.
#ifndef __vtkXMLMaterial_h
#define __vtkXMLMaterial_h
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkObject.h"
class vtkXMLDataElement;
class vtkXMLMaterialInternals;
class vtkXMLShader;
class vtkXMLMaterial : public vtkObject
{
public:
static vtkXMLMaterial* New();
vtkTypeMacro(vtkXMLMaterial, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Create a new instance. It searches for the material
// using the following order: first, check the MaterialLibrary; second,
// treat the name as an absolute path and try to locate it; third,
// search the Material repository. Returns null is it fails to
// locate the material.
static vtkXMLMaterial* CreateInstance(const char* name);
// Description:
// Get number of elements of type Property.
int GetNumberOfProperties();
// Description:
// Get number of elements of type Texture.
int GetNumberOfTextures();
// Description:
// Get number of Vertex shaders.
int GetNumberOfVertexShaders();
// Description:
// Get number of fragment shaders.
int GetNumberOfFragmentShaders();
+ int GetNumberOfGeometryShaders();
// Description:
// Get the ith vtkXMLDataElement of type <Property />.
vtkXMLDataElement* GetProperty(int id=0);
// Description:
// Get the ith vtkXMLDataElement of type <Texture />.
vtkXMLDataElement* GetTexture(int id=0);
// Description:
// Get the ith vtkXMLDataElement of type <VertexShader />.
vtkXMLShader* GetVertexShader(int id=0);
// Description:
// Get the ith vtkXMLDataElement of type <FragmentShader />.
vtkXMLShader* GetFragmentShader(int id=0);
+ vtkXMLShader* GetGeometryShader(int id=0);
+
// Description:
// Get/Set the XML root element that describes this material.
vtkGetObjectMacro(RootElement, vtkXMLDataElement);
void SetRootElement(vtkXMLDataElement*);
// Description:
// Get the style the shaders.
// \post valid_result: result==1 || result==2
int GetShaderStyle();
protected:
vtkXMLMaterial();
~vtkXMLMaterial();
vtkXMLDataElement* RootElement;
vtkXMLMaterialInternals* Internals;
private:
vtkXMLMaterial(const vtkXMLMaterial&); // Not implemented.
void operator=(const vtkXMLMaterial&); // Not implemented.
};
#endif
diff --git a/Modules/VtkShaders/vtkXMLShader.cpp b/Modules/VtkShaders/vtkXMLShader.cpp
index fcf7a1cd84..5edfdda307 100644
--- a/Modules/VtkShaders/vtkXMLShader.cpp
+++ b/Modules/VtkShaders/vtkXMLShader.cpp
@@ -1,293 +1,300 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
/*=========================================================================
Program: Visualization Toolkit
Module: vtkXMLShader.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkXMLShader.h"
#include "vtkObjectFactory.h"
#include "vtkXMLDataElement.h"
#include <vtksys/SystemTools.hxx>
#include <assert.h>
vtkStandardNewMacro(vtkXMLShader);
vtkCxxSetObjectMacro(vtkXMLShader, SourceLibraryElement, vtkXMLDataElement);
//-----------------------------------------------------------------------------
vtkXMLShader::vtkXMLShader()
: Code(NULL),
RootElement(NULL),
SourceLibraryElement(NULL),
Args(NULL)
{
}
//-----------------------------------------------------------------------------
vtkXMLShader::~vtkXMLShader()
{
if (this->RootElement)
{
this->RootElement->UnRegister(this);
this->RootElement = 0;
}
this->SetSourceLibraryElement(0);
this->SetCode(0);
this->CleanupArgs();
}
//-----------------------------------------------------------------------------
void vtkXMLShader::SetRootElement(vtkXMLDataElement* root)
{
vtkSetObjectBodyMacro(RootElement, vtkXMLDataElement, root);
this->SetCode(0);
this->SetSourceLibraryElement(0); // release the SourceLibrary element.
}
//-----------------------------------------------------------------------------
// Note that this method allocates a new string which must be deleted by
// the caller.
char* vtkXMLShader::LocateFile(const char* filename)
{
if(!filename)
{
return NULL;
}
// if filename is absolute path, return the same.
if (vtksys::SystemTools::FileExists(filename))
{
return vtksys::SystemTools::DuplicateString(filename);
}
// Fetch any runtime defined user paths for materials
std::vector<std::string> paths;
std::string userpaths;
vtksys::SystemTools::GetEnv("USER_MATERIALS_DIRS", userpaths);
if (userpaths.size()>0)
{
vtksys::SystemTools::Split(userpaths.c_str(), paths, ';');
}
#ifdef VTK_MATERIALS_DIRS
// search thru default paths to locate file.
vtksys::SystemTools::Split(VTK_MATERIALS_DIRS, paths, ';');
#endif
for (unsigned int i =0; i < paths.size(); i++)
{
std::string path = paths[i];
if (path.size() == 0)
{
continue;
}
vtksys::SystemTools::ConvertToUnixSlashes(path);
if (path[path.size()-1] != '/')
{
path += "/";
}
path += filename;
if (vtksys::SystemTools::FileExists(path.c_str()))
{
return vtksys::SystemTools::DuplicateString(path.c_str());
}
}
return NULL;
}
//-----------------------------------------------------------------------------
int vtkXMLShader::GetScope()
{
if (this->RootElement)
{
const char* scope = this->RootElement->GetAttribute("scope");
if (!scope)
{
vtkErrorMacro("Shader description missing \"scope\" attribute.");
}
else if (strcmp(scope, "Vertex") == 0)
{
return vtkXMLShader::SCOPE_VERTEX;
}
else if (strcmp(scope, "Fragment") == 0)
{
return vtkXMLShader::SCOPE_FRAGMENT;
}
+ else if (strcmp(scope, "Geometry") == 0)
+ {
+ return vtkXMLShader::SCOPE_GEOMETRY;
+ }
}
return vtkXMLShader::SCOPE_NONE;
}
// ----------------------------------------------------------------------------
// \post valid_result: result==1 || result==2
int vtkXMLShader::GetStyle()
{
int result=1;
if(this->RootElement)
{
const char *loc=this->RootElement->GetAttribute("style");
if(loc==0)
{
// fine. this attribute is optional.
}
else
{
if(strcmp(loc,"1")==0)
{
// fine. default value.
}
else
{
if(strcmp(loc,"2")==0)
{
result=2; // new style
}
else
{
vtkErrorMacro(<<"style number not supported. Expect 1 or 2. We force it to be 1.");
}
}
}
}
assert("post valid_result" && (result==1 || result==2) );
return result;
}
//-----------------------------------------------------------------------------
const char* vtkXMLShader::GetName()
{
return (this->RootElement)? this->RootElement->GetAttribute("name") : 0;
}
//-----------------------------------------------------------------------------
const char* vtkXMLShader::GetEntry()
{
return (this->RootElement)? this->RootElement->GetAttribute("entry") : 0;
}
//-----------------------------------------------------------------------------
const char** vtkXMLShader::GetArgs()
{
this->CleanupArgs();
if (!this->RootElement || !this->RootElement->GetAttribute("args"))
{
return 0;
}
std::vector<std::string> args;
vtksys::SystemTools::Split(this->RootElement->GetAttribute("args"), args, ' ');
int i;
int size = static_cast<int>(args.size());
if (size == 0)
{
return 0;
}
this->Args = new char*[size+1];
for (i=0; i < size; i++)
{
this->Args[i] = vtksys::SystemTools::DuplicateString(args[i].c_str());
}
this->Args[size] = 0;
return const_cast<const char**>(this->Args);
}
//-----------------------------------------------------------------------------
const char* vtkXMLShader::GetCode()
{
return this->RootElement->GetCharacterData();
}
//-----------------------------------------------------------------------------
void vtkXMLShader::CleanupArgs()
{
if (this->Args)
{
char** a = this->Args;
while (*a)
{
delete [] (*a);
a++;
}
delete [] this->Args;
this->Args = 0;
}
}
//-----------------------------------------------------------------------------
void vtkXMLShader::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Name: " << (this->GetName()? this->GetName() : "(none)")
<< endl;
os << indent << "Scope: ";
switch(this->GetScope())
{
case SCOPE_NONE:
os << "None";
break;
case SCOPE_MIXED:
os << "Mixed";
break;
case SCOPE_VERTEX:
os << "Vertex";
break;
case SCOPE_FRAGMENT:
os << "Fragment";
break;
+ case SCOPE_GEOMETRY:
+ os << "Geometry";
+ break;
}
os << endl;
os << indent << "Entry: "
<< (this->GetEntry()? this->GetEntry() : "(none)") << endl;
os << indent << "Args: ";
const char** args = this->GetArgs();
if (!args)
{
os << "(none)" << endl;
}
else
{
while (*args)
{
os << indent << *args << " ";
args++;
}
os << endl;
}
os << indent << "RootElement: ";
if (this->RootElement)
{
os << endl;
this->RootElement->PrintSelf(os, indent.GetNextIndent());
}
else
{
os << "(none)" << endl;
}
}
diff --git a/Modules/VtkShaders/vtkXMLShader.h b/Modules/VtkShaders/vtkXMLShader.h
index e828343a56..5dcfa4d0e9 100644
--- a/Modules/VtkShaders/vtkXMLShader.h
+++ b/Modules/VtkShaders/vtkXMLShader.h
@@ -1,128 +1,129 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
/*=========================================================================
Program: Visualization Toolkit
Module: vtkXMLShader.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkXMLShader - encapsulates a Shader XML description.
// .SECTION Description
// vtkXMLShader encapsulates the XML description for a Shader.
// It provides convenient access to various attributes/properties
// of a shader.
// .SECTION Thanks
// Shader support in VTK includes key contributions by Gary Templet at
// Sandia National Labs.
#ifndef __vtkXMLShader_h
#define __vtkXMLShader_h
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkObject.h"
class vtkXMLDataElement;
class vtkXMLShader : public vtkObject
{
public:
static vtkXMLShader* New();
vtkTypeMacro(vtkXMLShader, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Get/Set the XML root element that describes this shader.
vtkGetObjectMacro(RootElement, vtkXMLDataElement);
void SetRootElement(vtkXMLDataElement*);
// Description:
// Returns the type of the shader as defined in the XML description.
int GetScope();
// Description:
// Returns the style of the shader as optionaly defined in the XML
// description. If not present, default style is 1. "style=2" means it is
// a shader without a main(). In style 2, the "main" function for the vertex
// shader part is void propFuncVS(void), the main function for the fragment
// shader part is void propFuncFS(). This is useful when combining a shader
// at the actor level and a shader defines at the renderer level, like
// the depth peeling pass.
// \post valid_result: result==1 || result==2
int GetStyle();
// Description:
// Get the name of the Shader.
const char* GetName();
// Description:
// Get the entry point to the shader code as defined in the XML.
const char* GetEntry();
// Description:
// Get the shader code.
const char* GetCode();
// Description:
// Returns an null terminate array of the pointers to space sepatared Args
// defined in the XML description.
const char** GetArgs();
// Description:
// Searches the file in the VTK_MATERIALS_DIRS.
// Note that this allocates new memory for the string.
// The caller must delete it.
static char* LocateFile(const char* filename);
//BTX
enum ScopeCodes
{
SCOPE_NONE=0,
SCOPE_MIXED,
SCOPE_VERTEX,
- SCOPE_FRAGMENT
+ SCOPE_FRAGMENT,
+ SCOPE_GEOMETRY
};
//ETX
protected:
vtkXMLShader();
~vtkXMLShader();
char* Code; // cache for the code.
vtkSetStringMacro(Code);
vtkXMLDataElement* RootElement;
vtkXMLDataElement* SourceLibraryElement;
void SetSourceLibraryElement(vtkXMLDataElement*);
char** Args;
void CleanupArgs();
private:
vtkXMLShader(const vtkXMLShader&); // Not implemented.
void operator=(const vtkXMLShader&); // Not implemented.
};
#endif
diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake
index a630fbbacf..1a6e6ada9d 100644
--- a/Plugins/PluginList.cmake
+++ b/Plugins/PluginList.cmake
@@ -1,58 +1,58 @@
# Plug-ins must be ordered according to their dependencies
if (MITK_USE_Qt4)
set(MITK_EXT_PLUGINS
org.mitk.core.services:ON
org.mitk.gui.common:ON
org.mitk.planarfigure:ON
org.mitk.core.ext:OFF
org.mitk.core.jobs:OFF
org.mitk.diffusionimaging:OFF
org.mitk.simulation:OFF
org.mitk.gui.qt.application:ON
org.mitk.gui.qt.coreapplication:OFF
org.mitk.gui.qt.ext:OFF
org.mitk.gui.qt.extapplication:OFF
org.mitk.gui.qt.common:ON
org.mitk.gui.qt.stdmultiwidgeteditor:ON
org.mitk.gui.qt.common.legacy:OFF
org.mitk.gui.qt.cmdlinemodules:OFF
org.mitk.gui.qt.diffusionimagingapp:OFF
org.mitk.gui.qt.datamanager:ON
org.mitk.gui.qt.datamanagerlight:OFF
org.mitk.gui.qt.properties:ON
org.mitk.gui.qt.basicimageprocessing:OFF
org.mitk.gui.qt.dicom:OFF
org.mitk.gui.qt.diffusionimaging:OFF
org.mitk.gui.qt.dtiatlasapp:OFF
org.mitk.gui.qt.igtexamples:OFF
org.mitk.gui.qt.igttracking:OFF
org.mitk.gui.qt.imagecropper:OFF
org.mitk.gui.qt.imagenavigator:ON
- org.mitk.gui.qt.candystore:OFF
+ org.mitk.gui.qt.viewnavigator:OFF
org.mitk.gui.qt.materialeditor:OFF
org.mitk.gui.qt.measurementtoolbox:OFF
org.mitk.gui.qt.moviemaker:OFF
org.mitk.gui.qt.pointsetinteraction:OFF
org.mitk.gui.qt.python:OFF
org.mitk.gui.qt.registration:OFF
org.mitk.gui.qt.remeshing:OFF
org.mitk.gui.qt.segmentation:OFF
org.mitk.gui.qt.simulation:OFF
org.mitk.gui.qt.toftutorial:OFF
org.mitk.gui.qt.tofutil:OFF
org.mitk.gui.qt.ugvisualization:OFF
org.mitk.gui.qt.ultrasound:OFF
org.mitk.gui.qt.volumevisualization:OFF
org.mitk.gui.qt.eventrecorder:OFF
org.mitk.gui.qt.xnat:OFF
)
else()
set(MITK_EXT_PLUGINS
# empty so far
)
endif()
diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp
index f6035585d8..aff7c6d02b 100644
--- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp
+++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp
@@ -1,1355 +1,1355 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkBasicImageProcessingView.h"
// QT includes (GUI)
#include <qlabel.h>
#include <qspinbox.h>
#include <qpushbutton.h>
#include <qcheckbox.h>
#include <qgroupbox.h>
#include <qradiobutton.h>
#include <qmessagebox.h>
// Berry includes (selection service)
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// MITK includes (GUI)
#include "QmitkStdMultiWidget.h"
#include "QmitkDataNodeSelectionProvider.h"
#include "mitkDataNodeObject.h"
// MITK includes (general)
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateAnd.h"
#include "mitkImageTimeSelector.h"
#include "mitkVectorImageMapper2D.h"
#include "mitkProperties.h"
// Includes for image casting between ITK and MITK
#include "mitkImageCast.h"
#include "mitkITKImageImport.h"
// ITK includes (general)
#include <itkVectorImage.h>
#include <itkImageFileWriter.h>
// Morphological Operations
#include <itkBinaryBallStructuringElement.h>
#include <itkGrayscaleDilateImageFilter.h>
#include <itkGrayscaleErodeImageFilter.h>
#include <itkGrayscaleMorphologicalOpeningImageFilter.h>
#include <itkGrayscaleMorphologicalClosingImageFilter.h>
// Smoothing
#include <itkMedianImageFilter.h>
#include <itkDiscreteGaussianImageFilter.h>
#include <itkTotalVariationDenoisingImageFilter.h>
// Threshold
#include <itkBinaryThresholdImageFilter.h>
// Inversion
#include <itkInvertIntensityImageFilter.h>
// Derivatives
#include <itkGradientMagnitudeRecursiveGaussianImageFilter.h>
#include <itkLaplacianImageFilter.h>
#include <itkSobelEdgeDetectionImageFilter.h>
// Resampling
#include <itkResampleImageFilter.h>
#include <itkNearestNeighborInterpolateImageFunction.h>
#include <itkCastImageFilter.h>
#include <itkLinearInterpolateImageFunction.h>
// Image Arithmetics
#include <itkAddImageFilter.h>
#include <itkSubtractImageFilter.h>
#include <itkMultiplyImageFilter.h>
#include <itkDivideImageFilter.h>
// Boolean operations
#include <itkOrImageFilter.h>
#include <itkAndImageFilter.h>
#include <itkXorImageFilter.h>
// Flip Image
#include <itkFlipImageFilter.h>
#include <itkRescaleIntensityImageFilter.h>
// Convenient Definitions
typedef itk::Image<short, 3> ImageType;
typedef itk::Image<unsigned char, 3> SegmentationImageType;
typedef itk::Image<double, 3> FloatImageType;
typedef itk::Image<itk::Vector<float,3>, 3> VectorImageType;
typedef itk::BinaryBallStructuringElement<ImageType::PixelType, 3> BallType;
typedef itk::GrayscaleDilateImageFilter<ImageType, ImageType, BallType> DilationFilterType;
typedef itk::GrayscaleErodeImageFilter<ImageType, ImageType, BallType> ErosionFilterType;
typedef itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, BallType> OpeningFilterType;
typedef itk::GrayscaleMorphologicalClosingImageFilter<ImageType, ImageType, BallType> ClosingFilterType;
typedef itk::MedianImageFilter< ImageType, ImageType > MedianFilterType;
typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType> GaussianFilterType;
typedef itk::TotalVariationDenoisingImageFilter<FloatImageType, FloatImageType> TotalVariationFilterType;
typedef itk::TotalVariationDenoisingImageFilter<VectorImageType, VectorImageType> VectorTotalVariationFilterType;
typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType;
typedef itk::InvertIntensityImageFilter< ImageType, ImageType > InversionFilterType;
typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, ImageType > GradientFilterType;
typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > LaplacianFilterType;
typedef itk::SobelEdgeDetectionImageFilter< FloatImageType, FloatImageType > SobelFilterType;
typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType;
typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType2;
typedef itk::CastImageFilter< ImageType, FloatImageType > ImagePTypeToFloatPTypeCasterType;
typedef itk::AddImageFilter< ImageType, ImageType, ImageType > AddFilterType;
typedef itk::SubtractImageFilter< ImageType, ImageType, ImageType > SubtractFilterType;
typedef itk::MultiplyImageFilter< ImageType, ImageType, ImageType > MultiplyFilterType;
typedef itk::DivideImageFilter< ImageType, ImageType, FloatImageType > DivideFilterType;
typedef itk::OrImageFilter< ImageType, ImageType > OrImageFilterType;
typedef itk::AndImageFilter< ImageType, ImageType > AndImageFilterType;
typedef itk::XorImageFilter< ImageType, ImageType > XorImageFilterType;
typedef itk::FlipImageFilter< ImageType > FlipImageFilterType;
typedef itk::LinearInterpolateImageFunction< ImageType, double > LinearInterpolatorType;
typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestInterpolatorType;
QmitkBasicImageProcessing::QmitkBasicImageProcessing()
: QmitkFunctionality(),
m_Controls(NULL),
m_SelectedImageNode(NULL),
m_TimeStepperAdapter(NULL),
m_SelectionListener(NULL)
{
}
QmitkBasicImageProcessing::~QmitkBasicImageProcessing()
{
//berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
//if(s)
// s->RemoveSelectionListener(m_SelectionListener);
}
void QmitkBasicImageProcessing::CreateQtPartControl(QWidget *parent)
{
if (m_Controls == NULL)
{
m_Controls = new Ui::QmitkBasicImageProcessingViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
//setup predictaes for combobox
mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3);
mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image");
m_Controls->m_ImageSelector2->SetDataStorage(this->GetDefaultDataStorage());
m_Controls->m_ImageSelector2->SetPredicate(mitk::NodePredicateAnd::New(dimensionPredicate, imagePredicate));
}
m_Controls->gbTwoImageOps->hide();
m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false);
}
void QmitkBasicImageProcessing::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->cbWhat1), SIGNAL( activated(int) ), this, SLOT( SelectAction(int) ) );
connect( (QObject*)(m_Controls->btnDoIt), SIGNAL(clicked()),(QObject*) this, SLOT(StartButtonClicked()));
connect( (QObject*)(m_Controls->cbWhat2), SIGNAL( activated(int) ), this, SLOT( SelectAction2(int) ) );
connect( (QObject*)(m_Controls->btnDoIt2), SIGNAL(clicked()),(QObject*) this, SLOT(StartButton2Clicked()));
connect( (QObject*)(m_Controls->rBOneImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) );
connect( (QObject*)(m_Controls->rBTwoImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) );
connect( (QObject*)(m_Controls->cbParam4), SIGNAL( activated(int) ), this, SLOT( SelectInterpolator(int) ) );
}
m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime,
GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromBIP");
}
void QmitkBasicImageProcessing::Activated()
{
QmitkFunctionality::Activated();
this->m_Controls->cbWhat1->clear();
this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select operation", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Denoising ---", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( GAUSSIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gaussian", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( MEDIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Median", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Total Variation", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Morphological ---", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( DILATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Dilation", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( EROSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Erosion", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( OPENING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Opening", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( CLOSING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Closing", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Edge Detection ---", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( GRADIENT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gradient", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( LAPLACIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Laplacian (2nd Derivative)", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( SOBEL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Sobel Operator", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Misc ---", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( THRESHOLD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Threshold", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( INVERSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Image Inversion", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Downsampling", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( FLIPPING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Flipping", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( RESAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Resample to", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat1->insertItem( RESCALE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Rescale image values", 0, QApplication::UnicodeUTF8) ));
this->m_Controls->cbWhat2->clear();
this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select on operation", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Arithmetric operations ---", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( ADD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Add to Image 1:", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( SUBTRACT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Subtract from Image 1:", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( MULTIPLY, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Multiply with Image 1:", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( RESAMPLE_TO, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Resample Image 1 to fit geometry:", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( DIVIDE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Divide Image 1 by:", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Boolean operations ---", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( AND, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "AND", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( OR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "OR", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbWhat2->insertItem( XOR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "XOR", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbParam4->clear();
this->m_Controls->cbParam4->insertItem( LINEAR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Linear", 0, QApplication::UnicodeUTF8) ) );
this->m_Controls->cbParam4->insertItem( NEAREST, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Nearest neighbor", 0, QApplication::UnicodeUTF8) ) );
m_Controls->dsbParam1->hide();
m_Controls->dsbParam2->hide();
m_Controls->dsbParam3->hide();
m_Controls->tlParam3->hide();
m_Controls->tlParam4->hide();
m_Controls->cbParam4->hide();
}
//datamanager selection changed
void QmitkBasicImageProcessing::OnSelectionChanged(std::vector<mitk::DataNode*> nodes)
{
//any nodes there?
if (!nodes.empty())
{
// reset GUI
// this->ResetOneImageOpPanel();
m_Controls->sliceNavigatorTime->setEnabled(false);
m_Controls->leImage1->setText("Select an Image in Data Manager");
m_Controls->tlWhat1->setEnabled(false);
m_Controls->cbWhat1->setEnabled(false);
m_Controls->tlWhat2->setEnabled(false);
m_Controls->cbWhat2->setEnabled(false);
m_SelectedImageNode->RemoveAllNodes();
//get the selected Node
mitk::DataNode* _DataNode = nodes.front();
*m_SelectedImageNode = _DataNode;
//try to cast to image
mitk::Image::Pointer tempImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
//no image
if( tempImage.IsNull() || (tempImage->IsInitialized() == false) )
{
m_Controls->leImage1->setText("Not an image.");
return;
}
//2D image
if( tempImage->GetDimension() < 3)
{
m_Controls->leImage1->setText("2D images are not supported.");
return;
}
//image
m_Controls->leImage1->setText(QString(m_SelectedImageNode->GetNode()->GetName().c_str()));
// button coding
if ( tempImage->GetDimension() > 3 )
{
m_Controls->sliceNavigatorTime->setEnabled(true);
m_Controls->tlTime->setEnabled(true);
}
m_Controls->tlWhat1->setEnabled(true);
m_Controls->cbWhat1->setEnabled(true);
m_Controls->tlWhat2->setEnabled(true);
m_Controls->cbWhat2->setEnabled(true);
}
}
void QmitkBasicImageProcessing::ChangeGUI()
{
if(m_Controls->rBOneImOp->isChecked())
{
m_Controls->gbTwoImageOps->hide();
m_Controls->gbOneImageOps->show();
}
else if(m_Controls->rBTwoImOp->isChecked())
{
m_Controls->gbOneImageOps->hide();
m_Controls->gbTwoImageOps->show();
}
}
void QmitkBasicImageProcessing::ResetOneImageOpPanel()
{
m_Controls->tlParam1->setText("Param1");
m_Controls->tlParam2->setText("Param2");
m_Controls->cbWhat1->setCurrentIndex(0);
m_Controls->tlTime->setEnabled(false);
this->ResetParameterPanel();
m_Controls->btnDoIt->setEnabled(false);
m_Controls->cbHideOrig->setEnabled(false);
}
void QmitkBasicImageProcessing::ResetParameterPanel()
{
m_Controls->tlParam->setEnabled(false);
m_Controls->tlParam1->setEnabled(false);
m_Controls->tlParam2->setEnabled(false);
m_Controls->tlParam3->setEnabled(false);
m_Controls->tlParam4->setEnabled(false);
m_Controls->sbParam1->setEnabled(false);
m_Controls->sbParam2->setEnabled(false);
m_Controls->dsbParam1->setEnabled(false);
m_Controls->dsbParam2->setEnabled(false);
m_Controls->dsbParam3->setEnabled(false);
m_Controls->cbParam4->setEnabled(false);
m_Controls->sbParam1->setValue(0);
m_Controls->sbParam2->setValue(0);
m_Controls->dsbParam1->setValue(0);
m_Controls->dsbParam2->setValue(0);
m_Controls->dsbParam3->setValue(0);
m_Controls->sbParam1->show();
m_Controls->sbParam2->show();
m_Controls->dsbParam1->hide();
m_Controls->dsbParam2->hide();
m_Controls->dsbParam3->hide();
m_Controls->cbParam4->hide();
m_Controls->tlParam3->hide();
m_Controls->tlParam4->hide();
}
void QmitkBasicImageProcessing::ResetTwoImageOpPanel()
{
m_Controls->cbWhat2->setCurrentIndex(0);
m_Controls->tlImage2->setEnabled(false);
m_Controls->m_ImageSelector2->setEnabled(false);
m_Controls->btnDoIt2->setEnabled(false);
}
void QmitkBasicImageProcessing::SelectAction(int action)
{
if ( ! m_SelectedImageNode->GetNode() ) return;
// Prepare GUI
this->ResetParameterPanel();
m_Controls->btnDoIt->setEnabled(false);
m_Controls->cbHideOrig->setEnabled(false);
QString text1 = "No Parameters";
QString text2 = "No Parameters";
QString text3 = "No Parameters";
QString text4 = "No Parameters";
if (action != 19)
{
m_Controls->dsbParam1->hide();
m_Controls->dsbParam2->hide();
m_Controls->dsbParam3->hide();
m_Controls->tlParam3->hide();
m_Controls->tlParam4->hide();
m_Controls->sbParam1->show();
m_Controls->sbParam2->show();
m_Controls->cbParam4->hide();
}
// check which operation the user has selected and set parameters and GUI accordingly
switch (action)
{
case 2:
{
m_SelectedAction = GAUSSIAN;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Variance:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 2 );
break;
}
case 3:
{
m_SelectedAction = MEDIAN;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 4:
{
m_SelectedAction = TOTALVARIATION;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
m_Controls->sbParam2->setEnabled(true);
text1 = "Number Iterations:";
text2 = "Regularization\n(Lambda/1000):";
m_Controls->sbParam1->setMinimum( 1 );
m_Controls->sbParam1->setMaximum( 1000 );
m_Controls->sbParam1->setValue( 40 );
m_Controls->sbParam2->setMinimum( 0 );
m_Controls->sbParam2->setMaximum( 100000 );
m_Controls->sbParam2->setValue( 1 );
break;
}
case 6:
{
m_SelectedAction = DILATION;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 7:
{
m_SelectedAction = EROSION;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 8:
{
m_SelectedAction = OPENING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 9:
{
m_SelectedAction = CLOSING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 11:
{
m_SelectedAction = GRADIENT;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "Sigma of Gaussian Kernel:\n(in Image Spacing Units)";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 2 );
break;
}
case 12:
{
m_SelectedAction = LAPLACIAN;
break;
}
case 13:
{
m_SelectedAction = SOBEL;
break;
}
case 15:
{
m_SelectedAction = THRESHOLD;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
m_Controls->sbParam2->setEnabled(true);
text1 = "Lower threshold:";
text2 = "Upper threshold:";
m_Controls->sbParam1->setMinimum( -100000 );
m_Controls->sbParam1->setMaximum( 100000 );
m_Controls->sbParam1->setValue( 0 );
m_Controls->sbParam2->setMinimum( -100000 );
m_Controls->sbParam2->setMaximum( 100000 );
m_Controls->sbParam2->setValue( 300 );
break;
}
case 16:
{
m_SelectedAction = INVERSION;
break;
}
case 17:
{
m_SelectedAction = DOWNSAMPLING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "Downsampling by Factor:";
m_Controls->sbParam1->setMinimum( 1 );
m_Controls->sbParam1->setMaximum( 100 );
m_Controls->sbParam1->setValue( 2 );
break;
}
case 18:
{
m_SelectedAction = FLIPPING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "Flip across axis:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 2 );
m_Controls->sbParam1->setValue( 1 );
break;
}
case 19:
{
m_SelectedAction = RESAMPLING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(false);
m_Controls->sbParam1->hide();
m_Controls->dsbParam1->show();
m_Controls->dsbParam1->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
m_Controls->sbParam2->setEnabled(false);
m_Controls->sbParam2->hide();
m_Controls->dsbParam2->show();
m_Controls->dsbParam2->setEnabled(true);
m_Controls->tlParam3->show();
m_Controls->tlParam3->setEnabled(true);
m_Controls->dsbParam3->show();
m_Controls->dsbParam3->setEnabled(true);
m_Controls->tlParam4->show();
m_Controls->tlParam4->setEnabled(true);
m_Controls->cbParam4->show();
m_Controls->cbParam4->setEnabled(true);
m_Controls->dsbParam1->setMinimum(0.01);
m_Controls->dsbParam1->setMaximum(10.0);
m_Controls->dsbParam1->setSingleStep(0.1);
m_Controls->dsbParam1->setValue(0.3);
m_Controls->dsbParam2->setMinimum(0.01);
m_Controls->dsbParam2->setMaximum(10.0);
m_Controls->dsbParam2->setSingleStep(0.1);
m_Controls->dsbParam2->setValue(0.3);
m_Controls->dsbParam3->setMinimum(0.01);
m_Controls->dsbParam3->setMaximum(10.0);
m_Controls->dsbParam3->setSingleStep(0.1);
m_Controls->dsbParam3->setValue(1.5);
text1 = "x-spacing:";
text2 = "y-spacing:";
text3 = "z-spacing:";
text4 = "Interplation:";
break;
}
case 20:
{
m_SelectedAction = RESCALE;
m_Controls->dsbParam1->show();
m_Controls->tlParam1->show();
m_Controls->dsbParam1->setEnabled(true);
m_Controls->tlParam1->setEnabled(true);
m_Controls->dsbParam2->show();
m_Controls->tlParam2->show();
m_Controls->dsbParam2->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
text1 = "Output minimum:";
text2 = "Output maximum:";
break;
}
default: return;
}
m_Controls->tlParam->setEnabled(true);
m_Controls->tlParam1->setText(text1);
m_Controls->tlParam2->setText(text2);
m_Controls->tlParam3->setText(text3);
m_Controls->tlParam4->setText(text4);
m_Controls->btnDoIt->setEnabled(true);
m_Controls->cbHideOrig->setEnabled(true);
}
void QmitkBasicImageProcessing::StartButtonClicked()
{
if(!m_SelectedImageNode->GetNode()) return;
this->BusyCursorOn();
mitk::Image::Pointer newImage;
try
{
newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
}
catch ( std::exception &e )
{
QString exceptionString = "An error occured during image loading:\n";
exceptionString.append( e.what() );
QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
this->BusyCursorOff();
return;
}
// check if input image is valid, casting does not throw exception when casting from 'NULL-Object'
if ( (! newImage) || (newImage->IsInitialized() == false) )
{
this->BusyCursorOff();
QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
return;
}
// check if operation is done on 4D a image time step
if(newImage->GetDimension() > 3)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(newImage);
timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
timeSelector->Update();
newImage = timeSelector->GetOutput();
}
// check if image or vector image
ImageType::Pointer itkImage = ImageType::New();
VectorImageType::Pointer itkVecImage = VectorImageType::New();
int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();
if(isVectorImage > 1)
{
CastToItkImage( newImage, itkVecImage );
}
else
{
CastToItkImage( newImage, itkImage );
}
std::stringstream nameAddition("");
int param1 = m_Controls->sbParam1->value();
int param2 = m_Controls->sbParam2->value();
double dparam1 = m_Controls->dsbParam1->value();
double dparam2 = m_Controls->dsbParam2->value();
double dparam3 = m_Controls->dsbParam3->value();
try{
switch (m_SelectedAction)
{
case GAUSSIAN:
{
GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
gaussianFilter->SetInput( itkImage );
gaussianFilter->SetVariance( param1 );
gaussianFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone();
nameAddition << "_Gaussian_var_" << param1;
std::cout << "Gaussian filtering successful." << std::endl;
break;
}
case MEDIAN:
{
MedianFilterType::Pointer medianFilter = MedianFilterType::New();
MedianFilterType::InputSizeType size;
size.Fill(param1);
medianFilter->SetRadius( size );
medianFilter->SetInput(itkImage);
medianFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone();
nameAddition << "_Median_radius_" << param1;
std::cout << "Median Filtering successful." << std::endl;
break;
}
case TOTALVARIATION:
{
if(isVectorImage > 1)
{
VectorTotalVariationFilterType::Pointer TVFilter
= VectorTotalVariationFilterType::New();
TVFilter->SetInput( itkVecImage.GetPointer() );
TVFilter->SetNumberIterations(param1);
TVFilter->SetLambda(double(param2)/1000.);
TVFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
}
else
{
ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New();
floatCaster->SetInput( itkImage );
floatCaster->Update();
FloatImageType::Pointer fImage = floatCaster->GetOutput();
TotalVariationFilterType::Pointer TVFilter
= TotalVariationFilterType::New();
TVFilter->SetInput( fImage.GetPointer() );
TVFilter->SetNumberIterations(param1);
TVFilter->SetLambda(double(param2)/1000.);
TVFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
}
nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
std::cout << "Total Variation Filtering successful." << std::endl;
break;
}
case DILATION:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
dilationFilter->SetInput( itkImage );
dilationFilter->SetKernel( binaryBall );
dilationFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone();
nameAddition << "_Dilated_by_" << param1;
std::cout << "Dilation successful." << std::endl;
break;
}
case EROSION:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
erosionFilter->SetInput( itkImage );
erosionFilter->SetKernel( binaryBall );
erosionFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone();
nameAddition << "_Eroded_by_" << param1;
std::cout << "Erosion successful." << std::endl;
break;
}
case OPENING:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
openFilter->SetInput( itkImage );
openFilter->SetKernel( binaryBall );
openFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone();
nameAddition << "_Opened_by_" << param1;
std::cout << "Opening successful." << std::endl;
break;
}
case CLOSING:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
closeFilter->SetInput( itkImage );
closeFilter->SetKernel( binaryBall );
closeFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone();
nameAddition << "_Closed_by_" << param1;
std::cout << "Closing successful." << std::endl;
break;
}
case GRADIENT:
{
GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
gradientFilter->SetInput( itkImage );
gradientFilter->SetSigma( param1 );
gradientFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone();
nameAddition << "_Gradient_sigma_" << param1;
std::cout << "Gradient calculation successful." << std::endl;
break;
}
case LAPLACIAN:
{
// the laplace filter requires a float type image as input, we need to cast the itkImage
// to correct type
ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
caster->SetInput( itkImage );
caster->Update();
FloatImageType::Pointer fImage = caster->GetOutput();
LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
laplacianFilter->SetInput( fImage );
laplacianFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone();
nameAddition << "_Second_Derivative";
std::cout << "Laplacian filtering successful." << std::endl;
break;
}
case SOBEL:
{
// the sobel filter requires a float type image as input, we need to cast the itkImage
// to correct type
ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
caster->SetInput( itkImage );
caster->Update();
FloatImageType::Pointer fImage = caster->GetOutput();
SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
sobelFilter->SetInput( fImage );
sobelFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone();
nameAddition << "_Sobel";
std::cout << "Edge Detection successful." << std::endl;
break;
}
case THRESHOLD:
{
ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
thFilter->SetInsideValue(1);
thFilter->SetOutsideValue(0);
thFilter->SetInput(itkImage);
thFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone();
nameAddition << "_Threshold";
std::cout << "Thresholding successful." << std::endl;
break;
}
case INVERSION:
{
InversionFilterType::Pointer invFilter = InversionFilterType::New();
mitk::ScalarType min = newImage->GetScalarValueMin();
mitk::ScalarType max = newImage->GetScalarValueMax();
invFilter->SetMaximum( max + min );
invFilter->SetInput(itkImage);
invFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone();
nameAddition << "_Inverted";
std::cout << "Image inversion successful." << std::endl;
break;
}
case DOWNSAMPLING:
{
ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
downsampler->SetInput( itkImage );
NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
downsampler->SetInterpolator( interpolator );
downsampler->SetDefaultPixelValue( 0 );
ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
spacing *= (double) param1;
downsampler->SetOutputSpacing( spacing );
downsampler->SetOutputOrigin( itkImage->GetOrigin() );
downsampler->SetOutputDirection( itkImage->GetDirection() );
ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
for ( int i = 0; i < 3; ++i )
{
size[i] /= param1;
}
downsampler->SetSize( size );
downsampler->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone();
nameAddition << "_Downsampled_by_" << param1;
std::cout << "Downsampling successful." << std::endl;
break;
}
case FLIPPING:
{
FlipImageFilterType::Pointer flipper = FlipImageFilterType::New();
flipper->SetInput( itkImage );
itk::FixedArray<bool, 3> flipAxes;
for(int i=0; i<3; ++i)
{
if(i == param1)
{
flipAxes[i] = true;
}
else
{
flipAxes[i] = false;
}
}
flipper->SetFlipAxes(flipAxes);
flipper->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone();
std::cout << "Image flipping successful." << std::endl;
break;
}
case RESAMPLING:
{
std::string selectedInterpolator;
ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New();
switch (m_SelectedInterpolation)
{
case LINEAR:
{
LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
resampler->SetInterpolator(interpolator);
selectedInterpolator = "Linear";
break;
}
case NEAREST:
{
NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
resampler->SetInterpolator(interpolator);
selectedInterpolator = "Nearest";
break;
}
default:
{
LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
resampler->SetInterpolator(interpolator);
selectedInterpolator = "Linear";
break;
}
}
resampler->SetInput( itkImage );
resampler->SetOutputOrigin( itkImage->GetOrigin() );
ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize();
ImageType::SpacingType input_spacing = itkImage->GetSpacing();
ImageType::SizeType output_size;
ImageType::SpacingType output_spacing;
output_size[0] = input_size[0] * (input_spacing[0] / dparam1);
output_size[1] = input_size[1] * (input_spacing[1] / dparam2);
output_size[2] = input_size[2] * (input_spacing[2] / dparam3);
output_spacing [0] = dparam1;
output_spacing [1] = dparam2;
output_spacing [2] = dparam3;
resampler->SetSize( output_size );
resampler->SetOutputSpacing( output_spacing );
resampler->SetOutputDirection( itkImage->GetDirection() );
resampler->UpdateLargestPossibleRegion();
ImageType::Pointer resampledImage = resampler->GetOutput();
newImage = mitk::ImportItkImage( resampledImage );
nameAddition << "_Resampled_" << selectedInterpolator;
std::cout << "Resampling successful." << std::endl;
break;
}
case RESCALE:
{
FloatImageType::Pointer floatImage = FloatImageType::New();
CastToItkImage( newImage, floatImage );
itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::Pointer filter = itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::New();
filter->SetInput(0, floatImage);
filter->SetOutputMinimum(dparam1);
filter->SetOutputMaximum(dparam2);
filter->Update();
floatImage = filter->GetOutput();
newImage = mitk::Image::New();
newImage->InitializeByItk(floatImage.GetPointer());
newImage->SetVolume(floatImage->GetBufferPointer());
nameAddition << "_Rescaled";
std::cout << "Rescaling successful." << std::endl;
break;
}
default:
this->BusyCursorOff();
return;
}
}
catch (...)
{
this->BusyCursorOff();
QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
return;
}
newImage->DisconnectPipeline();
// adjust level/window to new image
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( newImage );
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
levWinProp->SetLevelWindow( levelwindow );
// compose new image name
std::string name = m_SelectedImageNode->GetNode()->GetName();
if (name.find(".pic.gz") == name.size() -7 )
{
name = name.substr(0,name.size() -7);
}
name.append( nameAddition.str() );
// create final result MITK data storage node
mitk::DataNode::Pointer result = mitk::DataNode::New();
result->SetProperty( "levelwindow", levWinProp );
result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
result->SetData( newImage );
// for vector images, a different mapper is needed
if(isVectorImage > 1)
{
mitk::VectorImageMapper2D::Pointer mapper =
mitk::VectorImageMapper2D::New();
result->SetMapper(1,mapper);
}
// reset GUI to ease further processing
// this->ResetOneImageOpPanel();
// add new image to data storage and set as active to ease further processing
GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
if ( m_Controls->cbHideOrig->isChecked() == true )
m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
// TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result);
// show the results
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
this->BusyCursorOff();
}
void QmitkBasicImageProcessing::SelectAction2(int operation)
{
// check which operation the user has selected and set parameters and GUI accordingly
switch (operation)
{
case 2:
m_SelectedOperation = ADD;
break;
case 3:
m_SelectedOperation = SUBTRACT;
break;
case 4:
m_SelectedOperation = MULTIPLY;
break;
case 5:
m_SelectedOperation = DIVIDE;
break;
case 6:
m_SelectedOperation = RESAMPLE_TO;
break;
case 8:
m_SelectedOperation = AND;
break;
case 9:
m_SelectedOperation = OR;
break;
case 10:
m_SelectedOperation = XOR;
break;
default:
// this->ResetTwoImageOpPanel();
return;
}
m_Controls->tlImage2->setEnabled(true);
m_Controls->m_ImageSelector2->setEnabled(true);
m_Controls->btnDoIt2->setEnabled(true);
}
void QmitkBasicImageProcessing::StartButton2Clicked()
{
mitk::Image::Pointer newImage1 = dynamic_cast<mitk::Image*>
(m_SelectedImageNode->GetNode()->GetData());
mitk::Image::Pointer newImage2 = dynamic_cast<mitk::Image*>
(m_Controls->m_ImageSelector2->GetSelectedNode()->GetData());
// check if images are valid
if( (!newImage1) || (!newImage2) || (newImage1->IsInitialized() == false) || (newImage2->IsInitialized() == false) )
{
itkGenericExceptionMacro(<< "At least one of the input images are broken or not initialized. Returning");
return;
}
this->BusyCursorOn();
// this->ResetTwoImageOpPanel();
// check if 4D image and use filter on correct time step
int time = ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos();
- if(time>=0)
+ if(newImage1->GetDimension() > 3)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(newImage1);
timeSelector->SetTimeNr( time );
timeSelector->UpdateLargestPossibleRegion();
newImage1 = timeSelector->GetOutput();
newImage1->DisconnectPipeline();
timeSelector->SetInput(newImage2);
timeSelector->SetTimeNr( time );
timeSelector->UpdateLargestPossibleRegion();
newImage2 = timeSelector->GetOutput();
newImage2->DisconnectPipeline();
}
// reset GUI for better usability
// this->ResetTwoImageOpPanel();
ImageType::Pointer itkImage1 = ImageType::New();
ImageType::Pointer itkImage2 = ImageType::New();
CastToItkImage( newImage1, itkImage1 );
CastToItkImage( newImage2, itkImage2 );
// Remove temp image
newImage2 = NULL;
std::string nameAddition = "";
try
{
switch (m_SelectedOperation)
{
case ADD:
{
AddFilterType::Pointer addFilter = AddFilterType::New();
addFilter->SetInput1( itkImage1 );
addFilter->SetInput2( itkImage2 );
addFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(addFilter->GetOutput())->Clone();
nameAddition = "_Added";
}
break;
case SUBTRACT:
{
SubtractFilterType::Pointer subFilter = SubtractFilterType::New();
subFilter->SetInput1( itkImage1 );
subFilter->SetInput2( itkImage2 );
subFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(subFilter->GetOutput())->Clone();
nameAddition = "_Subtracted";
}
break;
case MULTIPLY:
{
MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New();
multFilter->SetInput1( itkImage1 );
multFilter->SetInput2( itkImage2 );
multFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(multFilter->GetOutput())->Clone();
nameAddition = "_Multiplied";
}
break;
case DIVIDE:
{
DivideFilterType::Pointer divFilter = DivideFilterType::New();
divFilter->SetInput1( itkImage1 );
divFilter->SetInput2( itkImage2 );
divFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage<FloatImageType>(divFilter->GetOutput())->Clone();
nameAddition = "_Divided";
}
break;
case AND:
{
AndImageFilterType::Pointer andFilter = AndImageFilterType::New();
andFilter->SetInput1( itkImage1 );
andFilter->SetInput2( itkImage2 );
andFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(andFilter->GetOutput())->Clone();
nameAddition = "_AND";
break;
}
case OR:
{
OrImageFilterType::Pointer orFilter = OrImageFilterType::New();
orFilter->SetInput1( itkImage1 );
orFilter->SetInput2( itkImage2 );
orFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(orFilter->GetOutput())->Clone();
nameAddition = "_OR";
break;
}
case XOR:
{
XorImageFilterType::Pointer xorFilter = XorImageFilterType::New();
xorFilter->SetInput1( itkImage1 );
xorFilter->SetInput2( itkImage2 );
xorFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(xorFilter->GetOutput())->Clone();
nameAddition = "_XOR";
break;
}
case RESAMPLE_TO:
{
itk::NearestNeighborInterpolateImageFunction<ImageType>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<ImageType>::New();
ResampleImageFilterType2::Pointer resampleFilter = ResampleImageFilterType2::New();
resampleFilter->SetInput( itkImage1 );
resampleFilter->SetReferenceImage( itkImage2 );
resampleFilter->SetUseReferenceImage( true );
resampleFilter->SetInterpolator( nn_interpolator );
resampleFilter->SetDefaultPixelValue( 0 );
- ImageType::Pointer resampledImage = resampleFilter->GetOutput()->Clone();
-
try
{
resampleFilter->UpdateLargestPossibleRegion();
}
catch( const itk::ExceptionObject &e)
{
MITK_WARN << "Updating resampling filter failed. ";
MITK_WARN << "REASON: " << e.what();
}
+ ImageType::Pointer resampledImage = resampleFilter->GetOutput();
+
newImage1 = mitk::ImportItkImage( resampledImage )->Clone();
nameAddition = "_Resampled";
break;
}
default:
std::cout << "Something went wrong..." << std::endl;
this->BusyCursorOff();
return;
}
}
catch (const itk::ExceptionObject& e )
{
this->BusyCursorOff();
QMessageBox::warning(NULL, "ITK Exception", e.what() );
QMessageBox::warning(NULL, "Warning", "Problem when applying arithmetic operation to two images. Check dimensions of input images.");
return;
}
// disconnect pipeline; images will not be reused
newImage1->DisconnectPipeline();
itkImage1 = NULL;
itkImage2 = NULL;
// adjust level/window to new image and compose new image name
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( newImage1 );
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
levWinProp->SetLevelWindow( levelwindow );
std::string name = m_SelectedImageNode->GetNode()->GetName();
if (name.find(".pic.gz") == name.size() -7 )
{
name = name.substr(0,name.size() -7);
}
// create final result MITK data storage node
mitk::DataNode::Pointer result = mitk::DataNode::New();
result->SetProperty( "levelwindow", levWinProp );
result->SetProperty( "name", mitk::StringProperty::New( (name + nameAddition ).c_str() ));
result->SetData( newImage1 );
GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
// show only the newly created image
m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
m_Controls->m_ImageSelector2->GetSelectedNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
// show the newly created image
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
this->BusyCursorOff();
}
void QmitkBasicImageProcessing::SelectInterpolator(int interpolator)
{
switch (interpolator)
{
case 0:
{
m_SelectedInterpolation = LINEAR;
break;
}
case 1:
{
m_SelectedInterpolation = NEAREST;
break;
}
}
}
diff --git a/Plugins/org.mitk.gui.qt.candystore/CMakeLists.txt b/Plugins/org.mitk.gui.qt.candystore/CMakeLists.txt
deleted file mode 100644
index e34977274f..0000000000
--- a/Plugins/org.mitk.gui.qt.candystore/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-project(org_mitk_gui_qt_candystore)
-
-MACRO_CREATE_MITK_CTK_PLUGIN(
- EXPORT_DIRECTIVE CANDYSTORE_EXPORT
- EXPORTED_INCLUDE_SUFFIXES src
- MODULE_DEPENDENCIES MitkQtWidgetsExt
- PACKAGE_DEPENDS CTK
-)
diff --git a/Plugins/org.mitk.gui.qt.candystore/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.candystore/documentation/UserManual/Manual.dox
deleted file mode 100644
index eb80add408..0000000000
--- a/Plugins/org.mitk.gui.qt.candystore/documentation/UserManual/Manual.dox
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
-\page org_mitk_gui_qt_candystore Candy Store
-
-\imageMacro{icon.png,"Icon of Candy Store",2.00}
-
-Available sections:
- - \ref org_mitk_gui_qt_candystoreOverview
-
-\section org_mitk_gui_qt_candystoreOverview
-Describe the features of your awesome plugin here
-<ul>
-<li>Increases productivity
-<li>Creates beautiful images
-<li>Generates PhD thesis
-<li>Brings world peace
-</ul>
-
-*/
diff --git a/Plugins/org.mitk.gui.qt.candystore/documentation/UserManual/icon.xpm b/Plugins/org.mitk.gui.qt.candystore/documentation/UserManual/icon.xpm
deleted file mode 100644
index 9057c20bc6..0000000000
--- a/Plugins/org.mitk.gui.qt.candystore/documentation/UserManual/icon.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * icon_xpm[] = {
-"16 16 2 1",
-" c #FF0000",
-". c #000000",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Plugins/org.mitk.gui.qt.candystore/plugin.xml b/Plugins/org.mitk.gui.qt.candystore/plugin.xml
deleted file mode 100644
index 8a9bb6095a..0000000000
--- a/Plugins/org.mitk.gui.qt.candystore/plugin.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin>
-
- <extension point="org.blueberry.ui.views">
- <view id="org.mitk.views.candystoreview"
- name="Candy Store"
- class="CandyStoreView"
- icon="resources/Candy_icon.png" />
- </extension>
-
-</plugin>
diff --git a/Plugins/org.mitk.gui.qt.candystore/resources/Candy_icon.png b/Plugins/org.mitk.gui.qt.candystore/resources/Candy_icon.png
deleted file mode 100644
index f71e77664c..0000000000
Binary files a/Plugins/org.mitk.gui.qt.candystore/resources/Candy_icon.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.candystore/resources/icon.xpm b/Plugins/org.mitk.gui.qt.candystore/resources/icon.xpm
deleted file mode 100644
index 9057c20bc6..0000000000
--- a/Plugins/org.mitk.gui.qt.candystore/resources/icon.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * icon_xpm[] = {
-"16 16 2 1",
-" c #FF0000",
-". c #000000",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/files.cmake b/Plugins/org.mitk.gui.qt.cmdlinemodules/files.cmake
index bd086df2f0..5b8c83a816 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/files.cmake
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/files.cmake
@@ -1,65 +1,65 @@
set(SRC_CPP_FILES
QmitkCmdLineModuleMenuComboBox.cpp
)
set(INTERNAL_CPP_FILES
QmitkDataStorageComboBoxWithSelectNone.cpp
QmitkDirectoryListWidget.cpp
QmitkFileListWidget.cpp
QmitkCmdLineModuleGui.cpp
QmitkCmdLineModuleFactoryGui.cpp
QmitkUiLoader.cpp
org_mitk_gui_qt_cmdlinemodules_Activator.cpp
CommandLineModulesViewConstants.cpp
CommandLineModulesViewControls.cpp
CommandLineModulesPreferencesPage.cpp
CommandLineModulesView.cpp
- QmitkCmdLineModuleProgressWidget.cpp
+ QmitkCmdLineModuleRunner.cpp
)
set(UI_FILES
src/internal/QmitkPathListWidget.ui
src/internal/CommandLineModulesViewControls.ui
src/internal/QmitkCmdLineModuleProgressWidget.ui
)
set(MOC_H_FILES
src/QmitkCmdLineModuleMenuComboBox.h
src/internal/QmitkDataStorageComboBoxWithSelectNone.h
src/internal/QmitkDirectoryListWidget.h
src/internal/QmitkFileListWidget.h
src/internal/QmitkCmdLineModuleGui.h
src/internal/QmitkUiLoader.h
src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h
src/internal/CommandLineModulesViewControls.h
src/internal/CommandLineModulesPreferencesPage.h
src/internal/CommandLineModulesView.h
- src/internal/QmitkCmdLineModuleProgressWidget.h
+ src/internal/QmitkCmdLineModuleRunner.h
)
# list of resource files which can be used by the plug-in
# system without loading the plug-ins shared library,
# for example the icon used in the menu and tabs for the
# plug-in views in the workbench
set(CACHED_RESOURCE_FILES
resources/icon.xpm
resources/run.png
resources/stop.png
plugin.xml
)
# list of Qt .qrc files which contain additional resources
# specific to this plugin
set(QRC_FILES
resources/CommandLineModulesResources.qrc
)
set(CPP_FILES )
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.cpp b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.cpp
index 96598270de..049842aaff 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.cpp
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.cpp
@@ -1,553 +1,552 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) University College London (UCL).
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <berryIPreferences.h>
#include <berryIPreferencesService.h>
#include <berryIBerryPreferences.h>
// Qmitk
#include "CommandLineModulesView.h"
#include "CommandLineModulesViewConstants.h"
#include "CommandLineModulesViewControls.h"
#include "CommandLineModulesPreferencesPage.h"
#include "QmitkCmdLineModuleFactoryGui.h"
#include "QmitkCmdLineModuleGui.h"
-#include "QmitkCmdLineModuleProgressWidget.h"
+#include "QmitkCmdLineModuleRunner.h"
// Qt
#include <QDebug>
#include <QDir>
#include <QAction>
#include <QVBoxLayout>
#include <QLayoutItem>
#include <QWidgetItem>
#include <QMessageBox>
#include <QtConcurrentMap>
// CTK
#include <ctkCmdLineModuleManager.h>
#include <ctkCmdLineModuleFrontend.h>
#include <ctkCmdLineModuleBackendLocalProcess.h>
#include <ctkCmdLineModuleDefaultPathBuilder.h>
#include <ctkCmdLineModuleDirectoryWatcher.h>
#include <ctkCmdLineModuleReference.h>
#include <ctkCmdLineModuleDescription.h>
#include <ctkCmdLineModuleParameter.h>
#include <ctkCmdLineModuleUtils.h>
#include <ctkCmdLineModuleConcurrentHelpers.h>
//-----------------------------------------------------------------------------
CommandLineModulesView::CommandLineModulesView()
: m_Controls(NULL)
, m_Parent(NULL)
, m_Layout(NULL)
, m_ModuleManager(NULL)
, m_ModuleBackend(NULL)
, m_DirectoryWatcher(NULL)
, m_TemporaryDirectoryName("")
, m_MaximumConcurrentProcesses(4)
, m_CurrentlyRunningProcesses(0)
, m_DebugOutput(false)
, m_XmlTimeoutSeconds(30) // 30 seconds = QProcess default timeout.
{
}
//-----------------------------------------------------------------------------
CommandLineModulesView::~CommandLineModulesView()
{
if (m_ModuleManager != NULL)
{
delete m_ModuleManager;
}
if (m_ModuleBackend != NULL)
{
delete m_ModuleBackend;
}
if (m_DirectoryWatcher != NULL)
{
delete m_DirectoryWatcher;
}
if (m_Layout != NULL)
{
delete m_Layout;
}
for (int i = 0; i < m_ListOfModules.size(); i++)
{
delete m_ListOfModules[i];
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::SetFocus()
{
this->m_Controls->m_ComboBox->setFocus();
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::CreateQtPartControl( QWidget *parent )
{
m_Parent = parent;
if (!m_Controls)
{
// We create CommandLineModulesViewControls, which derives from the Qt generated class.
m_Controls = new CommandLineModulesViewControls(parent);
- // Create a layout to contain a display of QmitkCmdLineModuleProgressWidget.
+ // Create a layout to contain a display of QmitkCmdLineModuleRunner.
m_Layout = new QVBoxLayout(m_Controls->m_RunningWidgets);
m_Layout->setContentsMargins(0,0,0,0);
m_Layout->setSpacing(0);
// This must be done independent of other preferences, as we need it before
// we create the ctkCmdLineModuleManager to initialise the Cache.
this->RetrieveAndStoreTemporaryDirectoryPreferenceValues();
this->RetrieveAndStoreValidationMode();
// Start to create the command line module infrastructure.
m_ModuleBackend = new ctkCmdLineModuleBackendLocalProcess();
m_ModuleManager = new ctkCmdLineModuleManager(m_ValidationMode, m_TemporaryDirectoryName);
// Set the main object, the ctkCmdLineModuleManager onto all the objects that need it.
m_Controls->m_ComboBox->SetManager(m_ModuleManager);
m_DirectoryWatcher = new ctkCmdLineModuleDirectoryWatcher(m_ModuleManager);
connect(this->m_DirectoryWatcher, SIGNAL(errorDetected(QString)), this, SLOT(OnDirectoryWatcherErrorsDetected(QString)));
m_ModuleManager->registerBackend(m_ModuleBackend);
// Setup the remaining preferences.
this->RetrieveAndStorePreferenceValues();
// Connect signals to slots after we have set up GUI.
connect(this->m_Controls->m_RunButton, SIGNAL(pressed()), this, SLOT(OnRunButtonPressed()));
connect(this->m_Controls->m_RestoreDefaults, SIGNAL(pressed()), this, SLOT(OnRestoreButtonPressed()));
connect(this->m_Controls->m_ComboBox, SIGNAL(actionChanged(QAction*)), this, SLOT(OnActionChanged(QAction*)));
connect(this->m_Controls->m_TabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(OnTabCloseRequested(int)));
connect(this->m_Controls->m_ClearXMLCache, SIGNAL(pressed()), this, SLOT(OnClearCache()));
connect(this->m_Controls->m_ReloadModules, SIGNAL(pressed()), this, SLOT(OnReloadModules()));
this->UpdateRunButtonEnabledStatus();
}
}
//-----------------------------------------------------------------------------
berry::IBerryPreferences::Pointer CommandLineModulesView::RetrievePreferences()
{
berry::IPreferencesService::Pointer prefService
= berry::Platform::GetServiceRegistry()
.GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
assert( prefService );
std::string id = "/" + CommandLineModulesViewConstants::VIEW_ID;
berry::IBerryPreferences::Pointer prefs
= (prefService->GetSystemPreferences()->Node(id))
.Cast<berry::IBerryPreferences>();
assert( prefs );
return prefs;
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::RetrieveAndStoreTemporaryDirectoryPreferenceValues()
{
berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences();
QString fallbackTmpDir = QDir::tempPath();
m_TemporaryDirectoryName = QString::fromStdString(
prefs->Get(CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME, fallbackTmpDir.toStdString()));
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::RetrieveAndStoreValidationMode()
{
berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences();
int value = prefs->GetInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, 0);
if (value == 0)
{
m_ValidationMode = ctkCmdLineModuleManager::STRICT_VALIDATION;
}
else if (value == 1)
{
m_ValidationMode = ctkCmdLineModuleManager::SKIP_VALIDATION;
}
else
{
m_ValidationMode = ctkCmdLineModuleManager::WEAK_VALIDATION;
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::RetrieveAndStorePreferenceValues()
{
berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences();
QString fallbackHomeDir = QDir::homePath();
m_OutputDirectoryName = QString::fromStdString(
prefs->Get(CommandLineModulesViewConstants::OUTPUT_DIRECTORY_NODE_NAME, fallbackHomeDir.toStdString()));
m_MaximumConcurrentProcesses = prefs->GetInt(CommandLineModulesViewConstants::MAX_CONCURRENT, 4);
m_XmlTimeoutSeconds = prefs->GetInt(CommandLineModulesViewConstants::XML_TIMEOUT_SECS, 30);
m_ModuleManager->setTimeOutForXMLRetrieval(m_XmlTimeoutSeconds * 1000); // preference is in seconds, underlying CTK library in milliseconds.
// Get the flag for debug output, useful when parsing all the XML.
m_DebugOutput = prefs->GetBool(CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME, false);
m_DirectoryWatcher->setDebug(m_DebugOutput);
// Show/Hide the advanced widgets
this->m_Controls->SetAdvancedWidgetsVisible(prefs->GetBool(CommandLineModulesViewConstants::SHOW_ADVANCED_WIDGETS_NAME, false));
bool loadApplicationDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR, false);
bool loadApplicationDirCliModules = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR_CLI_MODULES, true);
bool loadHomeDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR, false);
bool loadHomeDirCliModules = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR_CLI_MODULES, false);
bool loadCurrentDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR, false);
bool loadCurrentDirCliModules = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR_CLI_MODULES, false);
bool loadAutoLoadDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR, false);
// Get some default application paths.
// Here we can use the preferences to set up the builder,
ctkCmdLineModuleDefaultPathBuilder builder;
if (loadApplicationDir) builder.addApplicationDir();
if (loadApplicationDirCliModules) builder.addApplicationDir("cli-modules");
if (loadHomeDir) builder.addHomeDir();
if (loadHomeDirCliModules) builder.addHomeDir("cli-modules");
if (loadCurrentDir) builder.addCurrentDir();
if (loadCurrentDirCliModules) builder.addCurrentDir("cli-modules");
if (loadAutoLoadDir) builder.addCtkModuleLoadPath();
// and then we ask the builder to set up the paths.
QStringList defaultPaths = builder.getDirectoryList();
// We get additional directory paths from preferences.
QString pathString = QString::fromStdString(prefs->Get(CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME, ""));
QStringList additionalPaths = pathString.split(";", QString::SkipEmptyParts);
// Combine the sets of directory paths.
QStringList totalPaths;
totalPaths << defaultPaths;
totalPaths << additionalPaths;
QString additionalModulesString = QString::fromStdString(prefs->Get(CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME, ""));
QStringList additionalModules = additionalModulesString.split(";", QString::SkipEmptyParts);
// OnPreferencesChanged can be called for each preference in a dialog box, so
// when you hit "OK", it is called repeatedly, whereas we want to only call these only once.
if (m_DirectoryPaths != totalPaths)
{
m_DirectoryPaths = totalPaths;
m_DirectoryWatcher->setDirectories(totalPaths);
}
if (m_ModulePaths != additionalModules)
{
m_ModulePaths = additionalModules;
m_DirectoryWatcher->setAdditionalModules(additionalModules);
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnPreferencesChanged(const berry::IBerryPreferences* /*prefs*/)
{
this->RetrieveAndStoreTemporaryDirectoryPreferenceValues();
this->RetrieveAndStoreValidationMode();
this->RetrieveAndStorePreferenceValues();
}
//-----------------------------------------------------------------------------
ctkCmdLineModuleReference CommandLineModulesView::GetReferenceByFullName(QString fullName)
{
ctkCmdLineModuleReference result;
QList<ctkCmdLineModuleReference> references = this->m_ModuleManager->moduleReferences();
ctkCmdLineModuleReference ref;
foreach(ref, references)
{
QString name = ref.description().categoryDotTitle();
if (name == fullName)
{
result = ref;
}
}
return result;
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnActionChanged(QAction* action)
{
QString fullName = action->objectName();
ctkCmdLineModuleReference ref = this->GetReferenceByFullName(fullName);
// ref should never be invalid, as the menu was generated from each ctkCmdLineModuleReference.
// But just to be sure ... if invalid, don't do anything.
if (ref)
{
// Check if we already have the reference.
int tabIndex = -1;
for (int i = 0; i < m_ListOfModules.size(); i++)
{
ctkCmdLineModuleReference tabsReference = m_ListOfModules[i]->moduleReference();
if (ref.location() == tabsReference.location())
{
tabIndex = i;
break;
}
}
// i.e. we found a matching tab, so just switch to it.
if (tabIndex != -1)
{
m_Controls->m_TabWidget->setCurrentIndex(tabIndex);
}
else // i.e. we did not find a matching tab
{
// In this case, we need to create a new tab, and give
// it a GUI for the user to setup the parameters with.
QmitkCmdLineModuleFactoryGui factory(this->GetDataStorage());
ctkCmdLineModuleFrontend *frontEnd = factory.create(ref);
QmitkCmdLineModuleGui *theGui = dynamic_cast<QmitkCmdLineModuleGui*>(frontEnd);
// Add to list and tab wigdget
m_ListOfModules.push_back(frontEnd);
int tabIndex = m_Controls->m_TabWidget->addTab(theGui->getGui(), ref.description().title());
m_Controls->m_TabWidget->setTabToolTip(tabIndex, ref.description().title() + ":" + ref.xmlValidationErrorString());
// Here lies a small caveat.
//
// The XML may specify a default output file name.
// However, this will probably have no file path, so we should probably add one.
// Otherwise you will likely be trying to write in the application installation folder
// eg. C:/Program Files (Windows) or /Applications/ (Mac)
//
// Also, we may find that 3rd party apps crash when they can't write.
// So lets plan for the worst and hope for the best :-)
QString parameterName;
QList<ctkCmdLineModuleParameter> parameters;
parameters = frontEnd->parameters("image", ctkCmdLineModuleFrontend::Output);
parameters << frontEnd->parameters("file", ctkCmdLineModuleFrontend::Output);
parameters << frontEnd->parameters("geometry", ctkCmdLineModuleFrontend::Output);
foreach (ctkCmdLineModuleParameter parameter, parameters)
{
parameterName = parameter.name();
QString outputFileName = frontEnd->value(parameterName, ctkCmdLineModuleFrontend::DisplayRole).toString();
QFileInfo outputFileInfo(outputFileName);
if (outputFileInfo.absoluteFilePath() != outputFileName)
{
QDir defaultOutputDir(m_OutputDirectoryName);
QFileInfo replacementFileInfo(defaultOutputDir, outputFileName);
frontEnd->setValue(parameterName, replacementFileInfo.absoluteFilePath(), ctkCmdLineModuleFrontend::DisplayRole);
}
}
}
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnTabCloseRequested(int tabNumber)
{
ctkCmdLineModuleFrontend *frontEnd = m_ListOfModules[tabNumber];
m_Controls->m_TabWidget->removeTab(tabNumber);
m_ListOfModules.removeAt(tabNumber);
delete frontEnd;
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::AskUserToSelectAModule() const
{
QMessageBox msgBox;
msgBox.setText("Please select a module!");
msgBox.setIcon(QMessageBox::Warning);
msgBox.exec();
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnRestoreButtonPressed()
{
int tabNumber = m_Controls->m_TabWidget->currentIndex();
if (tabNumber >= 0)
{
ctkCmdLineModuleFrontend *frontEnd = m_ListOfModules[tabNumber];
frontEnd->resetValues();
}
else
{
this->AskUserToSelectAModule();
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnRunButtonPressed()
{
int tabNumber = m_Controls->m_TabWidget->currentIndex();
if (tabNumber >= 0)
{
- // 1. Create a new QmitkCmdLineModuleProgressWidget to represent the running widget.
- QmitkCmdLineModuleProgressWidget *widget = new QmitkCmdLineModuleProgressWidget(m_Controls->m_RunningWidgets);
+ // 1. Create a new QmitkCmdLineModuleRunner to represent the running widget.
+ QmitkCmdLineModuleRunner *widget = new QmitkCmdLineModuleRunner(m_Controls->m_RunningWidgets);
widget->SetDataStorage(this->GetDataStorage());
widget->SetManager(m_ModuleManager);
- widget->SetTemporaryDirectory(m_TemporaryDirectoryName);
widget->SetOutputDirectory(m_OutputDirectoryName);
// 2. Create a new front end.
QmitkCmdLineModuleFactoryGui factory(this->GetDataStorage());
ctkCmdLineModuleFrontend *frontEndOnCurrentTab = m_ListOfModules[tabNumber];
QmitkCmdLineModuleGui *frontEndGuiOnCurrentTab = dynamic_cast<QmitkCmdLineModuleGui*>(frontEndOnCurrentTab);
ctkCmdLineModuleReference currentTabFrontendReferences = frontEndGuiOnCurrentTab->moduleReference();
ctkCmdLineModuleFrontend *newFrontEnd = factory.create(currentTabFrontendReferences);
QmitkCmdLineModuleGui *newFrontEndGui = dynamic_cast<QmitkCmdLineModuleGui*>(newFrontEnd);
widget->SetFrontend(newFrontEndGui);
m_Layout->insertWidget(0, widget);
// 3. Copy parameters. This MUST come after widget->SetFrontEnd
newFrontEndGui->copyParameters(*frontEndGuiOnCurrentTab);
newFrontEndGui->setParameterContainerEnabled(false);
// 4. Connect widget signals to here, to count how many jobs running.
connect(widget, SIGNAL(started()), this, SLOT(OnJobStarted()));
connect(widget, SIGNAL(finished()), this, SLOT(OnJobFinished()));
// 5. GO.
widget->Run();
}
else
{
this->AskUserToSelectAModule();
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::UpdateRunButtonEnabledStatus()
{
if (m_CurrentlyRunningProcesses >= m_MaximumConcurrentProcesses)
{
m_Controls->m_RunButton->setEnabled(false);
}
else
{
m_Controls->m_RunButton->setEnabled(true);
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnJobStarted()
{
m_CurrentlyRunningProcesses++;
this->UpdateRunButtonEnabledStatus();
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnJobFinished()
{
m_CurrentlyRunningProcesses--;
this->UpdateRunButtonEnabledStatus();
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnDirectoryWatcherErrorsDetected(const QString& errorMsg)
{
ctkCmdLineModuleUtils::messageBoxForModuleRegistration(errorMsg);
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnClearCache()
{
if (this->m_DebugOutput)
{
qDebug() << "CommandLineModulesView::OnClearCache(): starting";
}
m_ModuleManager->clearCache();
if (this->m_DebugOutput)
{
qDebug() << "CommandLineModulesView::OnClearCache(): finishing";
}
}
//-----------------------------------------------------------------------------
void CommandLineModulesView::OnReloadModules()
{
QList<QUrl> urls;
QList<ctkCmdLineModuleReference> moduleRefs = m_ModuleManager->moduleReferences();
foreach (ctkCmdLineModuleReference ref, moduleRefs)
{
urls.push_back(ref.location());
}
if (this->m_DebugOutput)
{
qDebug() << "CommandLineModulesView::OnReloadModules(): unloading:" << urls;
}
foreach (ctkCmdLineModuleReference ref, moduleRefs)
{
m_ModuleManager->unregisterModule(ref);
}
if (this->m_DebugOutput)
{
qDebug() << "CommandLineModulesView::OnReloadModules(): reloading.";
}
QList<ctkCmdLineModuleReferenceResult> refResults = QtConcurrent::blockingMapped(urls,
ctkCmdLineModuleConcurrentRegister(m_ModuleManager, m_DebugOutput));
if (this->m_DebugOutput)
{
qDebug() << "CommandLineModulesView::OnReloadModules(): finished.";
}
QString errorMessages = ctkCmdLineModuleUtils::errorMessagesFromModuleRegistration(refResults,
m_ModuleManager->validationMode());
ctkCmdLineModuleUtils::messageBoxForModuleRegistration(errorMessages);
}
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.h b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.h
index a626d0abb7..51e05c279f 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.h
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/CommandLineModulesView.h
@@ -1,255 +1,255 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) University College London (UCL).
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef CommandLineModulesView_h
#define CommandLineModulesView_h
#include <QmitkAbstractView.h>
#include <berryIPreferences.h>
#include <berryIPreferencesService.h>
#include <berryIBerryPreferences.h>
#include <ctkCmdLineModuleReference.h>
#include <ctkCmdLineModuleResult.h>
#include <ctkCmdLineModuleManager.h>
class ctkCmdLineModuleBackendLocalProcess;
class ctkCmdLineModuleDirectoryWatcher;
class CommandLineModulesViewControls;
-class QmitkCmdLineModuleProgressWidget;
+class QmitkCmdLineModuleRunner;
class QAction;
class QVBoxLayout;
namespace berry
{
struct IBerryPreferences;
}
/*!
* \class CommandLineModulesView
* \brief Provides basic GUI interface to the CTK command line modules.
* \author Matt Clarkson (m.clarkson@ucl.ac.uk)
* \ingroup org_mitk_gui_qt_cmdlinemodules_internal
* \sa QmitkAbstractView
*/
class CommandLineModulesView : public QmitkAbstractView
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
CommandLineModulesView();
virtual ~CommandLineModulesView();
/**
* \brief Main method, called by framework to create the GUI at the right time.
* \param parent The parent QWidget, as this class itself is not a QWidget subclass.
*/
virtual void CreateQtPartControl(QWidget *parent);
/**
* \brief Called by the framework to indicate that the preferences have changed.
* \param prefs not used, as we call RetrievePreferenceValues().
*/
void OnPreferencesChanged(const berry::IBerryPreferences* prefs);
protected Q_SLOTS:
/**
* \brief Called when the ctkMenuComboBox has the menu selection changed,
* and causes the corresponding GUI to be displayed.
*/
void OnActionChanged(QAction*);
/**
* \brief Slot that is called when the restore defaults button is pressed,
* to reset the current GUI form to the default values, if the XML specifies defaults.
*/
void OnRestoreButtonPressed();
/**
* \brief Slot that is called when the Run button is pressed to run the current module.
*/
void OnRunButtonPressed();
/**
* \brief Alerts the user of any errors comming out of the directory watcher.
*/
void OnDirectoryWatcherErrorsDetected(const QString&);
protected:
/**
* \brief Called by framework to set the focus on the right widget
* when this view has focus, so currently, thats the ctkMenuCombo box.
*/
virtual void SetFocus();
private slots:
/**
* \brief Called when the user clicks to close a tab, and removes the front end from m_ListOfModules
*/
void OnTabCloseRequested(int tabNumber);
/**
* \brief Called from QmitkCmdLineModuleProgressWidget to indicate a job has started.
*/
void OnJobStarted();
/**
* \brief Called from QmitkCmdLineModuleProgressWidget to indicate a job has finished.
*/
void OnJobFinished();
/**
* \brief Called when the user hits the 'clear XML cache' button.
*/
void OnClearCache();
/**
* \brief Called when the user hits the 'reload modules' button.
*/
void OnReloadModules();
private:
/**
* \brief Called on startup and by OnPreferencesChanged to load all
* preferences except the temporary folder into member variables.
*/
void RetrieveAndStorePreferenceValues();
/**
* \brief Called on startup and by OnPreferencesChanged to load the temporary folder
* preference into member variable m_TemporaryDirectoryName.
*/
void RetrieveAndStoreTemporaryDirectoryPreferenceValues();
/**
* \brief Called on startup and by OnPreferencesChanged to set the validation mode, but will require a restart.
*/
void RetrieveAndStoreValidationMode();
/**
* \brief Called to get hold of the actual preferences node.
*/
berry::IBerryPreferences::Pointer RetrievePreferences();
/**
* \brief Search all modules for the one matching the given identifier.
* \param fullName The "fullName" is the <category>.<title> from the XML.
* \return ctkCmdLineModuleReference the reference corresponding to the fullName, or an invalid reference if non found.
*/
ctkCmdLineModuleReference GetReferenceByFullName(QString fullName);
/**
* \brief Raises a message box asking the user to select a module first.
*/
void AskUserToSelectAModule() const;
/**
* \brief Enables or Disables the Run Button.
*/
void UpdateRunButtonEnabledStatus();
/**
* \brief The GUI controls contain a reset and run button, and a QWidget container, and the GUI component
* for each command line module is added to the QWidget dynamically at run time.
*/
CommandLineModulesViewControls *m_Controls;
/**
* \brief We store the parent, passed in via CommandLineModulesView::CreateQtPartControl,
* as this class itself is not a QWidget.
*/
QWidget *m_Parent;
/**
* \brief We keep a local layout, and arrange a display of QmitkCmdLineModuleProgressWidget,
* where each QmitkCmdLineModuleProgressWidget represents a single running job.
*/
QVBoxLayout *m_Layout;
/**
* \brief The manager is responsible for loading and instantiating command line modules.
*/
ctkCmdLineModuleManager *m_ModuleManager;
/**
* \brief We are using a back-end that runs locally installed command line programs.
*/
ctkCmdLineModuleBackendLocalProcess *m_ModuleBackend;
/**
* \brief The ctkCmdLineModuleDirectoryWatcher maintains the list of directories
* we are using to load modules, to provide automatic updates.
*/
ctkCmdLineModuleDirectoryWatcher *m_DirectoryWatcher;
/**
* \brief We store a temporary folder name, accessible via user preferences.
*/
QString m_TemporaryDirectoryName;
/**
* \brief We store an output folder name, accessible via user preferences for when
* the file specified in a default output path is not within a writable directory.
*/
QString m_OutputDirectoryName;
/**
* \brief Cache the list of directory paths locally to avoid repeatedly trying to update Directory Watcher.
*/
QStringList m_DirectoryPaths;
/**
* \brief Cache the list of module/executable paths locally to avoid repeatedly trying to update Directory Watcher.
*/
QStringList m_ModulePaths;
/**
* \brief We store the validation mode, accessisble via user preferences.
*/
ctkCmdLineModuleManager::ValidationMode m_ValidationMode;
/**
* \brief We store the maximum number of concurrent processes, and disable the run button accordingly.
*/
int m_MaximumConcurrentProcesses;
/**
* \brief Counts the number of currently running processes.
*/
int m_CurrentlyRunningProcesses;
/**
* \brief Member variable, taken from preference page.
*/
bool m_DebugOutput;
/**
* \brief Member variable, taken from preferences page.
*/
int m_XmlTimeoutSeconds;
/**
* \brief We keep a list of front ends to match the m_TabWidget.
*/
QList<ctkCmdLineModuleFrontend*> m_ListOfModules;
};
#endif // CommandLineModulesView_h
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleProgressWidget.cpp b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleRunner.cpp
similarity index 76%
rename from Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleProgressWidget.cpp
rename to Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleRunner.cpp
index e928ad843b..7168720ff5 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleProgressWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleRunner.cpp
@@ -1,641 +1,655 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) University College London (UCL).
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#include "QmitkCmdLineModuleProgressWidget.h"
+#include "QmitkCmdLineModuleRunner.h"
#include "ui_QmitkCmdLineModuleProgressWidget.h"
// Qt
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QLayoutItem>
#include <QTextBrowser>
#include <QByteArray>
#include <QApplication>
#include <QRegExp>
// CTK
#include <ctkCmdLineModuleFuture.h>
#include <ctkCmdLineModuleFutureWatcher.h>
#include <ctkCmdLineModuleManager.h>
#include <ctkCmdLineModuleFrontend.h>
#include <ctkCmdLineModuleDescription.h>
-#include <ctkCmdLineModuleParameter.h>
#include <ctkCollapsibleGroupBox.h>
// MITK
#include <mitkIOUtil.h>
#include <mitkDataStorage.h>
-#include <mitkDataNode.h>
+#include <mitkExceptionMacro.h>
#include <QmitkCustomVariants.h>
#include "QmitkCmdLineModuleGui.h"
//-----------------------------------------------------------------------------
-QmitkCmdLineModuleProgressWidget::QmitkCmdLineModuleProgressWidget(QWidget *parent)
+QmitkCmdLineModuleRunner::QmitkCmdLineModuleRunner(QWidget *parent)
: QWidget(parent)
, m_ModuleManager(NULL)
, m_DataStorage(NULL)
-, m_TemporaryDirectoryName("")
, m_UI(new Ui::QmitkCmdLineModuleProgressWidget)
, m_Layout(NULL)
, m_ModuleFrontEnd(NULL)
, m_FutureWatcher(NULL)
{
m_UI->setupUi(this);
m_UI->m_RemoveButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_TitleBarCloseButton));
m_Layout = new QVBoxLayout();
m_Layout->setContentsMargins(0,0,0,0);
m_Layout->setSpacing(0);
m_UI->m_ParametersGroupBox->setLayout(m_Layout);
qRegisterMetaType<ctkCmdLineModuleReference>();
connect(m_UI->m_RemoveButton, SIGNAL(clicked()), this, SLOT(OnRemoveButtonClicked()));
// Due to Qt bug 12152, we cannot listen to the "paused" signal because it is
// not emitted directly when the QFuture is paused. Instead, it is emitted after
// resuming the future, after the "resume" signal has been emitted... we use
// a polling approach instead.
connect(&m_PollPauseTimer, SIGNAL(timeout()), SLOT(OnCheckModulePaused()));
m_PollPauseTimer.setInterval(300);
m_PollPauseTimer.start();
}
//-----------------------------------------------------------------------------
-QmitkCmdLineModuleProgressWidget::~QmitkCmdLineModuleProgressWidget()
+QmitkCmdLineModuleRunner::~QmitkCmdLineModuleRunner()
{
if (m_ModuleFrontEnd != NULL)
{
delete m_ModuleFrontEnd;
}
this->ClearUpTemporaryFiles();
delete m_UI;
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::SetManager(ctkCmdLineModuleManager* manager)
+void QmitkCmdLineModuleRunner::SetManager(ctkCmdLineModuleManager* manager)
{
this->m_ModuleManager = manager;
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::SetDataStorage(mitk::DataStorage* dataStorage)
+void QmitkCmdLineModuleRunner::SetDataStorage(mitk::DataStorage* dataStorage)
{
this->m_DataStorage = dataStorage;
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::SetTemporaryDirectory(const QString& directoryName)
-{
- this->m_TemporaryDirectoryName = directoryName;
-}
-
-
-//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::SetOutputDirectory(const QString& directoryName)
+void QmitkCmdLineModuleRunner::SetOutputDirectory(const QString& directoryName)
{
this->m_OutputDirectoryName = directoryName;
}
//-----------------------------------------------------------------------------
-QString QmitkCmdLineModuleProgressWidget::GetTitle()
+QString QmitkCmdLineModuleRunner::GetTitle()
{
assert(m_ModuleFrontEnd);
ctkCmdLineModuleReference reference = m_ModuleFrontEnd->moduleReference();
ctkCmdLineModuleDescription description = reference.description();
return description.title();
}
//-----------------------------------------------------------------------------
-QString QmitkCmdLineModuleProgressWidget::GetFullName() const
+QString QmitkCmdLineModuleRunner::GetFullName() const
{
assert(m_ModuleFrontEnd);
ctkCmdLineModuleReference reference = m_ModuleFrontEnd->moduleReference();
ctkCmdLineModuleDescription description = reference.description();
return description.categoryDotTitle();
}
//-----------------------------------------------------------------------------
-QString QmitkCmdLineModuleProgressWidget::GetValidNodeName(const QString& nodeName)
+QString QmitkCmdLineModuleRunner::GetValidNodeName(const QString& nodeName) const
{
QString outputName = nodeName;
// We will allow A-Z, a-z, 0-9, period, hyphen and underscore in the output file name.
// This method is parsing a node name, and other bits of code add on a file extension .nii.
// So, in the output string from this function, we should not allow period, so that
// the second recommendation on this page:
// http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/portability_guide.htm
// is still true.
QRegExp rx("[A-Z|a-z|0-9|-|_]{1,1}");
QString singleLetter;
for (int i = 0; i < outputName.size(); i++)
{
if (i == 0 && outputName[i] == '-')
{
outputName[i] = '_';
}
singleLetter = outputName[i];
if (!rx.exactMatch(singleLetter))
{
outputName[i] = '-';
}
}
return outputName;
}
//-----------------------------------------------------------------------------
-bool QmitkCmdLineModuleProgressWidget::IsStarted() const
+bool QmitkCmdLineModuleRunner::IsStarted() const
{
bool isStarted = false;
if (m_FutureWatcher != NULL && m_FutureWatcher->isStarted())
{
isStarted = true;
}
return isStarted;
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnCheckModulePaused()
+void QmitkCmdLineModuleRunner::OnCheckModulePaused()
{
if (!this->IsStarted())
{
return;
}
if (this->m_FutureWatcher->future().isPaused())
{
if (!m_UI->m_PauseButton->isChecked())
{
m_UI->m_PauseButton->setChecked(true);
}
}
else
{
if (m_UI->m_PauseButton->isChecked())
{
m_UI->m_PauseButton->setChecked(false);
}
}
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnPauseButtonToggled(bool toggled)
+void QmitkCmdLineModuleRunner::OnPauseButtonToggled(bool toggled)
{
this->m_FutureWatcher->setPaused(toggled);
if (toggled)
{
this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": paused");
}
else
{
this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": resumed");
}
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnRemoveButtonClicked()
+void QmitkCmdLineModuleRunner::OnRemoveButtonClicked()
{
this->deleteLater();
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleStarted()
+void QmitkCmdLineModuleRunner::OnModuleStarted()
{
this->m_UI->m_ProgressBar->setMaximum(0);
QString message = "started.";
this->PublishMessage(message);
emit started();
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleCanceled()
+void QmitkCmdLineModuleRunner::OnModuleCanceled()
{
QString message = "cancelling.";
this->PublishMessage(message);
this->m_UI->m_PauseButton->setEnabled(false);
this->m_UI->m_PauseButton->setChecked(false);
this->m_UI->m_CancelButton->setEnabled(false);
this->m_UI->m_RemoveButton->setEnabled(true);
this->m_UI->m_ParametersGroupBox->setCollapsed(true);
this->m_UI->m_ConsoleGroupBox->setCollapsed(true);
this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": cancelled");
message = "cancelled.";
this->PublishMessage(message);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleFinished()
+void QmitkCmdLineModuleRunner::OnModuleFinished()
{
this->m_UI->m_PauseButton->setEnabled(false);
this->m_UI->m_PauseButton->setChecked(false);
this->m_UI->m_CancelButton->setEnabled(false);
this->m_UI->m_RemoveButton->setEnabled(true);
if (!this->m_FutureWatcher->isCanceled())
{
QString message = "finishing.";
this->PublishMessage(message);
// If no incremental results from stdout, try getting hold of the whole buffer and printing it.
if (m_OutputCount == 0)
{
message = "Output channel is:";
this->PublishMessage(message);
this->PublishByteArray(this->m_FutureWatcher->readAllOutputData());
}
// If no incremental results from stderr, try getting hold of the whole buffer and printing it.
if (m_ErrorCount == 0)
{
message = "Error channel is:";
this->PublishMessage(message);
this->PublishByteArray(this->m_FutureWatcher->readAllErrorData());
}
this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": finished");
this->LoadOutputData();
this->ClearUpTemporaryFiles();
message = "finished.";
this->PublishMessage(message);
}
emit finished();
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleResumed()
+void QmitkCmdLineModuleRunner::OnModuleResumed()
{
this->m_UI->m_PauseButton->setChecked(false);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleProgressRangeChanged(int progressMin, int progressMax)
+void QmitkCmdLineModuleRunner::OnModuleProgressRangeChanged(int progressMin, int progressMax)
{
this->m_UI->m_ProgressBar->setMinimum(progressMin);
this->m_UI->m_ProgressBar->setMaximum(progressMax);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleProgressTextChanged(const QString& progressText)
+void QmitkCmdLineModuleRunner::OnModuleProgressTextChanged(const QString& progressText)
{
this->m_UI->m_Console->appendPlainText(progressText);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnModuleProgressValueChanged(int progressValue)
+void QmitkCmdLineModuleRunner::OnModuleProgressValueChanged(int progressValue)
{
this->m_UI->m_ProgressBar->setValue(progressValue);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnOutputDataReady()
+void QmitkCmdLineModuleRunner::OnOutputDataReady()
{
m_OutputCount++;
this->PublishByteArray(this->m_FutureWatcher->readPendingOutputData());
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::OnErrorDataReady()
+void QmitkCmdLineModuleRunner::OnErrorDataReady()
{
m_ErrorCount++;
this->PublishByteArray(this->m_FutureWatcher->readPendingErrorData());
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::PublishMessage(const QString& message)
+void QmitkCmdLineModuleRunner::PublishMessage(const QString& message)
{
QString prefix = ""; // Can put additional prefix here if needed.
QString outputMessage = prefix + message;
qDebug() << outputMessage;
this->m_UI->m_Console->appendPlainText(outputMessage);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::PublishByteArray(const QByteArray& array)
+void QmitkCmdLineModuleRunner::PublishByteArray(const QByteArray& array)
{
QString message = array.data();
this->PublishMessage(message);
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::ClearUpTemporaryFiles()
+void QmitkCmdLineModuleRunner::ClearUpTemporaryFiles()
{
QString message;
QString fileName;
- foreach (fileName, m_TemporaryFileNames)
+ foreach (QTemporaryFile* file, m_TemporaryFiles)
{
- QFile file(fileName);
- if (file.exists())
- {
- message = QObject::tr("removing %1").arg(fileName);
- this->PublishMessage(message);
+ assert(file != NULL);
- bool success = file.remove();
+ fileName = file->fileName();
+ message = QObject::tr("removing %1").arg(fileName);
+ this->PublishMessage(message);
- message = QObject::tr("removed %1, successfully=%2").arg(fileName).arg(success);
- this->PublishMessage(message);
- }
+ delete file;
}
+
+ m_TemporaryFiles.clear();
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::LoadOutputData()
+void QmitkCmdLineModuleRunner::LoadOutputData()
{
assert(m_DataStorage);
std::vector<std::string> fileNames;
QString fileName;
foreach (fileName, m_OutputDataToLoad)
{
QString message = QObject::tr("loading %1").arg(fileName);
this->PublishMessage(message);
fileNames.push_back(fileName.toStdString());
}
if (fileNames.size() > 0)
{
int numberLoaded = mitk::IOUtil::LoadFiles(fileNames, *(m_DataStorage));
QString message = QObject::tr("loaded %1 files").arg(numberLoaded);
this->PublishMessage(message);
}
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::SetFrontend(QmitkCmdLineModuleGui* frontEnd)
+void QmitkCmdLineModuleRunner::SetFrontend(QmitkCmdLineModuleGui* frontEnd)
{
assert(frontEnd);
assert(m_ModuleManager);
assert(m_DataStorage);
// We are assuming that this method is ONLY EVER CALLED ONCE.
assert(!m_ModuleFrontEnd);
// Assign the frontEnd to the member variable.
m_ModuleFrontEnd = frontEnd;
// We put the new GUI into the layout.
m_Layout->insertWidget(0, m_ModuleFrontEnd->getGui());
// And configure a few other niceties.
m_UI->m_ProgressTitle->setText(this->GetTitle());
m_UI->m_ConsoleGroupBox->setCollapsed(true); // We basically call SetFrontend then Run
m_UI->m_ParametersGroupBox->setCollapsed(true); // so in practice the user will only want the progress bar.
}
//-----------------------------------------------------------------------------
-void QmitkCmdLineModuleProgressWidget::Run()
+void QmitkCmdLineModuleRunner::Run()
{
assert(m_ModuleManager);
assert(m_DataStorage);
assert(m_ModuleFrontEnd);
m_OutputDataToLoad.clear();
QString parameterName;
QString message;
QList<ctkCmdLineModuleParameter> parameters;
ctkCmdLineModuleReference reference = m_ModuleFrontEnd->moduleReference();
ctkCmdLineModuleDescription description = reference.description();
// Check we have valid output. If at all possible, they should be somewhere writable.
parameters = m_ModuleFrontEnd->parameters("image", ctkCmdLineModuleFrontend::Output);
parameters << m_ModuleFrontEnd->parameters("file", ctkCmdLineModuleFrontend::Output);
parameters << m_ModuleFrontEnd->parameters("geometry", ctkCmdLineModuleFrontend::Output);
foreach (ctkCmdLineModuleParameter parameter, parameters)
{
parameterName = parameter.name();
QString outputFileName = m_ModuleFrontEnd->value(parameterName, ctkCmdLineModuleFrontend::DisplayRole).toString();
// Try to make sure we are not running in the application installation folder,
// as more likely than not, it should not have write access, and you certainly
// don't want users output files dumped there.
//
// eg. C:/Program Files (Windows), /Applications (Mac), /usr/local (Linux) etc.
QFileInfo outputFileInfo(outputFileName);
QString applicationDir = QApplication::applicationDirPath();
QString outputDir = outputFileInfo.dir().absolutePath();
if (applicationDir == outputDir)
{
- qDebug() << "QmitkCmdLineModuleProgressWidget::Run(), output folder = application folder, so will swap to defaultOutputDir, specified in CLI module preferences";
+ qDebug() << "QmitkCmdLineModuleRunner::Run(), output folder = application folder, so will swap to defaultOutputDir, specified in CLI module preferences";
QFileInfo newOutputFileInfo(m_OutputDirectoryName, outputFileInfo.fileName());
QString newOutputFileAbsolutePath = newOutputFileInfo.absoluteFilePath();
- qDebug() << "QmitkCmdLineModuleProgressWidget::Run(), swapping " << outputFileName << " to " << newOutputFileAbsolutePath;
+ qDebug() << "QmitkCmdLineModuleRunner::Run(), swapping " << outputFileName << " to " << newOutputFileAbsolutePath;
QMessageBox msgBox;
msgBox.setText("The output directory is the same as the application installation directory");
msgBox.setInformativeText(tr("Output file:\n%1\n\nwill be swapped to\n%2").arg(outputFileName).arg(newOutputFileAbsolutePath));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setIcon(QMessageBox::Warning);
msgBox.exec();
m_ModuleFrontEnd->setValue(parameterName, newOutputFileAbsolutePath, ctkCmdLineModuleFrontend::DisplayRole);
}
}
// For each output image or file, store the filename, so we can auto-load it once the process finishes.
foreach (ctkCmdLineModuleParameter parameter, parameters)
{
parameterName = parameter.name();
QString outputFileName = m_ModuleFrontEnd->value(parameterName, ctkCmdLineModuleFrontend::DisplayRole).toString();
if (!outputFileName.isEmpty())
{
m_OutputDataToLoad.push_back(outputFileName);
message = "Registered " + outputFileName + " to auto load upon completion.";
this->PublishMessage(message);
}
}
// For each input image, write a temporary file as a Nifti image (TODO - iterate through list of file formats).
// and then save the full path name back on the parameter.
message = "Saving image data to temporary storage...";
this->PublishMessage(message);
parameters = m_ModuleFrontEnd->parameters("image", ctkCmdLineModuleFrontend::Input);
foreach (ctkCmdLineModuleParameter parameter, parameters)
{
parameterName = parameter.name();
QVariant tmp = m_ModuleFrontEnd->value(parameterName, ctkCmdLineModuleFrontend::UserRole);
mitk::DataNode::Pointer node = tmp.value<mitkDataNodePtr>();
if (node.IsNotNull())
{
mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData());
if (image != NULL)
{
- QString name = this->GetValidNodeName(QString::fromStdString(node->GetName()));
- int pid = QCoreApplication::applicationPid();
- int randomInt = qrand() % 1000000;
-
- QString fileNameBase = m_TemporaryDirectoryName + "/" + name + QString::number(pid) + "_" + QString::number(randomInt);
- QString fileName = "";
- bool writeSucess = false;
+ QString errorMessage;
+ QTemporaryFile* tempFile = this->SaveTemporaryImage(parameter, node.GetPointer(), errorMessage);
- // Try to save the image using one of the specified "fileExtensions" or
- // .nii if none have been specified.
- if (parameter.fileExtensions().isEmpty())
+ if(tempFile == NULL)
{
- fileName = fileNameBase + ".nii";
- try
- {
- if (mitk::IOUtil::SaveBaseData( image, fileName.toStdString() ))
- {
- writeSucess = true;
- }
- }
- catch(const std::exception&){}
- }
- else
- {
- foreach (QString extension, parameter.fileExtensions())
- {
- if (extension[0]!='.')
- fileName = fileNameBase + "." + extension;
- else
- fileName = fileNameBase + extension;
-
- try
- {
- if (mitk::IOUtil::SaveBaseData( image, fileName.toStdString() ))
- {
- writeSucess = true;
- break;
- }
- }
- catch(const std::exception&)
- {}
- }
- }
-
- if(!writeSucess)
- {
- QStringList extensions = parameter.fileExtensions();
- if (extensions.isEmpty())
- {
- extensions.push_back("nii");
- }
- QMessageBox::warning(this, "Saving temporary input file failed",
- QString("Unsupported file formats: ") + extensions.join(", "));
+ QMessageBox::warning(this, "Saving temporary file failed", errorMessage);
return;
}
- m_TemporaryFileNames.push_back(fileName);
- m_ModuleFrontEnd->setValue(parameterName, fileName);
- message = "Saved " + fileName;
+ m_TemporaryFiles.push_back(tempFile);
+ m_ModuleFrontEnd->setValue(parameterName, tempFile->fileName());
+
+ message = "Saved " + tempFile->fileName();
this->PublishMessage(message);
+
} // end if image
} // end if node
} // end foreach input image
m_OutputCount = 0;
m_ErrorCount = 0;
// Now we run stuff.
message = "starting.";
this->PublishMessage(message);
if (m_FutureWatcher == NULL)
{
m_FutureWatcher = new ctkCmdLineModuleFutureWatcher();
connect(m_FutureWatcher, SIGNAL(started()), SLOT(OnModuleStarted()));
connect(m_FutureWatcher, SIGNAL(canceled()), SLOT(OnModuleCanceled()));
connect(m_FutureWatcher, SIGNAL(finished()), SLOT(OnModuleFinished()));
connect(m_FutureWatcher, SIGNAL(resumed()), SLOT(OnModuleResumed()));
connect(m_FutureWatcher, SIGNAL(progressRangeChanged(int,int)), SLOT(OnModuleProgressRangeChanged(int,int)));
connect(m_FutureWatcher, SIGNAL(progressTextChanged(QString)), SLOT(OnModuleProgressTextChanged(QString)));
connect(m_FutureWatcher, SIGNAL(progressValueChanged(int)), SLOT(OnModuleProgressValueChanged(int)));
connect(m_FutureWatcher, SIGNAL(outputDataReady()), SLOT(OnOutputDataReady()));
connect(m_FutureWatcher, SIGNAL(errorDataReady()), SLOT(OnErrorDataReady()));
connect(m_UI->m_CancelButton, SIGNAL(clicked()), m_FutureWatcher, SLOT(cancel()));
connect(m_UI->m_PauseButton, SIGNAL(toggled(bool)), this, SLOT(OnPauseButtonToggled(bool)));
}
ctkCmdLineModuleFuture future = m_ModuleManager->run(m_ModuleFrontEnd);
m_FutureWatcher->setFuture(future);
m_UI->m_PauseButton->setEnabled(future.canPause());
m_UI->m_CancelButton->setEnabled(future.canCancel());
m_UI->m_RemoveButton->setEnabled(!future.isRunning());
// Give some immediate indication that we are running.
m_UI->m_ProgressTitle->setText(description.title() + ": running");
}
+
+
+//-----------------------------------------------------------------------------
+QTemporaryFile* QmitkCmdLineModuleRunner::SaveTemporaryImage(const ctkCmdLineModuleParameter &parameter, mitk::DataNode::ConstPointer node, QString& errorMessage) const
+{
+ // Don't call this if node is null or node is not an image.
+ assert(node.GetPointer());
+ mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData());
+ assert(image);
+
+ QString intermediateError;
+ QString intermediateErrors;
+
+ QTemporaryFile *returnedFile = NULL;
+ QString name = this->GetValidNodeName(QString::fromStdString(node->GetName()));
+ QString fileNameTemplate = name + "_XXXXXX";
+
+ // If no file extensions are specified, we default to .nii
+ QStringList fileExts = parameter.fileExtensions();
+ if (fileExts.isEmpty())
+ {
+ fileExts.push_back(".nii");
+ }
+
+ // Try each extension until we get a good one.
+ foreach (QString extension, fileExts)
+ {
+ // File extensions may or may not include the leading dot, so add one if necessary.
+ if (!extension.startsWith("."))
+ {
+ extension.prepend(".");
+ }
+ fileNameTemplate = fileNameTemplate + extension;
+
+ try
+ {
+ QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + QDir::separator() + fileNameTemplate);
+ if (tempFile->open())
+ {
+ tempFile->close();
+ if (mitk::IOUtil::SaveBaseData( image, tempFile->fileName().toStdString() ))
+ {
+ returnedFile = tempFile;
+ break;
+ }
+ else
+ {
+ intermediateError = QObject::tr("Tried %1, failed to save image:\n%2\n").arg(extension).arg(tempFile->fileName());
+ }
+ }
+ else
+ {
+ intermediateError = QObject::tr("Tried %1, failed to open file:\n%2\n").arg(extension).arg(tempFile->fileName());
+ }
+ }
+ catch(const mitk::Exception &e)
+ {
+ intermediateError = QObject::tr("Tried %1, caught MITK Exception:\nDescription: %2\nFilename: %3\nLine: %4\n")
+ .arg(extension).arg(e.GetDescription()).arg(e.GetFile()).arg(e.GetLine());
+ }
+ catch(const std::exception& e)
+ {
+ intermediateError = QObject::tr("Tried %1, caught exception:\nDescription: %2\n")
+ .arg(extension).arg(e.what());
+ }
+ intermediateErrors += intermediateError;
+ }
+ errorMessage = intermediateErrors;
+ return returnedFile;
+}
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleProgressWidget.h b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleRunner.h
similarity index 81%
rename from Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleProgressWidget.h
rename to Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleRunner.h
index e04c7fec35..d2f9e9efcd 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleProgressWidget.h
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/QmitkCmdLineModuleRunner.h
@@ -1,228 +1,235 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) University College London (UCL).
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef QMITKCMDLINEMODULEPROGRESSWIDGET_H
-#define QMITKCMDLINEMODULEPROGRESSWIDGET_H
+#ifndef QMITKCMDLINEMODULERUNNER_H
+#define QMITKCMDLINEMODULERUNNER_H
#include <QWidget>
#include <QTimer>
+#include <QList>
+
+#include <ctkCmdLineModuleParameter.h>
+#include <mitkDataNode.h>
class QVBoxLayout;
+class QTemporaryFile;
class QmitkCmdLineModuleGui;
class ctkCmdLineModuleManager;
class ctkCmdLineModuleFutureWatcher;
namespace Ui {
class QmitkCmdLineModuleProgressWidget;
}
namespace mitk {
class DataStorage;
}
/**
- * \class QmitkCmdLineModuleProgressWidget
+ * \class QmitkCmdLineModuleRunner
* \brief Based on ctkCmdLineModuleExplorerProgressWidget, implements a progress widget
* with console output, and space for storing the GUI widgets.
* \author Matt Clarkson (m.clarkson@ucl.ac.uk)
* \ingroup org_mitk_gui_qt_cmdlinemodules_internal
* \sa ctkCmdLineModuleExplorerProgressWidget
*/
-class QmitkCmdLineModuleProgressWidget : public QWidget
+class QmitkCmdLineModuleRunner : public QWidget
{
Q_OBJECT
public:
- QmitkCmdLineModuleProgressWidget(QWidget *parent = 0);
- virtual ~QmitkCmdLineModuleProgressWidget();
+ QmitkCmdLineModuleRunner(QWidget *parent = 0);
+ virtual ~QmitkCmdLineModuleRunner();
/**
* \brief Sets the manager on this object, and must be called immediately
* after construction, before using the widget.
*/
void SetManager(ctkCmdLineModuleManager* manager);
/**
* \brief Sets the DataStorage on this object, and must be called immediately
* after construction, before using the widget.
*/
void SetDataStorage(mitk::DataStorage* dataStorage);
- /**
- * \brief Sets the Temporary Directory on this widget, and must be called
- * immediately after construction, before using the widget.
- */
- void SetTemporaryDirectory(const QString& directoryName);
-
/**
* \brief Sets the Output Directory on this widget, and must be called
* immediately after construction, before using the widget.
*/
void SetOutputDirectory(const QString& directoryName);
/**
* \brief Tells this widget, which module frontend it is running
* \param frontEnd our QmitkCmdLineModuleGui class derived from ctkCmdLineModuleFrontend
*/
void SetFrontend(QmitkCmdLineModuleGui* frontEnd);
/**
* \brief Runs the module that this widget is currently referring to.
*/
void Run();
Q_SIGNALS:
// These signals so that container classes such as CommandLineModuleView
// can keep track of how many modules are running simultaneously.
void started(); // emmitted when the module is started.
void finished(); // emmitted when the module is completely finished.
private Q_SLOTS:
void OnCheckModulePaused();
void OnPauseButtonToggled(bool toggled);
void OnRemoveButtonClicked();
void OnModuleStarted();
void OnModuleCanceled();
void OnModuleFinished();
void OnModuleResumed();
void OnModuleProgressRangeChanged(int progressMin, int progressMax);
void OnModuleProgressTextChanged(const QString& progressText);
void OnModuleProgressValueChanged(int progressValue);
void OnOutputDataReady();
void OnErrorDataReady();
private:
/**
* \brief Simply returns true if this widget is considered as having been started.
*/
bool IsStarted() const;
/**
* \brief Used to write output to the console widget, and also to qDebug().
*/
void PublishMessage(const QString& message);
/**
* \brief Used to write output to the console widget, and also to qDebug().
*/
void PublishByteArray(const QByteArray& array);
/**
* \brief Destroys any images listed in m_TemporaryFileNames.
*/
void ClearUpTemporaryFiles();
/**
* \brief Loads any data listed in m_OutputDataToLoad into the m_DataStorage.
*/
void LoadOutputData();
+ /**
+ * \brief Saves temporary image to file.
+ * \param[in] node non-NULL pointer to node containing a non-NULL mitk::Image.
+ * \param[out] errorMessage which if not empty means an error occurred.
+ * \return QTemporaryFile temporary file that the caller is responsible for deleting.
+ *
+ * If the returned QTemporaryFile is NULL, check errorMessage.
+ * If the returned QTemporaryFile is not-NULL, there could still be data in the errorMessage.
+ * It could be that this method tried n file extensions, before finding a successful one.
+ * In this case, the returned QTemporaryFile is the successful one, and the errorMessage contains error messages of all the failed attempts.
+ */
+ QTemporaryFile* SaveTemporaryImage(const ctkCmdLineModuleParameter& parameter, mitk::DataNode::ConstPointer node, QString& errorMessage) const;
+
/**
* \brief Utility method to look up the title from the description.
*/
QString GetTitle();
/**
* \brief Returns <category>.<title>, derived from the ctkCmdLineModuleReference and
* hence from the ctkCmdLineModuleDescription.
*/
QString GetFullName() const;
/**
* \brief Takes nodeName, and makes sure that it only contains A-Z, a-z, 0-9, hyphen and underscore,
* and does not use hyphen as the first character.
*
* Inspired by <a href="http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/portability_guide.htm">boost recommendations</a>.
*/
- QString GetValidNodeName(const QString& nodeName);
+ QString GetValidNodeName(const QString& nodeName) const;
/**
* \brief This must be injected before the Widget is used.
*/
ctkCmdLineModuleManager *m_ModuleManager;
/**
* \brief This must be injected before the Widget is used.
*/
mitk::DataStorage *m_DataStorage;
- /**
- * \brief This must be injected before the Widget is used.
- */
- QString m_TemporaryDirectoryName;
-
/**
* \brief This must be injected before the Widget is used.
*/
QString m_OutputDirectoryName;
/**
* \brief We instantiate the main widgets from this .ui file.
*/
Ui::QmitkCmdLineModuleProgressWidget *m_UI;
/**
* \brief The m_ParametersGroupBox needs a layout.
*/
QVBoxLayout *m_Layout;
/**
* \brief The QmitkCmdLineModuleGui is created by the QmitkCmdLineModuleFactoryGui outside
* of this class and injected into this class before being run.
*/
QmitkCmdLineModuleGui *m_ModuleFrontEnd;
/**
* \brief Main object to keep track of a running command line module.
*/
ctkCmdLineModuleFutureWatcher *m_FutureWatcher;
/**
* \brief Due to Qt bug 12152, we use a timer to correctly check for a paused module.
*/
QTimer m_PollPauseTimer;
/**
* \brief We store a list of temporary file names that are saved to disk before
* launching a command line app, and then must be cleared up when the command line
* app successfully finishes.
*/
- QStringList m_TemporaryFileNames;
+ QList<QTemporaryFile*> m_TemporaryFiles;
/**
* \brief We store a list of output images, so that on successful completion of
* the command line module, we automatically load the output data into the mitk::DataStorage.
*/
QStringList m_OutputDataToLoad;
/**
* \brief We track how many times the OnOutputDataReady is called.
*/
int m_OutputCount;
/**
* \brief We track how many times the OnErrorDataReady is called.
*/
int m_ErrorCount;
};
-#endif // QMITKCMDLINEMODULEPROGRESSWIDGET_H
+#endif // QMITKCMDLINEMODULERUNNER_H
diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp
index 7593868302..769b1f9816 100644
--- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp
+++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp
@@ -1,602 +1,602 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkAbstractView.h"
#include "QmitkDataNodeSelectionProvider.h"
#include "internal/QmitkCommonActivator.h"
#include "internal/QmitkDataNodeItemModel.h"
// mitk Includes
#include <mitkLogMacros.h>
#include <mitkIDataStorageService.h>
#include <mitkDataStorageEditorInput.h>
#include <mitkWorkbenchUtil.h>
#include <mitkDataNodeObject.h>
#include <mitkIRenderingManager.h>
// berry Includes
#include <berryIWorkbenchPage.h>
#include <berryIBerryPreferences.h>
#include <berryIEditorPart.h>
#include <berryINullSelectionListener.h>
#include <berryUIException.h>
// CTK Includes
#include <ctkServiceTracker.h>
// Qt Includes
#include <QItemSelectionModel>
#include <QApplication>
#include <QMessageBox>
#include <QScrollArea>
#include <QVBoxLayout>
class QmitkAbstractViewPrivate
{
public:
QmitkAbstractViewPrivate(QmitkAbstractView* qq)
: q(qq)
, m_PrefServiceTracker(QmitkCommonActivator::GetContext())
, m_DataStorageServiceTracker(QmitkCommonActivator::GetContext())
, m_Parent(0)
, m_DataNodeItemModel(new QmitkDataNodeItemModel)
, m_DataNodeSelectionModel(new QItemSelectionModel(m_DataNodeItemModel))
, m_InDataStorageChanged(false)
{
m_PrefServiceTracker.open();
m_DataStorageServiceTracker.open();
}
~QmitkAbstractViewPrivate()
{
delete m_DataNodeSelectionModel;
delete m_DataNodeItemModel;
m_PrefServiceTracker.close();
m_DataStorageServiceTracker.close();
}
/**
* Called when a DataStorage Add Event was thrown. Sets
* m_InDataStorageChanged to true and calls NodeAdded afterwards.
* \see m_InDataStorageChanged
*/
void NodeAddedProxy(const mitk::DataNode* node)
{
// garantuee no recursions when a new node event is thrown in NodeAdded()
if(!m_InDataStorageChanged)
{
m_InDataStorageChanged = true;
q->NodeAdded(node);
q->DataStorageModified();
m_InDataStorageChanged = false;
}
}
/**
* Called when a DataStorage remove event was thrown. Sets
* m_InDataStorageChanged to true and calls NodeRemoved afterwards.
* \see m_InDataStorageChanged
*/
void NodeRemovedProxy(const mitk::DataNode* node)
{
// garantuee no recursions when a new node event is thrown in NodeAdded()
if(!m_InDataStorageChanged)
{
m_InDataStorageChanged = true;
q->NodeRemoved(node);
q->DataStorageModified();
m_InDataStorageChanged = false;
}
}
/**
* Called when a DataStorage changed event was thrown. Sets
* m_InDataStorageChanged to true and calls NodeChanged afterwards.
* \see m_InDataStorageChanged
*/
void NodeChangedProxy(const mitk::DataNode* node)
{
// garantuee no recursions when a new node event is thrown in NodeAdded()
if(!m_InDataStorageChanged)
{
m_InDataStorageChanged = true;
q->NodeChanged(node);
q->DataStorageModified();
m_InDataStorageChanged = false;
}
}
/**
* reactions to selection events from views
*/
void BlueBerrySelectionChanged(berry::IWorkbenchPart::Pointer sourcepart, berry::ISelection::ConstPointer selection)
{
if(sourcepart.IsNull() || sourcepart.GetPointer() == static_cast<berry::IWorkbenchPart*>(q))
return;
if(selection.IsNull())
{
q->OnNullSelection(sourcepart);
return;
}
mitk::DataNodeSelection::ConstPointer _DataNodeSelection
= selection.Cast<const mitk::DataNodeSelection>();
q->OnSelectionChanged(sourcepart, this->DataNodeSelectionToQList(_DataNodeSelection));
}
/**
* Converts a mitk::DataNodeSelection to a QList<mitk::DataNode::Pointer> (possibly empty)
*/
QList<mitk::DataNode::Pointer> DataNodeSelectionToQList(mitk::DataNodeSelection::ConstPointer currentSelection) const;
QmitkAbstractView* const q;
ctkServiceTracker<berry::IPreferencesService*> m_PrefServiceTracker;
ctkServiceTracker<mitk::IDataStorageService*> m_DataStorageServiceTracker;
/**
* Saves the parent of this view (this is the scrollarea created in CreatePartControl(void*)
* \see CreatePartControl(void*)
*/
QWidget* m_Parent;
/**
* Holds the current selection (selection made by this View !!!)
*/
QmitkDataNodeSelectionProvider::Pointer m_SelectionProvider;
/**
* Holds a helper model for firing selection events.
*/
QmitkDataNodeItemModel* m_DataNodeItemModel;
/**
* The selection model for the QmitkDataNodeItemModel;
*/
QItemSelectionModel* m_DataNodeSelectionModel;
/**
* object to observe BlueBerry selections
*/
berry::ISelectionListener::Pointer m_BlueBerrySelectionListener;
/**
* Saves if this class is currently working on DataStorage changes.
* This is a protector variable to avoid recursive calls on event listener functions.
*/
bool m_InDataStorageChanged;
};
QmitkAbstractView::QmitkAbstractView()
: d(new QmitkAbstractViewPrivate(this))
{
}
void QmitkAbstractView::CreatePartControl(void* parent)
{
// scrollArea
QScrollArea* scrollArea = new QScrollArea;
//QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollArea);
scrollArea->setFrameShadow(QFrame::Plain);
scrollArea->setFrameShape(QFrame::NoFrame);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
// m_Parent
d->m_Parent = new QWidget;
//m_Parent->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
this->CreateQtPartControl(d->m_Parent);
//scrollAreaLayout->addWidget(m_Parent);
//scrollArea->setLayout(scrollAreaLayout);
// set the widget now
scrollArea->setWidgetResizable(true);
scrollArea->setWidget(d->m_Parent);
// add the scroll area to the real parent (the view tabbar)
QWidget* parentQWidget = static_cast<QWidget*>(parent);
QVBoxLayout* parentLayout = new QVBoxLayout(parentQWidget);
parentLayout->setMargin(0);
parentLayout->setSpacing(0);
parentLayout->addWidget(scrollArea);
// finally set the layout containing the scroll area to the parent widget (= show it)
parentQWidget->setLayout(parentLayout);
this->AfterCreateQtPartControl();
}
void QmitkAbstractView::AfterCreateQtPartControl()
{
this->SetSelectionProvider();
// REGISTER DATASTORAGE LISTENER
this->GetDataStorage()->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkAbstractViewPrivate, const mitk::DataNode*>
( d.data(), &QmitkAbstractViewPrivate::NodeAddedProxy ) );
this->GetDataStorage()->ChangedNodeEvent.AddListener( mitk::MessageDelegate1<QmitkAbstractViewPrivate, const mitk::DataNode*>
( d.data(), &QmitkAbstractViewPrivate::NodeChangedProxy ) );
this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkAbstractViewPrivate, const mitk::DataNode*>
( d.data(), &QmitkAbstractViewPrivate::NodeRemovedProxy ) );
// REGISTER PREFERENCES LISTENER
berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast<berry::IBerryPreferences>();
if(prefs.IsNotNull())
prefs->OnChanged.AddListener(
berry::MessageDelegate1<QmitkAbstractView, const berry::IBerryPreferences*>(this,
&QmitkAbstractView::OnPreferencesChanged));
// REGISTER FOR WORKBENCH SELECTION EVENTS
d->m_BlueBerrySelectionListener = berry::ISelectionListener::Pointer(
new berry::NullSelectionChangedAdapter<QmitkAbstractViewPrivate>(d.data(),
&QmitkAbstractViewPrivate::BlueBerrySelectionChanged));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(d->m_BlueBerrySelectionListener);
// EMULATE INITIAL SELECTION EVENTS
// send the current selection
berry::IWorkbenchPart::Pointer activePart = this->GetSite()->GetPage()->GetActivePart();
if (activePart.IsNotNull())
{
this->OnSelectionChanged(activePart, this->GetCurrentSelection());
}
// send preferences changed event
this->OnPreferencesChanged(this->GetPreferences().Cast<berry::IBerryPreferences>().GetPointer());
}
QmitkAbstractView::~QmitkAbstractView()
{
this->Register();
this->GetDataStorage()->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkAbstractViewPrivate, const mitk::DataNode*>
( d.data(), &QmitkAbstractViewPrivate::NodeAddedProxy ) );
this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkAbstractViewPrivate, const mitk::DataNode*>
( d.data(), &QmitkAbstractViewPrivate::NodeRemovedProxy) );
this->GetDataStorage()->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkAbstractViewPrivate, const mitk::DataNode*>
( d.data(), &QmitkAbstractViewPrivate::NodeChangedProxy ) );
berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast<berry::IBerryPreferences>();
if(prefs.IsNotNull())
{
prefs->OnChanged.RemoveListener(
berry::MessageDelegate1<QmitkAbstractView, const berry::IBerryPreferences*>(this,
&QmitkAbstractView::OnPreferencesChanged));
// flush the preferences here (disabled, everyone should flush them by themselves at the right moment)
// prefs->Flush();
}
// REMOVE SELECTION PROVIDER
this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(NULL));
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
if(s)
{
s->RemovePostSelectionListener(d->m_BlueBerrySelectionListener);
}
this->UnRegister(false);
}
void QmitkAbstractView::SetSelectionProvider()
{
// REGISTER A SELECTION PROVIDER
d->m_SelectionProvider = QmitkDataNodeSelectionProvider::Pointer(new QmitkDataNodeSelectionProvider);
d->m_SelectionProvider->SetItemSelectionModel(GetDataNodeSelectionModel());
this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(d->m_SelectionProvider));
}
QItemSelectionModel *QmitkAbstractView::GetDataNodeSelectionModel() const
{
return 0;
}
void QmitkAbstractView::OnPreferencesChanged( const berry::IBerryPreferences* )
{
}
void QmitkAbstractView::DataStorageModified()
{
}
void QmitkAbstractView::DataStorageChanged(mitk::IDataStorageReference::Pointer /*dsRef*/)
{
}
mitk::IRenderWindowPart* QmitkAbstractView::GetRenderWindowPart( IRenderWindowPartStrategies strategies ) const
{
berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage();
// Return the active editor if it implements mitk::IRenderWindowPart
mitk::IRenderWindowPart* renderPart =
dynamic_cast<mitk::IRenderWindowPart*>(page->GetActiveEditor().GetPointer());
if (renderPart) return renderPart;
// No suitable active editor found, check visible editors
std::list<berry::IEditorReference::Pointer> editors = page->GetEditorReferences();
for (std::list<berry::IEditorReference::Pointer>::iterator i = editors.begin();
i != editors.end(); ++i)
{
berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false);
if (page->IsPartVisible(part))
{
renderPart = dynamic_cast<mitk::IRenderWindowPart*>(part.GetPointer());
if (renderPart) return renderPart;
}
}
// No suitable visible editor found, check visible views
std::vector<berry::IViewReference::Pointer> views = page->GetViewReferences();
for(std::vector<berry::IViewReference::Pointer>::iterator i = views.begin();
i != views.end(); ++i)
{
berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false);
if (page->IsPartVisible(part))
{
renderPart = dynamic_cast<mitk::IRenderWindowPart*>(part.GetPointer());
if (renderPart) return renderPart;
}
}
// No strategies given
if (strategies == NONE) return 0;
mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(GetDataStorageReference()));
bool activate = false;
if(strategies & ACTIVATE)
{
activate = true;
}
berry::IEditorPart::Pointer editorPart;
if(strategies & OPEN)
{
// This will create a default editor for the given input. If an editor
// with that input is already open, the editor is brought to the front.
try
{
editorPart = mitk::WorkbenchUtil::OpenEditor(page, input, activate);
}
catch (const berry::PartInitException&)
{
// There is no editor registered which can handle the given input.
}
}
else if (activate || (strategies & BRING_TO_FRONT))
{
// check if a suitable editor is already opened
editorPart = page->FindEditor(input);
if (editorPart)
{
if (activate)
{
page->Activate(editorPart);
}
else
{
page->BringToTop(editorPart);
}
}
}
return dynamic_cast<mitk::IRenderWindowPart*>(editorPart.GetPointer());
}
void QmitkAbstractView::RequestRenderWindowUpdate(mitk::RenderingManager::RequestType requestType)
{
mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart();
if (renderPart == 0) return;
if (mitk::IRenderingManager* renderingManager = renderPart->GetRenderingManager())
{
renderingManager->RequestUpdateAll(requestType);
}
else
{
renderPart->RequestUpdate(requestType);
}
}
void QmitkAbstractView::HandleException( const char* str, QWidget* parent, bool showDialog ) const
{
//itkGenericOutputMacro( << "Exception caught: " << str );
MITK_ERROR << str;
if ( showDialog )
{
QMessageBox::critical ( parent, "Exception caught!", str );
}
}
void QmitkAbstractView::HandleException( std::exception& e, QWidget* parent, bool showDialog ) const
{
HandleException( e.what(), parent, showDialog );
}
void QmitkAbstractView::WaitCursorOn()
{
QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
}
void QmitkAbstractView::BusyCursorOn()
{
QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) );
}
void QmitkAbstractView::WaitCursorOff()
{
this->RestoreOverrideCursor();
}
void QmitkAbstractView::BusyCursorOff()
{
this->RestoreOverrideCursor();
}
void QmitkAbstractView::RestoreOverrideCursor()
{
QApplication::restoreOverrideCursor();
}
berry::IPreferences::Pointer QmitkAbstractView::GetPreferences() const
{
berry::IPreferencesService* prefService = d->m_PrefServiceTracker.getService();
// const_cast workaround for bad programming: const uncorrectness this->GetViewSite() should be const
std::string id = "/" + (const_cast<QmitkAbstractView*>(this))->GetViewSite()->GetId();
return prefService ? prefService->GetSystemPreferences()->Node(id): berry::IPreferences::Pointer(0);
}
mitk::DataStorage::Pointer
QmitkAbstractView::GetDataStorage() const
{
mitk::IDataStorageService* dsService = d->m_DataStorageServiceTracker.getService();
if (dsService != 0)
{
return dsService->GetDataStorage()->GetDataStorage();
}
return 0;
}
mitk::IDataStorageReference::Pointer QmitkAbstractView::GetDataStorageReference() const
{
mitk::IDataStorageService* dsService = d->m_DataStorageServiceTracker.getService();
if (dsService != 0)
{
return dsService->GetDataStorage();
}
return mitk::IDataStorageReference::Pointer(0);
}
QList<mitk::DataNode::Pointer> QmitkAbstractView::GetCurrentSelection() const
{
berry::ISelection::ConstPointer selection( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection());
mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast<const mitk::DataNodeSelection>();
return d->DataNodeSelectionToQList(currentSelection);
}
bool QmitkAbstractView::IsCurrentSelectionValid() const
{
return this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection();
}
QList<mitk::DataNode::Pointer> QmitkAbstractView::GetDataManagerSelection() const
{
berry::ISelection::ConstPointer selection( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast<const mitk::DataNodeSelection>();
return d->DataNodeSelectionToQList(currentSelection);
}
bool QmitkAbstractView::IsDataManagerSelectionValid() const
{
return this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager");
}
void QmitkAbstractView::SetDataManagerSelection(const berry::ISelection::ConstPointer &selection,
QItemSelectionModel::SelectionFlags flags) const
{
berry::IViewPart::Pointer datamanagerView = this->GetSite()->GetWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.datamanager");
if (datamanagerView.IsNull()) return;
datamanagerView->GetSite()->GetSelectionProvider().Cast<berry::QtSelectionProvider>()->SetSelection(selection, flags);
}
void QmitkAbstractView::SynchronizeDataManagerSelection() const
{
berry::ISelection::ConstPointer currentSelection = this->GetSite()->GetSelectionProvider()->GetSelection();
if (currentSelection.IsNull()) return;
SetDataManagerSelection(currentSelection);
}
void QmitkAbstractView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/,
const QList<mitk::DataNode::Pointer>& /*nodes*/)
{
}
void QmitkAbstractView::OnNullSelection(berry::IWorkbenchPart::Pointer /*part*/)
{
}
QList<mitk::DataNode::Pointer> QmitkAbstractViewPrivate::DataNodeSelectionToQList(mitk::DataNodeSelection::ConstPointer currentSelection) const
{
if (currentSelection.IsNull()) return QList<mitk::DataNode::Pointer>();
return QList<mitk::DataNode::Pointer>::fromStdList(currentSelection->GetSelectedDataNodes());
}
void QmitkAbstractView::NodeAdded( const mitk::DataNode* /*node*/ )
{
}
void QmitkAbstractView::NodeRemoved( const mitk::DataNode* /*node*/ )
{
}
void QmitkAbstractView::NodeChanged( const mitk::DataNode* /*node*/ )
{
}
void QmitkAbstractView::FireNodeSelected( mitk::DataNode::Pointer node )
{
QList<mitk::DataNode::Pointer> nodes;
nodes << node;
this->FireNodesSelected(nodes);
}
void QmitkAbstractView::FireNodesSelected( const QList<mitk::DataNode::Pointer>& nodes )
{
// if this is the first call to FireNodesSelected and the selection provider has no QItemSelectiomMode
// yet, set our helper model
if (d->m_SelectionProvider->GetItemSelectionModel() == 0)
{
d->m_SelectionProvider->SetItemSelectionModel(d->m_DataNodeSelectionModel);
}
else if (d->m_SelectionProvider->GetItemSelectionModel() != d->m_DataNodeSelectionModel)
{
MITK_WARN << "A custom data node selection model has been set. Ignoring call to FireNodesSelected().";
return;
}
if (nodes.empty())
{
d->m_DataNodeSelectionModel->clearSelection();
d->m_DataNodeItemModel->clear();
}
else
{
// The helper data node model is just used for sending selection events.
// We add the to be selected nodes and set the selection range to everything.
d->m_DataNodeItemModel->clear();
foreach(mitk::DataNode::Pointer node, nodes)
{
d->m_DataNodeItemModel->AddDataNode(node);
}
- d->m_DataNodeSelectionModel->select(QItemSelection(d->m_DataNodeItemModel->index(0,0), d->m_DataNodeItemModel->index(nodes.size(), 0)),
+ d->m_DataNodeSelectionModel->select(QItemSelection(d->m_DataNodeItemModel->index(0,0), d->m_DataNodeItemModel->index(nodes.size()-1, 0)),
QItemSelectionModel::ClearAndSelect);
}
}
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
index c36edc20f6..cfe1160cdd 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
@@ -1,1077 +1,1119 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkDataManagerView.h"
#include <itkOtsuThresholdImageFilter.h>
//# Own Includes
//## mitk
#include "mitkDataStorageEditorInput.h"
#include "mitkIDataStorageReference.h"
#include "mitkNodePredicateDataType.h"
#include "mitkCoreObjectFactory.h"
#include "mitkDataNodeFactory.h"
#include "mitkColorProperty.h"
#include "mitkCommon.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateNot.h"
+#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateProperty.h"
#include "mitkEnumerationProperty.h"
#include "mitkLookupTableProperty.h"
#include "mitkProperties.h"
#include <mitkNodePredicateAnd.h>
#include <mitkITKImageImport.h>
#include <mitkIDataStorageService.h>
#include <mitkIRenderingManager.h>
#include <mitkImageCast.h>
//## Qmitk
#include <QmitkDnDFrameWidget.h>
-#include <QmitkDataStorageTableModel.h>
#include <QmitkIOUtil.h>
#include <QmitkDataStorageTreeModel.h>
#include <QmitkCustomVariants.h>
+#include <QmitkDataStorageFilterProxyModel.h>
#include <QmitkNumberPropertySlider.h>
#include "src/internal/QmitkNodeTableViewKeyFilter.h"
#include "src/internal/QmitkInfoDialog.h"
#include "src/internal/QmitkDataManagerItemDelegate.h"
//## Berry
#include <berryIEditorPart.h>
#include <berryIWorkbenchPage.h>
#include <berryIPreferencesService.h>
#include <berryPlatform.h>
#include <berryPlatformUI.h>
#include <berryIEditorRegistry.h>
//# Toolkit Includes
#include <QTableView>
#include <QGroupBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QListView>
#include <QMenu>
#include <QAction>
#include <QComboBox>
#include <QApplication>
#include <QCursor>
#include <QHeaderView>
#include <QTreeView>
#include <QWidgetAction>
#include <QSplitter>
#include <QPushButton>
#include <QMotifStyle>
#include <QFileDialog>
#include <QMessageBox>
#include <QToolBar>
#include <QKeyEvent>
#include <QColor>
#include <QColorDialog>
#include <QSizePolicy>
+#include <QSortFilterProxyModel>
#include <QSignalMapper>
#include "mitkDataNodeObject.h"
#include "mitkIContextMenuAction.h"
#include "berryIExtensionPointService.h"
#include "mitkRenderingModeProperty.h"
const std::string QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager";
QmitkDataManagerView::QmitkDataManagerView()
: m_GlobalReinitOnNodeDelete(true),
m_ItemDelegate(NULL)
{
}
QmitkDataManagerView::~QmitkDataManagerView()
{
//Remove all registered actions from each descriptor
for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++)
{
// first== the NodeDescriptor; second== the registered QAction
(it->first)->RemoveAction(it->second);
}
}
void QmitkDataManagerView::CreateQtPartControl(QWidget* parent)
{
m_CurrentRowCount = 0;
m_Parent = parent;
//# Preferences
berry::IPreferencesService::Pointer prefService
= berry::Platform::GetServiceRegistry()
.GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
berry::IBerryPreferences::Pointer prefs
= (prefService->GetSystemPreferences()->Node(VIEW_ID))
.Cast<berry::IBerryPreferences>();
assert( prefs );
prefs->OnChanged.AddListener( berry::MessageDelegate1<QmitkDataManagerView
, const berry::IBerryPreferences*>( this
, &QmitkDataManagerView::OnPreferencesChanged ) );
//# GUI
m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage());
m_NodeTreeModel->setParent( parent );
m_NodeTreeModel->SetPlaceNewNodesOnTop(
prefs->GetBool("Place new nodes on top", true) );
- m_NodeTreeModel->SetShowHelperObjects(
- prefs->GetBool("Show helper objects", false) );
- m_NodeTreeModel->SetShowNodesContainingNoData(
- prefs->GetBool("Show nodes containing no data", false) );
+
m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false);
+ // Prepare filters
+ m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New(
+ mitk::NodePredicateProperty::New("helper object"),
+ mitk::NodePredicateProperty::New("hidden object"));
+ m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(0);
+
+ m_FilterModel = new QmitkDataStorageFilterProxyModel();
+ m_FilterModel->setSourceModel(m_NodeTreeModel);
+ m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate);
+ m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate);
//# Tree View (experimental)
m_NodeTreeView = new QTreeView;
m_NodeTreeView->setHeaderHidden(true);
m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection );
m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows );
m_NodeTreeView->setAlternatingRowColors(true);
m_NodeTreeView->setDragEnabled(true);
m_NodeTreeView->setDropIndicatorShown(true);
m_NodeTreeView->setAcceptDrops(true);
m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
- m_NodeTreeView->setModel(m_NodeTreeModel);
+ m_NodeTreeView->setModel(m_FilterModel);
m_NodeTreeView->setTextElideMode(Qt::ElideMiddle);
m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this));
m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView);
m_NodeTreeView->setItemDelegate(m_ItemDelegate);
QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&))
, this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) );
QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int))
, this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) );
QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int))
, this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) );
QObject::connect( m_NodeTreeView->selectionModel()
, SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) )
, this
, SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) );
//# m_NodeMenu
m_NodeMenu = new QMenu(m_NodeTreeView);
// # Actions
berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
std::list<berry::IEditorDescriptor::Pointer> editors = editorRegistry->GetEditors("*.mitk");
if (editors.size() > 1)
{
m_ShowInMapper = new QSignalMapper(this);
foreach(berry::IEditorDescriptor::Pointer descriptor, editors)
{
QAction* action = new QAction(QString::fromStdString(descriptor->GetLabel()), this);
m_ShowInActions << action;
m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map()));
m_ShowInMapper->setMapping(action, QString::fromStdString(descriptor->GetId()));
}
connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString)));
}
QmitkNodeDescriptor* unknownDataNodeDescriptor =
QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor();
QmitkNodeDescriptor* imageDataNodeDescriptor =
QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image");
QmitkNodeDescriptor* surfaceDataNodeDescriptor =
QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface");
QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this);
QObject::connect( globalReinitAction, SIGNAL( triggered(bool) )
, this, SLOT( GlobalReinit(bool) ) );
unknownDataNodeDescriptor->AddAction(globalReinitAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor, globalReinitAction));
QAction* saveAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), "Save...", this);
QObject::connect( saveAction, SIGNAL( triggered(bool) )
, this, SLOT( SaveSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(saveAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,saveAction));
QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this);
QObject::connect( removeAction, SIGNAL( triggered(bool) )
, this, SLOT( RemoveSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(removeAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,removeAction));
QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this);
QObject::connect( reinitAction, SIGNAL( triggered(bool) )
, this, SLOT( ReinitSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(reinitAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,reinitAction));
// find contextMenuAction extension points and add them to the node descriptor
berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService();
berry::IConfigurationElement::vector cmActions(
extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") );
berry::IConfigurationElement::vector::iterator cmActionsIt;
std::string cmNodeDescriptorName;
std::string cmLabel;
std::string cmIcon;
std::string cmClass;
QmitkNodeDescriptor* tmpDescriptor;
QAction* contextMenuAction;
QVariant cmActionDataIt;
m_ConfElements.clear();
int i=1;
for (cmActionsIt = cmActions.begin()
; cmActionsIt != cmActions.end()
; ++cmActionsIt)
{
cmIcon.erase();
if((*cmActionsIt)->GetAttribute("nodeDescriptorName", cmNodeDescriptorName)
&& (*cmActionsIt)->GetAttribute("label", cmLabel)
&& (*cmActionsIt)->GetAttribute("class", cmClass))
{
(*cmActionsIt)->GetAttribute("icon", cmIcon);
// create context menu entry here
tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(QString::fromStdString(cmNodeDescriptorName));
if(!tmpDescriptor)
{
MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist";
continue;
}
contextMenuAction = new QAction( QString::fromStdString(cmLabel), parent);
tmpDescriptor->AddAction(contextMenuAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(tmpDescriptor,contextMenuAction));
m_ConfElements[contextMenuAction] = *cmActionsIt;
cmActionDataIt.setValue<int>(i);
contextMenuAction->setData( cmActionDataIt );
connect( contextMenuAction, SIGNAL( triggered(bool) ) , this, SLOT( ContextMenuActionTriggered(bool) ) );
++i;
}
}
m_OpacitySlider = new QSlider;
m_OpacitySlider->setMinimum(0);
m_OpacitySlider->setMaximum(100);
m_OpacitySlider->setOrientation(Qt::Horizontal);
QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) )
, this, SLOT( OpacityChanged(int) ) );
QLabel* _OpacityLabel = new QLabel("Opacity: ");
QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout;
_OpacityWidgetLayout->setContentsMargins(4,4,4,4);
_OpacityWidgetLayout->addWidget(_OpacityLabel);
_OpacityWidgetLayout->addWidget(m_OpacitySlider);
QWidget* _OpacityWidget = new QWidget;
_OpacityWidget->setLayout(_OpacityWidgetLayout);
QWidgetAction* opacityAction = new QWidgetAction(this);
opacityAction ->setDefaultWidget(_OpacityWidget);
QObject::connect( opacityAction , SIGNAL( changed() )
, this, SLOT( OpacityActionChanged() ) );
unknownDataNodeDescriptor->AddAction(opacityAction , false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,opacityAction));
m_ColorButton = new QPushButton;
m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
//m_ColorButton->setText("Change color");
QObject::connect( m_ColorButton, SIGNAL( clicked() )
, this, SLOT( ColorChanged() ) );
QLabel* _ColorLabel = new QLabel("Color: ");
_ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout;
_ColorWidgetLayout->setContentsMargins(4,4,4,4);
_ColorWidgetLayout->addWidget(_ColorLabel);
_ColorWidgetLayout->addWidget(m_ColorButton);
QWidget* _ColorWidget = new QWidget;
_ColorWidget->setLayout(_ColorWidgetLayout);
QWidgetAction* colorAction = new QWidgetAction(this);
colorAction->setDefaultWidget(_ColorWidget);
QObject::connect( colorAction, SIGNAL( changed() )
, this, SLOT( ColorActionChanged() ) );
unknownDataNodeDescriptor->AddAction(colorAction, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,colorAction));
m_ComponentSlider = new QmitkNumberPropertySlider;
m_ComponentSlider->setOrientation(Qt::Horizontal);
//QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) )
// , this, SLOT( OpacityChanged(int) ) );
QLabel* _ComponentLabel = new QLabel("Component: ");
QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout;
_ComponentWidgetLayout->setContentsMargins(4,4,4,4);
_ComponentWidgetLayout->addWidget(_ComponentLabel);
_ComponentWidgetLayout->addWidget(m_ComponentSlider);
QLabel* _ComponentValueLabel = new QLabel();
_ComponentWidgetLayout->addWidget(_ComponentValueLabel);
connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int)));
QWidget* _ComponentWidget = new QWidget;
_ComponentWidget->setLayout(_ComponentWidgetLayout);
QWidgetAction* componentAction = new QWidgetAction(this);
componentAction->setDefaultWidget(_ComponentWidget);
QObject::connect( componentAction , SIGNAL( changed() )
, this, SLOT( ComponentActionChanged() ) );
imageDataNodeDescriptor->AddAction(componentAction, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor,componentAction));
m_TextureInterpolation = new QAction("Texture Interpolation", this);
m_TextureInterpolation->setCheckable ( true );
QObject::connect( m_TextureInterpolation, SIGNAL( changed() )
, this, SLOT( TextureInterpolationChanged() ) );
QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) )
, this, SLOT( TextureInterpolationToggled(bool) ) );
imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor,m_TextureInterpolation));
m_ColormapAction = new QAction("Colormap", this);
m_ColormapAction->setMenu(new QMenu);
QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() )
, this, SLOT( ColormapMenuAboutToShow() ) );
imageDataNodeDescriptor->AddAction(m_ColormapAction, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor, m_ColormapAction));
m_SurfaceRepresentation = new QAction("Surface Representation", this);
m_SurfaceRepresentation->setMenu(new QMenu);
QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() )
, this, SLOT( SurfaceRepresentationMenuAboutToShow() ) );
surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(surfaceDataNodeDescriptor, m_SurfaceRepresentation));
QAction* showOnlySelectedNodes
= new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png")
, "Show only selected nodes", this);
QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) )
, this, SLOT( ShowOnlySelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor, showOnlySelectedNodes));
QAction* toggleSelectedVisibility
= new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png")
, "Toggle visibility", this);
QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) )
, this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,toggleSelectedVisibility));
QAction* actionShowInfoDialog
= new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png")
, "Details...", this);
QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) )
, this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(actionShowInfoDialog);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,actionShowInfoDialog));
//obsolete...
//QAction* otsuFilterAction = new QAction("Apply Otsu Filter", this);
//QObject::connect( otsuFilterAction, SIGNAL( triggered(bool) )
// , this, SLOT( OtsuFilter(bool) ) );
// //Otsu filter does not work properly, remove it temporarily
// imageDataNodeDescriptor->AddAction(otsuFilterAction);
// m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor,otsuFilterAction));
QGridLayout* _DndFrameWidgetLayout = new QGridLayout;
_DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0);
_DndFrameWidgetLayout->setContentsMargins(0,0,0,0);
m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent);
m_DndFrameWidget->setLayout(_DndFrameWidgetLayout);
QVBoxLayout* layout = new QVBoxLayout(parent);
layout->addWidget(m_DndFrameWidget);
layout->setContentsMargins(0,0,0,0);
m_Parent->setLayout(layout);
}
void QmitkDataManagerView::SetFocus()
{
}
void QmitkDataManagerView::ContextMenuActionTriggered( bool )
{
QAction* action = qobject_cast<QAction*> ( sender() );
std::map<QAction*, berry::IConfigurationElement::Pointer>::iterator it
= m_ConfElements.find( action );
if( it == m_ConfElements.end() )
{
MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found";
return;
}
berry::IConfigurationElement::Pointer confElem = it->second;
mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension<mitk::IContextMenuAction>("class");
std::string className;
std::string smoothed;
confElem->GetAttribute("class", className);
confElem->GetAttribute("smoothed", smoothed);
if(className == "QmitkCreatePolygonModelAction")
{
contextMenuAction->SetDataStorage(this->GetDataStorage());
if(smoothed == "false")
{
contextMenuAction->SetSmoothed(false);
}
else
{
contextMenuAction->SetSmoothed(true);
}
contextMenuAction->SetDecimated(m_SurfaceDecimation);
}
else if(className == "QmitkStatisticsAction")
{
contextMenuAction->SetFunctionality(this);
}
else if(className == "QmitkCreateSimulationAction")
{
contextMenuAction->SetDataStorage(this->GetDataStorage());
}
contextMenuAction->Run( this->GetCurrentSelection() ); // run the action
}
void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) )
m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() );
- if( m_NodeTreeModel->GetShowHelperObjectsFlag()!= prefs->GetBool("Show helper objects", false) )
- m_NodeTreeModel->SetShowHelperObjects( !m_NodeTreeModel->GetShowHelperObjectsFlag() );
+ bool hideHelperObjects = !prefs->GetBool("Show helper objects", false);
+ if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects)
+ {
+ if (hideHelperObjects)
+ {
+ m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate);
+ }
+ else
+ {
+ m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate);
+ }
+ }
+ bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false);
- if( m_NodeTreeModel->GetShowNodesContainingNoDataFlag()!= prefs->GetBool("Show nodes containing no data", false) )
- m_NodeTreeModel->SetShowNodesContainingNoData( !m_NodeTreeModel->GetShowNodesContainingNoDataFlag() );
+ if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData)
+ {
+ if (hideNodesWithNoData)
+ {
+ m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate);
+ }
+ else
+ {
+ m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate);
+ }
+ }
m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true);
m_NodeTreeView->expandAll();
m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false);
this->GlobalReinit();
}
void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos )
{
- QModelIndex selected = m_NodeTreeView->indexAt ( pos );
+ QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos );
+ QModelIndex selected = m_FilterModel->mapToSource(selectedProxy);
+
mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected);
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
if(!selectedNodes.isEmpty())
{
m_NodeMenu->clear();
QList<QAction*> actions;
if(selectedNodes.size() == 1 )
{
actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node);
for(QList<QAction*>::iterator it = actions.begin(); it != actions.end(); ++it)
{
(*it)->setData(QVariant::fromValue(node.GetPointer()));
}
}
else
actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes);
if (!m_ShowInActions.isEmpty())
{
QMenu* showInMenu = m_NodeMenu->addMenu("Show In");
showInMenu->addActions(m_ShowInActions);
}
m_NodeMenu->addActions(actions);
m_NodeMenu->popup(QCursor::pos());
}
}
void QmitkDataManagerView::OpacityChanged(int value)
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
float opacity = static_cast<float>(value)/100.0f;
node->SetFloatProperty("opacity", opacity);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::OpacityActionChanged()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
float opacity = 0.0;
if(node->GetFloatProperty("opacity", opacity))
{
m_OpacitySlider->setValue(static_cast<int>(opacity*100));
}
}
}
void QmitkDataManagerView::ComponentActionChanged()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
mitk::IntProperty* componentProperty = NULL;
int numComponents = 0;
if(node)
{
componentProperty =
dynamic_cast<mitk::IntProperty*>(node->GetProperty("Image.Displayed Component"));
mitk::Image* img = dynamic_cast<mitk::Image*>(node->GetData());
if (img != NULL)
{
numComponents = img->GetPixelType().GetNumberOfComponents();
}
}
if (componentProperty && numComponents > 1)
{
m_ComponentSlider->SetProperty(componentProperty);
m_ComponentSlider->setMinValue(0);
m_ComponentSlider->setMaxValue(numComponents-1);
}
else
{
m_ComponentSlider->SetProperty(static_cast<mitk::IntProperty*>(NULL));
}
}
void QmitkDataManagerView::ColorChanged()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
mitk::Color color;
mitk::ColorProperty::Pointer colorProp;
node->GetProperty(colorProp,"color");
if(colorProp.IsNull())
return;
color = colorProp->GetValue();
QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255);
QColor qcolor = QColorDialog::getColor(initial,0,QString("Change color"));
if (!qcolor.isValid())
return;
m_ColorButton->setAutoFillBackground(true);
node->SetProperty("color",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0));
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::ColorActionChanged()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
mitk::Color color;
mitk::ColorProperty::Pointer colorProp;
node->GetProperty(colorProp,"color");
if(colorProp.IsNull())
return;
color = colorProp->GetValue();
QString styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color[0]*255));
styleSheet.append(",");
styleSheet.append(QString::number(color[1]*255));
styleSheet.append(",");
styleSheet.append(QString::number(color[2]*255));
styleSheet.append(")");
m_ColorButton->setStyleSheet(styleSheet);
}
}
void QmitkDataManagerView::TextureInterpolationChanged()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
bool textureInterpolation = false;
node->GetBoolProperty("texture interpolation", textureInterpolation);
m_TextureInterpolation->setChecked(textureInterpolation);
}
}
void QmitkDataManagerView::TextureInterpolationToggled( bool checked )
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
node->SetBoolProperty("texture interpolation", checked);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ )
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::LookupTableProperty::Pointer lookupTableProperty =
dynamic_cast<mitk::LookupTableProperty*>(node->GetProperty("LookupTable"));
if (!lookupTableProperty)
return;
QAction* senderAction = qobject_cast<QAction*>(QObject::sender());
if(!senderAction)
return;
std::string activatedItem = senderAction->text().toStdString();
mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue();
if (!lookupTable)
return;
lookupTable->SetType(activatedItem);
lookupTableProperty->SetValue(lookupTable);
mitk::RenderingModeProperty::Pointer renderingMode =
dynamic_cast<mitk::RenderingModeProperty*>(node->GetProperty("Image Rendering.Mode"));
renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ColormapMenuAboutToShow()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::LookupTableProperty::Pointer lookupTableProperty =
dynamic_cast<mitk::LookupTableProperty*>(node->GetProperty("LookupTable"));
if (!lookupTableProperty)
{
mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New();
lookupTableProperty = mitk::LookupTableProperty::New();
lookupTableProperty->SetLookupTable(mitkLut);
node->SetProperty("LookupTable", lookupTableProperty);
}
mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue();
if (!lookupTable)
return;
m_ColormapAction->menu()->clear();
QAction* tmp;
int i = 0;
std::string lutType = lookupTable->typenameList[i];
while (lutType != "END_OF_ARRAY")
{
tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType));
tmp->setCheckable(true);
if (lutType == lookupTable->GetActiveTypeAsString())
{
tmp->setChecked(true);
}
QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool)));
lutType = lookupTable->typenameList[++i];
}
}
void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow()
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::EnumerationProperty* representationProp =
dynamic_cast<mitk::EnumerationProperty*> (node->GetProperty("material.representation"));
if(!representationProp)
return;
// clear menu
m_SurfaceRepresentation->menu()->clear();
QAction* tmp;
// create menu entries
for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End()
; it++)
{
tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second));
tmp->setCheckable(true);
if(it->second == representationProp->GetValueAsString())
{
tmp->setChecked(true);
}
QObject::connect( tmp, SIGNAL( triggered(bool) )
, this, SLOT( SurfaceRepresentationActionToggled(bool) ) );
}
}
void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ )
{
- mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex());
+ mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::EnumerationProperty* representationProp =
dynamic_cast<mitk::EnumerationProperty*> (node->GetProperty("material.representation"));
if(!representationProp)
return;
QAction* senderAction = qobject_cast<QAction*> ( QObject::sender() );
if(!senderAction)
return;
std::string activatedItem = senderAction->text().toStdString();
if ( activatedItem != representationProp->GetValueAsString() )
{
if ( representationProp->IsValidEnumerationValue( activatedItem ) )
{
representationProp->SetValue( activatedItem );
representationProp->InvokeEvent( itk::ModifiedEvent() );
representationProp->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
}
void QmitkDataManagerView::SaveSelectedNodes( bool )
{
- QModelIndexList indexesOfSelectedRows = m_NodeTreeView->selectionModel()->selectedRows();
+ QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows();
+ QModelIndexList indexesOfSelectedRows;
+ for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i)
+ {
+ indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i]));
+ }
mitk::DataNode* node = 0;
unsigned int indexesOfSelectedRowsSize = indexesOfSelectedRows.size();
for (unsigned int i = 0; i<indexesOfSelectedRowsSize; ++i)
{
node = m_NodeTreeModel->GetNode(indexesOfSelectedRows.at(i));
// if node is not defined or if the node contains geometry data do not remove it
if ( node != 0 )
{
mitk::BaseData::Pointer data = node->GetData();
if (data.IsNotNull())
{
QString error;
try
{
QmitkIOUtil::SaveBaseDataWithDialog( data.GetPointer(), node->GetName().c_str(), m_Parent );
}
catch(std::exception& e)
{
error = e.what();
}
catch(...)
{
error = "Unknown error occured";
}
if( !error.isEmpty() )
QMessageBox::critical( m_Parent, "Error saving...", error );
}
}
}
}
void QmitkDataManagerView::ReinitSelectedNodes( bool )
{
mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
if (renderWindow == NULL)
renderWindow = this->OpenRenderWindowPart(false);
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
foreach(mitk::DataNode::Pointer node, selectedNodes)
{
mitk::BaseData::Pointer basedata = node->GetData();
if ( basedata.IsNotNull() &&
basedata->GetTimeGeometry()->IsValid() )
{
renderWindow->GetRenderingManager()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
renderWindow->GetRenderingManager()->RequestUpdateAll();
}
}
}
void QmitkDataManagerView::RemoveSelectedNodes( bool )
{
- QModelIndexList indexesOfSelectedRows = m_NodeTreeView->selectionModel()->selectedRows();
+ QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows();
+ QModelIndexList indexesOfSelectedRows;
+ for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i)
+ {
+ indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i]));
+ }
+
if(indexesOfSelectedRows.size() < 1)
{
return;
}
std::vector<mitk::DataNode*> selectedNodes;
mitk::DataNode* node = 0;
QString question = tr("Do you really want to remove ");
for (QModelIndexList::iterator it = indexesOfSelectedRows.begin()
; it != indexesOfSelectedRows.end(); it++)
{
node = m_NodeTreeModel->GetNode(*it);
// if node is not defined or if the node contains geometry data do not remove it
if ( node != 0 /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ )
{
selectedNodes.push_back(node);
question.append(QString::fromStdString(node->GetName()));
question.append(", ");
}
}
// remove the last two characters = ", "
question = question.remove(question.size()-2, 2);
question.append(" from data storage?");
QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent
, tr("DataManager")
, question
, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if(answerButton == QMessageBox::Yes)
{
for (std::vector<mitk::DataNode*>::iterator it = selectedNodes.begin()
; it != selectedNodes.end(); it++)
{
node = *it;
this->GetDataStorage()->Remove(node);
if (m_GlobalReinitOnNodeDelete)
this->GlobalReinit(false);
}
}
}
void QmitkDataManagerView::MakeAllNodesInvisible( bool )
{
QList<mitk::DataNode::Pointer> nodes = m_NodeTreeModel->GetNodeSet();
foreach(mitk::DataNode::Pointer node, nodes)
{
node->SetVisibility(false);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ShowOnlySelectedNodes( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
QList<mitk::DataNode::Pointer> allNodes = m_NodeTreeModel->GetNodeSet();
foreach(mitk::DataNode::Pointer node, allNodes)
{
node->SetVisibility(selectedNodes.contains(node));
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
bool isVisible = false;
foreach(mitk::DataNode::Pointer node, selectedNodes)
{
isVisible = false;
node->GetBoolProperty("visible", isVisible);
node->SetVisibility(!isVisible);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent);
_QmitkInfoDialog.exec();
}
void QmitkDataManagerView::Load( bool )
{
QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Load data", "", mitk::CoreObjectFactory::GetInstance()->GetFileExtensions());
for ( QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it )
{
FileOpen((*it).toAscii(), 0);
}
}
void QmitkDataManagerView::FileOpen( const char * fileName, mitk::DataNode* parentNode )
{
mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
try
{
factory->SetFileName( fileName );
QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
factory->Update();
for ( unsigned int i = 0 ; i < factory->GetNumberOfOutputs( ); ++i )
{
mitk::DataNode::Pointer node = factory->GetOutput( i );
if ( ( node.IsNotNull() ) && ( node->GetData() != NULL ) )
{
this->GetDataStorage()->Add(node, parentNode);
mitk::BaseData::Pointer basedata = node->GetData();
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
//mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
}
catch ( itk::ExceptionObject & ex )
{
itkGenericOutputMacro( << "Exception during file open: " << ex );
}
QApplication::restoreOverrideCursor();
}
+void QmitkDataManagerView::NodeChanged(const mitk::DataNode* node)
+{
+ // m_FilterModel->invalidate();
+ // fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014
+ QMetaObject::invokeMethod( m_FilterModel, "invalidate", Qt::QueuedConnection );
+}
+
QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const
{
return m_NodeTreeView->selectionModel();
}
void QmitkDataManagerView::GlobalReinit( bool )
{
mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
if (renderWindow == NULL)
renderWindow = this->OpenRenderWindowPart(false);
// no render window available
if (renderWindow == NULL) return;
mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage());
}
void QmitkDataManagerView::OtsuFilter( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
mitk::Image::Pointer mitkImage = 0;
foreach(mitk::DataNode::Pointer node, selectedNodes)
{
mitkImage = dynamic_cast<mitk::Image*>( node->GetData() );
if(mitkImage.IsNull())
continue;
try
{
// get selected mitk image
const unsigned short dim = 3;
typedef short InputPixelType;
typedef unsigned char OutputPixelType;
typedef itk::Image< InputPixelType, dim > InputImageType;
typedef itk::Image< OutputPixelType, dim > OutputImageType;
typedef itk::OtsuThresholdImageFilter< InputImageType, OutputImageType > FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetOutsideValue( 1 );
filter->SetInsideValue( 0 );
InputImageType::Pointer itkImage;
mitk::CastToItkImage(mitkImage, itkImage);
filter->SetInput( itkImage );
filter->Update();
mitk::DataNode::Pointer resultNode = mitk::DataNode::New();
std::string nameOfResultImage = node->GetName();
nameOfResultImage.append("Otsu");
resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) );
resultNode->SetProperty("binary", mitk::BoolProperty::New(true) );
resultNode->SetData( mitk::ImportItkImage(filter->GetOutput())->Clone());
this->GetDataStorage()->Add(resultNode, node);
}
catch( std::exception& err )
{
MITK_ERROR(this->GetClassName()) << err.what();
}
}
}
void QmitkDataManagerView::NodeTreeViewRowsRemoved (
const QModelIndex & /*parent*/, int /*start*/, int /*end*/ )
{
m_CurrentRowCount = m_NodeTreeModel->rowCount();
}
void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int )
{
m_NodeTreeView->setExpanded(parent, true);
// a new row was inserted
if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 )
{
this->OpenRenderWindowPart();
m_CurrentRowCount = m_NodeTreeModel->rowCount();
- /*
- std::vector<mitk::DataNode*> nodes = m_NodeTreeModel->GetNodeSet();
- if(nodes.size() == 1)
- {
- QModelIndex treeIndex = m_NodeTreeModel->GetIndex(nodes.front());
- m_NodeTreeView->selectionModel()->setCurrentIndex( treeIndex, QItemSelectionModel::ClearAndSelect );
- }
- */
+
}
}
void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ )
{
QList<mitk::DataNode::Pointer> nodes = m_NodeTreeModel->GetNodeSet();
foreach(mitk::DataNode::Pointer node, nodes)
{
if ( node.IsNotNull() )
node->SetBoolProperty("selected", false);
}
nodes.clear();
nodes = this->GetCurrentSelection();
foreach(mitk::DataNode::Pointer node, nodes)
{
if ( node.IsNotNull() )
node->SetBoolProperty("selected", true);
}
//changing the selection does NOT require any rendering processes!
//mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ShowIn(const QString &editorId)
{
berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage();
berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference()));
page->OpenEditor(input, editorId.toStdString(), false, berry::IWorkbenchPage::MATCH_ID);
}
mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor)
{
if (activatedEditor)
{
return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN);
}
else
{
return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN);
}
}
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
index 316b9f6c0a..db9be5face 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
@@ -1,269 +1,277 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKDATAMANAGERVIEW_H_
#define QMITKDATAMANAGERVIEW_H_
// BlueBerry includes
#include <berryIBerryPreferences.h>
/// Qmitk
#include <QmitkAbstractView.h>
#include <QmitkNodeDescriptorManager.h>
/// Qt
#include <QItemSelection>
#include <org_mitk_gui_qt_datamanager_Export.h>
// Forward declarations
class QMenu;
class QAction;
class QComboBox;
class QWidgetAction;
class QSlider;
class QModelIndex;
class QTreeView;
class QPushButton;
class QToolBar;
class QMenu;
class QSignalMapper;
class QmitkDnDFrameWidget;
class QmitkDataStorageTreeModel;
class QmitkDataManagerItemDelegate;
class QmitkNumberPropertySlider;
+class QmitkDataStorageFilterProxyModel;
///
/// \ingroup org_mitk_gui_qt_datamanager_internal
///
/// \brief A View class that can show all data tree nodes of a certain DataStorage
///
/// \TODO: complete PACS support, in save dialog show regular filename
///
class MITK_QT_DATAMANAGER QmitkDataManagerView : public QmitkAbstractView
{
Q_OBJECT
public:
static const std::string VIEW_ID; // = "org.mitk.extapp.defaultperspective"
///
/// \brief Standard ctor.
///
QmitkDataManagerView();
///
/// \brief Standard dtor.
///
virtual ~QmitkDataManagerView();
public slots:
///
/// Invoked when the opacity slider changed
///
void OpacityChanged(int value);
///
/// Invoked when the opacity action changed
/// In this function the the opacity slider is set to the selected nodes opacity value
///
void OpacityActionChanged();
/// Invoked when the component action changed
/// In this function the the opacity slider is set to the selected nodes opacity value
///
void ComponentActionChanged();
///
/// Invoked when the color button is pressed
///
void ColorChanged();
///
/// Invoked when the color action changed
///
void ColorActionChanged();
///
/// Invoked when the color button is pressed
///
void TextureInterpolationChanged();
///
/// Invoked when the color action changed
///
void TextureInterpolationToggled ( bool checked );
///
/// \brief Agreggates available colormaps
///
void ColormapMenuAboutToShow ();
///
/// \brief changes the active colormap
///
void ColormapActionToggled (bool);
///
/// SurfaceRepresentationActionToggled
///
void SurfaceRepresentationMenuAboutToShow ();
///
/// SurfaceRepresentationActionToggled
///
void SurfaceRepresentationActionToggled ( bool checked );
///
/// \brief Shows a node context menu.
///
void NodeTableViewContextMenuRequested( const QPoint & index );
///
/// \brief Invoked when an element should be saved.
///
void SaveSelectedNodes( bool checked = false );
///
/// \brief Invoked when an element should be removed.
///
void RemoveSelectedNodes( bool checked = false );
///
/// \brief Invoked when an element should be reinitiliased.
///
void ReinitSelectedNodes( bool checked = false );
///
/// \brief Invoked when the visibility of the selected nodes should be toggled.
///
void MakeAllNodesInvisible ( bool checked = false );
///
/// \brief Makes all selected nodes visible, all other nodes invisible.
///
void ShowOnlySelectedNodes ( bool checked = false );
///
/// \brief Invoked when the visibility of the selected nodes should be toggled.
///
void ToggleVisibilityOfSelectedNodes ( bool checked = false );
///
/// \brief Invoked when infos of the selected nodes should be shown in a dialog.
///
void ShowInfoDialogForSelectedNodes ( bool checked = false );
///
/// \brief Shows a load dialog.
///
void Load ( bool checked = false );
///
/// \brief Reinits everything.
///
void GlobalReinit ( bool checked = false );
///
/// Invoked when the preferences were changed
///
void OnPreferencesChanged(const berry::IBerryPreferences*);
///
/// \brief will be toggled when a extension point context menu action is toggled
/// this is a proxy method which will load the corresponding extension class
/// and run IContextMenuAction
///
void ContextMenuActionTriggered( bool );
/// Invoked when the median action is invoked
void OtsuFilter( bool checked = false );
/// When rows are inserted auto expand them
void NodeTreeViewRowsInserted ( const QModelIndex & parent, int start, int end );
/// will setup m_CurrentRowCount
void NodeTreeViewRowsRemoved ( const QModelIndex & parent, int start, int end );
/// Whenever the selection changes set the "selected" property respectively
void NodeSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
/// Opens the editor with the given id using the current data storage
void ShowIn(const QString& editorId);
protected:
///
/// \brief Create the view here.
///
virtual void CreateQtPartControl(QWidget* parent);
void SetFocus();
///
/// \brief Shows a file open dialog.
///
void FileOpen( const char * fileName, mitk::DataNode* parentNode );
+ ///
+ /// React to node changes. Overridden from QmitkAbstractView.
+ ///
+ virtual void NodeChanged(const mitk::DataNode* node);
protected:
QWidget* m_Parent;
QmitkDnDFrameWidget* m_DndFrameWidget;
///
/// \brief A plain widget as the base pane.
///
QmitkDataStorageTreeModel* m_NodeTreeModel;
+ QmitkDataStorageFilterProxyModel* m_FilterModel;
+ mitk::NodePredicateBase::Pointer m_HelperObjectFilterPredicate;
+ mitk::NodePredicateBase::Pointer m_NodeWithNoDataFilterPredicate;
///
/// Holds the preferences for the datamanager.
///
berry::IBerryPreferences::Pointer m_DataManagerPreferencesNode;
///
/// saves the configuration elements for the context menu actions from extension points
///
std::map<QAction*, berry::IConfigurationElement::Pointer> m_ConfElements;
///
/// \brief The Table view to show the selected nodes.
///
QTreeView* m_NodeTreeView;
///
/// \brief The context menu that shows up when right clicking on a node.
///
QMenu* m_NodeMenu;
///
/// \brief flag indicating whether a surface created from a selected decimation is decimated with vtkQuadricDecimation or not
///
bool m_SurfaceDecimation;
///# A list of ALL actions for the Context Menu
std::vector< std::pair< QmitkNodeDescriptor*, QAction* > > m_DescriptorActionList;
/// A Slider widget to change the opacity of a node
QSlider* m_OpacitySlider;
/// A Slider widget to change the rendered vector component of an image
QmitkNumberPropertySlider* m_ComponentSlider;
/// button to change the color of a node
QPushButton* m_ColorButton;
/// TextureInterpolation action
QAction* m_TextureInterpolation;
/// SurfaceRepresentation action
QAction* m_SurfaceRepresentation;
/// Lookuptable selection action
QAction* m_ColormapAction;
/// Maps "Show in" actions to editor ids
QSignalMapper* m_ShowInMapper;
/// A list of "Show in" actions
QList<QAction*> m_ShowInActions;
/// saves the current amount of rows shown in the datamanager
size_t m_CurrentRowCount;
/// if true, GlobalReinit() is called if a node is deleted
bool m_GlobalReinitOnNodeDelete;
QmitkDataManagerItemDelegate* m_ItemDelegate;
private:
QItemSelectionModel* GetDataNodeSelectionModel() const;
/// Reopen multi widget editor if it has been closed
mitk::IRenderWindowPart *OpenRenderWindowPart(bool activatedEditor = true);
};
#endif /*QMITKDATAMANAGERVIEW_H_*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml
index ae71b8ef94..cfda0a2210 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml
@@ -1,359 +1,359 @@
<?xml version="1.0" encoding="UTF-8"?>
<?BlueBerry version="0.1"?>
<plugin>
<extension point="org.blueberry.ui.keywords">
<keyword label="DICOM" id="org.mitk.views.diffusiondicomimport.Keyword"/>
<keyword label="image" id="org.mitk.views.diffusiondicomimport.Keyword"/>
<keyword label="data" id="org.mitk.views.diffusiondicomimport.Keyword"/>
<keyword label="load" id="org.mitk.views.diffusiondicomimport.Keyword"/>
<keyword label="signal" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="reconstruction" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="ball" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="diffusion" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="qball" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="q-ball" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="propagator" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="modeling" id="org.mitk.views.qballreconstruction.Keyword"/>
<keyword label="signal" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="reconstruction" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="tensor" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="diffusion" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="second order" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="propagator" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="modeling" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="DTI" id="org.mitk.views.tensorreconstruction.Keyword"/>
<keyword label="tractography" id="org.mitk.views.gibbstracking.Keyword"/>
<keyword label="tracking" id="org.mitk.views.gibbstracking.Keyword"/>
<keyword label="fiber" id="org.mitk.views.gibbstracking.Keyword"/>
<keyword label="global" id="org.mitk.views.gibbstracking.Keyword"/>
<keyword label="gibbs" id="org.mitk.views.gibbstracking.Keyword"/>
<keyword label="diffusion" id="org.mitk.views.gibbstracking.Keyword"/>
<keyword label="tractography" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="tracking" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="fiber" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="deterministic" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="streamline" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="tend" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="tensorline" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="tensorlines" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="multi" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="tensor" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="dti" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="diffusion" id="org.mitk.views.streamlinetracking.Keyword"/>
<keyword label="tractography" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="tracking" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="fiber" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="stochastic" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="probabilistic" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="streamline" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="tensor" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="dti" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="diffusion" id="org.mitk.views.stochasticfibertracking.Keyword"/>
<keyword label="diffusion" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="signal" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="simulation" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="data" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="synthetic" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="numeric" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="ball" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="dot" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="astrosticks" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="k-space" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="acquisition" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="artifact" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="artefact" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="gibbs ringing" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="spikes" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="distortions" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="aliasing" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="noise" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="fiberfox" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="rician" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="ghost" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="fieldmap" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="generator" id="org.mitk.views.fiberfoxview.Keyword"/>
<keyword label="GFA" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="RA" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="AD" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="RD" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="MD" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="anisotropy" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="fractional" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="radial" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="axial" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="diffusivity" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="mean" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="generalized" id="org.mitk.views.diffusionquantification.Keyword"/>
<keyword label="derived" id="org.mitk.views.diffusionquantification.Keyword"/>
</extension>
<extension point="org.blueberry.ui.views">
<view id="org.mitk.views.qballreconstruction"
name="Q-Balls"
category="Signal modeling"
icon="resources/qball.png"
class="QmitkQBallReconstructionView">
<description>Q-Ball reconstruction view</description>
<keywordReference id="org.mitk.views.qballreconstruction.Keyword"/>
</view>
<view id="org.mitk.views.diffusiondicomimport"
name="DICOM Import"
category="Data handling"
class="QmitkDiffusionDicomImport"
icon="resources/dwiimport.png">
<description>Diffusion DICOM data import</description>
<keywordReference id="org.mitk.views.diffusiondicomimport.Keyword"/>
</view>
<view id="org.mitk.views.diffusionpreprocessing"
name="Preprocessing"
category="Preprocessing"
class="QmitkPreprocessingView"
icon="resources/dwi2.png">
<keywordReference id="org.mitk.views.diffusionpreprocessing.Keyword"/>
</view>
<view id="org.mitk.views.diffusionquantification"
name="Scalar Indices"
category="Quantification"
class="QmitkDiffusionQuantificationView"
icon="resources/quantification.png">
<description>Calculation of tensor and Q-ball derived measures.</description>
<keywordReference id="org.mitk.views.diffusionquantification.Keyword"/>
</view>
<view id="org.mitk.views.tensorreconstruction"
name="Tensors"
category="Signal modeling"
icon="resources/tensor.png"
class="QmitkTensorReconstructionView">
<keywordReference id="org.mitk.views.tensorreconstruction.Keyword"/>
</view>
<view id="org.mitk.views.controlvisualizationpropertiesview"
name="Visualization"
icon="resources/vizControls.png"
class="QmitkControlVisualizationPropertiesView">
<keywordReference id="org.mitk.views.controlvisualizationpropertiesview.Keyword"/>
</view>
<view id="org.mitk.views.ivim"
name="IVIM"
category="Quantification"
class="QmitkIVIMView"
icon="resources/IVIM_48.png">
<keywordReference id="org.mitk.views.ivim.Keyword"/>
</view>
<view id="org.mitk.views.odfdetails"
name="ODF Details"
category="Quantification"
class="QmitkODFDetailsView"
icon="resources/OdfDetails.png">
<keywordReference id="org.mitk.views.odfdetails.Keyword"/>
</view>
<view id="org.mitk.views.gibbstracking"
name="Gibbs Tracking"
category="Fiber tractography"
class="QmitkGibbsTrackingView"
icon="resources/GibbsTracking.png">
<keywordReference id="org.mitk.views.gibbstracking.Keyword"/>
</view>
<view id="org.mitk.views.stochasticfibertracking"
name="Stochastic Tracking"
category="Fiber tractography"
class="QmitkStochasticFiberTrackingView"
icon="resources/stochFB.png">
<keywordReference id="org.mitk.views.stochasticfibertracking.Keyword"/>
</view>
<view id="org.mitk.views.streamlinetracking"
name="Streamline Tracking"
category="Fiber tractography"
class="QmitkStreamlineTrackingView"
icon="resources/StreamlineTracking.png">
<keywordReference id="org.mitk.views.streamlinetracking.Keyword"/>
</view>
<view id="org.mitk.views.fiberprocessing"
name="Fiber Processing"
category="Fiber processing"
class="QmitkFiberProcessingView"
icon="resources/FiberBundleOperations.png">
<keywordReference id="org.mitk.views.fiberprocessing.Keyword"/>
</view>
<view id="org.mitk.views.fiberextraction"
name="Fiber Extraction"
category="Fiber processing"
class="QmitkFiberExtractionView"
icon="resources/FiberBundleOperations.png">
<keywordReference id="org.mitk.views.fiberextraction.Keyword"/>
</view>
<view id="org.mitk.views.partialvolumeanalysisview"
name="PV Analysis"
category="Quantification"
class="QmitkPartialVolumeAnalysisView"
icon="resources/PartialVolumeAnalysis_24.png">
<keywordReference id="org.mitk.views.partialvolumeanalysisview.Keyword"/>
</view>
<view id="org.mitk.views.tbssskeletonization"
name="Tbss Skeletonization"
category="Quantification"
class="QmitkTbssSkeletonizationView"
icon="resources/tbss.png">
<keywordReference id="org.mitk.views.tbssskeletonization.Keyword"/>
</view>
<view id="org.mitk.views.tractbasedspatialstatistics"
name="Tract-based spatial statistics"
category="Quantification"
class="QmitkTractbasedSpatialStatisticsView"
icon="resources/tbss.png">
<keywordReference id="org.mitk.views.tractbasedspatialstatistics.Keyword"/>
</view>
<view id="org.mitk.views.connectomicsnetworkoperations"
name="Network Operations"
category="Connectomics"
class="QmitkConnectomicsNetworkOperationsView"
icon="resources/connectomics/QmitkConnectomicsNetworkOperationsViewIcon_48.png">
<keywordReference id="org.mitk.views.connectomicsnetworkoperations.Keyword"/>
</view>
<view id="org.mitk.views.connectomicsdata"
name="Network Data"
category="Connectomics"
class="QmitkConnectomicsDataView"
icon="resources/connectomics/QmitkConnectomicsDataViewIcon_48.png">
<keywordReference id="org.mitk.views.connectomicsdata.Keyword"/>
</view>
<view id="org.mitk.views.connectomicsstatistics"
name="Network Statistics"
category="Connectomics"
class="QmitkConnectomicsStatisticsView"
icon="resources/connectomics/QmitkConnectomicsStatisticsViewIcon_48.png">
<keywordReference id="org.mitk.views.connectomicsstatistics.Keyword"/>
</view>
<view id="org.mitk.views.randomparcellationview"
name="Random Parcellation View"
category="Connectomics"
class="QmitkRandomParcellationView"
icon="resources/connectomics/QmitkRandomParcellationIcon.png" >
<keywordReference id="org.mitk.views.randomparcellationview.Keyword"/>
</view>
<view id="org.mitk.views.odfmaximaextraction"
name="Peak Extraction"
category="Signal modeling"
class="QmitkOdfMaximaExtractionView"
icon="resources/qball_peaks.png">
<keywordReference id="org.mitk.views.odfmaximaextraction.Keyword"/>
</view>
<view id="org.mitk.views.fiberfoxview"
name="Fiberfox"
category="Simulated data"
class="QmitkFiberfoxView"
icon="resources/phantom.png">
<description>Diffusion weighted MRI data simulation tool.</description>
<keywordReference id="org.mitk.views.fiberfoxview.Keyword"/>
</view>
<view id="org.mitk.views.fieldmapgenerator"
name="Fieldmap Generator"
category="Simulated data"
class="QmitkFieldmapGeneratorView"
icon="resources/odf.png">
<keywordReference id="org.mitk.views.fiberfoxview.Keyword"/>
</view>
<view id="org.mitk.views.diffusionregistrationview"
name="DWI Registration"
category="Registration"
class="QmitkDiffusionRegistrationView"
icon="resources/diffusionregistration.png">
<keywordReference id="org.mitk.views.diffusionregistrationview.Keyword"/>
</view>
<view id="org.mitk.views.denoisingview"
name="DWI Denoising"
category="Preprocessing"
class="QmitkDenoisingView"
icon="resources/denoisingicon.png">
<keywordReference id="org.mitk.views.denoisingview.Keyword"/>
</view>
</extension>
<extension point="org.blueberry.ui.perspectives">
<perspective id="org.mitk.perspectives.fiberprocessings"
name="Fiber Processing"
class="QmitkFiberProcessingPerspective"
icon="resources/FiberBundleOperations.png">
- <description>This persective contains all views necessary to postprocess fibers.</description>
+ <description>This perspective contains all views necessary to post process fibers.</description>
<keywordReference id="org.mitk.perspectives.fiberprocessings.Keyword"/>
</perspective>
<perspective id="org.mitk.perspectives.tractography1"
name="Global Gibbs Tractography"
category="Fiber Tractography"
class="QmitkGibbsTractographyPerspective"
icon="resources/tractography.png">
<keywordReference id="org.mitk.perspectives.tractography1.Keyword"/>
</perspective>
<perspective id="org.mitk.perspectives.tractography2"
name="Deterministic streamline tractography"
category="Fiber Tractography"
class="QmitkStreamlineTractographyPerspective"
icon="resources/tractography.png">
<keywordReference id="org.mitk.perspectives.tractography2.Keyword"/>
</perspective>
<perspective id="org.mitk.perspectives.tractography3"
name="Probabilistic streamline tractography"
category="Fiber Tractography"
class="QmitkProbabilisticTractographyPerspective"
icon="resources/tractography.png">
<keywordReference id="org.mitk.perspectives.tractography3.Keyword"/>
</perspective>
<perspective id="org.mitk.perspectives.syntheticdata"
name="Synthetic Data"
class="QmitkDIAppSyntheticDataGenerationPerspective"
icon="resources/syntheticdata.png">
<keywordReference id="org.mitk.perspectives.syntheticdata.Keyword"/>
</perspective>
<perspective id="org.mitk.perspectives.ivim"
name="Intra-Voxel Incoherent Motion (IVIM)"
class="QmitkDIAppIVIMPerspective"
icon="resources/ivim.png">
<keywordReference id="org.mitk.perspectives.ivim.Keyword"/>
</perspective>
</extension>
</plugin>
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp
index cb8521e316..abf9af0b68 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp
@@ -1,559 +1,572 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
#include "QmitkFiberProcessingView.h"
#include <QmitkStdMultiWidget.h>
// Qt
#include <QMessageBox>
// MITK
#include <mitkNodePredicateProperty.h>
#include <mitkImageCast.h>
#include <mitkPointSet.h>
#include <mitkPlanarCircle.h>
#include <mitkPlanarPolygon.h>
#include <mitkPlanarRectangle.h>
#include <mitkPlanarFigureInteractor.h>
#include <mitkGlobalInteraction.h>
#include <mitkImageAccessByItk.h>
#include <mitkDataNodeObject.h>
#include <mitkDiffusionImage.h>
#include <mitkTensorImage.h>
// ITK
#include <itkResampleImageFilter.h>
#include <itkGaussianInterpolateImageFunction.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkTractsToFiberEndingsImageFilter.h>
#include <itkTractDensityImageFilter.h>
#include <itkImageRegion.h>
#include <itkTractsToRgbaImageFilter.h>
#include <itkTractsToVectorImageFilter.h>
#include <math.h>
#include <boost/lexical_cast.hpp>
const std::string QmitkFiberProcessingView::VIEW_ID = "org.mitk.views.fiberprocessing";
const std::string id_DataManager = "org.mitk.views.datamanager";
using namespace mitk;
QmitkFiberProcessingView::QmitkFiberProcessingView()
: QmitkFunctionality()
, m_Controls( 0 )
, m_MultiWidget( NULL )
, m_UpsamplingFactor(5)
{
}
// Destructor
QmitkFiberProcessingView::~QmitkFiberProcessingView()
{
}
void QmitkFiberProcessingView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkFiberProcessingViewControls;
m_Controls->setupUi( parent );
connect( m_Controls->m_ProcessFiberBundleButton, SIGNAL(clicked()), this, SLOT(ProcessSelectedBundles()) );
connect( m_Controls->m_ResampleFibersButton, SIGNAL(clicked()), this, SLOT(ResampleSelectedBundles()) );
connect(m_Controls->m_FaColorFibersButton, SIGNAL(clicked()), this, SLOT(DoImageColorCoding()));
connect( m_Controls->m_PruneFibersButton, SIGNAL(clicked()), this, SLOT(PruneBundle()) );
connect( m_Controls->m_CurvatureThresholdButton, SIGNAL(clicked()), this, SLOT(ApplyCurvatureThreshold()) );
connect( m_Controls->m_MirrorFibersButton, SIGNAL(clicked()), this, SLOT(MirrorFibers()) );
connect( m_Controls->m_CompressFibersButton, SIGNAL(clicked()), this, SLOT(CompressSelectedBundles()) );
connect( m_Controls->m_ExtractFiberPeaks, SIGNAL(clicked()), this, SLOT(CalculateFiberDirections()) );
}
}
void QmitkFiberProcessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkFiberProcessingView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkFiberProcessingView::CalculateFiberDirections()
{
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
// load fiber bundle
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.back()->GetData());
itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
- // load/create mask image
if (m_SelectedImage.IsNotNull())
{
ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
mitk::CastToItkImage<ItkUcharImgType>(m_SelectedImage, itkMaskImage);
fOdfFilter->SetMaskImage(itkMaskImage);
}
// extract directions from fiber bundle
fOdfFilter->SetFiberBundle(inputTractogram);
fOdfFilter->SetAngularThreshold(cos(m_Controls->m_AngularThreshold->value()*M_PI/180));
fOdfFilter->SetNormalizeVectors(true);
fOdfFilter->SetUseWorkingCopy(true);
+ fOdfFilter->SetCreateDirectionImages(m_Controls->m_DirectionImagesBox->isChecked());
fOdfFilter->SetSizeThreshold(m_Controls->m_PeakThreshold->value());
fOdfFilter->SetMaxNumDirections(m_Controls->m_MaxNumDirections->value());
fOdfFilter->Update();
QString name = m_SelectedFB.back()->GetName().c_str();
if (m_Controls->m_VectorFieldBox->isChecked())
{
+ float minSpacing = 1;
+ if (m_SelectedImage.IsNotNull())
+ {
+ mitk::Vector3D outImageSpacing = m_SelectedImage->GetGeometry()->GetSpacing();
+
+ if(outImageSpacing[0]<outImageSpacing[1] && outImageSpacing[0]<outImageSpacing[2])
+ minSpacing = outImageSpacing[0];
+ else if (outImageSpacing[1] < outImageSpacing[2])
+ minSpacing = outImageSpacing[1];
+ else
+ minSpacing = outImageSpacing[2];
+ }
+
mitk::FiberBundleX::Pointer directions = fOdfFilter->GetOutputFiberBundle();
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(directions);
node->SetName((name+"_vectorfield").toStdString().c_str());
-// node->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(minSpacing));
+ node->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(minSpacing));
node->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(false));
node->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 1.0f));
GetDefaultDataStorage()->Add(node, m_SelectedFB.back());
}
if (m_Controls->m_NumDirectionsBox->isChecked())
{
mitk::Image::Pointer mitkImage = mitk::Image::New();
mitkImage->InitializeByItk( fOdfFilter->GetNumDirectionsImage().GetPointer() );
mitkImage->SetVolume( fOdfFilter->GetNumDirectionsImage()->GetBufferPointer() );
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(mitkImage);
node->SetName((name+"_numdirections").toStdString().c_str());
GetDefaultDataStorage()->Add(node, m_SelectedFB.back());
}
if (m_Controls->m_DirectionImagesBox->isChecked())
{
ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();
for (unsigned int i=0; i<directionImageContainer->Size(); i++)
{
itk::TractsToVectorImageFilter<float>::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i);
if (itkImg.IsNull())
return;
mitk::Image::Pointer mitkImage = mitk::Image::New();
mitkImage->InitializeByItk( itkImg.GetPointer() );
mitkImage->SetVolume( itkImg->GetBufferPointer() );
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(mitkImage);
node->SetName( (name+"_direction_"+boost::lexical_cast<std::string>(i).c_str()).toStdString().c_str());
node->SetVisibility(false);
GetDefaultDataStorage()->Add(node, m_SelectedFB.back());
}
}
}
void QmitkFiberProcessingView::UpdateGui()
{
m_Controls->m_CompressFibersButton->setEnabled(!m_SelectedFB.empty());
m_Controls->m_ProcessFiberBundleButton->setEnabled(!m_SelectedFB.empty());
m_Controls->m_ResampleFibersButton->setEnabled(!m_SelectedFB.empty());
m_Controls->m_FaColorFibersButton->setEnabled(!m_SelectedFB.empty());
m_Controls->m_PruneFibersButton->setEnabled(!m_SelectedFB.empty());
m_Controls->m_CurvatureThresholdButton->setEnabled(!m_SelectedFB.empty());
m_Controls->m_ExtractFiberPeaks->setEnabled(!m_SelectedFB.empty());
// are fiber bundles selected?
if ( m_SelectedFB.empty() )
{
if (m_SelectedSurfaces.size()>0)
m_Controls->m_MirrorFibersButton->setEnabled(true);
else
m_Controls->m_MirrorFibersButton->setEnabled(false);
}
else
{
if (m_SelectedImage.IsNotNull())
m_Controls->m_FaColorFibersButton->setEnabled(true);
}
}
void QmitkFiberProcessingView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
//reset existing Vectors containing FiberBundles and PlanarFigures from a previous selection
m_SelectedFB.clear();
m_SelectedSurfaces.clear();
m_SelectedImage = NULL;
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if ( dynamic_cast<mitk::FiberBundleX*>(node->GetData()) )
{
m_SelectedFB.push_back(node);
}
else if (dynamic_cast<mitk::Image*>(node->GetData()))
m_SelectedImage = dynamic_cast<mitk::Image*>(node->GetData());
else if (dynamic_cast<mitk::Surface*>(node->GetData()))
{
m_SelectedSurfaces.push_back(dynamic_cast<mitk::Surface*>(node->GetData()));
}
}
UpdateGui();
GenerateStats();
}
void QmitkFiberProcessingView::Activated()
{
}
void QmitkFiberProcessingView::PruneBundle()
{
int minLength = this->m_Controls->m_PruneFibersSpinBox->value();
int maxLength = this->m_Controls->m_MaxPruneFibersSpinBox->value();
for (int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
if (!fib->RemoveShortFibers(minLength))
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
else if (!fib->RemoveLongFibers(maxLength))
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
}
GenerateStats();
RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberProcessingView::ApplyCurvatureThreshold()
{
int mm = this->m_Controls->m_MinCurvatureRadiusBox->value();
for (int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
if (!fib->ApplyCurvatureThreshold(mm, this->m_Controls->m_RemoveFiberDueToCurvatureCheckbox->isChecked()))
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
}
GenerateStats();
RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberProcessingView::GenerateStats()
{
if ( m_SelectedFB.empty() )
return;
QString stats("");
for( int i=0; i<m_SelectedFB.size(); i++ )
{
mitk::DataNode::Pointer node = m_SelectedFB[i];
if (node.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(node->GetData()))
{
if (i>0)
stats += "\n-----------------------------\n";
stats += QString(node->GetName().c_str()) + "\n";
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(node->GetData());
stats += "Number of fibers: "+ QString::number(fib->GetNumFibers()) + "\n";
stats += "Number of points: "+ QString::number(fib->GetNumberOfPoints()) + "\n";
stats += "Min. length: "+ QString::number(fib->GetMinFiberLength(),'f',1) + " mm\n";
stats += "Max. length: "+ QString::number(fib->GetMaxFiberLength(),'f',1) + " mm\n";
stats += "Mean length: "+ QString::number(fib->GetMeanFiberLength(),'f',1) + " mm\n";
stats += "Median length: "+ QString::number(fib->GetMedianFiberLength(),'f',1) + " mm\n";
stats += "Standard deviation: "+ QString::number(fib->GetLengthStDev(),'f',1) + " mm\n";
}
}
this->m_Controls->m_StatsTextEdit->setText(stats);
}
void QmitkFiberProcessingView::ProcessSelectedBundles()
{
if ( m_SelectedFB.empty() ){
QMessageBox::information( NULL, "Warning", "No fibe bundle selected!");
MITK_WARN("QmitkFiberProcessingView") << "no fibe bundle selected";
return;
}
int generationMethod = m_Controls->m_GenerationBox->currentIndex();
for( int i=0; i<m_SelectedFB.size(); i++ )
{
mitk::DataNode::Pointer node = m_SelectedFB[i];
if (node.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(node->GetData()))
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(node->GetData());
QString name(node->GetName().c_str());
DataNode::Pointer newNode = NULL;
switch(generationMethod){
case 0:
newNode = GenerateTractDensityImage(fib, false, true);
name += "_TDI";
break;
case 1:
newNode = GenerateTractDensityImage(fib, false, false);
name += "_TDI";
break;
case 2:
newNode = GenerateTractDensityImage(fib, true, false);
name += "_envelope";
break;
case 3:
newNode = GenerateColorHeatmap(fib);
break;
case 4:
newNode = GenerateFiberEndingsImage(fib);
name += "_fiber_endings";
break;
case 5:
newNode = GenerateFiberEndingsPointSet(fib);
name += "_fiber_endings";
break;
}
if (newNode.IsNotNull())
{
newNode->SetName(name.toStdString());
GetDataStorage()->Add(newNode);
}
}
}
}
// generate pointset displaying the fiber endings
mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateFiberEndingsPointSet(mitk::FiberBundleX::Pointer fib)
{
mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
vtkSmartPointer<vtkPolyData> fiberPolyData = fib->GetFiberPolyData();
vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
vLines->InitTraversal();
int count = 0;
int numFibers = fib->GetNumFibers();
for( int i=0; i<numFibers; i++ )
{
vtkIdType numPoints(0);
vtkIdType* points(NULL);
vLines->GetNextCell ( numPoints, points );
if (numPoints>0)
{
double* point = fiberPolyData->GetPoint(points[0]);
itk::Point<float,3> itkPoint;
itkPoint[0] = point[0];
itkPoint[1] = point[1];
itkPoint[2] = point[2];
pointSet->InsertPoint(count, itkPoint);
count++;
}
if (numPoints>2)
{
double* point = fiberPolyData->GetPoint(points[numPoints-1]);
itk::Point<float,3> itkPoint;
itkPoint[0] = point[0];
itkPoint[1] = point[1];
itkPoint[2] = point[2];
pointSet->InsertPoint(count, itkPoint);
count++;
}
}
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( pointSet );
return node;
}
// generate image displaying the fiber endings
mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateFiberEndingsImage(mitk::FiberBundleX::Pointer fib)
{
typedef unsigned char OutPixType;
typedef itk::Image<OutPixType,3> OutImageType;
typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType;
ImageGeneratorType::Pointer generator = ImageGeneratorType::New();
generator->SetFiberBundle(fib);
generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
if (m_SelectedImage.IsNotNull())
{
OutImageType::Pointer itkImage = OutImageType::New();
CastToItkImage(m_SelectedImage, itkImage);
generator->SetInputImage(itkImage);
generator->SetUseImageGeometry(true);
}
generator->Update();
// get output image
OutImageType::Pointer outImg = generator->GetOutput();
mitk::Image::Pointer img = mitk::Image::New();
img->InitializeByItk(outImg.GetPointer());
img->SetVolume(outImg->GetBufferPointer());
// init data node
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(img);
return node;
}
// generate rgba heatmap from fiber bundle
mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateColorHeatmap(mitk::FiberBundleX::Pointer fib)
{
typedef itk::RGBAPixel<unsigned char> OutPixType;
typedef itk::Image<OutPixType, 3> OutImageType;
typedef itk::TractsToRgbaImageFilter< OutImageType > ImageGeneratorType;
ImageGeneratorType::Pointer generator = ImageGeneratorType::New();
generator->SetFiberBundle(fib);
generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
if (m_SelectedImage.IsNotNull())
{
itk::Image<unsigned char, 3>::Pointer itkImage = itk::Image<unsigned char, 3>::New();
CastToItkImage(m_SelectedImage, itkImage);
generator->SetInputImage(itkImage);
generator->SetUseImageGeometry(true);
}
generator->Update();
// get output image
typedef itk::Image<OutPixType,3> OutType;
OutType::Pointer outImg = generator->GetOutput();
mitk::Image::Pointer img = mitk::Image::New();
img->InitializeByItk(outImg.GetPointer());
img->SetVolume(outImg->GetBufferPointer());
// init data node
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(img);
return node;
}
// generate tract density image from fiber bundle
mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateTractDensityImage(mitk::FiberBundleX::Pointer fib, bool binary, bool absolute)
{
typedef float OutPixType;
typedef itk::Image<OutPixType, 3> OutImageType;
itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New();
generator->SetFiberBundle(fib);
generator->SetBinaryOutput(binary);
generator->SetOutputAbsoluteValues(absolute);
generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
if (m_SelectedImage.IsNotNull())
{
OutImageType::Pointer itkImage = OutImageType::New();
CastToItkImage(m_SelectedImage, itkImage);
generator->SetInputImage(itkImage);
generator->SetUseImageGeometry(true);
}
generator->Update();
// get output image
typedef itk::Image<OutPixType,3> OutType;
OutType::Pointer outImg = generator->GetOutput();
mitk::Image::Pointer img = mitk::Image::New();
img->InitializeByItk(outImg.GetPointer());
img->SetVolume(outImg->GetBufferPointer());
// init data node
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(img);
return node;
}
void QmitkFiberProcessingView::ResampleSelectedBundles()
{
double factor = this->m_Controls->m_ResampleFibersSpinBox->value();
for (int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
fib->DoFiberSmoothing(factor);
}
GenerateStats();
RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberProcessingView::CompressSelectedBundles()
{
double factor = this->m_Controls->m_FiberErrorSpinBox->value();
for (int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
fib->CompressFibers(factor);
}
GenerateStats();
RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberProcessingView::MirrorFibers()
{
unsigned int axis = this->m_Controls->m_AxisSelectionBox->currentIndex();
for (int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
fib->MirrorFibers(axis);
}
if (m_SelectedFB.size()>0)
GenerateStats();
if (m_SelectedSurfaces.size()>0)
{
for (int i=0; i<m_SelectedSurfaces.size(); i++)
{
mitk::Surface::Pointer surf = m_SelectedSurfaces.at(i);
vtkSmartPointer<vtkPolyData> poly = surf->GetVtkPolyData();
vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
for (int i=0; i<poly->GetNumberOfPoints(); i++)
{
double* point = poly->GetPoint(i);
point[axis] *= -1;
vtkNewPoints->InsertNextPoint(point);
}
poly->SetPoints(vtkNewPoints);
surf->CalculateBoundingBox();
}
}
RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberProcessingView::DoImageColorCoding()
{
if (m_SelectedImage.IsNull())
return;
for( int i=0; i<m_SelectedFB.size(); i++ )
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
fib->SetFAMap(m_SelectedImage);
fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_FA_BASED);
fib->DoColorCodingFaBased();
}
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp
index 2c85f47582..d9100132e7 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp
@@ -1,2579 +1,2623 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//misc
#define _USE_MATH_DEFINES
#include <math.h>
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
#include "QmitkFiberfoxView.h"
// MITK
#include <mitkImage.h>
#include <mitkDiffusionImage.h>
#include <mitkImageToItk.h>
#include <mitkImageCast.h>
#include <mitkProperties.h>
#include <mitkPlanarFigureInteractor.h>
#include <mitkDataStorage.h>
#include <itkFibersFromPlanarFiguresFilter.h>
#include <itkTractsToDWIImageFilter.h>
#include <mitkTensorImage.h>
#include <mitkILinkedRenderWindowPart.h>
#include <mitkGlobalInteraction.h>
#include <mitkImageToItk.h>
#include <mitkImageCast.h>
#include <mitkImageGenerator.h>
#include <mitkNodePredicateDataType.h>
#include <itkScalableAffineTransform.h>
#include <mitkLevelWindowProperty.h>
#include <mitkNodePredicateOr.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateNot.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <QFileDialog>
#include <QMessageBox>
#include "usModuleRegistry.h"
#include <mitkChiSquareNoiseModel.h>
#include <itksys/SystemTools.hxx>
#include <mitkIOUtil.h>
#include <QScrollBar>
#include <itkInvertIntensityImageFilter.h>
#include <QDialogButtonBox>
#include <itkAdcImageFilter.h>
#include <itkShiftScaleImageFilter.h>
#define _USE_MATH_DEFINES
#include <math.h>
QmitkFiberfoxWorker::QmitkFiberfoxWorker(QmitkFiberfoxView* view)
: m_View(view)
{
}
void QmitkFiberfoxWorker::run()
{
try{
switch (m_FilterType)
{
case 0:
m_View->m_TractsToDwiFilter->Update();
break;
case 1:
m_View->m_ArtifactsToDwiFilter->Update();
break;
}
}
catch( ... )
{
}
m_View->m_Thread.quit();
}
const std::string QmitkFiberfoxView::VIEW_ID = "org.mitk.views.fiberfoxview";
QmitkFiberfoxView::QmitkFiberfoxView()
: QmitkAbstractView()
, m_Controls( 0 )
, m_SelectedImage( NULL )
, m_Worker(this)
, m_ThreadIsRunning(false)
{
m_Worker.moveToThread(&m_Thread);
connect(&m_Thread, SIGNAL(started()), this, SLOT(BeforeThread()));
connect(&m_Thread, SIGNAL(started()), &m_Worker, SLOT(run()));
connect(&m_Thread, SIGNAL(finished()), this, SLOT(AfterThread()));
connect(&m_Thread, SIGNAL(terminated()), this, SLOT(AfterThread()));
m_SimulationTimer = new QTimer(this);
}
void QmitkFiberfoxView::KillThread()
{
MITK_INFO << "Aborting DWI simulation.";
switch (m_Worker.m_FilterType)
{
case 0:
m_TractsToDwiFilter->SetAbortGenerateData(true);
break;
case 1:
m_ArtifactsToDwiFilter->SetAbortGenerateData(true);
break;
}
m_Controls->m_AbortSimulationButton->setEnabled(false);
m_Controls->m_AbortSimulationButton->setText("Aborting simulation ...");
}
void QmitkFiberfoxView::BeforeThread()
{
m_SimulationTime = QTime::currentTime();
m_SimulationTimer->start(100);
m_Controls->m_AbortSimulationButton->setVisible(true);
m_Controls->m_GenerateImageButton->setVisible(false);
m_Controls->m_SimulationStatusText->setVisible(true);
m_ThreadIsRunning = true;
}
void QmitkFiberfoxView::AfterThread()
{
UpdateSimulationStatus();
m_SimulationTimer->stop();
m_Controls->m_AbortSimulationButton->setVisible(false);
m_Controls->m_AbortSimulationButton->setEnabled(true);
m_Controls->m_AbortSimulationButton->setText("Abort simulation");
m_Controls->m_GenerateImageButton->setVisible(true);
m_ThreadIsRunning = false;
QString statusText;
FiberfoxParameters<double> parameters;
mitk::DiffusionImage<short>::Pointer mitkImage = mitk::DiffusionImage<short>::New();
switch (m_Worker.m_FilterType)
{
case 0:
{
statusText = QString(m_TractsToDwiFilter->GetStatusText().c_str());
if (m_TractsToDwiFilter->GetAbortGenerateData())
{
MITK_INFO << "Simulation aborted.";
return;
}
parameters = m_TractsToDwiFilter->GetParameters();
mitkImage->SetVectorImage( m_TractsToDwiFilter->GetOutput() );
- mitkImage->SetReferenceBValue(parameters.m_Bvalue);
- mitkImage->SetDirections(parameters.GetGradientDirections());
+ mitkImage->SetReferenceBValue(parameters.m_SignalGen.m_Bvalue);
+ mitkImage->SetDirections(parameters.m_SignalGen.GetGradientDirections());
mitkImage->InitializeFromVectorImage();
- parameters.m_ResultNode->SetData( mitkImage );
+ parameters.m_Misc.m_ResultNode->SetData( mitkImage );
- parameters.m_ResultNode->SetName(parameters.m_ParentNode->GetName()
- +"_D"+QString::number(parameters.m_ImageRegion.GetSize(0)).toStdString()
- +"-"+QString::number(parameters.m_ImageRegion.GetSize(1)).toStdString()
- +"-"+QString::number(parameters.m_ImageRegion.GetSize(2)).toStdString()
- +"_S"+QString::number(parameters.m_ImageSpacing[0]).toStdString()
- +"-"+QString::number(parameters.m_ImageSpacing[1]).toStdString()
- +"-"+QString::number(parameters.m_ImageSpacing[2]).toStdString()
- +"_b"+QString::number(parameters.m_Bvalue).toStdString()
- +"_"+parameters.m_SignalModelString
- +parameters.m_ArtifactModelString);
+ parameters.m_Misc.m_ResultNode->SetName(parameters.m_Misc.m_ParentNode->GetName()
+ +"_D"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(0)).toStdString()
+ +"-"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(1)).toStdString()
+ +"-"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(2)).toStdString()
+ +"_S"+QString::number(parameters.m_SignalGen.m_ImageSpacing[0]).toStdString()
+ +"-"+QString::number(parameters.m_SignalGen.m_ImageSpacing[1]).toStdString()
+ +"-"+QString::number(parameters.m_SignalGen.m_ImageSpacing[2]).toStdString()
+ +"_b"+QString::number(parameters.m_SignalGen.m_Bvalue).toStdString()
+ +"_"+parameters.m_Misc.m_SignalModelString
+ +parameters.m_Misc.m_ArtifactModelString);
- GetDataStorage()->Add(parameters.m_ResultNode, parameters.m_ParentNode);
+ GetDataStorage()->Add(parameters.m_Misc.m_ResultNode, parameters.m_Misc.m_ParentNode);
- parameters.m_ResultNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New(m_TractsToDwiFilter->GetLevelWindow()) );
+ parameters.m_Misc.m_ResultNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New(m_TractsToDwiFilter->GetLevelWindow()) );
if (m_Controls->m_VolumeFractionsBox->isChecked())
{
std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = m_TractsToDwiFilter->GetVolumeFractions();
for (unsigned int k=0; k<volumeFractions.size(); k++)
{
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk(volumeFractions.at(k).GetPointer());
image->SetVolume(volumeFractions.at(k)->GetBufferPointer());
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( image );
- node->SetName(parameters.m_ParentNode->GetName()+"_CompartmentVolume-"+QString::number(k).toStdString());
- GetDataStorage()->Add(node, parameters.m_ParentNode);
+ node->SetName(parameters.m_Misc.m_ParentNode->GetName()+"_CompartmentVolume-"+QString::number(k).toStdString());
+ GetDataStorage()->Add(node, parameters.m_Misc.m_ParentNode);
}
}
m_TractsToDwiFilter = NULL;
break;
}
case 1:
{
statusText = QString(m_ArtifactsToDwiFilter->GetStatusText().c_str());
if (m_ArtifactsToDwiFilter->GetAbortGenerateData())
{
MITK_INFO << "Simulation aborted.";
return;
}
parameters = m_ArtifactsToDwiFilter->GetParameters().CopyParameters<double>();
- mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(parameters.m_ParentNode->GetData());
+ mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(parameters.m_Misc.m_ParentNode->GetData());
mitkImage = mitk::DiffusionImage<short>::New();
mitkImage->SetVectorImage( m_ArtifactsToDwiFilter->GetOutput() );
mitkImage->SetReferenceBValue(diffImg->GetReferenceBValue());
mitkImage->SetDirections(diffImg->GetDirections());
mitkImage->InitializeFromVectorImage();
- parameters.m_ResultNode->SetData( mitkImage );
- parameters.m_ResultNode->SetName(parameters.m_ParentNode->GetName()+parameters.m_ArtifactModelString);
- GetDataStorage()->Add(parameters.m_ResultNode, parameters.m_ParentNode);
+ parameters.m_Misc.m_ResultNode->SetData( mitkImage );
+ parameters.m_Misc.m_ResultNode->SetName(parameters.m_Misc.m_ParentNode->GetName()+parameters.m_Misc.m_ArtifactModelString);
+ GetDataStorage()->Add(parameters.m_Misc.m_ResultNode, parameters.m_Misc.m_ParentNode);
m_ArtifactsToDwiFilter = NULL;
break;
}
}
- mitk::BaseData::Pointer basedata = parameters.m_ResultNode->GetData();
+ mitk::BaseData::Pointer basedata = parameters.m_Misc.m_ResultNode->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
- if (!parameters.m_OutputPath.empty())
+ if (!parameters.m_Misc.m_OutputPath.empty())
{
try{
- QString outputFileName(parameters.m_OutputPath.c_str());
- outputFileName += parameters.m_ResultNode->GetName().c_str();
+ QString outputFileName(parameters.m_Misc.m_OutputPath.c_str());
+ outputFileName += parameters.m_Misc.m_ResultNode->GetName().c_str();
outputFileName.replace(QString("."), QString("_"));
outputFileName += ".dwi";
QString status("Saving output image to ");
status += outputFileName;
m_Controls->m_SimulationStatusText->append(status);
mitk::IOUtil::SaveBaseData(mitkImage, outputFileName.toStdString());
m_Controls->m_SimulationStatusText->append("File saved successfully.");
}
catch (itk::ExceptionObject &e)
{
QString status("Exception during DWI writing: ");
status += e.GetDescription();
m_Controls->m_SimulationStatusText->append(status);
}
catch (...)
{
m_Controls->m_SimulationStatusText->append("Unknown exception during DWI writing!");
}
}
- parameters.m_FrequencyMap = NULL;
+ parameters.m_SignalGen.m_FrequencyMap = NULL;
}
void QmitkFiberfoxView::UpdateSimulationStatus()
{
QString statusText;
switch (m_Worker.m_FilterType)
{
case 0:
statusText = QString(m_TractsToDwiFilter->GetStatusText().c_str());
break;
case 1:
statusText = QString(m_ArtifactsToDwiFilter->GetStatusText().c_str());
break;
}
if (QString::compare(m_SimulationStatusText,statusText)!=0)
{
m_Controls->m_SimulationStatusText->clear();
statusText = "<pre>"+statusText+"</pre>";
m_Controls->m_SimulationStatusText->setText(statusText);
QScrollBar *vScrollBar = m_Controls->m_SimulationStatusText->verticalScrollBar();
vScrollBar->triggerAction(QScrollBar::SliderToMaximum);
}
}
// Destructor
QmitkFiberfoxView::~QmitkFiberfoxView()
{
delete m_SimulationTimer;
}
void QmitkFiberfoxView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkFiberfoxViewControls;
m_Controls->setupUi( parent );
m_Controls->m_StickWidget1->setVisible(true);
m_Controls->m_StickWidget2->setVisible(false);
m_Controls->m_ZeppelinWidget1->setVisible(false);
m_Controls->m_ZeppelinWidget2->setVisible(false);
m_Controls->m_TensorWidget1->setVisible(false);
m_Controls->m_TensorWidget2->setVisible(false);
m_Controls->m_BallWidget1->setVisible(true);
m_Controls->m_BallWidget2->setVisible(false);
m_Controls->m_AstrosticksWidget1->setVisible(false);
m_Controls->m_AstrosticksWidget2->setVisible(false);
m_Controls->m_DotWidget1->setVisible(false);
m_Controls->m_DotWidget2->setVisible(false);
m_Controls->m_PrototypeWidget1->setVisible(false);
m_Controls->m_PrototypeWidget2->setVisible(false);
m_Controls->m_PrototypeWidget3->setVisible(false);
m_Controls->m_PrototypeWidget4->setVisible(false);
m_Controls->m_PrototypeWidget3->SetMinFa(0.0);
m_Controls->m_PrototypeWidget3->SetMaxFa(0.15);
m_Controls->m_PrototypeWidget4->SetMinFa(0.0);
m_Controls->m_PrototypeWidget4->SetMaxFa(0.15);
m_Controls->m_PrototypeWidget3->SetMinAdc(0.0);
m_Controls->m_PrototypeWidget3->SetMaxAdc(0.001);
m_Controls->m_PrototypeWidget4->SetMinAdc(0.003);
m_Controls->m_PrototypeWidget4->SetMaxAdc(0.004);
m_Controls->m_Comp4FractionFrame->setVisible(false);
m_Controls->m_DiffusionPropsMessage->setVisible(false);
m_Controls->m_GeometryMessage->setVisible(false);
m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false);
m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false);
m_Controls->m_VarianceBox->setVisible(false);
m_Controls->m_NoiseFrame->setVisible(false);
m_Controls->m_GhostFrame->setVisible(false);
m_Controls->m_DistortionsFrame->setVisible(false);
m_Controls->m_EddyFrame->setVisible(false);
m_Controls->m_SpikeFrame->setVisible(false);
m_Controls->m_AliasingFrame->setVisible(false);
m_Controls->m_MotionArtifactFrame->setVisible(false);
m_ParameterFile = QDir::currentPath()+"/param.ffp";
m_Controls->m_AbortSimulationButton->setVisible(false);
m_Controls->m_SimulationStatusText->setVisible(false);
m_Controls->m_FrequencyMapBox->SetDataStorage(this->GetDataStorage());
mitk::TNodePredicateDataType<mitk::Image>::Pointer isMitkImage = mitk::TNodePredicateDataType<mitk::Image>::New();
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti);
isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi);
mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage);
mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage);
m_Controls->m_FrequencyMapBox->SetPredicate(finalPredicate);
m_Controls->m_Comp4VolumeFraction->SetDataStorage(this->GetDataStorage());
m_Controls->m_Comp4VolumeFraction->SetPredicate(finalPredicate);
connect( m_SimulationTimer, SIGNAL(timeout()), this, SLOT(UpdateSimulationStatus()) );
connect((QObject*) m_Controls->m_AbortSimulationButton, SIGNAL(clicked()), (QObject*) this, SLOT(KillThread()));
connect((QObject*) m_Controls->m_GenerateImageButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateImage()));
connect((QObject*) m_Controls->m_GenerateFibersButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateFibers()));
connect((QObject*) m_Controls->m_CircleButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnDrawROI()));
connect((QObject*) m_Controls->m_FlipButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnFlipButton()));
connect((QObject*) m_Controls->m_JoinBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(JoinBundles()));
connect((QObject*) m_Controls->m_VarianceBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnVarianceChanged(double)));
connect((QObject*) m_Controls->m_DistributionBox, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(OnDistributionChanged(int)));
connect((QObject*) m_Controls->m_FiberDensityBox, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(OnFiberDensityChanged(int)));
connect((QObject*) m_Controls->m_FiberSamplingBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnFiberSamplingChanged(double)));
connect((QObject*) m_Controls->m_TensionBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnTensionChanged(double)));
connect((QObject*) m_Controls->m_ContinuityBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnContinuityChanged(double)));
connect((QObject*) m_Controls->m_BiasBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnBiasChanged(double)));
connect((QObject*) m_Controls->m_AddNoise, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddNoise(int)));
connect((QObject*) m_Controls->m_AddGhosts, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddGhosts(int)));
connect((QObject*) m_Controls->m_AddDistortions, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddDistortions(int)));
connect((QObject*) m_Controls->m_AddEddy, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddEddy(int)));
connect((QObject*) m_Controls->m_AddSpikes, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddSpikes(int)));
connect((QObject*) m_Controls->m_AddAliasing, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddAliasing(int)));
connect((QObject*) m_Controls->m_AddMotion, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddMotion(int)));
connect((QObject*) m_Controls->m_ConstantRadiusBox, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnConstantRadius(int)));
connect((QObject*) m_Controls->m_CopyBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(CopyBundles()));
connect((QObject*) m_Controls->m_TransformBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(ApplyTransform()));
connect((QObject*) m_Controls->m_AlignOnGrid, SIGNAL(clicked()), (QObject*) this, SLOT(AlignOnGrid()));
connect((QObject*) m_Controls->m_Compartment1Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp1ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_Compartment2Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp2ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_Compartment3Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp3ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_Compartment4Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp4ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_AdvancedOptionsBox, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int)));
connect((QObject*) m_Controls->m_AdvancedOptionsBox_2, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int)));
connect((QObject*) m_Controls->m_SaveParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(SaveParameters()));
connect((QObject*) m_Controls->m_LoadParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(LoadParameters()));
connect((QObject*) m_Controls->m_OutputPathButton, SIGNAL(clicked()), (QObject*) this, SLOT(SetOutputPath()));
}
}
template< class ScalarType >
FiberfoxParameters< ScalarType > QmitkFiberfoxView::UpdateImageParameters()
{
FiberfoxParameters< ScalarType > parameters;
- parameters.m_OutputPath = "";
+ parameters.m_Misc.m_OutputPath = "";
+ parameters.m_Misc.m_CheckAdvancedFiberOptionsBox = m_Controls->m_AdvancedOptionsBox->isChecked();
+ parameters.m_Misc.m_CheckAdvancedSignalOptionsBox = m_Controls->m_AdvancedOptionsBox_2->isChecked();
string outputPath = m_Controls->m_SavePathEdit->text().toStdString();
if (outputPath.compare("-")!=0)
{
- parameters.m_OutputPath = outputPath;
- parameters.m_OutputPath += "/";
+ parameters.m_Misc.m_OutputPath = outputPath;
+ parameters.m_Misc.m_OutputPath += "/";
}
if (m_MaskImageNode.IsNotNull())
{
mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
- mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, parameters.m_MaskImage);
+ mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, parameters.m_SignalGen.m_MaskImage);
itk::ImageDuplicator<ItkUcharImgType>::Pointer duplicator = itk::ImageDuplicator<ItkUcharImgType>::New();
- duplicator->SetInputImage(parameters.m_MaskImage);
+ duplicator->SetInputImage(parameters.m_SignalGen.m_MaskImage);
duplicator->Update();
- parameters.m_MaskImage = duplicator->GetOutput();
+ parameters.m_SignalGen.m_MaskImage = duplicator->GetOutput();
}
if (m_SelectedDWI.IsNotNull()) // use parameters of selected DWI
{
mitk::DiffusionImage<short>::Pointer dwi = dynamic_cast<mitk::DiffusionImage<short>*>(m_SelectedDWI->GetData());
- parameters.m_ImageRegion = dwi->GetVectorImage()->GetLargestPossibleRegion();
- parameters.m_ImageSpacing = dwi->GetVectorImage()->GetSpacing();
- parameters.m_ImageOrigin = dwi->GetVectorImage()->GetOrigin();
- parameters.m_ImageDirection = dwi->GetVectorImage()->GetDirection();
- parameters.m_Bvalue = dwi->GetReferenceBValue();
- parameters.SetGradienDirections(dwi->GetDirections());
+ parameters.m_SignalGen.m_ImageRegion = dwi->GetVectorImage()->GetLargestPossibleRegion();
+ parameters.m_SignalGen.m_ImageSpacing = dwi->GetVectorImage()->GetSpacing();
+ parameters.m_SignalGen.m_ImageOrigin = dwi->GetVectorImage()->GetOrigin();
+ parameters.m_SignalGen.m_ImageDirection = dwi->GetVectorImage()->GetDirection();
+ parameters.m_SignalGen.m_Bvalue = dwi->GetReferenceBValue();
+ parameters.m_SignalGen.SetGradienDirections(dwi->GetDirections());
}
else if (m_SelectedImage.IsNotNull()) // use geometry of selected image
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(m_SelectedImage->GetData());
itk::Image< float, 3 >::Pointer itkImg = itk::Image< float, 3 >::New();
CastToItkImage< itk::Image< float, 3 > >(img, itkImg);
- parameters.m_ImageRegion = itkImg->GetLargestPossibleRegion();
- parameters.m_ImageSpacing = itkImg->GetSpacing();
- parameters.m_ImageOrigin = itkImg->GetOrigin();
- parameters.m_ImageDirection = itkImg->GetDirection();
- parameters.SetNumWeightedGradients(m_Controls->m_NumGradientsBox->value());
- parameters.m_Bvalue = m_Controls->m_BvalueBox->value();
+ parameters.m_SignalGen.m_ImageRegion = itkImg->GetLargestPossibleRegion();
+ parameters.m_SignalGen.m_ImageSpacing = itkImg->GetSpacing();
+ parameters.m_SignalGen.m_ImageOrigin = itkImg->GetOrigin();
+ parameters.m_SignalGen.m_ImageDirection = itkImg->GetDirection();
+ parameters.m_SignalGen.SetNumWeightedVolumes(m_Controls->m_NumGradientsBox->value());
+ parameters.m_SignalGen.m_Bvalue = m_Controls->m_BvalueBox->value();
}
else // use GUI parameters
{
- parameters.m_ImageRegion.SetSize(0, m_Controls->m_SizeX->value());
- parameters.m_ImageRegion.SetSize(1, m_Controls->m_SizeY->value());
- parameters.m_ImageRegion.SetSize(2, m_Controls->m_SizeZ->value());
- parameters.m_ImageSpacing[0] = m_Controls->m_SpacingX->value();
- parameters.m_ImageSpacing[1] = m_Controls->m_SpacingY->value();
- parameters.m_ImageSpacing[2] = m_Controls->m_SpacingZ->value();
- parameters.m_ImageOrigin[0] = parameters.m_ImageSpacing[0]/2;
- parameters.m_ImageOrigin[1] = parameters.m_ImageSpacing[1]/2;
- parameters.m_ImageOrigin[2] = parameters.m_ImageSpacing[2]/2;
- parameters.m_ImageDirection.SetIdentity();
- parameters.SetNumWeightedGradients(m_Controls->m_NumGradientsBox->value());
- parameters.m_Bvalue = m_Controls->m_BvalueBox->value();
- parameters.GenerateGradientHalfShell();
+ parameters.m_SignalGen.m_ImageRegion.SetSize(0, m_Controls->m_SizeX->value());
+ parameters.m_SignalGen.m_ImageRegion.SetSize(1, m_Controls->m_SizeY->value());
+ parameters.m_SignalGen.m_ImageRegion.SetSize(2, m_Controls->m_SizeZ->value());
+ parameters.m_SignalGen.m_ImageSpacing[0] = m_Controls->m_SpacingX->value();
+ parameters.m_SignalGen.m_ImageSpacing[1] = m_Controls->m_SpacingY->value();
+ parameters.m_SignalGen.m_ImageSpacing[2] = m_Controls->m_SpacingZ->value();
+ parameters.m_SignalGen.m_ImageOrigin[0] = parameters.m_SignalGen.m_ImageSpacing[0]/2;
+ parameters.m_SignalGen.m_ImageOrigin[1] = parameters.m_SignalGen.m_ImageSpacing[1]/2;
+ parameters.m_SignalGen.m_ImageOrigin[2] = parameters.m_SignalGen.m_ImageSpacing[2]/2;
+ parameters.m_SignalGen.m_ImageDirection.SetIdentity();
+ parameters.m_SignalGen.SetNumWeightedVolumes(m_Controls->m_NumGradientsBox->value());
+ parameters.m_SignalGen.m_Bvalue = m_Controls->m_BvalueBox->value();
+ parameters.m_SignalGen.GenerateGradientHalfShell();
}
// signal relaxation
- parameters.m_DoSimulateRelaxation = m_Controls->m_RelaxationBox->isChecked();
- parameters.m_SimulateKspaceAcquisition = parameters.m_DoSimulateRelaxation;
- if (parameters.m_DoSimulateRelaxation && m_SelectedBundles.size()>0 )
- parameters.m_ArtifactModelString += "_RELAX";
+ parameters.m_SignalGen.m_DoSimulateRelaxation = m_Controls->m_RelaxationBox->isChecked();
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = parameters.m_SignalGen.m_DoSimulateRelaxation;
+ if (parameters.m_SignalGen.m_DoSimulateRelaxation && m_SelectedBundles.size()>0 )
+ parameters.m_Misc.m_ArtifactModelString += "_RELAX";
// N/2 ghosts
+ parameters.m_Misc.m_CheckAddGhostsBox = m_Controls->m_AddGhosts->isChecked();
if (m_Controls->m_AddGhosts->isChecked())
{
- parameters.m_SimulateKspaceAcquisition = true;
- parameters.m_ArtifactModelString += "_GHOST";
- parameters.m_KspaceLineOffset = m_Controls->m_kOffsetBox->value();
- parameters.m_ResultNode->AddProperty("Fiberfox.Ghost", DoubleProperty::New(parameters.m_KspaceLineOffset));
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
+ parameters.m_Misc.m_ArtifactModelString += "_GHOST";
+ parameters.m_SignalGen.m_KspaceLineOffset = m_Controls->m_kOffsetBox->value();
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Ghost", DoubleProperty::New(parameters.m_SignalGen.m_KspaceLineOffset));
}
else
- parameters.m_KspaceLineOffset = 0;
+ parameters.m_SignalGen.m_KspaceLineOffset = 0;
// Aliasing
+ parameters.m_Misc.m_CheckAddAliasingBox = m_Controls->m_AddAliasing->isChecked();
if (m_Controls->m_AddAliasing->isChecked())
{
- parameters.m_SimulateKspaceAcquisition = true;
- parameters.m_ArtifactModelString += "_ALIASING";
- parameters.m_CroppingFactor = (100-m_Controls->m_WrapBox->value())/100;
- parameters.m_ResultNode->AddProperty("Fiberfox.Aliasing", DoubleProperty::New(m_Controls->m_WrapBox->value()));
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
+ parameters.m_Misc.m_ArtifactModelString += "_ALIASING";
+ parameters.m_SignalGen.m_CroppingFactor = (100-m_Controls->m_WrapBox->value())/100;
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Aliasing", DoubleProperty::New(m_Controls->m_WrapBox->value()));
}
// Spikes
+ parameters.m_Misc.m_CheckAddSpikesBox = m_Controls->m_AddSpikes->isChecked();
if (m_Controls->m_AddSpikes->isChecked())
{
- parameters.m_SimulateKspaceAcquisition = true;
- parameters.m_Spikes = m_Controls->m_SpikeNumBox->value();
- parameters.m_SpikeAmplitude = m_Controls->m_SpikeScaleBox->value();
- parameters.m_ArtifactModelString += "_SPIKES";
- parameters.m_ResultNode->AddProperty("Fiberfox.Spikes.Number", IntProperty::New(parameters.m_Spikes));
- parameters.m_ResultNode->AddProperty("Fiberfox.Spikes.Amplitude", DoubleProperty::New(parameters.m_SpikeAmplitude));
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
+ parameters.m_SignalGen.m_Spikes = m_Controls->m_SpikeNumBox->value();
+ parameters.m_SignalGen.m_SpikeAmplitude = m_Controls->m_SpikeScaleBox->value();
+ parameters.m_Misc.m_ArtifactModelString += "_SPIKES";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Spikes.Number", IntProperty::New(parameters.m_SignalGen.m_Spikes));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Spikes.Amplitude", DoubleProperty::New(parameters.m_SignalGen.m_SpikeAmplitude));
}
// gibbs ringing
- parameters.m_DoAddGibbsRinging = m_Controls->m_AddGibbsRinging->isChecked();
+ parameters.m_SignalGen.m_DoAddGibbsRinging = m_Controls->m_AddGibbsRinging->isChecked();
if (m_Controls->m_AddGibbsRinging->isChecked())
{
- parameters.m_SimulateKspaceAcquisition = true;
- parameters.m_ResultNode->AddProperty("Fiberfox.Ringing", BoolProperty::New(true));
- parameters.m_ArtifactModelString += "_RINGING";
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Ringing", BoolProperty::New(true));
+ parameters.m_Misc.m_ArtifactModelString += "_RINGING";
}
// add distortions
+ parameters.m_Misc.m_CheckAddDistortionsBox = m_Controls->m_AddDistortions->isChecked();
if (m_Controls->m_AddDistortions->isChecked() && m_Controls->m_FrequencyMapBox->GetSelectedNode().IsNotNull())
{
mitk::DataNode::Pointer fMapNode = m_Controls->m_FrequencyMapBox->GetSelectedNode();
mitk::Image* img = dynamic_cast<mitk::Image*>(fMapNode->GetData());
ItkDoubleImgType::Pointer itkImg = ItkDoubleImgType::New();
CastToItkImage< ItkDoubleImgType >(img, itkImg);
- if (parameters.m_ImageRegion.GetSize(0)==itkImg->GetLargestPossibleRegion().GetSize(0) &&
- parameters.m_ImageRegion.GetSize(1)==itkImg->GetLargestPossibleRegion().GetSize(1) &&
- parameters.m_ImageRegion.GetSize(2)==itkImg->GetLargestPossibleRegion().GetSize(2))
+ if (m_SelectedImage.IsNull()) // use geometry of frequency map
{
- parameters.m_SimulateKspaceAcquisition = true;
+ parameters.m_SignalGen.m_ImageRegion = itkImg->GetLargestPossibleRegion();
+ parameters.m_SignalGen.m_ImageSpacing = itkImg->GetSpacing();
+ parameters.m_SignalGen.m_ImageOrigin = itkImg->GetOrigin();
+ parameters.m_SignalGen.m_ImageDirection = itkImg->GetDirection();
+ }
+
+ if (parameters.m_SignalGen.m_ImageRegion.GetSize(0)==itkImg->GetLargestPossibleRegion().GetSize(0) &&
+ parameters.m_SignalGen.m_ImageRegion.GetSize(1)==itkImg->GetLargestPossibleRegion().GetSize(1) &&
+ parameters.m_SignalGen.m_ImageRegion.GetSize(2)==itkImg->GetLargestPossibleRegion().GetSize(2))
+ {
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
itk::ImageDuplicator<ItkDoubleImgType>::Pointer duplicator = itk::ImageDuplicator<ItkDoubleImgType>::New();
duplicator->SetInputImage(itkImg);
duplicator->Update();
- parameters.m_FrequencyMap = duplicator->GetOutput();
- parameters.m_ArtifactModelString += "_DISTORTED";
- parameters.m_ResultNode->AddProperty("Fiberfox.Distortions", BoolProperty::New(true));
+ parameters.m_SignalGen.m_FrequencyMap = duplicator->GetOutput();
+ parameters.m_Misc.m_ArtifactModelString += "_DISTORTED";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Distortions", BoolProperty::New(true));
}
}
- parameters.m_EddyStrength = 0;
+ parameters.m_SignalGen.m_EddyStrength = 0;
+ parameters.m_Misc.m_CheckAddEddyCurrentsBox = m_Controls->m_AddEddy->isChecked();
if (m_Controls->m_AddEddy->isChecked())
{
- parameters.m_EddyStrength = m_Controls->m_EddyGradientStrength->value();
- parameters.m_ArtifactModelString += "_EDDY";
- parameters.m_ResultNode->AddProperty("Fiberfox.Eddy-strength", DoubleProperty::New(parameters.m_EddyStrength));
+ parameters.m_SignalGen.m_EddyStrength = m_Controls->m_EddyGradientStrength->value();
+ parameters.m_Misc.m_ArtifactModelString += "_EDDY";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Eddy-strength", DoubleProperty::New(parameters.m_SignalGen.m_EddyStrength));
}
// Motion
- parameters.m_DoAddMotion = m_Controls->m_AddMotion->isChecked();
- parameters.m_DoRandomizeMotion = m_Controls->m_RandomMotion->isChecked();
- parameters.m_Translation[0] = m_Controls->m_MaxTranslationBoxX->value();
- parameters.m_Translation[1] = m_Controls->m_MaxTranslationBoxY->value();
- parameters.m_Translation[2] = m_Controls->m_MaxTranslationBoxZ->value();
- parameters.m_Rotation[0] = m_Controls->m_MaxRotationBoxX->value();
- parameters.m_Rotation[1] = m_Controls->m_MaxRotationBoxY->value();
- parameters.m_Rotation[2] = m_Controls->m_MaxRotationBoxZ->value();
+ parameters.m_SignalGen.m_DoAddMotion = m_Controls->m_AddMotion->isChecked();
+ parameters.m_SignalGen.m_DoRandomizeMotion = m_Controls->m_RandomMotion->isChecked();
+ parameters.m_SignalGen.m_Translation[0] = m_Controls->m_MaxTranslationBoxX->value();
+ parameters.m_SignalGen.m_Translation[1] = m_Controls->m_MaxTranslationBoxY->value();
+ parameters.m_SignalGen.m_Translation[2] = m_Controls->m_MaxTranslationBoxZ->value();
+ parameters.m_SignalGen.m_Rotation[0] = m_Controls->m_MaxRotationBoxX->value();
+ parameters.m_SignalGen.m_Rotation[1] = m_Controls->m_MaxRotationBoxY->value();
+ parameters.m_SignalGen.m_Rotation[2] = m_Controls->m_MaxRotationBoxZ->value();
if ( m_Controls->m_AddMotion->isChecked() && m_SelectedBundles.size()>0 )
{
- parameters.m_ArtifactModelString += "_MOTION";
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Random", BoolProperty::New(parameters.m_DoRandomizeMotion));
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-x", DoubleProperty::New(parameters.m_Translation[0]));
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-y", DoubleProperty::New(parameters.m_Translation[1]));
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-z", DoubleProperty::New(parameters.m_Translation[2]));
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-x", DoubleProperty::New(parameters.m_Rotation[0]));
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-y", DoubleProperty::New(parameters.m_Rotation[1]));
- parameters.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-z", DoubleProperty::New(parameters.m_Rotation[2]));
+ parameters.m_Misc.m_ArtifactModelString += "_MOTION";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Random", BoolProperty::New(parameters.m_SignalGen.m_DoRandomizeMotion));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-x", DoubleProperty::New(parameters.m_SignalGen.m_Translation[0]));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-y", DoubleProperty::New(parameters.m_SignalGen.m_Translation[1]));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-z", DoubleProperty::New(parameters.m_SignalGen.m_Translation[2]));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-x", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[0]));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-y", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[1]));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-z", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[2]));
}
// other imaging parameters
- parameters.m_tLine = m_Controls->m_LineReadoutTimeBox->value();
- parameters.m_tInhom = m_Controls->m_T2starBox->value();
- parameters.m_tEcho = m_Controls->m_TEbox->value();
- parameters.m_DoDisablePartialVolume = m_Controls->m_EnforcePureFiberVoxelsBox->isChecked();
- parameters.m_AxonRadius = m_Controls->m_FiberRadius->value();
- parameters.m_SignalScale = m_Controls->m_SignalScaleBox->value();
+ parameters.m_SignalGen.m_tLine = m_Controls->m_LineReadoutTimeBox->value();
+ parameters.m_SignalGen.m_tInhom = m_Controls->m_T2starBox->value();
+ parameters.m_SignalGen.m_tEcho = m_Controls->m_TEbox->value();
+ parameters.m_SignalGen.m_DoDisablePartialVolume = m_Controls->m_EnforcePureFiberVoxelsBox->isChecked();
+ parameters.m_SignalGen.m_AxonRadius = m_Controls->m_FiberRadius->value();
+ parameters.m_SignalGen.m_SignalScale = m_Controls->m_SignalScaleBox->value();
// adjust echo time if needed
- if ( parameters.m_tEcho < parameters.m_ImageRegion.GetSize(1)*parameters.m_tLine )
+ if ( parameters.m_SignalGen.m_tEcho < parameters.m_SignalGen.m_ImageRegion.GetSize(1)*parameters.m_SignalGen.m_tLine )
{
- this->m_Controls->m_TEbox->setValue( parameters.m_ImageRegion.GetSize(1)*parameters.m_tLine );
- parameters.m_tEcho = m_Controls->m_TEbox->value();
- QMessageBox::information( NULL, "Warning", "Echo time is too short! Time not sufficient to read slice. Automaticall adjusted to "+QString::number(parameters.m_tEcho)+" ms");
+ this->m_Controls->m_TEbox->setValue( parameters.m_SignalGen.m_ImageRegion.GetSize(1)*parameters.m_SignalGen.m_tLine );
+ parameters.m_SignalGen.m_tEcho = m_Controls->m_TEbox->value();
+ QMessageBox::information( NULL, "Warning", "Echo time is too short! Time not sufficient to read slice. Automaticall adjusted to "+QString::number(parameters.m_SignalGen.m_tEcho)+" ms");
}
// Noise
+ parameters.m_Misc.m_CheckAddNoiseBox = m_Controls->m_AddNoise->isChecked();
if (m_Controls->m_AddNoise->isChecked())
{
double noiseVariance = m_Controls->m_NoiseLevel->value();
{
switch (m_Controls->m_NoiseDistributionBox->currentIndex())
{
case 0:
{
parameters.m_NoiseModel = new mitk::RicianNoiseModel<ScalarType>();
- parameters.m_ArtifactModelString += "_RICIAN-";
- parameters.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician"));
+ parameters.m_Misc.m_ArtifactModelString += "_RICIAN-";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician"));
break;
}
case 1:
{
parameters.m_NoiseModel = new mitk::ChiSquareNoiseModel<ScalarType>();
- parameters.m_ArtifactModelString += "_CHISQUARED-";
- parameters.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Chi-squared"));
+ parameters.m_Misc.m_ArtifactModelString += "_CHISQUARED-";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Chi-squared"));
break;
}
default:
{
parameters.m_NoiseModel = new mitk::RicianNoiseModel<ScalarType>();
- parameters.m_ArtifactModelString += "_RICIAN-";
- parameters.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician"));
+ parameters.m_Misc.m_ArtifactModelString += "_RICIAN-";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician"));
}
}
}
parameters.m_NoiseModel->SetNoiseVariance(noiseVariance);
- parameters.m_ArtifactModelString += QString::number(noiseVariance).toStdString();
- parameters.m_ResultNode->AddProperty("Fiberfox.Noise-Variance", DoubleProperty::New(noiseVariance));
+ parameters.m_Misc.m_ArtifactModelString += QString::number(noiseVariance).toStdString();
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Variance", DoubleProperty::New(noiseVariance));
}
// adjusting line readout time to the adapted image size needed for the DFT
- unsigned int y = parameters.m_ImageRegion.GetSize(1);
+ unsigned int y = parameters.m_SignalGen.m_ImageRegion.GetSize(1);
y += y%2;
- if ( y>parameters.m_ImageRegion.GetSize(1) )
- parameters.m_tLine *= (double)parameters.m_ImageRegion.GetSize(1)/y;
+ if ( y>parameters.m_SignalGen.m_ImageRegion.GetSize(1) )
+ parameters.m_SignalGen.m_tLine *= (double)parameters.m_SignalGen.m_ImageRegion.GetSize(1)/y;
// signal models
- m_PrototypeModel1.Clear();
- m_PrototypeModel3.Clear();
- m_PrototypeModel4.Clear();
-
- // compartment 1
- switch (m_Controls->m_Compartment1Box->currentIndex())
- {
- case 0:
- m_StickModel1.SetGradientList(parameters.GetGradientDirections());
- m_StickModel1.SetBvalue(parameters.m_Bvalue);
- m_StickModel1.SetDiffusivity(m_Controls->m_StickWidget1->GetD());
- m_StickModel1.SetT2(m_Controls->m_StickWidget1->GetT2());
- parameters.m_FiberModelList.push_back(&m_StickModel1);
- parameters.m_SignalModelString += "Stick";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Stick") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.D", DoubleProperty::New(m_Controls->m_StickWidget1->GetD()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(m_StickModel1.GetT2()) );
- break;
- case 1:
- m_ZeppelinModel1.SetGradientList(parameters.GetGradientDirections());
- m_ZeppelinModel1.SetBvalue(parameters.m_Bvalue);
- m_ZeppelinModel1.SetDiffusivity1(m_Controls->m_ZeppelinWidget1->GetD1());
- m_ZeppelinModel1.SetDiffusivity2(m_Controls->m_ZeppelinWidget1->GetD2());
- m_ZeppelinModel1.SetDiffusivity3(m_Controls->m_ZeppelinWidget1->GetD2());
- m_ZeppelinModel1.SetT2(m_Controls->m_ZeppelinWidget1->GetT2());
- parameters.m_FiberModelList.push_back(&m_ZeppelinModel1);
- parameters.m_SignalModelString += "Zeppelin";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Zeppelin") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD1()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD2()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(m_ZeppelinModel1.GetT2()) );
- break;
- case 2:
- m_TensorModel1.SetGradientList(parameters.GetGradientDirections());
- m_TensorModel1.SetBvalue(parameters.m_Bvalue);
- m_TensorModel1.SetDiffusivity1(m_Controls->m_TensorWidget1->GetD1());
- m_TensorModel1.SetDiffusivity2(m_Controls->m_TensorWidget1->GetD2());
- m_TensorModel1.SetDiffusivity3(m_Controls->m_TensorWidget1->GetD3());
- m_TensorModel1.SetT2(m_Controls->m_TensorWidget1->GetT2());
- parameters.m_FiberModelList.push_back(&m_TensorModel1);
- parameters.m_SignalModelString += "Tensor";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Tensor") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD1()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD2()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.D3", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD3()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(m_ZeppelinModel1.GetT2()) );
- break;
- case 3:
- parameters.m_SimulateKspaceAcquisition = false;
- m_PrototypeModel1.SetGradientList(parameters.GetGradientDirections());
- m_PrototypeModel1.SetMaxNumKernels(m_Controls->m_PrototypeWidget1->GetNumberOfSamples());
- m_PrototypeModel1.SetFaRange(m_Controls->m_PrototypeWidget1->GetMinFa(), m_Controls->m_PrototypeWidget1->GetMaxFa());
- m_PrototypeModel1.SetAdcRange(m_Controls->m_PrototypeWidget1->GetMinAdc(), m_Controls->m_PrototypeWidget1->GetMaxAdc());
- parameters.m_FiberModelList.push_back(&m_PrototypeModel1);
- parameters.m_SignalModelString += "Prototype";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Prototype") );
- break;
- }
-
- // compartment 2
- switch (m_Controls->m_Compartment2Box->currentIndex())
- {
- case 0:
- break;
- case 1:
- m_StickModel2.SetGradientList(parameters.GetGradientDirections());
- m_StickModel2.SetBvalue(parameters.m_Bvalue);
- m_StickModel2.SetDiffusivity(m_Controls->m_StickWidget2->GetD());
- m_StickModel2.SetT2(m_Controls->m_StickWidget2->GetT2());
- parameters.m_FiberModelList.push_back(&m_StickModel2);
- parameters.m_SignalModelString += "Stick";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Stick") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.D", DoubleProperty::New(m_Controls->m_StickWidget2->GetD()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(m_StickModel2.GetT2()) );
- break;
- case 2:
- m_ZeppelinModel2.SetGradientList(parameters.GetGradientDirections());
- m_ZeppelinModel2.SetBvalue(parameters.m_Bvalue);
- m_ZeppelinModel2.SetDiffusivity1(m_Controls->m_ZeppelinWidget2->GetD1());
- m_ZeppelinModel2.SetDiffusivity2(m_Controls->m_ZeppelinWidget2->GetD2());
- m_ZeppelinModel2.SetDiffusivity3(m_Controls->m_ZeppelinWidget2->GetD2());
- m_ZeppelinModel2.SetT2(m_Controls->m_ZeppelinWidget2->GetT2());
- parameters.m_FiberModelList.push_back(&m_ZeppelinModel2);
- parameters.m_SignalModelString += "Zeppelin";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Zeppelin") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD1()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD2()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(m_ZeppelinModel2.GetT2()) );
- break;
- case 3:
- m_TensorModel2.SetGradientList(parameters.GetGradientDirections());
- m_TensorModel2.SetBvalue(parameters.m_Bvalue);
- m_TensorModel2.SetDiffusivity1(m_Controls->m_TensorWidget2->GetD1());
- m_TensorModel2.SetDiffusivity2(m_Controls->m_TensorWidget2->GetD2());
- m_TensorModel2.SetDiffusivity3(m_Controls->m_TensorWidget2->GetD3());
- m_TensorModel2.SetT2(m_Controls->m_TensorWidget2->GetT2());
- parameters.m_FiberModelList.push_back(&m_TensorModel2);
- parameters.m_SignalModelString += "Tensor";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Tensor") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD1()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD2()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.D3", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD3()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(m_ZeppelinModel2.GetT2()) );
- break;
- }
-
- // compartment 3
- switch (m_Controls->m_Compartment3Box->currentIndex())
- {
- case 0:
- m_BallModel1.SetGradientList(parameters.GetGradientDirections());
- m_BallModel1.SetBvalue(parameters.m_Bvalue);
- m_BallModel1.SetDiffusivity(m_Controls->m_BallWidget1->GetD());
- m_BallModel1.SetT2(m_Controls->m_BallWidget1->GetT2());
- parameters.m_NonFiberModelList.push_back(&m_BallModel1);
- parameters.m_SignalModelString += "Ball";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Ball") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_BallWidget1->GetD()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(m_BallModel1.GetT2()) );
- break;
- case 1:
- m_AstrosticksModel1.SetGradientList(parameters.GetGradientDirections());
- m_AstrosticksModel1.SetBvalue(parameters.m_Bvalue);
- m_AstrosticksModel1.SetDiffusivity(m_Controls->m_AstrosticksWidget1->GetD());
- m_AstrosticksModel1.SetT2(m_Controls->m_AstrosticksWidget1->GetT2());
- m_AstrosticksModel1.SetRandomizeSticks(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks());
- parameters.m_NonFiberModelList.push_back(&m_AstrosticksModel1);
- parameters.m_SignalModelString += "Astrosticks";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Astrosticks") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget1->GetD()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(m_AstrosticksModel1.GetT2()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()) );
- break;
- case 2:
- m_DotModel1.SetGradientList(parameters.GetGradientDirections());
- m_DotModel1.SetT2(m_Controls->m_DotWidget1->GetT2());
- parameters.m_NonFiberModelList.push_back(&m_DotModel1);
- parameters.m_SignalModelString += "Dot";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Dot") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(m_DotModel1.GetT2()) );
- break;
- case 3:
- parameters.m_SimulateKspaceAcquisition = false;
- m_PrototypeModel3.SetGradientList(parameters.GetGradientDirections());
- m_PrototypeModel3.SetMaxNumKernels(m_Controls->m_PrototypeWidget3->GetNumberOfSamples());
- m_PrototypeModel3.SetFaRange(m_Controls->m_PrototypeWidget3->GetMinFa(), m_Controls->m_PrototypeWidget3->GetMaxFa());
- m_PrototypeModel3.SetAdcRange(m_Controls->m_PrototypeWidget3->GetMinAdc(), m_Controls->m_PrototypeWidget3->GetMaxAdc());
- parameters.m_NonFiberModelList.push_back(&m_PrototypeModel3);
- parameters.m_SignalModelString += "Prototype";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Prototype") );
- break;
- }
-
- // compartment 4
- ItkDoubleImgType::Pointer comp4VolumeImage = NULL;
- ItkDoubleImgType::Pointer comp3VolumeImage = NULL;
- if (m_Controls->m_Compartment4Box->currentIndex()>0)
{
- mitk::DataNode::Pointer volumeNode = m_Controls->m_Comp4VolumeFraction->GetSelectedNode();
- if (volumeNode.IsNull())
+ // compartment 1
+ switch (m_Controls->m_Compartment1Box->currentIndex())
{
- MITK_WARN << "No volume fraction image selected! Second extra-axonal compartment has been disabled.";
+ case 0:
+ {
+ mitk::StickModel<ScalarType>* model = new mitk::StickModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity(m_Controls->m_StickWidget1->GetD());
+ model->SetT2(m_Controls->m_StickWidget1->GetT2());
+ model->m_CompartmentId = 1;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Stick";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Stick") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D", DoubleProperty::New(m_Controls->m_StickWidget1->GetD()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) );
+ break;
}
- else
+ case 1:
{
- MITK_INFO << "Rescaling volume fraction image...";
- comp4VolumeImage = ItkDoubleImgType::New();
- mitk::Image* img = dynamic_cast<mitk::Image*>(volumeNode->GetData());
- CastToItkImage< ItkDoubleImgType >(img, comp4VolumeImage);
-
- double max = itk::NumericTraits<double>::min();
- double min = itk::NumericTraits<double>::max();
-
- itk::ImageRegionIterator< ItkDoubleImgType > it(comp4VolumeImage, comp4VolumeImage->GetLargestPossibleRegion());
- while(!it.IsAtEnd())
- {
- if (parameters.m_MaskImage.IsNotNull() && parameters.m_MaskImage->GetPixel(it.GetIndex())<=0)
- {
- it.Set(0.0);
- ++it;
- continue;
- }
-
- if (it.Get()>max)
- max = it.Get();
- if (it.Get()<min)
- min = it.Get();
- ++it;
- }
- itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer scaler = itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New();
- scaler->SetInput(comp4VolumeImage);
- scaler->SetShift(-min);
- scaler->SetScale(1/(max-min));
- scaler->Update();
- comp4VolumeImage = scaler->GetOutput();
-
- itk::ImageFileWriter< ItkDoubleImgType >::Pointer wr = itk::ImageFileWriter< ItkDoubleImgType >::New();
- wr->SetInput(comp4VolumeImage);
- wr->SetFileName("/local/comp4.nrrd");
- wr->Update();
-
-// if (max>1 || min<0) // are volume fractions between 0 and 1?
-// {
-// itk::RescaleIntensityImageFilter<ItkDoubleImgType,ItkDoubleImgType>::Pointer rescaler = itk::RescaleIntensityImageFilter<ItkDoubleImgType,ItkDoubleImgType>::New();
-// rescaler->SetInput(0, comp4VolumeImage);
-// rescaler->SetOutputMaximum(1);
-// rescaler->SetOutputMinimum(0);
-// rescaler->Update();
-// comp4VolumeImage = rescaler->GetOutput();
-// }
-
- itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer inverter = itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New();
- inverter->SetMaximum(1.0);
- inverter->SetInput(comp4VolumeImage);
- inverter->Update();
- comp3VolumeImage = inverter->GetOutput();
+ mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity1(m_Controls->m_ZeppelinWidget1->GetD1());
+ model->SetDiffusivity2(m_Controls->m_ZeppelinWidget1->GetD2());
+ model->SetDiffusivity3(m_Controls->m_ZeppelinWidget1->GetD2());
+ model->SetT2(m_Controls->m_ZeppelinWidget1->GetT2());
+ model->m_CompartmentId = 1;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Zeppelin";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Zeppelin") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD1()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD2()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) );
+ break;
+ }
+ case 2:
+ {
+ mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity1(m_Controls->m_TensorWidget1->GetD1());
+ model->SetDiffusivity2(m_Controls->m_TensorWidget1->GetD2());
+ model->SetDiffusivity3(m_Controls->m_TensorWidget1->GetD3());
+ model->SetT2(m_Controls->m_TensorWidget1->GetT2());
+ model->m_CompartmentId = 1;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Tensor";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Tensor") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD1()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD2()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D3", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD3()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) );
+ break;
+ }
+ case 3:
+ {
+ mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = false;
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetMaxNumKernels(m_Controls->m_PrototypeWidget1->GetNumberOfSamples());
+ model->SetFaRange(m_Controls->m_PrototypeWidget1->GetMinFa(), m_Controls->m_PrototypeWidget1->GetMaxFa());
+ model->SetAdcRange(m_Controls->m_PrototypeWidget1->GetMinAdc(), m_Controls->m_PrototypeWidget1->GetMaxAdc());
+ model->m_CompartmentId = 1;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Prototype";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Prototype") );
+ break;
+ }
}
- }
- if (comp4VolumeImage.IsNotNull())
- switch (m_Controls->m_Compartment4Box->currentIndex())
+ // compartment 2
+ switch (m_Controls->m_Compartment2Box->currentIndex())
{
case 0:
break;
case 1:
{
- m_BallModel2.SetGradientList(parameters.GetGradientDirections());
- m_BallModel2.SetBvalue(parameters.m_Bvalue);
- m_BallModel2.SetDiffusivity(m_Controls->m_BallWidget2->GetD());
- m_BallModel2.SetT2(m_Controls->m_BallWidget2->GetT2());
- m_BallModel2.SetVolumeFractionImage(comp4VolumeImage);
- parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
- parameters.m_NonFiberModelList.push_back(&m_BallModel2);
- parameters.m_SignalModelString += "Ball";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Ball") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_BallWidget2->GetD()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(m_BallModel2.GetT2()) );
+ mitk::StickModel<ScalarType>* model = new mitk::StickModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity(m_Controls->m_StickWidget2->GetD());
+ model->SetT2(m_Controls->m_StickWidget2->GetT2());
+ model->m_CompartmentId = 2;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Stick";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Stick") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D", DoubleProperty::New(m_Controls->m_StickWidget2->GetD()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 2:
{
- m_AstrosticksModel2.SetGradientList(parameters.GetGradientDirections());
- m_AstrosticksModel2.SetBvalue(parameters.m_Bvalue);
- m_AstrosticksModel2.SetDiffusivity(m_Controls->m_AstrosticksWidget2->GetD());
- m_AstrosticksModel2.SetT2(m_Controls->m_AstrosticksWidget2->GetT2());
- m_AstrosticksModel2.SetRandomizeSticks(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks());
- parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
- m_AstrosticksModel2.SetVolumeFractionImage(comp4VolumeImage);
- parameters.m_NonFiberModelList.push_back(&m_AstrosticksModel2);
- parameters.m_SignalModelString += "Astrosticks";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Astrosticks") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget2->GetD()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(m_AstrosticksModel2.GetT2()) );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()) );
+ mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity1(m_Controls->m_ZeppelinWidget2->GetD1());
+ model->SetDiffusivity2(m_Controls->m_ZeppelinWidget2->GetD2());
+ model->SetDiffusivity3(m_Controls->m_ZeppelinWidget2->GetD2());
+ model->SetT2(m_Controls->m_ZeppelinWidget2->GetT2());
+ model->m_CompartmentId = 2;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Zeppelin";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Zeppelin") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD1()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD2()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 3:
{
- m_DotModel2.SetGradientList(parameters.GetGradientDirections());
- m_DotModel2.SetT2(m_Controls->m_DotWidget2->GetT2());
- m_DotModel2.SetVolumeFractionImage(comp4VolumeImage);
- parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
- parameters.m_NonFiberModelList.push_back(&m_DotModel2);
- parameters.m_SignalModelString += "Dot";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Dot") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(m_DotModel2.GetT2()) );
+ mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity1(m_Controls->m_TensorWidget2->GetD1());
+ model->SetDiffusivity2(m_Controls->m_TensorWidget2->GetD2());
+ model->SetDiffusivity3(m_Controls->m_TensorWidget2->GetD3());
+ model->SetT2(m_Controls->m_TensorWidget2->GetT2());
+ model->m_CompartmentId = 2;
+ parameters.m_FiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Tensor";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Tensor") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD1()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD2()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D3", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD3()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) );
break;
}
- case 4:
+ }
+
+ // compartment 3
+ switch (m_Controls->m_Compartment3Box->currentIndex())
+ {
+ case 0:
{
- parameters.m_SimulateKspaceAcquisition = false;
- m_PrototypeModel4.SetGradientList(parameters.GetGradientDirections());
- m_PrototypeModel4.SetMaxNumKernels(m_Controls->m_PrototypeWidget4->GetNumberOfSamples());
- m_PrototypeModel4.SetFaRange(m_Controls->m_PrototypeWidget4->GetMinFa(), m_Controls->m_PrototypeWidget4->GetMaxFa());
- m_PrototypeModel4.SetAdcRange(m_Controls->m_PrototypeWidget4->GetMinAdc(), m_Controls->m_PrototypeWidget4->GetMaxAdc());
- m_PrototypeModel4.SetVolumeFractionImage(comp4VolumeImage);
- parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
- parameters.m_NonFiberModelList.push_back(&m_PrototypeModel4);
- parameters.m_SignalModelString += "Prototype";
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
- parameters.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Prototype") );
+ mitk::BallModel<ScalarType>* model = new mitk::BallModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity(m_Controls->m_BallWidget1->GetD());
+ model->SetT2(m_Controls->m_BallWidget1->GetT2());
+ model->m_CompartmentId = 3;
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Ball";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Ball") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_BallWidget1->GetD()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) );
+ break;
+ }
+ case 1:
+ {
+ mitk::AstroStickModel<ScalarType>* model = new mitk::AstroStickModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity(m_Controls->m_AstrosticksWidget1->GetD());
+ model->SetT2(m_Controls->m_AstrosticksWidget1->GetT2());
+ model->SetRandomizeSticks(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks());
+ model->m_CompartmentId = 3;
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Astrosticks";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Astrosticks") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget1->GetD()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()) );
+ break;
+ }
+ case 2:
+ {
+ mitk::DotModel<ScalarType>* model = new mitk::DotModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetT2(m_Controls->m_DotWidget1->GetT2());
+ model->m_CompartmentId = 3;
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Dot";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Dot") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) );
+ break;
+ }
+ case 3:
+ {
+ mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = false;
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetMaxNumKernels(m_Controls->m_PrototypeWidget3->GetNumberOfSamples());
+ model->SetFaRange(m_Controls->m_PrototypeWidget3->GetMinFa(), m_Controls->m_PrototypeWidget3->GetMaxFa());
+ model->SetAdcRange(m_Controls->m_PrototypeWidget3->GetMinAdc(), m_Controls->m_PrototypeWidget3->GetMaxAdc());
+ model->m_CompartmentId = 3;
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Prototype";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Prototype") );
break;
}
}
- parameters.m_DiffusionDirectionMode = FiberfoxParameters<ScalarType>::FIBER_TANGENT_DIRECTIONS;
+ // compartment 4
+ ItkDoubleImgType::Pointer comp4VolumeImage = NULL;
+ ItkDoubleImgType::Pointer comp3VolumeImage = NULL;
+ if (m_Controls->m_Compartment4Box->currentIndex()>0)
+ {
+ mitk::DataNode::Pointer volumeNode = m_Controls->m_Comp4VolumeFraction->GetSelectedNode();
+ if (volumeNode.IsNull())
+ {
+ QMessageBox::information( NULL, "Information", "No volume fraction image selected! Second extra-axonal compartment has been disabled for this simultation.");
+ MITK_WARN << "No volume fraction image selected! Second extra-axonal compartment has been disabled.";
+ }
+ else
+ {
+ MITK_INFO << "Rescaling volume fraction image...";
+ comp4VolumeImage = ItkDoubleImgType::New();
+ mitk::Image* img = dynamic_cast<mitk::Image*>(volumeNode->GetData());
+ CastToItkImage< ItkDoubleImgType >(img, comp4VolumeImage);
- parameters.m_ResultNode->AddProperty("Fiberfox.SignalScale", IntProperty::New(parameters.m_SignalScale));
- parameters.m_ResultNode->AddProperty("Fiberfox.FiberRadius", IntProperty::New(parameters.m_AxonRadius));
- parameters.m_ResultNode->AddProperty("Fiberfox.Tinhom", DoubleProperty::New(parameters.m_tInhom));
- parameters.m_ResultNode->AddProperty("Fiberfox.Tline", DoubleProperty::New(parameters.m_tLine));
- parameters.m_ResultNode->AddProperty("Fiberfox.TE", DoubleProperty::New(parameters.m_tEcho));
- parameters.m_ResultNode->AddProperty("Fiberfox.b-value", DoubleProperty::New(parameters.m_Bvalue));
- parameters.m_ResultNode->AddProperty("Fiberfox.NoPartialVolume", BoolProperty::New(parameters.m_DoDisablePartialVolume));
- parameters.m_ResultNode->AddProperty("Fiberfox.Relaxation", BoolProperty::New(parameters.m_DoSimulateRelaxation));
- parameters.m_ResultNode->AddProperty("binary", BoolProperty::New(false));
+ double max = itk::NumericTraits<double>::min();
+ double min = itk::NumericTraits<double>::max();
+
+ itk::ImageRegionIterator< ItkDoubleImgType > it(comp4VolumeImage, comp4VolumeImage->GetLargestPossibleRegion());
+ while(!it.IsAtEnd())
+ {
+ if (parameters.m_SignalGen.m_MaskImage.IsNotNull() && parameters.m_SignalGen.m_MaskImage->GetPixel(it.GetIndex())<=0)
+ {
+ it.Set(0.0);
+ ++it;
+ continue;
+ }
+
+ if (it.Get()>max)
+ max = it.Get();
+ if (it.Get()<min)
+ min = it.Get();
+ ++it;
+ }
+ itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer scaler = itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New();
+ scaler->SetInput(comp4VolumeImage);
+ scaler->SetShift(-min);
+ scaler->SetScale(1.0/(max-min));
+ scaler->Update();
+ comp4VolumeImage = scaler->GetOutput();
+
+ // itk::ImageFileWriter< ItkDoubleImgType >::Pointer wr = itk::ImageFileWriter< ItkDoubleImgType >::New();
+ // wr->SetInput(comp4VolumeImage);
+ // wr->SetFileName("/local/comp4.nrrd");
+ // wr->Update();
+
+ // if (max>1 || min<0) // are volume fractions between 0 and 1?
+ // {
+ // itk::RescaleIntensityImageFilter<ItkDoubleImgType,ItkDoubleImgType>::Pointer rescaler = itk::RescaleIntensityImageFilter<ItkDoubleImgType,ItkDoubleImgType>::New();
+ // rescaler->SetInput(0, comp4VolumeImage);
+ // rescaler->SetOutputMaximum(1);
+ // rescaler->SetOutputMinimum(0);
+ // rescaler->Update();
+ // comp4VolumeImage = rescaler->GetOutput();
+ // }
+
+ itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer inverter = itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New();
+ inverter->SetMaximum(1.0);
+ inverter->SetInput(comp4VolumeImage);
+ inverter->Update();
+ comp3VolumeImage = inverter->GetOutput();
+ }
+ }
+
+ if (comp4VolumeImage.IsNotNull())
+ {
+ switch (m_Controls->m_Compartment4Box->currentIndex())
+ {
+ case 0:
+ break;
+ case 1:
+ {
+ mitk::BallModel<ScalarType>* model = new mitk::BallModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity(m_Controls->m_BallWidget2->GetD());
+ model->SetT2(m_Controls->m_BallWidget2->GetT2());
+ model->SetVolumeFractionImage(comp4VolumeImage);
+ model->m_CompartmentId = 4;
+ parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Ball";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Ball") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_BallWidget2->GetD()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) );
+ break;
+ }
+ case 2:
+ {
+ mitk::AstroStickModel<ScalarType>* model = new mitk::AstroStickModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
+ model->SetDiffusivity(m_Controls->m_AstrosticksWidget2->GetD());
+ model->SetT2(m_Controls->m_AstrosticksWidget2->GetT2());
+ model->SetRandomizeSticks(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks());
+ parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
+ model->SetVolumeFractionImage(comp4VolumeImage);
+ model->m_CompartmentId = 4;
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Astrosticks";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Astrosticks") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget2->GetD()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()) );
+ break;
+ }
+ case 3:
+ {
+ mitk::DotModel<ScalarType>* model = new mitk::DotModel<ScalarType>();
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetT2(m_Controls->m_DotWidget2->GetT2());
+ model->SetVolumeFractionImage(comp4VolumeImage);
+ model->m_CompartmentId = 4;
+ parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Dot";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Dot") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) );
+ break;
+ }
+ case 4:
+ {
+ mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
+ parameters.m_SignalGen.m_SimulateKspaceAcquisition = false;
+ model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
+ model->SetMaxNumKernels(m_Controls->m_PrototypeWidget4->GetNumberOfSamples());
+ model->SetFaRange(m_Controls->m_PrototypeWidget4->GetMinFa(), m_Controls->m_PrototypeWidget4->GetMaxFa());
+ model->SetAdcRange(m_Controls->m_PrototypeWidget4->GetMinAdc(), m_Controls->m_PrototypeWidget4->GetMaxAdc());
+ model->SetVolumeFractionImage(comp4VolumeImage);
+ model->m_CompartmentId = 4;
+ parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
+ parameters.m_NonFiberModelList.push_back(model);
+ parameters.m_Misc.m_SignalModelString += "Prototype";
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Prototype") );
+ break;
+ }
+ }
+ }
+ }
+
+ parameters.m_SignalGen.m_FiberSeparationThreshold = m_Controls->m_SeparationAngleBox->value();
+ switch (m_Controls->m_DiffusionDirectionBox->currentIndex())
+ {
+ case 0:
+ parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS;
+ break;
+ case 1:
+ parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::MAIN_FIBER_DIRECTIONS;
+ break;
+ case 2:
+ parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::RANDOM_DIRECTIONS;
+ parameters.m_SignalGen.m_DoAddMotion = false;
+ parameters.m_SignalGen.m_DoAddGibbsRinging = false;
+ parameters.m_SignalGen.m_KspaceLineOffset = 0.0;
+ parameters.m_SignalGen.m_FrequencyMap = NULL;
+ parameters.m_SignalGen.m_CroppingFactor = 1.0;
+ parameters.m_SignalGen.m_EddyStrength = 0;
+ break;
+ default:
+ parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS;
+ }
+
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.SignalScale", IntProperty::New(parameters.m_SignalGen.m_SignalScale));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.FiberRadius", IntProperty::New(parameters.m_SignalGen.m_AxonRadius));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Tinhom", DoubleProperty::New(parameters.m_SignalGen.m_tInhom));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Tline", DoubleProperty::New(parameters.m_SignalGen.m_tLine));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.TE", DoubleProperty::New(parameters.m_SignalGen.m_tEcho));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.b-value", DoubleProperty::New(parameters.m_SignalGen.m_Bvalue));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.NoPartialVolume", BoolProperty::New(parameters.m_SignalGen.m_DoDisablePartialVolume));
+ parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Relaxation", BoolProperty::New(parameters.m_SignalGen.m_DoSimulateRelaxation));
+ parameters.m_Misc.m_ResultNode->AddProperty("binary", BoolProperty::New(false));
+
+ parameters.m_Misc.m_CheckRealTimeFibersBox = m_Controls->m_RealTimeFibers->isChecked();
+ parameters.m_Misc.m_CheckAdvancedFiberOptionsBox = m_Controls->m_AdvancedOptionsBox->isChecked();
+ parameters.m_Misc.m_CheckIncludeFiducialsBox = m_Controls->m_IncludeFiducials->isChecked();
+ parameters.m_Misc.m_CheckConstantRadiusBox = m_Controls->m_ConstantRadiusBox->isChecked();
+
+ switch(m_Controls->m_DistributionBox->currentIndex())
+ {
+ case 0:
+ parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
+ break;
+ case 1:
+ parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_GAUSSIAN;
+ break;
+ default:
+ parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
+ }
+ parameters.m_FiberGen.m_Variance = m_Controls->m_VarianceBox->value();
+ parameters.m_FiberGen.m_Density = m_Controls->m_FiberDensityBox->value();
+ parameters.m_FiberGen.m_Sampling = m_Controls->m_FiberSamplingBox->value();
+ parameters.m_FiberGen.m_Tension = m_Controls->m_TensionBox->value();
+ parameters.m_FiberGen.m_Continuity = m_Controls->m_ContinuityBox->value();
+ parameters.m_FiberGen.m_Bias = m_Controls->m_BiasBox->value();
+ parameters.m_FiberGen.m_Rotation[0] = m_Controls->m_XrotBox->value();
+ parameters.m_FiberGen.m_Rotation[1] = m_Controls->m_YrotBox->value();
+ parameters.m_FiberGen.m_Rotation[2] = m_Controls->m_ZrotBox->value();
+ parameters.m_FiberGen.m_Translation[0] = m_Controls->m_XtransBox->value();
+ parameters.m_FiberGen.m_Translation[1] = m_Controls->m_YtransBox->value();
+ parameters.m_FiberGen.m_Translation[2] = m_Controls->m_ZtransBox->value();
+ parameters.m_FiberGen.m_Scale[0] = m_Controls->m_XscaleBox->value();
+ parameters.m_FiberGen.m_Scale[1] = m_Controls->m_YscaleBox->value();
+ parameters.m_FiberGen.m_Scale[2] = m_Controls->m_ZscaleBox->value();
return parameters;
}
void QmitkFiberfoxView::SaveParameters()
{
- FiberfoxParameters<double> ffParamaters = UpdateImageParameters<double>();
+ FiberfoxParameters<> ffParamaters = UpdateImageParameters<double>();
QString filename = QFileDialog::getSaveFileName(
0,
tr("Save Parameters"),
m_ParameterFile,
tr("Fiberfox Parameters (*.ffp)") );
- if(filename.isEmpty() || filename.isNull())
- return;
- if(!filename.endsWith(".ffp"))
- filename += ".ffp";
+ bool ok = true;
+ bool first = true;
+ bool dosampling = false;
+ mitk::DiffusionImage<short>::Pointer diffImg;
+ itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = NULL;
+ const int shOrder = 2;
+ typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,shOrder,QBALL_ODFSIZE> QballFilterType;
+ QballFilterType::CoefficientImageType::Pointer itkFeatureImage = NULL;
+ ItkDoubleImgType::Pointer adcImage = NULL;
+
+ for (unsigned int i=0; i<ffParamaters.m_FiberModelList.size()+ffParamaters.m_NonFiberModelList.size(); i++)
+ {
+ mitk::RawShModel<>* model = NULL;
+ if (i<ffParamaters.m_FiberModelList.size())
+ model = dynamic_cast< mitk::RawShModel<>* >(ffParamaters.m_FiberModelList.at(i));
+ else
+ model = dynamic_cast< mitk::RawShModel<>* >(ffParamaters.m_NonFiberModelList.at(i-ffParamaters.m_FiberModelList.size()));
- m_ParameterFile = filename;
+ if (model!=0 && model->GetNumberOfKernels()<=0)
+ {
+ if (first==true)
+ {
+ if (QMessageBox::question(NULL, "Prototype signal sampling", "Do you want to sample prototype signals from the selected diffusion-weighted imag and save them?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
+ dosampling = true;
- boost::property_tree::ptree parameters;
-
- // fiber generation parameters
- parameters.put("fiberfox.fibers.realtime", m_Controls->m_RealTimeFibers->isChecked());
- parameters.put("fiberfox.fibers.showadvanced", m_Controls->m_AdvancedOptionsBox->isChecked());
- parameters.put("fiberfox.fibers.distribution", m_Controls->m_DistributionBox->currentIndex());
- parameters.put("fiberfox.fibers.variance", m_Controls->m_VarianceBox->value());
- parameters.put("fiberfox.fibers.density", m_Controls->m_FiberDensityBox->value());
- parameters.put("fiberfox.fibers.spline.sampling", m_Controls->m_FiberSamplingBox->value());
- parameters.put("fiberfox.fibers.spline.tension", m_Controls->m_TensionBox->value());
- parameters.put("fiberfox.fibers.spline.continuity", m_Controls->m_ContinuityBox->value());
- parameters.put("fiberfox.fibers.spline.bias", m_Controls->m_BiasBox->value());
- parameters.put("fiberfox.fibers.constantradius", m_Controls->m_ConstantRadiusBox->isChecked());
- parameters.put("fiberfox.fibers.rotation.x", m_Controls->m_XrotBox->value());
- parameters.put("fiberfox.fibers.rotation.y", m_Controls->m_YrotBox->value());
- parameters.put("fiberfox.fibers.rotation.z", m_Controls->m_ZrotBox->value());
- parameters.put("fiberfox.fibers.translation.x", m_Controls->m_XtransBox->value());
- parameters.put("fiberfox.fibers.translation.y", m_Controls->m_YtransBox->value());
- parameters.put("fiberfox.fibers.translation.z", m_Controls->m_ZtransBox->value());
- parameters.put("fiberfox.fibers.scale.x", m_Controls->m_XscaleBox->value());
- parameters.put("fiberfox.fibers.scale.y", m_Controls->m_YscaleBox->value());
- parameters.put("fiberfox.fibers.scale.z", m_Controls->m_ZscaleBox->value());
- parameters.put("fiberfox.fibers.includeFiducials", m_Controls->m_IncludeFiducials->isChecked());
- parameters.put("fiberfox.fibers.includeFiducials", m_Controls->m_IncludeFiducials->isChecked());
+ first = false;
+ if (dosampling && m_SelectedDWI.IsNull())
+ {
+ QMessageBox::information(NULL, "Parameter file not saved", "No diffusion-weighted image selected to sample signal from.");
+ return;
+ }
+ else if (dosampling)
+ {
+ diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(m_SelectedDWI->GetData());
+
+ typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
+ TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
+ filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
+ filter->SetBValue(diffImg->GetReferenceBValue());
+ filter->Update();
+ tensorImage = filter->GetOutput();
+
+ const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder;
+ QballFilterType::Pointer qballfilter = QballFilterType::New();
+ qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
+ qballfilter->SetBValue(diffImg->GetReferenceBValue());
+ qballfilter->SetLambda(0.006);
+ qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL);
+ qballfilter->Update();
+ itkFeatureImage = qballfilter->GetCoefficientImage();
+
+ itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
+ adcFilter->SetInput(diffImg->GetVectorImage());
+ adcFilter->SetGradientDirections(diffImg->GetDirections());
+ adcFilter->SetB_value(diffImg->GetReferenceBValue());
+ adcFilter->Update();
+ adcImage = adcFilter->GetOutput();
+ }
+ }
- // image generation parameters
- parameters.put("fiberfox.image.basic.size.x", ffParamaters.m_ImageRegion.GetSize(0));
- parameters.put("fiberfox.image.basic.size.y", ffParamaters.m_ImageRegion.GetSize(1));
- parameters.put("fiberfox.image.basic.size.z", ffParamaters.m_ImageRegion.GetSize(2));
- parameters.put("fiberfox.image.basic.spacing.x", ffParamaters.m_ImageSpacing[0]);
- parameters.put("fiberfox.image.basic.spacing.y", ffParamaters.m_ImageSpacing[1]);
- parameters.put("fiberfox.image.basic.spacing.z", ffParamaters.m_ImageSpacing[2]);
- parameters.put("fiberfox.image.basic.numgradients", ffParamaters.GetNumWeightedVolumes());
- parameters.put("fiberfox.image.basic.bvalue", ffParamaters.m_Bvalue);
- parameters.put("fiberfox.image.showadvanced", m_Controls->m_AdvancedOptionsBox_2->isChecked());
- parameters.put("fiberfox.image.signalScale", ffParamaters.m_SignalScale);
- parameters.put("fiberfox.image.tEcho", ffParamaters.m_tEcho);
- parameters.put("fiberfox.image.tLine", m_Controls->m_LineReadoutTimeBox->value());
- parameters.put("fiberfox.image.tInhom", ffParamaters.m_tInhom);
- parameters.put("fiberfox.image.axonRadius", ffParamaters.m_AxonRadius);
- parameters.put("fiberfox.image.doSimulateRelaxation", ffParamaters.m_DoSimulateRelaxation);
- parameters.put("fiberfox.image.doDisablePartialVolume", ffParamaters.m_DoDisablePartialVolume);
- parameters.put("fiberfox.image.outputvolumefractions", m_Controls->m_VolumeFractionsBox->isChecked());
-
- parameters.put("fiberfox.image.artifacts.addnoise", m_Controls->m_AddNoise->isChecked());
- parameters.put("fiberfox.image.artifacts.noisedistribution", m_Controls->m_NoiseDistributionBox->currentIndex());
- parameters.put("fiberfox.image.artifacts.noisevariance", m_Controls->m_NoiseLevel->value());
- parameters.put("fiberfox.image.artifacts.addghost", m_Controls->m_AddGhosts->isChecked());
- parameters.put("fiberfox.image.artifacts.kspaceLineOffset", m_Controls->m_kOffsetBox->value());
- parameters.put("fiberfox.image.artifacts.distortions", m_Controls->m_AddDistortions->isChecked());
- parameters.put("fiberfox.image.artifacts.addeddy", m_Controls->m_AddEddy->isChecked());
- parameters.put("fiberfox.image.artifacts.eddyStrength", m_Controls->m_EddyGradientStrength->value());
- parameters.put("fiberfox.image.artifacts.addringing", m_Controls->m_AddGibbsRinging->isChecked());
- parameters.put("fiberfox.image.artifacts.addspikes", m_Controls->m_AddSpikes->isChecked());
- parameters.put("fiberfox.image.artifacts.spikesnum", m_Controls->m_SpikeNumBox->value());
- parameters.put("fiberfox.image.artifacts.spikesscale", m_Controls->m_SpikeScaleBox->value());
- parameters.put("fiberfox.image.artifacts.addaliasing", m_Controls->m_AddAliasing->isChecked());
- parameters.put("fiberfox.image.artifacts.aliasingfactor", m_Controls->m_WrapBox->value());
- parameters.put("fiberfox.image.artifacts.doAddMotion", m_Controls->m_AddMotion->isChecked());
- parameters.put("fiberfox.image.artifacts.randomMotion", m_Controls->m_RandomMotion->isChecked());
- parameters.put("fiberfox.image.artifacts.translation0", m_Controls->m_MaxTranslationBoxX->value());
- parameters.put("fiberfox.image.artifacts.translation1", m_Controls->m_MaxTranslationBoxY->value());
- parameters.put("fiberfox.image.artifacts.translation2", m_Controls->m_MaxTranslationBoxZ->value());
- parameters.put("fiberfox.image.artifacts.rotation0", m_Controls->m_MaxRotationBoxX->value());
- parameters.put("fiberfox.image.artifacts.rotation1", m_Controls->m_MaxRotationBoxY->value());
- parameters.put("fiberfox.image.artifacts.rotation2", m_Controls->m_MaxRotationBoxZ->value());
-
- parameters.put("fiberfox.image.compartment1.index", m_Controls->m_Compartment1Box->currentIndex());
- parameters.put("fiberfox.image.compartment2.index", m_Controls->m_Compartment2Box->currentIndex());
- parameters.put("fiberfox.image.compartment3.index", m_Controls->m_Compartment3Box->currentIndex());
- parameters.put("fiberfox.image.compartment4.index", m_Controls->m_Compartment4Box->currentIndex());
-
- parameters.put("fiberfox.image.compartment1.stick.d", m_Controls->m_StickWidget1->GetD());
- parameters.put("fiberfox.image.compartment1.stick.t2", m_Controls->m_StickWidget1->GetT2());
- parameters.put("fiberfox.image.compartment1.zeppelin.d1", m_Controls->m_ZeppelinWidget1->GetD1());
- parameters.put("fiberfox.image.compartment1.zeppelin.d2", m_Controls->m_ZeppelinWidget1->GetD2());
- parameters.put("fiberfox.image.compartment1.zeppelin.t2", m_Controls->m_ZeppelinWidget1->GetT2());
- parameters.put("fiberfox.image.compartment1.tensor.d1", m_Controls->m_TensorWidget1->GetD1());
- parameters.put("fiberfox.image.compartment1.tensor.d2", m_Controls->m_TensorWidget1->GetD2());
- parameters.put("fiberfox.image.compartment1.tensor.d3", m_Controls->m_TensorWidget1->GetD3());
- parameters.put("fiberfox.image.compartment1.tensor.t2", m_Controls->m_TensorWidget1->GetT2());
- parameters.put("fiberfox.image.compartment1.prototype.minFA", m_Controls->m_PrototypeWidget1->GetMinFa());
- parameters.put("fiberfox.image.compartment1.prototype.maxFA", m_Controls->m_PrototypeWidget1->GetMaxFa());
- parameters.put("fiberfox.image.compartment1.prototype.minADC", m_Controls->m_PrototypeWidget1->GetMinAdc());
- parameters.put("fiberfox.image.compartment1.prototype.maxADC", m_Controls->m_PrototypeWidget1->GetMaxAdc());
- parameters.put("fiberfox.image.compartment1.prototype.numSamples", m_Controls->m_PrototypeWidget1->GetNumberOfSamples());
-
- parameters.put("fiberfox.image.compartment2.stick.d", m_Controls->m_StickWidget2->GetD());
- parameters.put("fiberfox.image.compartment2.stick.t2", m_Controls->m_StickWidget2->GetT2());
- parameters.put("fiberfox.image.compartment2.zeppelin.d1", m_Controls->m_ZeppelinWidget2->GetD1());
- parameters.put("fiberfox.image.compartment2.zeppelin.d2", m_Controls->m_ZeppelinWidget2->GetD2());
- parameters.put("fiberfox.image.compartment2.zeppelin.t2", m_Controls->m_ZeppelinWidget2->GetT2());
- parameters.put("fiberfox.image.compartment2.tensor.d1", m_Controls->m_TensorWidget2->GetD1());
- parameters.put("fiberfox.image.compartment2.tensor.d2", m_Controls->m_TensorWidget2->GetD2());
- parameters.put("fiberfox.image.compartment2.tensor.d3", m_Controls->m_TensorWidget2->GetD3());
- parameters.put("fiberfox.image.compartment2.tensor.t2", m_Controls->m_TensorWidget2->GetT2());
-
- parameters.put("fiberfox.image.compartment3.ball.d", m_Controls->m_BallWidget1->GetD());
- parameters.put("fiberfox.image.compartment3.ball.t2", m_Controls->m_BallWidget1->GetT2());
- parameters.put("fiberfox.image.compartment3.astrosticks.d", m_Controls->m_AstrosticksWidget1->GetD());
- parameters.put("fiberfox.image.compartment3.astrosticks.t2", m_Controls->m_AstrosticksWidget1->GetT2());
- parameters.put("fiberfox.image.compartment3.astrosticks.randomize", m_Controls->m_AstrosticksWidget1->GetRandomizeSticks());
- parameters.put("fiberfox.image.compartment3.dot.t2", m_Controls->m_DotWidget1->GetT2());
- parameters.put("fiberfox.image.compartment3.prototype.minFA", m_Controls->m_PrototypeWidget3->GetMinFa());
- parameters.put("fiberfox.image.compartment3.prototype.maxFA", m_Controls->m_PrototypeWidget3->GetMaxFa());
- parameters.put("fiberfox.image.compartment3.prototype.minADC", m_Controls->m_PrototypeWidget3->GetMinAdc());
- parameters.put("fiberfox.image.compartment3.prototype.maxADC", m_Controls->m_PrototypeWidget3->GetMaxAdc());
- parameters.put("fiberfox.image.compartment3.prototype.numSamples", m_Controls->m_PrototypeWidget3->GetNumberOfSamples());
-
- parameters.put("fiberfox.image.compartment4.ball.d", m_Controls->m_BallWidget2->GetD());
- parameters.put("fiberfox.image.compartment4.ball.t2", m_Controls->m_BallWidget2->GetT2());
- parameters.put("fiberfox.image.compartment4.astrosticks.d", m_Controls->m_AstrosticksWidget2->GetD());
- parameters.put("fiberfox.image.compartment4.astrosticks.t2", m_Controls->m_AstrosticksWidget2->GetT2());
- parameters.put("fiberfox.image.compartment4.astrosticks.randomize", m_Controls->m_AstrosticksWidget2->GetRandomizeSticks());
- parameters.put("fiberfox.image.compartment4.dot.t2", m_Controls->m_DotWidget2->GetT2());
- parameters.put("fiberfox.image.compartment4.prototype.minFA", m_Controls->m_PrototypeWidget4->GetMinFa());
- parameters.put("fiberfox.image.compartment4.prototype.maxFA", m_Controls->m_PrototypeWidget4->GetMaxFa());
- parameters.put("fiberfox.image.compartment4.prototype.minADC", m_Controls->m_PrototypeWidget4->GetMinAdc());
- parameters.put("fiberfox.image.compartment4.prototype.maxADC", m_Controls->m_PrototypeWidget4->GetMaxAdc());
- parameters.put("fiberfox.image.compartment4.prototype.numSamples", m_Controls->m_PrototypeWidget4->GetNumberOfSamples());
-
- boost::property_tree::xml_parser::write_xml(filename.toStdString(), parameters);
+ if (dosampling && m_SelectedDWI.IsNotNull())
+ {
+ ok = model->SampleKernels(diffImg, ffParamaters.m_SignalGen.m_MaskImage, tensorImage, itkFeatureImage, adcImage);
+ if (!ok)
+ {
+ QMessageBox::information( NULL, "Parameter file not saved", "No valid prototype signals could be sampled.");
+ return;
+ }
+ }
+ }
+ }
+
+ ffParamaters.SaveParameters(filename.toStdString());
+ m_ParameterFile = filename;
}
void QmitkFiberfoxView::LoadParameters()
{
QString filename = QFileDialog::getOpenFileName(0, tr("Load Parameters"), QString(itksys::SystemTools::GetFilenamePath(m_ParameterFile.toStdString()).c_str()), tr("Fiberfox Parameters (*.ffp)") );
if(filename.isEmpty() || filename.isNull())
return;
m_ParameterFile = filename;
- boost::property_tree::ptree parameters;
- boost::property_tree::xml_parser::read_xml(filename.toStdString(), parameters);
+ FiberfoxParameters<> parameters;
+ parameters.LoadParameters(filename.toStdString());
+
+ m_Controls->m_RealTimeFibers->setChecked(parameters.m_Misc.m_CheckRealTimeFibersBox);
+ m_Controls->m_AdvancedOptionsBox->setChecked(parameters.m_Misc.m_CheckAdvancedFiberOptionsBox);
+ m_Controls->m_IncludeFiducials->setChecked(parameters.m_Misc.m_CheckIncludeFiducialsBox);
+ m_Controls->m_ConstantRadiusBox->setChecked(parameters.m_Misc.m_CheckConstantRadiusBox);
+
+ m_Controls->m_DistributionBox->setCurrentIndex(parameters.m_FiberGen.m_Distribution);
+ m_Controls->m_VarianceBox->setValue(parameters.m_FiberGen.m_Variance);
+ m_Controls->m_FiberDensityBox->setValue(parameters.m_FiberGen.m_Density);
+ m_Controls->m_FiberSamplingBox->setValue(parameters.m_FiberGen.m_Sampling);
+ m_Controls->m_TensionBox->setValue(parameters.m_FiberGen.m_Tension);
+ m_Controls->m_ContinuityBox->setValue(parameters.m_FiberGen.m_Continuity);
+ m_Controls->m_BiasBox->setValue(parameters.m_FiberGen.m_Bias);
+ m_Controls->m_XrotBox->setValue(parameters.m_FiberGen.m_Rotation[0]);
+ m_Controls->m_YrotBox->setValue(parameters.m_FiberGen.m_Rotation[1]);
+ m_Controls->m_ZrotBox->setValue(parameters.m_FiberGen.m_Rotation[2]);
+ m_Controls->m_XtransBox->setValue(parameters.m_FiberGen.m_Translation[0]);
+ m_Controls->m_YtransBox->setValue(parameters.m_FiberGen.m_Translation[1]);
+ m_Controls->m_ZtransBox->setValue(parameters.m_FiberGen.m_Translation[2]);
+ m_Controls->m_XscaleBox->setValue(parameters.m_FiberGen.m_Scale[0]);
+ m_Controls->m_YscaleBox->setValue(parameters.m_FiberGen.m_Scale[1]);
+ m_Controls->m_ZscaleBox->setValue(parameters.m_FiberGen.m_Scale[2]);
- BOOST_FOREACH( boost::property_tree::ptree::value_type const& v1, parameters.get_child("fiberfox") )
- {
- if( v1.first == "fibers" )
+ // image generation parameters
+ m_Controls->m_SizeX->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(0));
+ m_Controls->m_SizeY->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(1));
+ m_Controls->m_SizeZ->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(2));
+ m_Controls->m_SpacingX->setValue(parameters.m_SignalGen.m_ImageSpacing[0]);
+ m_Controls->m_SpacingY->setValue(parameters.m_SignalGen.m_ImageSpacing[1]);
+ m_Controls->m_SpacingZ->setValue(parameters.m_SignalGen.m_ImageSpacing[2]);
+ m_Controls->m_NumGradientsBox->setValue(parameters.m_SignalGen.GetNumWeightedVolumes());
+ m_Controls->m_BvalueBox->setValue(parameters.m_SignalGen.m_Bvalue);
+ m_Controls->m_SignalScaleBox->setValue(parameters.m_SignalGen.m_SignalScale);
+ m_Controls->m_TEbox->setValue(parameters.m_SignalGen.m_tEcho);
+ m_Controls->m_LineReadoutTimeBox->setValue(parameters.m_SignalGen.m_tLine);
+ m_Controls->m_T2starBox->setValue(parameters.m_SignalGen.m_tInhom);
+ m_Controls->m_FiberRadius->setValue(parameters.m_SignalGen.m_AxonRadius);
+ m_Controls->m_RelaxationBox->setChecked(parameters.m_SignalGen.m_DoSimulateRelaxation);
+ m_Controls->m_EnforcePureFiberVoxelsBox->setChecked(parameters.m_SignalGen.m_DoDisablePartialVolume);
+
+ if (parameters.m_NoiseModel!=NULL)
+ {
+ m_Controls->m_AddNoise->setChecked(parameters.m_Misc.m_CheckAddNoiseBox);
+ if (dynamic_cast<mitk::RicianNoiseModel<double>*>(parameters.m_NoiseModel))
+ m_Controls->m_NoiseDistributionBox->setCurrentIndex(0);
+ else if (dynamic_cast<mitk::ChiSquareNoiseModel<double>*>(parameters.m_NoiseModel))
+ m_Controls->m_NoiseDistributionBox->setCurrentIndex(1);
+ m_Controls->m_NoiseLevel->setValue(parameters.m_NoiseModel->GetNoiseVariance());
+ }
+ else
+ m_Controls->m_AddNoise->setChecked(false);
+
+ m_Controls->m_VolumeFractionsBox->setChecked(parameters.m_Misc.m_CheckOutputVolumeFractionsBox);
+ m_Controls->m_AdvancedOptionsBox_2->setChecked(parameters.m_Misc.m_CheckAdvancedSignalOptionsBox);
+ m_Controls->m_AddGhosts->setChecked(parameters.m_Misc.m_CheckAddGhostsBox);
+ m_Controls->m_AddAliasing->setChecked(parameters.m_Misc.m_CheckAddAliasingBox);
+ m_Controls->m_AddDistortions->setChecked(parameters.m_Misc.m_CheckAddDistortionsBox);
+ m_Controls->m_AddSpikes->setChecked(parameters.m_Misc.m_CheckAddSpikesBox);
+ m_Controls->m_AddEddy->setChecked(parameters.m_Misc.m_CheckAddEddyCurrentsBox);
+
+ m_Controls->m_kOffsetBox->setValue(parameters.m_SignalGen.m_KspaceLineOffset);
+ m_Controls->m_WrapBox->setValue(100*(1-parameters.m_SignalGen.m_CroppingFactor));
+ m_Controls->m_SpikeNumBox->setValue(parameters.m_SignalGen.m_Spikes);
+ m_Controls->m_SpikeScaleBox->setValue(parameters.m_SignalGen.m_SpikeAmplitude);
+ m_Controls->m_EddyGradientStrength->setValue(parameters.m_SignalGen.m_EddyStrength);
+ m_Controls->m_AddGibbsRinging->setChecked(parameters.m_SignalGen.m_DoAddGibbsRinging);
+ m_Controls->m_AddMotion->setChecked(parameters.m_SignalGen.m_DoAddMotion);
+ m_Controls->m_RandomMotion->setChecked(parameters.m_SignalGen.m_DoRandomizeMotion);
+ m_Controls->m_MaxTranslationBoxX->setValue(parameters.m_SignalGen.m_Translation[0]);
+ m_Controls->m_MaxTranslationBoxY->setValue(parameters.m_SignalGen.m_Translation[1]);
+ m_Controls->m_MaxTranslationBoxZ->setValue(parameters.m_SignalGen.m_Translation[2]);
+ m_Controls->m_MaxRotationBoxX->setValue(parameters.m_SignalGen.m_Rotation[0]);
+ m_Controls->m_MaxRotationBoxY->setValue(parameters.m_SignalGen.m_Rotation[1]);
+ m_Controls->m_MaxRotationBoxZ->setValue(parameters.m_SignalGen.m_Rotation[2]);
+ m_Controls->m_DiffusionDirectionBox->setCurrentIndex(parameters.m_SignalGen.m_DiffusionDirectionMode);
+ m_Controls->m_SeparationAngleBox->setValue(parameters.m_SignalGen.m_FiberSeparationThreshold);
+
+ m_Controls->m_Compartment1Box->setCurrentIndex(0);
+ m_Controls->m_Compartment2Box->setCurrentIndex(0);
+ m_Controls->m_Compartment3Box->setCurrentIndex(0);
+ m_Controls->m_Compartment4Box->setCurrentIndex(0);
+
+ for (unsigned int i=0; i<parameters.m_FiberModelList.size()+parameters.m_NonFiberModelList.size(); i++)
+ {
+ mitk::DiffusionSignalModel<ScalarType>* signalModel = NULL;
+ if (i<parameters.m_FiberModelList.size())
+ signalModel = parameters.m_FiberModelList.at(i);
+ else
+ signalModel = parameters.m_NonFiberModelList.at(i-parameters.m_FiberModelList.size());
+
+ switch (signalModel->m_CompartmentId)
{
- m_Controls->m_RealTimeFibers->setChecked(v1.second.get<bool>("realtime"));
- m_Controls->m_AdvancedOptionsBox->setChecked(v1.second.get<bool>("showadvanced"));
- m_Controls->m_DistributionBox->setCurrentIndex(v1.second.get<int>("distribution"));
- m_Controls->m_VarianceBox->setValue(v1.second.get<double>("variance"));
- m_Controls->m_FiberDensityBox->setValue(v1.second.get<int>("density"));
- m_Controls->m_IncludeFiducials->setChecked(v1.second.get<bool>("includeFiducials"));
- m_Controls->m_ConstantRadiusBox->setChecked(v1.second.get<bool>("constantradius"));
-
- BOOST_FOREACH( boost::property_tree::ptree::value_type const& v2, v1.second )
+ case 1:
+ {
+ if (dynamic_cast<mitk::StickModel<>*>(signalModel))
{
- if( v2.first == "spline" )
- {
- m_Controls->m_FiberSamplingBox->setValue(v2.second.get<double>("sampling"));
- m_Controls->m_TensionBox->setValue(v2.second.get<double>("tension"));
- m_Controls->m_ContinuityBox->setValue(v2.second.get<double>("continuity"));
- m_Controls->m_BiasBox->setValue(v2.second.get<double>("bias"));
- }
- if( v2.first == "rotation" )
- {
- m_Controls->m_XrotBox->setValue(v2.second.get<double>("x"));
- m_Controls->m_YrotBox->setValue(v2.second.get<double>("y"));
- m_Controls->m_ZrotBox->setValue(v2.second.get<double>("z"));
- }
- if( v2.first == "translation" )
- {
- m_Controls->m_XtransBox->setValue(v2.second.get<double>("x"));
- m_Controls->m_YtransBox->setValue(v2.second.get<double>("y"));
- m_Controls->m_ZtransBox->setValue(v2.second.get<double>("z"));
- }
- if( v2.first == "scale" )
- {
- m_Controls->m_XscaleBox->setValue(v2.second.get<double>("x"));
- m_Controls->m_YscaleBox->setValue(v2.second.get<double>("y"));
- m_Controls->m_ZscaleBox->setValue(v2.second.get<double>("z"));
- }
+ mitk::StickModel<>* model = dynamic_cast<mitk::StickModel<>*>(signalModel);
+ m_Controls->m_StickWidget1->SetT2(model->GetT2());
+ m_Controls->m_StickWidget1->SetD(model->GetDiffusivity());
+ m_Controls->m_Compartment1Box->setCurrentIndex(0);
+ break;
+ }
+ else if (dynamic_cast<mitk::TensorModel<>*>(signalModel))
+ {
+ mitk::TensorModel<>* model = dynamic_cast<mitk::TensorModel<>*>(signalModel);
+ m_Controls->m_TensorWidget1->SetT2(model->GetT2());
+ m_Controls->m_TensorWidget1->SetD1(model->GetDiffusivity1());
+ m_Controls->m_TensorWidget1->SetD2(model->GetDiffusivity1());
+ m_Controls->m_TensorWidget1->SetD3(model->GetDiffusivity1());
+ m_Controls->m_Compartment1Box->setCurrentIndex(2);
+ break;
}
+ else if (dynamic_cast<mitk::RawShModel<>*>(signalModel))
+ {
+ mitk::RawShModel<>* model = dynamic_cast<mitk::RawShModel<>*>(signalModel);
+ m_Controls->m_PrototypeWidget1->SetNumberOfSamples(model->GetMaxNumKernels());
+ m_Controls->m_PrototypeWidget1->SetMinFa(model->GetFaRange().first);
+ m_Controls->m_PrototypeWidget1->SetMaxFa(model->GetFaRange().second);
+ m_Controls->m_PrototypeWidget1->SetMinAdc(model->GetAdcRange().first);
+ m_Controls->m_PrototypeWidget1->SetMaxAdc(model->GetAdcRange().second);
+ m_Controls->m_Compartment1Box->setCurrentIndex(3);
+ break;
+ }
+ break;
}
- if( v1.first == "image" )
+ case 2:
{
- m_Controls->m_SizeX->setValue(v1.second.get<int>("basic.size.x"));
- m_Controls->m_SizeY->setValue(v1.second.get<int>("basic.size.y"));
- m_Controls->m_SizeZ->setValue(v1.second.get<int>("basic.size.z"));
- m_Controls->m_SpacingX->setValue(v1.second.get<double>("basic.spacing.x"));
- m_Controls->m_SpacingY->setValue(v1.second.get<double>("basic.spacing.y"));
- m_Controls->m_SpacingZ->setValue(v1.second.get<double>("basic.spacing.z"));
- m_Controls->m_NumGradientsBox->setValue(v1.second.get<int>("basic.numgradients"));
- m_Controls->m_BvalueBox->setValue(v1.second.get<int>("basic.bvalue"));
- m_Controls->m_AdvancedOptionsBox_2->setChecked(v1.second.get<bool>("showadvanced"));
- m_Controls->m_SignalScaleBox->setValue(v1.second.get<int>("signalScale"));
- m_Controls->m_TEbox->setValue(v1.second.get<double>("tEcho"));
- m_Controls->m_LineReadoutTimeBox->setValue(v1.second.get<double>("tLine"));
- m_Controls->m_T2starBox->setValue(v1.second.get<double>("tInhom"));
- m_Controls->m_FiberRadius->setValue(v1.second.get<double>("axonRadius"));
- m_Controls->m_RelaxationBox->setChecked(v1.second.get<bool>("doSimulateRelaxation"));
- m_Controls->m_EnforcePureFiberVoxelsBox->setChecked(v1.second.get<bool>("doDisablePartialVolume"));
- m_Controls->m_VolumeFractionsBox->setChecked(v1.second.get<bool>("outputvolumefractions"));
-
- m_Controls->m_AddNoise->setChecked(v1.second.get<bool>("artifacts.addnoise"));
- m_Controls->m_NoiseDistributionBox->setCurrentIndex(v1.second.get<int>("artifacts.noisedistribution"));
- m_Controls->m_NoiseLevel->setValue(v1.second.get<double>("artifacts.noisevariance"));
- m_Controls->m_AddGhosts->setChecked(v1.second.get<bool>("artifacts.addghost"));
- m_Controls->m_kOffsetBox->setValue(v1.second.get<double>("artifacts.kspaceLineOffset"));
- m_Controls->m_AddAliasing->setChecked(v1.second.get<bool>("artifacts.addaliasing"));
- m_Controls->m_WrapBox->setValue(v1.second.get<double>("artifacts.aliasingfactor"));
- m_Controls->m_AddDistortions->setChecked(v1.second.get<bool>("artifacts.distortions"));
- m_Controls->m_AddSpikes->setChecked(v1.second.get<bool>("artifacts.addspikes"));
- m_Controls->m_SpikeNumBox->setValue(v1.second.get<int>("artifacts.spikesnum"));
- m_Controls->m_SpikeScaleBox->setValue(v1.second.get<double>("artifacts.spikesscale"));
- m_Controls->m_AddEddy->setChecked(v1.second.get<bool>("artifacts.addeddy"));
- m_Controls->m_EddyGradientStrength->setValue(v1.second.get<double>("artifacts.eddyStrength"));
- m_Controls->m_AddGibbsRinging->setChecked(v1.second.get<bool>("artifacts.addringing"));
- m_Controls->m_AddMotion->setChecked(v1.second.get<bool>("artifacts.doAddMotion"));
- m_Controls->m_RandomMotion->setChecked(v1.second.get<bool>("artifacts.randomMotion"));
- m_Controls->m_MaxTranslationBoxX->setValue(v1.second.get<double>("artifacts.translation0"));
- m_Controls->m_MaxTranslationBoxY->setValue(v1.second.get<double>("artifacts.translation1"));
- m_Controls->m_MaxTranslationBoxZ->setValue(v1.second.get<double>("artifacts.translation2"));
- m_Controls->m_MaxRotationBoxX->setValue(v1.second.get<double>("artifacts.rotation0"));
- m_Controls->m_MaxRotationBoxY->setValue(v1.second.get<double>("artifacts.rotation1"));
- m_Controls->m_MaxRotationBoxZ->setValue(v1.second.get<double>("artifacts.rotation2"));
-
- m_Controls->m_Compartment1Box->setCurrentIndex(v1.second.get<int>("compartment1.index"));
- m_Controls->m_Compartment2Box->setCurrentIndex(v1.second.get<int>("compartment2.index"));
- m_Controls->m_Compartment3Box->setCurrentIndex(v1.second.get<int>("compartment3.index"));
- m_Controls->m_Compartment4Box->setCurrentIndex(v1.second.get<int>("compartment4.index"));
-
- m_Controls->m_StickWidget1->SetD(v1.second.get<double>("compartment1.stick.d"));
- m_Controls->m_StickWidget1->SetT2(v1.second.get<double>("compartment1.stick.t2"));
- m_Controls->m_ZeppelinWidget1->SetD1(v1.second.get<double>("compartment1.zeppelin.d1"));
- m_Controls->m_ZeppelinWidget1->SetD2(v1.second.get<double>("compartment1.zeppelin.d2"));
- m_Controls->m_ZeppelinWidget1->SetT2(v1.second.get<double>("compartment1.zeppelin.t2"));
- m_Controls->m_TensorWidget1->SetD1(v1.second.get<double>("compartment1.tensor.d1"));
- m_Controls->m_TensorWidget1->SetD2(v1.second.get<double>("compartment1.tensor.d2"));
- m_Controls->m_TensorWidget1->SetD3(v1.second.get<double>("compartment1.tensor.d3"));
- m_Controls->m_TensorWidget1->SetT2(v1.second.get<double>("compartment1.tensor.t2"));
- m_Controls->m_PrototypeWidget1->SetMinFa(v1.second.get<double>("compartment1.prototype.minFA"));
- m_Controls->m_PrototypeWidget1->SetMaxFa(v1.second.get<double>("compartment1.prototype.maxFA"));
- m_Controls->m_PrototypeWidget1->SetMinAdc(v1.second.get<double>("compartment1.prototype.minADC"));
- m_Controls->m_PrototypeWidget1->SetMaxAdc(v1.second.get<double>("compartment1.prototype.maxADC"));
- m_Controls->m_PrototypeWidget1->SetNumberOfSamples(v1.second.get<double>("compartment1.prototype.numSamples"));
-
- m_Controls->m_StickWidget2->SetD(v1.second.get<double>("compartment2.stick.d"));
- m_Controls->m_StickWidget2->SetT2(v1.second.get<double>("compartment2.stick.t2"));
- m_Controls->m_ZeppelinWidget2->SetD1(v1.second.get<double>("compartment2.zeppelin.d1"));
- m_Controls->m_ZeppelinWidget2->SetD2(v1.second.get<double>("compartment2.zeppelin.d2"));
- m_Controls->m_ZeppelinWidget2->SetT2(v1.second.get<double>("compartment2.zeppelin.t2"));
- m_Controls->m_TensorWidget2->SetD1(v1.second.get<double>("compartment2.tensor.d1"));
- m_Controls->m_TensorWidget2->SetD2(v1.second.get<double>("compartment2.tensor.d2"));
- m_Controls->m_TensorWidget2->SetD3(v1.second.get<double>("compartment2.tensor.d3"));
- m_Controls->m_TensorWidget2->SetT2(v1.second.get<double>("compartment2.tensor.t2"));
-
- m_Controls->m_BallWidget1->SetD(v1.second.get<double>("compartment3.ball.d"));
- m_Controls->m_BallWidget1->SetT2(v1.second.get<double>("compartment3.ball.t2"));
- m_Controls->m_AstrosticksWidget1->SetD(v1.second.get<double>("compartment3.astrosticks.d"));
- m_Controls->m_AstrosticksWidget1->SetT2(v1.second.get<double>("compartment3.astrosticks.t2"));
- m_Controls->m_AstrosticksWidget1->SetRandomizeSticks(v1.second.get<bool>("compartment3.astrosticks.randomize"));
- m_Controls->m_DotWidget1->SetT2(v1.second.get<double>("compartment3.dot.t2"));
- m_Controls->m_PrototypeWidget3->SetMinFa(v1.second.get<double>("compartment3.prototype.minFA"));
- m_Controls->m_PrototypeWidget3->SetMaxFa(v1.second.get<double>("compartment3.prototype.maxFA"));
- m_Controls->m_PrototypeWidget3->SetMinAdc(v1.second.get<double>("compartment3.prototype.minADC"));
- m_Controls->m_PrototypeWidget3->SetMaxAdc(v1.second.get<double>("compartment3.prototype.maxADC"));
- m_Controls->m_PrototypeWidget3->SetNumberOfSamples(v1.second.get<double>("compartment3.prototype.numSamples"));
-
- m_Controls->m_BallWidget2->SetD(v1.second.get<double>("compartment4.ball.d"));
- m_Controls->m_BallWidget2->SetT2(v1.second.get<double>("compartment4.ball.t2"));
- m_Controls->m_AstrosticksWidget2->SetD(v1.second.get<double>("compartment4.astrosticks.d"));
- m_Controls->m_AstrosticksWidget2->SetT2(v1.second.get<double>("compartment4.astrosticks.t2"));
- m_Controls->m_AstrosticksWidget2->SetRandomizeSticks(v1.second.get<bool>("compartment4.astrosticks.randomize"));
- m_Controls->m_DotWidget2->SetT2(v1.second.get<double>("compartment4.dot.t2"));
- m_Controls->m_PrototypeWidget4->SetMinFa(v1.second.get<double>("compartment4.prototype.minFA"));
- m_Controls->m_PrototypeWidget4->SetMaxFa(v1.second.get<double>("compartment4.prototype.maxFA"));
- m_Controls->m_PrototypeWidget4->SetMinAdc(v1.second.get<double>("compartment4.prototype.minADC"));
- m_Controls->m_PrototypeWidget4->SetMaxAdc(v1.second.get<double>("compartment4.prototype.maxADC"));
- m_Controls->m_PrototypeWidget4->SetNumberOfSamples(v1.second.get<double>("compartment4.prototype.numSamples"));
+ if (dynamic_cast<mitk::StickModel<>*>(signalModel))
+ {
+ mitk::StickModel<>* model = dynamic_cast<mitk::StickModel<>*>(signalModel);
+ m_Controls->m_StickWidget2->SetT2(model->GetT2());
+ m_Controls->m_StickWidget2->SetD(model->GetDiffusivity());
+ m_Controls->m_Compartment2Box->setCurrentIndex(1);
+ break;
+ }
+ else if (dynamic_cast<mitk::TensorModel<>*>(signalModel))
+ {
+ mitk::TensorModel<>* model = dynamic_cast<mitk::TensorModel<>*>(signalModel);
+ m_Controls->m_TensorWidget2->SetT2(model->GetT2());
+ m_Controls->m_TensorWidget2->SetD1(model->GetDiffusivity1());
+ m_Controls->m_TensorWidget2->SetD2(model->GetDiffusivity1());
+ m_Controls->m_TensorWidget2->SetD3(model->GetDiffusivity1());
+ m_Controls->m_Compartment2Box->setCurrentIndex(3);
+ break;
+ }
+ break;
+ }
+ case 3:
+ {
+ if (dynamic_cast<mitk::BallModel<>*>(signalModel))
+ {
+ mitk::BallModel<>* model = dynamic_cast<mitk::BallModel<>*>(signalModel);
+ m_Controls->m_BallWidget1->SetT2(model->GetT2());
+ m_Controls->m_BallWidget1->SetD(model->GetDiffusivity());
+ m_Controls->m_Compartment3Box->setCurrentIndex(0);
+ break;
+ }
+ else if (dynamic_cast<mitk::AstroStickModel<>*>(signalModel))
+ {
+ mitk::AstroStickModel<>* model = dynamic_cast<mitk::AstroStickModel<>*>(signalModel);
+ m_Controls->m_AstrosticksWidget1->SetT2(model->GetT2());
+ m_Controls->m_AstrosticksWidget1->SetD(model->GetDiffusivity());
+ m_Controls->m_AstrosticksWidget1->SetRandomizeSticks(model->GetRandomizeSticks());
+ m_Controls->m_Compartment3Box->setCurrentIndex(1);
+ break;
+ }
+ else if (dynamic_cast<mitk::DotModel<>*>(signalModel))
+ {
+ mitk::DotModel<>* model = dynamic_cast<mitk::DotModel<>*>(signalModel);
+ m_Controls->m_DotWidget1->SetT2(model->GetT2());
+ m_Controls->m_Compartment3Box->setCurrentIndex(2);
+ break;
+ }
+ else if (dynamic_cast<mitk::RawShModel<>*>(signalModel))
+ {
+ mitk::RawShModel<>* model = dynamic_cast<mitk::RawShModel<>*>(signalModel);
+ m_Controls->m_PrototypeWidget3->SetNumberOfSamples(model->GetMaxNumKernels());
+ m_Controls->m_PrototypeWidget3->SetMinFa(model->GetFaRange().first);
+ m_Controls->m_PrototypeWidget3->SetMaxFa(model->GetFaRange().second);
+ m_Controls->m_PrototypeWidget3->SetMinAdc(model->GetAdcRange().first);
+ m_Controls->m_PrototypeWidget3->SetMaxAdc(model->GetAdcRange().second);
+ m_Controls->m_Compartment3Box->setCurrentIndex(3);
+ break;
+ }
+ break;
+ }
+ case 4:
+ {
+ if (dynamic_cast<mitk::BallModel<>*>(signalModel))
+ {
+ mitk::BallModel<>* model = dynamic_cast<mitk::BallModel<>*>(signalModel);
+ m_Controls->m_BallWidget2->SetT2(model->GetT2());
+ m_Controls->m_BallWidget2->SetD(model->GetDiffusivity());
+ m_Controls->m_Compartment4Box->setCurrentIndex(1);
+ break;
+ }
+ else if (dynamic_cast<mitk::AstroStickModel<>*>(signalModel))
+ {
+ mitk::AstroStickModel<>* model = dynamic_cast<mitk::AstroStickModel<>*>(signalModel);
+ m_Controls->m_AstrosticksWidget2->SetT2(model->GetT2());
+ m_Controls->m_AstrosticksWidget2->SetD(model->GetDiffusivity());
+ m_Controls->m_AstrosticksWidget2->SetRandomizeSticks(model->GetRandomizeSticks());
+ m_Controls->m_Compartment4Box->setCurrentIndex(2);
+ break;
+ }
+ else if (dynamic_cast<mitk::DotModel<>*>(signalModel))
+ {
+ mitk::DotModel<>* model = dynamic_cast<mitk::DotModel<>*>(signalModel);
+ m_Controls->m_DotWidget2->SetT2(model->GetT2());
+ m_Controls->m_Compartment4Box->setCurrentIndex(3);
+ break;
+ }
+ else if (dynamic_cast<mitk::RawShModel<>*>(signalModel))
+ {
+ mitk::RawShModel<>* model = dynamic_cast<mitk::RawShModel<>*>(signalModel);
+ m_Controls->m_PrototypeWidget4->SetNumberOfSamples(model->GetMaxNumKernels());
+ m_Controls->m_PrototypeWidget4->SetMinFa(model->GetFaRange().first);
+ m_Controls->m_PrototypeWidget4->SetMaxFa(model->GetFaRange().second);
+ m_Controls->m_PrototypeWidget4->SetMinAdc(model->GetAdcRange().first);
+ m_Controls->m_PrototypeWidget4->SetMaxAdc(model->GetAdcRange().second);
+ m_Controls->m_Compartment4Box->setCurrentIndex(4);
+ break;
+ }
+ break;
+ }
}
}
}
void QmitkFiberfoxView::ShowAdvancedOptions(int state)
{
if (state)
{
m_Controls->m_AdvancedFiberOptionsFrame->setVisible(true);
m_Controls->m_AdvancedSignalOptionsFrame->setVisible(true);
m_Controls->m_AdvancedOptionsBox->setChecked(true);
m_Controls->m_AdvancedOptionsBox_2->setChecked(true);
}
else
{
m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false);
m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false);
m_Controls->m_AdvancedOptionsBox->setChecked(false);
m_Controls->m_AdvancedOptionsBox_2->setChecked(false);
}
}
void QmitkFiberfoxView::Comp1ModelFrameVisibility(int index)
{
m_Controls->m_StickWidget1->setVisible(false);
m_Controls->m_ZeppelinWidget1->setVisible(false);
m_Controls->m_TensorWidget1->setVisible(false);
m_Controls->m_PrototypeWidget1->setVisible(false);
switch (index)
{
case 0:
m_Controls->m_StickWidget1->setVisible(true);
break;
case 1:
m_Controls->m_ZeppelinWidget1->setVisible(true);
break;
case 2:
m_Controls->m_TensorWidget1->setVisible(true);
break;
case 3:
m_Controls->m_PrototypeWidget1->setVisible(true);
break;
}
}
void QmitkFiberfoxView::Comp2ModelFrameVisibility(int index)
{
m_Controls->m_StickWidget2->setVisible(false);
m_Controls->m_ZeppelinWidget2->setVisible(false);
m_Controls->m_TensorWidget2->setVisible(false);
switch (index)
{
case 0:
break;
case 1:
m_Controls->m_StickWidget2->setVisible(true);
break;
case 2:
m_Controls->m_ZeppelinWidget2->setVisible(true);
break;
case 3:
m_Controls->m_TensorWidget2->setVisible(true);
break;
}
}
void QmitkFiberfoxView::Comp3ModelFrameVisibility(int index)
{
m_Controls->m_BallWidget1->setVisible(false);
m_Controls->m_AstrosticksWidget1->setVisible(false);
m_Controls->m_DotWidget1->setVisible(false);
m_Controls->m_PrototypeWidget3->setVisible(false);
switch (index)
{
case 0:
m_Controls->m_BallWidget1->setVisible(true);
break;
case 1:
m_Controls->m_AstrosticksWidget1->setVisible(true);
break;
case 2:
m_Controls->m_DotWidget1->setVisible(true);
break;
case 3:
m_Controls->m_PrototypeWidget3->setVisible(true);
break;
}
}
void QmitkFiberfoxView::Comp4ModelFrameVisibility(int index)
{
m_Controls->m_BallWidget2->setVisible(false);
m_Controls->m_AstrosticksWidget2->setVisible(false);
m_Controls->m_DotWidget2->setVisible(false);
m_Controls->m_PrototypeWidget4->setVisible(false);
m_Controls->m_Comp4FractionFrame->setVisible(false);
switch (index)
{
case 0:
break;
case 1:
m_Controls->m_BallWidget2->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
case 2:
m_Controls->m_AstrosticksWidget2->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
case 3:
m_Controls->m_DotWidget2->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
case 4:
m_Controls->m_PrototypeWidget4->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
}
}
void QmitkFiberfoxView::OnConstantRadius(int value)
{
if (value>0 && m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnAddMotion(int value)
{
if (value>0)
m_Controls->m_MotionArtifactFrame->setVisible(true);
else
m_Controls->m_MotionArtifactFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddAliasing(int value)
{
if (value>0)
m_Controls->m_AliasingFrame->setVisible(true);
else
m_Controls->m_AliasingFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddSpikes(int value)
{
if (value>0)
m_Controls->m_SpikeFrame->setVisible(true);
else
m_Controls->m_SpikeFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddEddy(int value)
{
if (value>0)
m_Controls->m_EddyFrame->setVisible(true);
else
m_Controls->m_EddyFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddDistortions(int value)
{
if (value>0)
m_Controls->m_DistortionsFrame->setVisible(true);
else
m_Controls->m_DistortionsFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddGhosts(int value)
{
if (value>0)
m_Controls->m_GhostFrame->setVisible(true);
else
m_Controls->m_GhostFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddNoise(int value)
{
if (value>0)
m_Controls->m_NoiseFrame->setVisible(true);
else
m_Controls->m_NoiseFrame->setVisible(false);
}
void QmitkFiberfoxView::OnDistributionChanged(int value)
{
if (value==1)
m_Controls->m_VarianceBox->setVisible(true);
else
m_Controls->m_VarianceBox->setVisible(false);
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnVarianceChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnFiberDensityChanged(int)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnFiberSamplingChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnTensionChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnContinuityChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnBiasChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::AlignOnGrid()
{
for (unsigned int i=0; i<m_SelectedFiducials.size(); i++)
{
mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(m_SelectedFiducials.at(i)->GetData());
mitk::Point3D wc0 = pe->GetWorldControlPoint(0);
mitk::DataStorage::SetOfObjects::ConstPointer parentFibs = GetDataStorage()->GetSources(m_SelectedFiducials.at(i));
for( mitk::DataStorage::SetOfObjects::const_iterator it = parentFibs->begin(); it != parentFibs->end(); ++it )
{
mitk::DataNode::Pointer pFibNode = *it;
if ( pFibNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(pFibNode->GetData()) )
{
mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(pFibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 )
{
mitk::DataNode::Pointer pImgNode = *it2;
if ( pImgNode.IsNotNull() && dynamic_cast<mitk::Image*>(pImgNode->GetData()) )
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(pImgNode->GetData());
mitk::BaseGeometry::Pointer geom = img->GetGeometry();
itk::Index<3> idx;
geom->WorldToIndex(wc0, idx);
mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2];
mitk::Point3D world;
geom->IndexToWorld(cIdx,world);
mitk::Vector3D trans = world - wc0;
pe->GetGeometry()->Translate(trans);
break;
}
}
break;
}
}
}
for(unsigned int i=0; i<m_SelectedBundles2.size(); i++ )
{
mitk::DataNode::Pointer fibNode = m_SelectedBundles2.at(i);
mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(fibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it = sources->begin(); it != sources->end(); ++it )
{
mitk::DataNode::Pointer imgNode = *it;
if ( imgNode.IsNotNull() && dynamic_cast<mitk::Image*>(imgNode->GetData()) )
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(fibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData());
mitk::Point3D wc0 = pe->GetWorldControlPoint(0);
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(imgNode->GetData());
mitk::BaseGeometry::Pointer geom = img->GetGeometry();
itk::Index<3> idx;
geom->WorldToIndex(wc0, idx);
mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2];
mitk::Point3D world;
geom->IndexToWorld(cIdx,world);
mitk::Vector3D trans = world - wc0;
pe->GetGeometry()->Translate(trans);
}
}
break;
}
}
}
for(unsigned int i=0; i<m_SelectedImages.size(); i++ )
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(m_SelectedImages.at(i)->GetData());
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(m_SelectedImages.at(i));
for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it )
{
mitk::DataNode::Pointer fibNode = *it;
if ( fibNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(fibNode->GetData()) )
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations2 = GetDataStorage()->GetDerivations(fibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations2->begin(); it2 != derivations2->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData());
mitk::Point3D wc0 = pe->GetWorldControlPoint(0);
mitk::BaseGeometry::Pointer geom = img->GetGeometry();
itk::Index<3> idx;
geom->WorldToIndex(wc0, idx);
mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2];
mitk::Point3D world;
geom->IndexToWorld(cIdx,world);
mitk::Vector3D trans = world - wc0;
pe->GetGeometry()->Translate(trans);
}
}
}
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnFlipButton()
{
if (m_SelectedFiducial.IsNull())
return;
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it = m_DataNodeToPlanarFigureData.find(m_SelectedFiducial.GetPointer());
if( it != m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
data.m_Flipped += 1;
data.m_Flipped %= 2;
}
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
QmitkFiberfoxView::GradientListType QmitkFiberfoxView::GenerateHalfShell(int NPoints)
{
NPoints *= 2;
GradientListType pointshell;
int numB0 = NPoints/20;
if (numB0==0)
numB0=1;
GradientType g;
g.Fill(0.0);
for (int i=0; i<numB0; i++)
pointshell.push_back(g);
if (NPoints==0)
return pointshell;
vnl_vector<double> theta; theta.set_size(NPoints);
vnl_vector<double> phi; phi.set_size(NPoints);
double C = sqrt(4*M_PI);
phi(0) = 0.0;
phi(NPoints-1) = 0.0;
for(int i=0; i<NPoints; i++)
{
theta(i) = acos(-1.0+2.0*i/(NPoints-1.0)) - M_PI / 2.0;
if( i>0 && i<NPoints-1)
{
phi(i) = (phi(i-1) + C /
sqrt(NPoints*(1-(-1.0+2.0*i/(NPoints-1.0))*(-1.0+2.0*i/(NPoints-1.0)))));
// % (2*DIST_POINTSHELL_PI);
}
}
for(int i=0; i<NPoints; i++)
{
g[2] = sin(theta(i));
if (g[2]<0)
continue;
g[0] = cos(theta(i)) * cos(phi(i));
g[1] = cos(theta(i)) * sin(phi(i));
pointshell.push_back(g);
}
return pointshell;
}
template<int ndirs>
std::vector<itk::Vector<double,3> > QmitkFiberfoxView::MakeGradientList()
{
std::vector<itk::Vector<double,3> > retval;
vnl_matrix_fixed<double, 3, ndirs>* U =
itk::PointShell<ndirs, vnl_matrix_fixed<double, 3, ndirs> >::DistributePointShell();
// Add 0 vector for B0
int numB0 = ndirs/10;
if (numB0==0)
numB0=1;
itk::Vector<double,3> v;
v.Fill(0.0);
for (int i=0; i<numB0; i++)
{
retval.push_back(v);
}
for(int i=0; i<ndirs;i++)
{
itk::Vector<double,3> v;
v[0] = U->get(0,i); v[1] = U->get(1,i); v[2] = U->get(2,i);
retval.push_back(v);
}
return retval;
}
void QmitkFiberfoxView::OnAddBundle()
{
if (m_SelectedImage.IsNull())
return;
mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedImage);
mitk::FiberBundleX::Pointer bundle = mitk::FiberBundleX::New();
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( bundle );
QString name = QString("Bundle_%1").arg(children->size());
node->SetName(name.toStdString());
m_SelectedBundles.push_back(node);
UpdateGui();
GetDataStorage()->Add(node, m_SelectedImage);
}
void QmitkFiberfoxView::OnDrawROI()
{
if (m_SelectedBundles.empty())
OnAddBundle();
if (m_SelectedBundles.empty())
return;
mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedBundles.at(0));
mitk::PlanarEllipse::Pointer figure = mitk::PlanarEllipse::New();
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( figure );
node->SetBoolProperty("planarfigure.3drendering", true);
QList<mitk::DataNode::Pointer> nodes = this->GetDataManagerSelection();
for( int i=0; i<nodes.size(); i++)
nodes.at(i)->SetSelected(false);
m_SelectedFiducial = node;
QString name = QString("Fiducial_%1").arg(children->size());
node->SetName(name.toStdString());
node->SetSelected(true);
this->DisableCrosshairNavigation();
mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( node );
}
UpdateGui();
GetDataStorage()->Add(node, m_SelectedBundles.at(0));
}
bool CompareLayer(mitk::DataNode::Pointer i,mitk::DataNode::Pointer j)
{
int li = -1;
i->GetPropertyValue("layer", li);
int lj = -1;
j->GetPropertyValue("layer", lj);
return li<lj;
}
void QmitkFiberfoxView::GenerateFibers()
{
if (m_SelectedBundles.empty())
{
if (m_SelectedFiducial.IsNull())
return;
mitk::DataStorage::SetOfObjects::ConstPointer parents = GetDataStorage()->GetSources(m_SelectedFiducial);
for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it )
if(dynamic_cast<mitk::FiberBundleX*>((*it)->GetData()))
m_SelectedBundles.push_back(*it);
if (m_SelectedBundles.empty())
return;
}
- vector< vector< mitk::PlanarEllipse::Pointer > > fiducials;
- vector< vector< unsigned int > > fliplist;
+ FiberfoxParameters<double> parameters = UpdateImageParameters<double>();
+
for (unsigned int i=0; i<m_SelectedBundles.size(); i++)
{
mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedBundles.at(i));
std::vector< mitk::DataNode::Pointer > childVector;
for( mitk::DataStorage::SetOfObjects::const_iterator it = children->begin(); it != children->end(); ++it )
childVector.push_back(*it);
sort(childVector.begin(), childVector.end(), CompareLayer);
vector< mitk::PlanarEllipse::Pointer > fib;
vector< unsigned int > flip;
float radius = 1;
int count = 0;
for( std::vector< mitk::DataNode::Pointer >::const_iterator it = childVector.begin(); it != childVector.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if ( node.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(node->GetData()) )
{
mitk::PlanarEllipse* ellipse = dynamic_cast<mitk::PlanarEllipse*>(node->GetData());
if (m_Controls->m_ConstantRadiusBox->isChecked())
{
ellipse->SetTreatAsCircle(true);
mitk::Point2D c = ellipse->GetControlPoint(0);
mitk::Point2D p = ellipse->GetControlPoint(1);
mitk::Vector2D v = p-c;
if (count==0)
{
radius = v.GetVnlVector().magnitude();
ellipse->SetControlPoint(1, p);
}
else
{
v.Normalize();
v *= radius;
ellipse->SetControlPoint(1, c+v);
}
}
fib.push_back(ellipse);
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it = m_DataNodeToPlanarFigureData.find(node.GetPointer());
if( it != m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
flip.push_back(data.m_Flipped);
}
else
flip.push_back(0);
}
count++;
}
if (fib.size()>1)
{
- fiducials.push_back(fib);
- fliplist.push_back(flip);
+ parameters.m_FiberGen.m_Fiducials.push_back(fib);
+ parameters.m_FiberGen.m_FlipList.push_back(flip);
}
else if (fib.size()>0)
m_SelectedBundles.at(i)->SetData( mitk::FiberBundleX::New() );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New();
- filter->SetFiducials(fiducials);
- filter->SetFlipList(fliplist);
-
- switch(m_Controls->m_DistributionBox->currentIndex()){
- case 0:
- filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_UNIFORM);
- break;
- case 1:
- filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_GAUSSIAN);
- filter->SetVariance(m_Controls->m_VarianceBox->value());
- break;
- }
-
- filter->SetDensity(m_Controls->m_FiberDensityBox->value());
- filter->SetTension(m_Controls->m_TensionBox->value());
- filter->SetContinuity(m_Controls->m_ContinuityBox->value());
- filter->SetBias(m_Controls->m_BiasBox->value());
- filter->SetFiberSampling(m_Controls->m_FiberSamplingBox->value());
+ filter->SetParameters(parameters.m_FiberGen);
filter->Update();
vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles();
for (unsigned int i=0; i<fiberBundles.size(); i++)
{
m_SelectedBundles.at(i)->SetData( fiberBundles.at(i) );
if (fiberBundles.at(i)->GetNumFibers()>50000)
m_SelectedBundles.at(i)->SetVisibility(false);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::GenerateImage()
{
if (m_SelectedBundles.empty() && m_SelectedDWI.IsNull())
{
mitk::Image::Pointer image = mitk::ImageGenerator::GenerateGradientImage<unsigned int>(
m_Controls->m_SizeX->value(),
m_Controls->m_SizeY->value(),
m_Controls->m_SizeZ->value(),
m_Controls->m_SpacingX->value(),
m_Controls->m_SpacingY->value(),
m_Controls->m_SpacingZ->value());
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( image );
node->SetName("Dummy");
unsigned int window = m_Controls->m_SizeX->value()*m_Controls->m_SizeY->value()*m_Controls->m_SizeZ->value();
unsigned int level = window/2;
mitk::LevelWindow lw; lw.SetLevelWindow(level, window);
node->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) );
GetDataStorage()->Add(node);
m_SelectedImage = node;
mitk::BaseData::Pointer basedata = node->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
UpdateGui();
}
else if (!m_SelectedBundles.empty())
SimulateImageFromFibers(m_SelectedBundles.at(0));
else if (m_SelectedDWI.IsNotNull())
SimulateForExistingDwi(m_SelectedDWI);
}
void QmitkFiberfoxView::SimulateForExistingDwi(mitk::DataNode* imageNode)
{
if (!dynamic_cast<mitk::DiffusionImage<short>*>(imageNode->GetData()))
return;
FiberfoxParameters<short> parameters = UpdateImageParameters<short>();
if (parameters.m_NoiseModel==NULL &&
- parameters.m_Spikes==0 &&
- parameters.m_FrequencyMap.IsNull() &&
- parameters.m_KspaceLineOffset<=0.000001 &&
- !parameters.m_DoAddGibbsRinging &&
- !(parameters.m_EddyStrength>0) &&
- parameters.m_CroppingFactor>0.999)
+ parameters.m_SignalGen.m_Spikes==0 &&
+ parameters.m_SignalGen.m_FrequencyMap.IsNull() &&
+ parameters.m_SignalGen.m_KspaceLineOffset<=0.000001 &&
+ !parameters.m_SignalGen.m_DoAddGibbsRinging &&
+ !(parameters.m_SignalGen.m_EddyStrength>0) &&
+ parameters.m_SignalGen.m_CroppingFactor>0.999)
{
QMessageBox::information( NULL, "Simulation cancelled", "No valid artifact enabled! Motion artifacts and relaxation effects can NOT be added to an existing diffusion weighted image.");
return;
}
mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(imageNode->GetData());
m_ArtifactsToDwiFilter = itk::AddArtifactsToDwiImageFilter< short >::New();
m_ArtifactsToDwiFilter->SetInput(diffImg->GetVectorImage());
- parameters.m_ParentNode = imageNode;
+ parameters.m_Misc.m_ParentNode = imageNode;
m_ArtifactsToDwiFilter->SetParameters(parameters);
m_Worker.m_FilterType = 1;
m_Thread.start(QThread::LowestPriority);
}
void QmitkFiberfoxView::SimulateImageFromFibers(mitk::DataNode* fiberNode)
{
mitk::FiberBundleX::Pointer fiberBundle = dynamic_cast<mitk::FiberBundleX*>(fiberNode->GetData());
if (fiberBundle->GetNumFibers()<=0)
return;
FiberfoxParameters<double> parameters = UpdateImageParameters<double>();
m_TractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
- parameters.m_ParentNode = fiberNode;
+ parameters.m_Misc.m_ParentNode = fiberNode;
if (m_SelectedDWI.IsNotNull())
{
+ bool first = true;
+ bool ok = true;
mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(m_SelectedDWI->GetData());
+ itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = NULL;
+ const int shOrder = 2;
+ typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,shOrder,QBALL_ODFSIZE> QballFilterType;
+ QballFilterType::CoefficientImageType::Pointer itkFeatureImage = NULL;
+ ItkDoubleImgType::Pointer adcImage = NULL;
- bool doSampling = false;
- for (unsigned int i=0; i<parameters.m_FiberModelList.size(); i++)
- if ( dynamic_cast< RawShModel<double>* >(parameters.m_FiberModelList[i]) )
- doSampling = true;
- for (unsigned int i=0; i<parameters.m_NonFiberModelList.size(); i++)
- if ( dynamic_cast< RawShModel<double>* >(parameters.m_NonFiberModelList[i]) )
- doSampling = true;
-
- // sample prototype signals
- if ( doSampling )
+ for (unsigned int i=0; i<parameters.m_FiberModelList.size()+parameters.m_NonFiberModelList.size(); i++)
{
- const int shOrder = 2;
-
- typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
- TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
- filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
- filter->SetBValue(diffImg->GetReferenceBValue());
- filter->Update();
- itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = filter->GetOutput();
-
- const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder;
- typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,shOrder,QBALL_ODFSIZE> QballFilterType;
- QballFilterType::Pointer qballfilter = QballFilterType::New();
- qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
- qballfilter->SetBValue(diffImg->GetReferenceBValue());
- qballfilter->SetLambda(0.006);
- qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL);
- qballfilter->Update();
- QballFilterType::CoefficientImageType::Pointer itkFeatureImage = qballfilter->GetCoefficientImage();
-
- itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
- adcFilter->SetInput(diffImg->GetVectorImage());
- adcFilter->SetGradientDirections(diffImg->GetDirections());
- adcFilter->SetB_value(diffImg->GetReferenceBValue());
- adcFilter->Update();
- ItkDoubleImgType::Pointer adcImage = adcFilter->GetOutput();
-
- int b0Index;
- for (unsigned int i=0; i<diffImg->GetDirectionsWithoutMeasurementFrame()->Size(); i++)
- if ( diffImg->GetDirectionsWithoutMeasurementFrame()->GetElement(i).magnitude()<0.001 )
- {
- b0Index = i;
- break;
- }
-
- double max = 0;
- {
- itk::ImageRegionIterator< itk::VectorImage< short, 3 > > it(diffImg->GetVectorImage(), diffImg->GetVectorImage()->GetLargestPossibleRegion());
- while(!it.IsAtEnd())
- {
- if (parameters.m_MaskImage.IsNotNull() && parameters.m_MaskImage->GetPixel(it.GetIndex())<=0)
- {
- ++it;
- continue;
- }
- if (it.Get()[b0Index]>max)
- max = it.Get()[b0Index];
- ++it;
- }
- }
-
- MITK_INFO << "Sampling signal kernels.";
+ mitk::RawShModel<>* model = NULL;
+ if (i<parameters.m_FiberModelList.size())
+ model = dynamic_cast< mitk::RawShModel<>* >(parameters.m_FiberModelList.at(i));
+ else
+ model = dynamic_cast< mitk::RawShModel<>* >(parameters.m_NonFiberModelList.at(i-parameters.m_FiberModelList.size()));
- itk::ImageRegionIterator< itk::Image< itk::DiffusionTensor3D< double >, 3 > > it(tensorImage, tensorImage->GetLargestPossibleRegion());
- while(!it.IsAtEnd())
+ if (model!=0 && model->GetNumberOfKernels()<=0)
{
- bool skipPixel = false;
- if (parameters.m_MaskImage.IsNotNull() && parameters.m_MaskImage->GetPixel(it.GetIndex())<=0)
- {
- ++it;
- continue;
- }
- for (unsigned int i=0; i<diffImg->GetDirections()->Size(); i++)
- {
- if (diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i]!=diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i] || diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i]<=0 || diffImg->GetVectorImage()->GetPixel(it.GetIndex())[i]>diffImg->GetVectorImage()->GetPixel(it.GetIndex())[b0Index])
- {
- skipPixel = true;
- break;
- }
- }
- if (skipPixel)
- {
- ++it;
- continue;
- }
-
- typedef itk::DiffusionTensor3D<double> TensorType;
- TensorType::EigenValuesArrayType eigenvalues;
- TensorType::EigenVectorsMatrixType eigenvectors;
- TensorType tensor = it.Get();
- double FA = tensor.GetFractionalAnisotropy();
- double ADC = adcImage->GetPixel(it.GetIndex());
- QballFilterType::CoefficientImageType::PixelType itkv = itkFeatureImage->GetPixel(it.GetIndex());
- vnl_vector_fixed< double, NumCoeffs > coeffs;
- for (unsigned int c=0; c<itkv.Size(); c++)
- coeffs[c] = itkv[c]/max;
-
- for (unsigned int i=0; i<parameters.m_FiberModelList.size(); i++)
- {
- RawShModel<double>* model = dynamic_cast< RawShModel<double>* >(parameters.m_FiberModelList[i]);
- if ( model && model->GetMaxNumKernels()>model->GetNumberOfKernels() && FA>model->GetFaRange().first && FA<model->GetFaRange().second && ADC>model->GetAdcRange().first && ADC<model->GetAdcRange().second)
- {
- if (model->SetShCoefficients( coeffs, (double)diffImg->GetVectorImage()->GetPixel(it.GetIndex())[b0Index]/max ))
- {
- tensor.ComputeEigenAnalysis(eigenvalues, eigenvectors);
- itk::Vector<double,3> dir;
- dir[0] = eigenvectors(2, 0);
- dir[1] = eigenvectors(2, 1);
- dir[2] = eigenvectors(2, 2);
- model->m_PrototypeMaxDirection.push_back(dir);
- MITK_INFO << "WM KERNEL: " << it.GetIndex() << " (" << model->GetNumberOfKernels() << ")";
- }
- }
- }
- for (unsigned int i=0; i<parameters.m_NonFiberModelList.size(); i++)
+ if (first==true)
{
- RawShModel<double>* model = dynamic_cast< RawShModel<double>* >(parameters.m_NonFiberModelList[i]);
- if ( model && model->GetMaxNumKernels()>model->GetNumberOfKernels() && FA>model->GetFaRange().first && FA<model->GetFaRange().second && ADC>model->GetAdcRange().first && ADC<model->GetAdcRange().second)
- {
- if (model->SetShCoefficients( coeffs, (double)diffImg->GetVectorImage()->GetPixel(it.GetIndex())[b0Index]/max ))
- MITK_INFO << "CSF/GM KERNEL: " << it.GetIndex() << " (" << model->GetNumberOfKernels() << ")";
- }
+ typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
+ TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
+ filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
+ filter->SetBValue(diffImg->GetReferenceBValue());
+ filter->Update();
+ tensorImage = filter->GetOutput();
+
+ const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder;
+ QballFilterType::Pointer qballfilter = QballFilterType::New();
+ qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
+ qballfilter->SetBValue(diffImg->GetReferenceBValue());
+ qballfilter->SetLambda(0.006);
+ qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL);
+ qballfilter->Update();
+ itkFeatureImage = qballfilter->GetCoefficientImage();
+
+ itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
+ adcFilter->SetInput(diffImg->GetVectorImage());
+ adcFilter->SetGradientDirections(diffImg->GetDirections());
+ adcFilter->SetB_value(diffImg->GetReferenceBValue());
+ adcFilter->Update();
+ adcImage = adcFilter->GetOutput();
}
- ++it;
+ ok = model->SampleKernels(diffImg, parameters.m_SignalGen.m_MaskImage, tensorImage, itkFeatureImage, adcImage);
+ if (!ok)
+ break;
}
+ }
- for (unsigned int i=0; i<parameters.m_FiberModelList.size(); i++)
- {
- RawShModel<double>* model = dynamic_cast< RawShModel<double>* >(parameters.m_FiberModelList[i]);
- if ( model && model->GetNumberOfKernels()<=0 )
- {
- QMessageBox::information( NULL, "Simulation cancelled", "No suitable voxels found for fiber compartment "+QString::number(i));
- return;
- }
- }
- for (unsigned int i=0; i<parameters.m_NonFiberModelList.size(); i++)
- {
- RawShModel<double>* model = dynamic_cast< RawShModel<double>* >(parameters.m_NonFiberModelList[i]);
- if ( model && model->GetNumberOfKernels()<=0 )
- {
- QMessageBox::information( NULL, "Simulation cancelled", "No suitable voxels found for non-fiber compartment "+QString::number(i));
- return;
- }
- }
+ if (!ok)
+ {
+ QMessageBox::information( NULL, "Simulation cancelled", "No valid prototype signals could be sampled.");
+ return;
}
}
else if ( m_Controls->m_Compartment1Box->currentIndex()==3 || m_Controls->m_Compartment3Box->currentIndex()==3 || m_Controls->m_Compartment4Box->currentIndex()==4 )
{
QMessageBox::information( NULL, "Simulation cancelled", "Prototype signal but no diffusion-weighted image selected to sample signal from.");
return;
}
m_TractsToDwiFilter->SetParameters(parameters);
m_TractsToDwiFilter->SetFiberBundle(fiberBundle);
m_Worker.m_FilterType = 0;
m_Thread.start(QThread::LowestPriority);
}
void QmitkFiberfoxView::ApplyTransform()
{
vector< mitk::DataNode::Pointer > selectedBundles;
for(unsigned int i=0; i<m_SelectedImages.size(); i++ )
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(m_SelectedImages.at(i));
for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it )
{
mitk::DataNode::Pointer fibNode = *it;
if ( fibNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(fibNode->GetData()) )
selectedBundles.push_back(fibNode);
}
}
if (selectedBundles.empty())
selectedBundles = m_SelectedBundles2;
if (!selectedBundles.empty())
{
for (std::vector<mitk::DataNode::Pointer>::const_iterator it = selectedBundles.begin(); it!=selectedBundles.end(); ++it)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>((*it)->GetData());
fib->RotateAroundAxis(m_Controls->m_XrotBox->value(), m_Controls->m_YrotBox->value(), m_Controls->m_ZrotBox->value());
fib->TranslateFibers(m_Controls->m_XtransBox->value(), m_Controls->m_YtransBox->value(), m_Controls->m_ZtransBox->value());
fib->ScaleFibers(m_Controls->m_XscaleBox->value(), m_Controls->m_YscaleBox->value(), m_Controls->m_ZscaleBox->value());
// handle child fiducials
if (m_Controls->m_IncludeFiducials->isChecked())
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse* pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData());
mitk::BaseGeometry* geom = pe->GetGeometry();
// translate
mitk::Vector3D world;
world[0] = m_Controls->m_XtransBox->value();
world[1] = m_Controls->m_YtransBox->value();
world[2] = m_Controls->m_ZtransBox->value();
geom->Translate(world);
// calculate rotation matrix
double x = m_Controls->m_XrotBox->value()*M_PI/180;
double y = m_Controls->m_YrotBox->value()*M_PI/180;
double z = m_Controls->m_ZrotBox->value()*M_PI/180;
itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity();
rotX[1][1] = cos(x);
rotX[2][2] = rotX[1][1];
rotX[1][2] = -sin(x);
rotX[2][1] = -rotX[1][2];
itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity();
rotY[0][0] = cos(y);
rotY[2][2] = rotY[0][0];
rotY[0][2] = sin(y);
rotY[2][0] = -rotY[0][2];
itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity();
rotZ[0][0] = cos(z);
rotZ[1][1] = rotZ[0][0];
rotZ[0][1] = -sin(z);
rotZ[1][0] = -rotZ[0][1];
itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX;
// transform control point coordinate into geometry translation
geom->SetOrigin(pe->GetWorldControlPoint(0));
mitk::Point2D cp; cp.Fill(0.0);
pe->SetControlPoint(0, cp);
// rotate fiducial
geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix());
// implicit translation
mitk::Vector3D trans;
trans[0] = geom->GetOrigin()[0]-fib->GetGeometry()->GetCenter()[0];
trans[1] = geom->GetOrigin()[1]-fib->GetGeometry()->GetCenter()[1];
trans[2] = geom->GetOrigin()[2]-fib->GetGeometry()->GetCenter()[2];
mitk::Vector3D newWc = rot*trans;
newWc = newWc-trans;
geom->Translate(newWc);
pe->Modified();
}
}
}
}
}
else
{
for (unsigned int i=0; i<m_SelectedFiducials.size(); i++)
{
mitk::PlanarEllipse* pe = dynamic_cast<mitk::PlanarEllipse*>(m_SelectedFiducials.at(i)->GetData());
mitk::BaseGeometry* geom = pe->GetGeometry();
// translate
mitk::Vector3D world;
world[0] = m_Controls->m_XtransBox->value();
world[1] = m_Controls->m_YtransBox->value();
world[2] = m_Controls->m_ZtransBox->value();
geom->Translate(world);
// calculate rotation matrix
double x = m_Controls->m_XrotBox->value()*M_PI/180;
double y = m_Controls->m_YrotBox->value()*M_PI/180;
double z = m_Controls->m_ZrotBox->value()*M_PI/180;
itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity();
rotX[1][1] = cos(x);
rotX[2][2] = rotX[1][1];
rotX[1][2] = -sin(x);
rotX[2][1] = -rotX[1][2];
itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity();
rotY[0][0] = cos(y);
rotY[2][2] = rotY[0][0];
rotY[0][2] = sin(y);
rotY[2][0] = -rotY[0][2];
itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity();
rotZ[0][0] = cos(z);
rotZ[1][1] = rotZ[0][0];
rotZ[0][1] = -sin(z);
rotZ[1][0] = -rotZ[0][1];
itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX;
// transform control point coordinate into geometry translation
geom->SetOrigin(pe->GetWorldControlPoint(0));
mitk::Point2D cp; cp.Fill(0.0);
pe->SetControlPoint(0, cp);
// rotate fiducial
geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix());
pe->Modified();
}
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::CopyBundles()
{
if ( m_SelectedBundles.size()<1 ){
QMessageBox::information( NULL, "Warning", "Select at least one fiber bundle!");
MITK_WARN("QmitkFiberProcessingView") << "Select at least one fiber bundle!";
return;
}
for (std::vector<mitk::DataNode::Pointer>::const_iterator it = m_SelectedBundles.begin(); it!=m_SelectedBundles.end(); ++it)
{
// find parent image
mitk::DataNode::Pointer parentNode;
mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(*it);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 )
{
mitk::DataNode::Pointer pImgNode = *it2;
if ( pImgNode.IsNotNull() && dynamic_cast<mitk::Image*>(pImgNode->GetData()) )
{
parentNode = pImgNode;
break;
}
}
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>((*it)->GetData());
mitk::FiberBundleX::Pointer newBundle = fib->GetDeepCopy();
QString name((*it)->GetName().c_str());
name += "_copy";
mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
fbNode->SetData(newBundle);
fbNode->SetName(name.toStdString());
fbNode->SetVisibility(true);
if (parentNode.IsNotNull())
GetDataStorage()->Add(fbNode, parentNode);
else
GetDataStorage()->Add(fbNode);
// copy child fiducials
if (m_Controls->m_IncludeFiducials->isChecked())
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse::Pointer pe = mitk::PlanarEllipse::New();
pe->DeepCopy(dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()));
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetData(pe);
newNode->SetName(fiducialNode->GetName());
newNode->SetBoolProperty("planarfigure.3drendering", true);
GetDataStorage()->Add(newNode, fbNode);
}
}
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::JoinBundles()
{
if ( m_SelectedBundles.size()<2 ){
QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!");
MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!";
return;
}
std::vector<mitk::DataNode::Pointer>::const_iterator it = m_SelectedBundles.begin();
mitk::FiberBundleX::Pointer newBundle = dynamic_cast<mitk::FiberBundleX*>((*it)->GetData());
QString name("");
name += QString((*it)->GetName().c_str());
++it;
for (; it!=m_SelectedBundles.end(); ++it)
{
newBundle = newBundle->AddBundle(dynamic_cast<mitk::FiberBundleX*>((*it)->GetData()));
name += "+"+QString((*it)->GetName().c_str());
}
mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
fbNode->SetData(newBundle);
fbNode->SetName(name.toStdString());
fbNode->SetVisibility(true);
GetDataStorage()->Add(fbNode);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::UpdateGui()
{
m_Controls->m_FiberBundleLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_GeometryFrame->setEnabled(true);
m_Controls->m_GeometryMessage->setVisible(false);
m_Controls->m_DiffusionPropsMessage->setVisible(false);
m_Controls->m_FiberGenMessage->setVisible(true);
m_Controls->m_TransformBundlesButton->setEnabled(false);
m_Controls->m_CopyBundlesButton->setEnabled(false);
m_Controls->m_GenerateFibersButton->setEnabled(false);
m_Controls->m_FlipButton->setEnabled(false);
m_Controls->m_CircleButton->setEnabled(false);
m_Controls->m_BvalueBox->setEnabled(true);
m_Controls->m_NumGradientsBox->setEnabled(true);
m_Controls->m_JoinBundlesButton->setEnabled(false);
m_Controls->m_AlignOnGrid->setEnabled(false);
if (m_SelectedFiducial.IsNotNull())
{
m_Controls->m_TransformBundlesButton->setEnabled(true);
m_Controls->m_FlipButton->setEnabled(true);
m_Controls->m_AlignOnGrid->setEnabled(true);
}
if (m_SelectedImage.IsNotNull() || !m_SelectedBundles.empty())
{
m_Controls->m_TransformBundlesButton->setEnabled(true);
m_Controls->m_CircleButton->setEnabled(true);
m_Controls->m_FiberGenMessage->setVisible(false);
m_Controls->m_AlignOnGrid->setEnabled(true);
}
if (m_MaskImageNode.IsNotNull() || m_SelectedImage.IsNotNull())
{
m_Controls->m_GeometryMessage->setVisible(true);
m_Controls->m_GeometryFrame->setEnabled(false);
}
if (m_SelectedDWI.IsNotNull())
{
m_Controls->m_DiffusionPropsMessage->setVisible(true);
m_Controls->m_BvalueBox->setEnabled(false);
m_Controls->m_NumGradientsBox->setEnabled(false);
m_Controls->m_GeometryMessage->setVisible(true);
m_Controls->m_GeometryFrame->setEnabled(false);
}
if (!m_SelectedBundles.empty())
{
m_Controls->m_CopyBundlesButton->setEnabled(true);
m_Controls->m_GenerateFibersButton->setEnabled(true);
m_Controls->m_FiberBundleLabel->setText(m_SelectedBundles.at(0)->GetName().c_str());
if (m_SelectedBundles.size()>1)
m_Controls->m_JoinBundlesButton->setEnabled(true);
}
}
void QmitkFiberfoxView::OnSelectionChanged( berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes )
{
m_SelectedBundles2.clear();
m_SelectedImages.clear();
m_SelectedFiducials.clear();
m_SelectedFiducial = NULL;
m_SelectedBundles.clear();
m_SelectedImage = NULL;
m_SelectedDWI = NULL;
m_MaskImageNode = NULL;
m_Controls->m_TissueMaskLabel->setText("<font color='grey'>optional</font>");
// iterate all selected objects, adjust warning visibility
for( int i=0; i<nodes.size(); i++)
{
mitk::DataNode::Pointer node = nodes.at(i);
if ( node.IsNotNull() && dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()) )
{
m_SelectedDWI = node;
m_SelectedImage = node;
m_SelectedImages.push_back(node);
}
else if( node.IsNotNull() && dynamic_cast<mitk::Image*>(node->GetData()) )
{
m_SelectedImages.push_back(node);
m_SelectedImage = node;
bool isbinary = false;
node->GetPropertyValue<bool>("binary", isbinary);
if (isbinary)
{
m_MaskImageNode = node;
m_Controls->m_TissueMaskLabel->setText(m_MaskImageNode->GetName().c_str());
}
}
else if ( node.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(node->GetData()) )
{
m_SelectedBundles2.push_back(node);
if (m_Controls->m_RealTimeFibers->isChecked())
{
m_SelectedBundles.push_back(node);
mitk::FiberBundleX::Pointer newFib = dynamic_cast<mitk::FiberBundleX*>(node->GetData());
if (newFib->GetNumFibers()!=m_Controls->m_FiberDensityBox->value())
GenerateFibers();
}
else
m_SelectedBundles.push_back(node);
}
else if ( node.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(node->GetData()) )
{
m_SelectedFiducials.push_back(node);
m_SelectedFiducial = node;
m_SelectedBundles.clear();
mitk::DataStorage::SetOfObjects::ConstPointer parents = GetDataStorage()->GetSources(node);
for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it )
{
mitk::DataNode::Pointer pNode = *it;
if ( pNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(pNode->GetData()) )
m_SelectedBundles.push_back(pNode);
}
}
}
UpdateGui();
}
void QmitkFiberfoxView::EnableCrosshairNavigation()
{
MITK_DEBUG << "EnableCrosshairNavigation";
// enable the crosshair navigation
if (mitk::ILinkedRenderWindowPart* linkedRenderWindow =
dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart()))
{
MITK_DEBUG << "enabling linked navigation";
linkedRenderWindow->EnableLinkedNavigation(true);
// linkedRenderWindow->EnableSlicingPlanes(true);
}
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::DisableCrosshairNavigation()
{
MITK_DEBUG << "DisableCrosshairNavigation";
// disable the crosshair navigation during the drawing
if (mitk::ILinkedRenderWindowPart* linkedRenderWindow =
dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart()))
{
MITK_DEBUG << "disabling linked navigation";
linkedRenderWindow->EnableLinkedNavigation(false);
// linkedRenderWindow->EnableSlicingPlanes(false);
}
}
void QmitkFiberfoxView::NodeRemoved(const mitk::DataNode* node)
{
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>(node);
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it = m_DataNodeToPlanarFigureData.find(nonConstNode);
if (dynamic_cast<FiberBundleX*>(node->GetData()))
{
m_SelectedBundles.clear();
m_SelectedBundles2.clear();
}
else if (dynamic_cast<Image*>(node->GetData()))
m_SelectedImages.clear();
if( it != m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
// remove observers
data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag );
data.m_Figure->RemoveObserver( data.m_SelectObserverTag );
data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag );
data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag );
m_DataNodeToPlanarFigureData.erase( it );
}
}
void QmitkFiberfoxView::NodeAdded( const mitk::DataNode* node )
{
// add observer for selection in renderwindow
mitk::PlanarFigure* figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
bool isPositionMarker (false);
node->GetBoolProperty("isContourMarker", isPositionMarker);
if( figure && !isPositionMarker )
{
MITK_DEBUG << "figure added. will add interactor if needed.";
mitk::PlanarFigureInteractor::Pointer figureInteractor
= dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>( node );
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( nonConstNode );
}
MITK_DEBUG << "will now add observers for planarfigure";
QmitkPlanarFigureData data;
data.m_Figure = figure;
// // add observer for event when figure has been placed
typedef itk::SimpleMemberCommand< QmitkFiberfoxView > SimpleCommandType;
// SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New();
// initializationCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureInitialized );
// data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand );
// add observer for event when figure is picked (selected)
typedef itk::MemberCommand< QmitkFiberfoxView > MemberCommandType;
MemberCommandType::Pointer selectCommand = MemberCommandType::New();
selectCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureSelected );
data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand );
// add observer for event when interaction with figure starts
SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New();
startInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::DisableCrosshairNavigation);
data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand );
// add observer for event when interaction with figure starts
SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New();
endInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::EnableCrosshairNavigation);
data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand );
m_DataNodeToPlanarFigureData[nonConstNode] = data;
}
}
void QmitkFiberfoxView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& )
{
mitk::TNodePredicateDataType<mitk::PlanarFigure>::Pointer isPf = mitk::TNodePredicateDataType<mitk::PlanarFigure>::New();
mitk::DataStorage::SetOfObjects::ConstPointer allPfs = this->GetDataStorage()->GetSubset( isPf );
for ( mitk::DataStorage::SetOfObjects::const_iterator it = allPfs->begin(); it!=allPfs->end(); ++it)
{
mitk::DataNode* node = *it;
if( node->GetData() == object )
{
node->SetSelected(true);
m_SelectedFiducial = node;
}
else
node->SetSelected(false);
}
UpdateGui();
this->RequestRenderWindowUpdate();
}
void QmitkFiberfoxView::SetFocus()
{
m_Controls->m_CircleButton->setFocus();
}
void QmitkFiberfoxView::SetOutputPath()
{
// SELECT FOLDER DIALOG
string outputPath = QFileDialog::getExistingDirectory(NULL, "Save images to...", QString(outputPath.c_str())).toStdString();
if (outputPath.empty())
m_Controls->m_SavePathEdit->setText("-");
else
{
outputPath += "/";
m_Controls->m_SavePathEdit->setText(QString(outputPath.c_str()));
}
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h
index fc4f611076..dbe58f859b 100755
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h
@@ -1,228 +1,209 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <berryISelectionListener.h>
#include <berryIStructuredSelection.h>
#include <QmitkAbstractView.h>
#include "ui_QmitkFiberfoxViewControls.h"
#include <itkVectorImage.h>
#include <itkVectorContainer.h>
#include <itkOrientationDistributionFunction.h>
#include <mitkFiberBundleX.h>
#include <mitkPlanarEllipse.h>
#include <mitkDiffusionNoiseModel.h>
#include <mitkDiffusionSignalModel.h>
#include <mitkRicianNoiseModel.h>
#include <itkTractsToDWIImageFilter.h>
#include <itkAddArtifactsToDwiImageFilter.h>
#include <mitkTensorModel.h>
#include <mitkBallModel.h>
#include <mitkStickModel.h>
#include <mitkAstroStickModel.h>
#include <mitkDotModel.h>
#include <QThread>
#include <QObject>
#include <QTimer>
#include <QTime>
#include <mitkFiberfoxParameters.h>
#include <itkStatisticsImageFilter.h>
/*!
\brief View for fiber based diffusion software phantoms (Fiberfox). See "Fiberfox: Facilitating the creation of realistic white matter software phantoms" (DOI: 10.1002/mrm.25045) for details.
\sa QmitkFunctionality
\ingroup Functionalities
*/
// Forward Qt class declarations
using namespace std;
class QmitkFiberfoxView;
class QmitkFiberfoxWorker : public QObject
{
Q_OBJECT
public:
QmitkFiberfoxWorker(QmitkFiberfoxView* view);
int m_FilterType;
public slots:
void run();
private:
QmitkFiberfoxView* m_View;
};
class QmitkFiberfoxView : public QmitkAbstractView
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
static const string VIEW_ID;
QmitkFiberfoxView();
virtual ~QmitkFiberfoxView();
virtual void CreateQtPartControl(QWidget *parent);
void SetFocus();
typedef itk::Image<double, 3> ItkDoubleImgType;
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::Vector<double,3> GradientType;
typedef vector<GradientType> GradientListType;
template<int ndirs> vector<itk::Vector<double,3> > MakeGradientList();
protected slots:
void SetOutputPath(); ///< path where image is automatically saved to after the simulation is finished
void LoadParameters(); ///< load fiberfox parameters
void SaveParameters(); ///< save fiberfox parameters
void BeforeThread();
void AfterThread();
void KillThread(); ///< abort simulation
void UpdateSimulationStatus(); ///< print simulation progress and satus messages
void OnDrawROI(); ///< adds new ROI, handles interactors etc.
void OnAddBundle(); ///< adds new fiber bundle to datastorage
void OnFlipButton(); ///< negate one coordinate of the fiber waypoints in the selcted planar figure. needed in case of unresolvable twists
void GenerateFibers(); ///< generate fibers from the selected ROIs
void GenerateImage(); ///< start image simulation
void JoinBundles(); ///< merges selcted fiber bundles into one
void CopyBundles(); ///< add copy of the selected bundle to the datamanager
void ApplyTransform(); ///< rotate and shift selected bundles
void AlignOnGrid(); ///< shift selected fiducials to nearest voxel center
void Comp1ModelFrameVisibility(int index); ///< only show parameters of selected signal model for compartment 1
void Comp2ModelFrameVisibility(int index); ///< only show parameters of selected signal model for compartment 2
void Comp3ModelFrameVisibility(int index); ///< only show parameters of selected signal model for compartment 3
void Comp4ModelFrameVisibility(int index); ///< only show parameters of selected signal model for compartment 4
void ShowAdvancedOptions(int state);
/** update fibers if any parameter changes */
void OnFiberDensityChanged(int value);
void OnFiberSamplingChanged(double value);
void OnTensionChanged(double value);
void OnContinuityChanged(double value);
void OnBiasChanged(double value);
void OnVarianceChanged(double value);
void OnDistributionChanged(int value);
void OnConstantRadius(int value);
/** update GUI elements */
void OnAddNoise(int value);
void OnAddGhosts(int value);
void OnAddDistortions(int value);
void OnAddEddy(int value);
void OnAddSpikes(int value);
void OnAddAliasing(int value);
void OnAddMotion(int value);
protected:
/// \brief called by QmitkFunctionality when DataManager's selection has changed
virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>&);
GradientListType GenerateHalfShell(int NPoints); ///< generate vectors distributed over the halfsphere
Ui::QmitkFiberfoxViewControls* m_Controls;
void SimulateForExistingDwi(mitk::DataNode* imageNode); ///< add artifacts to existing diffusion weighted image
void SimulateImageFromFibers(mitk::DataNode* fiberNode); ///< simulate new diffusion weighted image
template< class ScalarType > FiberfoxParameters< ScalarType > UpdateImageParameters(); ///< update fiberfox paramater object (template parameter defines noise model type)
void UpdateGui(); ///< enable/disbale buttons etc. according to current datamanager selection
void PlanarFigureSelected( itk::Object* object, const itk::EventObject& );
void EnableCrosshairNavigation(); ///< enable crosshair navigation if planar figure interaction ends
void DisableCrosshairNavigation(); ///< disable crosshair navigation if planar figure interaction starts
void NodeAdded( const mitk::DataNode* node ); ///< add observers
void NodeRemoved(const mitk::DataNode* node); ///< remove observers
/** structure to keep track of planar figures and observers */
struct QmitkPlanarFigureData
{
QmitkPlanarFigureData()
: m_Figure(0)
, m_EndPlacementObserverTag(0)
, m_SelectObserverTag(0)
, m_StartInteractionObserverTag(0)
, m_EndInteractionObserverTag(0)
, m_Flipped(0)
{
}
mitk::PlanarFigure* m_Figure;
unsigned int m_EndPlacementObserverTag;
unsigned int m_SelectObserverTag;
unsigned int m_StartInteractionObserverTag;
unsigned int m_EndInteractionObserverTag;
unsigned int m_Flipped;
};
std::map<mitk::DataNode*, QmitkPlanarFigureData> m_DataNodeToPlanarFigureData; ///< map each planar figure uniquely to a QmitkPlanarFigureData
mitk::DataNode::Pointer m_SelectedFiducial; ///< selected planar ellipse
mitk::DataNode::Pointer m_SelectedImage;
mitk::DataNode::Pointer m_SelectedDWI;
vector< mitk::DataNode::Pointer > m_SelectedBundles;
vector< mitk::DataNode::Pointer > m_SelectedBundles2;
vector< mitk::DataNode::Pointer > m_SelectedFiducials;
vector< mitk::DataNode::Pointer > m_SelectedImages;
mitk::DataNode::Pointer m_MaskImageNode;
- /** intra and inter axonal compartments */
- mitk::StickModel<double> m_StickModel1;
- mitk::StickModel<double> m_StickModel2;
- mitk::TensorModel<double> m_ZeppelinModel1;
- mitk::TensorModel<double> m_ZeppelinModel2;
- mitk::TensorModel<double> m_TensorModel1;
- mitk::TensorModel<double> m_TensorModel2;
- mitk::RawShModel<double> m_PrototypeModel1;
-
- /** extra axonal compartment models */
- mitk::BallModel<double> m_BallModel1;
- mitk::BallModel<double> m_BallModel2;
- mitk::AstroStickModel<double> m_AstrosticksModel1;
- mitk::AstroStickModel<double> m_AstrosticksModel2;
- mitk::DotModel<double> m_DotModel1;
- mitk::DotModel<double> m_DotModel2;
- mitk::RawShModel<double> m_PrototypeModel3;
- mitk::RawShModel<double> m_PrototypeModel4;
-
QString m_ParameterFile; ///< parameter file name
// GUI thread
QmitkFiberfoxWorker m_Worker; ///< runs filter
QThread m_Thread; ///< worker thread
bool m_ThreadIsRunning;
QTimer* m_SimulationTimer;
QTime m_SimulationTime;
QString m_SimulationStatusText;
/** Image filters that do all the simulations. */
itk::TractsToDWIImageFilter< short >::Pointer m_TractsToDwiFilter;
itk::AddArtifactsToDwiImageFilter< short >::Pointer m_ArtifactsToDwiFilter;
friend class QmitkFiberfoxWorker;
};
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui
index c4274ce619..cf15c8a6b3 100755
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui
@@ -1,3037 +1,3083 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkFiberfoxViewControls</class>
<widget class="QWidget" name="QmitkFiberfoxViewControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>435</width>
- <height>2305</height>
+ <width>443</width>
+ <height>2332</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="0">
<widget class="QCommandLinkButton" name="m_LoadParametersButton">
<property name="text">
<string>Load Parameters</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/upload.ico</normaloff>:/QmitkDiffusionImaging/general_icons/upload.ico</iconset>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Fiber Definition</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<item row="7" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="m_FiberGenMessage">
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string>Please select an image or an existing fiber bundle to draw the fiber fiducials. If you can't provide a suitable image, generate one using the &quot;Signal Generation&quot; tab.</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>Fiducial Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_16">
<item row="0" column="0">
<widget class="QCheckBox" name="m_ConstantRadiusBox">
<property name="toolTip">
<string>All fiducials are treated as circles with the same radius as the first fiducial. </string>
</property>
<property name="text">
<string>Use Constant Fiducial Radius</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCommandLinkButton" name="m_AlignOnGrid">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Align selected fiducials with voxel grid. Shifts selected fiducials to nearest voxel center.</string>
</property>
<property name="text">
<string>Align With Grid</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/right.ico</normaloff>:/QmitkDiffusionImaging/general_icons/right.ico</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Operations</string>
</property>
<layout class="QGridLayout" name="gridLayout_11">
<item row="5" column="0">
<widget class="QCommandLinkButton" name="m_JoinBundlesButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Join Bundles</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/plus.ico</normaloff>:/QmitkDiffusionImaging/general_icons/plus.ico</iconset>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_12">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="2">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_18">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Y</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="m_XrotBox">
<property name="toolTip">
<string>Rotation angle (in degree) around x-axis.</string>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_22">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Axis:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QDoubleSpinBox" name="m_YrotBox">
<property name="toolTip">
<string>Rotation angle (in degree) around y-axis.</string>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_21">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Translation:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QDoubleSpinBox" name="m_ZtransBox">
<property name="toolTip">
<string>Translation (in mm) in direction of the z-axis.</string>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>1000.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QDoubleSpinBox" name="m_YtransBox">
<property name="toolTip">
<string>Translation (in mm) in direction of the y-axis.</string>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>1000.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_17">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>X</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_20">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Rotation:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_19">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Z</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QDoubleSpinBox" name="m_ZrotBox">
<property name="toolTip">
<string>Rotation angle (in degree) around z-axis.</string>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="m_XtransBox">
<property name="toolTip">
<string>Translation (in mm) in direction of the x-axis.</string>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>1000.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_24">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Scaling:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="m_XscaleBox">
<property name="toolTip">
<string>Scaling factor for selected fiber bundle along the x-axis.</string>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QDoubleSpinBox" name="m_YscaleBox">
<property name="toolTip">
<string>Scaling factor for selected fiber bundle along the y-axis.</string>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QDoubleSpinBox" name="m_ZscaleBox">
<property name="toolTip">
<string>Scaling factor for selected fiber bundle along the z-axis.</string>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QCommandLinkButton" name="m_CopyBundlesButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Copy Bundles</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/copy2.ico</normaloff>:/QmitkDiffusionImaging/general_icons/copy2.ico</iconset>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCommandLinkButton" name="m_TransformBundlesButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Transform Selection</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/refresh.ico</normaloff>:/QmitkDiffusionImaging/general_icons/refresh.ico</iconset>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="m_IncludeFiducials">
<property name="toolTip">
<string>If checked, the fiducials belonging to the modified bundle are also modified.</string>
</property>
<property name="text">
<string>Include Fiducials</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>Fiber Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_15">
<item row="2" column="0">
<widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="0">
<widget class="QFrame" name="m_AdvancedFiberOptionsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_21">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_5">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Tension:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_8">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Fiber Sampling:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="m_TensionBox">
<property name="toolTip">
<string/>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="m_BiasBox">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_7">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Bias:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_6">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Continuity:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="m_ContinuityBox">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="m_FiberSamplingBox">
<property name="toolTip">
<string>Distance of fiber sampling points (in mm)</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_25">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_4">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>#Fibers:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="m_FiberDensityBox">
<property name="toolTip">
<string>Specify number of fibers to generate for the selected bundle.</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QCommandLinkButton" name="m_GenerateFibersButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Generate Fibers</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/right.ico</normaloff>:/QmitkDiffusionImaging/general_icons/right.ico</iconset>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QComboBox" name="m_DistributionBox">
<property name="toolTip">
<string>Select fiber distribution inside of the fiducials.</string>
</property>
<item>
<property name="text">
<string>Uniform</string>
</property>
</item>
<item>
<property name="text">
<string>Gaussian</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="m_TensorsToDWIBValueLabel_9">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>Fiber Distribution:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="m_VarianceBox">
<property name="toolTip">
<string>Variance of the gaussian</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QFrame" name="frame_8">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_22">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="m_RealTimeFibers">
<property name="toolTip">
<string>Disable to only generate fibers if &quot;Generate Fibers&quot; button is pressed.</string>
</property>
<property name="text">
<string>Real Time Fibers</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="m_AdvancedOptionsBox">
<property name="toolTip">
<string>Disable to only generate fibers if &quot;Generate Fibers&quot; button is pressed.</string>
</property>
<property name="text">
<string>Advanced Options</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QPushButton" name="m_CircleButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Draw elliptical fiducial.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/circle.png</normaloff>:/QmitkDiffusionImaging/circle.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="m_FlipButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Flip fiber waypoints of selcted fiducial around one axis.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/refresh.xpm</normaloff>:/QmitkDiffusionImaging/refresh.xpm</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Signal Generation</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
- <item row="0" column="0" rowspan="2">
- <widget class="QGroupBox" name="groupBox_2">
+ <item row="10" column="0">
+ <widget class="QGroupBox" name="groupBox_6">
<property name="title">
- <string>Data</string>
+ <string>Extra-axonal Compartments</string>
</property>
- <layout class="QGridLayout" name="gridLayout_10">
- <item row="3" column="0" colspan="2">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_3">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Tissue Mask:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QLabel" name="m_TissueMaskLabel">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#969696;&quot;&gt;optional&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0" rowspan="2" colspan="2">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_16">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Fiber Bundle:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="2" rowspan="2">
- <widget class="QLabel" name="m_FiberBundleLabel">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;mandatory&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_10">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Save path:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="2">
- <widget class="QFrame" name="frame_6">
+ <layout class="QGridLayout" name="gridLayout_14">
+ <item row="17" column="0">
+ <widget class="QFrame" name="m_Comp4FractionFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_20">
+ <layout class="QGridLayout" name="gridLayout_18">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <property name="spacing">
- <number>0</number>
- </property>
<item row="0" column="0">
- <widget class="QLineEdit" name="m_SavePathEdit">
+ <widget class="QLabel" name="m_NoiseLabel_3">
<property name="text">
- <string>-</string>
+ <string>Volume Fraction:</string>
</property>
</widget>
</item>
<item row="0" column="1">
- <widget class="QToolButton" name="m_OutputPathButton">
- <property name="text">
- <string>...</string>
+ <widget class="QmitkDataStorageComboBox" name="m_Comp4VolumeFraction">
+ <property name="toolTip">
+ <string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- </layout>
- </widget>
- </item>
- <item row="13" column="0">
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>Noise and other Artifacts</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="20" column="0">
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <item row="6" column="0">
+ <widget class="QComboBox" name="m_Compartment3Box">
+ <property name="toolTip">
+ <string>Select signal model for extra-axonal compartment.</string>
</property>
+ <item>
+ <property name="text">
+ <string>Ball Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Astrosticks Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Dot Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>PrototypeSignal</string>
+ </property>
+ </item>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QCheckBox" name="m_AddNoise">
- <property name="text">
- <string>Add Noise</string>
- </property>
- <property name="checked">
- <bool>false</bool>
+ <item row="8" column="0">
+ <widget class="QmitkAstrosticksModelParametersWidget" name="m_AstrosticksWidget1" native="true"/>
+ </item>
+ <item row="10" column="0">
+ <widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget3" native="true"/>
+ </item>
+ <item row="15" column="0">
+ <widget class="QmitkDotModelParametersWidget" name="m_DotWidget2" native="true"/>
+ </item>
+ <item row="9" column="0">
+ <widget class="QmitkDotModelParametersWidget" name="m_DotWidget1" native="true"/>
+ </item>
+ <item row="11" column="0">
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="21" column="0">
- <widget class="QCheckBox" name="m_AddGibbsRinging">
+ <item row="13" column="0">
+ <widget class="QmitkBallModelParametersWidget" name="m_BallWidget2" native="true"/>
+ </item>
+ <item row="7" column="0">
+ <widget class="QmitkBallModelParametersWidget" name="m_BallWidget1" native="true"/>
+ </item>
+ <item row="14" column="0">
+ <widget class="QmitkAstrosticksModelParametersWidget" name="m_AstrosticksWidget2" native="true"/>
+ </item>
+ <item row="12" column="0">
+ <widget class="QComboBox" name="m_Compartment4Box">
<property name="toolTip">
- <string>Add ringing artifacts occuring at strong edges in the image.</string>
+ <string>Select signal model for extra-axonal compartment.</string>
</property>
+ <item>
+ <property name="text">
+ <string>--</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Ball Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Astrosticks Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Dot Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Prototype Signal</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="16" column="0">
+ <widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget4" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="7" column="0">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Image Settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="6" column="0">
+ <widget class="QCheckBox" name="m_AdvancedOptionsBox_2">
<property name="text">
- <string>Add Gibbs Ringing</string>
- </property>
- <property name="checked">
- <bool>false</bool>
+ <string>Advanced Options</string>
</property>
</widget>
</item>
- <item row="10" column="0">
- <widget class="QFrame" name="m_AliasingFrame">
- <property name="enabled">
- <bool>true</bool>
- </property>
+ <item row="5" column="0">
+ <widget class="QFrame" name="m_TensorsToDWIFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QFormLayout" name="formLayout_10">
- <property name="horizontalSpacing">
- <number>6</number>
- </property>
+ <layout class="QGridLayout" name="gridLayout_24">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
<item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_27">
- <property name="toolTip">
- <string/>
+ <widget class="QLabel" name="m_TensorsToDWINumDirsLabel">
+ <property name="text">
+ <string>Gradient Directions:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="m_NumGradientsBox">
+ <property name="toolTip">
+ <string>Number of gradient directions distributed over the half sphere.</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel">
+ <property name="toolTip">
+ <string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
- <string>Shrink FOV (%):</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;b-Value&lt;span style=&quot; font-style:italic;&quot;&gt; [s/mm&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:super;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;]&lt;/span&gt;:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QDoubleSpinBox" name="m_WrapBox">
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="m_BvalueBox">
<property name="toolTip">
- <string>Shrink FOV by this percentage.</string>
- </property>
- <property name="decimals">
- <number>1</number>
+ <string>b-value in s/mm²</string>
</property>
<property name="minimum">
- <double>0.000000000000000</double>
+ <number>0</number>
</property>
<property name="maximum">
- <double>90.000000000000000</double>
+ <number>10000</number>
</property>
<property name="singleStep">
- <double>0.100000000000000</double>
+ <number>100</number>
</property>
<property name="value">
- <double>25.000000000000000</double>
+ <number>1000</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="17" column="0">
- <widget class="Line" name="line_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <item row="2" column="0">
+ <widget class="QLabel" name="m_GeometryMessage">
+ <property name="styleSheet">
+ <string notr="true">color: rgb(255, 0, 0);</string>
+ </property>
+ <property name="text">
+ <string>Using geometry of selected image!</string>
</property>
</widget>
</item>
<item row="4" column="0">
- <widget class="QFrame" name="m_SpikeFrame">
+ <widget class="QLabel" name="m_DiffusionPropsMessage">
+ <property name="styleSheet">
+ <string notr="true">color: rgb(255, 0, 0);</string>
+ </property>
+ <property name="text">
+ <string>Using gradients of selected DWI!</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QFrame" name="m_AdvancedSignalOptionsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QFormLayout" name="formLayout_9">
+ <layout class="QGridLayout" name="gridLayout_23">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <item row="0" column="0">
- <widget class="QLabel" name="m_NoiseLabel_2">
- <property name="text">
- <string>Num. Spikes:</string>
- </property>
- </widget>
- </item>
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
<item row="0" column="1">
- <widget class="QSpinBox" name="m_SpikeNumBox">
+ <widget class="QSpinBox" name="m_SignalScaleBox">
<property name="toolTip">
- <string>The number of randomly occurring signal spikes.</string>
+ <string>TE in milliseconds</string>
</property>
- <property name="value">
+ <property name="minimum">
<number>1</number>
</property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="m_SpikeScaleBox">
- <property name="toolTip">
- <string>Spike amplitude relative to the largest signal amplitude of the corresponding k-space slice.</string>
+ <property name="maximum">
+ <number>10000</number>
</property>
<property name="singleStep">
- <double>0.100000000000000</double>
+ <number>1</number>
</property>
<property name="value">
- <double>0.100000000000000</double>
+ <number>100</number>
</property>
</widget>
</item>
<item row="1" column="0">
- <widget class="QLabel" name="m_NoiseLabel_4">
- <property name="text">
- <string>Scale:</string>
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_13">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
</property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="18" column="0">
- <widget class="QCheckBox" name="m_AddEddy">
- <property name="toolTip">
- <string>!!!EXPERIMENTAL!!!</string>
- </property>
- <property name="text">
- <string>Add Eddy Current Effects</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QCheckBox" name="m_AddSpikes">
- <property name="text">
- <string>Add Spikes</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QFrame" name="m_NoiseFrame">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QFormLayout" name="formLayout_5">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="1" column="0">
- <widget class="QLabel" name="m_NoiseLabel">
<property name="text">
- <string>Variance:</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Echo Time &lt;span style=&quot; font-style:italic;&quot;&gt;TE&lt;/span&gt;: &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="m_NoiseLevel">
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="m_LineReadoutTimeBox">
<property name="toolTip">
- <string>Variance of selected noise distribution.</string>
- </property>
- <property name="decimals">
- <number>4</number>
- </property>
- <property name="minimum">
- <double>0.000000000000000</double>
+ <string>T2* relaxation time (in milliseconds).</string>
</property>
<property name="maximum">
- <double>999999999.000000000000000</double>
+ <double>100.000000000000000</double>
</property>
<property name="singleStep">
- <double>0.001000000000000</double>
+ <double>0.100000000000000</double>
</property>
<property name="value">
- <double>50.000000000000000</double>
+ <double>1.000000000000000</double>
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QLabel" name="m_NoiseLabel_5">
+ <item row="9" column="0">
+ <widget class="QCheckBox" name="m_VolumeFractionsBox">
+ <property name="toolTip">
+ <string>Output one image per compartment containing the corresponding volume fractions per voxel.</string>
+ </property>
<property name="text">
- <string>Distribution:</string>
+ <string>Output Volume Fractions</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QComboBox" name="m_NoiseDistributionBox">
- <property name="toolTip">
- <string>Noise distribution</string>
- </property>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="m_DiffusionDirectionBox">
<item>
<property name="text">
- <string>Rician</string>
+ <string>Fiber tangent</string>
</property>
</item>
<item>
<property name="text">
- <string>Chi-squared</string>
+ <string>Main fiber directions</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Random</string>
</property>
</item>
</widget>
</item>
- </layout>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QCheckBox" name="m_AddGhosts">
- <property name="text">
- <string>Add N/2 Ghosts</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="13" column="0">
- <widget class="QFrame" name="m_DistortionsFrame">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QFormLayout" name="formLayout_7">
- <property name="horizontalSpacing">
- <number>6</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_25">
+ <item row="7" column="0">
+ <widget class="QCheckBox" name="m_RelaxationBox">
<property name="toolTip">
- <string/>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;TE&lt;/span&gt;, &lt;span style=&quot; font-style:italic;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;inhom&lt;/span&gt; and &lt;span style=&quot; font-style:italic;&quot;&gt;T2&lt;/span&gt; will have no effect if unchecked.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
- <property name="statusTip">
+ <property name="text">
+ <string>Simulate Signal Relaxation</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="m_TensorsToDWINumDirsLabel_4">
+ <property name="text">
+ <string>Fiber Radius:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_15">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
- <string>Frequency Map:</string>
+ <string>Line Readout Time: </string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QmitkDataStorageComboBox" name="m_FrequencyMapBox">
+ <item row="3" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_12">
<property name="toolTip">
- <string>Select image specifying the frequency inhomogeneities (in Hz).</string>
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;inhom&lt;/span&gt; Relaxation: &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Diffusion Direction:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QSpinBox" name="m_T2starBox">
+ <property name="toolTip">
+ <string>Relaxation time due to magnetic field inhomogeneities (T2', in milliseconds).</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="m_TEbox">
+ <property name="toolTip">
+ <string>TE in milliseconds</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_TensorsToDWINumDirsLabel_5">
+ <property name="text">
+ <string>Signal Scale:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSpinBox" name="m_FiberRadius">
+ <property name="toolTip">
+ <string>Fiber radius used to calculate volume fractions (in µm). Set to 0 for automatic radius estimation.</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Separation Angle:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QCheckBox" name="m_EnforcePureFiberVoxelsBox">
+ <property name="toolTip">
+ <string>Disable partial volume. Treat voxel content as fiber-only if at least one fiber is present.</string>
+ </property>
+ <property name="text">
+ <string>Disable Partial Volume Effects</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QDoubleSpinBox" name="m_SeparationAngleBox">
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>90.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>45.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="14" column="0">
- <widget class="Line" name="line_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="Line" name="line_7">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="11" column="0">
- <widget class="Line" name="line_6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="16" column="0">
- <widget class="QFrame" name="m_MotionArtifactFrame">
- <property name="enabled">
- <bool>true</bool>
- </property>
+ <item row="3" column="0">
+ <widget class="QFrame" name="m_GeometryFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QFormLayout" name="formLayout_11">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <property name="horizontalSpacing">
- <number>6</number>
- </property>
+ <layout class="QGridLayout" name="gridLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
- <number>6</number>
+ <number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <item row="0" column="0">
- <widget class="QCheckBox" name="m_RandomMotion">
- <property name="toolTip">
- <string>Toggle between random movement and linear movement.</string>
+ <item row="2" column="2">
+ <widget class="QDoubleSpinBox" name="m_SpacingY">
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>50.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>2.000000000000000</double>
</property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
<property name="text">
- <string>Randomize motion</string>
+ <string>Image Spacing:</string>
</property>
- <property name="checked">
- <bool>true</bool>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QDoubleSpinBox" name="m_SpacingZ">
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>50.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>2.000000000000000</double>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="2">
- <widget class="QGroupBox" name="m_RotationArtifactFrame">
- <property name="title">
- <string>Rotation</string>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="m_SpacingX">
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>50.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>2.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Image Dimensions:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="m_SizeX">
+ <property name="toolTip">
+ <string>Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions.</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>11</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QSpinBox" name="m_SizeY">
+ <property name="toolTip">
+ <string>Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions.</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>11</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QSpinBox" name="m_SizeZ">
+ <property name="toolTip">
+ <string>Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions.</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QGroupBox" name="groupBox_5">
+ <property name="title">
+ <string>Inter-axonal Compartment</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_17">
+ <item row="0" column="0">
+ <widget class="QComboBox" name="m_Compartment2Box">
+ <property name="toolTip">
+ <string>Select signal model for intra-axonal compartment.</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>--</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Stick Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Zeppelin Model</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Tensor Model</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QmitkZeppelinModelParametersWidget" name="m_ZeppelinWidget2" native="true"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QmitkStickModelParametersWidget" name="m_StickWidget2" native="true"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QmitkTensorModelParametersWidget" name="m_TensorWidget2" native="true"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget2" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QCommandLinkButton" name="m_AbortSimulationButton">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip">
+ <string>Stop current simulation.</string>
+ </property>
+ <property name="text">
+ <string>Abort Simulation</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../resources/QmitkDiffusionImaging.qrc">
+ <normaloff>:/QmitkDiffusionImaging/general_icons/abort.ico</normaloff>:/QmitkDiffusionImaging/general_icons/abort.ico</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" rowspan="2">
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Data</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_10">
+ <item row="3" column="0" colspan="2">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_3">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Tissue Mask:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLabel" name="m_TissueMaskLabel">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#969696;&quot;&gt;optional&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" rowspan="2" colspan="2">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_16">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Fiber Bundle:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" rowspan="2">
+ <widget class="QLabel" name="m_FiberBundleLabel">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;mandatory&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_10">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Save path:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QFrame" name="frame_6">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_20">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLineEdit" name="m_SavePathEdit">
+ <property name="text">
+ <string>-</string>
</property>
- <layout class="QGridLayout" name="gridLayout_19">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>9</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="1" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_36">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Degree:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_29">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>x</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_28">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Axis:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="m_MaxRotationBoxX">
- <property name="toolTip">
- <string>Maximum rotation around x-axis.</string>
- </property>
- <property name="decimals">
- <number>1</number>
- </property>
- <property name="maximum">
- <double>360.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>1.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QDoubleSpinBox" name="m_MaxRotationBoxZ">
- <property name="toolTip">
- <string>Maximum rotation around z-axis.</string>
- </property>
- <property name="decimals">
- <number>1</number>
- </property>
- <property name="maximum">
- <double>360.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>1.000000000000000</double>
- </property>
- <property name="value">
- <double>15.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_30">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>y</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_31">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>z</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QDoubleSpinBox" name="m_MaxRotationBoxY">
- <property name="toolTip">
- <string>Maximum rotation around y-axis.</string>
- </property>
- <property name="decimals">
- <number>1</number>
- </property>
- <property name="maximum">
- <double>360.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>1.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
</widget>
</item>
- <item row="2" column="0" colspan="2">
- <widget class="QGroupBox" name="m_TranslationArtifactFrame">
- <property name="title">
- <string>Translation</string>
+ <item row="0" column="1">
+ <widget class="QToolButton" name="m_OutputPathButton">
+ <property name="text">
+ <string>...</string>
</property>
- <layout class="QGridLayout" name="gridLayout_28">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="1" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_48">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Distance:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_51">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>x</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_52">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>y</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_47">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Axis:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_53">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>z</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="m_MaxTranslationBoxX">
- <property name="toolTip">
- <string>Maximum translation along x-axis.</string>
- </property>
- <property name="decimals">
- <number>1</number>
- </property>
- <property name="maximum">
- <double>1000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>1.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QDoubleSpinBox" name="m_MaxTranslationBoxY">
- <property name="toolTip">
- <string>Maximum translation along y-axis.</string>
- </property>
- <property name="decimals">
- <number>1</number>
- </property>
- <property name="maximum">
- <double>1000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>1.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QDoubleSpinBox" name="m_MaxTranslationBoxZ">
- <property name="toolTip">
- <string>Maximum translation along z-axis.</string>
- </property>
- <property name="decimals">
- <number>1</number>
- </property>
- <property name="maximum">
- <double>1000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>1.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="15" column="0">
- <widget class="QCheckBox" name="m_AddMotion">
- <property name="text">
- <string>Add Motion Artifacts</string>
- </property>
- <property name="checked">
- <bool>false</bool>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QTextEdit" name="m_SimulationStatusText">
+ <property name="font">
+ <font>
+ <pointsize>8</pointsize>
+ </font>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>Noise and other Artifacts</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="20" column="0">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="12" column="0">
- <widget class="QCheckBox" name="m_AddDistortions">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="m_AddNoise">
<property name="text">
- <string>Add Distortions</string>
+ <string>Add Noise</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="9" column="0">
- <widget class="QCheckBox" name="m_AddAliasing">
+ <item row="21" column="0">
+ <widget class="QCheckBox" name="m_AddGibbsRinging">
+ <property name="toolTip">
+ <string>Add ringing artifacts occuring at strong edges in the image.</string>
+ </property>
<property name="text">
- <string>Add Aliasing</string>
+ <string>Add Gibbs Ringing</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="7" column="0">
- <widget class="QFrame" name="m_GhostFrame">
+ <item row="10" column="0">
+ <widget class="QFrame" name="m_AliasingFrame">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QFormLayout" name="formLayout_6">
+ <layout class="QFormLayout" name="formLayout_10">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_23">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_27">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
- <string>K-Space Line Offset:</string>
+ <string>Shrink FOV (%):</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
- <widget class="QDoubleSpinBox" name="m_kOffsetBox">
+ <widget class="QDoubleSpinBox" name="m_WrapBox">
<property name="toolTip">
- <string>A larger offset increases the inensity of the ghost image.</string>
+ <string>Shrink FOV by this percentage.</string>
</property>
<property name="decimals">
- <number>3</number>
+ <number>1</number>
+ </property>
+ <property name="minimum">
+ <double>0.000000000000000</double>
</property>
<property name="maximum">
- <double>1.000000000000000</double>
+ <double>90.000000000000000</double>
</property>
<property name="singleStep">
- <double>0.010000000000000</double>
+ <double>0.100000000000000</double>
</property>
<property name="value">
- <double>0.250000000000000</double>
+ <double>25.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="19" column="0">
- <widget class="QFrame" name="m_EddyFrame">
- <property name="enabled">
- <bool>true</bool>
+ <item row="17" column="0">
+ <widget class="Line" name="line_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QFrame" name="m_SpikeFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QFormLayout" name="formLayout_8">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <property name="horizontalSpacing">
- <number>6</number>
- </property>
+ <layout class="QFormLayout" name="formLayout_9">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <item row="1" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_26">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_NoiseLabel_2">
<property name="text">
- <string>Magnitude:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
+ <string>Num. Spikes:</string>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="m_EddyGradientStrength">
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="m_SpikeNumBox">
<property name="toolTip">
- <string>Maximum magnitude of eddy current induced magnetic field inhomogeneities (in mT).</string>
+ <string>The number of randomly occurring signal spikes.</string>
</property>
- <property name="decimals">
- <number>5</number>
+ <property name="value">
+ <number>1</number>
</property>
- <property name="maximum">
- <double>1000.000000000000000</double>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="m_SpikeScaleBox">
+ <property name="toolTip">
+ <string>Spike amplitude relative to the largest signal amplitude of the corresponding k-space slice.</string>
</property>
<property name="singleStep">
- <double>0.001000000000000</double>
+ <double>0.100000000000000</double>
</property>
<property name="value">
- <double>0.005000000000000</double>
+ <double>0.100000000000000</double>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QLabel" name="m_DiffusionPropsMessage_2">
- <property name="styleSheet">
- <string notr="true">color: rgb(255, 0, 0);</string>
- </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="m_NoiseLabel_4">
<property name="text">
- <string>Experimental!</string>
+ <string>Scale:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="5" column="0">
- <widget class="Line" name="line_8">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <item row="18" column="0">
+ <widget class="QCheckBox" name="m_AddEddy">
+ <property name="toolTip">
+ <string>!!!EXPERIMENTAL!!!</string>
+ </property>
+ <property name="text">
+ <string>Add Eddy Current Effects</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="2" column="0">
- <widget class="Line" name="line_9">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <item row="3" column="0">
+ <widget class="QCheckBox" name="m_AddSpikes">
+ <property name="text">
+ <string>Add Spikes</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
</property>
</widget>
</item>
- </layout>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Image Settings</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="7" column="0">
- <widget class="QFrame" name="m_AdvancedSignalOptionsFrame">
+ <item row="1" column="0">
+ <widget class="QFrame" name="m_NoiseFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_23">
+ <layout class="QFormLayout" name="formLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <property name="horizontalSpacing">
- <number>6</number>
- </property>
- <item row="1" column="1">
- <widget class="QSpinBox" name="m_TEbox">
- <property name="toolTip">
- <string>TE in milliseconds</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>100</number>
- </property>
- </widget>
- </item>
<item row="1" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_13">
- <property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
+ <widget class="QLabel" name="m_NoiseLabel">
<property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Echo Time &lt;span style=&quot; font-style:italic;&quot;&gt;TE&lt;/span&gt;: &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QSpinBox" name="m_T2starBox">
- <property name="toolTip">
- <string>Relaxation time due to magnetic field inhomogeneities (T2', in milliseconds).</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>50</number>
+ <string>Variance:</string>
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QCheckBox" name="m_EnforcePureFiberVoxelsBox">
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="m_NoiseLevel">
<property name="toolTip">
- <string>Disable partial volume. Treat voxel content as fiber-only if at least one fiber is present.</string>
- </property>
- <property name="text">
- <string>Disable Partial Volume Effects</string>
- </property>
- <property name="checked">
- <bool>false</bool>
+ <string>Variance of selected noise distribution.</string>
</property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QDoubleSpinBox" name="m_LineReadoutTimeBox">
- <property name="toolTip">
- <string>T2* relaxation time (in milliseconds).</string>
+ <property name="decimals">
+ <number>4</number>
+ </property>
+ <property name="minimum">
+ <double>0.000000000000000</double>
</property>
<property name="maximum">
- <double>100.000000000000000</double>
+ <double>999999999.000000000000000</double>
</property>
<property name="singleStep">
- <double>0.100000000000000</double>
+ <double>0.001000000000000</double>
</property>
<property name="value">
- <double>1.000000000000000</double>
+ <double>50.000000000000000</double>
</property>
</widget>
</item>
- <item row="7" column="0">
- <widget class="QCheckBox" name="m_VolumeFractionsBox">
- <property name="toolTip">
- <string>Output one image per compartment containing the corresponding volume fractions per voxel.</string>
- </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_NoiseLabel_5">
<property name="text">
- <string>Output Volume Fractions</string>
- </property>
- <property name="checked">
- <bool>false</bool>
+ <string>Distribution:</string>
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_12">
+ <item row="0" column="1">
+ <widget class="QComboBox" name="m_NoiseDistributionBox">
<property name="toolTip">
- <string/>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;inhom&lt;/span&gt; Relaxation: &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
+ <string>Noise distribution</string>
</property>
+ <item>
+ <property name="text">
+ <string>Rician</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Chi-squared</string>
+ </property>
+ </item>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel_15">
+ </layout>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QCheckBox" name="m_AddGhosts">
+ <property name="text">
+ <string>Add N/2 Ghosts</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QFrame" name="m_DistortionsFrame">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QFormLayout" name="formLayout_7">
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_25">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
- <string>Line Readout Time: </string>
+ <string>Frequency Map:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="4" column="1">
- <widget class="QSpinBox" name="m_FiberRadius">
+ <item row="0" column="1">
+ <widget class="QmitkDataStorageComboBox" name="m_FrequencyMapBox">
<property name="toolTip">
- <string>Fiber radius used to calculate volume fractions (in µm). Set to 0 for automatic radius estimation.</string>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>1000</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="m_TensorsToDWINumDirsLabel_4">
- <property name="text">
- <string>Fiber Radius:</string>
+ <string>Select image specifying the frequency inhomogeneities (in Hz).</string>
</property>
</widget>
</item>
+ </layout>
+ </widget>
+ </item>
+ <item row="14" column="0">
+ <widget class="Line" name="line_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="Line" name="line_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="Line" name="line_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="16" column="0">
+ <widget class="QFrame" name="m_MotionArtifactFrame">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QFormLayout" name="formLayout_11">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWINumDirsLabel_5">
- <property name="text">
- <string>Signal Scale:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QCheckBox" name="m_RelaxationBox">
+ <widget class="QCheckBox" name="m_RandomMotion">
<property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;TE&lt;/span&gt;, &lt;span style=&quot; font-style:italic;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;inhom&lt;/span&gt; and &lt;span style=&quot; font-style:italic;&quot;&gt;T2&lt;/span&gt; will have no effect if unchecked.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>Toggle between random movement and linear movement.</string>
</property>
<property name="text">
- <string>Simulate Signal Relaxation</string>
+ <string>Randomize motion</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="m_SignalScaleBox">
- <property name="toolTip">
- <string>TE in milliseconds</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>100</number>
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="m_RotationArtifactFrame">
+ <property name="title">
+ <string>Rotation</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_19">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>9</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_36">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Degree:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_29">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>x</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_28">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Axis:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="m_MaxRotationBoxX">
+ <property name="toolTip">
+ <string>Maximum rotation around x-axis.</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>360.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QDoubleSpinBox" name="m_MaxRotationBoxZ">
+ <property name="toolTip">
+ <string>Maximum rotation around z-axis.</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>360.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>15.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_30">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>y</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_31">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>z</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QDoubleSpinBox" name="m_MaxRotationBoxY">
+ <property name="toolTip">
+ <string>Maximum rotation around y-axis.</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>360.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QGroupBox" name="m_TranslationArtifactFrame">
+ <property name="title">
+ <string>Translation</string>
</property>
+ <layout class="QGridLayout" name="gridLayout_28">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_48">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Distance:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_51">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>x</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_52">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>y</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_47">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Axis:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_53">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>z</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="m_MaxTranslationBoxX">
+ <property name="toolTip">
+ <string>Maximum translation along x-axis.</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QDoubleSpinBox" name="m_MaxTranslationBoxY">
+ <property name="toolTip">
+ <string>Maximum translation along y-axis.</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QDoubleSpinBox" name="m_MaxTranslationBoxZ">
+ <property name="toolTip">
+ <string>Maximum translation along z-axis.</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="m_GeometryMessage">
- <property name="styleSheet">
- <string notr="true">color: rgb(255, 0, 0);</string>
- </property>
+ <item row="15" column="0">
+ <widget class="QCheckBox" name="m_AddMotion">
<property name="text">
- <string>Using geometry of selected image!</string>
+ <string>Add Motion Artifacts</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="4" column="0">
- <widget class="QLabel" name="m_DiffusionPropsMessage">
- <property name="styleSheet">
- <string notr="true">color: rgb(255, 0, 0);</string>
+ <item row="12" column="0">
+ <widget class="QCheckBox" name="m_AddDistortions">
+ <property name="text">
+ <string>Add Distortions</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
</property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QCheckBox" name="m_AddAliasing">
<property name="text">
- <string>Using gradients of selected DWI!</string>
+ <string>Add Aliasing</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QFrame" name="m_GeometryFrame">
+ <item row="7" column="0">
+ <widget class="QFrame" name="m_GhostFrame">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_7">
+ <layout class="QFormLayout" name="formLayout_6">
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <item row="2" column="2">
- <widget class="QDoubleSpinBox" name="m_SpacingY">
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>0.100000000000000</double>
- </property>
- <property name="maximum">
- <double>50.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>2.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Image Spacing:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QDoubleSpinBox" name="m_SpacingZ">
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>0.100000000000000</double>
- </property>
- <property name="maximum">
- <double>50.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>2.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QDoubleSpinBox" name="m_SpacingX">
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>0.100000000000000</double>
- </property>
- <property name="maximum">
- <double>50.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>2.000000000000000</double>
- </property>
- </widget>
- </item>
<item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Image Dimensions:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="m_SizeX">
- <property name="toolTip">
- <string>Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions.</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>1000</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>11</number>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QSpinBox" name="m_SizeY">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_23">
<property name="toolTip">
- <string>Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions.</string>
+ <string/>
</property>
- <property name="minimum">
- <number>1</number>
+ <property name="statusTip">
+ <string/>
</property>
- <property name="maximum">
- <number>1000</number>
+ <property name="whatsThis">
+ <string/>
</property>
- <property name="singleStep">
- <number>1</number>
+ <property name="text">
+ <string>K-Space Line Offset:</string>
</property>
- <property name="value">
- <number>11</number>
+ <property name="wordWrap">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="0" column="3">
- <widget class="QSpinBox" name="m_SizeZ">
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="m_kOffsetBox">
<property name="toolTip">
- <string>Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions.</string>
+ <string>A larger offset increases the inensity of the ghost image.</string>
</property>
- <property name="minimum">
- <number>1</number>
+ <property name="decimals">
+ <number>3</number>
</property>
<property name="maximum">
- <number>1000</number>
+ <double>1.000000000000000</double>
</property>
<property name="singleStep">
- <number>1</number>
+ <double>0.010000000000000</double>
</property>
<property name="value">
- <number>3</number>
+ <double>0.250000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="5" column="0">
- <widget class="QFrame" name="m_TensorsToDWIFrame">
+ <item row="19" column="0">
+ <widget class="QFrame" name="m_EddyFrame">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_24">
+ <layout class="QFormLayout" name="formLayout_8">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="m_TensorsToDWINumDirsLabel">
- <property name="text">
- <string>Gradient Directions:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="m_NumGradientsBox">
- <property name="toolTip">
- <string>Number of gradient directions distributed over the half sphere.</string>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>30</number>
- </property>
- </widget>
- </item>
<item row="1" column="0">
- <widget class="QLabel" name="m_TensorsToDWIBValueLabel">
+ <widget class="QLabel" name="m_TensorsToDWIBValueLabel_26">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;b-Value&lt;span style=&quot; font-style:italic;&quot;&gt; [s/mm&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:super;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;]&lt;/span&gt;:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>Magnitude:</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
- <widget class="QSpinBox" name="m_BvalueBox">
+ <widget class="QDoubleSpinBox" name="m_EddyGradientStrength">
<property name="toolTip">
- <string>b-value in s/mm²</string>
+ <string>Maximum magnitude of eddy current induced magnetic field inhomogeneities (in mT).</string>
</property>
- <property name="minimum">
- <number>0</number>
+ <property name="decimals">
+ <number>5</number>
</property>
<property name="maximum">
- <number>10000</number>
+ <double>1000.000000000000000</double>
</property>
<property name="singleStep">
- <number>100</number>
+ <double>0.001000000000000</double>
</property>
<property name="value">
- <number>1000</number>
+ <double>0.005000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="m_DiffusionPropsMessage_2">
+ <property name="styleSheet">
+ <string notr="true">color: rgb(255, 0, 0);</string>
+ </property>
+ <property name="text">
+ <string>Experimental!</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QCheckBox" name="m_AdvancedOptionsBox_2">
- <property name="text">
- <string>Advanced Options</string>
+ <item row="5" column="0">
+ <widget class="Line" name="line_8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="Line" name="line_9">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QCommandLinkButton" name="m_GenerateImageButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Start DWI generation from selected fiber bundle.&lt;/p&gt;&lt;p&gt;If no fiber bundle but an existing diffusion weighted image is selected, the enabled artifacts are added to this image.&lt;/p&gt;&lt;p&gt;If neither a fiber bundle nor a diffusion weighted image is selected, a grayscale image containing a simple gradient is generated.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Start Simulation</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/right.ico</normaloff>:/QmitkDiffusionImaging/general_icons/right.ico</iconset>
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="8" column="0">
<widget class="QGroupBox" name="m_IntraAxonalGroupBox">
<property name="title">
<string>Intra-axonal Compartment</string>
</property>
<layout class="QGridLayout" name="gridLayout_13">
<item row="2" column="0">
<widget class="QmitkZeppelinModelParametersWidget" name="m_ZeppelinWidget1" native="true"/>
</item>
<item row="3" column="0">
<widget class="QmitkTensorModelParametersWidget" name="m_TensorWidget1" native="true"/>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="m_Compartment1Box">
<property name="toolTip">
<string>Select signal model for intra-axonal compartment.</string>
</property>
<item>
<property name="text">
<string>Stick Model</string>
</property>
</item>
<item>
<property name="text">
<string>Zeppelin Model</string>
</property>
</item>
<item>
<property name="text">
<string>Tensor Model</string>
</property>
</item>
<item>
<property name="text">
<string>PrototypeSignal</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QmitkStickModelParametersWidget" name="m_StickWidget1" native="true"/>
</item>
<item row="4" column="0">
<widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget1" native="true"/>
</item>
</layout>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QCommandLinkButton" name="m_AbortSimulationButton">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>Stop current simulation.</string>
- </property>
- <property name="text">
- <string>Abort Simulation</string>
- </property>
- <property name="icon">
- <iconset resource="../../resources/QmitkDiffusionImaging.qrc">
- <normaloff>:/QmitkDiffusionImaging/general_icons/abort.ico</normaloff>:/QmitkDiffusionImaging/general_icons/abort.ico</iconset>
- </property>
- </widget>
- </item>
- <item row="11" column="0">
- <widget class="QGroupBox" name="groupBox_6">
- <property name="title">
- <string>Extra-axonal Compartments</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_14">
- <item row="17" column="0">
- <widget class="QFrame" name="m_Comp4FractionFrame">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout_18">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="m_NoiseLabel_3">
- <property name="text">
- <string>Volume Fraction:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QmitkDataStorageComboBox" name="m_Comp4VolumeFraction">
- <property name="toolTip">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QComboBox" name="m_Compartment3Box">
- <property name="toolTip">
- <string>Select signal model for extra-axonal compartment.</string>
- </property>
- <item>
- <property name="text">
- <string>Ball Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Astrosticks Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Dot Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>PrototypeSignal</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QmitkAstrosticksModelParametersWidget" name="m_AstrosticksWidget1" native="true"/>
- </item>
- <item row="10" column="0">
- <widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget3" native="true"/>
- </item>
- <item row="15" column="0">
- <widget class="QmitkDotModelParametersWidget" name="m_DotWidget2" native="true"/>
- </item>
- <item row="9" column="0">
- <widget class="QmitkDotModelParametersWidget" name="m_DotWidget1" native="true"/>
- </item>
- <item row="11" column="0">
- <widget class="Line" name="line_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="13" column="0">
- <widget class="QmitkBallModelParametersWidget" name="m_BallWidget2" native="true"/>
- </item>
- <item row="7" column="0">
- <widget class="QmitkBallModelParametersWidget" name="m_BallWidget1" native="true"/>
- </item>
- <item row="14" column="0">
- <widget class="QmitkAstrosticksModelParametersWidget" name="m_AstrosticksWidget2" native="true"/>
- </item>
- <item row="12" column="0">
- <widget class="QComboBox" name="m_Compartment4Box">
- <property name="toolTip">
- <string>Select signal model for extra-axonal compartment.</string>
- </property>
- <item>
- <property name="text">
- <string>--</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Ball Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Astrosticks Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Dot Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Prototype Signal</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="16" column="0">
- <widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget4" native="true"/>
- </item>
- </layout>
- </widget>
- </item>
- <item row="14" column="0">
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="10" column="0">
- <widget class="QGroupBox" name="groupBox_5">
- <property name="title">
- <string>Inter-axonal Compartment</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_17">
- <item row="0" column="0">
- <widget class="QComboBox" name="m_Compartment2Box">
- <property name="toolTip">
- <string>Select signal model for intra-axonal compartment.</string>
- </property>
- <item>
- <property name="text">
- <string>--</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Stick Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Zeppelin Model</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Tensor Model</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QmitkZeppelinModelParametersWidget" name="m_ZeppelinWidget2" native="true"/>
- </item>
- <item row="2" column="0">
- <widget class="QmitkStickModelParametersWidget" name="m_StickWidget2" native="true"/>
- </item>
- <item row="3" column="0">
- <widget class="QmitkTensorModelParametersWidget" name="m_TensorWidget2" native="true"/>
- </item>
- <item row="4" column="0">
- <widget class="QmitkPrototypeSignalParametersWidget" name="m_PrototypeWidget2" native="true"/>
- </item>
- </layout>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QTextEdit" name="m_SimulationStatusText">
- <property name="font">
- <font>
- <pointsize>8</pointsize>
- </font>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
</layout>
</widget>
</widget>
</item>
<item row="2" column="0">
<widget class="QCommandLinkButton" name="m_SaveParametersButton">
<property name="text">
<string>Save Parameters</string>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/general_icons/download.ico</normaloff>:/QmitkDiffusionImaging/general_icons/download.ico</iconset>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QmitkDataStorageComboBox</class>
<extends>QComboBox</extends>
<header location="global">QmitkDataStorageComboBox.h</header>
</customwidget>
<customwidget>
<class>QmitkTensorModelParametersWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkTensorModelParametersWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QmitkStickModelParametersWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkStickModelParametersWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QmitkZeppelinModelParametersWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkZeppelinModelParametersWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QmitkBallModelParametersWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkBallModelParametersWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QmitkAstrosticksModelParametersWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkAstrosticksModelParametersWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QmitkDotModelParametersWidget</class>
<extends>QWidget</extends>
<header>QmitkDotModelParametersWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QmitkPrototypeSignalParametersWidget</class>
<extends>QWidget</extends>
<header>QmitkPrototypeSignalParametersWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>m_CircleButton</tabstop>
<tabstop>m_FlipButton</tabstop>
<tabstop>m_RealTimeFibers</tabstop>
<tabstop>m_AdvancedOptionsBox</tabstop>
<tabstop>m_DistributionBox</tabstop>
<tabstop>m_VarianceBox</tabstop>
<tabstop>m_FiberDensityBox</tabstop>
<tabstop>m_FiberSamplingBox</tabstop>
<tabstop>m_TensionBox</tabstop>
<tabstop>m_ContinuityBox</tabstop>
<tabstop>m_BiasBox</tabstop>
<tabstop>m_GenerateFibersButton</tabstop>
<tabstop>m_ConstantRadiusBox</tabstop>
<tabstop>m_AlignOnGrid</tabstop>
<tabstop>m_XrotBox</tabstop>
<tabstop>m_YrotBox</tabstop>
<tabstop>m_ZrotBox</tabstop>
<tabstop>m_XtransBox</tabstop>
<tabstop>m_YtransBox</tabstop>
<tabstop>m_ZtransBox</tabstop>
<tabstop>m_XscaleBox</tabstop>
<tabstop>m_YscaleBox</tabstop>
<tabstop>m_ZscaleBox</tabstop>
<tabstop>m_TransformBundlesButton</tabstop>
<tabstop>m_CopyBundlesButton</tabstop>
<tabstop>m_JoinBundlesButton</tabstop>
<tabstop>m_IncludeFiducials</tabstop>
<tabstop>m_GenerateImageButton</tabstop>
<tabstop>m_SizeX</tabstop>
<tabstop>m_SizeY</tabstop>
<tabstop>m_SizeZ</tabstop>
<tabstop>m_SpacingX</tabstop>
<tabstop>m_SpacingY</tabstop>
<tabstop>m_SpacingZ</tabstop>
<tabstop>m_NumGradientsBox</tabstop>
<tabstop>m_BvalueBox</tabstop>
<tabstop>m_AdvancedOptionsBox_2</tabstop>
<tabstop>m_SignalScaleBox</tabstop>
<tabstop>m_TEbox</tabstop>
<tabstop>m_LineReadoutTimeBox</tabstop>
<tabstop>m_T2starBox</tabstop>
<tabstop>m_FiberRadius</tabstop>
<tabstop>m_RelaxationBox</tabstop>
<tabstop>m_EnforcePureFiberVoxelsBox</tabstop>
<tabstop>m_VolumeFractionsBox</tabstop>
<tabstop>m_Compartment1Box</tabstop>
<tabstop>m_Compartment2Box</tabstop>
<tabstop>m_Compartment3Box</tabstop>
<tabstop>m_Compartment4Box</tabstop>
<tabstop>m_AddNoise</tabstop>
<tabstop>m_NoiseLevel</tabstop>
<tabstop>m_AddSpikes</tabstop>
<tabstop>m_SpikeNumBox</tabstop>
<tabstop>m_SpikeScaleBox</tabstop>
<tabstop>m_AddGhosts</tabstop>
<tabstop>m_kOffsetBox</tabstop>
<tabstop>m_AddAliasing</tabstop>
<tabstop>m_WrapBox</tabstop>
<tabstop>m_AddDistortions</tabstop>
<tabstop>m_FrequencyMapBox</tabstop>
<tabstop>m_AddMotion</tabstop>
<tabstop>m_RandomMotion</tabstop>
<tabstop>m_MaxRotationBoxX</tabstop>
<tabstop>m_MaxRotationBoxY</tabstop>
<tabstop>m_MaxRotationBoxZ</tabstop>
<tabstop>m_MaxTranslationBoxX</tabstop>
<tabstop>m_MaxTranslationBoxY</tabstop>
<tabstop>m_MaxTranslationBoxZ</tabstop>
<tabstop>m_AddEddy</tabstop>
<tabstop>m_EddyGradientStrength</tabstop>
<tabstop>m_AddGibbsRinging</tabstop>
<tabstop>m_SaveParametersButton</tabstop>
<tabstop>m_LoadParametersButton</tabstop>
<tabstop>tabWidget</tabstop>
</tabstops>
<resources>
<include location="../../resources/QmitkDiffusionImaging.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.ext/documentation/UserManual/MITKUserManual.dox b/Plugins/org.mitk.gui.qt.ext/documentation/UserManual/MITKUserManual.dox
index 150516b830..2085c66129 100644
--- a/Plugins/org.mitk.gui.qt.ext/documentation/UserManual/MITKUserManual.dox
+++ b/Plugins/org.mitk.gui.qt.ext/documentation/UserManual/MITKUserManual.dox
@@ -1,115 +1,117 @@
/**
\page MITKUserManualPage The MITK User Manual
Welcome to the basic MITK user manual. This document tries to give a concise overview of the basic functions of MITK and be an comprehensible guide on using them.
\tableofcontents
\section MITKUserManualPageOverview About MITK
MITK is an open-source framework that was originally developed as a common framework for Ph.D. students in the Division of Medical and Biological Informatics (MBI) at the German Cancer Research Center. MITK aims at supporting the development of leading-edge medical imaging software with a high degree of interaction.
MITK re-uses virtually anything from VTK and ITK. Thus, it is not at all a competitor to VTK or ITK, but an extension, which tries to ease the combination of both and to add features not supported by VTK or ITK.
Research institutes, medical professionals and companies alike can use MITK as a basic framework for their research and even commercial (thorough code research needed) software due to the BSD-like software license.
Research institutes will profit from the high level of integration of ITK and VTK enhanced with data management, advanced visualization and interaction functionality in a single framework that is supported by a wide variety of researchers and developers. You will not have to reinvent the wheel over and over and can concentrate on your work.
Medical Professionals will profit from MITK and the MITK applications by using its basic functionalities for research projects. But nonetheless they will be better off, unless they are programmers themselves, to cooperate with a research institute developing with MITK to get the functionalitiy they need. MITK and the MITK applications are not certified medical products and may be used in a research setting only. They must not be used in patient care.
\section MITKUserManualPageUserInterface The User Interface
The layout of the MITK applications is designed to give a clear distinction between the different work areas. The following figure gives an overview of the main sections of the user interface.
\imageMacro{MITKUserManual_GUICommented.png,"The Common MITK Application Graphical User Interface",16.00}
The datamanager and the \ref MITKUserManualPagePerspectives have their own help sections. This document explains the use of:
- The \ref MITKUserManualPageMultiWidget
- The \ref MITKUserManualPageMenu
- The \ref MITKUserManualPageLevelWindow
- The \ref MITKUserManualPageMemoryUsage
- The \ref MITKUserManualPageViews
\section MITKUserManualPageMultiWidget Four Window View
\subsection MITKUserManualPageMultiWidgetOverview Overview
The four window view is the heart of the MITK image viewing. The standard layout is three 2D windows and one 3D window, with the axial window in the top left quarter, the sagittal window in the top right quarter, the coronal window in the lower left quarter and the 3D window in the lower right quarter. The different planes form a crosshair that can be seen in the 3D window.
Once you select a point within the picture, informations about it are displayed at the bottom of the screen.
\subsection MITKUserManualPageMultiWidgetNavigation Navigation
Left click in any of the 2D windows centers the crosshair on that point. Pressing the right mouse button and moving the mouse <B>zooms</B> in and out. By scrolling with the mouse wheel you can <B>navigate through</B> the slices of the active window and pressing the mouse wheel while moving the mouse <B>pans</B> the image section.
In the 3D window you can <B>rotate</B> the object by pressing the left mouse button and moving the mouse, <B>zoom</B> either with the right mouse button as in 2D or with the mouse wheel, and <B>pan</B> the object by moving the mouse while the mouse wheel is pressed. Placing the cursor within the 3D window and holding the "F" key allows <B>free flight</B> into the 3D view.
\subsection MITKUserManualPageMultiWidgetCustomizingViews Customizing
By moving the cursor to the upper right corner of any window you can activate the window menu. It consists of three buttons.
\imageMacro{MITKUserManual_CrosshairModes.png,"Crosshair",8.72}
The crosshair button allows you toggle the crosshair, reset the view and change the behaviour of the planes.
Activating either of the rotation modes allows you to rotate the planes visible in a 2D window by moving the mouse cursor close to them and click and dragging once it changes to indicate that rotation can be done.
The swivel mode is recommended only for advanced users as the planes can be moved freely by clicking and dragging anywhere within a 2D window.
The middle button expands the corresponding window to fullscreen within the four window view.
\imageMacro{MITKUserManual_ViewsChoices.png,"Layout Choices",5.19}
The right button allows you to choose between many different layouts of the four window view to use the one most suited to your task.
\section MITKUserManualPageMenu Menu
\subsection MITKUserManualPageFile File
This dialog allows you to save, load and clear entire projects, this includes any nodes in the data manager.
\subsection MITKUserManualPageEdit Edit
This dialog supports undo and redo operations as well as the image navigator, which gives you sliders to navigate through the data quickly.
\subsection MITKUserManualPageWindow Window
This dialog allows you to open a new window, change between perspectives and reset your current one to default settings.
If you want to use an operation of a certain perspective within another perspective the "Show View" menu allows to select a specific function that is opened and can be moved within the working areas according to your wishes. Be aware that not every function works with every perspective in a meaningful way.
The Preferences dialog allows you to adjust and save your custom settings.
\imageMacro{MITKUserManual_WindowDropdown.png,"Preferences",4.89}
\subsection MITKUserManualPageHelp Help
This dialog contains this help, the welcome screen and information about MITK.
\section MITKUserManualPageLevelWindow Levelwindow
Once an image is loaded the levelwindow appears to the right hand side of the four window view. With this tool you can adjust the range of grey values displayed and the gradient between them. Moving the lower boundary up results in any pixels having a value lower than that boundary to be displayed as black. Lowering the upper boundary causes all pixels having a value higher than it to be displayed as white.
The pixels with a value between the lower and upper boundary are displayed in different shades of grey. This way a smaller levelwindow results in higher contrasts while cutting of the information outside its range whereas a larger levelwindow displays more information at the cost of contrast and detail.
You can pick the levelwindow with the mouse to move it up and down, while moving the mouse cursor to the left or right to change its size. Picking one of the boundaries with a left click allows you to change the size symmetrically. Holding CTRL and clicking a boundary adjusts only that value.
+With line edit fields below you can directly adjust the levelwindow. The upper field describes the center of the levelwindow, the bottom the span of the window around the center. By selecting one of fields and typing any number you can set these two parameters.
+
\section MITKUserManualPageMemoryUsage System Load Indicator
The System Load Indicator in the lower right hand corner of the screen gives information about the memory currently required by the MITK application. Keep in mind that image processing is a highly memory intensive task and monitor the indicator to avoid your system freezing while constantly swapping to the hard drive.
\section MITKUserManualPageViews Views
Each solution for a specific problem that is self contained is realized as a single view. Thus you can create a workflow for your problem by combining the capabilities of different views to suit your needs.
One elegant way to do this is by combining views in \ref MITKUserManualPagePerspectives.
By pressing and holding the left mouse button on a views tab you can move it around to suit your needs, even out of the application window.
\section MITKUserManualPagePerspectives Perspectives
The different tasks that arise in medical imaging need very different approaches. To acknowledge this circumstance MITK supplies a framework that can be build uppon by very different solutions to those tasks. These solutions are called perspectives, each of them works independently of others although they might be used in sequence to achieve the solution of more difficult problems.
It is possible to switch between the perspectives using the "Window"->"Open Perspective" dialog.
See \ref MITKUserManualPageMenu for more information about switching perspectives.
*/
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/Candy_icon.png b/Plugins/org.mitk.gui.qt.ext/resources/Candy_icon.png
deleted file mode 100644
index f71e77664c..0000000000
Binary files a/Plugins/org.mitk.gui.qt.ext/resources/Candy_icon.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc
index 60cefbb18c..c47d801dd4 100644
--- a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc
+++ b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc
@@ -1,14 +1,14 @@
<RCC>
<qresource prefix="/org.mitk.gui.qt.ext">
<file>Load_48.png</file>
<file>Redo_48.png</file>
<file>Save_48.png</file>
<file>Undo_48.png</file>
<file>Remove_48.png</file>
<file>dcm-icon.png</file>
<file>Slider.png</file>
<file>index.html</file>
<file>xnat-icon.png</file>
- <file>Candy_icon.png</file>
+ <file>view-manager_48.png</file>
</qresource>
</RCC>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/view-manager_48.png b/Plugins/org.mitk.gui.qt.ext/resources/view-manager_48.png
new file mode 100644
index 0000000000..429a977eed
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.ext/resources/view-manager_48.png differ
diff --git a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp
index 6db9cb8e66..4eb0392a16 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp
+++ b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp
@@ -1,1322 +1,1322 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkExtWorkbenchWindowAdvisor.h"
#include "QmitkExtActionBarAdvisor.h"
#include <QMenu>
#include <QMenuBar>
#include <QMainWindow>
#include <QStatusBar>
#include <QString>
#include <QFile>
#include <QRegExp>
#include <QTextStream>
#include <QSettings>
#include <ctkPluginException.h>
#include <service/event/ctkEventAdmin.h>
#include <berryPlatform.h>
#include <berryPlatformUI.h>
#include <berryIWorkbenchWindow.h>
#include <berryIWorkbenchPage.h>
#include <berryIPreferencesService.h>
#include <berryIPerspectiveRegistry.h>
#include <berryIPerspectiveDescriptor.h>
#include <berryIWorkbenchPartConstants.h>
#include <internal/berryQtShowViewAction.h>
#include <internal/berryQtOpenPerspectiveAction.h>
#include <QmitkFileOpenAction.h>
#include <QmitkExtFileSaveProjectAction.h>
#include <QmitkFileExitAction.h>
#include <QmitkCloseProjectAction.h>
#include <QmitkDefaultDropTargetListener.h>
#include <QmitkStatusBar.h>
#include <QmitkProgressBar.h>
#include <QmitkMemoryUsageIndicatorView.h>
#include <QmitkPreferencesDialog.h>
#include <QmitkOpenDicomEditorAction.h>
#include <QmitkOpenXnatEditorAction.h>
#include <itkConfigure.h>
#include <vtkConfigure.h>
#include <mitkVersion.h>
#include <mitkIDataStorageService.h>
#include <mitkIDataStorageReference.h>
#include <mitkDataStorageEditorInput.h>
#include <mitkWorkbenchUtil.h>
#include <vtkVersionMacros.h>
// UGLYYY
#include "internal/QmitkExtWorkbenchWindowAdvisorHack.h"
#include "internal/QmitkCommonExtPlugin.h"
#include "mitkUndoController.h"
#include "mitkVerboseLimitedLinearUndo.h"
#include <QToolBar>
#include <QMessageBox>
#include <QLabel>
#include <QmitkAboutDialog/QmitkAboutDialog.h>
QmitkExtWorkbenchWindowAdvisorHack
* QmitkExtWorkbenchWindowAdvisorHack::undohack =
new QmitkExtWorkbenchWindowAdvisorHack();
QString QmitkExtWorkbenchWindowAdvisor::QT_SETTINGS_FILENAME = "QtSettings.ini";
class PartListenerForTitle: public berry::IPartListener
{
public:
PartListenerForTitle(QmitkExtWorkbenchWindowAdvisor* wa) :
windowAdvisor(wa)
{
}
Events::Types GetPartEventTypes() const
{
return Events::ACTIVATED | Events::BROUGHT_TO_TOP | Events::CLOSED
| Events::HIDDEN | Events::VISIBLE;
}
void PartActivated(berry::IWorkbenchPartReference::Pointer ref)
{
if (ref.Cast<berry::IEditorReference> ())
{
windowAdvisor->UpdateTitle(false);
}
}
void PartBroughtToTop(berry::IWorkbenchPartReference::Pointer ref)
{
if (ref.Cast<berry::IEditorReference> ())
{
windowAdvisor->UpdateTitle(false);
}
}
void PartClosed(berry::IWorkbenchPartReference::Pointer /*ref*/)
{
windowAdvisor->UpdateTitle(false);
}
void PartHidden(berry::IWorkbenchPartReference::Pointer ref)
{
if (!windowAdvisor->lastActiveEditor.Expired() &&
ref->GetPart(false) == windowAdvisor->lastActiveEditor.Lock())
{
windowAdvisor->UpdateTitle(true);
}
}
void PartVisible(berry::IWorkbenchPartReference::Pointer ref)
{
if (!windowAdvisor->lastActiveEditor.Expired() &&
ref->GetPart(false) == windowAdvisor->lastActiveEditor.Lock())
{
windowAdvisor->UpdateTitle(false);
}
}
private:
QmitkExtWorkbenchWindowAdvisor* windowAdvisor;
};
-class PartListenerForCandyStore: public berry::IPartListener
+class PartListenerForViewNavigator: public berry::IPartListener
{
public:
- PartListenerForCandyStore(QAction* act) :
- candyStoreAction(act)
+ PartListenerForViewNavigator(QAction* act) :
+ viewNavigatorAction(act)
{
}
Events::Types GetPartEventTypes() const
{
return Events::OPENED | Events::CLOSED | Events::HIDDEN |
Events::VISIBLE;
}
void PartOpened(berry::IWorkbenchPartReference::Pointer ref)
{
- if (ref->GetId()=="org.mitk.views.candystoreview")
+ if (ref->GetId()=="org.mitk.views.viewnavigatorview")
{
- candyStoreAction->setChecked(true);
+ viewNavigatorAction->setChecked(true);
}
}
void PartClosed(berry::IWorkbenchPartReference::Pointer ref)
{
- if (ref->GetId()=="org.mitk.views.candystoreview")
+ if (ref->GetId()=="org.mitk.views.viewnavigatorview")
{
- candyStoreAction->setChecked(false);
+ viewNavigatorAction->setChecked(false);
}
}
void PartVisible(berry::IWorkbenchPartReference::Pointer ref)
{
- if (ref->GetId()=="org.mitk.views.candystoreview")
+ if (ref->GetId()=="org.mitk.views.viewnavigatorview")
{
- candyStoreAction->setChecked(true);
+ viewNavigatorAction->setChecked(true);
}
}
void PartHidden(berry::IWorkbenchPartReference::Pointer ref)
{
- if (ref->GetId()=="org.mitk.views.candystoreview")
+ if (ref->GetId()=="org.mitk.views.viewnavigatorview")
{
- candyStoreAction->setChecked(false);
+ viewNavigatorAction->setChecked(false);
}
}
private:
- QAction* candyStoreAction;
+ QAction* viewNavigatorAction;
};
class PartListenerForImageNavigator: public berry::IPartListener
{
public:
PartListenerForImageNavigator(QAction* act) :
imageNavigatorAction(act)
{
}
Events::Types GetPartEventTypes() const
{
return Events::OPENED | Events::CLOSED | Events::HIDDEN |
Events::VISIBLE;
}
void PartOpened(berry::IWorkbenchPartReference::Pointer ref)
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(true);
}
}
void PartClosed(berry::IWorkbenchPartReference::Pointer ref)
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(false);
}
}
void PartVisible(berry::IWorkbenchPartReference::Pointer ref)
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(true);
}
}
void PartHidden(berry::IWorkbenchPartReference::Pointer ref)
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(false);
}
}
private:
QAction* imageNavigatorAction;
};
class PerspectiveListenerForTitle: public berry::IPerspectiveListener
{
public:
PerspectiveListenerForTitle(QmitkExtWorkbenchWindowAdvisor* wa) :
windowAdvisor(wa), perspectivesClosed(false)
{
}
Events::Types GetPerspectiveEventTypes() const
{
return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED
// remove the following line when command framework is finished
| Events::CLOSED | Events::OPENED;
}
void PerspectiveActivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
windowAdvisor->UpdateTitle(false);
}
void PerspectiveSavedAs(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*oldPerspective*/,
berry::IPerspectiveDescriptor::Pointer /*newPerspective*/)
{
windowAdvisor->UpdateTitle(false);
}
void PerspectiveDeactivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
windowAdvisor->UpdateTitle(false);
}
void PerspectiveOpened(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
if (perspectivesClosed)
{
QListIterator<QAction*> i(windowAdvisor->viewActions);
while (i.hasNext())
{
i.next()->setEnabled(true);
}
//GetViewRegistry()->Find("org.mitk.views.imagenavigator");
if(windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicomeditor"))
{
windowAdvisor->openDicomEditorAction->setEnabled(true);
}
if(windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.xnat.browser"))
{
windowAdvisor->openXnatEditorAction->setEnabled(true);
}
windowAdvisor->fileSaveProjectAction->setEnabled(true);
windowAdvisor->closeProjectAction->setEnabled(true);
windowAdvisor->undoAction->setEnabled(true);
windowAdvisor->redoAction->setEnabled(true);
windowAdvisor->imageNavigatorAction->setEnabled(true);
- windowAdvisor->candyStoreAction->setEnabled(true);
+ windowAdvisor->viewNavigatorAction->setEnabled(true);
windowAdvisor->resetPerspAction->setEnabled(true);
if( windowAdvisor->GetShowClosePerspectiveMenuItem() )
{
windowAdvisor->closePerspAction->setEnabled(true);
}
}
perspectivesClosed = false;
}
void PerspectiveClosed(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
berry::IWorkbenchWindow::Pointer wnd = windowAdvisor->GetWindowConfigurer()->GetWindow();
bool allClosed = true;
if (wnd->GetActivePage())
{
std::vector<berry::IPerspectiveDescriptor::Pointer> perspectives(wnd->GetActivePage()->GetOpenPerspectives());
allClosed = perspectives.empty();
}
if (allClosed)
{
perspectivesClosed = true;
QListIterator<QAction*> i(windowAdvisor->viewActions);
while (i.hasNext())
{
i.next()->setEnabled(false);
}
if(windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicomeditor"))
{
windowAdvisor->openDicomEditorAction->setEnabled(false);
}
if(windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.xnat.browser"))
{
windowAdvisor->openXnatEditorAction->setEnabled(false);
}
windowAdvisor->fileSaveProjectAction->setEnabled(false);
windowAdvisor->closeProjectAction->setEnabled(false);
windowAdvisor->undoAction->setEnabled(false);
windowAdvisor->redoAction->setEnabled(false);
windowAdvisor->imageNavigatorAction->setEnabled(false);
- windowAdvisor->candyStoreAction->setEnabled(false);
+ windowAdvisor->viewNavigatorAction->setEnabled(false);
windowAdvisor->resetPerspAction->setEnabled(false);
if( windowAdvisor->GetShowClosePerspectiveMenuItem() )
{
windowAdvisor->closePerspAction->setEnabled(false);
}
}
}
private:
QmitkExtWorkbenchWindowAdvisor* windowAdvisor;
bool perspectivesClosed;
};
class PerspectiveListenerForMenu: public berry::IPerspectiveListener
{
public:
PerspectiveListenerForMenu(QmitkExtWorkbenchWindowAdvisor* wa) :
windowAdvisor(wa)
{
}
Events::Types GetPerspectiveEventTypes() const
{
return Events::ACTIVATED | Events::DEACTIVATED;
}
void PerspectiveActivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer perspective)
{
QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()];
if (action)
{
action->setChecked(true);
}
}
void PerspectiveDeactivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer perspective)
{
QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()];
if (action)
{
action->setChecked(false);
}
}
private:
QmitkExtWorkbenchWindowAdvisor* windowAdvisor;
};
QmitkExtWorkbenchWindowAdvisor::QmitkExtWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor,
berry::IWorkbenchWindowConfigurer::Pointer configurer) :
berry::WorkbenchWindowAdvisor(configurer),
lastInput(0),
wbAdvisor(wbAdvisor),
showViewToolbar(true),
showPerspectiveToolbar(false),
showVersionInfo(true),
showMitkVersionInfo(true),
showViewMenuItem(true),
showNewWindowMenuItem(false),
showClosePerspectiveMenuItem(true),
- candyStoreFound(false),
+ viewNavigatorFound(false),
showMemoryIndicator(true),
dropTargetListener(new QmitkDefaultDropTargetListener)
{
productName = QCoreApplication::applicationName().toStdString();
- viewExcludeList.push_back("org.mitk.views.candystoreview");
+ viewExcludeList.push_back("org.mitk.views.viewnavigatorview");
}
berry::ActionBarAdvisor::Pointer QmitkExtWorkbenchWindowAdvisor::CreateActionBarAdvisor(
berry::IActionBarConfigurer::Pointer configurer)
{
berry::ActionBarAdvisor::Pointer actionBarAdvisor(
new QmitkExtActionBarAdvisor(configurer));
return actionBarAdvisor;
}
void* QmitkExtWorkbenchWindowAdvisor::CreateEmptyWindowContents(void* parent)
{
QWidget* parentWidget = static_cast<QWidget*>(parent);
QLabel* label = new QLabel(parentWidget);
label->setText("<b>No perspectives are open. Open a perspective in the <i>Window->Open Perspective</i> menu.</b>");
label->setContentsMargins(10,10,10,10);
label->setAlignment(Qt::AlignTop);
label->setEnabled(false);
parentWidget->layout()->addWidget(label);
return label;
}
void QmitkExtWorkbenchWindowAdvisor::ShowClosePerspectiveMenuItem(bool show)
{
showClosePerspectiveMenuItem = show;
}
bool QmitkExtWorkbenchWindowAdvisor::GetShowClosePerspectiveMenuItem()
{
return showClosePerspectiveMenuItem;
}
void QmitkExtWorkbenchWindowAdvisor::ShowMemoryIndicator(bool show)
{
showMemoryIndicator = show;
}
bool QmitkExtWorkbenchWindowAdvisor::GetShowMemoryIndicator()
{
return showMemoryIndicator;
}
void QmitkExtWorkbenchWindowAdvisor::ShowNewWindowMenuItem(bool show)
{
showNewWindowMenuItem = show;
}
void QmitkExtWorkbenchWindowAdvisor::ShowViewToolbar(bool show)
{
showViewToolbar = show;
}
void QmitkExtWorkbenchWindowAdvisor::ShowViewMenuItem(bool show)
{
showViewMenuItem = show;
}
void QmitkExtWorkbenchWindowAdvisor::ShowPerspectiveToolbar(bool show)
{
showPerspectiveToolbar = show;
}
void QmitkExtWorkbenchWindowAdvisor::ShowVersionInfo(bool show)
{
showVersionInfo = show;
}
void QmitkExtWorkbenchWindowAdvisor::ShowMitkVersionInfo(bool show)
{
showMitkVersionInfo = show;
}
void QmitkExtWorkbenchWindowAdvisor::SetProductName(const std::string& product)
{
productName = product;
}
void QmitkExtWorkbenchWindowAdvisor::SetWindowIcon(const std::string& wndIcon)
{
windowIcon = wndIcon;
}
void QmitkExtWorkbenchWindowAdvisor::PostWindowCreate()
{
// very bad hack...
berry::IWorkbenchWindow::Pointer window =
this->GetWindowConfigurer()->GetWindow();
QMainWindow* mainWindow =
static_cast<QMainWindow*> (window->GetShell()->GetControl());
window->SetPerspectiveExcludeList(perspectiveExcludeList);
window->SetViewExcludeList(viewExcludeList);
if (!windowIcon.empty())
{
mainWindow->setWindowIcon(QIcon(QString::fromStdString(windowIcon)));
}
mainWindow->setContextMenuPolicy(Qt::PreventContextMenu);
/*mainWindow->setStyleSheet("color: white;"
"background-color: #808080;"
"selection-color: #659EC7;"
"selection-background-color: #808080;"
" QMenuBar {"
"background-color: #808080; }");*/
// ==== Application menu ============================
QMenuBar* menuBar = mainWindow->menuBar();
menuBar->setContextMenuPolicy(Qt::PreventContextMenu);
QMenu* fileMenu = menuBar->addMenu("&File");
fileMenu->setObjectName("FileMenu");
QAction* fileOpenAction = new QmitkFileOpenAction(QIcon(":/org.mitk.gui.qt.ext/Load_48.png"), window);
fileMenu->addAction(fileOpenAction);
fileSaveProjectAction = new QmitkExtFileSaveProjectAction(window);
fileSaveProjectAction->setIcon(QIcon(":/org.mitk.gui.qt.ext/Save_48.png"));
fileMenu->addAction(fileSaveProjectAction);
closeProjectAction = new QmitkCloseProjectAction(window);
closeProjectAction->setIcon(QIcon(":/org.mitk.gui.qt.ext/Remove_48.png"));
fileMenu->addAction(closeProjectAction);
fileMenu->addSeparator();
QAction* fileExitAction = new QmitkFileExitAction(window);
fileExitAction->setObjectName("QmitkFileExitAction");
fileMenu->addAction(fileExitAction);
if(this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicomeditor"))
{
openDicomEditorAction = new QmitkOpenDicomEditorAction(QIcon(":/org.mitk.gui.qt.ext/dcm-icon.png"),window);
}
if(this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.xnat.browser"))
{
openXnatEditorAction = new QmitkOpenXnatEditorAction(QIcon(":/org.mitk.gui.qt.ext/xnat-icon.png"),window);
}
berry::IViewRegistry* viewRegistry =
berry::PlatformUI::GetWorkbench()->GetViewRegistry();
const std::vector<berry::IViewDescriptor::Pointer>& viewDescriptors =
viewRegistry->GetViews();
// another bad hack to get an edit/undo menu...
QMenu* editMenu = menuBar->addMenu("&Edit");
undoAction = editMenu->addAction(QIcon(":/org.mitk.gui.qt.ext/Undo_48.png"),
"&Undo",
QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onUndo()),
QKeySequence("CTRL+Z"));
undoAction->setToolTip("Undo the last action (not supported by all modules)");
redoAction = editMenu->addAction(QIcon(":/org.mitk.gui.qt.ext/Redo_48.png")
, "&Redo",
QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onRedo()),
QKeySequence("CTRL+Y"));
redoAction->setToolTip("execute the last action that was undone again (not supported by all modules)");
imageNavigatorAction = new QAction(QIcon(":/org.mitk.gui.qt.ext/Slider.png"), "&Image Navigator", NULL);
bool imageNavigatorViewFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.imagenavigator");
if (imageNavigatorViewFound)
{
QObject::connect(imageNavigatorAction, SIGNAL(triggered(bool)), QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onImageNavigator()));
imageNavigatorAction->setCheckable(true);
// add part listener for image navigator
imageNavigatorPartListener = new PartListenerForImageNavigator(imageNavigatorAction);
window->GetPartService()->AddPartListener(imageNavigatorPartListener);
berry::IViewPart::Pointer imageNavigatorView =
window->GetActivePage()->FindView("org.mitk.views.imagenavigator");
imageNavigatorAction->setChecked(false);
if (imageNavigatorView)
{
bool isImageNavigatorVisible = window->GetActivePage()->IsPartVisible(imageNavigatorView);
if (isImageNavigatorVisible)
imageNavigatorAction->setChecked(true);
}
imageNavigatorAction->setToolTip("Toggle image navigator for navigating through image");
}
- candyStoreAction = new QAction(QIcon(":/org.mitk.gui.qt.ext/Candy_icon.png"), "&Candy Store", NULL);
- candyStoreFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.candystoreview");
- if (candyStoreFound)
+ viewNavigatorAction = new QAction(QIcon(":/org.mitk.gui.qt.ext/view-manager_48.png"),"&View Navigator", NULL);
+ viewNavigatorFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.viewnavigatorview");
+ if (viewNavigatorFound)
{
- QObject::connect(candyStoreAction, SIGNAL(triggered(bool)), QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onCandyStore()));
- candyStoreAction->setCheckable(true);
+ QObject::connect(viewNavigatorAction, SIGNAL(triggered(bool)), QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onViewNavigator()));
+ viewNavigatorAction->setCheckable(true);
- // add part listener for candy store
- candyStorePartListener = new PartListenerForCandyStore(candyStoreAction);
- window->GetPartService()->AddPartListener(candyStorePartListener);
- berry::IViewPart::Pointer candystoreview =
- window->GetActivePage()->FindView("org.mitk.views.candystoreview");
- candyStoreAction->setChecked(false);
- if (candystoreview)
+ // add part listener for view navigator
+ viewNavigatorPartListener = new PartListenerForViewNavigator(viewNavigatorAction);
+ window->GetPartService()->AddPartListener(viewNavigatorPartListener);
+ berry::IViewPart::Pointer viewnavigatorview =
+ window->GetActivePage()->FindView("org.mitk.views.viewnavigatorview");
+ viewNavigatorAction->setChecked(false);
+ if (viewnavigatorview)
{
- bool isCandyStoreVisible = window->GetActivePage()->IsPartVisible(candystoreview);
- if (isCandyStoreVisible)
- candyStoreAction->setChecked(true);
+ bool isViewNavigatorVisible = window->GetActivePage()->IsPartVisible(viewnavigatorview);
+ if (isViewNavigatorVisible)
+ viewNavigatorAction->setChecked(true);
}
- candyStoreAction->setToolTip("Toggle Candy Store");
+ viewNavigatorAction->setToolTip("Toggle View Navigator");
}
// toolbar for showing file open, undo, redo and other main actions
QToolBar* mainActionsToolBar = new QToolBar;
mainActionsToolBar->setObjectName("mainActionsToolBar");
mainActionsToolBar->setContextMenuPolicy(Qt::PreventContextMenu);
#ifdef __APPLE__
mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon );
#else
mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
#endif
mainActionsToolBar->addAction(fileOpenAction);
mainActionsToolBar->addAction(fileSaveProjectAction);
mainActionsToolBar->addAction(closeProjectAction);
mainActionsToolBar->addAction(undoAction);
mainActionsToolBar->addAction(redoAction);
if(this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicomeditor"))
{
mainActionsToolBar->addAction(openDicomEditorAction);
}
if(this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.xnat.browser"))
{
mainActionsToolBar->addAction(openXnatEditorAction);
}
if (imageNavigatorViewFound)
{
mainActionsToolBar->addAction(imageNavigatorAction);
}
- if (candyStoreFound)
- mainActionsToolBar->addAction(candyStoreAction);
+ if (viewNavigatorFound)
+ mainActionsToolBar->addAction(viewNavigatorAction);
mainWindow->addToolBar(mainActionsToolBar);
#ifdef __APPLE__
mainWindow->setUnifiedTitleAndToolBarOnMac(true);
#endif
// ==== Window Menu ==========================
QMenu* windowMenu = menuBar->addMenu("Window");
if (showNewWindowMenuItem)
{
windowMenu->addAction("&New Window", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onNewWindow()));
windowMenu->addSeparator();
}
QMenu* perspMenu = windowMenu->addMenu("&Open Perspective");
QMenu* viewMenu;
if (showViewMenuItem)
{
viewMenu = windowMenu->addMenu("Show &View");
viewMenu->setObjectName("Show View");
}
windowMenu->addSeparator();
resetPerspAction = windowMenu->addAction("&Reset Perspective",
QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onResetPerspective()));
if(showClosePerspectiveMenuItem)
closePerspAction = windowMenu->addAction("&Close Perspective", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onClosePerspective()));
windowMenu->addSeparator();
windowMenu->addAction("&Preferences...",
QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onEditPreferences()),
QKeySequence("CTRL+P"));
// fill perspective menu
berry::IPerspectiveRegistry* perspRegistry =
window->GetWorkbench()->GetPerspectiveRegistry();
QActionGroup* perspGroup = new QActionGroup(menuBar);
std::vector<berry::IPerspectiveDescriptor::Pointer> perspectives(
perspRegistry->GetPerspectives());
bool skip = false;
for (std::vector<berry::IPerspectiveDescriptor::Pointer>::iterator perspIt =
perspectives.begin(); perspIt != perspectives.end(); ++perspIt)
{
// if perspectiveExcludeList is set, it contains the id-strings of perspectives, which
// should not appear as an menu-entry in the perspective menu
if (perspectiveExcludeList.size() > 0)
{
for (unsigned int i=0; i<perspectiveExcludeList.size(); i++)
{
if (perspectiveExcludeList.at(i) == (*perspIt)->GetId())
{
skip = true;
break;
}
}
if (skip)
{
skip = false;
continue;
}
}
QAction* perspAction = new berry::QtOpenPerspectiveAction(window,
*perspIt, perspGroup);
mapPerspIdToAction.insert(std::make_pair((*perspIt)->GetId(), perspAction));
}
perspMenu->addActions(perspGroup->actions());
// sort elements (converting vector to map...)
std::vector<berry::IViewDescriptor::Pointer>::const_iterator iter;
std::map<std::string, berry::IViewDescriptor::Pointer> VDMap;
skip = false;
for (iter = viewDescriptors.begin(); iter != viewDescriptors.end(); ++iter)
{
// if viewExcludeList is set, it contains the id-strings of view, which
// should not appear as an menu-entry in the menu
if (viewExcludeList.size() > 0)
{
for (unsigned int i=0; i<viewExcludeList.size(); i++)
{
if (viewExcludeList.at(i) == (*iter)->GetId())
{
skip = true;
break;
}
}
if (skip)
{
skip = false;
continue;
}
}
if ((*iter)->GetId() == "org.blueberry.ui.internal.introview")
continue;
if ((*iter)->GetId() == "org.mitk.views.imagenavigator")
continue;
- if ((*iter)->GetId() == "org.mitk.views.candystoreview")
+ if ((*iter)->GetId() == "org.mitk.views.viewnavigatorview")
continue;
std::pair<std::string, berry::IViewDescriptor::Pointer> p(
(*iter)->GetLabel(), (*iter));
VDMap.insert(p);
}
// ==== Perspective Toolbar ==================================
QToolBar* qPerspectiveToolbar = new QToolBar;
qPerspectiveToolbar->setObjectName("perspectiveToolBar");
if (showPerspectiveToolbar)
{
qPerspectiveToolbar->addActions(perspGroup->actions());
mainWindow->addToolBar(qPerspectiveToolbar);
}
else
delete qPerspectiveToolbar;
// ==== View Toolbar ==================================
QToolBar* qToolbar = new QToolBar;
qToolbar->setObjectName("viewToolBar");
std::map<std::string, berry::IViewDescriptor::Pointer>::const_iterator
MapIter;
for (MapIter = VDMap.begin(); MapIter != VDMap.end(); ++MapIter)
{
berry::QtShowViewAction* viewAction = new berry::QtShowViewAction(window,
(*MapIter).second);
viewActions.push_back(viewAction);
if(showViewMenuItem)
viewMenu->addAction(viewAction);
if (showViewToolbar)
{
qToolbar->addAction(viewAction);
}
}
if (showViewToolbar)
{
mainWindow->addToolBar(qToolbar);
}
else
delete qToolbar;
QSettings settings(GetQSettingsFile(), QSettings::IniFormat);
mainWindow->restoreState(settings.value("ToolbarPosition").toByteArray());
// ===== Help menu ====================================
QMenu* helpMenu = menuBar->addMenu("&Help");
helpMenu->addAction("&Welcome",this, SLOT(onIntro()));
helpMenu->addAction("&Open Help Perspective", this, SLOT(onHelpOpenHelpPerspective()));
helpMenu->addAction("&Context Help",this, SLOT(onHelp()), QKeySequence("F1"));
helpMenu->addAction("&About",this, SLOT(onAbout()));
// =====================================================
QStatusBar* qStatusBar = new QStatusBar();
//creating a QmitkStatusBar for Output on the QStatusBar and connecting it with the MainStatusBar
QmitkStatusBar *statusBar = new QmitkStatusBar(qStatusBar);
//disabling the SizeGrip in the lower right corner
statusBar->SetSizeGripEnabled(false);
QmitkProgressBar *progBar = new QmitkProgressBar();
qStatusBar->addPermanentWidget(progBar, 0);
progBar->hide();
// progBar->AddStepsToDo(2);
// progBar->Progress(1);
mainWindow->setStatusBar(qStatusBar);
if (showMemoryIndicator)
{
QmitkMemoryUsageIndicatorView* memoryIndicator = new QmitkMemoryUsageIndicatorView();
qStatusBar->addPermanentWidget(memoryIndicator, 0);
}
}
void QmitkExtWorkbenchWindowAdvisor::PreWindowOpen()
{
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
// show the shortcut bar and progress indicator, which are hidden by
// default
//configurer->SetShowPerspectiveBar(true);
//configurer->SetShowFastViewBars(true);
//configurer->SetShowProgressIndicator(true);
// // add the drag and drop support for the editor area
// configurer.addEditorAreaTransfer(EditorInputTransfer.getInstance());
// configurer.addEditorAreaTransfer(ResourceTransfer.getInstance());
// configurer.addEditorAreaTransfer(FileTransfer.getInstance());
// configurer.addEditorAreaTransfer(MarkerTransfer.getInstance());
// configurer.configureEditorAreaDropListener(new EditorAreaDropAdapter(
// configurer.getWindow()));
this->HookTitleUpdateListeners(configurer);
menuPerspectiveListener = new PerspectiveListenerForMenu(this);
configurer->GetWindow()->AddPerspectiveListener(menuPerspectiveListener);
configurer->AddEditorAreaTransfer(QStringList("text/uri-list"));
configurer->ConfigureEditorAreaDropListener(dropTargetListener);
}
void QmitkExtWorkbenchWindowAdvisor::PostWindowOpen()
{
// Force Rendering Window Creation on startup.
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
ctkPluginContext* context = QmitkCommonExtPlugin::getContext();
ctkServiceReference serviceRef = context->getServiceReference<mitk::IDataStorageService>();
if (serviceRef)
{
mitk::IDataStorageService *dsService = context->getService<mitk::IDataStorageService>(serviceRef);
if (dsService)
{
mitk::IDataStorageReference::Pointer dsRef = dsService->GetDataStorage();
mitk::DataStorageEditorInput::Pointer dsInput(new mitk::DataStorageEditorInput(dsRef));
mitk::WorkbenchUtil::OpenEditor(configurer->GetWindow()->GetActivePage(),dsInput);
}
}
}
void QmitkExtWorkbenchWindowAdvisor::onIntro()
{
QmitkExtWorkbenchWindowAdvisorHack::undohack->onIntro();
}
void QmitkExtWorkbenchWindowAdvisor::onHelp()
{
QmitkExtWorkbenchWindowAdvisorHack::undohack->onHelp();
}
void QmitkExtWorkbenchWindowAdvisor::onHelpOpenHelpPerspective()
{
QmitkExtWorkbenchWindowAdvisorHack::undohack->onHelpOpenHelpPerspective();
}
void QmitkExtWorkbenchWindowAdvisor::onAbout()
{
QmitkExtWorkbenchWindowAdvisorHack::undohack->onAbout();
}
//--------------------------------------------------------------------------------
// Ugly hack from here on. Feel free to delete when command framework
// and undo buttons are done.
//--------------------------------------------------------------------------------
QmitkExtWorkbenchWindowAdvisorHack::QmitkExtWorkbenchWindowAdvisorHack() : QObject()
{
}
QmitkExtWorkbenchWindowAdvisorHack::~QmitkExtWorkbenchWindowAdvisorHack()
{
}
void QmitkExtWorkbenchWindowAdvisorHack::onUndo()
{
mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel();
if (model)
{
if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast<mitk::VerboseLimitedLinearUndo*>( model ))
{
mitk::VerboseLimitedLinearUndo::StackDescription descriptions =
verboseundo->GetUndoDescriptions();
if (descriptions.size() >= 1)
{
MITK_INFO << "Undo " << descriptions.front().second;
}
}
model->Undo();
}
else
{
MITK_ERROR << "No undo model instantiated";
}
}
void QmitkExtWorkbenchWindowAdvisorHack::onRedo()
{
mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel();
if (model)
{
if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast<mitk::VerboseLimitedLinearUndo*>( model ))
{
mitk::VerboseLimitedLinearUndo::StackDescription descriptions =
verboseundo->GetRedoDescriptions();
if (descriptions.size() >= 1)
{
MITK_INFO << "Redo " << descriptions.front().second;
}
}
model->Redo();
}
else
{
MITK_ERROR << "No undo model instantiated";
}
}
void QmitkExtWorkbenchWindowAdvisorHack::onImageNavigator()
{
// get ImageNavigatorView
berry::IViewPart::Pointer imageNavigatorView =
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.imagenavigator");
if (imageNavigatorView)
{
bool isImageNavigatorVisible = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->IsPartVisible(imageNavigatorView);
if (isImageNavigatorVisible)
{
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->HideView(imageNavigatorView);
return;
}
}
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ShowView("org.mitk.views.imagenavigator");
//berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective();
}
-void QmitkExtWorkbenchWindowAdvisorHack::onCandyStore()
+void QmitkExtWorkbenchWindowAdvisorHack::onViewNavigator()
{
- // get candystoreView
- berry::IViewPart::Pointer candystoreView =
- berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.candystoreview");
- if (candystoreView)
+ // get viewnavigatorView
+ berry::IViewPart::Pointer viewnavigatorView =
+ berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.viewnavigatorview");
+ if (viewnavigatorView)
{
- bool iscandystoreVisible = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->IsPartVisible(candystoreView);
- if (iscandystoreVisible)
+ bool isviewnavigatorVisible = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->IsPartVisible(viewnavigatorView);
+ if (isviewnavigatorVisible)
{
- berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->HideView(candystoreView);
+ berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->HideView(viewnavigatorView);
return;
}
}
- berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ShowView("org.mitk.views.candystoreview");
+ berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ShowView("org.mitk.views.viewnavigatorview");
//berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective();
}
void QmitkExtWorkbenchWindowAdvisorHack::onEditPreferences()
{
QmitkPreferencesDialog _PreferencesDialog(QApplication::activeWindow());
_PreferencesDialog.exec();
}
void QmitkExtWorkbenchWindowAdvisorHack::onQuit()
{
berry::PlatformUI::GetWorkbench()->Close();
}
void QmitkExtWorkbenchWindowAdvisorHack::onResetPerspective()
{
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective();
}
void QmitkExtWorkbenchWindowAdvisorHack::onClosePerspective()
{
berry::IWorkbenchPage::Pointer
page =
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->ClosePerspective(page->GetPerspective(), true, true);
}
void QmitkExtWorkbenchWindowAdvisorHack::onNewWindow()
{
berry::PlatformUI::GetWorkbench()->OpenWorkbenchWindow(0);
}
void QmitkExtWorkbenchWindowAdvisorHack::onIntro()
{
bool hasIntro =
berry::PlatformUI::GetWorkbench()->GetIntroManager()->HasIntro();
if (!hasIntro)
{
QRegExp reg("(.*)<title>(\\n)*");
QRegExp reg2("(\\n)*</title>(.*)");
QFile file(":/org.mitk.gui.qt.ext/index.html");
file.open(QIODevice::ReadOnly | QIODevice::Text); //text file only for reading
QString text = QString(file.readAll());
file.close();
QString title = text;
title.replace(reg, "");
title.replace(reg2, "");
std::cout << title.toStdString() << std::endl;
QMessageBox::information(NULL, title,
text, "Close");
}
else
{
berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro(
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(), false);
}
}
void QmitkExtWorkbenchWindowAdvisorHack::onHelp()
{
ctkPluginContext* context = QmitkCommonExtPlugin::getContext();
if (context == 0)
{
MITK_WARN << "Plugin context not set, unable to open context help";
return;
}
// Check if the org.blueberry.ui.qt.help plug-in is installed and started
QList<QSharedPointer<ctkPlugin> > plugins = context->getPlugins();
foreach(QSharedPointer<ctkPlugin> p, plugins)
{
if (p->getSymbolicName() == "org.blueberry.ui.qt.help")
{
if (p->getState() != ctkPlugin::ACTIVE)
{
// try to activate the plug-in explicitly
try
{
p->start(ctkPlugin::START_TRANSIENT);
}
catch (const ctkPluginException& pe)
{
MITK_ERROR << "Activating org.blueberry.ui.qt.help failed: " << pe.what();
return;
}
}
}
}
ctkServiceReference eventAdminRef = context->getServiceReference<ctkEventAdmin>();
ctkEventAdmin* eventAdmin = 0;
if (eventAdminRef)
{
eventAdmin = context->getService<ctkEventAdmin>(eventAdminRef);
}
if (eventAdmin == 0)
{
MITK_WARN << "ctkEventAdmin service not found. Unable to open context help";
}
else
{
ctkEvent ev("org/blueberry/ui/help/CONTEXTHELP_REQUESTED");
eventAdmin->postEvent(ev);
}
}
void QmitkExtWorkbenchWindowAdvisorHack::onHelpOpenHelpPerspective()
{
berry::PlatformUI::GetWorkbench()->ShowPerspective("org.blueberry.perspectives.help",
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow());
}
void QmitkExtWorkbenchWindowAdvisorHack::onAbout()
{
QmitkAboutDialog* aboutDialog = new QmitkAboutDialog(QApplication::activeWindow(),NULL);
aboutDialog->open();
}
void QmitkExtWorkbenchWindowAdvisor::HookTitleUpdateListeners(
berry::IWorkbenchWindowConfigurer::Pointer configurer)
{
// hook up the listeners to update the window title
titlePartListener = new PartListenerForTitle(this);
titlePerspectiveListener = new PerspectiveListenerForTitle(this);
editorPropertyListener = new berry::PropertyChangeIntAdapter<
QmitkExtWorkbenchWindowAdvisor>(this,
&QmitkExtWorkbenchWindowAdvisor::PropertyChange);
// configurer.getWindow().addPageListener(new IPageListener() {
// public void pageActivated(IWorkbenchPage page) {
// updateTitle(false);
// }
//
// public void pageClosed(IWorkbenchPage page) {
// updateTitle(false);
// }
//
// public void pageOpened(IWorkbenchPage page) {
// // do nothing
// }
// });
configurer->GetWindow()->AddPerspectiveListener(titlePerspectiveListener);
configurer->GetWindow()->GetPartService()->AddPartListener(titlePartListener);
}
std::string QmitkExtWorkbenchWindowAdvisor::ComputeTitle()
{
berry::IWorkbenchWindowConfigurer::Pointer configurer =
GetWindowConfigurer();
berry::IWorkbenchPage::Pointer currentPage =
configurer->GetWindow()->GetActivePage();
berry::IEditorPart::Pointer activeEditor;
if (currentPage)
{
activeEditor = lastActiveEditor.Lock();
}
std::string title;
//TODO Product
// IProduct product = Platform.getProduct();
// if (product != null) {
// title = product.getName();
// }
// instead of the product name, we use a custom variable for now
title = productName;
if(showMitkVersionInfo)
{
title += std::string(" ") + MITK_VERSION_STRING;
}
if (showVersionInfo)
{
// add version informatioin
QString versions = QString(" (ITK %1.%2.%3 VTK %4.%5.%6 Qt %7 MITK %8)")
.arg(ITK_VERSION_MAJOR).arg(ITK_VERSION_MINOR).arg(ITK_VERSION_PATCH)
.arg(VTK_MAJOR_VERSION).arg(VTK_MINOR_VERSION).arg(VTK_BUILD_VERSION)
.arg(QT_VERSION_STR)
.arg(MITK_VERSION_STRING);
title += versions.toStdString();
}
if (currentPage)
{
if (activeEditor)
{
lastEditorTitle = activeEditor->GetTitleToolTip();
if (!lastEditorTitle.empty())
title = lastEditorTitle + " - " + title;
}
berry::IPerspectiveDescriptor::Pointer persp =
currentPage->GetPerspective();
std::string label = "";
if (persp)
{
label = persp->GetLabel();
}
berry::IAdaptable* input = currentPage->GetInput();
if (input && input != wbAdvisor->GetDefaultPageInput())
{
label = currentPage->GetLabel();
}
if (!label.empty())
{
title = label + " - " + title;
}
}
title += " (Not for use in diagnosis or treatment of patients)";
return title;
}
void QmitkExtWorkbenchWindowAdvisor::RecomputeTitle()
{
berry::IWorkbenchWindowConfigurer::Pointer configurer =
GetWindowConfigurer();
std::string oldTitle = configurer->GetTitle();
std::string newTitle = ComputeTitle();
if (newTitle != oldTitle)
{
configurer->SetTitle(newTitle);
}
}
void QmitkExtWorkbenchWindowAdvisor::UpdateTitle(bool editorHidden)
{
berry::IWorkbenchWindowConfigurer::Pointer configurer =
GetWindowConfigurer();
berry::IWorkbenchWindow::Pointer window = configurer->GetWindow();
berry::IEditorPart::Pointer activeEditor;
berry::IWorkbenchPage::Pointer currentPage = window->GetActivePage();
berry::IPerspectiveDescriptor::Pointer persp;
berry::IAdaptable* input = 0;
if (currentPage)
{
activeEditor = currentPage->GetActiveEditor();
persp = currentPage->GetPerspective();
input = currentPage->GetInput();
}
if (editorHidden)
{
activeEditor = 0;
}
// Nothing to do if the editor hasn't changed
if (activeEditor == lastActiveEditor.Lock() && currentPage == lastActivePage.Lock()
&& persp == lastPerspective.Lock() && input == lastInput)
{
return;
}
if (!lastActiveEditor.Expired())
{
lastActiveEditor.Lock()->RemovePropertyListener(editorPropertyListener);
}
lastActiveEditor = activeEditor;
lastActivePage = currentPage;
lastPerspective = persp;
lastInput = input;
if (activeEditor)
{
activeEditor->AddPropertyListener(editorPropertyListener);
}
RecomputeTitle();
}
void QmitkExtWorkbenchWindowAdvisor::PropertyChange(berry::Object::Pointer /*source*/, int propId)
{
if (propId == berry::IWorkbenchPartConstants::PROP_TITLE)
{
if (!lastActiveEditor.Expired())
{
std::string newTitle = lastActiveEditor.Lock()->GetPartName();
if (lastEditorTitle != newTitle)
{
RecomputeTitle();
}
}
}
}
void QmitkExtWorkbenchWindowAdvisor::SetPerspectiveExcludeList(std::vector<std::string> v)
{
this->perspectiveExcludeList = v;
}
std::vector<std::string> QmitkExtWorkbenchWindowAdvisor::GetPerspectiveExcludeList()
{
return this->perspectiveExcludeList;
}
void QmitkExtWorkbenchWindowAdvisor::SetViewExcludeList(std::vector<std::string> v)
{
this->viewExcludeList = v;
}
std::vector<std::string> QmitkExtWorkbenchWindowAdvisor::GetViewExcludeList()
{
return this->viewExcludeList;
}
void QmitkExtWorkbenchWindowAdvisor::PostWindowClose()
{
berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow();
QMainWindow* mainWindow = static_cast<QMainWindow*> (window->GetShell()->GetControl());
QSettings settings(GetQSettingsFile(), QSettings::IniFormat);
settings.setValue("ToolbarPosition", mainWindow->saveState());
}
QString QmitkExtWorkbenchWindowAdvisor::GetQSettingsFile() const
{
QFileInfo settingsInfo = QmitkCommonExtPlugin::getContext()->getDataFile(QT_SETTINGS_FILENAME);
return settingsInfo.canonicalFilePath();
}
diff --git a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.h b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.h
index a85e8c04dd..c076beb4c4 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.h
+++ b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.h
@@ -1,178 +1,178 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKEXTWORKBENCHWINDOWADVISOR_H_
#define QMITKEXTWORKBENCHWINDOWADVISOR_H_
#include <berryWorkbenchWindowAdvisor.h>
#include <berryIPartListener.h>
#include <berryIEditorPart.h>
#include <berryIWorkbenchPage.h>
#include <berryWorkbenchAdvisor.h>
#include <berryWorkbenchWindowAdvisor.h>
#include <org_mitk_gui_qt_ext_Export.h>
#include <QList>
class QAction;
class QMenu;
class MITK_QT_COMMON_EXT_EXPORT QmitkExtWorkbenchWindowAdvisor : public QObject, public berry::WorkbenchWindowAdvisor
{
Q_OBJECT
public:
QmitkExtWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor,
berry::IWorkbenchWindowConfigurer::Pointer configurer);
berry::ActionBarAdvisor::Pointer CreateActionBarAdvisor(
berry::IActionBarConfigurer::Pointer configurer);
void* CreateEmptyWindowContents(void* parent);
void PostWindowCreate();
void PreWindowOpen();
void PostWindowOpen();
void PostWindowClose();
void ShowViewToolbar(bool show);
void ShowPerspectiveToolbar(bool show);
void ShowVersionInfo(bool show);
void ShowMitkVersionInfo(bool show);
void ShowViewMenuItem(bool show);
void ShowNewWindowMenuItem(bool show);
void ShowClosePerspectiveMenuItem(bool show);
bool GetShowClosePerspectiveMenuItem();
void ShowMemoryIndicator(bool show);
bool GetShowMemoryIndicator();
//TODO should be removed when product support is here
void SetProductName(const std::string& product);
void SetWindowIcon(const std::string& wndIcon);
void SetPerspectiveExcludeList(std::vector<std::string> v);
std::vector<std::string> GetPerspectiveExcludeList();
void SetViewExcludeList(std::vector<std::string> v);
std::vector<std::string> GetViewExcludeList();
protected slots:
virtual void onIntro();
virtual void onHelp();
virtual void onHelpOpenHelpPerspective();
virtual void onAbout();
private:
/**
* Hooks the listeners needed on the window
*
* @param configurer
*/
void HookTitleUpdateListeners(berry::IWorkbenchWindowConfigurer::Pointer configurer);
std::string ComputeTitle();
void RecomputeTitle();
QString GetQSettingsFile() const;
/**
* Updates the window title. Format will be: [pageInput -]
* [currentPerspective -] [editorInput -] [workspaceLocation -] productName
* @param editorHidden TODO
*/
void UpdateTitle(bool editorHidden);
void PropertyChange(berry::Object::Pointer /*source*/, int propId);
static QString QT_SETTINGS_FILENAME;
berry::IPartListener::Pointer titlePartListener;
berry::IPerspectiveListener::Pointer titlePerspectiveListener;
berry::IPerspectiveListener::Pointer menuPerspectiveListener;
berry::IPartListener::Pointer imageNavigatorPartListener;
- berry::IPartListener::Pointer candyStorePartListener;
+ berry::IPartListener::Pointer viewNavigatorPartListener;
berry::IPropertyChangeListener::Pointer editorPropertyListener;
friend struct berry::PropertyChangeIntAdapter<QmitkExtWorkbenchWindowAdvisor>;
friend class PartListenerForTitle;
friend class PerspectiveListenerForTitle;
friend class PerspectiveListenerForMenu;
friend class PartListenerForImageNavigator;
- friend class PartListenerForCandyStore;
+ friend class PartListenerForViewNavigator;
berry::IEditorPart::WeakPtr lastActiveEditor;
berry::IPerspectiveDescriptor::WeakPtr lastPerspective;
berry::IWorkbenchPage::WeakPtr lastActivePage;
std::string lastEditorTitle;
berry::IAdaptable* lastInput;
berry::WorkbenchAdvisor* wbAdvisor;
bool showViewToolbar;
bool showPerspectiveToolbar;
bool showVersionInfo;
bool showMitkVersionInfo;
bool showViewMenuItem;
bool showNewWindowMenuItem;
bool showClosePerspectiveMenuItem;
- bool candyStoreFound;
+ bool viewNavigatorFound;
bool showMemoryIndicator;
std::string productName;
std::string windowIcon;
// enables DnD on the editor area
berry::IDropTargetListener::Pointer dropTargetListener;
// stringlist for excluding perspectives from the perspective menu entry (e.g. Welcome Perspective)
std::vector<std::string> perspectiveExcludeList;
// stringlist for excluding views from the menu entry
std::vector<std::string> viewExcludeList;
// maps perspective ids to QAction objects
std::map<std::string, QAction*> mapPerspIdToAction;
// actions which will be enabled/disabled depending on the application state
QList<QAction*> viewActions;
QAction* fileSaveProjectAction;
QAction* closeProjectAction;
QAction* undoAction;
QAction* redoAction;
QAction* imageNavigatorAction;
- QAction* candyStoreAction;
+ QAction* viewNavigatorAction;
QAction* resetPerspAction;
QAction* closePerspAction;
QAction* openDicomEditorAction;
QAction* openXnatEditorAction;
};
#endif /*QMITKEXTWORKBENCHWINDOWADVISOR_H_*/
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExtWorkbenchWindowAdvisorHack.h b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExtWorkbenchWindowAdvisorHack.h
index a994eb806f..ee7b2a8db8 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExtWorkbenchWindowAdvisorHack.h
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExtWorkbenchWindowAdvisorHack.h
@@ -1,59 +1,59 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <QObject>
class ctkPluginContext;
class QmitkPreferencesDialog;
class QmitkExtWorkbenchWindowAdvisorHack : public QObject
{
Q_OBJECT
public slots:
void onUndo();
void onRedo();
void onImageNavigator();
- void onCandyStore();
+ void onViewNavigator();
void onEditPreferences();
void onQuit();
void onResetPerspective();
void onClosePerspective();
void onNewWindow();
void onIntro();
/**
* @brief This slot is called if the user klicks the menu item "help->context help" or presses F1.
* The help page is shown in a workbench editor.
*/
void onHelp();
void onHelpOpenHelpPerspective();
/**
* @brief This slot is called if the user clicks in help menu the about button
*/
void onAbout();
public:
QmitkExtWorkbenchWindowAdvisorHack();
~QmitkExtWorkbenchWindowAdvisorHack();
static QmitkExtWorkbenchWindowAdvisorHack* undohack;
};
diff --git a/Plugins/org.mitk.gui.qt.python/documentation/UserManual/MitkPythonPluginView.png b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/MitkPythonPluginView.png
new file mode 100644
index 0000000000..befab56719
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/MitkPythonPluginView.png differ
diff --git a/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox
index d1ab3c52fe..0696c4eed9 100644
--- a/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox
+++ b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox
@@ -1,10 +1,35 @@
/**
\page org_mitk_gui_qt_python The Python Plugin
Available sections:
- \ref org_mitk_gui_qt_pythonOverview
+ - \ref org_mitk_gui_qt_pythonUsage
+ - \ref org_mitk_gui_qt_PythonConsole
+ - \ref org_mitk_gui_qt_PythonSnippets
\section org_mitk_gui_qt_pythonOverview Overview
The Python view provides the graphical front end to run Python code through the mitkPython module. Furthermore the ITK/VTK/OpenCV Python wrapping can be used.
+Images and surfaces in the DataManager can be transferred via a drag & drop mechanism into the MITK Python Console.
+
+\section org_mitk_gui_qt_pythonUsage Transfer data
+Images and surfaces can be tranferred from the data manger into the python console. To transfer an image or
+surface simply drag it from the data manager into the Variable Stack view, as shown in Figure.
+A new entry will appear in the Variable Stack, as soon as the data is transferred. As soon as the
+entry is available the object can be accessed and modified in the python console. Three dimensional
+images will be copied in-memory to python via numpy and a SimpleITK image object is created with the
+same properties. When a two dimensional image is transferred the user can choose to transfer it as an OpenCV
+image object. Surfaces are fully memory mapped as a vtkPolyData object. To transfer an image or surface
+from the python runtime to the data manager just double click on the corresponding entry in the Variable Stack View.
+
+\imageMacro{QmitkPythonView.png,"Screenshot of the MITK Python Plugin",20}
+
+\section org_mitk_gui_qt_PythonConsole
+The Python console can be used for interactive programming. All items in the data storage can be accessed
+in the python console. The console can also be used to load python scripts and run them.
+
+\section org_mitk_gui_qt_PythonSnippets
+The python plugin contains some code snippets of SimpleITK/VTK/OpenCV that can be run in the python console.
+Snippets can be modified and saved by the user.
+
*/
diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp
index a09be60d72..8c287ae903 100644
--- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp
+++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp
@@ -1,1456 +1,1467 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Qmitk includes
#include "QmitkRigidRegistrationView.h"
#include "QmitkStdMultiWidget.h"
// MITK includes
#include "mitkDataNodeObject.h"
#include <mitkImageCast.h>
#include "mitkManualSegmentationToSurfaceFilter.h"
#include <mitkSegmentationSink.h>
#include <mitkImageStatisticsHolder.h>
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateProperty.h"
// QT includes
#include "qinputdialog.h"
#include "qmessagebox.h"
#include "qcursor.h"
#include "qapplication.h"
#include "qradiobutton.h"
#include "qslider.h"
#include "qtooltip.h"
// VTK includes
#include <vtkTransform.h>
// ITK includes
#include <itkBinaryThresholdImageFilter.h>
// BlueBerry includes
#include "berryIWorkbenchWindow.h"
#include "berryISelectionService.h"
const std::string QmitkRigidRegistrationView::VIEW_ID = "org.mitk.views.rigidregistration";
using namespace berry;
struct SelListenerRigidRegistration : ISelectionListener
{
berryObjectMacro(SelListenerRigidRegistration);
SelListenerRigidRegistration(QmitkRigidRegistrationView* view)
{
m_View = view;
}
void DoSelectionChanged(ISelection::ConstPointer selection)
{
// save current selection in member variable
m_View->m_CurrentSelection = selection.Cast<const IStructuredSelection>();
// do something with the selected items
if(m_View->m_CurrentSelection)
{
if (m_View->m_CurrentSelection->Size() != 2)
{
if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull())
{
m_View->m_Controls.m_StatusLabel->show();
m_View->m_Controls.TextLabelFixed->hide();
m_View->m_Controls.m_FixedLabel->hide();
m_View->m_Controls.TextLabelMoving->hide();
m_View->m_Controls.m_MovingLabel->hide();
m_View->m_Controls.m_UseMaskingCB->hide();
m_View->m_Controls.m_OpacityLabel->setEnabled(false);
m_View->m_Controls.m_OpacitySlider->setEnabled(false);
m_View->m_Controls.label->setEnabled(false);
m_View->m_Controls.label_2->setEnabled(false);
m_View->m_Controls.m_ShowRedGreenValues->setEnabled(false);
m_View->m_Controls.m_SwitchImages->hide();
}
}
else
{
m_View->m_Controls.m_StatusLabel->hide();
bool foundFixedImage = false;
mitk::DataNode::Pointer fixedNode;
// iterate selection
for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin();
i != m_View->m_CurrentSelection->End(); ++i)
{
// extract datatree node
if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
{
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
// only look at interesting types
if(QString("Image").compare(node->GetData()->GetNameOfClass())==0)
{
if (dynamic_cast<mitk::Image*>(node->GetData())->GetDimension() == 4)
{
m_View->m_Controls.m_StatusLabel->show();
QMessageBox::information( NULL, "RigidRegistration", "Only 2D or 3D images can be processed.", QMessageBox::Ok );
return;
}
if (foundFixedImage == false)
{
fixedNode = node;
foundFixedImage = true;
}
else
{
// m_View->SetImagesVisible(selection);
m_View->FixedSelected(fixedNode);
m_View->MovingSelected(node);
m_View->m_Controls.m_StatusLabel->hide();
m_View->m_Controls.TextLabelFixed->show();
m_View->m_Controls.m_FixedLabel->show();
m_View->m_Controls.TextLabelMoving->show();
m_View->m_Controls.m_MovingLabel->show();
m_View->m_Controls.m_UseMaskingCB->show();
m_View->m_Controls.m_OpacityLabel->setEnabled(true);
m_View->m_Controls.m_OpacitySlider->setEnabled(true);
m_View->m_Controls.label->setEnabled(true);
m_View->m_Controls.label_2->setEnabled(true);
m_View->m_Controls.m_ShowRedGreenValues->setEnabled(true);
}
}
else
{
m_View->m_Controls.m_StatusLabel->show();
return;
}
}
}
}
}
else if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull())
{
m_View->m_Controls.m_StatusLabel->show();
}
}
void SelectionChanged(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection)
{
// check, if selection comes from datamanager
if (part)
{
QString partname(part->GetPartName().c_str());
if(partname.compare("Data Manager")==0)
{
// apply selection
DoSelectionChanged(selection);
}
}
}
QmitkRigidRegistrationView* m_View;
};
QmitkRigidRegistrationView::QmitkRigidRegistrationView(QObject * /*parent*/, const char * /*name*/)
: QmitkFunctionality(), m_MultiWidget(NULL), m_MovingNode(NULL), m_MovingMaskNode(NULL), m_FixedNode(NULL), m_FixedMaskNode(NULL),
m_ShowRedGreen(false), m_Opacity(0.5), m_OriginalOpacity(1.0), m_Deactivated(false),m_FixedDimension(0), m_MovingDimension(0)
{
m_TranslateSliderPos[0] = 0;
m_TranslateSliderPos[1] = 0;
m_TranslateSliderPos[2] = 0;
m_RotateSliderPos[0] = 0;
m_RotateSliderPos[1] = 0;
m_RotateSliderPos[2] = 0;
m_ScaleSliderPos[0] = 0;
m_ScaleSliderPos[1] = 0;
m_ScaleSliderPos[2] = 0;
translationParams = new int[3];
rotationParams = new int[3];
scalingParams = new int[3];
m_TimeStepperAdapter = NULL;
this->GetDataStorage()->RemoveNodeEvent.AddListener(mitk::MessageDelegate1<QmitkRigidRegistrationView,
const mitk::DataNode*> ( this, &QmitkRigidRegistrationView::DataNodeHasBeenRemoved ));
}
QmitkRigidRegistrationView::~QmitkRigidRegistrationView()
{
if(m_SelListener.IsNotNull())
{
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
if(s)
s->RemovePostSelectionListener(m_SelListener);
m_SelListener = NULL;
}
this->GetDataStorage()->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1<QmitkRigidRegistrationView,
const mitk::DataNode*> ( this, &QmitkRigidRegistrationView::DataNodeHasBeenRemoved ));
}
void QmitkRigidRegistrationView::CreateQtPartControl(QWidget* parent)
{
m_Controls.setupUi(parent);
m_Controls.m_ManualFrame->hide();
m_Controls.timeSlider->hide();
m_Controls.TextLabelFixed->hide();
m_Controls.m_FixedLabel->hide();
m_Controls.TextLabelMoving->hide();
m_Controls.m_MovingLabel->hide();
//m_Controls.m_UseFixedImageMask->hide();
//m_Controls.m_UseMovingImageMask->hide();
m_Controls.m_UseMaskingCB->hide();
m_Controls.m_OpacityLabel->setEnabled(false);
m_Controls.m_OpacitySlider->setEnabled(false);
m_Controls.label->setEnabled(false);
m_Controls.label_2->setEnabled(false);
m_Controls.m_ShowRedGreenValues->setEnabled(false);
m_Controls.m_SwitchImages->hide();
if (m_Controls.m_RigidTransform->currentIndex() == 1)
{
m_Controls.frame->show();
}
else
{
m_Controls.frame->hide();
}
m_Controls.m_ManualFrame->setEnabled(false);
m_Parent->setEnabled(false);
mitk::NodePredicateAnd::Pointer andPred = // we want binary images in the selectors
mitk::NodePredicateAnd::New(mitk::NodePredicateDataType::New("Image"),
mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)));
m_Controls.m_FixedImageCB->SetPredicate(andPred);
m_Controls.m_FixedImageCB->SetDataStorage(this->GetDataStorage());
m_Controls.m_FixedImageCB->hide();
m_Controls.m_FixedMaskLB->hide();
m_Controls.m_MovingImageCB->SetPredicate(andPred);
m_Controls.m_MovingImageCB->SetDataStorage(this->GetDataStorage());
m_Controls.m_MovingImageCB->hide();
m_Controls.m_MovingMaskLB->hide();
this->CreateConnections();
this->CheckCalculateEnabled();
}
void QmitkRigidRegistrationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_Parent->setEnabled(true);
m_MultiWidget = &stdMultiWidget;
m_MultiWidget->SetWidgetPlanesVisibility(true);
}
void QmitkRigidRegistrationView::StdMultiWidgetNotAvailable()
{
m_Parent->setEnabled(false);
m_MultiWidget = NULL;
}
void QmitkRigidRegistrationView::CreateConnections()
{
connect( m_Controls.m_ManualRegistrationCheckbox, SIGNAL(toggled(bool)), this, SLOT(ShowManualRegistrationFrame(bool)));
connect((QObject*)(m_Controls.m_SwitchImages),SIGNAL(clicked()),this,SLOT(SwitchImages()));
connect(m_Controls.m_ShowRedGreenValues, SIGNAL(toggled(bool)), this, SLOT(ShowRedGreen(bool)));
connect(m_Controls.m_ShowContour, SIGNAL(toggled(bool)), this, SLOT(EnableContour(bool)));
//connect(m_Controls.m_UseFixedImageMask, SIGNAL(toggled(bool)), this, SLOT(UseFixedMaskImageChecked(bool)));
//connect(m_Controls.m_UseMovingImageMask, SIGNAL(toggled(bool)), this, SLOT(UseMovingMaskImageChecked(bool)));
connect(m_Controls.m_RigidTransform, SIGNAL(currentChanged(int)), this, SLOT(TabChanged(int)));
connect(m_Controls.m_OpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityUpdate(int)));
connect(m_Controls.m_ContourSlider, SIGNAL(sliderReleased()), this, SLOT(ShowContour()));
connect(m_Controls.m_CalculateTransformation, SIGNAL(clicked()), this, SLOT(Calculate()));
connect(m_Controls.m_UndoTransformation,SIGNAL(clicked()),this,SLOT(UndoTransformation()));
connect(m_Controls.m_RedoTransformation,SIGNAL(clicked()),this,SLOT(RedoTransformation()));
connect(m_Controls.m_AutomaticTranslation,SIGNAL(clicked()),this,SLOT(AlignCenters()));
connect(m_Controls.m_StopOptimization,SIGNAL(clicked()), this , SLOT(StopOptimizationClicked()));
connect(m_Controls.m_XTransSlider, SIGNAL(valueChanged(int)), this, SLOT(xTrans_valueChanged(int)));
connect(m_Controls.m_YTransSlider, SIGNAL(valueChanged(int)), this, SLOT(yTrans_valueChanged(int)));
connect(m_Controls.m_ZTransSlider, SIGNAL(valueChanged(int)), this, SLOT(zTrans_valueChanged(int)));
connect(m_Controls.m_XRotSlider, SIGNAL(valueChanged(int)), this, SLOT(xRot_valueChanged(int)));
connect(m_Controls.m_YRotSlider, SIGNAL(valueChanged(int)), this, SLOT(yRot_valueChanged(int)));
connect(m_Controls.m_ZRotSlider, SIGNAL(valueChanged(int)), this, SLOT(zRot_valueChanged(int)));
connect(m_Controls.m_XScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(xScale_valueChanged(int)));
connect(m_Controls.m_YScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(yScale_valueChanged(int)));
connect(m_Controls.m_ZScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(zScale_valueChanged(int)));
connect(m_Controls.m_LoadRigidRegistrationParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(LoadRigidRegistrationParameter()));
connect(m_Controls.m_SaveRigidRegistrationParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(SaveRigidRegistrationParameter()));
connect(m_Controls.m_LoadRigidRegistrationTestParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(LoadRigidRegistrationTestParameter()));
connect(m_Controls.m_SaveRigidRegistrationTestParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(SaveRigidRegistrationTestParameter()));
connect(m_Controls.qmitkRigidRegistrationSelector1,SIGNAL(OptimizerChanged(double)),this,SLOT(SetOptimizerValue( double )));
connect(m_Controls.qmitkRigidRegistrationSelector1,SIGNAL(TransformChanged()),this,SLOT(CheckCalculateEnabled()));
connect(m_Controls.qmitkRigidRegistrationSelector1,SIGNAL(AddNewTransformationToUndoList()),this,SLOT(AddNewTransformationToUndoList()));
connect(m_Controls.m_UseMaskingCB, SIGNAL(stateChanged(int)),this,SLOT(OnUseMaskingChanged(int)));
connect(m_Controls.m_FixedImageCB, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),this,SLOT(OnFixedMaskImageChanged(const mitk::DataNode*)));
connect(m_Controls.m_MovingImageCB, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),this,SLOT(OnMovingMaskImageChanged(const mitk::DataNode*)));
}
void QmitkRigidRegistrationView::Activated()
{
m_Deactivated = false;
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
QmitkFunctionality::Activated();
if (m_SelListener.IsNull())
{
m_SelListener = berry::ISelectionListener::Pointer(new SelListenerRigidRegistration(this));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener);
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<SelListenerRigidRegistration>()->DoSelectionChanged(sel);
}
this->OpacityUpdate(m_Controls.m_OpacitySlider->value());
this->ShowRedGreen(m_Controls.m_ShowRedGreenValues->isChecked());
this->ClearTransformationLists();
this->CheckCalculateEnabled();
/*
m_Deactivated = false;
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
QmitkFunctionality::Activated();
if (m_SelListener.IsNull())
{
m_SelListener = berry::ISelectionListener::Pointer(new SelListenerRigidRegistration(this));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/ *"org.mitk.views.datamanager",* / m_SelListener);
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<SelListenerRigidRegistration>()->DoSelectionChanged(sel);
}
this->OpacityUpdate(m_Controls.m_OpacitySlider->value());
this->ShowRedGreen(m_Controls.m_ShowRedGreenValues->isChecked());
this->ClearTransformationLists();
this->CheckCalculateEnabled();*/
}
void QmitkRigidRegistrationView::Visible()
{
/*
m_Deactivated = false;
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
QmitkFunctionality::Activated();
if (m_SelListener.IsNull())
{
m_SelListener = berry::ISelectionListener::Pointer(new SelListenerRigidRegistration(this));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener("org.mitk.views.datamanager", m_SelListener);
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<SelListenerRigidRegistration>()->DoSelectionChanged(sel);
}
this->OpacityUpdate(m_Controls.m_OpacitySlider->value());
this->ShowRedGreen(m_Controls.m_ShowRedGreenValues->isChecked());
this->ClearTransformationLists();
this->CheckCalculateEnabled();*/
}
void QmitkRigidRegistrationView::Deactivated()
{
m_Deactivated = true;
this->SetImageColor(false);
if (m_FixedNode.IsNotNull())
m_FixedNode->SetOpacity(1.0);
m_FixedNode = NULL;
m_MovingNode = NULL;
this->ClearTransformationLists();
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
if(s)
s->RemovePostSelectionListener(m_SelListener);
m_SelListener = NULL;
/*
m_Deactivated = true;
this->SetImageColor(false);
m_FixedNode = NULL;
m_MovingNode = NULL;
this->ClearTransformationLists();
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
if(s)
s->RemovePostSelectionListener(m_SelListener);
m_SelListener = NULL;
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
QmitkFunctionality::Deactivated();*/
}
void QmitkRigidRegistrationView::Hidden()
{
/*m_Deactivated = true;
this->SetImageColor(false);
m_FixedNode = NULL;
m_MovingNode = NULL;
this->ClearTransformationLists();
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
if(s)
s->RemovePostSelectionListener(m_SelListener);
m_SelListener = NULL;
//mitk::RenderingManager::GetInstance()->RequestUpdateAll();
//QmitkFunctionality::Deactivated();*/
}
void QmitkRigidRegistrationView::DataNodeHasBeenRemoved(const mitk::DataNode* node)
{
if(node == m_FixedNode || node == m_MovingNode)
{
m_Controls.m_StatusLabel->show();
m_Controls.TextLabelFixed->hide();
m_Controls.m_FixedLabel->hide();
m_Controls.TextLabelMoving->hide();
m_Controls.m_MovingLabel->hide();
m_Controls.m_OpacityLabel->setEnabled(false);
m_Controls.m_OpacitySlider->setEnabled(false);
m_Controls.label->setEnabled(false);
m_Controls.label_2->setEnabled(false);
m_Controls.m_ShowRedGreenValues->setEnabled(false);
m_Controls.m_SwitchImages->hide();
}
else if(node == m_ContourHelperNode)
{
// can this cause a memory leak?
m_ContourHelperNode = NULL;
}
}
void QmitkRigidRegistrationView::FixedSelected(mitk::DataNode::Pointer fixedImage)
{
if (m_FixedNode.IsNotNull())
{
this->SetImageColor(false);
m_FixedNode->SetOpacity(1.0);
}
m_FixedNode = fixedImage;
if (m_FixedNode.IsNotNull())
{
m_FixedNode->SetOpacity(0.5);
m_FixedNode->SetVisibility(true);
m_Controls.TextLabelFixed->setText(QString::fromStdString(m_FixedNode->GetName()));
m_Controls.m_FixedLabel->show();
m_Controls.TextLabelFixed->show();
m_Controls.m_SwitchImages->show();
mitk::ColorProperty::Pointer colorProperty;
colorProperty = dynamic_cast<mitk::ColorProperty*>(m_FixedNode->GetProperty("color"));
if ( colorProperty.IsNotNull() )
{
m_FixedColor = colorProperty->GetColor();
}
this->SetImageColor(m_ShowRedGreen);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
if (dynamic_cast<mitk::Image*>(m_FixedNode->GetData()))
{
m_FixedDimension = dynamic_cast<mitk::Image*>(m_FixedNode->GetData())->GetDimension();
m_Controls.qmitkRigidRegistrationSelector1->SetFixedDimension(m_FixedDimension);
m_Controls.qmitkRigidRegistrationSelector1->SetFixedNode(m_FixedNode);
}
// what's about masking?
m_Controls.m_UseMaskingCB->show();
// Modify slider range
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(m_FixedNode->GetData());
int min = (int)image->GetStatistics()->GetScalarValueMin();
int max = (int)image->GetStatistics()->GetScalarValueMax();
m_Controls.m_ContourSlider->setRange(min, max);
// Set slider to a default value
int avg = (min+max) / 2;
m_Controls.m_ContourSlider->setSliderPosition(avg);
m_Controls.m_ThresholdLabel->setText(QString::number(avg));
}
else
{
m_Controls.m_FixedLabel->hide();
m_Controls.TextLabelFixed->hide();
m_Controls.m_SwitchImages->hide();
}
this->CheckCalculateEnabled();
if(this->GetActiveStdMultiWidget())
{
m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls.timeSlider, m_MultiWidget->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromRigidRegistration");
connect( m_TimeStepperAdapter, SIGNAL( Refetch() ), this, SLOT( UpdateTimestep() ) );
}
}
void QmitkRigidRegistrationView::MovingSelected(mitk::DataNode::Pointer movingImage)
{
if (m_MovingNode.IsNotNull())
{
m_MovingNode->SetOpacity(m_OriginalOpacity);
if (m_FixedNode == m_MovingNode)
m_FixedNode->SetOpacity(0.5);
this->SetImageColor(false);
}
- m_MovingNode = movingImage;
- if (m_MovingNode.IsNotNull())
+
+ // selection did not change - do onot reset
+ if( m_MovingNode.IsNotNull() && m_MovingNode == movingImage)
{
- m_MovingNode->SetVisibility(true);
- m_Controls.TextLabelMoving->setText(QString::fromStdString(m_MovingNode->GetName()));
- m_Controls.m_MovingLabel->show();
- m_Controls.TextLabelMoving->show();
- mitk::ColorProperty::Pointer colorProperty;
- colorProperty = dynamic_cast<mitk::ColorProperty*>(m_MovingNode->GetProperty("color"));
- if ( colorProperty.IsNotNull() )
- {
- m_MovingColor = colorProperty->GetColor();
- }
- this->SetImageColor(m_ShowRedGreen);
- m_MovingNode->GetFloatProperty("opacity", m_OriginalOpacity);
- this->OpacityUpdate(m_Opacity);
- // what's about masking?
- m_Controls.m_UseMaskingCB->show();
}
else
{
- m_Controls.m_MovingLabel->hide();
- m_Controls.TextLabelMoving->hide();
- m_Controls.m_UseMaskingCB->hide();
+
+ m_MovingNode = movingImage;
+ if (m_MovingNode.IsNotNull())
+ {
+ m_MovingNode->SetVisibility(true);
+ m_Controls.TextLabelMoving->setText(QString::fromStdString(m_MovingNode->GetName()));
+ m_Controls.m_MovingLabel->show();
+ m_Controls.TextLabelMoving->show();
+ mitk::ColorProperty::Pointer colorProperty;
+ colorProperty = dynamic_cast<mitk::ColorProperty*>(m_MovingNode->GetProperty("color"));
+ if ( colorProperty.IsNotNull() )
+ {
+ m_MovingColor = colorProperty->GetColor();
+ }
+ this->SetImageColor(m_ShowRedGreen);
+ m_MovingNode->GetFloatProperty("opacity", m_OriginalOpacity);
+ this->OpacityUpdate(m_Opacity);
+
+ // what's about masking?
+ m_Controls.m_UseMaskingCB->show();
+ }
+ else
+ {
+ m_Controls.m_MovingLabel->hide();
+ m_Controls.TextLabelMoving->hide();
+ m_Controls.m_UseMaskingCB->hide();
+ }
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+ this->MovingImageChanged();
+ this->CheckCalculateEnabled();
}
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- this->MovingImageChanged();
- this->CheckCalculateEnabled();
}
bool QmitkRigidRegistrationView::CheckCalculate()
{
if(m_MovingNode==m_FixedNode)
return false;
return true;
}
void QmitkRigidRegistrationView::AddNewTransformationToUndoList()
{
mitk::BaseData::Pointer movingData = m_MovingNode->GetData();
m_UndoGeometryList.push_back(static_cast<mitk::Geometry3D *>(movingData->GetGeometry()->Clone().GetPointer()));
GeometryMapType childGeometries = GeometryMapType();
if(m_MovingMaskNode.IsNotNull())
{
childGeometries.insert(std::pair<mitk::DataNode::Pointer, mitk::Geometry3D::Pointer>(m_MovingMaskNode,
static_cast<mitk::Geometry3D *>(m_MovingMaskNode->GetData()->GetGeometry()->Clone().GetPointer())));
}
mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode);
if(children.IsNotNull() && children->Size() != 0)
{
unsigned long size;
size = children->Size();
for (unsigned long i = 0; i < size; ++i)
{
childGeometries.insert(std::pair<mitk::DataNode::Pointer, mitk::Geometry3D::Pointer>(children->GetElement(i),
static_cast<mitk::Geometry3D *>(children->GetElement(i)->GetData()->GetGeometry()->Clone().GetPointer())));
}
}
m_UndoChildGeometryList.push_back(childGeometries);
m_RedoGeometryList.clear();
m_RedoChildGeometryList.clear();
this->SetUndoEnabled(true);
this->SetRedoEnabled(false);
}
void QmitkRigidRegistrationView::UndoTransformation()
{
if(!m_UndoGeometryList.empty())
{
mitk::BaseData::Pointer movingData = m_MovingNode->GetData();
m_RedoGeometryList.push_back(static_cast<mitk::Geometry3D *>(movingData->GetGeometry(0)->Clone().GetPointer()));
unsigned long size = 0;
GeometryMapType childGeometries = GeometryMapType();
if(m_MovingMaskNode.IsNotNull())
{
++size;
}
mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode);
size += children->Size();
for (unsigned long i = 0; i < size; ++i)
{
if(i==0)
{
childGeometries.insert(std::pair<mitk::DataNode::Pointer, mitk::Geometry3D::Pointer>(m_MovingMaskNode,
static_cast<mitk::Geometry3D *>(m_MovingMaskNode->GetData()->GetGeometry()->Clone().GetPointer())));
}
else
{
childGeometries.insert(std::pair<mitk::DataNode::Pointer, mitk::Geometry3D::Pointer>(children->GetElement(i),
static_cast<mitk::Geometry3D *>(children->GetElement(i)->GetData()->GetGeometry()->Clone().GetPointer())));
}
}
m_RedoChildGeometryList.push_back(childGeometries);
movingData->SetGeometry(m_UndoGeometryList.back());
m_UndoGeometryList.pop_back();
GeometryMapType oldChildGeometries;
oldChildGeometries = m_UndoChildGeometryList.back();
m_UndoChildGeometryList.pop_back();
GeometryMapType::iterator iter;
for (unsigned long j = 0; j < size; ++j)
{
if(j == 0) // we have put the geometry for the moving mask at position one
{
iter = oldChildGeometries.find(m_MovingMaskNode);
mitk::Geometry3D* geo = static_cast<mitk::Geometry3D*>((*iter).second);
m_MovingMaskNode->GetData()->SetGeometry(geo);
m_MovingMaskNode->GetData()->GetTimeGeometry()->Update();
}
else
{
iter = oldChildGeometries.find(children->GetElement(j));
children->GetElement(j)->GetData()->SetGeometry((*iter).second);
}
}
//\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper
//is still pointing to the old one. Workaround: delete mapper
//m_MovingNode->SetMapper(1, NULL);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
this->SetRedoEnabled(true);
}
if(!m_UndoGeometryList.empty())
{
this->SetUndoEnabled(true);
}
else
{
this->SetUndoEnabled(false);
}
this->CheckCalculateEnabled();
}
void QmitkRigidRegistrationView::RedoTransformation()
{
if(!m_RedoGeometryList.empty())
{
mitk::BaseData::Pointer movingData = m_MovingNode->GetData();
m_UndoGeometryList.push_back(static_cast<mitk::Geometry3D *>(movingData->GetGeometry(0)->Clone().GetPointer()));
unsigned long size = 0;
GeometryMapType childGeometries = GeometryMapType();
if(m_MovingMaskNode.IsNotNull())
{
++size;
}
mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode);
size += children->Size();
for (unsigned long i = 0; i < size; ++i)
{
if(i == 0)
{
childGeometries.insert(std::pair<mitk::DataNode::Pointer, mitk::Geometry3D::Pointer>(m_MovingMaskNode,
static_cast<mitk::Geometry3D *>(m_MovingMaskNode->GetData()->GetGeometry()->Clone().GetPointer())));
}
else
{
childGeometries.insert(std::pair<mitk::DataNode::Pointer, mitk::Geometry3D::Pointer>(children->GetElement(i),
static_cast<mitk::Geometry3D *>(children->GetElement(i)->GetData()->GetGeometry()->Clone().GetPointer())));
}
}
m_UndoChildGeometryList.push_back(childGeometries);
movingData->SetGeometry(m_RedoGeometryList.back());
m_RedoGeometryList.pop_back();
GeometryMapType oldChildGeometries;
oldChildGeometries = m_RedoChildGeometryList.back();
m_RedoChildGeometryList.pop_back();
GeometryMapType::iterator iter;
for (unsigned long j = 0; j < size; ++j)
{
if(j == 0)
{
iter = oldChildGeometries.find(m_MovingMaskNode);
m_MovingMaskNode->GetData()->SetGeometry((*iter).second);
}
else
{
iter = oldChildGeometries.find(children->GetElement(j));
children->GetElement(j)->GetData()->SetGeometry((*iter).second);
}
}
movingData->GetTimeGeometry()->Update();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
this->SetUndoEnabled(true);
}
if(!m_RedoGeometryList.empty())
{
this->SetRedoEnabled(true);
}
else
{
this->SetRedoEnabled(false);
}
}
void QmitkRigidRegistrationView::ShowRedGreen(bool redGreen)
{
m_ShowRedGreen = redGreen;
this->SetImageColor(m_ShowRedGreen);
}
void QmitkRigidRegistrationView::EnableContour(bool show)
{
if(show)
ShowContour();
// Can happen when the m_ContourHelperNode was deleted before and now the show contour checkbox is turned off
if(m_ContourHelperNode.IsNull())
return;
m_Controls.m_ContourSlider->setEnabled(show);
m_ContourHelperNode->SetProperty("visible", mitk::BoolProperty::New(show));
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
void QmitkRigidRegistrationView::ShowContour()
{
int threshold = m_Controls.m_ContourSlider->value();
bool show = m_Controls.m_ShowContour->isChecked();
if(m_FixedNode.IsNull() || !show)
return;
// Update the label next to the slider
m_Controls.m_ThresholdLabel->setText(QString::number(threshold));
mitk::Image::Pointer image = dynamic_cast<mitk::Image *>(m_FixedNode->GetData());
typedef itk::Image<float,3> FloatImageType;
typedef itk::Image<short,3> ShortImageType;
// Create a binary image using the given treshold
typedef itk::BinaryThresholdImageFilter<FloatImageType, ShortImageType> ThresholdFilterType;
FloatImageType::Pointer floatImage = FloatImageType::New();
mitk::CastToItkImage(image, floatImage);
ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New();
thresholdFilter->SetInput(floatImage);
thresholdFilter->SetLowerThreshold(threshold);
thresholdFilter->SetUpperThreshold((int)image->GetStatistics()->GetScalarValueMax());
thresholdFilter->SetInsideValue(1);
thresholdFilter->SetOutsideValue(0);
thresholdFilter->Update();
ShortImageType::Pointer binaryImage = thresholdFilter->GetOutput();
mitk::Image::Pointer mitkBinaryImage = mitk::Image::New();
mitk::CastToMitkImage(binaryImage, mitkBinaryImage);
// Create a contour from the binary image
mitk::ManualSegmentationToSurfaceFilter::Pointer surfaceFilter = mitk::ManualSegmentationToSurfaceFilter::New();
surfaceFilter->SetInput( mitkBinaryImage );
surfaceFilter->SetThreshold( 1 ); //expects binary image with zeros and ones
surfaceFilter->SetUseGaussianImageSmooth(false); // apply gaussian to thresholded image ?
surfaceFilter->SetMedianFilter3D(false); // apply median to segmentation before marching cubes ?
surfaceFilter->SetDecimate( mitk::ImageToSurfaceFilter::NoDecimation );
surfaceFilter->UpdateLargestPossibleRegion();
// calculate normals for nicer display
mitk::Surface::Pointer surface = surfaceFilter->GetOutput();
if(m_ContourHelperNode.IsNull())
{
m_ContourHelperNode = mitk::DataNode::New();
m_ContourHelperNode->SetData(surface);
m_ContourHelperNode->SetProperty("opacity", mitk::FloatProperty::New(1.0) );
m_ContourHelperNode->SetProperty("line width", mitk::IntProperty::New(2) );
m_ContourHelperNode->SetProperty("scalar visibility", mitk::BoolProperty::New(false) );
m_ContourHelperNode->SetProperty( "name", mitk::StringProperty::New("surface") );
m_ContourHelperNode->SetProperty("color", mitk::ColorProperty::New(1.0, 0.0, 0.0));
m_ContourHelperNode->SetBoolProperty("helper object", true);
this->GetDataStorage()->Add(m_ContourHelperNode);
}
else
{
m_ContourHelperNode->SetData(surface);
}
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
void QmitkRigidRegistrationView::SetImageColor(bool redGreen)
{
if (!redGreen && m_FixedNode.IsNotNull())
{
m_FixedNode->SetColor(m_FixedColor);
}
if (!redGreen && m_MovingNode.IsNotNull())
{
m_MovingNode->SetColor(m_MovingColor);
}
if (redGreen && m_FixedNode.IsNotNull())
{
m_FixedNode->SetColor(1.0f, 0.0f, 0.0f);
}
if (redGreen && m_MovingNode.IsNotNull())
{
m_MovingNode->SetColor(0.0f, 1.0f, 0.0f);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkRigidRegistrationView::OpacityUpdate(float opacity)
{
m_Opacity = opacity;
if (m_MovingNode.IsNotNull())
{
m_MovingNode->SetOpacity(m_Opacity);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkRigidRegistrationView::OpacityUpdate(int opacity)
{
float fValue = ((float)opacity)/100.0f;
this->OpacityUpdate(fValue);
}
void QmitkRigidRegistrationView::ClearTransformationLists()
{
this->SetUndoEnabled(false);
this->SetRedoEnabled(false);
m_UndoGeometryList.clear();
m_UndoChildGeometryList.clear();
m_RedoGeometryList.clear();
m_RedoChildGeometryList.clear();
}
void QmitkRigidRegistrationView::Translate(int* translateVector)
{
if (m_MovingNode.IsNotNull())
{
mitk::Vector3D translateVec;
+ mitk::ScalarType sliderSensitivity = 0.1;
- translateVec[0] = translateVector[0] - m_TranslateSliderPos[0];
- translateVec[1] = translateVector[1] - m_TranslateSliderPos[1];
- translateVec[2] = translateVector[2] - m_TranslateSliderPos[2];
+ translateVec[0] = sliderSensitivity * (translateVector[0] - m_TranslateSliderPos[0]);
+ translateVec[1] = sliderSensitivity * (translateVector[1] - m_TranslateSliderPos[1]);
+ translateVec[2] = sliderSensitivity * (translateVector[2] - m_TranslateSliderPos[2]);
m_TranslateSliderPos[0] = translateVector[0];
m_TranslateSliderPos[1] = translateVector[1];
m_TranslateSliderPos[2] = translateVector[2];
vtkMatrix4x4* translationMatrix = vtkMatrix4x4::New();
translationMatrix->Identity();
double (*transMatrix)[4] = translationMatrix->Element;
transMatrix[0][3] = -translateVec[0];
transMatrix[1][3] = -translateVec[1];
transMatrix[2][3] = -translateVec[2];
translationMatrix->Invert();
m_MovingNode->GetData()->GetGeometry()->Compose( translationMatrix );
m_MovingNode->GetData()->Modified();
mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode);
unsigned long size;
size = children->Size();
mitk::DataNode::Pointer childNode;
for (unsigned long i = 0; i < size; ++i)
{
childNode = children->GetElement(i);
childNode->GetData()->GetGeometry()->Compose( translationMatrix );
childNode->GetData()->Modified();
}
m_RedoGeometryList.clear();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkRigidRegistrationView::Rotate(int* rotateVector)
{
if (m_MovingNode.IsNotNull())
{
mitk::Vector3D rotateVec;
rotateVec[0] = rotateVector[0] - m_RotateSliderPos[0];
rotateVec[1] = rotateVector[1] - m_RotateSliderPos[1];
rotateVec[2] = rotateVector[2] - m_RotateSliderPos[2];
m_RotateSliderPos[0] = rotateVector[0];
m_RotateSliderPos[1] = rotateVector[1];
m_RotateSliderPos[2] = rotateVector[2];
vtkMatrix4x4* rotationMatrix = vtkMatrix4x4::New();
vtkMatrix4x4* translationMatrix = vtkMatrix4x4::New();
rotationMatrix->Identity();
translationMatrix->Identity();
double (*rotMatrix)[4] = rotationMatrix->Element;
double (*transMatrix)[4] = translationMatrix->Element;
mitk::Point3D centerBB = m_MovingNode->GetData()->GetGeometry()->GetCenter();
transMatrix[0][3] = centerBB[0];
transMatrix[1][3] = centerBB[1];
transMatrix[2][3] = centerBB[2];
translationMatrix->Invert();
m_MovingNode->GetData()->GetGeometry()->Compose( translationMatrix );
mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode);
unsigned long size;
size = children->Size();
mitk::DataNode::Pointer childNode;
for (unsigned long i = 0; i < size; ++i)
{
childNode = children->GetElement(i);
childNode->GetData()->GetGeometry()->Compose( translationMatrix );
childNode->GetData()->Modified();
}
double radianX = rotateVec[0] * vnl_math::pi / 180;
double radianY = rotateVec[1] * vnl_math::pi / 180;
double radianZ = rotateVec[2] * vnl_math::pi / 180;
if ( rotateVec[0] != 0 )
{
rotMatrix[1][1] = cos( radianX );
rotMatrix[1][2] = -sin( radianX );
rotMatrix[2][1] = sin( radianX );
rotMatrix[2][2] = cos( radianX );
}
else if ( rotateVec[1] != 0 )
{
rotMatrix[0][0] = cos( radianY );
rotMatrix[0][2] = sin( radianY );
rotMatrix[2][0] = -sin( radianY );
rotMatrix[2][2] = cos( radianY );
}
else if ( rotateVec[2] != 0 )
{
rotMatrix[0][0] = cos( radianZ );
rotMatrix[0][1] = -sin( radianZ );
rotMatrix[1][0] = sin( radianZ );
rotMatrix[1][1] = cos( radianZ );
}
m_MovingNode->GetData()->GetGeometry()->Compose( rotationMatrix );
for (unsigned long i = 0; i < size; ++i)
{
childNode = children->GetElement(i);
childNode->GetData()->GetGeometry()->Compose( rotationMatrix );
childNode->GetData()->Modified();
}
translationMatrix->Invert();
m_MovingNode->GetData()->GetGeometry()->Compose( translationMatrix );
for (unsigned long i = 0; i < size; ++i)
{
childNode = children->GetElement(i);
- childNode->GetData()->GetGeometry()->Compose( rotationMatrix );
+ childNode->GetData()->GetGeometry()->Compose( translationMatrix );
childNode->GetData()->Modified();
}
m_MovingNode->GetData()->Modified();
m_RedoGeometryList.clear();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkRigidRegistrationView::Scale(int* scaleVector)
{
if (m_MovingNode.IsNotNull())
{
mitk::Vector3D scaleVec;
scaleVec[0] = scaleVector[0] - m_ScaleSliderPos[0];
scaleVec[1] = scaleVector[1] - m_ScaleSliderPos[1];
scaleVec[2] = scaleVector[2] - m_ScaleSliderPos[2];
m_ScaleSliderPos[0] = scaleVector[0];
m_ScaleSliderPos[1] = scaleVector[1];
m_ScaleSliderPos[2] = scaleVector[2];
vtkMatrix4x4* scalingMatrix = vtkMatrix4x4::New();
scalingMatrix->Identity();
double (*scaleMatrix)[4] = scalingMatrix->Element;
if (scaleVec[0] >= 0)
{
for(int i = 0; i<scaleVec[0]; i++)
{
scaleMatrix[0][0] *= 0.95;
}
}
else
{
for(int i = 0; i<-scaleVec[0]; i++)
{
scaleMatrix[0][0] *= 1/0.95;
}
}
if (scaleVec[1] >= 0)
{
for(int i = 0; i<scaleVec[1]; i++)
{
scaleMatrix[1][1] *= 0.95;
}
}
else
{
for(int i = 0; i<-scaleVec[1]; i++)
{
scaleMatrix[1][1] *= 1/0.95;
}
}
if (scaleVec[2] >= 0)
{
for(int i = 0; i<scaleVec[2]; i++)
{
scaleMatrix[2][2] *= 0.95;
}
}
else
{
for(int i = 0; i<-scaleVec[2]; i++)
{
scaleMatrix[2][2] *= 1/0.95;
}
}
scalingMatrix->Invert();
m_MovingNode->GetData()->GetGeometry()->Compose( scalingMatrix );
m_MovingNode->GetData()->Modified();
mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode);
unsigned long size;
size = children->Size();
mitk::DataNode::Pointer childNode;
for (unsigned long i = 0; i < size; ++i)
{
childNode = children->GetElement(i);
childNode->GetData()->GetGeometry()->Compose( scalingMatrix );
childNode->GetData()->Modified();
}
m_RedoGeometryList.clear();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkRigidRegistrationView::AlignCenters()
{
if (m_FixedNode.IsNotNull() && m_MovingNode.IsNotNull())
{
mitk::Point3D fixedPoint = m_FixedNode->GetData()->GetGeometry()->GetCenter();
mitk::Point3D movingPoint = m_MovingNode->GetData()->GetGeometry()->GetCenter();
mitk::Vector3D translateVec;
translateVec = fixedPoint - movingPoint;
m_Controls.m_XTransSlider->setValue((int)m_Controls.m_XTransSlider->value() + (int)translateVec[0]);
m_Controls.m_YTransSlider->setValue((int)m_Controls.m_YTransSlider->value() + (int)translateVec[1]);
m_Controls.m_ZTransSlider->setValue((int)m_Controls.m_ZTransSlider->value() + (int)translateVec[2]);
}
}
void QmitkRigidRegistrationView::SetUndoEnabled( bool enable )
{
m_Controls.m_UndoTransformation->setEnabled(enable);
}
void QmitkRigidRegistrationView::SetRedoEnabled( bool enable )
{
m_Controls.m_RedoTransformation->setEnabled(enable);
}
void QmitkRigidRegistrationView::CheckCalculateEnabled()
{
if (m_FixedNode.IsNotNull() && m_MovingNode.IsNotNull())
{
m_Controls.m_ManualFrame->setEnabled(true);
m_Controls.m_CalculateTransformation->setEnabled(true);
if ( (m_FixedDimension != m_MovingDimension && std::max<int>(m_FixedDimension, m_MovingDimension) != 4) || m_FixedDimension < 2 /*|| m_FixedDimension > 3*/)
{
m_Controls.m_CalculateTransformation->setEnabled(false);
}
else if (m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() < 5 && (m_FixedDimension < 2) /*|| m_FixedDimension > 3)*/)
{
m_Controls.m_CalculateTransformation->setEnabled(false);
}
else if ((m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() > 4 && m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() < 13) && !(m_FixedDimension > 2))
{
m_Controls.m_CalculateTransformation->setEnabled(false);
}
else if (m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() > 12 && m_FixedDimension != 2)
{
m_Controls.m_CalculateTransformation->setEnabled(false);
}
}
else
{
m_Controls.m_CalculateTransformation->setEnabled(false);
m_Controls.m_ManualFrame->setEnabled(false);
}
}
void QmitkRigidRegistrationView::xTrans_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
translationParams[0]=v;
translationParams[1]=m_Controls.m_YTransSlider->value();
translationParams[2]=m_Controls.m_ZTransSlider->value();
Translate(translationParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::yTrans_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
translationParams[0]=m_Controls.m_XTransSlider->value();
translationParams[1]=v;
translationParams[2]=m_Controls.m_ZTransSlider->value();
Translate(translationParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::zTrans_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
translationParams[0]=m_Controls.m_XTransSlider->value();
translationParams[1]=m_Controls.m_YTransSlider->value();
translationParams[2]=v;
Translate(translationParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::xRot_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
rotationParams[0]=v;
rotationParams[1]=m_Controls.m_YRotSlider->value();
rotationParams[2]=m_Controls.m_ZRotSlider->value();
Rotate(rotationParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::yRot_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
rotationParams[0]=m_Controls.m_XRotSlider->value();
rotationParams[1]=v;
rotationParams[2]=m_Controls.m_ZRotSlider->value();
Rotate(rotationParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::zRot_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
rotationParams[0]=m_Controls.m_XRotSlider->value();
rotationParams[1]=m_Controls.m_YRotSlider->value();
rotationParams[2]=v;
Rotate(rotationParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::xScale_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
scalingParams[0]=v;
scalingParams[1]=m_Controls.m_YScaleSlider->value();
scalingParams[2]=m_Controls.m_ZScaleSlider->value();
Scale(scalingParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::yScale_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
scalingParams[0]=m_Controls.m_XScaleSlider->value();
scalingParams[1]=v;
scalingParams[2]=m_Controls.m_ZScaleSlider->value();
Scale(scalingParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::zScale_valueChanged( int v )
{
if (m_MovingNode.IsNotNull())
{
scalingParams[0]=m_Controls.m_XScaleSlider->value();
scalingParams[1]=m_Controls.m_YScaleSlider->value();
scalingParams[2]=v;
Scale(scalingParams);
}
else
{
MovingImageChanged();
}
}
void QmitkRigidRegistrationView::MovingImageChanged()
{
if (dynamic_cast<mitk::Image*>(m_MovingNode->GetData()))
{
m_Controls.m_XTransSlider->setValue(0);
m_Controls.m_YTransSlider->setValue(0);
m_Controls.m_ZTransSlider->setValue(0);
translationParams[0]=0;
translationParams[1]=0;
translationParams[2]=0;
m_Controls.m_XRotSlider->setValue(0);
m_Controls.m_YRotSlider->setValue(0);
m_Controls.m_ZRotSlider->setValue(0);
rotationParams[0]=0;
rotationParams[1]=0;
rotationParams[2]=0;
m_Controls.m_XScaleSlider->setValue(0);
m_Controls.m_YScaleSlider->setValue(0);
m_Controls.m_ZScaleSlider->setValue(0);
scalingParams[0]=0;
scalingParams[1]=0;
scalingParams[2]=0;
m_MovingDimension = dynamic_cast<mitk::Image*>(m_MovingNode->GetData())->GetDimension();
m_Controls.qmitkRigidRegistrationSelector1->SetMovingDimension(m_MovingDimension);
m_Controls.qmitkRigidRegistrationSelector1->SetMovingNode(m_MovingNode);
this->CheckCalculateEnabled();
}
}
void QmitkRigidRegistrationView::Calculate()
{
m_Controls.qmitkRigidRegistrationSelector1->SetFixedNode(m_FixedNode);
m_Controls.qmitkRigidRegistrationSelector1->SetMovingNode(m_MovingNode);
if (m_FixedMaskNode.IsNotNull() && m_Controls.m_UseMaskingCB->isChecked())
{
m_Controls.qmitkRigidRegistrationSelector1->SetFixedMaskNode(m_FixedMaskNode);
}
else
{
m_Controls.qmitkRigidRegistrationSelector1->SetFixedMaskNode(NULL);
}
if (m_MovingMaskNode.IsNotNull() && m_Controls.m_UseMaskingCB->isChecked())
{
m_Controls.qmitkRigidRegistrationSelector1->SetMovingMaskNode(m_MovingMaskNode);
}
else
{
m_Controls.qmitkRigidRegistrationSelector1->SetMovingMaskNode(NULL);
}
m_Controls.frame_2->setEnabled(false);
m_Controls.frame_3->setEnabled(false);
m_Controls.m_CalculateTransformation->setEnabled(false);
m_Controls.m_StopOptimization->setEnabled(true);
m_Controls.qmitkRigidRegistrationSelector1->CalculateTransformation(((QmitkSliderNavigatorWidget*)m_Controls.timeSlider)->GetPos());
m_Controls.m_StopOptimization->setEnabled(false);
m_Controls.frame_2->setEnabled(true);
m_Controls.frame_3->setEnabled(true);
m_Controls.m_CalculateTransformation->setEnabled(true);
m_Controls.qmitkRigidRegistrationSelector1->StopOptimization(false);
}
void QmitkRigidRegistrationView::SetOptimizerValue( double value )
{
m_Controls.m_OptimizerValueLCD->display(value);
}
void QmitkRigidRegistrationView::StopOptimizationClicked()
{
m_Controls.qmitkRigidRegistrationSelector1->StopOptimization(true);
}
void QmitkRigidRegistrationView::UpdateTimestep()
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkRigidRegistrationView::ShowManualRegistrationFrame(bool show)
{
if (show)
{
m_Controls.m_ManualFrame->show();
}
else
{
m_Controls.m_ManualFrame->hide();
}
}
void QmitkRigidRegistrationView::SetImagesVisible(berry::ISelection::ConstPointer /*selection*/)
{
if (this->m_CurrentSelection->Size() == 0)
{
// show all images
mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects = this->GetDataStorage()->GetAll();
for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin()
; nodeIt != setOfObjects->End(); ++nodeIt) // for each node
{
if ( (nodeIt->Value().IsNotNull()) && (nodeIt->Value()->GetProperty("visible")) && dynamic_cast<mitk::PlaneGeometryData*>(nodeIt->Value()->GetData())==NULL)
{
nodeIt->Value()->SetVisibility(true);
}
}
}
else
{
// hide all images
mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects = this->GetDataStorage()->GetAll();
for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin()
; nodeIt != setOfObjects->End(); ++nodeIt) // for each node
{
if ( (nodeIt->Value().IsNotNull()) && (nodeIt->Value()->GetProperty("visible")) && dynamic_cast<mitk::PlaneGeometryData*>(nodeIt->Value()->GetData())==NULL)
{
nodeIt->Value()->SetVisibility(false);
}
}
}
}
void QmitkRigidRegistrationView::TabChanged(int index)
{
if (index == 0)
{
m_Controls.frame->hide();
}
else
{
m_Controls.frame->show();
}
}
void QmitkRigidRegistrationView::SwitchImages()
{
mitk::DataNode::Pointer newMoving = m_FixedNode;
mitk::DataNode::Pointer newFixed = m_MovingNode;
this->FixedSelected(newFixed);
this->MovingSelected(newMoving);
if(m_ContourHelperNode.IsNotNull())
{
// Update the contour
ShowContour();
}
if(m_Controls.m_UseMaskingCB->isChecked())
{
mitk::DataNode::Pointer tempMovingMask = NULL;
mitk::DataNode::Pointer tempFixedMask = NULL;
if(m_FixedMaskNode.IsNotNull()) // it is initialized
{
tempFixedMask = m_Controls.m_FixedImageCB->GetSelectedNode();
}
if(m_MovingMaskNode.IsNotNull()) // it is initialized
{
tempMovingMask = m_Controls.m_MovingImageCB->GetSelectedNode();
}
m_Controls.m_FixedImageCB->SetSelectedNode(tempMovingMask);
m_Controls.m_MovingImageCB->SetSelectedNode(tempFixedMask);
}
}
void QmitkRigidRegistrationView::OnUseMaskingChanged( int state )
{
if(state == Qt::Checked)
{
m_Controls.m_FixedImageCB->show();
m_Controls.m_MovingImageCB->show();
m_Controls.m_MovingMaskLB->show();
m_Controls.m_FixedMaskLB->show();
}
else
{
m_Controls.m_FixedImageCB->hide();
m_Controls.m_MovingImageCB->hide();
m_Controls.m_MovingMaskLB->hide();
m_Controls.m_FixedMaskLB->hide();
m_FixedMaskNode = NULL;
m_MovingMaskNode = NULL;
}
}
void QmitkRigidRegistrationView::OnFixedMaskImageChanged( const mitk::DataNode* node )
{
if(m_Controls.m_UseMaskingCB->isChecked())
m_FixedMaskNode = const_cast<mitk::DataNode*>(node);
else
m_FixedMaskNode = NULL;
}
void QmitkRigidRegistrationView::OnMovingMaskImageChanged( const mitk::DataNode* node )
{
if(m_Controls.m_UseMaskingCB->isChecked())
m_MovingMaskNode = const_cast<mitk::DataNode*>(node);
else
m_MovingMaskNode = NULL;
-}
\ No newline at end of file
+}
diff --git a/Plugins/org.mitk.gui.qt.remeshing/src/internal/QmitkRemeshingView.cpp b/Plugins/org.mitk.gui.qt.remeshing/src/internal/QmitkRemeshingView.cpp
index 2a6f1a03c5..504639dfac 100644
--- a/Plugins/org.mitk.gui.qt.remeshing/src/internal/QmitkRemeshingView.cpp
+++ b/Plugins/org.mitk.gui.qt.remeshing/src/internal/QmitkRemeshingView.cpp
@@ -1,255 +1,254 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkRemeshingView.h"
// MITK
#include <mitkACVD.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateDataType.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateProperty.h>
#include <mitkSurface.h>
#include <mitkVtkRepresentationProperty.h>
// Qt
#include <QIntValidator>
// VTK
#include <vtkPolyData.h>
#include <vtkProperty.h>
// C++ Standard Library
#include <algorithm>
#include <limits>
QmitkRemeshingView::QmitkRemeshingView()
{
}
QmitkRemeshingView::~QmitkRemeshingView()
{
}
void QmitkRemeshingView::CreateQtPartControl(QWidget* parent)
{
m_Controls.setupUi(parent);
m_Controls.surfaceComboBox->SetDataStorage(this->GetDataStorage());
m_Controls.surfaceComboBox->SetPredicate(mitk::NodePredicateAnd::New(
mitk::TNodePredicateDataType<mitk::Surface>::New(),
mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))));
QIntValidator* posIntValidator = new QIntValidator(0, std::numeric_limits<int>::max(), parent);
m_Controls.maxNumVerticesLineEdit->setValidator(posIntValidator);
this->EnableWidgets(m_Controls.surfaceComboBox->GetSelectedNode().IsNotNull());
this->OnAdvancedSettingsButtonToggled(false);
connect(m_Controls.surfaceComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSelectedSurfaceChanged(const mitk::DataNode *)));
connect(m_Controls.numVerticesSlider, SIGNAL(valueChanged(int)), this, SLOT(OnNumberOfVerticesChanged(int)));
connect(m_Controls.numVerticesSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnNumberOfVerticesChanged(int)));
connect(m_Controls.gradationSlider, SIGNAL(valueChanged(double)), this, SLOT(OnGradationChanged(double)));
connect(m_Controls.gradationSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnGradationChanged(double)));
connect(m_Controls.advancedSettingsButton, SIGNAL(toggled(bool)), this, SLOT(OnAdvancedSettingsButtonToggled(bool)));
connect(m_Controls.maxNumVerticesLineEdit, SIGNAL(editingFinished()), this, SLOT(OnMaxNumVerticesLineEditEditingFinished()));
connect(m_Controls.edgeSplittingSlider, SIGNAL(valueChanged(double)), this, SLOT(OnEdgeSplittingChanged(double)));
connect(m_Controls.edgeSplittingSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnEdgeSplittingChanged(double)));
connect(m_Controls.subsamplingSlider, SIGNAL(valueChanged(int)), this, SLOT(OnSubsamplingChanged(int)));
connect(m_Controls.subsamplingSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnSubsamplingChanged(int)));
connect(m_Controls.optimizationLevelSlider, SIGNAL(valueChanged(int)), this, SLOT(OnOptimizationLevelChanged(int)));
connect(m_Controls.optimizationLevelSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnOptimizationLevelChanged(int)));
connect(m_Controls.remeshPushButton, SIGNAL(clicked()), this, SLOT(OnRemeshButtonClicked()));
this->OnSelectedSurfaceChanged(m_Controls.surfaceComboBox->GetSelectedNode());
}
void QmitkRemeshingView::EnableWidgets(bool enable)
{
m_Controls.surfaceComboBox->setEnabled(enable);
m_Controls.numVerticesSlider->setEnabled(enable);
m_Controls.numVerticesSpinBox->setEnabled(enable);
m_Controls.gradationSlider->setEnabled(enable);
m_Controls.gradationSpinBox->setEnabled(enable);
m_Controls.maxNumVerticesLineEdit->setEnabled(enable);
m_Controls.edgeSplittingSlider->setEnabled(enable);
m_Controls.edgeSplittingSpinBox->setEnabled(enable);
m_Controls.subsamplingSlider->setEnabled(enable);
m_Controls.subsamplingSpinBox->setEnabled(enable);
m_Controls.optimizationLevelSlider->setEnabled(enable);
m_Controls.optimizationLevelSpinBox->setEnabled(enable);
m_Controls.forceManifoldCheckBox->setEnabled(enable);
m_Controls.boundaryFixingCheckBox->setEnabled(enable);
m_Controls.remeshPushButton->setEnabled(enable);
}
void QmitkRemeshingView::OnAdvancedSettingsButtonToggled(bool toggled)
{
m_Controls.maxNumVerticesLabel->setVisible(toggled);
m_Controls.maxNumVerticesLineEdit->setVisible(toggled);
m_Controls.edgeSplittingLabel->setVisible(toggled);
m_Controls.edgeSplittingSlider->setVisible(toggled);
m_Controls.edgeSplittingSpinBox->setVisible(toggled);
m_Controls.subsamplingLabel->setVisible(toggled);
m_Controls.subsamplingSlider->setVisible(toggled);
m_Controls.subsamplingSpinBox->setVisible(toggled);
m_Controls.optimizationLevelLabel->setVisible(toggled);
m_Controls.optimizationLevelSlider->setVisible(toggled);
m_Controls.optimizationLevelSpinBox->setVisible(toggled);
m_Controls.forceManifoldCheckBox->setVisible(toggled);
m_Controls.boundaryFixingCheckBox->setVisible(toggled);
}
void QmitkRemeshingView::OnEdgeSplittingChanged(double edgeSplitting)
{
if (edgeSplitting != m_Controls.edgeSplittingSlider->value())
m_Controls.edgeSplittingSlider->setValue(edgeSplitting);
if (edgeSplitting != m_Controls.edgeSplittingSpinBox->value())
m_Controls.edgeSplittingSpinBox->setValue(edgeSplitting);
}
void QmitkRemeshingView::OnGradationChanged(double gradation)
{
if (gradation != m_Controls.gradationSlider->value())
m_Controls.gradationSlider->setValue(gradation);
if (gradation != m_Controls.gradationSpinBox->value())
m_Controls.gradationSpinBox->setValue(gradation);
}
void QmitkRemeshingView::OnMaxNumVerticesLineEditEditingFinished()
{
int maximum = m_Controls.maxNumVerticesLineEdit->text().toInt();
if (m_Controls.numVerticesSpinBox->maximum() != maximum)
{
m_Controls.numVerticesSlider->setMaximum(maximum);
m_Controls.numVerticesSpinBox->setMaximum(maximum);
}
}
void QmitkRemeshingView::OnNumberOfVerticesChanged(int numVertices)
{
if (numVertices != m_Controls.numVerticesSlider->value())
m_Controls.numVerticesSlider->setValue(numVertices);
if (numVertices != m_Controls.numVerticesSpinBox->value())
m_Controls.numVerticesSpinBox->setValue(numVertices);
}
void QmitkRemeshingView::OnOptimizationLevelChanged(int optimizationLevel)
{
if (optimizationLevel != m_Controls.optimizationLevelSlider->value())
m_Controls.optimizationLevelSlider->setValue(optimizationLevel);
if (optimizationLevel != m_Controls.optimizationLevelSpinBox->value())
m_Controls.optimizationLevelSpinBox->setValue(optimizationLevel);
}
void QmitkRemeshingView::OnRemeshButtonClicked()
{
mitk::DataNode::Pointer selectedNode = m_Controls.surfaceComboBox->GetSelectedNode();
mitk::Surface::ConstPointer surface = static_cast<mitk::Surface*>(selectedNode->GetData());
int numVertices = m_Controls.numVerticesSpinBox->value();
double gradation = m_Controls.gradationSpinBox->value();
int subsampling = m_Controls.subsamplingSpinBox->value();
double edgeSplitting = m_Controls.edgeSplittingSpinBox->value();
int optimizationLevel = m_Controls.optimizationLevelSpinBox->value();
bool forceManifold = m_Controls.forceManifoldCheckBox->isChecked();
bool boundaryFixing = m_Controls.boundaryFixingCheckBox->isChecked();
// mitk::Surface::Pointer remeshedSurface = mitk::ACVD::Remesh(surface, 0, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing);
mitk::ACVD::RemeshFilter::Pointer remesher = mitk::ACVD::RemeshFilter::New();
remesher->SetInput(surface);
remesher->SetTimeStep(0);
remesher->SetNumVertices(numVertices);
remesher->SetGradation(gradation);
remesher->SetSubsampling(subsampling);
remesher->SetEdgeSplitting(edgeSplitting);
remesher->SetOptimizationLevel(optimizationLevel);
remesher->SetForceManifold(forceManifold);
remesher->SetBoundaryFixing(boundaryFixing);
try
{
remesher->Update();
}
catch(const mitk::Exception& exception)
{
MITK_ERROR << exception.GetDescription();
return;
}
mitk::Surface::Pointer remeshedSurface = remesher->GetOutput();
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetName(QString("%1 (%2, %3)").arg(selectedNode->GetName().c_str()).arg(remeshedSurface->GetVtkPolyData()->GetNumberOfPoints()).arg(gradation).toStdString());
newNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME));
- newNode->SetProperty("material.specularCoefficient", mitk::FloatProperty::New(0.0f));
newNode->SetData(remeshedSurface);
this->GetDataStorage()->Add(newNode, selectedNode);
}
void QmitkRemeshingView::OnSelectedSurfaceChanged(const mitk::DataNode *node)
{
if (node != NULL)
{
int numVertices = static_cast<int>(static_cast<mitk::Surface*>(node->GetData())->GetVtkPolyData()->GetNumberOfPoints());
int minimum = numVertices < 100 ? numVertices : 100;
int maximum = numVertices == minimum ? numVertices * 10 : numVertices;
int step = std::max(1, maximum / 10);
this->SetNumberOfVertices(minimum, maximum, step, numVertices);
this->EnableWidgets(true);
}
else
{
this->EnableWidgets(false);
this->SetNumberOfVertices(0, 0, 0, 0);
}
}
void QmitkRemeshingView::OnSubsamplingChanged(int subsampling)
{
if (subsampling != m_Controls.subsamplingSlider->value())
m_Controls.subsamplingSlider->setValue(subsampling);
if (subsampling != m_Controls.subsamplingSpinBox->value())
m_Controls.subsamplingSpinBox->setValue(subsampling);
}
void QmitkRemeshingView::SetFocus()
{
m_Controls.surfaceComboBox->setFocus();
}
void QmitkRemeshingView::SetNumberOfVertices(int minimum, int maximum, int step, int value)
{
m_Controls.numVerticesSlider->setMinimum(minimum);
m_Controls.numVerticesSlider->setMaximum(maximum);
m_Controls.numVerticesSlider->setSingleStep(1);
m_Controls.numVerticesSlider->setPageStep(step);
m_Controls.numVerticesSpinBox->setMinimum(minimum);
m_Controls.numVerticesSpinBox->setMaximum(maximum);
m_Controls.numVerticesSpinBox->setSingleStep(step);
m_Controls.numVerticesSpinBox->setValue(value);
m_Controls.maxNumVerticesLineEdit->setText(QString("%1").arg(maximum));
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox
new file mode 100644
index 0000000000..27e63aa45e
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox
@@ -0,0 +1,71 @@
+/**
+\page org_mitk_views_deformableclippingplane The Clipping Plane
+
+\imageMacro{QmitkClippingPlane_Icon.png,"Icon of the Clipping Plane Plugin",5.00}
+
+\tableofcontents
+
+\section org_mitk_views_clippingPlaneManualOverview Overview
+
+The <b>Clipping Plane view</b> allows you to create clipping planes and calculate the volumina of the devided parts.
+
+\imageMacro{QmitkClippingPlane_Overview.png,"Clipping Plane view with segmentation and two clipping planes",16.00}
+
+\section org_mitk_views_clippingPlaneTechnicalIssue Technical Issue
+
+To use the Update Volumina function your image should be binary.
+
+\section org_mitk_views_clippingPlaneManualImageSelection Image Selection
+
+The Clipping Plane view makes use of the Data Manager view to give you an overview of all images, segmentations and clipping planes.
+
+\imageMacro{QmitkClippingPlane_DataManager.png,"Data Manager is used for selecting the current clipping plane. The reference plane is selected in the drop down box of the control area.",8.00}
+
+To select the reference plane use the drop down box in the control area of the Clipping Plane view or the Data Manager. The clipping plane selected in the Data Manager is displayed below the drop down box. If no clipping plane exists or none is selected create a new clipping plane by using the "Create new clipping plane" button.
+Some items of the graphical user interface might be disabled when no plane is selected.
+In any case, the application will give you hints if a selection is needed.
+
+\section org_mitk_views_clippingPlaneCreating Creating New Clipping Plane
+
+If you want to create a new clipping plane select an image from the Data Manager and press the button "Create new clipping plane". Optionally you can enable the "...with surface model" option.
+
+\section org_mitk_views_clippingPlaneInteraction Interaction with the planes
+\imageMacro{QmitkClippingPlane_Interaction.png,"The interaction buttons",5.00}
+
+You have different options to interact with the clipping planes:
+
+\subsection org_mitk_views_clippingPlaneTranslation Translation
+
+In Translation mode you can change the position of the clipping plane.
+ - Click the Translation Button
+ - Move mouse over the selected clipping plane (the plane changes its color from blue to green)
+ - Hold mouse-left button and move the mouse orthogonally to the plane
+
+\subsection org_mitk_views_clippingPlaneRotation Rotation
+
+In Rotation mode you can change the angle of the clipping plane.
+ - Click the Rotation Button
+ - Move mouse over the selected clipping plane (the plane changes its color from blue to green)
+ - Hold mouse-left button and move the mouse in the direction it should be rotated
+
+\subsection org_mitk_views_clippingPlaneDeformation Deformation
+
+In Deformation mode you can change the surface of the clipping plane.
+ - Click the Deformation Button
+ - Move mouse over the selected clipping plane (the plane changes its color from blue to green). The deformation area is highlighted in red and yellow.
+ - On mouse-scrolling you can change the size of the deformation area (Scroll-Down = smaller / Scroll-Up = bigger).
+ - Hold mouse-left button and move the mouse orthogonally to the plane to deformate the plane
+
+\section org_mitk_views_clippingPlaneUpdateVolumina Update Volumina
+
+\imageMacro{QmitkClippingPlane_UpdateVolumina.png,"The 'Update Volumina' button",5.00}
+
+Calculating the volumina of the segmentation parts, which are devided by the clipping plane(s).
+ - Create a segmentation (see Segmentation-Manual)
+ - Create one or more clipping plane(s)
+ - Use the interaction buttons (Translation, Rotation, Deformation) to adjust the clipping plane for intersecting the segmentation
+ - (You can decide which planes shouldnt be included for the calculation by changing their visibility to invisible)
+ - Click button "Update Volumina" button
+ - The intersected parts are displayed in different colors and their volumina are shown beneath the "Update Volumina" button
+
+**/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_DataManager.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_DataManager.png
new file mode 100644
index 0000000000..4ef9d53ef2
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_DataManager.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png
new file mode 100644
index 0000000000..28c5fb54e8
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Interaction.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Interaction.png
new file mode 100644
index 0000000000..49048201bf
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Interaction.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Overview.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Overview.png
new file mode 100644
index 0000000000..81d1d43d1f
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Overview.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_UpdateVolumina.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_UpdateVolumina.png
new file mode 100644
index 0000000000..3f035458a5
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_UpdateVolumina.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox
index b30dbd73c7..6c4e8fd64b 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox
@@ -1,290 +1,292 @@
/**
\page org_mitk_views_segmentation The Segmentation Plugin
\imageMacro{QmitkSegmentation_Icon.png,"Icon of the Segmentation Plugin",2.00}
<i>Some of the features described below are closed source additions to the open source toolkit MITK and are not available in every application.</i>
\tableofcontents
\section org_mitk_gui_qt_segmentationUserManualOverview Overview
The <b>Segmentation perspective</b> allows you to create segmentations of anatomical and pathological structures in medical images of the human body.
The perspective groups a number of tools which can be used for:
<ul>
<li> (semi-)automatic segmentation of organs on CT or MR image volumes
<li> semi-automatic segmentation of lesions such as enlarged lymph nodes or tumors
<li> manual segmentation of any structures you might want to delineate
</ul>
+For more detailed information on the clipping plane view see \subpage org_mitk_views_deformableclippingplane.
+
\imageMacro{QmitkSegmentation_IMGApplication.png,"Segmentation perspective consisting of the Data Manager view and the Segmentation view",16.00}
If you wonder what segmentations are good for, we shortly revisit the concept of a segmentation here.
A CT or MR image is made up of volume of physical measurements (volume elements are called voxels).
In CT images, for example, the gray value of each voxel corresponds to the mass absorbtion coefficient for X-rays in this voxel, which is similar in many %parts of the human body.
The gray value does not contain any further information, so the computer does not know whether a given voxel is part of the body or the background, nor can it tell a brain from a liver.
However, the distinction between a foreground and a background structure is required when:
<ul>
<li>you want to know the volume of a given organ (the computer needs to know which %parts of the image belong to this organ)
<li>you want to create 3D polygon visualizations (the computer needs to know the surfaces of structures that should be drawn)
<li>as a necessary pre-processing step for therapy planning, therapy support, and therapy monitoring
</ul>
Creating this distinction between foreground and background is called <i>segmentation</i>.
The Segmentation perspective of the MITK Workbench uses a voxel based approach to segmentation, i.e. each voxel of an image must be completely assigned to either foreground or background.
This is in contrast to some other applications which might use an approach based on contours, where the border of a structure might cut a voxel into two %parts.
The remainder of this document will summarize the features of the Segmentation perspective and how they are used.
\section org_mitk_gui_qt_segmentationUserManualTechnical Technical Issues
The Segmentation perspective makes a number of assumptions. To know what this view can be used for, it will help you to know that:
<ul>
<li> Images must be 2D, 3D, or 3D+t
<li> Images must be single-values, i.e. CT, MRI or "normal" ultrasound. Images from color doppler or photographic (RGB) images are not supported
<li> Segmentations are handled as binary images of the same extent as the original image
</ul>
\section org_mitk_gui_qt_segmentationUserManualImageSelection Image Selection
The Segmentation perspective makes use of the Data Manager view to give you an overview of all images and segmentations.
\imageMacro{QmitkSegmentation_IMGSelection.png,"Data Manager is used for selecting the current segmentation. The reference image is selected in the drop down box of the control area.",5.50}
To select the reference image (e.g. the original CT/MR image) use the drop down box in the control area of the Segmentation view. The segmentation image selected in the Data Manager is displayed below the drop down box. If no segmentation image exists or none is selected create a new segmentation image by using the "New segmentation" button.
Some items of the graphical user interface might be disabled when no image is selected.
In any case, the application will give you hints if a selection is needed.
\section org_mitk_gui_qt_segmentationUserManualManualKringeling Manual Contouring
With manual contouring you define which voxels are part of the segmentation and which are not.
This allows you to create segmentations of any structeres that you may find in an image, even if they are not part of the human body.
You might also use manual contouring to correct segmentations that result from sub-optimal automatic methods.
The drawback of manual contouring is that you might need to define contours on many 2D slices.
However, this is moderated by the interpolation feature, which will make suggestions for a segmentation.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling1 Creating New Segmentations
Unless you want to edit existing segmentations, you have to create a new, empty segmentation before you can edit it.
To do so, click the "New manual segmentation" button.
Input fields will appear where you can choose a name for the new segmentation and a color for its display.
Click the checkmark button to confirm or the X button to cancel the new segmentation.
Notice that the input field suggests names once you %start typing and that it also suggests colors for known organ names.
If you use names that are not yet known to the application, it will automatically remember these names and consider them the next time you create a new segmentation.
Once you created a new segmentation, you can notice a new item with the "binary mask" icon in the Data Manager tree view.
This item is automatically selected for you, allowing you to %start editing the new segmentation right away.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling2 Selecting Segmentations for Editing
As you might want to have segmentations of multiple structures in a single patient image, the application needs to know which of them to use for editing.
You select a segmenation by clicking it in the tree view of Data Manager. Note that segmentations are usually displayed as sub-items of "their" patient image.
In the rare case, where you need to edit a segmentation that is not displayed as a a sub-item, you can click both the original image AND the segmentation while holding down CTRL or for Mac OS X the CMD on the keyboard.
When a selection is made, the Segmentation View will hide all but the selected segmentation and the corresponding original image.
When there are multiple segmentations, the unselected ones will remain in the Data Manager, you can make them visible at any time by selecting them.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling3 Selecting Editing Tools
If you are familiar with the MITK Workbench, you know that clicking and moving the mouse in any of the 2D render windows will move around the crosshair that defines what part of the image is displayed.
This behavior is disabled while any of the manual segmentation tools are active -- otherwise you might have a hard time concentrating on the contour you are drawing.
To %start using one of the editing tools, click its button the the displayed toolbox.
The selected editing tool will be active and its corresponding button will stay pressed until you click the button again.
Selecting a different tool also deactivates the previous one.
If you have to delineate a lot of images, you should try using shortcuts to switch tools. Just hit the first letter of each tool to activate it (A for Add, S for Subtract, etc.).
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling4 Using Editing Tools
All of the editing tools work by the same principle: you use the mouse (left button) to click anywhere in a 2D window (any of the orientations axial, sagittal, or frontal), move the mouse while holding the mouse button and release to finish the editing action.
Multi-step undo and redo is fully supported by all editing tools. Use the application-wide undo button in the toolbar to revert erroneous %actions.
\imageMacro{QmitkSegmentation_IMGIconAddSubtract.png,"Add and Subtract Tools",7.70}
Use the left mouse button to draw a closed contour. When releasing the mouse button, the contour will be added (Add tool) to or removed from (Subtract tool) the current segmentation.
Hold down the CTRL / CMD key to invert the operation (this will switch tools temporarily to allow for quick corrections).
\imageMacro{QmitkSegmentation_IMGIconPaintWipe.png,"Paint and Wipe Tools",7.68}
Use the slider below the toolbox to change the radius of these round paintbrush tools. Move the mouse in any 2D window and press the left button to draw or erase pixels.
As the Add/Subtract tools, holding CTRL / CMD while drawing will invert the current tool's behavior.
\imageMacro{QmitkSegmentation_IMGIconRegionGrowing.png,"Region Growing Tool",3.81}
Click at one point in a 2D slice widget to add an image region to the segmentation with the region growing tool. Moving up the cursor while holding the left mouse button widens the range for the included grey values; moving it down narrows it.
When working on an image with a high range of grey values, the selection range can be influenced more strongly by moving the cursor at higher velocity.
Region Growing selects all pixels around the mouse cursor that have a similar gray value as the pixel below the mouse cursor.
This enables you to quickly create segmentations of structures that have a good contrast to surrounding tissue, e.g. the lungs.
The tool will select more or less pixels (corresponding to a changing gray value interval width) when you move the mouse up or down while holding down the left mouse button.
A common issue with region growing is the so called "leakage" which happens when the structure of interest is connected to other pixels, of similar gray values, through a narrow "bridge" at the border of the structure.
The Region Growing tool comes with a "leakage detection/removal" feature. If leakage happens, you can left-click into the leakage region and the tool will try to automatically remove this region (see illustration below).
\imageMacro{QmitkSegmentation_IMGLeakage.png,"Leakage correction feature of the Region Growing tool",11.28}
<br>
\imageMacro{QmitkSegmentation_IMGIconCorrection.png,"Correction Tool",3.77}
You do not have to draw a closed contour to use the Correction tool and do not need to switch between the Add and Substract tool to perform
small corrective changes. The following figure shows the usage of this tool:
<ul>
<li> if the user draws a line which %starts and ends outside the segmenation AND it intersects no other segmentation the endpoints of the line are connected and the resulting contour is filled
<li> if the user draws a line which %starts and ends outside the segmenation a part of it is cut off (left image)
<li> if the line is drawn fully inside the segmentation the marked region is added to the segmentation (right image)
</ul>
\imageMacro{QmitkSegmentation_IMGCorrectionActions.png,"%Actions of the Correction tool illustrated.",13.50}
<br>
\imageMacro{QmitkSegmentation_IMGIconFill.png,"Fill Tool",3.81}
Left-click inside a segmentation with holes to completely fill all holes.
\imageMacro{QmitkSegmentation_IMGIconErase.png,"Erase Tool",3.79}
This tool removes a connected part of pixels that form a segmentation. You may use it to remove so called islands (see picture) or to clear a whole slice at once (hold CTRL while clicking).
\imageMacro{QmitkSegmentation_IMGIconLiveWire.png,"LiveWire Tool",3.01}
The LiveWire Tool acts as a magnetic lasso with a contour snapping to edges of objects.
\imageMacro{QmitkSegmentation_IMGLiveWireUsage.png,"Steps for using LiveWire Tool",16.00}
<ul>
<li>(1) To start the Tool you have to double click near the edge of the object you want to segment. The initial anchor point will snap to the edge within a 3x3 region.
<li>(2) Move the mouse. You don't have trace the edge of the object. The contour will automatically snap to it.
<li>(3) To fix a segment you can set anchor points by single left mouse button click.
<li>(4) Go on with moving the mouse and setting anchor points.
<li>(5) To close the contour double click on the initial anchor point.
<li>(6) After closing the contour can be edited by moving, inserting and deleting anchor points.
</ul>
The contour will be transfered to its binary image representation by deactivating the tool.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling5 Interpolation
Creating segmentations for modern CT volumes is very time-consuming, because structures of interest can easily cover a range of 50 or more slices.
The Manual Segmentation View offers two helpful features for these cases:
<ul>
<li> <b>3D Interpolation</b>
<li> <b>2D Interpolation</b>
</ul>
<br>
<b>The 3D interpolation</b> is activated by default when using the manual segmentation tools. That means if you start contouring, from the second contour onwards, the surface of the segmented area will be interpolated based on the given contour information.
The interpolation works with all available manual tools. Please note that this is currently a pure mathematical interpolation, i.e. image intensity information is not taken into account. With each further contour the interpolation result will be improved,
but the more contours you provide the longer the recalculation will take. To achieve an optimal interpolation result and in this way a most accurate segmentation you should try to describe the surface with sparse contours by segmenting in arbitrary
oriented planes. The 3D interpolation is not meant to be used for parallel slice-wise segmentation.
\imageMacro{QmitkSegmentation_3DInterpolationWrongRight.png,"3D Interpolation HowTo",16.00}
You can accept the interpolation result by clicking the "Accept" - button below the tool buttons.
In this case the 3D interpolation will be deactivated automatically so that the result can be postprocessed without any interpolation running in background. During recalculation the interpolated surface is blinking yellow/white. When the interpolation
has finished the surface is shown yellow with a small opacity. Additional to the surface, black contours are shown in the 3D render window. They mark the positions of all the drawn contours which were used for the interpolation.
You can navigate between the drawn contours by clicking on the „Position“ - Nodes in the datamanager which are located below the selected segmentation. If you don't want to see these nodes just unckeck the „Show Position Nodes“ Checkbox and these nodes will be hidden.
If you want to delete a drawn contour we recommend to use the Erase-Tool since Redo/Undo is not yet working for 3D interpolation.
<br>
<b>The 2D Interpolation</b> creates suggestions for a segmentation whenever you have a slice that
<ul>
<li> has got neighboring slices with segmentations (these do not need to be direct neighbors but could also be a couple of slices away) AND
<li> is completely clear of a manual segmentation -- i.e. there will be no suggestion if there is even only a single pixel of segmentation in the current slice.
</ul>
Interpolated suggestions are displayed in a different way than manual segmentations are, until you "accept" them as part of the segmentation.
To accept single slices, click the "Accept" button below the toolbox.
If you have segmented a whole organ in every-x-slice, you may also review the interpolations and then accept all of them at once by clicking "... all slices".
\section org_mitk_gui_qt_segmentationUserManualOrganSegmentation Organ Segmentation
\note This feature is only available in our 3M3 Demo Application (http://www.mint-medical.de/productssolutions/mitk3m3/mitk3m3/#downloads) but not in the open source part of MITK
The manual contouring described above is a fallback option that will work for any kind of images and structures of interest.
However, manual contouring is very time-consuming and tedious.
This is why a major part of image analysis research is working towards automatic segmentation methods.
The Segmentation View comprises a number of easy-to-use tools for segmentation of CT images (Liver) and MR image (left ventricle and wall, left and right lung).
\subsection org_mitk_gui_qt_segmentationUserManualOrganSegmentation1 Liver on CT Images
On CT image volumes, preferrably with a contrast agent in the portal venous phase, the Liver tool will fully automatically analyze and segment the image.
All you have to do is to load and select the image, then click the "Liver" button.
During the process, which takes a minute or two, you will get visual progress feedback by means of a contour that moves closer and closer to the real liver boundaries.
\subsection org_mitk_gui_qt_segmentationUserManualOrganSegmentation2 Heart, Lung, and Hippocampus on MRI
While liver segmentation is performed fully automatic, the following tools for segmentation of the heart, the lungs, and the hippocampus need a minimum amount of guidance.
Click one of the buttons on the "Organ segmentation" page to add an average %model of the respective organ to the image.
This %model can be dragged to the right position by using the left mouse button while holding down the CTRL key.
You can also use CTRL + middle mouse button to rotate or CTRL + right mouse button to scale the %model.
Before starting the automatic segmentation process by clicking the "Start segmentation" button, try placing the %model closely to the organ in the MR image
(in most cases, you do not need to rotate or scale the %model).
During the segmentation process, a green contour that moves closer and closer to the real liver boundaries will provide you with visual feedback of the segmentation progress.
The algorithms used for segmentation of the heart and lung are method which need training by a number of example images.
They will not work well with other kind of images, so here is a list of the image types that were used for training:
<ul>
<li> Hippocampus segmentation: T1-weighted MR images, 1.5 Tesla scanner (Magnetom Vision, Siemens Medical Solutions), 1.0 mm isotropic resolution
<li> Heart: Left ventricle inner segmentation (LV Model): MRI; velocity encoded cine (VEC-cine) MRI sequence; trained on systole and diastole
<li> Heart: Left ventricular wall segmentation (LV Inner Wall, LV Outer Wall): 4D MRI; short axis 12 slice spin lock sequence(SA_12_sl); trained on whole heart cycle
<li> Lung segmentation: 3D and 4D MRI; works best on FLASH3D and TWIST4D sequences
</ul>
\subsection org_mitk_gui_qt_segmentationUserManualOrganSegmentation99 Other Organs
As mentioned in the Heart/Lung section, most of the underlying methods are based on "training".
The basic algorithm is versatile and can be applied on all kinds of segmentation problems where the structure of interest is topologically like a sphere (and not like a torus etc.).
If you are interested in other organs than those offered by the current version of the Segmentation view,
please contact our research team.
\section org_mitk_gui_qt_segmentationUserManualLesionSegmentation Lesion Segmentation
\note This feature is only available in our 3M3 Demo Application (http://www.mint-medical.de/productssolutions/mitk3m3/mitk3m3/#downloads) but not in the open source part of MITK
Lesion segmentation is a little different from organ segmentation. Since lesions are not part of the healthy body, they sometimes have a diffused border,
and are often found in varying places all over the body.
The tools in this section offer efficient ways to create 3D segmentations of such lesions.
The Segmentation View currently offers supoprt for enlarged lymph nodes.
To segment an enlarged lymph node, find a more or less central slice of it, activate the "Lymph Node" tool and draw a rough contour on the inside of the lymph node.
When releaseing the mouse button, a segmentation algorithm is started in a background task. The result will become visible after a couple of seconds, but you do not have to wait for it.
If you need to segment several lymph nodes, you can continue to inspect the image right after closing the drawn contour.
If the lymph node segmentation is not to your content, you can select the "Lymph Node Correction" tool and drag %parts of the lymph node surface towards the right position (works in 3D, not slice-by-slice).
This kind of correction helps in many cases.
If nothing else helps, you can still use the pure manual tools as a fallback.
\section org_mitk_gui_qt_segmentationUserManualPostprocessing Things you can do with segmentations
As mentioned in the introduction, segmentations are never an end in themselves.
Consequently, the Segmentation view adds a couple of "post-processing" %actions to the Data Manager.
These %actions are accessible through the context-menu of segmentations in Data Manager's list view
\imageMacro{QmitkSegmentation_IMGDataManagerContextMenu.png,"Context menu items for segmentations.",10.58}
<ul>
<li> <b>Create polygon %model</b> applies the marching cubes algorithms to the segmentation. This polygon %model can be used for visualization in 3D or other things such as stereolithography (3D printing).
<li> <b>Create smoothed polygon %model</b> uses smoothing in addition to the marching cubes algorithms, which creates models that do not follow the exact outlines of the segmentation, but look smoother.
<li> <b>Statistics</b> goes through all the voxels in the patient image that are part of the segmentation and calculates some statistical measures (minumum, maximum, median, histogram, etc.). Note that the statistics are ALWAYS calculated for the parent element of the segmentation as shown in Data Manager.
<li> <b>Autocrop</b> can save memory. Manual segmentations have the same extent as the patient image, even if the segmentation comprises only a small sub-volume. This invisible and meaningless margin is removed by autocropping.
</ul>
\section QmitkSegmentation_UserManualSurfaceMasking Surface Masking
You can use the surface masking tool to create binary images from a surface which
is used used as a mask on an image. This task is demonstrated below:
\imageMacro{QmitkSegmentation_FromSurfaceBefore.png,"Load an image and a surface.",16.00}
Select the image and the surface in the corresponding drop-down boxes (both are selected automatically if there is just one image and one surface)
\imageMacro{QmitkSegmentation_FromSurfaceAfter.png,"Create segmentation from surface",16.00}
After clicking "Create segmentation from surface" the newly created binary image is inserted in the DataManager and can be used for further processing
\section org_mitk_gui_qt_segmentationUserManualTechnicalDetail Technical Information for Developers
For technical specifications see \subpage QmitkSegmentationTechnicalPage and for information on the extensions of the tools system \subpage toolextensions .
*/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
index 5dcdc18953..90cd5f934d 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
@@ -1,1226 +1,1238 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkProperties.h"
#include "mitkSegTool2D.h"
#include "mitkStatusBar.h"
#include "QmitkStdMultiWidget.h"
#include "QmitkNewSegmentationDialog.h"
#include <QMessageBox>
#include <berryIWorkbenchPage.h>
#include "QmitkSegmentationView.h"
#include "QmitkSegmentationOrganNamesHandling.cpp"
#include <mitkSurfaceToImageFilter.h>
#include "mitkVtkResliceInterpolationProperty.h"
#include "mitkApplicationCursor.h"
#include "mitkSegmentationObjectFactory.h"
#include "mitkPluginActivator.h"
#include "usModuleResource.h"
#include "usModuleResourceStream.h"
//micro service to get the ToolManager instance
#include "mitkToolManagerProvider.h"
const std::string QmitkSegmentationView::VIEW_ID =
"org.mitk.views.segmentation";
// public methods
QmitkSegmentationView::QmitkSegmentationView()
:m_Parent(NULL)
,m_Controls(NULL)
,m_MultiWidget(NULL)
,m_DataSelectionChanged(false)
,m_MouseCursorSet(false)
{
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti);
isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi);
m_IsOfTypeImagePredicate = mitk::NodePredicateOr::New(isDiffusionImage, mitk::TNodePredicateDataType<mitk::Image>::New());
m_IsBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
m_IsNotBinaryPredicate = mitk::NodePredicateNot::New( m_IsBinaryPredicate );
m_IsNotABinaryImagePredicate = mitk::NodePredicateAnd::New( m_IsOfTypeImagePredicate, m_IsNotBinaryPredicate );
m_IsABinaryImagePredicate = mitk::NodePredicateAnd::New( m_IsOfTypeImagePredicate, m_IsBinaryPredicate);
}
QmitkSegmentationView::~QmitkSegmentationView()
{
delete m_Controls;
}
void QmitkSegmentationView::NewNodesGenerated()
{
MITK_WARN<<"Use of deprecated function: NewNodesGenerated!! This function is empty and will be removed in the next time!";
}
void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes)
{
if (!nodes) return;
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
if (!toolManager) return;
for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
{
this->FireNodeSelected( *iter );
// only last iteration meaningful, multiple generated objects are not taken into account here
}
}
void QmitkSegmentationView::Visible()
{
if (m_DataSelectionChanged)
{
this->OnSelectionChanged(this->GetDataManagerSelection());
}
}
void QmitkSegmentationView::Activated()
{
// should be moved to ::BecomesVisible() or similar
if( m_Controls )
{
m_Controls->m_ManualToolSelectionBox2D->setEnabled( true );
m_Controls->m_ManualToolSelectionBox3D->setEnabled( true );
// m_Controls->m_OrganToolSelectionBox->setEnabled( true );
// m_Controls->m_LesionToolSelectionBox->setEnabled( true );
// m_Controls->m_SlicesInterpolator->Enable3DInterpolation( m_Controls->widgetStack->currentWidget() == m_Controls->pageManual );
mitk::DataStorage::SetOfObjects::ConstPointer segmentations = this->GetDefaultDataStorage()->GetSubset( m_IsABinaryImagePredicate );
mitk::DataStorage::SetOfObjects::ConstPointer image = this->GetDefaultDataStorage()->GetSubset( m_IsNotABinaryImagePredicate );
if (!image->empty()) {
OnSelectionChanged(*image->begin());
}
for ( mitk::DataStorage::SetOfObjects::const_iterator iter = segmentations->begin();
iter != segmentations->end();
++iter)
{
mitk::DataNode* node = *iter;
itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged);
m_WorkingDataObserverTags.insert( std::pair<mitk::DataNode*, unsigned long>( node, node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) );
itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command2 = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged);
m_BinaryPropertyObserverTags.insert( std::pair<mitk::DataNode*, unsigned long>( node, node->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) );
}
}
itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command3 = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
command3->SetCallbackFunction( this, &QmitkSegmentationView::RenderingManagerReinitialized );
m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver( mitk::RenderingManagerViewsInitializedEvent(), command3 );
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode());
}
void QmitkSegmentationView::Deactivated()
{
if( m_Controls )
{
this->SetToolSelectionBoxesEnabled( false );
//deactivate all tools
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
//Removing all observers
for ( NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter )
{
(*dataIter).first->GetProperty("visible")->RemoveObserver( (*dataIter).second );
}
m_WorkingDataObserverTags.clear();
for ( NodeTagMapType::iterator dataIter = m_BinaryPropertyObserverTags.begin(); dataIter != m_BinaryPropertyObserverTags.end(); ++dataIter )
{
(*dataIter).first->GetProperty("binary")->RemoveObserver( (*dataIter).second );
}
m_BinaryPropertyObserverTags.clear();
mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag);
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>();
mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef);
service->RemoveAllPlanePositions();
context->ungetService(ppmRef);
this->SetToolManagerSelection(0,0);
}
}
void QmitkSegmentationView::StdMultiWidgetAvailable( QmitkStdMultiWidget& stdMultiWidget )
{
SetMultiWidget(&stdMultiWidget);
}
void QmitkSegmentationView::StdMultiWidgetNotAvailable()
{
SetMultiWidget(NULL);
}
void QmitkSegmentationView::StdMultiWidgetClosed( QmitkStdMultiWidget& /*stdMultiWidget*/ )
{
SetMultiWidget(NULL);
}
void QmitkSegmentationView::SetMultiWidget(QmitkStdMultiWidget* multiWidget)
{
// save the current multiwidget as the working widget
m_MultiWidget = multiWidget;
if (m_Parent)
{
m_Parent->setEnabled(m_MultiWidget);
}
// tell the interpolation about toolmanager and multiwidget (and data storage)
if (m_Controls && m_MultiWidget)
{
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
m_Controls->m_SlicesInterpolator->SetDataStorage( this->GetDefaultDataStorage());
QList<mitk::SliceNavigationController*> controllers;
controllers.push_back(m_MultiWidget->GetRenderWindow1()->GetSliceNavigationController());
controllers.push_back(m_MultiWidget->GetRenderWindow2()->GetSliceNavigationController());
controllers.push_back(m_MultiWidget->GetRenderWindow3()->GetSliceNavigationController());
m_Controls->m_SlicesInterpolator->Initialize( toolManager, controllers );
}
}
void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if (m_Controls != NULL)
{
bool slimView = prefs->GetBool("slim view", false);
m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView);
m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView);
}
m_AutoSelectionEnabled = prefs->GetBool("auto selection", false);
this->ForceDisplayPreferencesUponAllImages();
}
void QmitkSegmentationView::CreateNewSegmentation()
{
mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
if (node.IsNotNull())
{
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
if (image.IsNotNull())
{
if (image->GetDimension()>1)
{
// ask about the name and organ type of the new segmentation
QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog( m_Parent ); // needs a QWidget as parent, "this" is not QWidget
QString storedList = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") );
QStringList organColors;
if (storedList.isEmpty())
{
organColors = GetDefaultOrganColorString();
}
else
{
/*
a couple of examples of how organ names are stored:
a simple item is built up like 'name#AABBCC' where #AABBCC is the hexadecimal notation of a color as known from HTML
items are stored separated by ';'
this makes it necessary to escape occurrences of ';' in name.
otherwise the string "hugo;ypsilon#AABBCC;eugen#AABBCC" could not be parsed as two organs
but we would get "hugo" and "ypsilon#AABBCC" and "eugen#AABBCC"
so the organ name "hugo;ypsilon" is stored as "hugo\;ypsilon"
and must be unescaped after loading
the following lines could be one split with Perl's negative lookbehind
*/
// recover string list from BlueBerry view's preferences
QString storedString = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") );
MITK_DEBUG << "storedString: " << storedString.toStdString();
// match a string consisting of any number of repetitions of either "anything but ;" or "\;". This matches everything until the next unescaped ';'
QRegExp onePart("(?:[^;]|\\\\;)*");
MITK_DEBUG << "matching " << onePart.pattern().toStdString();
int count = 0;
int pos = 0;
while( (pos = onePart.indexIn( storedString, pos )) != -1 )
{
++count;
int length = onePart.matchedLength();
if (length == 0) break;
QString matchedString = storedString.mid(pos, length);
MITK_DEBUG << " Captured length " << length << ": " << matchedString.toStdString();
pos += length + 1; // skip separating ';'
// unescape possible occurrences of '\;' in the string
matchedString.replace("\\;", ";");
// add matched string part to output list
organColors << matchedString;
}
MITK_DEBUG << "Captured " << count << " organ name/colors";
}
dialog->SetSuggestionList( organColors );
int dialogReturnValue = dialog->exec();
if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar
// ask the user about an organ type and name, add this information to the image's (!) propertylist
// create a new image of the same dimensions and smallest possible pixel type
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
mitk::Tool* firstTool = toolManager->GetToolById(0);
if (firstTool)
{
try
{
std::string newNodeName = dialog->GetSegmentationName().toStdString();
if(newNodeName.empty())
newNodeName = "no_name";
mitk::DataNode::Pointer emptySegmentation =
firstTool->CreateEmptySegmentationNode( image, newNodeName, dialog->GetColor() );
// initialize showVolume to false to prevent recalculating the volume while working on the segmentation
emptySegmentation->SetProperty( "showVolume", mitk::BoolProperty::New( false ) );
if (!emptySegmentation) return; // could be aborted by user
UpdateOrganList( organColors, dialog->GetSegmentationName(), dialog->GetColor() );
/*
escape ';' here (replace by '\;'), see longer comment above
*/
std::string stringForStorage = organColors.replaceInStrings(";","\\;").join(";").toStdString();
MITK_DEBUG << "Will store: " << stringForStorage;
this->GetPreferences()->PutByteArray("Organ-Color-List", stringForStorage );
this->GetPreferences()->Flush();
if(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0))
{
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false);
}
emptySegmentation->SetSelected(true);
this->GetDefaultDataStorage()->Add( emptySegmentation, node ); // add as a child, because the segmentation "derives" from the original
this->ApplyDisplayOptions( emptySegmentation );
this->FireNodeSelected( emptySegmentation );
this->OnSelectionChanged( emptySegmentation );
m_Controls->segImageSelector->SetSelectedNode(emptySegmentation);
}
catch (std::bad_alloc)
{
QMessageBox::warning(NULL,"Create new segmentation","Could not allocate memory for new segmentation");
}
}
}
else
{
QMessageBox::information(NULL,"Segmentation","Segmentation is currently not supported for 2D images");
}
}
}
else
{
MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected...";
}
}
void QmitkSegmentationView::OnWorkingNodeVisibilityChanged()
{
mitk::DataNode* selectedNode = m_Controls->segImageSelector->GetSelectedNode();
+ if ( !selectedNode )
+ {
+ this->SetToolSelectionBoxesEnabled(false);
+ return;
+ }
+
bool selectedNodeIsVisible = selectedNode->IsVisible(mitk::BaseRenderer::GetInstance(
mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")));
if (!selectedNodeIsVisible)
{
this->SetToolSelectionBoxesEnabled(false);
this->UpdateWarningLabel("The selected segmentation is currently not visible!");
}
else
{
this->SetToolSelectionBoxesEnabled(true);
this->UpdateWarningLabel("");
}
}
void QmitkSegmentationView::OnBinaryPropertyChanged()
{
mitk::DataStorage::SetOfObjects::ConstPointer patImages = m_Controls->patImageSelector->GetNodes();
bool isBinary(false);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = patImages->Begin(); it != patImages->End(); ++it)
{
const mitk::DataNode* node = it->Value();
node->GetBoolProperty("binary", isBinary);
if(isBinary)
{
m_Controls->patImageSelector->RemoveNode(node);
m_Controls->segImageSelector->AddNode(node);
this->SetToolManagerSelection(NULL,NULL);
return;
}
}
mitk::DataStorage::SetOfObjects::ConstPointer segImages = m_Controls->segImageSelector->GetNodes();
isBinary = true;
for (mitk::DataStorage::SetOfObjects::ConstIterator it = segImages->Begin(); it != segImages->End(); ++it)
{
const mitk::DataNode* node = it->Value();
node->GetBoolProperty("binary", isBinary);
if(!isBinary)
{
m_Controls->segImageSelector->RemoveNode(node);
m_Controls->patImageSelector->AddNode(node);
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node)
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->SetWorkingData(NULL);
return;
}
}
}
void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node)
{
bool isBinary (false);
bool isHelperObject (false);
node->GetBoolProperty("binary", isBinary);
node->GetBoolProperty("helper object", isHelperObject);
if (m_AutoSelectionEnabled)
{
if (!isBinary && dynamic_cast<mitk::Image*>(node->GetData()))
{
FireNodeSelected(const_cast<mitk::DataNode*>(node));
}
}
if (isBinary && !isHelperObject)
{
itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged);
m_WorkingDataObserverTags.insert( std::pair<mitk::DataNode*, unsigned long>( const_cast<mitk::DataNode*>(node), node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) );
itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command2 = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged);
m_BinaryPropertyObserverTags.insert( std::pair<mitk::DataNode*, unsigned long>( const_cast<mitk::DataNode*>(node), node->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) );
this->ApplyDisplayOptions( const_cast<mitk::DataNode*>(node) );
m_Controls->segImageSelector->setCurrentIndex( m_Controls->segImageSelector->Find(node) );
}
}
void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node)
{
bool isSeg(false);
bool isHelperObject(false);
node->GetBoolProperty("helper object", isHelperObject);
node->GetBoolProperty("binary", isSeg);
mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData());
if(isSeg && !isHelperObject && image)
{
//First of all remove all possible contour markers of the segmentation
mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker"
, mitk::BoolProperty::New(true)));
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>();
mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t+1).c_str())-1;
service->RemovePlanePosition(id);
this->GetDataStorage()->Remove(it->Value());
}
context->ungetService(ppmRef);
service = NULL;
if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull())
{
this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), NULL);
this->UpdateWarningLabel("Select or create a segmentation");
}
mitk::SurfaceInterpolationController::GetInstance()->RemoveSegmentationFromContourList(image);
}
mitk::DataNode* tempNode = const_cast<mitk::DataNode*>(node);
//Since the binary property could be changed during runtime by the user
if (image && !isHelperObject)
{
node->GetProperty("visible")->RemoveObserver( m_WorkingDataObserverTags[tempNode] );
m_WorkingDataObserverTags.erase(tempNode);
node->GetProperty("binary")->RemoveObserver( m_BinaryPropertyObserverTags[tempNode] );
m_BinaryPropertyObserverTags.erase(tempNode);
}
if((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) == node))
{
//as we don't know which node was actually removed e.g. our reference node, disable 'New Segmentation' button.
//consider the case that there is no more image in the datastorage
this->SetToolManagerSelection(NULL, NULL);
this->SetToolSelectionBoxesEnabled( false );
}
}
//void QmitkSegmentationView::CreateSegmentationFromSurface()
//{
// mitk::DataNode::Pointer surfaceNode =
// m_Controls->MaskSurfaces->GetSelectedNode();
// mitk::Surface::Pointer surface(0);
// if(surfaceNode.IsNotNull())
// surface = dynamic_cast<mitk::Surface*> ( surfaceNode->GetData() );
// if(surface.IsNull())
// {
// this->HandleException( "No surface selected.", m_Parent, true);
// return;
// }
// mitk::DataNode::Pointer imageNode
// = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
// mitk::Image::Pointer image(0);
// if (imageNode.IsNotNull())
// image = dynamic_cast<mitk::Image*>( imageNode->GetData() );
// if(image.IsNull())
// {
// this->HandleException( "No image selected.", m_Parent, true);
// return;
// }
// mitk::SurfaceToImageFilter::Pointer s2iFilter
// = mitk::SurfaceToImageFilter::New();
// s2iFilter->MakeOutputBinaryOn();
// s2iFilter->SetInput(surface);
// s2iFilter->SetImage(image);
// s2iFilter->Update();
// mitk::DataNode::Pointer resultNode = mitk::DataNode::New();
// std::string nameOfResultImage = imageNode->GetName();
// nameOfResultImage.append(surfaceNode->GetName());
// resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) );
// resultNode->SetProperty("binary", mitk::BoolProperty::New(true) );
// resultNode->SetData( s2iFilter->GetOutput() );
// this->GetDataStorage()->Add(resultNode, imageNode);
//}
//void QmitkSegmentationView::ToolboxStackPageChanged(int id)
//{
// // interpolation only with manual tools visible
// m_Controls->m_SlicesInterpolator->EnableInterpolation( id == 0 );
// if( id == 0 )
// {
// mitk::DataNode::Pointer workingData = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0);
// if( workingData.IsNotNull() )
// {
// m_Controls->segImageSelector->setCurrentIndex( m_Controls->segImageSelector->Find(workingData) );
// }
// }
// // this is just a workaround, should be removed when all tools support 3D+t
// if (id==2) // lesions
// {
// mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
// if (node.IsNotNull())
// {
// mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
// if (image.IsNotNull())
// {
// if (image->GetDimension()>3)
// {
// m_Controls->widgetStack->setCurrentIndex(0);
// QMessageBox::information(NULL,"Segmentation","Lesion segmentation is currently not supported for 4D images");
// }
// }
// }
// }
//}
// protected
void QmitkSegmentationView::OnPatientComboBoxSelectionChanged( const mitk::DataNode* node )
{
//mitk::DataNode* selectedNode = const_cast<mitk::DataNode*>(node);
if( node != NULL )
{
this->UpdateWarningLabel("");
mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode();
if (segNode)
{
mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources( segNode, m_IsNotABinaryImagePredicate );
bool isSourceNode(false);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = possibleParents->Begin(); it != possibleParents->End(); it++)
{
if (it.Value() == node)
isSourceNode = true;
}
if ( !isSourceNode && (!this->CheckForSameGeometry(segNode, node) || possibleParents->Size() > 0 ))
{
this->SetToolManagerSelection(node, NULL);
this->SetToolSelectionBoxesEnabled( false );
this->UpdateWarningLabel("The selected patient image does not match with the selected segmentation!");
}
else if ((!isSourceNode && this->CheckForSameGeometry(segNode, node)) || isSourceNode )
{
this->SetToolManagerSelection(node, segNode);
//Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are
//loaded separately
int layer(10);
node->GetIntProperty("layer", layer);
layer++;
segNode->SetProperty("layer", mitk::IntProperty::New(layer));
//this->UpdateWarningLabel("");
RenderingManagerReinitialized();
}
}
else
{
this->SetToolManagerSelection(node, NULL);
this->SetToolSelectionBoxesEnabled( false );
this->UpdateWarningLabel("Select or create a segmentation");
}
}
else
{
this->UpdateWarningLabel("Please load an image!");
this->SetToolSelectionBoxesEnabled( false );
}
}
void QmitkSegmentationView::OnSegmentationComboBoxSelectionChanged(const mitk::DataNode *node)
{
if (node == NULL)
{
this->UpdateWarningLabel("Select or create a segmentation");
this->SetToolSelectionBoxesEnabled( false );
return;
}
mitk::DataNode* refNode = m_Controls->patImageSelector->GetSelectedNode();
RenderingManagerReinitialized();
- if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not nede to go any further
+ if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further
return;
if (m_AutoSelectionEnabled)
{
this->OnSelectionChanged(const_cast<mitk::DataNode*>(node));
}
else
{
mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources( node, m_IsNotABinaryImagePredicate );
if ( possibleParents->Size() == 1 )
{
mitk::DataNode* parentNode = possibleParents->ElementAt(0);
if (parentNode != refNode)
{
this->UpdateWarningLabel("The selected segmentation does not match with the selected patient image!");
this->SetToolSelectionBoxesEnabled( false );
this->SetToolManagerSelection(NULL, node);
}
else
{
this->UpdateWarningLabel("");
this->SetToolManagerSelection(refNode, node);
}
}
else if (refNode && this->CheckForSameGeometry(node, refNode))
{
this->UpdateWarningLabel("");
this->SetToolManagerSelection(refNode, node);
}
else if (!refNode || !this->CheckForSameGeometry(node, refNode))
{
this->UpdateWarningLabel("Please select or load the according patient image!");
}
}
if (!node->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))))
{
this->UpdateWarningLabel("The selected segmentation is currently not visible!");
this->SetToolSelectionBoxesEnabled( false );
}
}
void QmitkSegmentationView::OnShowMarkerNodes (bool state)
{
mitk::SegTool2D::Pointer manualSegmentationTool;
unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size();
for(unsigned int i = 0; i < numberOfExistingTools; i++)
{
manualSegmentationTool = dynamic_cast<mitk::SegTool2D*>(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i));
if (manualSegmentationTool)
{
if(state == true)
{
manualSegmentationTool->SetShowMarkerNodes( true );
}
else
{
manualSegmentationTool->SetShowMarkerNodes( false );
}
}
}
}
void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node)
{
std::vector<mitk::DataNode*> nodes;
nodes.push_back( node );
this->OnSelectionChanged( nodes );
}
void QmitkSegmentationView::OnSelectionChanged(std::vector<mitk::DataNode*> nodes)
{
if (nodes.size() != 0)
{
std::string markerName = "Position";
unsigned int numberOfNodes = nodes.size();
std::string nodeName = nodes.at( 0 )->GetName();
if ( ( numberOfNodes == 1 ) && ( nodeName.find( markerName ) == 0) )
{
this->OnContourMarkerSelected( nodes.at( 0 ) );
return;
}
}
if (m_AutoSelectionEnabled && this->IsActivated())
{
if (nodes.size() == 0 && m_Controls->patImageSelector->GetSelectedNode().IsNull())
{
SetToolManagerSelection(NULL,NULL);
}
else if (nodes.size() == 1)
{
mitk::DataNode::Pointer selectedNode = nodes.at(0);
if(selectedNode.IsNull())
{
return;
}
mitk::Image::Pointer selectedImage = dynamic_cast<mitk::Image*>(selectedNode->GetData());
if (selectedImage.IsNull())
{
SetToolManagerSelection(NULL,NULL);
return;
}
else
{
bool isASegmentation(false);
selectedNode->GetBoolProperty("binary", isASegmentation);
if (isASegmentation)
{
//If a segmentation is selected find a possible reference image:
mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(selectedNode, m_IsNotABinaryImagePredicate);
mitk::DataNode::Pointer refNode;
if (sources->Size() != 0)
{
refNode = sources->ElementAt(0);
refNode->SetVisibility(true);
selectedNode->SetVisibility(true);
SetToolManagerSelection(refNode,selectedNode);
mitk::DataStorage::SetOfObjects::ConstPointer otherSegmentations = this->GetDataStorage()->GetSubset(m_IsABinaryImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherSegmentations->begin(); iter != otherSegmentations->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast<mitk::Image*>(node->GetData()) != selectedImage.GetPointer())
node->SetVisibility(false);
}
mitk::DataStorage::SetOfObjects::ConstPointer otherPatientImages = this->GetDataStorage()->GetSubset(m_IsNotABinaryImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherPatientImages->begin(); iter != otherPatientImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast<mitk::Image*>(node->GetData()) != dynamic_cast<mitk::Image*>(refNode->GetData()))
node->SetVisibility(false);
}
}
else
{
mitk::DataStorage::SetOfObjects::ConstPointer possiblePatientImages = this->GetDataStorage()->GetSubset(m_IsNotABinaryImagePredicate);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = possiblePatientImages->Begin(); it != possiblePatientImages->End(); it++)
{
refNode = it->Value();
if (this->CheckForSameGeometry(selectedNode, it->Value()))
{
refNode->SetVisibility(true);
selectedNode->SetVisibility(true);
mitk::DataStorage::SetOfObjects::ConstPointer otherSegmentations = this->GetDataStorage()->GetSubset(m_IsABinaryImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherSegmentations->begin(); iter != otherSegmentations->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast<mitk::Image*>(node->GetData()) != selectedImage.GetPointer())
node->SetVisibility(false);
}
mitk::DataStorage::SetOfObjects::ConstPointer otherPatientImages = this->GetDataStorage()->GetSubset(m_IsNotABinaryImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherPatientImages->begin(); iter != otherPatientImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast<mitk::Image*>(node->GetData()) != dynamic_cast<mitk::Image*>(refNode->GetData()))
node->SetVisibility(false);
}
this->SetToolManagerSelection(refNode, selectedNode);
//Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are at the
//same level in the datamanager
int layer(10);
refNode->GetIntProperty("layer", layer);
layer++;
selectedNode->SetProperty("layer", mitk::IntProperty::New(layer));
return;
}
}
this->SetToolManagerSelection(NULL, selectedNode);
}
}
else
{
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) != selectedNode)
{
SetToolManagerSelection(selectedNode, NULL);
//May be a bug in the selection services. A node which is deselected will be passed as selected node to the OnSelectionChanged function
if (!selectedNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))))
selectedNode->SetVisibility(true);
this->UpdateWarningLabel("The selected patient image does not\nmatchwith the selected segmentation!");
this->SetToolSelectionBoxesEnabled( false );
}
}
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+ if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further
+ return;
+ RenderingManagerReinitialized();
}
}
void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node)
{
QmitkRenderWindow* selectedRenderWindow = 0;
QmitkRenderWindow* RenderWindow1 =
this->GetActiveStdMultiWidget()->GetRenderWindow1();
QmitkRenderWindow* RenderWindow2 =
this->GetActiveStdMultiWidget()->GetRenderWindow2();
QmitkRenderWindow* RenderWindow3 =
this->GetActiveStdMultiWidget()->GetRenderWindow3();
QmitkRenderWindow* RenderWindow4 =
this->GetActiveStdMultiWidget()->GetRenderWindow4();
bool PlanarFigureInitializedWindow = false;
// find initialized renderwindow
if (node->GetBoolProperty("PlanarFigureInitializedWindow",
PlanarFigureInitializedWindow, RenderWindow1->GetRenderer()))
{
selectedRenderWindow = RenderWindow1;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
RenderWindow2->GetRenderer()))
{
selectedRenderWindow = RenderWindow2;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
RenderWindow3->GetRenderer()))
{
selectedRenderWindow = RenderWindow3;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
RenderWindow4->GetRenderer()))
{
selectedRenderWindow = RenderWindow4;
}
// make node visible
if (selectedRenderWindow)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t+1).c_str())-1;
{
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>();
mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef);
selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id));
context->ungetService(ppmRef);
}
selectedRenderWindow->GetRenderer()->GetDisplayGeometry()->Fit();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkSegmentationView::OnTabWidgetChanged(int id)
{
//always disable tools on tab changed
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
//2D Tab ID = 0
//3D Tab ID = 1
if (id == 0)
{
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox3D->hide();
m_Controls->m_ManualToolSelectionBox2D->show();
//Deactivate possible active tool
//TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator
}
else
{
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox2D->hide();
m_Controls->m_ManualToolSelectionBox3D->show();
//Deactivate possible active tool
}
}
void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData)
{
// called as a result of new BlueBerry selections
// tells the ToolManager for manual segmentation about new selections
// updates GUI information about what the user should select
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
toolManager->SetReferenceData(const_cast<mitk::DataNode*>(referenceData));
toolManager->SetWorkingData( const_cast<mitk::DataNode*>(workingData));
// check original image
m_Controls->btnNewSegmentation->setEnabled(referenceData != NULL);
if (referenceData)
{
this->UpdateWarningLabel("");
disconnect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) );
m_Controls->patImageSelector->setCurrentIndex( m_Controls->patImageSelector->Find(referenceData) );
connect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) );
}
// check segmentation
if (referenceData)
{
if (workingData)
{
this->FireNodeSelected(const_cast<mitk::DataNode*>(workingData));
// if( m_Controls->widgetStack->currentIndex() == 0 )
// {
disconnect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnSegmentationComboBoxSelectionChanged( const mitk::DataNode* ) ) );
m_Controls->segImageSelector->setCurrentIndex(m_Controls->segImageSelector->Find(workingData));
connect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*)) );
// }
}
}
}
void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages()
{
if (!m_Parent || !m_Parent->isVisible()) return;
// check all images and segmentations in DataStorage:
// (items in brackets are implicitly done by previous steps)
// 1.
// if a reference image is selected,
// show the reference image
// and hide all other images (orignal and segmentation),
// (and hide all segmentations of the other original images)
// and show all the reference's segmentations
// if no reference image is selected, do do nothing
//
// 2.
// if a segmentation is selected,
// show it
// (and hide all all its siblings (childs of the same parent, incl, NULL parent))
// if no segmentation is selected, do nothing
if (!m_Controls)
return; // might happen on initialization (preferences loaded)
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
mitk::DataNode::Pointer referenceData = toolManager->GetReferenceData(0);
mitk::DataNode::Pointer workingData = toolManager->GetWorkingData(0);
// 1.
if (referenceData.IsNotNull())
{
// iterate all images
mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDefaultDataStorage()->GetSubset( m_IsABinaryImagePredicate );
for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
// apply display preferences
ApplyDisplayOptions(node);
// set visibility
node->SetVisibility(node == referenceData);
}
}
// 2.
if (workingData.IsNotNull())
workingData->SetVisibility(true);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node)
{
if (!node) return;
bool isBinary(false);
node->GetPropertyValue("binary", isBinary);
if (isBinary)
{
node->SetProperty( "outline binary", mitk::BoolProperty::New( this->GetPreferences()->GetBool("draw outline", true)) );
node->SetProperty( "outline width", mitk::FloatProperty::New( 2.0 ) );
node->SetProperty( "opacity", mitk::FloatProperty::New( this->GetPreferences()->GetBool("draw outline", true) ? 1.0 : 0.3 ) );
node->SetProperty( "volumerendering", mitk::BoolProperty::New( this->GetPreferences()->GetBool("volume rendering", false) ) );
}
}
void QmitkSegmentationView::RenderingManagerReinitialized()
{
if ( ! m_MultiWidget ) { return; }
/*
* Here we check whether the geometry of the selected segmentation image if aligned with the worldgeometry
* At the moment it is not supported to use a geometry different from the selected image for reslicing.
* For further information see Bug 16063
*/
mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode();
const mitk::BaseGeometry* worldGeo = m_MultiWidget->GetRenderWindow4()->GetSliceNavigationController()->GetCurrentGeometry3D();
if (workingNode && worldGeo)
{
const mitk::BaseGeometry* workingNodeGeo = workingNode->GetData()->GetGeometry();
- if (mitk::Equal(workingNodeGeo->GetBoundingBox(), worldGeo->GetBoundingBox(), mitk::eps, true))
+ const mitk::BaseGeometry* worldGeo = m_MultiWidget->GetRenderWindow4()->GetSliceNavigationController()->GetCurrentGeometry3D();
+ //if (mitk::Equal(workingNodeGeo->GetBoundingBox(), worldGeo->GetBoundingBox(), mitk::eps, true))
+ if (mitk::Equal(workingNodeGeo->GetCornerPoint(false,false,false), worldGeo->GetCornerPoint(false,false,false), mitk::eps) &&
+ mitk::Equal(workingNodeGeo->GetCornerPoint(true,true,true), worldGeo->GetCornerPoint(true,true,true), mitk::eps))
{
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), workingNode);
this->SetToolSelectionBoxesEnabled(true);
this->UpdateWarningLabel("");
}
else
{
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), NULL);
this->SetToolSelectionBoxesEnabled(false);
this->UpdateWarningLabel("Please perform a reinit on the segmentation image!");
}
}
}
bool QmitkSegmentationView::CheckForSameGeometry(const mitk::DataNode *node1, const mitk::DataNode *node2) const
{
bool isSameGeometry(true);
mitk::Image* image1 = dynamic_cast<mitk::Image*>(node1->GetData());
mitk::Image* image2 = dynamic_cast<mitk::Image*>(node2->GetData());
if (image1 && image2)
{
mitk::BaseGeometry* geo1 = image1->GetGeometry();
mitk::BaseGeometry* geo2 = image2->GetGeometry();
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetOrigin(), geo2->GetOrigin());
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(0), geo2->GetExtent(0));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(1), geo2->GetExtent(1));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(2), geo2->GetExtent(2));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetSpacing(), geo2->GetSpacing());
isSameGeometry = isSameGeometry && mitk::MatrixEqualElementWise(geo1->GetIndexToWorldTransform()->GetMatrix(), geo2->GetIndexToWorldTransform()->GetMatrix());
return isSameGeometry;
}
else
{
return false;
}
}
void QmitkSegmentationView::UpdateWarningLabel(QString text)
{
if (text.size() == 0)
m_Controls->lblSegmentationWarnings->hide();
else
m_Controls->lblSegmentationWarnings->show();
m_Controls->lblSegmentationWarnings->setText(text);
}
void QmitkSegmentationView::CreateQtPartControl(QWidget* parent)
{
// setup the basic GUI of this view
m_Parent = parent;
m_Controls = new Ui::QmitkSegmentationControls;
m_Controls->setupUi(parent);
m_Controls->patImageSelector->SetDataStorage(this->GetDefaultDataStorage());
m_Controls->patImageSelector->SetPredicate(m_IsNotABinaryImagePredicate);
this->UpdateWarningLabel("Please load an image");
if( m_Controls->patImageSelector->GetSelectedNode().IsNotNull() )
this->UpdateWarningLabel("Select or create a new segmentation");
m_Controls->segImageSelector->SetDataStorage(this->GetDefaultDataStorage());
m_Controls->segImageSelector->SetPredicate(m_IsABinaryImagePredicate);
if( m_Controls->segImageSelector->GetSelectedNode().IsNotNull() )
this->UpdateWarningLabel("");
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
assert ( toolManager );
toolManager->SetDataStorage( *(this->GetDefaultDataStorage()) );
toolManager->InitializeTools();
// all part of open source MITK
m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true);
m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer2D );
m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups("Add Subtract Correction Paint Wipe 'Region Growing' Fill Erase 'Live Wire' '2D Fast Marching'");
m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3);
m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible );
connect( m_Controls->m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int)) );
//setup 3D Tools
m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true);
m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer3D );
//specify tools to be added to 3D Tool area
m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking");
m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3);
m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible );
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox3D->hide();
m_Controls->m_ManualToolSelectionBox2D->show();
toolManager->NewNodesGenerated +=
mitk::MessageDelegate<QmitkSegmentationView>( this, &QmitkSegmentationView::NewNodesGenerated ); // update the list of segmentations
toolManager->NewNodeObjectsGenerated +=
mitk::MessageDelegate1<QmitkSegmentationView, mitk::ToolManager::DataVectorType*>( this, &QmitkSegmentationView::NewNodeObjectsGenerated ); // update the list of segmentations
// create signal/slot connections
connect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) );
connect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnSegmentationComboBoxSelectionChanged( const mitk::DataNode* ) ) );
connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) );
// connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) );
// connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) );
connect( m_Controls->tabWidgetSegmentationTools, SIGNAL(currentChanged(int)), this, SLOT(OnTabWidgetChanged(int)));
// connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
// this, SLOT( OnSurfaceSelectionChanged( ) ) );
connect(m_Controls->m_SlicesInterpolator, SIGNAL(SignalShowMarkerNodes(bool)), this, SLOT(OnShowMarkerNodes(bool)));
// m_Controls->MaskSurfaces->SetDataStorage(this->GetDefaultDataStorage());
// m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface"));
}
void QmitkSegmentationView::OnManualTool2DSelected(int id)
{
if (id >= 0)
{
std::string text = "Active Tool: \"";
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
text += toolManager->GetToolById(id)->GetName();
text += "\"";
mitk::StatusBar::GetInstance()->DisplayText(text.c_str());
us::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource();
this->SetMouseCursor(resource, 0, 0);
}
else
{
this->ResetMouseCursor();
mitk::StatusBar::GetInstance()->DisplayText("");
}
}
void QmitkSegmentationView::ResetMouseCursor()
{
if ( m_MouseCursorSet )
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
m_MouseCursorSet = false;
}
}
void QmitkSegmentationView::SetMouseCursor( const us::ModuleResource& resource, int hotspotX, int hotspotY )
{
if (!resource) return;
// Remove previously set mouse cursor
if ( m_MouseCursorSet )
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
}
us::ModuleResourceStream cursor(resource, std::ios::binary);
mitk::ApplicationCursor::GetInstance()->PushCursor( cursor, hotspotX, hotspotY );
m_MouseCursorSet = true;
}
void QmitkSegmentationView::SetToolSelectionBoxesEnabled(bool status)
{
m_Controls->m_ManualToolSelectionBox2D->setEnabled(status);
m_Controls->m_ManualToolSelectionBox3D->setEnabled(status);
m_Controls->m_SlicesInterpolator->setEnabled(status);
}
// ATTENTION some methods for handling the known list of (organ names, colors) are defined in QmitkSegmentationOrganNamesHandling.cpp
diff --git a/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt
index a4b3d17818..12c8c7349f 100644
--- a/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt
@@ -1,7 +1,11 @@
project(org_mitk_gui_qt_simulation)
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE SIMULATION_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgets MitkSimulation
)
+
+if(MSVC)
+ set_property(TARGET ${PLUGIN_TARGET} APPEND_STRING PROPERTY COMPILE_FLAGS " /wd4250 /wd4251 /wd4267 /wd4275")
+endif()
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.simulation/files.cmake b/Plugins/org.mitk.gui.qt.simulation/files.cmake
index b9f3403b63..744bd1618c 100644
--- a/Plugins/org.mitk.gui.qt.simulation/files.cmake
+++ b/Plugins/org.mitk.gui.qt.simulation/files.cmake
@@ -1,39 +1,47 @@
set(SRC_CPP_FILES
)
set(INTERNAL_CPP_FILES
org_mitk_gui_qt_simulation_Activator.cpp
+ QmitkBaseItemDelegate.cpp
+ QmitkBaseTreeWidget.cpp
+ QmitkNoEditItemDelegate.cpp
+ QmitkSceneTreeWidget.cpp
QmitkSimulationPreferencePage.cpp
QmitkSimulationView.cpp
)
set(UI_FILES
src/internal/QmitkSimulationPreferencePageControls.ui
src/internal/QmitkSimulationViewControls.ui
)
set(MOC_H_FILES
src/internal/org_mitk_gui_qt_simulation_Activator.h
+ src/internal/QmitkBaseItemDelegate.h
+ src/internal/QmitkBaseTreeWidget.h
+ src/internal/QmitkNoEditItemDelegate.h
+ src/internal/QmitkSceneTreeWidget.h
src/internal/QmitkSimulationPreferencePage.h
src/internal/QmitkSimulationView.h
)
set(CACHED_RESOURCE_FILES
resources/SOFAIcon.png
plugin.xml
)
set(QRC_FILES
resources/Simulation.qrc
)
set(CPP_FILES
)
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach()
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach()
diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png
new file mode 100644
index 0000000000..558445718c
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png differ
diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png
new file mode 100644
index 0000000000..4832b76336
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png differ
diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc b/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc
index 53480e1d88..2684648ed4 100644
--- a/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc
+++ b/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc
@@ -1,5 +1,8 @@
<RCC>
<qresource prefix="/Simulation">
- <file>SOFAIcon.png</file>
+ <file alias="Node">Node_16x16.png</file>
+ <file alias="Object">Object_16x16.png</file>
+ <file alias="Slave">Slave_16x16.png</file>
+ <file alias="SOFAIcon">SOFAIcon.png</file>
</qresource>
</RCC>
diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png
new file mode 100644
index 0000000000..9281fff450
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png differ
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp
new file mode 100644
index 0000000000..dfc589a25d
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp
@@ -0,0 +1,77 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "QmitkBaseItemDelegate.h"
+#include <sofa/core/objectmodel/BaseData.h>
+
+using namespace sofa::defaulttype;
+using namespace sofa::core::objectmodel;
+
+static inline BaseData* GetBaseData(const QModelIndex& index)
+{
+ return index.data(Qt::UserRole).value<BaseData*>();
+}
+
+QmitkBaseItemDelegate::QmitkBaseItemDelegate(QObject* parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+QmitkBaseItemDelegate::~QmitkBaseItemDelegate()
+{
+}
+
+QWidget* QmitkBaseItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ BaseData* baseData = GetBaseData(index);
+ const AbstractTypeInfo* typeInfo = baseData->getValueTypeInfo();
+
+ if (typeInfo->name() == "bool")
+ {
+ assert(false && "Bool type is directly handled by QmitkBaseTreeWidget!");
+ }
+ else if (typeInfo->size() == 1)
+ {
+ if (typeInfo->Integer() || typeInfo->Scalar() || typeInfo->Text())
+ {
+ // TODO: TagSet
+ return QStyledItemDelegate::createEditor(parent, option, index);
+ }
+
+ // TODO
+ }
+ else
+ {
+ // TODO
+ }
+
+ return NULL;
+}
+
+void QmitkBaseItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ QStyledItemDelegate::paint(painter, option, index);
+}
+
+void QmitkBaseItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
+{
+ QStyledItemDelegate::setEditorData(editor, index);
+}
+
+void QmitkBaseItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
+{
+ QStyledItemDelegate::setModelData(editor, model, index);
+}
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h
new file mode 100644
index 0000000000..01a009a16d
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h
@@ -0,0 +1,49 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef QmitkBaseItemDelegate_h
+#define QmitkBaseItemDelegate_h
+
+#include <QStyledItemDelegate>
+
+namespace sofa
+{
+ namespace core
+ {
+ namespace objectmodel
+ {
+ class BaseData;
+ }
+ }
+}
+
+class QmitkBaseItemDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit QmitkBaseItemDelegate(QObject* parent = NULL);
+ ~QmitkBaseItemDelegate();
+
+ QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void setEditorData(QWidget* editor, const QModelIndex& index) const;
+ void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
+};
+
+Q_DECLARE_METATYPE(sofa::core::objectmodel::BaseData*)
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp
new file mode 100644
index 0000000000..60fa449d06
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp
@@ -0,0 +1,115 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <QHeaderView>
+#include "QmitkBaseTreeWidget.h"
+#include "QmitkBaseItemDelegate.h"
+#include "QmitkNoEditItemDelegate.h"
+#include "QmitkSceneTreeWidget.h"
+
+QmitkBaseTreeWidget::QmitkBaseTreeWidget(QWidget* parent)
+ : QTreeWidget(parent),
+ m_Base(NULL)
+{
+ this->setItemDelegateForColumn(0, new QmitkNoEditItemDelegate);
+ this->setItemDelegateForColumn(1, new QmitkBaseItemDelegate);
+
+ this->setSortingEnabled(true);
+ this->header()->setSortIndicator(0, Qt::AscendingOrder);
+}
+
+QmitkBaseTreeWidget::~QmitkBaseTreeWidget()
+{
+}
+
+void QmitkBaseTreeWidget::clear()
+{
+ m_Base = NULL;
+ m_GroupItemMap.clear();
+
+ QTreeWidget::clear();
+}
+
+void QmitkBaseTreeWidget::OnSelectedBaseChanged(Base* base)
+{
+ this->clear();
+
+ m_Base = base;
+
+ if (base != NULL)
+ this->FillTreeWidget();
+}
+
+void QmitkBaseTreeWidget::FillTreeWidget()
+{
+ const Base::VecData& dataFields = m_Base->getDataFields();
+
+ for (Base::VecData::const_iterator dataField = dataFields.begin(); dataField != dataFields.end(); ++dataField)
+ {
+ if (!(*dataField)->isDisplayed())
+ continue;
+
+ QString name = QString::fromStdString((*dataField)->getName());
+
+ if (name.isEmpty())
+ continue;
+
+ QString group = (*dataField)->getGroup();
+
+ if (!group.isEmpty() && !m_GroupItemMap.contains(group))
+ m_GroupItemMap.insert(group, new QTreeWidgetItem(this, QStringList() << group));
+
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() << name);
+ item->setToolTip(0, (*dataField)->getHelp());
+
+ item->setFlags(!(*dataField)->isReadOnly()
+ ? item->flags() | Qt::ItemIsEditable
+ : Qt::ItemIsSelectable);
+
+ QString type = QString::fromStdString((*dataField)->getValueTypeString());
+
+ if (type == "bool")
+ {
+ item->setFlags((item->flags() & ~Qt::EditRole) | Qt::ItemIsUserCheckable);
+ item->setCheckState(1, (*dataField)->getValueString() == "1" ? Qt::Checked : Qt::Unchecked);
+ }
+ else
+ {
+ if (type == "double" || type == "float" || type == "int" || type == "string" || type == "unsigned int")
+ {
+ item->setData(1, Qt::DisplayRole, QVariant::fromValue(QString::fromStdString((*dataField)->getValueString())));
+ }
+ else
+ {
+ item->setData(1, Qt::DisplayRole, QVariant::fromValue("[" + type + "]"));
+ }
+
+ item->setData(1, Qt::UserRole, QVariant::fromValue(*dataField));
+ }
+
+ if (group.isEmpty())
+ {
+ this->addTopLevelItem(item);
+ }
+ else
+ {
+ m_GroupItemMap[group]->addChild(item);
+ }
+ }
+
+ this->setRootIsDecorated(!m_GroupItemMap.isEmpty());
+ this->expandAll();
+}
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h
new file mode 100644
index 0000000000..0aed7ef6c6
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h
@@ -0,0 +1,60 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef QmitkBaseTreeWidget_h
+#define QmitkBaseTreeWidget_h
+
+#include <QMap>
+#include <QTreeWidget>
+
+namespace sofa
+{
+ namespace core
+ {
+ namespace objectmodel
+ {
+ class Base;
+ }
+ }
+}
+
+class QmitkSceneTreeWidget;
+
+class QmitkBaseTreeWidget : public QTreeWidget
+{
+ Q_OBJECT
+
+public:
+ typedef sofa::core::objectmodel::Base Base;
+
+ explicit QmitkBaseTreeWidget(QWidget* parent = NULL);
+ ~QmitkBaseTreeWidget();
+
+ // QTreeWidget, QTreeView, and QAbstractItemView Interfaces /////////////////
+ void clear();
+ /////////////////////////////////////////////////////////////////////////////
+
+public slots:
+ void OnSelectedBaseChanged(Base* base);
+
+private:
+ void FillTreeWidget();
+
+ Base* m_Base;
+ QMap<QString, QTreeWidgetItem*> m_GroupItemMap;
+};
+
+#endif
diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp
similarity index 61%
rename from Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.h
rename to Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp
index 5f283e790a..7d2d6733ed 100644
--- a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.h
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp
@@ -1,28 +1,31 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef mitkGetSimulationDataNode_h
-#define mitkGetSimulationDataNode_h
+#include "QmitkNoEditItemDelegate.h"
-#include <mitkDataNode.h>
-#include <sofa/core/objectmodel/BaseNode.h>
+QmitkNoEditItemDelegate::QmitkNoEditItemDelegate(QObject* parent)
+ : QStyledItemDelegate(parent)
+{
+}
-namespace mitk
+QmitkNoEditItemDelegate::~QmitkNoEditItemDelegate()
{
- DataNode::Pointer GetSimulationDataNode(sofa::core::objectmodel::BaseNode::SPtr rootNode);
}
-#endif
+QWidget* QmitkNoEditItemDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const
+{
+ return NULL;
+}
diff --git a/Modules/Ext/DataManagement/vtkObjectObserver.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h
similarity index 57%
rename from Modules/Ext/DataManagement/vtkObjectObserver.h
rename to Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h
index 9c61d4eab5..e1d2477073 100644
--- a/Modules/Ext/DataManagement/vtkObjectObserver.h
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h
@@ -1,28 +1,33 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef VTKOBJECTOBSERVER_H
-#define VTKOBJECTOBSERVER_H
-class vtkObject;
+#ifndef QmitkNoEditItemDelegate_h
+#define QmitkNoEditItemDelegate_h
-class vtkObjectObserver
+#include <QStyledItemDelegate>
+
+class QmitkNoEditItemDelegate : public QStyledItemDelegate
{
+ Q_OBJECT
+
public:
- virtual void OnModified( const vtkObject* object ) = 0;
- virtual void OnDeleted( const vtkObject* object ) = 0;
+ explicit QmitkNoEditItemDelegate(QObject* parent = NULL);
+ ~QmitkNoEditItemDelegate();
+
+ QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
};
-#endif // VTKOBJECTOBSERVER_H
+#endif
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp
new file mode 100644
index 0000000000..f6938c7ed0
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp
@@ -0,0 +1,384 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "QmitkSceneTreeWidget.h"
+#include <sofa/core/collision/CollisionGroupManager.h>
+#include <sofa/core/collision/ContactManager.h>
+#include <sofa/simulation/common/Colors.h>
+#include <sofa/simulation/common/Node.h>
+
+template <class T>
+static inline T* as(QmitkSceneTreeWidget::Base* base)
+{
+ return dynamic_cast<T*>(base);
+}
+
+template <class T>
+static inline bool is(QmitkSceneTreeWidget::Base* base)
+{
+ return dynamic_cast<T*>(base) != NULL;
+}
+
+template <class T1, class T2>
+static inline bool is(QmitkSceneTreeWidget::Base* base)
+{
+ return is<T1>(base) || is<T2>(base);
+}
+
+template <class T1, class T2, class T3, class T4, class T5>
+static inline bool is(QmitkSceneTreeWidget::Base* base)
+{
+ return is<T1, T2>(base) || is<T3, T4>(base) || is<T5>(base);
+}
+
+static inline bool isBaseInteractionForceField(QmitkSceneTreeWidget::Base* base)
+{
+ sofa::core::behavior::BaseInteractionForceField* iff = dynamic_cast<sofa::core::behavior::BaseInteractionForceField*>(base);
+ return iff != NULL && iff->getMechModel1() != iff->getMechModel2();
+}
+
+static inline bool isMechanicalMapping(QmitkSceneTreeWidget::Base* base)
+{
+ sofa::core::BaseMapping* mm = dynamic_cast<sofa::core::BaseMapping*>(base);
+ return mm != NULL && mm->isMechanical();
+}
+
+static QRgb GetColor(QmitkSceneTreeWidget::Base* base)
+{
+ using namespace sofa::core;
+ using namespace sofa::core::behavior;
+ using namespace sofa::core::collision;
+ using namespace sofa::core::loader;
+ using namespace sofa::core::objectmodel;
+ using namespace sofa::core::topology;
+ using namespace sofa::core::visual;
+ using namespace sofa::simulation::Colors;
+
+ QString hexColor;
+
+ if (is<BaseNode>(base))
+ {
+ hexColor = COLOR[NODE];
+ }
+ else if (is<BaseObject>(base))
+ {
+ if (is<ContextObject>(base))
+ hexColor = COLOR[sofa::simulation::Colors::CONTEXT];
+ else if (is<BehaviorModel>(base))
+ hexColor = COLOR[BMODEL];
+ else if (is<CollisionModel>(base))
+ hexColor = COLOR[CMODEL];
+ else if (is<BaseMechanicalState>(base))
+ hexColor = COLOR[MMODEL];
+ else if (is<BaseProjectiveConstraintSet>(base))
+ hexColor = COLOR[PROJECTIVECONSTRAINTSET];
+ else if (is<BaseConstraintSet>(base))
+ hexColor = COLOR[CONSTRAINTSET];
+ else if (is<BaseMass>(base))
+ hexColor = COLOR[MASS];
+ else if (isBaseInteractionForceField(base))
+ hexColor = COLOR[IFFIELD];
+ else if (is<BaseForceField>(base))
+ hexColor = COLOR[FFIELD];
+ else if (is<BaseAnimationLoop, OdeSolver>(base))
+ hexColor = COLOR[SOLVER];
+ else if (is<Pipeline, Intersection, Detection, ContactManager, CollisionGroupManager>(base))
+ hexColor = COLOR[COLLISION];
+ else if (isMechanicalMapping(base))
+ hexColor = COLOR[MMAPPING];
+ else if (is<BaseMapping>(base))
+ hexColor = COLOR[MAPPING];
+ else if (is<Topology, BaseTopologyObject>(base))
+ hexColor = COLOR[TOPOLOGY];
+ else if (is<BaseLoader>(base))
+ hexColor = COLOR[LOADER];
+ else if (is<ConfigurationSetting>(base))
+ hexColor = COLOR[CONFIGURATIONSETTING];
+ else if (is<VisualModel>(base))
+ hexColor = COLOR[VMODEL];
+ else
+ hexColor = COLOR[OBJECT];
+ }
+ else
+ {
+ hexColor = "#000";
+ }
+
+ QColor color;
+ color.setNamedColor(hexColor);
+
+ return color.rgb();
+}
+
+static QPixmap ReplaceColor(const QPixmap& pixmap, QRgb from, QRgb to)
+{
+ QImage image = pixmap.toImage();
+
+ const int width = image.width();
+ const int height = image.height();
+ int x, y;
+
+ for (y = 0; y < height; ++y)
+ {
+ for (x = 0; x < width; ++x)
+ {
+ if (image.pixel(x, y) == from)
+ image.setPixel(x, y, to);
+ }
+ }
+
+ return QPixmap::fromImage(image);
+}
+
+static inline QIcon CreateObjectIcon(QmitkSceneTreeWidget::Base* base)
+{
+ return QIcon(ReplaceColor(QPixmap(":/Simulation/Object"), 0xff00ff00, GetColor(base)));
+}
+
+static inline QIcon CreateNodeIcon(QmitkSceneTreeWidget::BaseNode* node)
+{
+ return QIcon(ReplaceColor(QPixmap(":/Simulation/Node"), 0xff00ff00, GetColor(node)));
+}
+
+static inline QIcon CreateSlaveIcon(QmitkSceneTreeWidget::Base* base)
+{
+ return QIcon(ReplaceColor(QPixmap(":/Simulation/Slave"), 0xff00ff00, GetColor(base)));
+}
+
+static inline QString GetName(QmitkSceneTreeWidget::Base* base)
+{
+ return QString::fromStdString(base->getName());
+}
+
+static inline QString GetClassName(QmitkSceneTreeWidget::Base* base)
+{
+ return QString::fromStdString(base->getClassName());
+}
+
+QmitkSceneTreeWidget::QmitkSceneTreeWidget(QWidget* parent)
+ : QTreeWidget(parent)
+{
+}
+
+QmitkSceneTreeWidget::~QmitkSceneTreeWidget()
+{
+}
+
+void QmitkSceneTreeWidget::clear()
+{
+ QTreeWidgetItem* rootItem = this->topLevelItem(0);
+
+ if (rootItem != NULL)
+ this->removeChild(NULL, as<Node>(m_ItemBaseMap[rootItem]));
+
+ this->ClearMaps();
+
+ QTreeWidget::clear();
+}
+
+void QmitkSceneTreeWidget::addChild(Node* parent, Node* child)
+{
+ assert(child != NULL && "Child node is NULL!");
+ assert(!m_BaseItemMap.contains(child) && "TODO: Support nodes with multiple parents!");
+
+ QTreeWidgetItem* item;
+
+ if (parent == NULL)
+ {
+ item = new QTreeWidgetItem(QStringList() << GetName(child));
+ this->addTopLevelItem(item);
+ }
+ else
+ {
+ assert(m_BaseItemMap.contains(parent) && "Unknown parent node!");
+ item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(child));
+ }
+
+ item->setIcon(0, CreateNodeIcon(child));
+ this->InsertIntoMaps(child, item);
+
+ MutationListener::addChild(parent, child);
+}
+
+void QmitkSceneTreeWidget::removeChild(Node* parent, Node* child)
+{
+ assert(child != NULL && "Child node is NULL!");
+ assert(m_BaseItemMap.contains(child) && "Child node has already been removed!");
+
+ MutationListener::removeChild(parent, child);
+
+ if (parent == NULL)
+ {
+ delete m_BaseItemMap[child];
+ }
+ else
+ {
+ assert(m_BaseItemMap.contains(parent) && "Unknown parent node!");
+ m_BaseItemMap[parent]->removeChild(m_BaseItemMap[child]);
+ }
+
+ this->RemoveFromMaps(child);
+}
+
+void QmitkSceneTreeWidget::moveChild(Node* previous, Node* parent, Node* child)
+{
+ if (previous == NULL)
+ {
+ this->addChild(parent, child);
+ }
+ else if (parent == NULL)
+ {
+ this->removeChild(previous, child);
+ }
+ else
+ {
+ assert(child != NULL && "Child node is NULL!");
+ assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!");
+ assert(m_BaseItemMap.contains(parent) && "Unknown parent node!");
+ assert(m_BaseItemMap.contains(child) && "Unknown child node!");
+
+ QTreeWidgetItem* previousItem = m_BaseItemMap[previous];
+ m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[child])));
+ }
+}
+
+void QmitkSceneTreeWidget::addObject(Node* parent, BaseObject* object)
+{
+ assert(parent != NULL && "Parent node is NULL!");
+ assert(object != NULL && "Object is NULL!");
+ assert(m_BaseItemMap.contains(parent) && "Unknown parent node!");
+ // assert(!m_BaseItemMap.contains(object) && "Object has already been added!");
+
+ if (!m_BaseItemMap.contains(object))
+ {
+ QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(object));
+ item->setToolTip(0, GetClassName(object));
+ item->setIcon(0, CreateObjectIcon(object));
+ this->InsertIntoMaps(object, item);
+ }
+
+ MutationListener::addObject(parent, object);
+}
+
+void QmitkSceneTreeWidget::removeObject(Node* parent, BaseObject* object)
+{
+ assert(parent != NULL && "Parent node is NULL!");
+ assert(object != NULL && "Object is NULL!");
+ assert(m_BaseItemMap.contains(parent) && "Unknown parent node!");
+ assert(m_BaseItemMap.contains(object) && "Object has already been removed!");
+
+ MutationListener::removeObject(parent, object);
+
+ m_BaseItemMap[parent]->removeChild(m_BaseItemMap[object]);
+ this->RemoveFromMaps(object);
+}
+
+void QmitkSceneTreeWidget::moveObject(Node* previous, Node* parent, BaseObject* object)
+{
+ if (previous == NULL)
+ {
+ this->addObject(parent, object);
+ }
+ else if (parent == NULL)
+ {
+ this->removeObject(previous, object);
+ }
+ else
+ {
+ assert(object != NULL && "Object is NULL!");
+ assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!");
+ assert(m_BaseItemMap.contains(parent) && "Unknown parent node!");
+ assert(m_BaseItemMap.contains(object) && "Unknown object!");
+
+ QTreeWidgetItem* previousItem = m_BaseItemMap[previous];
+ m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[object])));
+ }
+}
+
+void QmitkSceneTreeWidget::addSlave(BaseObject* master, BaseObject* slave)
+{
+ assert(master != NULL && "Master object is NULL!");
+ assert(slave != NULL && "Slave object is NULL!");
+ assert(m_BaseItemMap.contains(master) && "Unknown master object!");
+ assert(!m_BaseItemMap.contains(slave) && "Slave object has already been added!");
+
+ QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[master], QStringList() << GetName(slave));
+ item->setToolTip(0, GetClassName(slave));
+ item->setIcon(0, CreateSlaveIcon(slave));
+ this->InsertIntoMaps(slave, item);
+
+ MutationListener::addSlave(master, slave);
+}
+
+void QmitkSceneTreeWidget::removeSlave(BaseObject* master, BaseObject* slave)
+{
+ assert(master != NULL && "Master object is NULL!");
+ assert(slave != NULL && "Slave object is NULL!");
+ assert(m_BaseItemMap.contains(master) && "Unknown master object!");
+ assert(m_BaseItemMap.contains(slave) && "Slave object has already been removed!");
+
+ MutationListener::removeSlave(master, slave);
+
+ m_BaseItemMap[master]->removeChild(m_BaseItemMap[slave]);
+ this->RemoveFromMaps(slave);
+}
+
+void QmitkSceneTreeWidget::moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave)
+{
+ if (previousMaster == NULL)
+ {
+ this->addSlave(master, slave);
+ }
+ else if (master == NULL)
+ {
+ this->removeSlave(previousMaster, slave);
+ }
+ else
+ {
+ assert(slave != NULL && "Slave object is NULL!");
+ assert(m_BaseItemMap.contains(previousMaster) && "Unknown previous master object!");
+ assert(m_BaseItemMap.contains(master) && "Unknown master object!");
+ assert(m_BaseItemMap.contains(slave) && "Unknown slave object!");
+
+ QTreeWidgetItem* previousMasterItem = m_BaseItemMap[previousMaster];
+ m_BaseItemMap[master]->addChild(previousMasterItem->takeChild(previousMasterItem->indexOfChild(m_BaseItemMap[slave])));
+ }
+}
+
+QmitkSceneTreeWidget::Base* QmitkSceneTreeWidget::GetBaseFromItem(QTreeWidgetItem* item) const
+{
+ return m_ItemBaseMap.contains(item)
+ ? m_ItemBaseMap[item]
+ : NULL;
+}
+
+void QmitkSceneTreeWidget::ClearMaps()
+{
+ m_BaseItemMap.clear();
+ m_ItemBaseMap.clear();
+}
+
+void QmitkSceneTreeWidget::InsertIntoMaps(Base* base, QTreeWidgetItem* item)
+{
+ m_BaseItemMap.insert(base, item);
+ m_ItemBaseMap.insert(item, base);
+}
+
+void QmitkSceneTreeWidget::RemoveFromMaps(Base* base)
+{
+ m_ItemBaseMap.remove(m_BaseItemMap[base]);
+ m_BaseItemMap.remove(base);
+}
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h
new file mode 100644
index 0000000000..ae104ced87
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h
@@ -0,0 +1,82 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef QmitkSceneTreeWidget_h
+#define QmitkSceneTreeWidget_h
+
+#include <QMap>
+#include <QTreeWidget>
+#include <sofa/simulation/common/MutationListener.h>
+
+namespace sofa
+{
+ namespace core
+ {
+ namespace objectmodel
+ {
+ class Base;
+ class BaseNode;
+ class BaseObject;
+ }
+ }
+
+ namespace simulation
+ {
+ class Node;
+ }
+}
+
+class QmitkSceneTreeWidget : public QTreeWidget, public sofa::simulation::MutationListener
+{
+ Q_OBJECT
+
+public:
+ typedef sofa::core::objectmodel::Base Base;
+ typedef sofa::core::objectmodel::BaseNode BaseNode;
+ typedef sofa::core::objectmodel::BaseObject BaseObject;
+ typedef sofa::simulation::Node Node;
+
+ explicit QmitkSceneTreeWidget(QWidget* parent = NULL);
+ ~QmitkSceneTreeWidget();
+
+ Base* GetBaseFromItem(QTreeWidgetItem* item) const;
+
+ // QTreeWidget, QTreeView, and QAbstractItemView Interfaces /////////////////
+ void clear();
+ /////////////////////////////////////////////////////////////////////////////
+
+ // MutationListener Interface ///////////////////////////////////////////////
+ void addChild(Node* parent, Node* child);
+ void removeChild(Node* parent, Node* child);
+ void moveChild(Node* previous, Node* parent, Node* child);
+ void addObject(Node* parent, BaseObject* object);
+ void removeObject(Node* parent, BaseObject* object);
+ void moveObject(Node* previous, Node* parent, BaseObject* object);
+ void addSlave(BaseObject* master, BaseObject* slave);
+ void removeSlave(BaseObject* master, BaseObject* slave);
+ void moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave);
+ /////////////////////////////////////////////////////////////////////////////
+
+private:
+ void ClearMaps();
+ void InsertIntoMaps(Base* base, QTreeWidgetItem* item);
+ void RemoveFromMaps(Base* base);
+
+ QMap<Base*, QTreeWidgetItem*> m_BaseItemMap;
+ QMap<QTreeWidgetItem*, Base*> m_ItemBaseMap;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp
index ba278290f9..07b79e9e8b 100644
--- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp
@@ -1,234 +1,301 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "org_mitk_gui_qt_simulation_Activator.h"
+#include "QmitkBaseItemDelegate.h"
+#include "QmitkNoEditItemDelegate.h"
#include "QmitkSimulationView.h"
-#include <mitkExportMitkVisitor.h>
-#include <mitkIRenderingManager.h>
#include <mitkISimulationService.h>
#include <mitkNodePredicateDataType.h>
+#include <mitkScheduler.h>
#include <mitkSimulation.h>
+#include <usModuleRegistry.h>
template <class T>
static T* GetService()
{
ctkPluginContext* context = mitk::org_mitk_gui_qt_simulation_Activator::GetContext();
if (context == NULL)
return NULL;
ctkServiceReference serviceReference = context->getServiceReference<T>();
return serviceReference
? context->getService<T>(serviceReference)
: NULL;
}
+static mitk::SimulationInteractor::Pointer CreateSimulationInteractor()
+{
+ const us::Module* simulationModule = us::ModuleRegistry::GetModule("MitkSimulation");
+
+ mitk::SimulationInteractor::Pointer interactor = mitk::SimulationInteractor::New();
+ interactor->LoadStateMachine("Simulation.xml", simulationModule);
+ interactor->SetEventConfig("SimulationConfig.xml", simulationModule);
+
+ return interactor;
+}
+
QmitkSimulationView::QmitkSimulationView()
: m_SimulationService(GetService<mitk::ISimulationService>()),
- m_SelectionWasRemovedFromDataStorage(false),
+ m_Interactor(CreateSimulationInteractor()),
m_Timer(this)
{
this->GetDataStorage()->RemoveNodeEvent.AddListener(
mitk::MessageDelegate1<QmitkSimulationView, const mitk::DataNode*>(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage));
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
}
QmitkSimulationView::~QmitkSimulationView()
{
this->GetDataStorage()->RemoveNodeEvent.RemoveListener(
mitk::MessageDelegate1<QmitkSimulationView, const mitk::DataNode*>(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage));
}
void QmitkSimulationView::CreateQtPartControl(QWidget* parent)
{
m_Controls.setupUi(parent);
- m_Controls.sceneComboBox->SetDataStorage(this->GetDataStorage());
- m_Controls.sceneComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation"));
-
- m_Controls.stepsRecordedLabel->hide();
+ m_Controls.simulationComboBox->SetDataStorage(this->GetDataStorage());
+ m_Controls.simulationComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation"));
- connect(m_Controls.sceneComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSceneChanged(const mitk::DataNode*)));
+ connect(m_Controls.simulationComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSimulationChanged(const mitk::DataNode*)));
connect(m_Controls.animateButton, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool)));
connect(m_Controls.stepButton, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked()));
connect(m_Controls.resetButton, SIGNAL(clicked()), this, SLOT(OnResetButtonClicked()));
connect(m_Controls.dtSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDtChanged(double)));
- connect(m_Controls.recordButton, SIGNAL(toggled(bool)), this, SLOT(OnRecordButtonToggled(bool)));
- connect(m_Controls.snapshotButton, SIGNAL(clicked()), this, SLOT(OnSnapshotButtonClicked()));
+ connect(m_Controls.sceneTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(OnSelectedBaseChanged()));
+ connect(m_Controls.pushButton, SIGNAL(clicked()), this, SLOT(OnButtonClicked()));
- if (m_Controls.sceneComboBox->GetSelectedNode().IsNotNull())
- this->OnSelectedSceneChanged(m_Controls.sceneComboBox->GetSelectedNode());
+ if (m_Controls.simulationComboBox->GetSelectedNode().IsNotNull())
+ {
+ this->OnSelectedSimulationChanged(m_Controls.simulationComboBox->GetSelectedNode());
+ }
+ else
+ {
+ this->SetSimulationControlsEnabled(false);
+ }
}
void QmitkSimulationView::OnAnimateButtonToggled(bool toggled)
{
- if (this->SetSelectionAsCurrentSimulation())
+ mitk::Scheduler* scheduler = m_SimulationService->GetScheduler();
+
+ if (toggled)
{
mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
- simulation->SetAnimationFlag(toggled);
- if (toggled)
- {
- m_Controls.stepButton->setEnabled(false);
- m_NextRenderWindowUpdate = QTime::currentTime().addMSecs(MsPerFrame);
- m_Timer.start(0);
- }
+ simulation->SetAnimationFlag(true);
+ scheduler->AddProcess(simulation);
+
+ m_Controls.stepButton->setEnabled(false);
}
+ else if (m_Selection.IsNotNull())
+ {
+ mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
+
+ scheduler->RemoveProcess(simulation);
+ simulation->SetAnimationFlag(false);
- if (!toggled)
+ m_Controls.stepButton->setEnabled(true);
+ }
+
+ if (!scheduler->IsEmpty())
+ {
+ if (!m_Timer.isActive())
+ m_Timer.start(0);
+ }
+ else
{
m_Timer.stop();
- m_Controls.stepButton->setEnabled(true);
}
}
void QmitkSimulationView::OnDtChanged(double dt)
{
- if (!this->SetSelectionAsCurrentSimulation())
+ if (m_Selection.IsNull())
return;
mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
simulation->SetDt(std::max(0.0, dt));
}
void QmitkSimulationView::OnNodeRemovedFromDataStorage(const mitk::DataNode* node)
{
- if (m_Selection.IsNotNull() && m_Selection.GetPointer() == node)
- m_SelectionWasRemovedFromDataStorage = true;
-}
+ mitk::Simulation::Pointer simulation = dynamic_cast<mitk::Simulation*>(node->GetData());
-void QmitkSimulationView::OnRecordButtonToggled(bool toggled)
-{
- if (!toggled)
+ if (simulation.IsNotNull())
{
+ mitk::Scheduler* scheduler = m_SimulationService->GetScheduler();
- m_Controls.stepsRecordedLabel->hide();
- m_Controls.stepsRecordedLabel->setText("0 steps recorded");
- }
- else
- {
- m_Controls.stepsRecordedLabel->show();
+ scheduler->RemoveProcess(simulation);
+
+ if (scheduler->IsEmpty() && m_Timer.isActive())
+ m_Timer.stop();
+
+ if (m_SimulationService->GetActiveSimulation() == simulation)
+ m_SimulationService->SetActiveSimulation(NULL);
}
}
void QmitkSimulationView::OnResetButtonClicked()
{
- if (!this->SetSelectionAsCurrentSimulation())
- return;
-
mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
+ m_SimulationService->SetActiveSimulation(simulation);
m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt());
simulation->Reset();
this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS);
}
-void QmitkSimulationView::OnSelectedSceneChanged(const mitk::DataNode* node)
+void QmitkSimulationView::OnSelectedSimulationChanged(const mitk::DataNode* node)
{
- if (m_Controls.animateButton->isChecked())
- m_Controls.animateButton->setChecked(false);
-
- if (m_SelectionWasRemovedFromDataStorage)
- {
- m_SelectionWasRemovedFromDataStorage = false;
- m_Selection = NULL;
- }
-
if (node != NULL)
{
- m_Selection = m_Controls.sceneComboBox->GetSelectedNode();
+ m_Selection = m_Controls.simulationComboBox->GetSelectedNode();
mitk::Simulation* simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
- m_SimulationService->SetSimulation(simulation);
-
- m_Controls.sceneGroupBox->setEnabled(true);
- m_Controls.snapshotButton->setEnabled(true);
+ m_Controls.animateButton->setChecked(simulation->GetAnimationFlag());
m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt());
+ this->SetSimulationControlsEnabled(true);
}
else
{
m_Selection = NULL;
- m_SimulationService->SetSimulation(NULL);
-
- m_Controls.sceneGroupBox->setEnabled(false);
- m_Controls.snapshotButton->setEnabled(false);
+ this->SetSimulationControlsEnabled(false);
+ m_Controls.animateButton->setChecked(false);
m_Controls.dtSpinBox->setValue(0.0);
}
+
+ m_Interactor->SetDataNode(m_Selection);
+
+ this->ResetSceneTreeWidget();
}
-void QmitkSimulationView::OnSnapshotButtonClicked()
+void QmitkSimulationView::OnSelectedBaseChanged()
{
- if (!this->SetSelectionAsCurrentSimulation())
- return;
+ QList<QTreeWidgetItem*> selectedBaseItems = m_Controls.sceneTreeWidget->selectedItems();
- mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
- mitk::ExportMitkVisitor exportVisitor;
-
- simulation->GetRootNode()->executeVisitor(&exportVisitor);
+ m_Controls.baseTreeWidget->OnSelectedBaseChanged(!selectedBaseItems.isEmpty()
+ ? m_Controls.sceneTreeWidget->GetBaseFromItem(selectedBaseItems[0])
+ : NULL);
}
void QmitkSimulationView::OnStep(bool renderWindowUpdate)
{
- if (!this->SetSelectionAsCurrentSimulation())
- return;
+ mitk::Scheduler* scheduler = m_SimulationService->GetScheduler();
+ mitk::Simulation::Pointer simulation = dynamic_cast<mitk::Simulation*>(scheduler->GetNextProcess());
- mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
+ m_SimulationService->SetActiveSimulation(simulation);
- simulation->Animate();
+ if (simulation.IsNotNull())
+ simulation->Animate();
if (renderWindowUpdate)
this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS);
}
void QmitkSimulationView::OnStepButtonClicked()
{
- this->OnStep(true);
-}
+ if (m_Selection.IsNull())
+ return;
-void QmitkSimulationView::SetFocus()
-{
- m_Controls.animateButton->setFocus();
-}
+ mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
-bool QmitkSimulationView::SetSelectionAsCurrentSimulation() const
-{
- if (m_Selection.IsNotNull())
- {
- m_SimulationService->SetSimulation(static_cast<mitk::Simulation*>(m_Selection->GetData()));
- return true;
- }
+ m_SimulationService->SetActiveSimulation(simulation);
+ simulation->Animate();
- return false;
+ this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS);
}
void QmitkSimulationView::OnTimeout()
{
QTime currentTime = QTime::currentTime();
if (currentTime.msecsTo(m_NextRenderWindowUpdate) > 0)
{
this->OnStep(false);
}
else
{
- m_NextRenderWindowUpdate = currentTime.addMSecs(MsPerFrame);
+ m_NextRenderWindowUpdate = currentTime.addMSecs(MSecsPerFrame);
this->OnStep(true);
}
}
+
+void QmitkSimulationView::ResetSceneTreeWidget()
+{
+ m_Controls.sceneTreeWidget->clear();
+
+ if (m_Selection.IsNull())
+ return;
+
+ mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(m_Selection->GetData());
+
+ m_Controls.sceneTreeWidget->addChild(NULL, simulation->GetRootNode().get());
+ m_Controls.sceneTreeWidget->expandItem(m_Controls.sceneTreeWidget->topLevelItem(0));
+}
+
+void QmitkSimulationView::SetSimulationControlsEnabled(bool enabled)
+{
+ m_Controls.animateButton->setEnabled(enabled);
+ m_Controls.stepButton->setEnabled(enabled);
+ m_Controls.resetButton->setEnabled(enabled);
+ m_Controls.dtLabel->setEnabled(enabled);
+ m_Controls.dtSpinBox->setEnabled(enabled);
+}
+
+void QmitkSimulationView::SetFocus()
+{
+ m_Controls.animateButton->setFocus();
+}
+
+void QmitkSimulationView::OnButtonClicked()
+{
+}
+
+/*#include <QmitkRenderWindow.h>
+#include <vtkImageShiftScale.h>
+#include <vtkPNGWriter.h>
+#include <vtkSmartPointer.h>
+#include <vtkWindowToImageFilter.h>
+
+void QmitkSimulationView::OnButtonClicked()
+{
+ vtkRenderWindow* renderWindow = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetVtkRenderWindow();
+
+ vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
+
+ windowToImageFilter->SetInput(renderWindow);
+ windowToImageFilter->SetInputBufferTypeToZBuffer();
+
+ vtkSmartPointer<vtkImageShiftScale> imageShiftScaleFilter = vtkSmartPointer<vtkImageShiftScale>::New();
+
+ imageShiftScaleFilter->SetInputConnection(windowToImageFilter->GetOutputPort());
+ imageShiftScaleFilter->SetOutputScalarTypeToUnsignedChar();
+ imageShiftScaleFilter->SetShift(0);
+ imageShiftScaleFilter->SetScale(-255);
+
+ vtkSmartPointer<vtkPNGWriter> pngWriter = vtkSmartPointer<vtkPNGWriter>::New();
+
+ pngWriter->SetInputConnection(imageShiftScaleFilter->GetOutputPort());
+ pngWriter->SetFileName("C:\\Users\\Stefan\\Desktop\\DepthBuffer.png");
+ pngWriter->Write();
+}*/
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h
index 8d6fe155b4..3eb8d7c803 100644
--- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h
@@ -1,67 +1,68 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QmitkSimulationView_h
#define QmitkSimulationView_h
-#include <mitkSurface.h>
+#include <mitkSimulationInteractor.h>
#include <QmitkAbstractView.h>
#include <QTime>
#include <QTimer>
#include <ui_QmitkSimulationViewControls.h>
namespace mitk
{
class ISimulationService;
}
class QmitkSimulationView : public QmitkAbstractView
{
Q_OBJECT
public:
QmitkSimulationView();
~QmitkSimulationView();
void CreateQtPartControl(QWidget* parent);
void SetFocus();
private slots:
void OnAnimateButtonToggled(bool toggled);
void OnDtChanged(double dt);
- void OnRecordButtonToggled(bool toggled);
void OnResetButtonClicked();
- void OnSelectedSceneChanged(const mitk::DataNode* node);
- void OnSnapshotButtonClicked();
+ void OnSelectedSimulationChanged(const mitk::DataNode* node);
+ void OnSelectedBaseChanged();
void OnStep(bool renderWindowUpdate);
void OnStepButtonClicked();
void OnTimeout();
+ void OnButtonClicked();
private:
void OnNodeRemovedFromDataStorage(const mitk::DataNode* node);
- bool SetSelectionAsCurrentSimulation() const;
+ void ResetSceneTreeWidget();
+ void SetSimulationControlsEnabled(bool enabled);
- static const int MsPerFrame = 17;
+ static const int MSecsPerFrame = 17;
Ui::QmitkSimulationViewControls m_Controls;
mitk::ISimulationService* m_SimulationService;
- bool m_SelectionWasRemovedFromDataStorage;
mitk::DataNode::Pointer m_Selection;
+ mitk::SimulationInteractor::Pointer m_Interactor;
QTimer m_Timer;
QTime m_NextRenderWindowUpdate;
};
#endif
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui
index 9c9e0516ee..6f7a23289c 100644
--- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui
@@ -1,179 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkSimulationViewControls</class>
<widget class="QWidget" name="QmitkSimulationViewControls">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>301</width>
- <height>548</height>
+ <width>248</width>
+ <height>751</height>
</rect>
</property>
<property name="windowTitle">
<string>Simulation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QGroupBox" name="sceneGroupBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="title">
- <string>Scene</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0" colspan="3">
- <widget class="QmitkDataStorageComboBox" name="sceneComboBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="animateButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Animate</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" colspan="2">
- <widget class="QPushButton" name="stepButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Step</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QPushButton" name="resetButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="dtLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>dt</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QDoubleSpinBox" name="dtSpinBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="suffix">
- <string> s</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="singleStep">
- <double>0.010000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="3">
+ <widget class="QmitkDataStorageComboBox" name="simulationComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="animateButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Animate</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QPushButton" name="stepButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Step</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="resetButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="dtLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>dt</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QDoubleSpinBox" name="dtSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> s</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
- <widget class="QGroupBox" name="surfaceRecordingGroupBox">
- <property name="title">
- <string>Surface Recording</string>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QPushButton" name="recordButton">
- <property name="text">
- <string>Record</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="snapshotButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Take Snapshot</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <widget class="QLabel" name="stepsRecordedLabel">
- <property name="text">
- <string>0 step(s) recorded</string>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QmitkSceneTreeWidget" name="sceneTreeWidget">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="columnCount">
+ <number>1</number>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QmitkBaseTreeWidget" name="baseTreeWidget">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>120</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Property</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
+ </widget>
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string/>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>421</height>
- </size>
- </property>
- </spacer>
+ </widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QmitkDataStorageComboBox</class>
<extends>QComboBox</extends>
- <header>QmitkDataStorageComboBox.h</header>
+ <header location="global">QmitkDataStorageComboBox.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QmitkSceneTreeWidget</class>
+ <extends>QTreeWidget</extends>
+ <header location="global">internal/QmitkSceneTreeWidget.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QmitkBaseTreeWidget</class>
+ <extends>QTreeWidget</extends>
+ <header location="global">internal/QmitkBaseTreeWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp
index e9c3299dba..4aa42c0c08 100644
--- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp
+++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp
@@ -1,528 +1,527 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <mitkIRenderingManager.h>
#include <mitkIRenderWindowPart.h>
#include <mitkILinkedRenderWindowPart.h>
// Qmitk
#include "QmitkToFUtilView.h"
#include <QmitkStdMultiWidget.h>
-#include <QmitkTextOverlay.h>
// Qt
#include <QMessageBox>
#include <QString>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qcombobox.h>
// MITK
#include <mitkBaseRenderer.h>
#include <mitkGlobalInteraction.h>
#include <mitkToFDistanceImageToPointSetFilter.h>
#include <mitkTransferFunction.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkToFDeviceFactoryManager.h>
#include <mitkToFCameraDevice.h>
#include <mitkCameraIntrinsicsProperty.h>
#include <mitkSmartPointerProperty.h>
#include <mitkRenderingModeProperty.h>
#include <mitkVtkScalarModeProperty.h>
// VTK
#include <vtkCamera.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
// ITK
#include <itkCommand.h>
#include <itksys/SystemTools.hxx>
const std::string QmitkToFUtilView::VIEW_ID = "org.mitk.views.tofutil";
//Constructor
QmitkToFUtilView::QmitkToFUtilView()
: QmitkAbstractView()
, m_Controls(NULL), m_MultiWidget( NULL )
, m_MitkDistanceImage(NULL), m_MitkAmplitudeImage(NULL), m_MitkIntensityImage(NULL), m_Surface(NULL)
, m_DistanceImageNode(NULL), m_AmplitudeImageNode(NULL), m_IntensityImageNode(NULL), m_RGBImageNode(NULL), m_SurfaceNode(NULL)
, m_ToFImageRecorder(NULL), m_ToFImageGrabber(NULL), m_ToFDistanceImageToSurfaceFilter(NULL), m_ToFCompositeFilter(NULL)
, m_2DDisplayCount(0)
, m_RealTimeClock(NULL)
, m_StepsForFramerate(100)
, m_2DTimeBefore(0.0)
, m_2DTimeAfter(0.0)
, m_CameraIntrinsics(NULL)
{
this->m_Frametimer = new QTimer(this);
this->m_ToFDistanceImageToSurfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New();
this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New();
this->m_ToFImageRecorder = mitk::ToFImageRecorder::New();
}
//Destructor, specifically calling OnToFCameraStopped() and OnToFCammeraDiconnected()
QmitkToFUtilView::~QmitkToFUtilView()
{
OnToFCameraStopped();
OnToFCameraDisconnected();
}
//Createing the PartControl Signal-Slot principal
void QmitkToFUtilView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkToFUtilViewControls;
m_Controls->setupUi( parent );
//Looking for Input and Defining reaction
connect(m_Frametimer, SIGNAL(timeout()), this, SLOT(OnUpdateCamera()));
connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(KinectAcquisitionModeChanged()), this, SLOT(OnKinectAcquisitionModeChanged()) ); // Todo in Widget2
connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraConnected()), this, SLOT(OnToFCameraConnected()) );
connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraDisconnected()), this, SLOT(OnToFCameraDisconnected()) );
connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(ToFCameraStarted()), this, SLOT(OnToFCameraStarted()) );
connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(ToFCameraStopped()), this, SLOT(OnToFCameraStopped()) );
connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(RecordingStarted()), this, SLOT(OnToFCameraStopped()) );
connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(RecordingStopped()), this, SLOT(OnToFCameraStarted()) );
}
}
//SetFocus-Method -> actually seting Focus to the Recorder
void QmitkToFUtilView::SetFocus()
{
m_Controls->m_ToFRecorderWidget->setFocus();
}
//Activated-Method->Generating RenderWindow
void QmitkToFUtilView::Activated()
{
//get the current RenderWindowPart or open a new one if there is none
if(this->GetRenderWindowPart(OPEN))
{
mitk::ILinkedRenderWindowPart* linkedRenderWindowPart = dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart());
if(linkedRenderWindowPart == 0)
{
MITK_ERROR << "No linked StdMultiWidget avaiable!!!";
}
else
{
linkedRenderWindowPart->EnableSlicingPlanes(false);
}
GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial);
GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SliceLockedOn();
GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial);
GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SliceLockedOn();
GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial);
GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SliceLockedOn();
this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews();
this->UseToFVisibilitySettings(true);
if (this->m_ToFCompositeFilter)
{
m_Controls->m_ToFCompositeFilterWidget->SetToFCompositeFilter(this->m_ToFCompositeFilter);
}
if (this->GetDataStorage())
{
m_Controls->m_ToFCompositeFilterWidget->SetDataStorage(this->GetDataStorage());
}
if (this->m_ToFImageGrabber.IsNull())
{
m_Controls->m_ToFRecorderWidget->setEnabled(false);
m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false);
m_Controls->m_ToFCompositeFilterWidget->setEnabled(false);
m_Controls->m_ToFMeasurementWidget->setEnabled(false);
m_Controls->m_ToFSurfaceGenerationWidget->setEnabled(false);
}
}
}
//ZomnnieView-Method -> Resetting GUI to default. Why not just QmitkToFUtilView()?!
void QmitkToFUtilView::ActivatedZombieView(berry::IWorkbenchPartReference::Pointer /*zombieView*/)
{
ResetGUIToDefault();
}
void QmitkToFUtilView::Deactivated()
{
}
void QmitkToFUtilView::Visible()
{
}
//Reset of the ToFUtilView
void QmitkToFUtilView::Hidden()
{
ResetGUIToDefault();
}
void QmitkToFUtilView::OnToFCameraConnected()
{
MITK_DEBUG <<"OnToFCameraConnected";
this->m_2DDisplayCount = 0;
this->m_ToFImageGrabber = m_Controls->m_ToFConnectionWidget->GetToFImageGrabber();
// initialize surface generation
this->m_ToFDistanceImageToSurfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New();
// initialize ToFImageRecorder and ToFRecorderWidget
this->m_ToFImageRecorder = mitk::ToFImageRecorder::New();
this->m_ToFImageRecorder->SetCameraDevice(this->m_ToFImageGrabber->GetCameraDevice());
m_Controls->m_ToFRecorderWidget->SetParameter(this->m_ToFImageGrabber, this->m_ToFImageRecorder);
m_Controls->m_ToFRecorderWidget->setEnabled(true);
m_Controls->m_ToFRecorderWidget->ResetGUIToInitial();
m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false);
// initialize ToFCompositeFilterWidget
this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New();
if (this->m_ToFCompositeFilter)
{
m_Controls->m_ToFCompositeFilterWidget->SetToFCompositeFilter(this->m_ToFCompositeFilter);
}
if (this->GetDataStorage())
{
m_Controls->m_ToFCompositeFilterWidget->SetDataStorage(this->GetDataStorage());
}
if ( this->GetRenderWindowPart() )
// initialize measurement widget
m_Controls->m_ToFMeasurementWidget->InitializeWidget(this->GetRenderWindowPart()->GetQmitkRenderWindows(),this->GetDataStorage(), this->m_ToFDistanceImageToSurfaceFilter->GetCameraIntrinsics());
else
MITK_WARN << "No StdMultiWidget available!!! MeasurementWidget will not work.";
this->m_RealTimeClock = mitk::RealTimeClock::New();
this->m_2DTimeBefore = this->m_RealTimeClock->GetCurrentStamp();
this->RequestRenderWindowUpdate();
}
void QmitkToFUtilView::ResetGUIToDefault()
{
if(this->GetRenderWindowPart())
{
mitk::ILinkedRenderWindowPart* linkedRenderWindowPart = dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart());
if(linkedRenderWindowPart == 0)
{
MITK_ERROR << "No linked StdMultiWidget avaiable!!!";
}
else
{
linkedRenderWindowPart->EnableSlicingPlanes(true);
}
GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial);
GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SliceLockedOff();
GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal);
GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SliceLockedOff();
GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Frontal);
GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SliceLockedOff();
this->UseToFVisibilitySettings(false);
//global reinit
this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews();
this->RequestRenderWindowUpdate();
}
}
void QmitkToFUtilView::OnToFCameraDisconnected()
{
this->GetDataStorage()->Remove(m_DistanceImageNode);
if(m_RGBImageNode)
this->GetDataStorage()->Remove(m_RGBImageNode);
if(m_AmplitudeImageNode)
this->GetDataStorage()->Remove(m_AmplitudeImageNode);
if(m_IntensityImageNode)
this->GetDataStorage()->Remove(m_IntensityImageNode);
if(m_SurfaceNode)
this->GetDataStorage()->Remove(m_SurfaceNode);
m_Controls->m_ToFRecorderWidget->OnStop();
m_Controls->m_ToFRecorderWidget->setEnabled(false);
m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false);
m_Controls->m_ToFMeasurementWidget->setEnabled(false);
m_Controls->m_ToFSurfaceGenerationWidget->setEnabled(false);
//clean up measurement widget
m_Controls->m_ToFMeasurementWidget->CleanUpWidget();
}
void QmitkToFUtilView::OnKinectAcquisitionModeChanged()
{
if (m_ToFCompositeFilter.IsNotNull()&&m_ToFImageGrabber.IsNotNull())
{
if (m_SelectedCamera.contains("Kinect"))
{
if (m_ToFImageGrabber->GetBoolProperty("RGB"))
{
this->m_RGBImageNode = ReplaceNodeData("RGB image",this->m_ToFImageGrabber->GetOutput(3));
this->m_ToFDistanceImageToSurfaceFilter->SetInput(3,this->m_ToFImageGrabber->GetOutput(3));
}
else if (m_ToFImageGrabber->GetBoolProperty("IR"))
{
this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1);
this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage);
}
}
this->UseToFVisibilitySettings(true);
}
}
void QmitkToFUtilView::OnToFCameraStarted()
{
if (m_ToFImageGrabber.IsNotNull())
{
// initialize camera intrinsics
if (this->m_ToFImageGrabber->GetProperty("CameraIntrinsics"))
{
m_CameraIntrinsics = dynamic_cast<mitk::CameraIntrinsicsProperty*>(this->m_ToFImageGrabber->GetProperty("CameraIntrinsics"))->GetValue();
MITK_INFO << m_CameraIntrinsics->ToString();
}
else
{
m_CameraIntrinsics = NULL;
MITK_ERROR << "No camera intrinsics were found!";
}
// set camera intrinsics
if ( m_CameraIntrinsics.IsNotNull() )
{
this->m_ToFDistanceImageToSurfaceFilter->SetCameraIntrinsics(m_CameraIntrinsics);
}
// initial update of image grabber
this->m_ToFImageGrabber->Update();
bool hasRGBImage = false;
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasRGBImage",hasRGBImage);
bool hasIntensityImage = false;
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasIntensityImage",hasIntensityImage);
bool hasAmplitudeImage = false;
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasAmplitudeImage",hasAmplitudeImage);
this->m_ToFCompositeFilter->SetInput(0,this->m_ToFImageGrabber->GetOutput(0));
if(hasAmplitudeImage)
this->m_ToFCompositeFilter->SetInput(1,this->m_ToFImageGrabber->GetOutput(1));
if(hasIntensityImage)
this->m_ToFCompositeFilter->SetInput(2,this->m_ToFImageGrabber->GetOutput(2));
// initial update of composite filter
this->m_ToFCompositeFilter->Update();
this->m_MitkDistanceImage = m_ToFCompositeFilter->GetOutput();
this->m_DistanceImageNode = ReplaceNodeData("Distance image",m_MitkDistanceImage);
std::string rgbFileName;
m_ToFImageGrabber->GetCameraDevice()->GetStringProperty("RGBImageFileName",rgbFileName);
if(hasRGBImage || (rgbFileName!=""))
{
if(m_ToFImageGrabber->GetBoolProperty("IR"))
{
this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1);
}
else
{
this->m_RGBImageNode = ReplaceNodeData("RGB image",this->m_ToFImageGrabber->GetOutput(3));
}
}
else
{
this->m_RGBImageNode = NULL;
}
if(hasAmplitudeImage)
{
this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1);
this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage);
}
if(hasIntensityImage)
{
this->m_MitkIntensityImage = m_ToFCompositeFilter->GetOutput(2);
this->m_IntensityImageNode = ReplaceNodeData("Intensity image",m_MitkIntensityImage);
}
this->m_ToFDistanceImageToSurfaceFilter->SetInput(0,m_MitkDistanceImage);
this->m_ToFDistanceImageToSurfaceFilter->SetInput(1,m_MitkAmplitudeImage);
this->m_ToFDistanceImageToSurfaceFilter->SetInput(2,m_MitkIntensityImage);
this->UseToFVisibilitySettings(true);
this->m_SurfaceNode = ReplaceNodeData("Surface", NULL);
m_Controls->m_ToFCompositeFilterWidget->UpdateFilterParameter();
// initialize visualization widget
m_Controls->m_ToFVisualisationSettingsWidget->Initialize(this->m_DistanceImageNode,
this->m_AmplitudeImageNode,
this->m_IntensityImageNode,
this->m_SurfaceNode);
m_Controls->m_ToFSurfaceGenerationWidget->Initialize(m_ToFDistanceImageToSurfaceFilter,
m_ToFImageGrabber,
m_CameraIntrinsics,
m_SurfaceNode,
GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderer()->GetVtkRenderer()->GetActiveCamera());
// set distance image to measurement widget
m_Controls->m_ToFMeasurementWidget->SetDistanceImage(m_MitkDistanceImage);
this->m_Frametimer->start(0);
m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(true);
m_Controls->m_ToFCompositeFilterWidget->setEnabled(true);
m_Controls->m_ToFMeasurementWidget->setEnabled(true);
m_Controls->m_ToFSurfaceGenerationWidget->setEnabled(true);
}
}
void QmitkToFUtilView::OnToFCameraStopped()
{
m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false);
m_Controls->m_ToFCompositeFilterWidget->setEnabled(false);
this->m_Frametimer->stop();
}
void QmitkToFUtilView::OnUpdateCamera()
{
if(!m_Controls->m_ToFSurfaceGenerationWidget->UpdateSurface())
{
// update pipeline
this->m_MitkDistanceImage->Update();
}
this->RequestRenderWindowUpdate();
this->m_2DDisplayCount++;
if ((this->m_2DDisplayCount % this->m_StepsForFramerate) == 0)
{
this->m_2DTimeAfter = this->m_RealTimeClock->GetCurrentStamp() - this->m_2DTimeBefore;
MITK_INFO << " 2D-Display-framerate (fps): " << this->m_StepsForFramerate / (this->m_2DTimeAfter/1000);
this->m_2DTimeBefore = this->m_RealTimeClock->GetCurrentStamp();
}
}
void QmitkToFUtilView::OnChangeCoronalWindowOutput(int index)
{
this->OnToFCameraStopped();
if(index == 0)
{
if(this->m_IntensityImageNode.IsNotNull())
this->m_IntensityImageNode->SetVisibility(false);
if(this->m_RGBImageNode.IsNotNull())
this->m_RGBImageNode->SetVisibility(true);
}
else if(index == 1)
{
if(this->m_IntensityImageNode.IsNotNull())
this->m_IntensityImageNode->SetVisibility(true);
if(this->m_RGBImageNode.IsNotNull())
this->m_RGBImageNode->SetVisibility(false);
}
this->RequestRenderWindowUpdate();
this->OnToFCameraStarted();
}
mitk::DataNode::Pointer QmitkToFUtilView::ReplaceNodeData( std::string nodeName, mitk::BaseData* data )
{
mitk::DataNode::Pointer node = this->GetDataStorage()->GetNamedNode(nodeName);
if (node.IsNull())
{
node = mitk::DataNode::New();
node->SetData(data);
node->SetName(nodeName);
node->SetBoolProperty("binary",false);
this->GetDataStorage()->Add(node);
}
else
{
node->SetData(data);
}
return node;
}
void QmitkToFUtilView::UseToFVisibilitySettings(bool useToF)
{
//We need this property for every node.
mitk::RenderingModeProperty::Pointer renderingModePropertyForTransferFunction = mitk::RenderingModeProperty::New(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR);
// set node properties
if (m_DistanceImageNode.IsNotNull())
{
this->m_DistanceImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true ));
this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetRenderWindow() ) );
this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetRenderWindow() ) );
this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) );
this->m_DistanceImageNode->SetProperty("Image Rendering.Mode", renderingModePropertyForTransferFunction);
}
if (m_AmplitudeImageNode.IsNotNull())
{
this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetRenderWindow() ) );
this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetRenderWindow() ) );
this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) );
this->m_AmplitudeImageNode->SetProperty("Image Rendering.Mode", renderingModePropertyForTransferFunction);
}
if (m_IntensityImageNode.IsNotNull())
{
this->m_IntensityImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true ));
this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetRenderWindow() ) );
this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetRenderWindow() ) );
this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) );
this->m_IntensityImageNode->SetProperty("Image Rendering.Mode", renderingModePropertyForTransferFunction);
}
if ((m_RGBImageNode.IsNotNull()))
{
this->m_RGBImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true ));
this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetRenderWindow() ) );
this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetRenderWindow() ) );
this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) );
}
// initialize images
if (m_MitkDistanceImage.IsNotNull())
{
this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews(
this->m_MitkDistanceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS, true);
}
if(this->m_SurfaceNode.IsNotNull())
{
QHash<QString, QmitkRenderWindow*> renderWindowHashMap = this->GetRenderWindowPart()->GetQmitkRenderWindows();
QHashIterator<QString, QmitkRenderWindow*> i(renderWindowHashMap);
while (i.hasNext()){
i.next();
this->m_SurfaceNode->SetVisibility( false, mitk::BaseRenderer::GetInstance(i.value()->GetRenderWindow()) );
}
this->m_SurfaceNode->SetVisibility( true, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) );
}
//disable/enable gradient background
this->GetRenderWindowPart()->EnableDecorations(!useToF, QStringList(QString("background")));
if((this->m_RGBImageNode.IsNotNull()))
{
bool RGBImageHasDifferentResolution = false;
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("RGBImageHasDifferentResolution",RGBImageHasDifferentResolution);
if(RGBImageHasDifferentResolution)
{
//update the display geometry by using the RBG image node. Only for renderwindow coronal
mitk::RenderingManager::GetInstance()->InitializeView( GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetRenderWindow(), this->m_RGBImageNode->GetData()->GetGeometry() );
}
}
}
diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h
index 3ecc09228f..36974e181f 100644
--- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h
+++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h
@@ -1,173 +1,172 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QmitkToFUtilView_h
#define QmitkToFUtilView_h
-#include <QmitkOverlayController.h>
#include <QmitkAbstractView.h>
#include <berryIWorkbenchPartReference.h>
#include <mitkIZombieViewPart.h>
#include <ui_QmitkToFUtilViewControls.h>
class QTimer;
#include <mitkRealTimeClock.h>
#include <mitkToFImageGrabber.h>
#include <mitkOpenCVVideoSource.h>
#include <mitkSurface.h>
#include <mitkToFDistanceImageToSurfaceFilter.h>
#include <mitkToFImageRecorder.h>
#include <mitkToFCompositeFilter.h>
#include <mitkCameraIntrinsics.h>
/*!
\brief QmitkToFUtilView
Application that allows simple playing, recording, visualization, processing and measurement of Time-of-Flight (ToF) data.
Currently the following features are implemented:
<ul>
<li>Connecting and showing ToF data from various cameras (PMD CamCube 2/3, PMD CamBoard, PMD O3, MESA SwissRanger)</li>
<li>Recording and playing of ToF data</li>
<li>Color coded visualization of ToF images</li>
<li>Preprocessing of the distance data: Threshold, median, average and bilateral filtering; surface generation</li>
<li>Simple measurement and PointSet definition</li>
</ul>
\sa QmitkFunctionality
\ingroup Functionalities
*/
class QmitkToFUtilView : public QmitkAbstractView, public mitk::IZombieViewPart
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkToFUtilView();
~QmitkToFUtilView();
virtual void CreateQtPartControl(QWidget *parent);
/// \brief Called when the functionality is activated.
virtual void Activated();
/// \brief Called when the functionality is deactivated. In this case the zombie view of this functionality becomes active!
virtual void ActivatedZombieView(berry::IWorkbenchPartReference::Pointer zombieView);
virtual void Deactivated();
virtual void Visible();
virtual void Hidden();
void SetFocus();
protected slots:
/*!
\brief Slot triggered from the timer to update the images and visualization
*/
void OnUpdateCamera();
/*!
\brief Slot called when the "Connect" button of the ConnectionWidget is pressed
*/
void OnToFCameraConnected();
/*!
\brief Slot called when the "Disconnect" button of the ConnectionWidget is pressed
*/
void OnToFCameraDisconnected();
/*!
\brief Slot called when the "Start" button of the RecorderWidget is pressed
*/
void OnToFCameraStarted();
/*!
\brief Slot called when the "Stop" button of the RecorderWidget is pressed
*/
void OnToFCameraStopped();
/*!
\brief Slot invoked when user alters the coronal window input from RGB to Intensity or vice versa.
*/
void OnChangeCoronalWindowOutput(int index);
/*!
\brief Slot invoked when acquisition mode of Kinect is changed
*/
void OnKinectAcquisitionModeChanged();
protected:
/*!
\brief initialize the visibility settings of ToF data (images + surface)
\param useToF true: distance image: widget1, amplitude image: widget 2, intensity image: widget 3; false: standard
*/
void UseToFVisibilitySettings(bool useToF);
Ui::QmitkToFUtilViewControls* m_Controls;
QmitkStdMultiWidget* m_MultiWidget;
QTimer* m_Frametimer; ///< Timer used to continuously update the images
QString m_SelectedCamera; ///< String holding the selected camera
mitk::Image::Pointer m_MitkDistanceImage; ///< member holding a pointer to the distance image of the selected camera
mitk::Image::Pointer m_MitkAmplitudeImage; ///< member holding a pointer to the amplitude image of the selected camera
mitk::Image::Pointer m_MitkIntensityImage; ///< member holding a pointer to the intensity image of the selected camera
mitk::Surface::Pointer m_Surface; ///< member holding a pointer to the surface generated from the distance image of the selected camera
mitk::DataNode::Pointer m_DistanceImageNode; ///< DataNode holding the distance image of the selected camera
mitk::DataNode::Pointer m_AmplitudeImageNode; ///< DataNode holding the amplitude image of the selected camera
mitk::DataNode::Pointer m_IntensityImageNode; ///< DataNode holding the intensity image of the selected camera
mitk::DataNode::Pointer m_RGBImageNode; ///< DataNode holding the rgb image of the selected camera
mitk::DataNode::Pointer m_SurfaceNode; ///< DataNode holding the surface generated from the distanc image of the selected camera
// ToF processing and recording filter
mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; ///< ToF image recorder used for lossless recording of ToF image data
mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< Source of a ToF image processing pipeline. Provides pointers to distance, amplitude and intensity image
mitk::ToFDistanceImageToSurfaceFilter::Pointer m_ToFDistanceImageToSurfaceFilter; ///< Filter for calculating a surface representation from a given distance image
mitk::ToFCompositeFilter::Pointer m_ToFCompositeFilter; ///< Filter combining several processing steps (thresholding, Median filtering, Bilateral filtering)
int m_2DDisplayCount; ///< member used to determine whether frame rate output should be shown
// members for calculating the frame rate
mitk::RealTimeClock::Pointer m_RealTimeClock; ///< real time clock used to calculate the display framerate
int m_StepsForFramerate; ///< number of steps used for calculating the display framerate
double m_2DTimeBefore; ///< holds the time stamp at the beginning of the display framerate measurement
double m_2DTimeAfter; ///< holds the time stamp at the end of the display framerate measurement
mitk::CameraIntrinsics::Pointer m_CameraIntrinsics; ///< member holding the intrinsic parameters of the camera
private:
/*!
\brief helper method to replace data of the specified node. If node does not exist it will be created
\param nodeName Name of the node
\param data Data object to be replaced
\return returns the node
*/
mitk::DataNode::Pointer ReplaceNodeData(std::string nodeName, mitk::BaseData* data);
void ProcessVideoTransform();
/*!
\brief Reset all GUI related things to default. E.g. show sagittal and coronal slices in the renderwindows.
*/
void ResetGUIToDefault();
};
#endif // _QMITKTOFUTILVIEW_H_INCLUDED
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/CMakeLists.txt b/Plugins/org.mitk.gui.qt.viewnavigator/CMakeLists.txt
new file mode 100644
index 0000000000..889fa29a2c
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/CMakeLists.txt
@@ -0,0 +1,8 @@
+project(org_mitk_gui_qt_viewnavigator)
+
+MACRO_CREATE_MITK_CTK_PLUGIN(
+ EXPORT_DIRECTIVE VIEWNAVIGATOR_EXPORT
+ EXPORTED_INCLUDE_SUFFIXES src
+ MODULE_DEPENDS MitkQtWidgetsExt
+ PACKAGE_DEPENDS CTK
+)
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox
new file mode 100644
index 0000000000..38a7d29305
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox
@@ -0,0 +1,10 @@
+/**
+\page org_mitk_gui_qt_viewnavigator View Navigator
+
+\imageMacro{view-manager_48.png,"Icon of the view navigator",2.00}
+
+This view allows for the easy navigation of the available views.
+
+You can select which view to open by double-clicking the name of the view in the view navigator. It provides a keyworded, grouped and searchable list of views.
+
+*/
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager_48.png b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager_48.png
new file mode 100644
index 0000000000..429a977eed
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager_48.png differ
diff --git a/Plugins/org.mitk.gui.qt.candystore/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/doxygen/modules.dox
similarity index 56%
rename from Plugins/org.mitk.gui.qt.candystore/documentation/doxygen/modules.dox
rename to Plugins/org.mitk.gui.qt.viewnavigator/documentation/doxygen/modules.dox
index 75081965a2..52de3fc0c2 100644
--- a/Plugins/org.mitk.gui.qt.candystore/documentation/doxygen/modules.dox
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/doxygen/modules.dox
@@ -1,16 +1,16 @@
/**
- \defgroup org_mitk_gui_qt_candystore org.mitk.gui.qt.candystore
+ \defgroup org_mitk_gui_qt_viewnavigator org.mitk.gui.qt.viewnavigator
\ingroup MITKPlugins
\brief Describe your plugin here.
*/
/**
- \defgroup org_mitk_gui_qt_candystore_internal Internal
- \ingroup org_mitk_gui_qt_candystore
+ \defgroup org_mitk_gui_qt_viewnavigator_internal Internal
+ \ingroup org_mitk_gui_qt_viewnavigator
- \brief This subcategory includes the internal classes of the org.mitk.gui.qt.candystore plugin. Other
+ \brief This subcategory includes the internal classes of the org.mitk.gui.qt.viewnavigator plugin. Other
plugins must not rely on these classes. They contain implementation details and their interface
may change at any time. We mean it.
*/
diff --git a/Plugins/org.mitk.gui.qt.candystore/files.cmake b/Plugins/org.mitk.gui.qt.viewnavigator/files.cmake
similarity index 69%
rename from Plugins/org.mitk.gui.qt.candystore/files.cmake
rename to Plugins/org.mitk.gui.qt.viewnavigator/files.cmake
index f39fa243be..74b6c45511 100644
--- a/Plugins/org.mitk.gui.qt.candystore/files.cmake
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/files.cmake
@@ -1,51 +1,50 @@
set(SRC_CPP_FILES
- QmitkCandyStoreWidget.cpp
+ QmitkViewNavigatorWidget.cpp
QmitkNewPerspectiveDialog.cpp
# mitkQtPerspectiveItem.h
# mitkQtViewItem.h
)
set(INTERNAL_CPP_FILES
- org_mitk_gui_qt_candystore_Activator.cpp
- CandyStoreView.cpp
+ org_mitk_gui_qt_viewnavigator_Activator.cpp
+ ViewNavigatorView.cpp
)
set(UI_FILES
- src/internal/CandyStoreViewControls.ui
- src/QmitkCandyStoreWidgetControls.ui
+ src/internal/ViewNavigatorViewControls.ui
+ src/QmitkViewNavigatorWidgetControls.ui
)
set(MOC_H_FILES
- src/internal/org_mitk_gui_qt_candystore_Activator.h
- src/internal/CandyStoreView.h
+ src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
+ src/internal/ViewNavigatorView.h
- src/QmitkCandyStoreWidget.h
+ src/QmitkViewNavigatorWidget.h
src/QmitkNewPerspectiveDialog.h
)
# list of resource files which can be used by the plug-in
# system without loading the plug-ins shared library,
# for example the icon used in the menu and tabs for the
# plug-in views in the workbench
set(CACHED_RESOURCE_FILES
- resources/icon.xpm
- resources/Candy_icon.png
+ resources/view-manager_48.png
plugin.xml
)
# list of Qt .qrc files which contain additional resources
# specific to this plugin
set(QRC_FILES
)
set(CPP_FILES )
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.candystore/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.viewnavigator/manifest_headers.cmake
similarity index 82%
rename from Plugins/org.mitk.gui.qt.candystore/manifest_headers.cmake
rename to Plugins/org.mitk.gui.qt.viewnavigator/manifest_headers.cmake
index 6657eca0c2..3235814344 100644
--- a/Plugins/org.mitk.gui.qt.candystore/manifest_headers.cmake
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/manifest_headers.cmake
@@ -1,5 +1,5 @@
-set(Plugin-Name "Candy Store")
+set(Plugin-Name "View Navigator")
set(Plugin-Version "0.1")
set(Plugin-Vendor "DKFZ, Medical and Biological Informatics")
set(Plugin-ContactAddress "")
set(Require-Plugin org.mitk.gui.qt.common)
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/plugin.xml b/Plugins/org.mitk.gui.qt.viewnavigator/plugin.xml
new file mode 100644
index 0000000000..51136cb4e5
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin>
+
+ <extension point="org.blueberry.ui.views">
+ <view id="org.mitk.views.viewnavigatorview"
+ name="View Navigator"
+ class="ViewNavigatorView"
+ icon="resources/view-manager_48.png"
+ />
+ </extension>
+
+</plugin>
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/resources/view-manager_48.png b/Plugins/org.mitk.gui.qt.viewnavigator/resources/view-manager_48.png
new file mode 100644
index 0000000000..429a977eed
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.viewnavigator/resources/view-manager_48.png differ
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/QmitkNewPerspectiveDialog.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkNewPerspectiveDialog.cpp
similarity index 100%
rename from Plugins/org.mitk.gui.qt.candystore/src/QmitkNewPerspectiveDialog.cpp
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkNewPerspectiveDialog.cpp
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/QmitkNewPerspectiveDialog.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkNewPerspectiveDialog.h
similarity index 100%
rename from Plugins/org.mitk.gui.qt.candystore/src/QmitkNewPerspectiveDialog.h
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkNewPerspectiveDialog.h
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidget.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp
similarity index 90%
rename from Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidget.cpp
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp
index 03df302846..5f7953896f 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp
@@ -1,770 +1,783 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
//Qmitk headers
-#include "QmitkCandyStoreWidget.h"
+#include "QmitkViewNavigatorWidget.h"
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
#include <berryIPerspectiveRegistry.h>
#include <berryPlatformUI.h>
#include <berryIWorkbenchPage.h>
#include <berryIExtensionPointService.h>
// Qt
#include <QMessageBox>
#include <QTreeView>
#include <QStandardItem>
#include <QSortFilterProxyModel>
class KeywordRegistry
{
public:
KeywordRegistry()
{
berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService();
berry::IConfigurationElement::vector keywordExts(extensionPointService->GetConfigurationElementsFor("org.blueberry.ui.keywords"));
std::string keywordId;
std::string keywordLabels;
berry::IConfigurationElement::vector::iterator keywordExtsIt;
for (keywordExtsIt = keywordExts.begin(); keywordExtsIt != keywordExts.end(); ++keywordExtsIt)
{
(*keywordExtsIt)->GetAttribute("id", keywordId);
(*keywordExtsIt)->GetAttribute("label", keywordLabels);
if (m_Keywords.find(keywordId) == m_Keywords.end())
{
m_Keywords[keywordId] = std::vector<QString>();
}
m_Keywords[keywordId].push_back(QString::fromStdString(keywordLabels));
}
}
std::vector<QString> GetKeywords(const std::string& id)
{
return m_Keywords[id];
}
std::vector<QString> GetKeywords(const std::vector<std::string>& ids)
{
std::vector<QString> result;
for (unsigned int i = 0; i < ids.size(); ++i)
{
std::vector< QString > tmpResult;
tmpResult = this->GetKeywords(ids[i]);
result.insert(result.end(), tmpResult.begin(), tmpResult.end());
}
return result;
}
private:
std::map<std::string, std::vector<QString> > m_Keywords;
};
class ClassFilterProxyModel : public QSortFilterProxyModel
{
private :
bool hasToBeDisplayed(const QModelIndex index) const;
bool displayElement(const QModelIndex index) const;
public:
ClassFilterProxyModel(QObject *parent = NULL);
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
ClassFilterProxyModel::ClassFilterProxyModel(QObject *parent):
QSortFilterProxyModel(parent)
{
}
bool ClassFilterProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
return hasToBeDisplayed(index);
}
bool ClassFilterProxyModel::displayElement(const QModelIndex index) const
{
bool result = false;
QString type = sourceModel()->data(index, Qt::DisplayRole).toString();
QStandardItem * item = dynamic_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(index);
if (type.contains(filterRegExp()))
{
return true;
}
{
mitk::QtViewItem* viewItem = dynamic_cast<mitk::QtViewItem*>(item);
if (viewItem)
{
for (unsigned int i = 0; i < viewItem->m_Tags.size(); ++i)
{
if (viewItem->m_Tags[i].contains(filterRegExp()))
{
return true;
}
}
if (viewItem->m_Description.contains(filterRegExp()))
{
return true;
}
}
}
{
mitk::QtPerspectiveItem* viewItem = dynamic_cast<mitk::QtPerspectiveItem*>(item);
if (viewItem)
{
for (unsigned int i = 0; i < viewItem->m_Tags.size(); ++i)
{
if (viewItem->m_Tags[i].contains(filterRegExp()))
{
return true;
}
}
if (viewItem->m_Description.contains(filterRegExp()))
{
return true;
}
}
}
return result;
}
bool ClassFilterProxyModel::hasToBeDisplayed(const QModelIndex index) const
{
bool result = false;
if ( sourceModel()->rowCount(index) > 0 )
{
for( int ii = 0; ii < sourceModel()->rowCount(index); ii++)
{
QModelIndex childIndex = sourceModel()->index(ii,0,index);
if ( ! childIndex.isValid() )
break;
result = hasToBeDisplayed(childIndex);
result |= displayElement(index);
if (result)
{
break;
}
}
}
else
{
result = displayElement(index);
}
return result;
}
-class CandyStorePerspectiveListener: public berry::IPerspectiveListener
+class ViewNavigatorPerspectiveListener: public berry::IPerspectiveListener
{
public:
- CandyStorePerspectiveListener(QmitkCandyStoreWidget* p) :
+ ViewNavigatorPerspectiveListener(QmitkViewNavigatorWidget* p) :
parentWidget(p)
{
}
Events::Types GetPerspectiveEventTypes() const
{
return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED
// remove the following line when command framework is finished
| Events::CLOSED | Events::OPENED | Events::PART_CHANGED;
}
void PerspectiveActivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveSavedAs(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*oldPerspective*/,
berry::IPerspectiveDescriptor::Pointer /*newPerspective*/)
{
}
void PerspectiveDeactivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveOpened(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveClosed(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveChanged(berry::IWorkbenchPage::Pointer,
berry::IPerspectiveDescriptor::Pointer,
berry::IWorkbenchPartReference::Pointer partRef, const std::string& changeId)
{
- if (changeId=="viewHide" && partRef->GetId()=="org.mitk.views.candystoreview")
+ if (changeId=="viewHide" && partRef->GetId()=="org.mitk.views.viewnavigatorview")
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->RemovePerspectiveListener(parentWidget->m_PerspectiveListener);
else
parentWidget->UpdateTreeList(NULL, partRef.GetPointer(), changeId);
}
private:
- QmitkCandyStoreWidget* parentWidget;
+ QmitkViewNavigatorWidget* parentWidget;
};
-struct CandyStoreWindowListener : public berry::IWindowListener
+struct ViewNavigatorWindowListener : public berry::IWindowListener
{
- CandyStoreWindowListener(QmitkCandyStoreWidget* switcher)
+ ViewNavigatorWindowListener(QmitkViewNavigatorWidget* switcher)
: switcher(switcher)
, m_Done(false)
{}
virtual void WindowOpened(berry::IWorkbenchWindow::Pointer window)
{
if (m_Done)
return;
if ( switcher->FillTreeList() )
{
m_Done = true;
- switcher->m_PerspectiveListener = CandyStorePerspectiveListener::Pointer(new CandyStorePerspectiveListener(switcher));
+ switcher->m_PerspectiveListener = ViewNavigatorPerspectiveListener::Pointer(new ViewNavigatorPerspectiveListener(switcher));
window->AddPerspectiveListener(switcher->m_PerspectiveListener);
}
}
virtual void WindowActivated(berry::IWorkbenchWindow::Pointer window)
{
if (m_Done)
return;
if ( switcher->FillTreeList() )
{
m_Done = true;
- switcher->m_PerspectiveListener = CandyStorePerspectiveListener::Pointer(new CandyStorePerspectiveListener(switcher));
+ switcher->m_PerspectiveListener = ViewNavigatorPerspectiveListener::Pointer(new ViewNavigatorPerspectiveListener(switcher));
window->AddPerspectiveListener(switcher->m_PerspectiveListener);
}
}
private:
- QmitkCandyStoreWidget* switcher;
+ QmitkViewNavigatorWidget* switcher;
bool m_Done;
};
bool compareViews(berry::IViewDescriptor::Pointer a, berry::IViewDescriptor::Pointer b)
{
if (a.IsNull() || b.IsNull())
return false;
return a->GetLabel().compare(b->GetLabel()) < 0;
}
bool comparePerspectives(berry::IPerspectiveDescriptor::Pointer a, berry::IPerspectiveDescriptor::Pointer b)
{
if (a.IsNull() || b.IsNull())
return false;
return a->GetLabel().compare(b->GetLabel()) < 0;
}
bool compareQStandardItems(QStandardItem* a, QStandardItem* b)
{
if (a==NULL || b==NULL)
return false;
return a->text().compare(b->text()) < 0;
}
-QmitkCandyStoreWidget::QmitkCandyStoreWidget( QWidget * parent, Qt::WindowFlags )
+QmitkViewNavigatorWidget::QmitkViewNavigatorWidget( QWidget * parent, Qt::WindowFlags )
: QWidget(parent)
{
+ m_Generated = false;
this->CreateQtPartControl(this);
}
-QmitkCandyStoreWidget::~QmitkCandyStoreWidget()
+QmitkViewNavigatorWidget::~QmitkViewNavigatorWidget()
{
}
-void QmitkCandyStoreWidget::CreateQtPartControl( QWidget *parent )
+void QmitkViewNavigatorWidget::setFocus()
+{
+ m_Controls.lineEdit->setFocus();
+}
+
+void QmitkViewNavigatorWidget::CreateQtPartControl( QWidget *parent )
{
// create GUI widgets from the Qt Designer's .ui file
if (berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow().IsNotNull())
{
- m_PerspectiveListener = CandyStorePerspectiveListener::Pointer(new CandyStorePerspectiveListener(this));
+ m_PerspectiveListener = ViewNavigatorPerspectiveListener::Pointer(new ViewNavigatorPerspectiveListener(this));
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->AddPerspectiveListener(m_PerspectiveListener);
}
else
{
- m_WindowListener = CandyStoreWindowListener::Pointer(new CandyStoreWindowListener(this));
+ m_WindowListener = ViewNavigatorWindowListener::Pointer(new ViewNavigatorWindowListener(this));
berry::PlatformUI::GetWorkbench()->AddWindowListener(m_WindowListener);
}
m_Parent = parent;
m_Controls.setupUi( parent );
connect( m_Controls.m_PluginTreeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint)));
connect( m_Controls.m_PluginTreeView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(ItemClicked(const QModelIndex&)));
connect( m_Controls.lineEdit, SIGNAL(textChanged(QString)), SLOT(FilterChanged()));
m_ContextMenu = new QMenu(m_Controls.m_PluginTreeView);
m_Controls.m_PluginTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
// Create a new TreeModel for the data
m_TreeModel = new QStandardItemModel();
m_FilterProxyModel = new ClassFilterProxyModel(this);
m_FilterProxyModel->setSourceModel(m_TreeModel);
//proxyModel->setFilterFixedString("Diff");
m_Controls.m_PluginTreeView->setModel(m_FilterProxyModel);
- FillTreeList();
}
-void QmitkCandyStoreWidget::UpdateTreeList(QStandardItem* root, berry::IWorkbenchPartReference *partRef, const std::string &changeId)
+void QmitkViewNavigatorWidget::UpdateTreeList(QStandardItem* root, berry::IWorkbenchPartReference *partRef, const std::string &changeId)
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
if (page.IsNull())
return;
+ if( !m_Generated )
+ {
+ m_Generated = FillTreeList();
+ }
+
if (root==NULL)
root = m_TreeModel->invisibleRootItem();
for (int i=0; i<root->rowCount(); i++)
{
QStandardItem* item = root->child(i);
QFont font;
if (dynamic_cast<mitk::QtPerspectiveItem*>(item))
{
mitk::QtPerspectiveItem* pItem = dynamic_cast<mitk::QtPerspectiveItem*>(item);
berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective();
if (currentPersp.IsNotNull() && currentPersp->GetId()==pItem->m_Perspective->GetId())
font.setBold(true);
pItem->setFont(font);
}
mitk::QtViewItem* vItem = dynamic_cast<mitk::QtViewItem*>(item);
if (vItem)
{
std::vector<berry::IViewPart::Pointer> viewParts(page->GetViews());
for (unsigned int i=0; i<viewParts.size(); i++)
if(viewParts[i]->GetPartName()==vItem->m_View->GetLabel())
{
font.setBold(true);
break;
}
if( partRef!=NULL && partRef->GetId()==vItem->m_View->GetId() && changeId=="viewHide")
font.setBold(false);
vItem->setFont(font);
}
UpdateTreeList(item, partRef, changeId);
}
}
-bool QmitkCandyStoreWidget::FillTreeList()
+bool QmitkViewNavigatorWidget::FillTreeList()
{
// active workbench window available?
if (berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow().IsNull())
return false;
// active page available?
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
if (page.IsNull())
return false;
// everything is fine and we can remove the window listener
if (m_WindowListener.IsNotNull())
berry::PlatformUI::GetWorkbench()->RemoveWindowListener(m_WindowListener);
// initialize tree model
m_TreeModel->clear();
QStandardItem *treeRootItem = m_TreeModel->invisibleRootItem();
// get all available perspectives
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
std::vector<berry::IPerspectiveDescriptor::Pointer> perspectiveDescriptors(perspRegistry->GetPerspectives());
std::sort(perspectiveDescriptors.begin(), perspectiveDescriptors.end(), comparePerspectives);
// get all Keywords
KeywordRegistry keywordRegistry;
berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective();
std::vector<std::string> perspectiveExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetPerspectiveExcludeList();
std::vector< QStandardItem* > categoryItems;
QStandardItem *perspectiveRootItem = new QStandardItem("Workflows");
perspectiveRootItem->setEditable(false);
treeRootItem->appendRow(perspectiveRootItem);
for (unsigned int i=0; i<perspectiveDescriptors.size(); i++)
{
berry::IPerspectiveDescriptor::Pointer p = perspectiveDescriptors.at(i);
bool skipPerspective = false;
for(unsigned int e=0; e<perspectiveExcludeList.size(); e++)
if(perspectiveExcludeList.at(e)==p->GetId())
{
skipPerspective = true;
break;
}
if (skipPerspective)
continue;
//QIcon* pIcon = static_cast<QIcon*>(p->GetImageDescriptor()->CreateImage());
mitk::QtPerspectiveItem* pItem = new mitk::QtPerspectiveItem(QString::fromStdString(p->GetLabel()));
pItem->m_Perspective = p;
pItem->m_Description = QString::fromStdString(p->GetDescription());
std::vector<std::string> keylist = p->GetKeywordReferences();
pItem->m_Tags = keywordRegistry.GetKeywords(keylist);
pItem->setEditable(false);
QFont font; font.setBold(true);
if (currentPersp.IsNotNull() && currentPersp->GetId()==p->GetId())
pItem->setFont(font);
std::vector<std::string> catPath = p->GetCategoryPath();
if (catPath.empty())
{
perspectiveRootItem->appendRow(pItem);
}
else
{
QStandardItem* categoryItem = NULL;
for (unsigned int c=0; c<categoryItems.size(); c++)
if (categoryItems.at(c)->text().toStdString() == catPath.front())
{
categoryItem = categoryItems.at(c);
break;
}
if (categoryItem==NULL)
{
categoryItem = new QStandardItem(QIcon(),catPath.front().c_str());
categoryItems.push_back(categoryItem);
}
categoryItem->setEditable(false);
categoryItem->appendRow(pItem);
}
}
std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems);
for (unsigned int i=0; i<categoryItems.size(); i++)
perspectiveRootItem->appendRow(categoryItems.at(i));
// get all available views
berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry();
std::vector<berry::IViewDescriptor::Pointer> viewDescriptors(viewRegistry->GetViews());
std::vector<berry::IViewPart::Pointer> viewParts(page->GetViews());
std::sort(viewDescriptors.begin(), viewDescriptors.end(), compareViews);
std::vector<std::string> viewExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetViewExcludeList();
- QStandardItem* viewRootItem = new QStandardItem(QIcon(),"Candies");
+ QStandardItem* viewRootItem = new QStandardItem(QIcon(),"Views");
viewRootItem->setEditable(false);
treeRootItem->appendRow(viewRootItem);
categoryItems.clear();
QStandardItem* noCategoryItem = new QStandardItem(QIcon(),"Miscellaneous");
noCategoryItem->setEditable(false);
for (unsigned int i = 0; i < viewDescriptors.size(); ++i)
{
berry::IViewDescriptor::Pointer v = viewDescriptors[i];
bool skipView = false;
for(unsigned int e=0; e<viewExcludeList.size(); e++)
if(viewExcludeList.at(e)==v->GetId())
{
skipView = true;
break;
}
if (skipView)
continue;
std::vector<std::string> catPath = v->GetCategoryPath();
QIcon* icon = static_cast<QIcon*>(v->GetImageDescriptor()->CreateImage());
mitk::QtViewItem* vItem = new mitk::QtViewItem(*icon, QString::fromStdString(v->GetLabel()));
vItem->m_View = v;
vItem->setToolTip(v->GetDescription().c_str());
vItem->m_Description = QString::fromStdString(v->GetDescription());
std::vector<std::string> keylist = v->GetKeywordReferences();
vItem->m_Tags = keywordRegistry.GetKeywords(keylist);
vItem->setEditable(false);
for (unsigned int i=0; i<viewParts.size(); i++)
if(viewParts[i]->GetPartName()==v->GetLabel())
{
QFont font; font.setBold(true);
vItem->setFont(font);
break;
}
if (catPath.empty())
noCategoryItem->appendRow(vItem);
else
{
QStandardItem* categoryItem = NULL;
for (unsigned int c=0; c<categoryItems.size(); c++)
if (categoryItems.at(c)->text().toStdString() == catPath.front())
{
categoryItem = categoryItems.at(c);
break;
}
if (categoryItem==NULL)
{
categoryItem = new QStandardItem(QIcon(),catPath.front().c_str());
categoryItems.push_back(categoryItem);
}
categoryItem->setEditable(false);
categoryItem->appendRow(vItem);
}
}
std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems);
for (unsigned int i=0; i<categoryItems.size(); i++)
viewRootItem->appendRow(categoryItems.at(i));
if (noCategoryItem->hasChildren())
viewRootItem->appendRow(noCategoryItem);
m_Controls.m_PluginTreeView->expandAll();
return true;
}
-void QmitkCandyStoreWidget::FilterChanged()
+void QmitkViewNavigatorWidget::FilterChanged()
{
QString filterString = m_Controls.lineEdit->text();
if (filterString.size() > 0 )
m_Controls.m_PluginTreeView->expandAll();
else
m_Controls.m_PluginTreeView->collapseAll();
// QRegExp::PatternSyntax syntax = QRegExp::RegExp;
Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
QString strPattern = "^*" + filterString;
QRegExp regExp(strPattern, caseSensitivity);
m_FilterProxyModel->setFilterRegExp(regExp);
}
-void QmitkCandyStoreWidget::ItemClicked(const QModelIndex &index)
+void QmitkViewNavigatorWidget::ItemClicked(const QModelIndex &index)
{
QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index));
if ( dynamic_cast< mitk::QtPerspectiveItem* >(item) )
{
try
{
mitk::QtPerspectiveItem* pItem = dynamic_cast< mitk::QtPerspectiveItem* >(item);
berry::PlatformUI::GetWorkbench()->ShowPerspective( pItem->m_Perspective->GetId(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() );
}
catch (...)
{
QMessageBox::critical(0, "Opening Perspective Failed", QString("The requested perspective could not be opened.\nSee the log for details."));
}
}
else if ( dynamic_cast< mitk::QtViewItem* >(item) )
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
if (page.IsNotNull())
{
try
{
mitk::QtViewItem* vItem = dynamic_cast< mitk::QtViewItem* >(item);
page->ShowView(vItem->m_View->GetId());
}
catch (berry::PartInitException e)
{
BERRY_ERROR << "Error: " << e.displayText() << std::endl;
}
}
}
}
-void QmitkCandyStoreWidget::AddPerspective()
+void QmitkViewNavigatorWidget::AddPerspective()
{
QmitkNewPerspectiveDialog* dialog = new QmitkNewPerspectiveDialog( m_Parent );
int dialogReturnValue = dialog->exec();
if ( dialogReturnValue == QDialog::Rejected )
return;
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
try
{
berry::IPerspectiveDescriptor::Pointer perspDesc;
perspDesc = perspRegistry->CreatePerspective(dialog->GetPerspectiveName().toStdString(), perspRegistry->FindPerspectiveWithId(perspRegistry->GetDefaultPerspective()));
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->SetPerspective(perspDesc);
}
catch(...)
{
QMessageBox::warning(m_Parent, "Error", "Duplication of selected perspective failed. Please make sure the specified perspective name is not already in use!");
}
FillTreeList();
}
-void QmitkCandyStoreWidget::ClonePerspective()
+void QmitkViewNavigatorWidget::ClonePerspective()
{
if (m_RegisteredPerspective.IsNotNull())
{
QmitkNewPerspectiveDialog* dialog = new QmitkNewPerspectiveDialog( m_Parent );
QString defaultName(m_RegisteredPerspective->GetLabel().c_str());
defaultName.append(" Copy");
dialog->SetPerspectiveName(defaultName);
int dialogReturnValue = dialog->exec();
if ( dialogReturnValue == QDialog::Rejected )
return;
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
try
{
berry::IPerspectiveDescriptor::Pointer perspDesc = perspRegistry->ClonePerspective(dialog->GetPerspectiveName().toStdString(), dialog->GetPerspectiveName().toStdString(), m_RegisteredPerspective);
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->SetPerspective(perspDesc);
}
catch(...)
{
QMessageBox::warning(m_Parent, "Error", "Duplication of selected perspective failed. Please make sure the specified perspective name is not already in use!");
}
FillTreeList();
}
}
-void QmitkCandyStoreWidget::ResetPerspective()
+void QmitkViewNavigatorWidget::ResetPerspective()
{
- if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to reset the curent perspective?", QMessageBox::Yes|QMessageBox::No).exec())
+ if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to reset the current perspective?", QMessageBox::Yes|QMessageBox::No).exec())
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective();
}
-void QmitkCandyStoreWidget::DeletePerspective()
+void QmitkViewNavigatorWidget::DeletePerspective()
{
if (m_RegisteredPerspective.IsNotNull())
{
QString question = "Do you really want to remove the perspective '";
question.append(m_RegisteredPerspective->GetLabel().c_str());
question.append("'?");
if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", question, QMessageBox::Yes|QMessageBox::No).exec())
{
+ if( m_RegisteredPerspective == berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->GetPerspective() )
+ {
+ berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->CloseCurrentPerspective(true, true);
+ }
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
perspRegistry->DeletePerspective(m_RegisteredPerspective);
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->RemovePerspective(m_RegisteredPerspective);
FillTreeList();
if (! berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->GetPerspective())
{
- berry::IPerspectiveDescriptor::Pointer persp = perspRegistry->FindPerspectiveWithId(perspRegistry->GetDefaultPerspective());
- berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->SetPerspective(persp);
+ berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->Close();
}
}
}
}
-void QmitkCandyStoreWidget::ClosePerspective()
+void QmitkViewNavigatorWidget::ClosePerspective()
{
- if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close the curent perspective?", QMessageBox::Yes|QMessageBox::No).exec())
+ if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close the current perspective?", QMessageBox::Yes|QMessageBox::No).exec())
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->CloseCurrentPerspective(true, true);
// if ( page->GetPerspective().IsNull() )
// {
// berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
// berry::PlatformUI::GetWorkbench()->ShowPerspective( perspRegistry->GetDefaultPerspective(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() );
// }
}
}
-void QmitkCandyStoreWidget::CloseAllPerspectives()
+void QmitkViewNavigatorWidget::CloseAllPerspectives()
{
if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close all perspectives?", QMessageBox::Yes|QMessageBox::No).exec())
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->CloseAllPerspectives(true, true);
// berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
// berry::PlatformUI::GetWorkbench()->ShowPerspective( perspRegistry->GetDefaultPerspective(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() );
}
}
-void QmitkCandyStoreWidget::ExpandAll()
+void QmitkViewNavigatorWidget::ExpandAll()
{
m_Controls.m_PluginTreeView->expandAll();
}
-void QmitkCandyStoreWidget::CollapseAll()
+void QmitkViewNavigatorWidget::CollapseAll()
{
m_Controls.m_PluginTreeView->collapseAll();
}
-void QmitkCandyStoreWidget::CustomMenuRequested(QPoint pos)
+void QmitkViewNavigatorWidget::CustomMenuRequested(QPoint pos)
{
QModelIndex index = m_Controls.m_PluginTreeView->indexAt(pos);
QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index));
if (m_ContextMenu==NULL)
return;
m_ContextMenu->clear();
m_RegisteredPerspective = NULL;
QAction* expandAction = new QAction("Expand tree", this);
m_ContextMenu->addAction(expandAction);
connect(expandAction, SIGNAL(triggered()), SLOT(ExpandAll()));
QAction* collapseAction = new QAction("Collapse tree", this);
m_ContextMenu->addAction(collapseAction);
connect(collapseAction, SIGNAL(triggered()), SLOT(CollapseAll()));
m_ContextMenu->addSeparator();
if ( item!=NULL && dynamic_cast< mitk::QtPerspectiveItem* >(item) )
{
m_RegisteredPerspective = dynamic_cast< mitk::QtPerspectiveItem* >(item)->m_Perspective;
//m_ContextMenu->addSeparator();
QAction* cloneAction = new QAction("Duplicate perspective", this);
m_ContextMenu->addAction(cloneAction);
connect(cloneAction, SIGNAL(triggered()), SLOT(ClonePerspective()));
if (!m_RegisteredPerspective->IsPredefined())
{
QAction* deleteAction = new QAction("Remove perspective", this);
m_ContextMenu->addAction(deleteAction);
connect(deleteAction, SIGNAL(triggered()), SLOT(DeletePerspective()));
}
m_ContextMenu->addSeparator();
}
QAction* resetAction = new QAction("Reset current perspective", this);
m_ContextMenu->addAction(resetAction);
connect(resetAction, SIGNAL(triggered()), SLOT(ResetPerspective()));
QAction* closeAction = new QAction("Close current perspective", this);
m_ContextMenu->addAction(closeAction);
connect(closeAction, SIGNAL(triggered()), SLOT(ClosePerspective()));
m_ContextMenu->addSeparator();
QAction* closeAllAction = new QAction("Close all perspectives", this);
m_ContextMenu->addAction(closeAllAction);
connect(closeAllAction, SIGNAL(triggered()), SLOT(CloseAllPerspectives()));
m_ContextMenu->popup(m_Controls.m_PluginTreeView->viewport()->mapToGlobal(pos));
}
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidget.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h
similarity index 81%
rename from Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidget.h
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h
index 509c4cdad6..32fe32b314 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidget.h
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h
@@ -1,89 +1,91 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef _QMITKCandyStoreWidget_H_INCLUDED
-#define _QMITKCandyStoreWidget_H_INCLUDED
+#ifndef _QMITKViewNavigatorWidget_H_INCLUDED
+#define _QMITKViewNavigatorWidget_H_INCLUDED
//QT headers
#include <QWidget>
#include <QString>
#include <ctkSearchBox.h>
-#include "ui_QmitkCandyStoreWidgetControls.h"
+#include "ui_QmitkViewNavigatorWidgetControls.h"
#include <berryISelectionListener.h>
#include <berryIPerspectiveListener.h>
#include <berryIWorkbench.h>
#include <berryIWorkbenchPage.h>
#include <berryIPerspectiveDescriptor.h>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QMenu>
#include <QmitkNewPerspectiveDialog.h>
#include <mitkQtPerspectiveItem.h>
#include <mitkQtViewItem.h>
class ClassFilterProxyModel;
/** @brief
*/
-class QmitkCandyStoreWidget : public QWidget
+class QmitkViewNavigatorWidget : public QWidget
{
//this is needed for all Qt objects that should have a MOC object (everything that derives from QObject)
Q_OBJECT
public:
- QmitkCandyStoreWidget (QWidget* parent = 0, Qt::WindowFlags f = 0);
- virtual ~QmitkCandyStoreWidget();
+ QmitkViewNavigatorWidget (QWidget* parent = 0, Qt::WindowFlags f = 0);
+ virtual ~QmitkViewNavigatorWidget();
virtual void CreateQtPartControl(QWidget *parent);
+ void setFocus();
bool FillTreeList();
void UpdateTreeList(QStandardItem* item = NULL, berry::IWorkbenchPartReference* partRef=NULL, const std::string& changeId="");
berry::IPerspectiveListener::Pointer m_PerspectiveListener;
berry::IWindowListener::Pointer m_WindowListener;
public slots:
void CustomMenuRequested(QPoint pos);
void ItemClicked(const QModelIndex &index);
void AddPerspective();
void ClonePerspective();
void ResetPerspective();
void DeletePerspective();
void CloseAllPerspectives();
void ClosePerspective();
void ExpandAll();
void CollapseAll();
void FilterChanged();
protected:
// member variables
- Ui::QmitkCandyStoreWidgetControls m_Controls;
+ Ui::QmitkViewNavigatorWidgetControls m_Controls;
QWidget* m_Parent;
QStandardItemModel* m_TreeModel;
ClassFilterProxyModel* m_FilterProxyModel;
QMenu* m_ContextMenu;
berry::IPerspectiveDescriptor::Pointer m_RegisteredPerspective;
+ bool m_Generated;
private:
};
-#endif // _QMITKCandyStoreWidget_H_INCLUDED
+#endif // _QMITKViewNavigatorWidget_H_INCLUDED
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidgetControls.ui b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidgetControls.ui
similarity index 90%
rename from Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidgetControls.ui
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidgetControls.ui
index 2f8a961032..7073a4bf1e 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/QmitkCandyStoreWidgetControls.ui
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidgetControls.ui
@@ -1,52 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>QmitkCandyStoreWidgetControls</class>
- <widget class="QWidget" name="QmitkCandyStoreWidgetControls">
+ <class>QmitkViewNavigatorWidgetControls</class>
+ <widget class="QWidget" name="QmitkViewNavigatorWidgetControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>752</width>
<height>974</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkTemplate</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="ctkSearchBox" name="lineEdit">
<property name="placeholderText">
<string>Filter...</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="m_PluginTreeView">
<property name="rootIsDecorated">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>ctkSearchBox</class>
<extends>QLineEdit</extends>
<header>ctkSearchBox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreView.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorView.cpp
similarity index 57%
rename from Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreView.cpp
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorView.cpp
index 1ad53d1f97..f2255bdfbc 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreView.cpp
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorView.cpp
@@ -1,57 +1,49 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
-#include "CandyStoreView.h"
+#include "ViewNavigatorView.h"
// Qt
#include <QMessageBox>
//mitk image
#include <mitkImage.h>
-const std::string CandyStoreView::VIEW_ID = "org.mitk.views.candystoreview";
+const std::string ViewNavigatorView::VIEW_ID = "org.mitk.views.viewnavigatorview";
-void CandyStoreView::SetFocus()
+void ViewNavigatorView::SetFocus()
{
-
+ m_Controls.widget->setFocus();
}
-void CandyStoreView::CreateQtPartControl( QWidget *parent )
+void ViewNavigatorView::CreateQtPartControl( QWidget *parent )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls.setupUi( parent );
-
-
-// candyStore = new QDockWidget("Candy Store");
-// candyStore->setWidget(new QmitkCandyStoreWidget());
-// candyStore->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
-// candyStore->setVisible(false);
-// candyStore->setObjectName("Candy Store");
-// mainWindow->addDockWidget(Qt::LeftDockWidgetArea, candyStore);
}
-void CandyStoreView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/,
+void ViewNavigatorView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/,
const QList<mitk::DataNode::Pointer>& nodes )
{
}
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreView.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorView.h
similarity index 82%
rename from Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreView.h
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorView.h
index 2b49dc9247..6e860b9038 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreView.h
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorView.h
@@ -1,64 +1,64 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef CandyStoreView_h
-#define CandyStoreView_h
+#ifndef ViewNavigatorView_h
+#define ViewNavigatorView_h
#include <berryISelectionListener.h>
#include <QmitkAbstractView.h>
-#include <QmitkCandyStoreWidget.h>
+#include <QmitkViewNavigatorWidget.h>
-#include "ui_CandyStoreViewControls.h"
+#include "ui_ViewNavigatorViewControls.h"
/**
- \brief CandyStoreView
+ \brief ViewNavigatorView
\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation.
\sa QmitkAbstractView
\ingroup ${plugin_target}_internal
*/
-class CandyStoreView : public QmitkAbstractView
+class ViewNavigatorView : public QmitkAbstractView
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
static const std::string VIEW_ID;
protected slots:
/// \brief Called when the user clicks the GUI button
protected:
virtual void CreateQtPartControl(QWidget *parent);
virtual void SetFocus();
/// \brief called by QmitkFunctionality when DataManager's selection has changed
virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source,
const QList<mitk::DataNode::Pointer>& nodes );
- Ui::CandyStoreViewControls m_Controls;
+ Ui::ViewNavigatorViewControls m_Controls;
};
-#endif // CandyStoreView_h
+#endif // ViewNavigatorView_h
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreViewControls.ui b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorViewControls.ui
similarity index 79%
rename from Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreViewControls.ui
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorViewControls.ui
index 4d663835b9..090827ba27 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/internal/CandyStoreViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/ViewNavigatorViewControls.ui
@@ -1,54 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>CandyStoreViewControls</class>
- <widget class="QWidget" name="CandyStoreViewControls">
+ <class>ViewNavigatorViewControls</class>
+ <widget class="QWidget" name="ViewNavigatorViewControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>222</width>
<height>161</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkTemplate</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
- <widget class="QmitkCandyStoreWidget" name="widget" native="true"/>
+ <widget class="QmitkViewNavigatorWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
- <class>QmitkCandyStoreWidget</class>
+ <class>QmitkViewNavigatorWidget</class>
<extends>QWidget</extends>
- <header>QmitkCandyStoreWidget.h</header>
+ <header>QmitkViewNavigatorWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/internal/org_mitk_gui_qt_candystore_Activator.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp
similarity index 59%
rename from Plugins/org.mitk.gui.qt.candystore/src/internal/org_mitk_gui_qt_candystore_Activator.cpp
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp
index cd04f1c6e5..50a638f6f0 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/internal/org_mitk_gui_qt_candystore_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp
@@ -1,38 +1,38 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#include "org_mitk_gui_qt_candystore_Activator.h"
+#include "org_mitk_gui_qt_viewnavigator_Activator.h"
#include <QtPlugin>
-#include "CandyStoreView.h"
+#include "ViewNavigatorView.h"
namespace mitk {
-void org_mitk_gui_qt_candystore_Activator::start(ctkPluginContext* context)
+void org_mitk_gui_qt_viewnavigator_Activator::start(ctkPluginContext* context)
{
- BERRY_REGISTER_EXTENSION_CLASS(CandyStoreView, context)
+ BERRY_REGISTER_EXTENSION_CLASS(ViewNavigatorView, context)
}
-void org_mitk_gui_qt_candystore_Activator::stop(ctkPluginContext* context)
+void org_mitk_gui_qt_viewnavigator_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_candystore, mitk::org_mitk_gui_qt_candystore_Activator)
+Q_EXPORT_PLUGIN2(org_mitk_gui_qt_viewnavigator, mitk::org_mitk_gui_qt_viewnavigator_Activator)
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/internal/org_mitk_gui_qt_candystore_Activator.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
similarity index 75%
rename from Plugins/org.mitk.gui.qt.candystore/src/internal/org_mitk_gui_qt_candystore_Activator.h
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
index d97e38fc8f..67ebc8166a 100644
--- a/Plugins/org.mitk.gui.qt.candystore/src/internal/org_mitk_gui_qt_candystore_Activator.h
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
@@ -1,40 +1,40 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#ifndef org_mitk_gui_qt_candystore_Activator_h
-#define org_mitk_gui_qt_candystore_Activator_h
+#ifndef org_mitk_gui_qt_viewnavigator_Activator_h
+#define org_mitk_gui_qt_viewnavigator_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
-class org_mitk_gui_qt_candystore_Activator :
+class org_mitk_gui_qt_viewnavigator_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
-}; // org_mitk_gui_qt_candystore_Activator
+}; // org_mitk_gui_qt_viewnavigator_Activator
}
-#endif // org_mitk_gui_qt_candystore_Activator_h
+#endif // org_mitk_gui_qt_viewnavigator_Activator_h
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/mitkQtPerspectiveItem.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/mitkQtPerspectiveItem.h
similarity index 100%
rename from Plugins/org.mitk.gui.qt.candystore/src/mitkQtPerspectiveItem.h
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/mitkQtPerspectiveItem.h
diff --git a/Plugins/org.mitk.gui.qt.candystore/src/mitkQtViewItem.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/mitkQtViewItem.h
similarity index 100%
rename from Plugins/org.mitk.gui.qt.candystore/src/mitkQtViewItem.h
rename to Plugins/org.mitk.gui.qt.viewnavigator/src/mitkQtViewItem.h
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp
index a79f97c3ec..989dbb8a71 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp
@@ -1,453 +1,482 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkXnatEditor.h"
// Qmitk
#include "QmitkXnatObjectEditorInput.h"
#include "org_mitk_gui_qt_xnatinterface_Activator.h"
// CTK XNAT Core
#include "ctkXnatObject.h"
#include "ctkXnatDataModel.h"
#include "ctkXnatScanFolder.h"
#include "ctkXnatFile.h"
// CTK XNAT Widgets
#include "ctkXnatListModel.h"
// Blueberry
#include <berryQModelIndexObject.h>
#include <berryIWorkbenchPage.h>
// Qt
#include <QListView>
#include <QRegExp>
#include <QModelIndex>
#include <QDir>
#include <QMessageBox>
// MITK
#include <mitkDataStorage.h>
#include <mitkIOUtil.h>
const std::string QmitkXnatEditor::EDITOR_ID = "org.mitk.editors.xnat.browser";
QmitkXnatEditor::QmitkXnatEditor() :
m_DataStorageServiceTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()),
m_Session(0),
m_ListModel(new ctkXnatListModel()),
m_SelectionListener(new berry::SelectionChangedAdapter<QmitkXnatEditor>(this, &QmitkXnatEditor::SelectionChanged)),
m_DownloadPath(berry::Platform::GetServiceRegistry().
GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID)->
GetSystemPreferences()->Node("/XnatConnection")->Get("Download Path", "").c_str())
{
m_DataStorageServiceTracker.open();
if(m_DownloadPath.isEmpty())
{
QString xnatFolder = "XNAT_DOWNLOADS";
QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath());
dir.mkdir(xnatFolder);
dir.setPath(dir.path() + "/" + xnatFolder);
m_DownloadPath = dir.path() + "/";
}
}
QmitkXnatEditor::~QmitkXnatEditor()
{
delete m_ListModel;
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
s->RemoveSelectionListener(m_SelectionListener);
m_DataStorageServiceTracker.close();
}
bool QmitkXnatEditor::IsDirty() const
{
return false;
}
bool QmitkXnatEditor::IsSaveAsAllowed() const
{
return false;
}
void QmitkXnatEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input)
{
- this->SetInput(input);
this->SetSite(site);
+ berry::QtEditorPart::SetInput(input);
+ this->SetInput(input);
}
void QmitkXnatEditor::DoSave()
{
}
void QmitkXnatEditor::DoSaveAs()
{
}
void QmitkXnatEditor::SetInput(berry::IEditorInput::Pointer input)
{
- // If the input is not a QmitkXnatObjectEditorInput the semi global xnat session will be loaded.
QmitkXnatObjectEditorInput::Pointer oPtr = input.Cast<QmitkXnatObjectEditorInput>();
if(oPtr.IsNotNull())
{
- SetInputWithNotify(oPtr);
+ berry::QtEditorPart::SetInput(oPtr);
this->GetEditorInput().Cast<QmitkXnatObjectEditorInput>()->GetXnatObject()->fetch();
}
- else
- {
- // Get the XNAT Session from Activator
- m_Session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->GetXnatSession();
-
- if(m_Session == 0)
- {
- QMessageBox::critical(QApplication::activeWindow(), "Error",
- "Please check the Preferences of XNAT. Maybe they are not ok.\nClose the tab 'XNAT Editor' and start it again.");
- MITK_INFO << "Please check your XNAT Connection Preferences!";
- }
- else
- {
- QmitkXnatObjectEditorInput::Pointer xoPtr = QmitkXnatObjectEditorInput::New( m_Session->dataModel() );
- berry::IEditorInput::Pointer editorInput( xoPtr );
- SetInputWithNotify(editorInput);
- this->GetEditorInput().Cast<QmitkXnatObjectEditorInput>()->GetXnatObject()->fetch();
- }
- }
}
void QmitkXnatEditor::SetFocus()
{
}
void QmitkXnatEditor::CreateQtPartControl( QWidget *parent )
{
- if(m_Session != 0) return;
-
// create GUI widgets from the Qt Designer's .ui file
m_Controls.setupUi( parent );
- m_Controls.treeView->setModel(m_ListModel);
GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener(m_SelectionListener);
connect( m_Controls.treeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(OnObjectActivated(const QModelIndex&)) );
connect( m_Controls.buttonDownloadResource, SIGNAL(clicked()), this, SLOT(DownloadResource()) );
connect( m_Controls.buttonDownloadFile, SIGNAL(clicked()), this, SLOT(DownloadFile()) );
connect( m_Controls.buttonDataModel, SIGNAL(clicked()), this, SLOT(OnDataModelButtonClicked()) );
connect( m_Controls.buttonProject, SIGNAL(clicked()), this, SLOT(OnProjectButtonClicked()) );
connect( m_Controls.buttonSubject, SIGNAL(clicked()), this, SLOT(OnSubjectButtonClicked()) );
connect( m_Controls.buttonExperiment, SIGNAL(clicked()), this, SLOT(OnExperimentButtonClicked()) );
connect( m_Controls.buttonKindOfData, SIGNAL(clicked()), this, SLOT(OnKindOfDataButtonClicked()) );
connect( m_Controls.buttonSession, SIGNAL(clicked()), this, SLOT(OnSessionButtonClicked()) );
connect( m_Controls.buttonResource, SIGNAL(clicked()), this, SLOT(OnResourceButtonClicked()) );
// Makes the breadcrumb feature invisible
for(int i = 0; i < m_Controls.breadcrumbHorizontalLayout->count()-1; i++)
{
QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i);
child->widget()->setVisible(false);
}
for(int i = 0; i < m_Controls.breadcrumbDescriptionLayout->count()-1; i++)
{
QLayoutItem* child = m_Controls.breadcrumbDescriptionLayout->itemAt(i);
child->widget()->setVisible(false);
}
- UpdateList();
+ QmitkXnatObjectEditorInput::Pointer oPtr = GetEditorInput().Cast<QmitkXnatObjectEditorInput>();
+ if(oPtr.IsNotNull())
+ {
+ UpdateList();
+ }
+ else
+ {
+ UpdateSession();
+ }
}
void QmitkXnatEditor::UpdateList()
{
QmitkXnatObjectEditorInput::Pointer xoPtr(GetEditorInput().Cast<QmitkXnatObjectEditorInput>());
if( xoPtr.IsNull() )
return;
ctkXnatObject* inputObject = xoPtr->GetXnatObject();
if( inputObject == NULL )
return;
+
+ m_Controls.treeView->setModel(m_ListModel);
m_ListModel->setRootObject( inputObject );
m_Controls.treeView->reset();
// recursive method to check parents of the inputObject
m_ParentCount = ParentChecker(inputObject);
// breadcrumb labels
for(int i = 0; i < m_Controls.breadcrumbHorizontalLayout->count()-1; i++)
{
QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i);
child->widget()->setVisible(false);
}
for(int i = 0; i < m_Controls.breadcrumbDescriptionLayout->count()-1; i++)
{
QLayoutItem* child = m_Controls.breadcrumbDescriptionLayout->itemAt(i);
child->widget()->setVisible(false);
}
ctkXnatObject* parent = NULL;
for(int i = m_ParentCount*2; i >= 0; i--)
{
if(i > 12)
break;
m_Controls.breadcrumbDescriptionLayout->itemAt(i)->widget()->setVisible(true);
QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i);
child->widget()->setVisible(true);
if(i>0)
{
m_Controls.breadcrumbHorizontalLayout->itemAt(i-1)->widget()->setVisible(true);
m_Controls.breadcrumbDescriptionLayout->itemAt(i-1)->widget()->setVisible(true);
}
if(parent == NULL)
{
parent = inputObject;
}
- // make breadcrumb button
+ // create breadcrumb button
QPushButton* breadcrumbButton = dynamic_cast<QPushButton*>(child->widget());
breadcrumbButton->setText(parent->id());
parent = parent->parent();
i--;
}
+ m_Controls.buttonDataModel->setText("root");
}
void QmitkXnatEditor::SelectionChanged(berry::IWorkbenchPart::Pointer sourcepart,
berry::ISelection::ConstPointer selection)
{
// check for null selection
if (selection.IsNull())
{
return;
}
// exclude own selection events and check whether this kind of selection can be handled
if (sourcepart != this &&
selection.Cast<const berry::IStructuredSelection>())
{
berry::IStructuredSelection::ConstPointer currentSelection = selection.Cast<const berry::IStructuredSelection>();
// iterates over the selection
for (berry::IStructuredSelection::iterator itr = currentSelection->Begin();
itr != currentSelection->End(); ++itr)
{
if (berry::SmartPointer<berry::QModelIndexObject> objectPointer = itr->Cast<berry::QModelIndexObject>())
{
// get object of selected ListWidgetElement
ctkXnatObject* object = objectPointer->GetQModelIndex().data(Qt::UserRole).value<ctkXnatObject*>();
// if a file is selected, don't change the input and list view
if ( dynamic_cast<ctkXnatFile*>(object) == NULL )
{
QmitkXnatObjectEditorInput::Pointer oPtr = QmitkXnatObjectEditorInput::New( object );
berry::IEditorInput::Pointer editorInput( oPtr );
if ( !(editorInput == this->GetEditorInput()) )
this->SetInput(editorInput);
UpdateList();
}
}
}
}
}
void QmitkXnatEditor::DownloadResource()
{
if (!m_Controls.treeView->selectionModel()->hasSelection())
return;
const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex();
QVariant variant = m_ListModel->data(index, Qt::UserRole);
if ( variant.isValid() )
{
ctkXnatScanFolder* resource = dynamic_cast<ctkXnatScanFolder*>(variant.value<ctkXnatObject*>());
if (resource != NULL)
{
MITK_INFO << "Download started ...";
MITK_INFO << "...";
QString resourcePath = m_DownloadPath + resource->id() + ".zip";
resource->download(resourcePath);
// Testing if the path exists
QDir downDir(m_DownloadPath);
if( downDir.exists(resource->id() + ".zip") )
{
MITK_INFO << "Download of " << resource->id().toStdString() << ".zip was completed!";
}
else
{
MITK_INFO << "Download of " << resource->id().toStdString() << ".zip failed!";
}
}
else
{
MITK_INFO << "Selection was not a resource folder!";
}
}
}
void QmitkXnatEditor::DownloadFile()
{
if (!m_Controls.treeView->selectionModel()->hasSelection())
return;
const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex();
InternalFileDownload(index);
}
void QmitkXnatEditor::ToHigherLevel()
{
ctkXnatObject* parent = GetEditorInput().Cast<QmitkXnatObjectEditorInput>()->GetXnatObject()->parent();
if( parent == NULL)
{
return;
}
QmitkXnatObjectEditorInput::Pointer oPtr = QmitkXnatObjectEditorInput::New( parent );
berry::IEditorInput::Pointer editorInput( oPtr );
- SetInput(editorInput);
+ this->SetInput(editorInput);
UpdateList();
}
void QmitkXnatEditor::OnObjectActivated(const QModelIndex &index)
{
if (!index.isValid()) return;
ctkXnatObject* child = GetEditorInput().Cast<QmitkXnatObjectEditorInput>()->GetXnatObject()->children().at(index.row());
if( child != NULL )
{
ctkXnatFile* file = dynamic_cast<ctkXnatFile*>(child);
if( file != NULL )
{
// Download file and put into datamanager
InternalFileDownload(index);
mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService();
if(dsService != NULL)
{
mitk::DataNode::Pointer node = mitk::IOUtil::LoadDataNode((m_DownloadPath + file->id()).toStdString());
if ( ( node.IsNotNull() ) && ( node->GetData() != NULL ) )
{
dsService->GetDataStorage()->GetDataStorage()->Add(node);
mitk::BaseData::Pointer basedata = node->GetData();
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
}
}
}
else
{
// Updates the root item
QmitkXnatObjectEditorInput::Pointer oPtr = QmitkXnatObjectEditorInput::New( child );
berry::IEditorInput::Pointer editorInput( oPtr );
- SetInput(editorInput);
+ this->SetInput(editorInput);
this->GetEditorInput().Cast<QmitkXnatObjectEditorInput>()->GetXnatObject()->fetch();
UpdateList();
}
}
}
void QmitkXnatEditor::InternalFileDownload(const QModelIndex& index)
{
QVariant variant = m_ListModel->data(index, Qt::UserRole);
if ( variant.isValid() )
{
ctkXnatFile* file = dynamic_cast<ctkXnatFile*>(variant.value<ctkXnatObject*>());
if (file != NULL)
{
MITK_INFO << "Download started ...";
MITK_INFO << "...";
QString filePath = m_DownloadPath + file->id();
file->download(filePath);
// Testing if the file exists
QDir downDir(m_DownloadPath);
if( downDir.exists(file->id()) )
{
MITK_INFO << "Download of " << file->id().toStdString() << " was completed!";
}
else
{
MITK_INFO << "Download of " << file->id().toStdString() << " failed!";
}
}
else
{
MITK_INFO << "Selection was not a file!";
}
}
}
int QmitkXnatEditor::ParentChecker(ctkXnatObject* child)
{
int sum;
if( child->parent() == NULL )
{
return 0;
}
else
{
sum = 1 + ParentChecker(child->parent());
}
return sum;
}
void QmitkXnatEditor::OnDataModelButtonClicked()
{
for(int i = m_ParentCount; i > 0; i--)
{
ToHigherLevel();
}
}
void QmitkXnatEditor::OnProjectButtonClicked()
{
for(int i = m_ParentCount-1; i > 0; i--)
{
ToHigherLevel();
}
}
void QmitkXnatEditor::OnSubjectButtonClicked()
{
for(int i = m_ParentCount-2; i > 0; i--)
{
ToHigherLevel();
}
}
void QmitkXnatEditor::OnExperimentButtonClicked()
{
for(int i = m_ParentCount-3; i > 0; i--)
{
ToHigherLevel();
}
}
void QmitkXnatEditor::OnKindOfDataButtonClicked()
{
for(int i = m_ParentCount-4; i > 0; i--)
{
ToHigherLevel();
}
}
void QmitkXnatEditor::OnSessionButtonClicked()
{
for(int i = m_ParentCount-5; i > 0; i--)
{
ToHigherLevel();
}
}
void QmitkXnatEditor::OnResourceButtonClicked()
{
for(int i = m_ParentCount-6; i > 0; i--)
{
ToHigherLevel();
}
}
+
+void QmitkXnatEditor::UpdateSession()
+{
+ GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemoveSelectionListener(m_SelectionListener);
+
+ if(m_Session != 0 && m_Session->isOpen())
+ {
+ m_ListModel->setRootObject(NULL);
+ m_Controls.treeView->reset();
+ }
+
+ // Get the XNAT Session from Activator
+ m_Session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->GetXnatSession();
+
+ if(m_Session != NULL)
+ {
+ m_Controls.labelInfo->setText("Current Position:");
+ m_Controls.labelInfo->setStyleSheet("QLabel { color: black; }");
+ m_Controls.buttonDownloadFile->setEnabled(true);
+ m_Controls.buttonDownloadResource->setEnabled(true);
+
+ connect( this->m_Session, SIGNAL(aboutToBeClosed()), this, SLOT(UpdateSession()) );
+
+ // Fill model and show in the GUI
+ QmitkXnatObjectEditorInput::Pointer xoPtr = QmitkXnatObjectEditorInput::New( m_Session->dataModel() );
+ berry::IEditorInput::Pointer editorInput( xoPtr );
+ this->SetInput(editorInput);
+ this->GetEditorInput().Cast<QmitkXnatObjectEditorInput>()->GetXnatObject()->fetch();
+ UpdateList();
+ }
+ else
+ {
+ m_Controls.labelInfo->setText("Please check the Preferences of the XNAT Connection.\nMaybe they are not ok. Close and reopen the tab.");
+ m_Controls.labelInfo->setStyleSheet("QLabel { color: red; }");
+ m_Controls.buttonDownloadFile->setEnabled(false);
+ m_Controls.buttonDownloadResource->setEnabled(false);
+ }
+
+ GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener(m_SelectionListener);
+}
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.h
index 9709681ffd..36cdebf47e 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.h
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.h
@@ -1,123 +1,126 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKXNATEDITOR_h
#define QMITKXNATEDITOR_h
#include <berryIReusableEditor.h>
#include <berryQtEditorPart.h>
#include <berryISelectionListener.h>
#include <mitkIDataStorageService.h>
#include <QmitkAbstractView.h>
#include "ui_QmitkXnatEditorControls.h"
#include "ctkXnatListModel.h"
#include "ctkXnatSession.h"
#include <ctkServiceTracker.h>
/*!
\brief QmitkXnatEditor
\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation.
\sa QmitkFunctionality
\ingroup ${plugin_target}_internal
*/
class QmitkXnatEditor : public berry::QtEditorPart, public berry::IReusableEditor
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
berryObjectMacro(QmitkXnatEditor)
QmitkXnatEditor();
~QmitkXnatEditor();
static const std::string EDITOR_ID;
void CreateQtPartControl(QWidget *parent);
void DoSave(/*IProgressMonitor monitor*/);
void DoSaveAs();
void Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input);
bool IsDirty() const;
bool IsSaveAsAllowed() const;
void SetInput(berry::IEditorInput::Pointer input);
/**
\brief Here the root object will be set and the view reset. Additionally the breadcrumbs will set visible.
*/
void UpdateList();
protected slots:
/**
\brief A resource folder will be downloaded to the chosen download path.
*/
void DownloadResource();
/**
\brief A file will be downloaded to the chosen download path.
*/
void DownloadFile();
/**
\brief Every time you activate a node in the list, the root item will be updated to a child of the previous parent.\
In exception of the node is a file. The file will be downloaded and loaded to the DataManager.
*/
void OnObjectActivated(const QModelIndex& index);
// Breadcrumb button slots
void OnDataModelButtonClicked();
void OnProjectButtonClicked();
void OnSubjectButtonClicked();
void OnExperimentButtonClicked();
void OnKindOfDataButtonClicked();
void OnSessionButtonClicked();
void OnResourceButtonClicked();
+ /// \brief Updates the ctkXnatSession and the user interface
+ void UpdateSession();
+
protected:
virtual void SetFocus();
Ui::QmitkXnatEditorControls m_Controls;
private:
int m_ParentCount;
QString m_DownloadPath;
ctkServiceTracker<mitk::IDataStorageService*> m_DataStorageServiceTracker;
void InternalFileDownload(const QModelIndex& index);
int ParentChecker(ctkXnatObject* child);
void ToHigherLevel();
ctkXnatListModel* m_ListModel;
ctkXnatSession* m_Session;
berry::ISelectionListener::Pointer m_SelectionListener;
void SelectionChanged(berry::IWorkbenchPart::Pointer sourcepart, berry::ISelection::ConstPointer selection);
};
#endif // QMITKXNATEDITOR_h
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui
index 5f13d15459..6fbb01a659 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui
@@ -1,460 +1,467 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkXnatEditorControls</class>
<widget class="QWidget" name="QmitkXnatEditorControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>823</width>
- <height>706</height>
+ <width>719</width>
+ <height>655</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkTemplate</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>xnat_icon.ico</normaloff>xnat_icon.ico</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QLabel" name="label">
+ <widget class="QLabel" name="labelInfo">
<property name="text">
<string>Current Position:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="breadcrumbDescriptionLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Server</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Project</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Subject</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Experiment</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Kind of Data</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Image Session</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_13">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_14">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Resource Folder</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="breadcrumbHorizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="buttonDataModel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Data Model</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelDataModelProject">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonProject">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Project</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelProjectSubject">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonSubject">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Subject</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSubjectExperiment">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonExperiment">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Experiment</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelExperimentKindOfData">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonKindOfData">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Kind of Data</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelKindOfDataSession">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonSession">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Session</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSessionResource">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonResource">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Resource</string>
</property>
</widget>
</item>
<item>
<spacer name="breadcrumbSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="treeView"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
- <widget class="QPushButton" name="buttonUpload">
- <property name="text">
- <string>(no function)</string>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </widget>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>250</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item>
<widget class="QPushButton" name="buttonDownloadResource">
<property name="text">
<string>Download Folder</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDownloadFile">
<property name="text">
<string>Download File</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
- <resources>
- <include location="images.qrc"/>
- </resources>
+ <resources/>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp
index 2cfaa010b6..575d78396e 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp
@@ -1,93 +1,83 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkXnatSessionManager.h"
#include "berryPlatform.h"
#include "berryIPreferences.h"
#include "mitkLogMacros.h"
#include <QMessageBox>
#include <QApplication>
#include "ctkXnatException.h"
QmitkXnatSessionManager::QmitkXnatSessionManager() :
m_Session(0)
{
m_PreferencesService = berry::Platform::GetServiceRegistry().
GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
- berry::IPreferencesService::Pointer prefService = m_PreferencesService.Lock();
- berry::IPreferences::Pointer nodeConnectionPref = prefService->GetSystemPreferences()->Node("/XnatConnection");
-
- QUrl url(QString::fromStdString(nodeConnectionPref->Get("Server Address", "")));
- url.setPort(QString::fromStdString(nodeConnectionPref->Get("Port", "")).toInt());
-
- ctkXnatLoginProfile profile;
- profile.setName("Default");
- profile.setServerUrl(url);
- profile.setUserName(QString::fromStdString(nodeConnectionPref->Get("Username", "")));
- profile.setPassword(QString::fromStdString(nodeConnectionPref->Get("Password", "")));
- profile.setDefault(true);
-
- m_Session = new ctkXnatSession(profile);
+ UpdateXnatSession();
}
QmitkXnatSessionManager::~QmitkXnatSessionManager()
{
delete m_Session;
}
ctkXnatSession* QmitkXnatSessionManager::GetXnatSession()
{
if(m_Session == NULL) return NULL;
if(!m_Session->isOpen())
{
try
{
m_Session->open();
}
catch(const ctkException& e)
{
MITK_ERROR << "Just look if your XNAT preferences are ok. Maybe the server is not running.\nTry to use 'Test Connection' funktionality.\n" << e.message().toStdString();
return NULL;
}
}
return m_Session;
}
void QmitkXnatSessionManager::UpdateXnatSession()
{
- m_Session->deleteLater();
+ if(m_Session != 0)
+ {
+ m_Session->deleteLater();
+ }
berry::IPreferencesService::Pointer prefService = m_PreferencesService.Lock();
berry::IPreferences::Pointer nodeConnectionPref = prefService->GetSystemPreferences()->Node("/XnatConnection");
QUrl url(QString::fromStdString(nodeConnectionPref->Get("Server Address", "")));
url.setPort(QString::fromStdString(nodeConnectionPref->Get("Port", "")).toInt());
ctkXnatLoginProfile profile;
profile.setName("Default");
profile.setServerUrl(url);
profile.setUserName(QString::fromStdString(nodeConnectionPref->Get("Username", "")));
profile.setPassword(QString::fromStdString(nodeConnectionPref->Get("Password", "")));
profile.setDefault(true);
m_Session = new ctkXnatSession(profile);
}
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp
index 5b307f4efd..9f3b718a7d 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp
@@ -1,124 +1,145 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkXnatTreeBrowserView.h"
// Qmitk
#include "QmitkXnatObjectEditorInput.h"
#include "QmitkXnatEditor.h"
#include "org_mitk_gui_qt_xnatinterface_Activator.h"
// Blueberry
#include <berryIWorkbenchPage.h>
// CTK XNAT Core
#include "ctkXnatFile.h"
const std::string QmitkXnatTreeBrowserView::VIEW_ID = "org.mitk.views.xnat.treebrowser";
QmitkXnatTreeBrowserView::QmitkXnatTreeBrowserView():
m_Session(0),
m_TreeModel(new ctkXnatTreeModel())
{
}
QmitkXnatTreeBrowserView::~QmitkXnatTreeBrowserView()
{
delete m_TreeModel;
}
void QmitkXnatTreeBrowserView::SetFocus()
{
}
void QmitkXnatTreeBrowserView::CreateQtPartControl( QWidget *parent )
{
- // Get the XNAT Session from Activator
- m_Session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->GetXnatSession();
-
- if(m_Session == 0)
- {
- m_Controls.labelError->setText("Please check the Preferences of XNAT. Maybe they are not ok.");
- m_Controls.labelError->setStyleSheet("QLabel { color: red; }");
- return;
- }
-
// Create GUI widgets from the Qt Designer's .ui file
m_Controls.setupUi( parent );
m_Controls.treeView->setModel(m_TreeModel);
m_Controls.treeView->header()->hide();
+ m_Controls.labelError->setText("Please check the Preferences of the XNAT Connection.\nMaybe they are not ok.");
+ m_Controls.labelError->setStyleSheet("QLabel { color: red; }");
m_SelectionProvider = new berry::QtSelectionProvider();
- m_SelectionProvider->SetItemSelectionModel(m_Controls.treeView->selectionModel());
this->SetSelectionProvider();
m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection);
- connect( m_Controls.treeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(OnActivatedNode(const QModelIndex&)) );
+ UpdateSession();
+
+ if(m_Session == 0)
+ {
+ m_Controls.labelError->show();
+ return;
+ }
+ else
+ {
+ m_Controls.labelError->hide();
+ }
- // Fill model and show in the GUI
- m_TreeModel->addDataModel(m_Session->dataModel());
- m_Controls.treeView->reset();
+ connect( m_Controls.treeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(OnActivatedNode(const QModelIndex&)) );
}
void QmitkXnatTreeBrowserView::OnActivatedNode(const QModelIndex& index)
{
if (!index.isValid()) return;
berry::IWorkbenchPage::Pointer page = GetSite()->GetPage();
QmitkXnatObjectEditorInput::Pointer oPtr = QmitkXnatObjectEditorInput::New( index.data(Qt::UserRole).value<ctkXnatObject*>() );
berry::IEditorInput::Pointer editorInput( oPtr );
berry::IEditorPart::Pointer reuseEditor = page->FindEditor(editorInput);
if(reuseEditor)
{
// Just set it activ
page->Activate(reuseEditor);
}
else
{
std::vector<berry::IEditorReference::Pointer> editors =
page->FindEditors(berry::IEditorInput::Pointer(0), QmitkXnatEditor::EDITOR_ID, berry::IWorkbenchPage::MATCH_ID);
if (editors.empty())
{
// No XnatEditor is currently open, create a new one
ctkXnatFile* file = dynamic_cast<ctkXnatFile*>(oPtr->GetXnatObject());
if(file != NULL)
{
// If a file is activated take the parent and open a new editor
QmitkXnatObjectEditorInput::Pointer oPtr2 = QmitkXnatObjectEditorInput::New( file->parent() );
berry::IEditorInput::Pointer editorInput2( oPtr2 );
page->OpenEditor(editorInput2, QmitkXnatEditor::EDITOR_ID);
}
else
{
page->OpenEditor(editorInput, QmitkXnatEditor::EDITOR_ID);
}
}
else
{
// Reuse an existing editor
reuseEditor = editors.front()->GetEditor(true);
page->ReuseEditor(reuseEditor.Cast<berry::IReusableEditor>(), editorInput);
page->Activate(reuseEditor);
}
}
}
void QmitkXnatTreeBrowserView::SetSelectionProvider()
{
GetSite()->SetSelectionProvider(m_SelectionProvider);
}
+
+void QmitkXnatTreeBrowserView::UpdateSession()
+{
+ if(m_Session != 0 && m_Session->isOpen())
+ {
+ m_TreeModel->removeDataModel(m_Session->dataModel());
+ m_Controls.treeView->reset();
+ }
+
+ // Get the XNAT Session from Activator
+ m_Session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->GetXnatSession();
+
+ if(m_Session != NULL)
+ {
+ connect( this->m_Session, SIGNAL(aboutToBeClosed()), this, SLOT(UpdateSession()) );
+
+ // Fill model and show in the GUI
+ m_TreeModel->addDataModel(m_Session->dataModel());
+ m_Controls.treeView->reset();
+ m_SelectionProvider->SetItemSelectionModel(m_Controls.treeView->selectionModel());
+ }
+}
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h
index 8c6de2b22c..d479113692 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h
@@ -1,76 +1,78 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKXNATTREEBROWSERVIEW_H
#define QMITKXNATTREEBROWSERVIEW_H
#include <berryQtSelectionProvider.h>
#include <QmitkAbstractView.h>
#include "ui_QmitkXnatTreeBrowserViewControls.h"
// ctkXnatCore
#include "ctkXnatSession.h"
// ctkXnatWidget
#include "ctkXnatTreeModel.h"
/*!
\brief QmitkXnatTreeBrowserView
\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation.
\sa QmitkFunctionality
\ingroup ${plugin_target}_internal
*/
class QmitkXnatTreeBrowserView : public QmitkAbstractView
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
QmitkXnatTreeBrowserView();
~QmitkXnatTreeBrowserView();
static const std::string VIEW_ID;
virtual void CreateQtPartControl(QWidget *parent);
- berry::QtSelectionProvider::Pointer m_SelectionProvider;
-
protected slots:
/// \brief Opens or reuses the xnat editor with the activated node as root item.
void OnActivatedNode(const QModelIndex& index);
+ /// \brief Updates the ctkXnatSession and the user interface
+ void UpdateSession();
+
protected:
virtual void SetFocus();
Ui::QmitkXnatTreeBrowserViewControls m_Controls;
private:
+ berry::QtSelectionProvider::Pointer m_SelectionProvider;
void SetSelectionProvider();
ctkXnatSession* m_Session;
ctkXnatTreeModel* m_TreeModel;
};
#endif // QMITKXNATTREEBROWSERVIEW_H
diff --git a/Plugins/org.mitk.simulation/files.cmake b/Plugins/org.mitk.simulation/files.cmake
index 43097f21ca..93637cdfb7 100644
--- a/Plugins/org.mitk.simulation/files.cmake
+++ b/Plugins/org.mitk.simulation/files.cmake
@@ -1,34 +1,31 @@
set(SRC_CPP_FILES
- mitkExportMitkVisitor.cpp
mitkGetSimulationPreferences.cpp
mitkMeshMitkLoader.cpp
)
set(INTERNAL_CPP_FILES
- mitkGetDataStorage.cpp
- mitkGetSimulationDataNode.cpp
org_mitk_simulation_Activator.cpp
)
set(MOC_H_FILES
src/internal/org_mitk_simulation_Activator.h
)
set(CACHED_RESOURCE_FILES
resources/SOFAIcon.png
)
set(QRC_FILES
resources/Simulation.qrc
)
set(CPP_FILES
)
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach()
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach()
diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetData.h b/Plugins/org.mitk.simulation/src/internal/mitkGetData.h
deleted file mode 100644
index 8d97cc482c..0000000000
--- a/Plugins/org.mitk.simulation/src/internal/mitkGetData.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#ifndef mitkGetData_h
-#define mitkGetData_h
-
-#include "mitkGetDataStorage.h"
-#include <mitkNodePredicateDataType.h>
-
-namespace mitk
-{
- template <class T>
- typename T::Pointer GetData(const std::string& name)
- {
- DataStorage::Pointer dataStorage = GetDataStorage();
-
- if (dataStorage.IsNull())
- return NULL;
-
- typename TNodePredicateDataType<T>::Pointer predicate = TNodePredicateDataType<T>::New();
- DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate);
-
- for (DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it)
- {
- DataNode::Pointer dataNode = it.Value();
-
- if (dataNode->GetName() == name)
- {
- typename T::Pointer data = static_cast<T*>(dataNode->GetData());
-
- if (data.IsNotNull())
- return data;
- }
- }
-
- return NULL;
- }
-}
-
-#endif
diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.cpp b/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.cpp
deleted file mode 100644
index 3a36bf5f87..0000000000
--- a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkGetDataStorage.h"
-#include "org_mitk_simulation_Activator.h"
-#include <mitkIDataStorageService.h>
-
-mitk::DataStorage::Pointer mitk::GetDataStorage()
-{
- IDataStorageService* dataStorageService = org_mitk_simulation_Activator::GetService<mitk::IDataStorageService>();
-
- if (dataStorageService != NULL)
- {
- IDataStorageReference::Pointer dataStorageReference = dataStorageService->GetDefaultDataStorage();
-
- if (dataStorageReference.IsNotNull())
- return dataStorageReference->GetDataStorage();
- }
-
- return NULL;
-}
diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.cpp b/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.cpp
deleted file mode 100644
index a4a37fa017..0000000000
--- a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-
-#include "mitkGetDataStorage.h"
-#include "mitkGetSimulationDataNode.h"
-#include <mitkNodePredicateDataType.h>
-#include <mitkSimulation.h>
-
-mitk::DataNode::Pointer mitk::GetSimulationDataNode(sofa::core::objectmodel::BaseNode::SPtr rootNode)
-{
- if (!rootNode)
- return NULL;
-
- DataStorage::Pointer dataStorage = GetDataStorage();
-
- if (dataStorage.IsNull())
- return NULL;
-
- TNodePredicateDataType<Simulation>::Pointer predicate = TNodePredicateDataType<Simulation>::New();
- DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate);
-
- for (DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it)
- {
- DataNode::Pointer dataNode = it.Value();
- Simulation::Pointer simulation = static_cast<Simulation*>(dataNode->GetData());
-
- if (simulation->GetRootNode() == rootNode)
- return dataNode;
- }
-
- return NULL;
-}
diff --git a/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp b/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp
index 1b4b799983..edfa68046e 100644
--- a/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp
+++ b/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp
@@ -1,140 +1,185 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#include "internal/mitkGetData.h"
+#include "internal/org_mitk_simulation_Activator.h"
#include "mitkMeshMitkLoader.h"
+#include <mitkDataStorage.h>
+#include <mitkIDataStorageService.h>
+#include <mitkNodePredicateDataType.h>
#include <mitkSurface.h>
#include <vtkCellArray.h>
#include <vtkLinearTransform.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkTransformPolyDataFilter.h>
+static mitk::DataStorage::Pointer GetDataStorage()
+{
+ mitk::IDataStorageService* dataStorageService = mitk::org_mitk_simulation_Activator::GetService<mitk::IDataStorageService>();
+
+ if (dataStorageService != NULL)
+ {
+ mitk::IDataStorageReference::Pointer dataStorageReference = dataStorageService->GetDefaultDataStorage();
+
+ if (dataStorageReference.IsNotNull())
+ return dataStorageReference->GetDataStorage();
+ }
+
+ return NULL;
+}
+
+template <class T>
+typename T::Pointer GetData(const std::string& name)
+{
+ mitk::DataStorage::Pointer dataStorage = GetDataStorage();
+
+ if (dataStorage.IsNull())
+ return NULL;
+
+ typename mitk::TNodePredicateDataType<T>::Pointer predicate = mitk::TNodePredicateDataType<T>::New();
+ mitk::DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate);
+
+ for (mitk::DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it)
+ {
+ mitk::DataNode::Pointer dataNode = it.Value();
+
+ if (dataNode->GetName() == name)
+ {
+ typename T::Pointer data = static_cast<T*>(dataNode->GetData());
+
+ if (data.IsNotNull())
+ return data;
+ }
+ }
+
+ return NULL;
+}
+
mitk::MeshMitkLoader::MeshMitkLoader()
{
this->addAlias(&m_filename, "dataNode");
this->addAlias(&m_filename, "surface");
}
mitk::MeshMitkLoader::~MeshMitkLoader()
{
}
bool mitk::MeshMitkLoader::canLoad()
{
Surface::Pointer surface = GetData<Surface>(m_filename.getValue());
if (surface.IsNull())
return false;
vtkPolyData* polyData = surface->GetVtkPolyData();
if (polyData == NULL || polyData->GetNumberOfCells() == 0)
return false;
return true;
}
bool mitk::MeshMitkLoader::load()
{
Surface::Pointer surface = GetData<Surface>(m_filename.getValue());
vtkPolyData* polyData = surface->GetVtkPolyData();
// vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
// transformFilter->SetTransform(surface->GetGeometry()->GetVtkTransform());
// transformFilter->SetInputConnection(polyData->GetProducerPort());
// transformFilter->Update();
// polyData = vtkPolyData::SafeDownCast(transformFilter->GetOutputDataObject(0));
sofa::helper::vector<sofa::defaulttype::Vector3>& positions = *this->positions.beginEdit();
sofa::helper::vector<Edge>& edges = *this->edges.beginEdit();
sofa::helper::vector<Triangle>& triangles = *this->triangles.beginEdit();
sofa::helper::vector<Quad>& quads = *this->quads.beginEdit();
sofa::helper::vector<sofa::helper::vector<unsigned int> > polygons = *this->polygons.beginEdit();
vtkPoints* points = polyData->GetPoints();
vtkIdType numPoints = points->GetNumberOfPoints();
double point[3];
for (vtkIdType i = 0; i < numPoints; ++i)
{
points->GetPoint(i, point);
positions.push_back(sofa::defaulttype::Vec3d(point[0], point[1], point[2]));
}
vtkCellArray* polys = polyData->GetPolys();
vtkIdType numPolys = polys->GetNumberOfCells();
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
Edge edge;
Triangle triangle;
Quad quad;
polys->InitTraversal();
while (polys->GetNextCell(poly) != 0)
{
switch (poly->GetNumberOfIds())
{
case 1:
break;
case 2:
edge[0] = poly->GetId(0);
edge[1] = poly->GetId(1);
edges.push_back(edge);
break;
case 3:
triangle[0] = poly->GetId(0);
triangle[1] = poly->GetId(1);
triangle[2] = poly->GetId(2);
triangles.push_back(triangle);
break;
case 4:
quad[0] = poly->GetId(0);
quad[1] = poly->GetId(1);
quad[2] = poly->GetId(2);
quad[3] = poly->GetId(3);
quads.push_back(quad);
break;
default:
sofa::helper::vector<unsigned int> polygon;
vtkIdType numIds = poly->GetNumberOfIds();
polygon.reserve(numIds);
for (vtkIdType i = 0; i < numIds; ++i)
polygon.push_back(poly->GetId(i));
polygons.push_back(polygon);
break;
}
}
this->positions.endEdit();
this->edges.endEdit();
this->triangles.endEdit();
this->quads.endEdit();
this->polygons.endEdit();
return true;
}
diff --git a/SuperBuild.cmake b/SuperBuild.cmake
index bf9eaecd94..c314290dca 100644
--- a/SuperBuild.cmake
+++ b/SuperBuild.cmake
@@ -1,454 +1,483 @@
#-----------------------------------------------------------------------------
# Convenient macro allowing to download a file
#-----------------------------------------------------------------------------
macro(downloadFile url dest)
file(DOWNLOAD ${url} ${dest} STATUS status)
list(GET status 0 error_code)
list(GET status 1 error_msg)
if(error_code)
message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}")
endif()
endmacro()
#-----------------------------------------------------------------------------
# MITK Prerequisites
#-----------------------------------------------------------------------------
if(UNIX AND NOT APPLE)
include(mitkFunctionCheckPackageHeader)
# Check for libxt-dev
mitkFunctionCheckPackageHeader(StringDefs.h libxt-dev /usr/include/X11/)
# Check for libtiff4-dev
mitkFunctionCheckPackageHeader(tiff.h libtiff4-dev)
# Check for libwrap0-dev
mitkFunctionCheckPackageHeader(tcpd.h libwrap0-dev)
endif()
#-----------------------------------------------------------------------------
# Qt options for external projects and MITK
#-----------------------------------------------------------------------------
if(MITK_USE_QT)
set(qt_project_args -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION})
else()
set(qt_project_args )
endif()
if(MITK_USE_Qt4)
list(APPEND qt_project_args
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} )
endif()
#-----------------------------------------------------------------------------
# ExternalProjects
#-----------------------------------------------------------------------------
set(external_projects
+ ZLIB
+ Python
+ Numpy
tinyxml
GLUT
ANN
CppUnit
GLEW
VTK
ACVD
GDCM
- CableSwig
OpenCV
Poco
ITK
Boost
DCMTK
CTK
SOFA
MITKData
Qwt
+ PCRE
+ Swig
+ SimpleITK
)
# Qxt supports Qt5. We need to also support it in QxtCMakeLists.txt
#if(MITK_USE_Qt4)
list(APPEND external_projects Qxt)
#endif()
# These are "hard" dependencies and always set to ON
set(MITK_USE_tinyxml 1)
set(MITK_USE_ANN 1)
set(MITK_USE_GLEW 1)
set(MITK_USE_GDCM 1)
set(MITK_USE_ITK 1)
set(MITK_USE_VTK 1)
# Semi-hard dependencies, enabled by user-controlled variables
-set(MITK_USE_CableSwig ${MITK_USE_Python})
if(MITK_USE_QT)
set(MITK_USE_Qwt 1)
#if(MITK_USE_Qt4)
set(MITK_USE_Qxt 1) #TODO: Check how Qxt builds with Qt 5
#endif()
endif()
if(MITK_USE_SOFA)
set(MITK_USE_GLUT 1)
endif()
+if(NOT MITK_USE_SYSTEM_PYTHON)
+ set(MITK_USE_ZLIB 1)
+endif()
+
+if(MITK_USE_SimpleITK OR MITK_USE_Python)
+ set(MITK_USE_SWIG 1)
+ if(UNIX)
+ set(MITK_USE_PCRE 1)
+ endif()
+endif()
+
# A list of "nice" external projects, playing well together with CMake
set(nice_external_projects ${external_projects})
list(REMOVE_ITEM nice_external_projects Boost)
foreach(proj ${nice_external_projects})
if(MITK_USE_${proj})
set(EXTERNAL_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory")
mark_as_advanced(EXTERNAL_${proj}_DIR)
if(EXTERNAL_${proj}_DIR)
set(${proj}_DIR ${EXTERNAL_${proj}_DIR})
endif()
endif()
endforeach()
if(MITK_USE_Boost)
set(EXTERNAL_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory")
mark_as_advanced(EXTERNAL_BOOST_ROOT)
if(EXTERNAL_BOOST_ROOT)
set(BOOST_ROOT ${EXTERNAL_BOOST_ROOT})
endif()
endif()
# Setup file for setting custom ctest vars
configure_file(
CMake/SuperbuildCTestCustom.cmake.in
${MITK_BINARY_DIR}/CTestCustom.cmake
@ONLY
)
if(BUILD_TESTING)
set(EXTERNAL_MITK_DATA_DIR "${MITK_DATA_DIR}" CACHE PATH "Path to the MITK data directory")
mark_as_advanced(EXTERNAL_MITK_DATA_DIR)
if(EXTERNAL_MITK_DATA_DIR)
set(MITK_DATA_DIR ${EXTERNAL_MITK_DATA_DIR})
endif()
endif()
# Look for git early on, if needed
if((BUILD_TESTING AND NOT EXTERNAL_MITK_DATA_DIR) OR
(MITK_USE_CTK AND NOT EXTERNAL_CTK_DIR))
find_package(Git REQUIRED)
endif()
#-----------------------------------------------------------------------------
# External project settings
#-----------------------------------------------------------------------------
include(ExternalProject)
set(ep_base "${CMAKE_BINARY_DIR}/CMakeExternals")
set_property(DIRECTORY PROPERTY EP_BASE ${ep_base})
set(ep_install_dir ${ep_base}/Install)
#set(ep_build_dir ${ep_base}/Build)
set(ep_source_dir ${ep_base}/Source)
#set(ep_parallelism_level)
set(ep_build_shared_libs ON)
set(ep_build_testing OFF)
if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL)
set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL http://mitk.org/download/thirdparty)
endif()
# Compute -G arg for configuring external projects with the same CMake generator:
if(CMAKE_EXTRA_GENERATOR)
set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
else()
set(gen "${CMAKE_GENERATOR}")
endif()
# Use this value where semi-colons are needed in ep_add args:
set(sep "^^")
##
if(MSVC_VERSION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /MP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /MP")
endif()
set(ep_common_args
-DBUILD_TESTING:BOOL=${ep_build_testing}
-DCMAKE_INSTALL_PREFIX:PATH=${ep_install_dir}
-DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH}
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}
-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}
#debug flags
-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG}
-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG}
#release flags
-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}
-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}
#relwithdebinfo
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO}
#link flags
-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS}
-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS}
-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS}
)
# Pass the CMAKE_OSX variables to external projects
if(APPLE)
set(MAC_OSX_ARCHITECTURE_ARGS
-DCMAKE_OSX_ARCHITECTURES:PATH=${CMAKE_OSX_ARCHITECTURES}
-DCMAKE_OSX_DEPLOYMENT_TARGET:PATH=${CMAKE_OSX_DEPLOYMENT_TARGET}
-DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
)
set(ep_common_args
${MAC_OSX_ARCHITECTURE_ARGS}
${ep_common_args}
)
endif()
# Include external projects
foreach(p ${external_projects})
include(CMakeExternals/${p}.cmake)
endforeach()
#-----------------------------------------------------------------------------
# Set superbuild boolean args
#-----------------------------------------------------------------------------
set(mitk_cmake_boolean_args
BUILD_SHARED_LIBS
WITH_COVERAGE
BUILD_TESTING
MITK_USE_QT
MITK_BUILD_ALL_PLUGINS
MITK_BUILD_ALL_APPS
MITK_BUILD_TUTORIAL # Deprecated. Use MITK_BUILD_EXAMPLES instead
MITK_BUILD_EXAMPLES
MITK_USE_ACVD
MITK_USE_CppUnit
MITK_USE_GLEW
MITK_USE_Boost
MITK_USE_SYSTEM_Boost
MITK_USE_BLUEBERRY
MITK_USE_CTK
MITK_USE_DCMTK
MITK_USE_OpenCV
MITK_USE_Poco
MITK_USE_SOFA
MITK_USE_Python
MITK_USE_OpenCL
MITK_ENABLE_PIC_READER
)
#-----------------------------------------------------------------------------
# Create the final variable containing superbuild boolean args
#-----------------------------------------------------------------------------
set(mitk_superbuild_boolean_args)
foreach(mitk_cmake_arg ${mitk_cmake_boolean_args})
list(APPEND mitk_superbuild_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}})
endforeach()
if(MITK_BUILD_ALL_PLUGINS)
list(APPEND mitk_superbuild_boolean_args -DBLUEBERRY_BUILD_ALL_PLUGINS:BOOL=ON)
endif()
#-----------------------------------------------------------------------------
# MITK Utilities
#-----------------------------------------------------------------------------
set(proj MITK-Utilities)
ExternalProject_Add(${proj}
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
DEPENDS
# Mandatory dependencies
${tinyxml_DEPENDS}
${ANN_DEPENDS}
${VTK_DEPENDS}
${ITK_DEPENDS}
# Optionnal dependencies
${ACVD_DEPENDS}
${CppUnit_DEPENDS}
${GLUT_DEPENDS}
${GLEW_DEPENDS}
${Boost_DEPENDS}
${CTK_DEPENDS}
${DCMTK_DEPENDS}
${OpenCV_DEPENDS}
${Poco_DEPENDS}
${SOFA_DEPENDS}
${MITK-Data_DEPENDS}
${Qwt_DEPENDS}
${Qxt_DEPENDS}
+ ${SimpleITK_DEPENDS}
+ ${Numpy_DEPENDS}
)
#-----------------------------------------------------------------------------
# Additional MITK CXX/C Flags
#-----------------------------------------------------------------------------
set(MITK_ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags for MITK")
set(MITK_ADDITIONAL_C_FLAGS_RELEASE "" CACHE STRING "Additional Release C Flags for MITK")
set(MITK_ADDITIONAL_C_FLAGS_DEBUG "" CACHE STRING "Additional Debug C Flags for MITK")
mark_as_advanced(MITK_ADDITIONAL_C_FLAGS MITK_ADDITIONAL_C_FLAGS_DEBUG MITK_ADDITIONAL_C_FLAGS_RELEASE)
set(MITK_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags for MITK")
set(MITK_ADDITIONAL_CXX_FLAGS_RELEASE "" CACHE STRING "Additional Release CXX Flags for MITK")
set(MITK_ADDITIONAL_CXX_FLAGS_DEBUG "" CACHE STRING "Additional Debug CXX Flags for MITK")
mark_as_advanced(MITK_ADDITIONAL_CXX_FLAGS MITK_ADDITIONAL_CXX_FLAGS_DEBUG MITK_ADDITIONAL_CXX_FLAGS_RELEASE)
set(MITK_ADDITIONAL_EXE_LINKER_FLAGS "" CACHE STRING "Additional exe linker flags for MITK")
set(MITK_ADDITIONAL_SHARED_LINKER_FLAGS "" CACHE STRING "Additional shared linker flags for MITK")
set(MITK_ADDITIONAL_MODULE_LINKER_FLAGS "" CACHE STRING "Additional module linker flags for MITK")
mark_as_advanced(MITK_ADDITIONAL_EXE_LINKER_FLAGS MITK_ADDITIONAL_SHARED_LINKER_FLAGS MITK_ADDITIONAL_MODULE_LINKER_FLAGS)
#-----------------------------------------------------------------------------
# MITK Configure
#-----------------------------------------------------------------------------
if(MITK_INITIAL_CACHE_FILE)
set(mitk_initial_cache_arg -C "${MITK_INITIAL_CACHE_FILE}")
endif()
set(mitk_optional_cache_args )
foreach(type RUNTIME ARCHIVE LIBRARY)
if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY)
list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY})
endif()
endforeach()
# Optional python variables
if(MITK_USE_Python)
+ list(APPEND mitk_optional_cache_args
+ -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
+ -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
+ -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
+ -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
+ -DMITK_USE_SYSTEM_PYTHON:BOOL=${MITK_USE_SYSTEM_PYTHON}
+ -DMITK_BUILD_org.mitk.gui.qt.python:BOOL=ON
+ )
+ if( NOT MITK_USE_SYSTEM_PYTHON )
list(APPEND mitk_optional_cache_args
- -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
- -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
- -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
- -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} )
+ # Folders are needed to create an installer
+ -DPython_DIR:PATH=${Python_DIR}
+ -DNumpy_DIR:PATH=${Numpy_DIR}
+ )
+ endif()
endif()
set(proj MITK-Configure)
ExternalProject_Add(${proj}
LIST_SEPARATOR ^^
DOWNLOAD_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_CACHE_ARGS
# --------------- Build options ----------------
-DBUILD_TESTING:BOOL=${ep_build_testing}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/MITK-build/install
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
# --------------- Compile options ----------------
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${MITK_ADDITIONAL_C_FLAGS}"
"-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_ADDITIONAL_CXX_FLAGS}"
# debug flags
"-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} ${MITK_ADDITIONAL_CXX_FLAGS_DEBUG}"
"-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} ${MITK_ADDITIONAL_C_FLAGS_DEBUG}"
# release flags
"-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} ${MITK_ADDITIONAL_CXX_FLAGS_RELEASE}"
"-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} ${MITK_ADDITIONAL_C_FLAGS_RELEASE}"
# relwithdebinfo
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO}
# link flags
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} ${MITK_ADDITIONAL_EXE_LINKER_FLAGS}"
"-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} ${MITK_ADDITIONAL_SHARED_LINKER_FLAGS}"
"-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ${MITK_ADDITIONAL_MODULE_LINKER_FLAGS}"
# Output directories
-DMITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}
-DMITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}
-DMITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
# ------------- Boolean build options --------------
${mitk_superbuild_boolean_args}
${mitk_optional_cache_args}
-DMITK_USE_SUPERBUILD:BOOL=OFF
-DMITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION}
-DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS}
# ----------------- Miscellaneous ---------------
-DMITK_CTEST_SCRIPT_MODE:STRING=${MITK_CTEST_SCRIPT_MODE}
-DMITK_SUPERBUILD_BINARY_DIR:PATH=${MITK_BINARY_DIR}
-DMITK_MODULES_TO_BUILD:INTERNAL=${MITK_MODULES_TO_BUILD}
${qt_project_args}
-DMITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES}
-DMITK_ACCESSBYITK_FLOATING_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES}
-DMITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES}
-DMITK_ACCESSBYITK_VECTOR_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}
-DMITK_ACCESSBYITK_DIMENSIONS:STRING=${MITK_ACCESSBYITK_DIMENSIONS}
# --------------- External project dirs ---------------
-DMITK_KWSTYLE_EXECUTABLE:FILEPATH=${MITK_KWSTYLE_EXECUTABLE}
-DCTK_DIR:PATH=${CTK_DIR}
-DDCMTK_DIR:PATH=${DCMTK_DIR}
-Dtinyxml_DIR:PATH=${tinyxml_DIR}
-DGLUT_DIR:PATH=${GLUT_DIR}
-DGLEW_DIR:PATH=${GLEW_DIR}
-DANN_DIR:PATH=${ANN_DIR}
-DCppUnit_DIR:PATH=${CppUnit_DIR}
-DVTK_DIR:PATH=${VTK_DIR} # FindVTK expects VTK_DIR
-DITK_DIR:PATH=${ITK_DIR} # FindITK expects ITK_DIR
-DACVD_DIR:PATH=${ACVD_DIR}
-DOpenCV_DIR:PATH=${OpenCV_DIR}
-DPoco_DIR:PATH=${Poco_DIR}
-DSOFA_DIR:PATH=${SOFA_DIR}
-DGDCM_DIR:PATH=${GDCM_DIR}
-DBOOST_ROOT:PATH=${BOOST_ROOT}
-DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES}
-DMITK_DATA_DIR:PATH=${MITK_DATA_DIR}
-DQwt_DIR:PATH=${Qwt_DIR}
-DQxt_DIR:PATH=${Qxt_DIR}
+ -DSimpleITK_DIR:PATH=${SimpleITK_DIR}
+ -DNumpy_DIR:PATH=${Numpy_DIR}
CMAKE_ARGS
${mitk_initial_cache_arg}
${MAC_OSX_ARCHITECTURE_ARGS}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build
BUILD_COMMAND ""
INSTALL_COMMAND ""
DEPENDS
MITK-Utilities
)
#-----------------------------------------------------------------------------
# MITK
#-----------------------------------------------------------------------------
if(CMAKE_GENERATOR MATCHES ".*Makefiles.*")
set(mitk_build_cmd "$(MAKE)")
else()
set(mitk_build_cmd ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/MITK-build --config ${CMAKE_CFG_INTDIR})
endif()
if(NOT DEFINED SUPERBUILD_EXCLUDE_MITKBUILD_TARGET OR NOT SUPERBUILD_EXCLUDE_MITKBUILD_TARGET)
set(MITKBUILD_TARGET_ALL_OPTION "ALL")
else()
set(MITKBUILD_TARGET_ALL_OPTION "")
endif()
add_custom_target(MITK-build ${MITKBUILD_TARGET_ALL_OPTION}
COMMAND ${mitk_build_cmd}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build
DEPENDS MITK-Configure
)
#-----------------------------------------------------------------------------
# Custom target allowing to drive the build of the MITK project itself
#-----------------------------------------------------------------------------
add_custom_target(MITK
COMMAND ${mitk_build_cmd}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build
)
diff --git a/Utilities/KWStyle/MITKFiles.txt.in b/Utilities/KWStyle/MITKFiles.txt.in
index dc85c3f6fc..5f36529ac1 100644
--- a/Utilities/KWStyle/MITKFiles.txt.in
+++ b/Utilities/KWStyle/MITKFiles.txt.in
@@ -1,346 +1,326 @@
@MITK_SOURCE_DIR@/Core/Code/*.cpp
@MITK_SOURCE_DIR@/Core/Code/*.h
@MITK_SOURCE_DIR@/Core/Code/Algorithms/*.cpp
@MITK_SOURCE_DIR@/Core/Code/Algorithms/*.h
@MITK_SOURCE_DIR@/Core/Code/Interactions/*.cpp
@MITK_SOURCE_DIR@/Core/Code/Interactions/*.h
@MITK_SOURCE_DIR@/Core/Code/DataManagement/*.cpp
@MITK_SOURCE_DIR@/Core/Code/DataManagement/*.h
@MITK_SOURCE_DIR@/Core/Code/Controllers/*.cpp
@MITK_SOURCE_DIR@/Core/Code/Controllers/*.h
@MITK_SOURCE_DIR@/Core/Code/Rendering/*.cpp
@MITK_SOURCE_DIR@/Core/Code/Rendering/*.h
@MITK_SOURCE_DIR@/Core/Code/IO/*.cpp
@MITK_SOURCE_DIR@/Core/Code/IO/*.h
@MITK_SOURCE_DIR@/Core/Code/Testing/*.cpp
@MITK_SOURCE_DIR@/Core/Code/Testing/*.h
@MITK_SOURCE_DIR@/Core/Code/Testing/Data/*.cpp
@MITK_SOURCE_DIR@/Core/Code/Testing/Data/*.h
@MITK_SOURCE_DIR@/CoreUI/Qmitk/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Qmitk/*.h
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/*.cpp
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/*.h
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/org.mitk.gui.qt.common.tests/*.cpp
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/org.mitk.gui.qt.common.tests/*.h
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/org.mitk.gui.qt.common.tests/src/*.cpp
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/org.mitk.gui.qt.common.tests/src/*.h
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/org.mitk.gui.qt.common.tests/src/api/*.cpp
@MITK_SOURCE_DIR@/CoreUI/BundleTesting/org.mitk.gui.qt.common.tests/src/api/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.core.services/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.core.services/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.core.services/src/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.core.services/src/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.core.services/src/internal/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.core.services/src/internal/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.application/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.application/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.application/src/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.application/src/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.application/src/internal/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.application/src/internal/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.common/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.common/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.common/src/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.common/src/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.common/src/internal/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.qt.common/src/internal/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.common/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.common/*.h
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.common/src/*.cpp
@MITK_SOURCE_DIR@/CoreUI/Bundles/org.mitk.gui.common/src/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/Algorithms/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/Algorithms/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/Interactions/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/Interactions/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/DataManagement/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/DataManagement/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/DataManagement/mitkDataStorage/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/DataManagement/mitkDataStorage/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/Controllers/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/Controllers/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/Rendering/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/Rendering/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/IO/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/IO/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/Testing/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/Testing/*.h
-@MITK_SOURCE_DIR@/Modules/MitkExt/Testing/Data/*.cpp
-@MITK_SOURCE_DIR@/Modules/MitkExt/Testing/Data/*.h
-@MITK_SOURCE_DIR@/Modules/RigidRegistration/*.cpp
+MITK_SOURCE_DIR@/Modules/RigidRegistration/*.cpp
@MITK_SOURCE_DIR@/Modules/RigidRegistration/*.h
@MITK_SOURCE_DIR@/Modules/RigidRegistration/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/RigidRegistration/Testing/*.h
@MITK_SOURCE_DIR@/Modules/IGTUI/*.cpp
@MITK_SOURCE_DIR@/Modules/IGTUI/*.h
@MITK_SOURCE_DIR@/Modules/IGTUI/Qmitk/*.cpp
@MITK_SOURCE_DIR@/Modules/IGTUI/Qmitk/*.h
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/*.cpp
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/*.h
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/RigidRegistrationTransforms/*.cpp
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/RigidRegistrationTransforms/*.h
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/RigidRegistrationOptimizer/*.cpp
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/RigidRegistrationOptimizer/*.h
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/RigidRegistrationMetrics/*.cpp
@MITK_SOURCE_DIR@/Modules/RigidRegistrationUI/RigidRegistrationMetrics/*.h
@MITK_SOURCE_DIR@/Modules/GPGPU/*.cpp
@MITK_SOURCE_DIR@/Modules/GPGPU/*.h
@MITK_SOURCE_DIR@/Modules/DeformableRegistrationUI/*.cpp
@MITK_SOURCE_DIR@/Modules/DeformableRegistrationUI/*.h
@MITK_SOURCE_DIR@/Modules/FLApplications/*.cpp
@MITK_SOURCE_DIR@/Modules/FLApplications/*.h
@MITK_SOURCE_DIR@/Modules/FLApplications/MITKFLExample/*.cpp
@MITK_SOURCE_DIR@/Modules/FLApplications/MITKFLExample/*.h
@MITK_SOURCE_DIR@/Modules/QmitkExt/*.cpp
@MITK_SOURCE_DIR@/Modules/QmitkExt/*.h
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkPropertyObservers/*.cpp
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkPropertyObservers/*.h
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkFunctionalityComponents/*.cpp
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkFunctionalityComponents/*.h
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkAboutDialog/*.cpp
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkAboutDialog/*.h
@MITK_SOURCE_DIR@/Modules/QmitkExt/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/QmitkExt/Testing/*.h
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkApplicationBase/*.cpp
@MITK_SOURCE_DIR@/Modules/QmitkExt/QmitkApplicationBase/*.h
@MITK_SOURCE_DIR@/Modules/SceneSerialization/*.cpp
@MITK_SOURCE_DIR@/Modules/SceneSerialization/*.h
@MITK_SOURCE_DIR@/Modules/SceneSerialization/BasePropertySerializer/*.cpp
@MITK_SOURCE_DIR@/Modules/SceneSerialization/BasePropertySerializer/*.h
@MITK_SOURCE_DIR@/Modules/SceneSerialization/BaseDataSerializer/*.cpp
@MITK_SOURCE_DIR@/Modules/SceneSerialization/BaseDataSerializer/*.h
@MITK_SOURCE_DIR@/Modules/SceneSerialization/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/SceneSerialization/Testing/*.h
@MITK_SOURCE_DIR@/Modules/SceneSerialization/BasePropertyDeserializer/*.cpp
@MITK_SOURCE_DIR@/Modules/SceneSerialization/BasePropertyDeserializer/*.h
@MITK_SOURCE_DIR@/Modules/FLmitk/*.cpp
@MITK_SOURCE_DIR@/Modules/FLmitk/*.h
@MITK_SOURCE_DIR@/Modules/OpenCVVideoSupport/*.cpp
@MITK_SOURCE_DIR@/Modules/OpenCVVideoSupport/*.h
@MITK_SOURCE_DIR@/Modules/OpenCVVideoSupport/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/OpenCVVideoSupport/Testing/*.h
@MITK_SOURCE_DIR@/Modules/DeformableRegistration/*.cpp
@MITK_SOURCE_DIR@/Modules/DeformableRegistration/*.h
@MITK_SOURCE_DIR@/Modules/DeformableRegistration/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/DeformableRegistration/Testing/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Reconstruction/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Reconstruction/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Algorithms/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Algorithms/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Tractography/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Tractography/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Rendering/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Rendering/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/DicomImport/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/DicomImport/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/Testing/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/DiffusionWeightedImages/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/DiffusionWeightedImages/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/TensorImages/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/TensorImages/*.h
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/QBallImages/*.cpp
@MITK_SOURCE_DIR@/Modules/DiffusionImaging/IODataStructures/QBallImages/*.h
@MITK_SOURCE_DIR@/Modules/IGT/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/*.h
@MITK_SOURCE_DIR@/Modules/IGT/IGTTrackingDevices/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/IGTTrackingDevices/*.h
@MITK_SOURCE_DIR@/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/*.h
@MITK_SOURCE_DIR@/Modules/IGT/IGTFilters/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/IGTFilters/*.h
@MITK_SOURCE_DIR@/Modules/IGT/IGTToolManagement/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/IGTToolManagement/*.h
@MITK_SOURCE_DIR@/Modules/IGT/IGTTutorial/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/IGTTutorial/*.h
@MITK_SOURCE_DIR@/Modules/IGT/Testing/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/Testing/*.h
@MITK_SOURCE_DIR@/Modules/IGT/Testing/Data/*.cpp
@MITK_SOURCE_DIR@/Modules/IGT/Testing/Data/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.viewinitialization/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.viewinitialization/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.viewinitialization/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.viewinitialization/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.viewinitialization/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.viewinitialization/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointbasedregistration/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointbasedregistration/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointbasedregistration/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointbasedregistration/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointbasedregistration/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointbasedregistration/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.rigidregistration/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.rigidregistration/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.rigidregistration/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.rigidregistration/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.rigidregistration/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.rigidregistration/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.regiongrowing/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.regiongrowing/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.regiongrowing/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.regiongrowing/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.regiongrowing/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.regiongrowing/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagestatistics/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagestatistics/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagestatistics/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagestatistics/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagestatistics/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagestatistics/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagecropper/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagecropper/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagecropper/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagecropper/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagecropper/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagecropper/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.segmentation/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.segmentation/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.segmentation/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.segmentation/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagenavigator/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagenavigator/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagenavigator/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagenavigator/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagenavigator/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.imagenavigator/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.jobs/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.jobs/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.jobs/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.jobs/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.jobs/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.jobs/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simplemeasurement/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simplemeasurement/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simplemeasurement/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simplemeasurement/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simplemeasurement/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simplemeasurement/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.extapplication/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.extapplication/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.extapplication/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.extapplication/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.extapplication/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.extapplication/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.ext/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.ext/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.ext/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.ext/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.ext/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.ext/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.moviemaker/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.moviemaker/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.moviemaker/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.moviemaker/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.moviemaker/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.moviemaker/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.ext/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.ext/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.ext/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.ext/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.ext/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.core.ext/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simpleexample/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simpleexample/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simpleexample/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simpleexample/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simpleexample/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.simpleexample/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttoolpairnavigation/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttoolpairnavigation/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttoolpairnavigation/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttoolpairnavigation/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttoolpairnavigation/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttoolpairnavigation/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.deformableregistration/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.deformableregistration/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.deformableregistration/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.deformableregistration/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.deformableregistration/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.deformableregistration/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumevisualization/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumevisualization/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumevisualization/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumevisualization/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumevisualization/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumevisualization/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttutorial/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttutorial/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttutorial/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttutorial/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttutorial/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igttutorial/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.isosurface/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.isosurface/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.isosurface/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.isosurface/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.isosurface/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.isosurface/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumetry/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumetry/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumetry/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumetry/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumetry/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.volumetry/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.colourimageprocessing/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.colourimageprocessing/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.colourimageprocessing/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.colourimageprocessing/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.colourimageprocessing/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.colourimageprocessing/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igtexample/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igtexample/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igtexample/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igtexample/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igtexample/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.igtexample/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointsetinteraction/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointsetinteraction/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointsetinteraction/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointsetinteraction/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointsetinteraction/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.pointsetinteraction/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.basicimageprocessing/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.basicimageprocessing/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.basicimageprocessing/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.basicimageprocessing/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.basicimageprocessing/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.basicimageprocessing/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.datamanager/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.datamanager/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.datamanager/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.datamanager/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.datamanager/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.datamanager/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.materialeditor/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.materialeditor/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.measurement/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.measurement/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.measurement/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.measurement/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.measurement/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.gui.qt.measurement/src/internal/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.diffusionimaging/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.diffusionimaging/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.diffusionimaging/src/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.diffusionimaging/src/*.h
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.diffusionimaging/src/internal/*.cpp
@MITK_SOURCE_DIR@/Modules/Bundles/org.mitk.diffusionimaging/src/internal/*.h
@MITK_SOURCE_DIR@/Applications/mitkWorkbench/*.cpp
@MITK_SOURCE_DIR@/Applications/mitkWorkbench/*.h
@MITK_SOURCE_DIR@/Applications/Tutorial/*.cpp
@MITK_SOURCE_DIR@/Applications/Tutorial/*.h
@MITK_SOURCE_DIR@/Applications/CoreApp/*.cpp
@MITK_SOURCE_DIR@/Applications/CoreApp/*.h
diff --git a/Utilities/mbilog/mbilog.cpp b/Utilities/mbilog/mbilog.cpp
index 95f8ae5fce..e212a032fd 100644
--- a/Utilities/mbilog/mbilog.cpp
+++ b/Utilities/mbilog/mbilog.cpp
@@ -1,69 +1,89 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <list>
+#include <set>
#include "mbilog.h"
static std::list<mbilog::BackendBase*> backends;
+static std::set<mbilog::OutputType> disabledBackendTypes;
namespace mbilog {
static const std::string NA_STRING = "n/a";
}
void mbilog::RegisterBackend(mbilog::BackendBase* backend)
{
backends.push_back(backend);
}
void mbilog::UnregisterBackend(mbilog::BackendBase* backend)
{
backends.remove(backend);
}
void mbilog::DistributeToBackends(mbilog::LogMessage &l)
{
//Crop Message
{
std::string::size_type i = l.message.find_last_not_of(" \t\f\v\n\r");
l.message = (i != std::string::npos) ? l.message.substr(0, i+1) : "";
}
//create dummy backend if there is no backend registered (so we have an output anyway)
static mbilog::BackendCout* dummyBackend = NULL;
if(backends.empty() && (dummyBackend == NULL))
{
dummyBackend = new mbilog::BackendCout();
dummyBackend->SetFull(false);
RegisterBackend(dummyBackend);
}
else if((backends.size()>1) && (dummyBackend != NULL))
{
//if there was added another backend remove the dummy backend and delete it
UnregisterBackend(dummyBackend);
delete dummyBackend;
dummyBackend = NULL;
}
//iterate through all registered images and call the ProcessMessage() methods of the backends
std::list<mbilog::BackendBase*>::iterator i;
for(i = backends.begin(); i != backends.end(); i++)
- (*i)->ProcessMessage(l);
+ {
+ if (IsBackendEnabled((*i)->GetOutputType()))
+ (*i)->ProcessMessage(l);
+ }
+}
+
+void mbilog::EnableBackends(OutputType type)
+{
+ disabledBackendTypes.erase(type);
+}
+
+void mbilog::DisableBackends(OutputType type)
+{
+ disabledBackendTypes.insert(type);
+}
+
+bool mbilog::IsBackendEnabled(OutputType type)
+{
+ return disabledBackendTypes.find(type) == disabledBackendTypes.end();
}
diff --git a/Utilities/mbilog/mbilog.h b/Utilities/mbilog/mbilog.h
index f814d6715f..ef5c64d6c1 100644
--- a/Utilities/mbilog/mbilog.h
+++ b/Utilities/mbilog/mbilog.h
@@ -1,232 +1,246 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MBILOG_H
#define _MBILOG_H
#include <sstream>
#include "mbilogExports.h"
#include "mbilogBackendBase.h"
#include "mbilogBackendCout.h"
#include "mbilogLogMessage.h"
#include "mbilogLoggingTypes.h"
#include "mbilogConfig.h"
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4251)
#endif
namespace mbilog {
/** \brief Registeres a backend to the mbi logging mechanism. If a backend is registered here, all mbilog messages
* are relayed to this backend through the method ProcessMessage. If no backend is registered the default
* backend is used.
*/
void MBILOG_DLL_API RegisterBackend(BackendBase* backend);
/** \brief Unregisters a backend.
*/
void MBILOG_DLL_API UnregisterBackend(BackendBase* backend);
/** \brief Distributes the given message to all registered backends. Should only be called by objects
* of the class pseudo stream.
*/
void MBILOG_DLL_API DistributeToBackends(LogMessage &l);
+
+ /**
+ * Enable the output of a backend.
+ **/
+ void MBILOG_DLL_API EnableBackends(OutputType type);
+ /**
+ * Disable the output of a backend.
+ **/
+ void MBILOG_DLL_API DisableBackends(OutputType type);
+ /**
+ * Checks wether the output of this backend is enabled.
+ **/
+ bool MBILOG_DLL_API IsBackendEnabled(OutputType type);
+
/**
* \brief An object of this class simulates a std::cout stream. This means messages can be added by
* using the bit shift operator (<<). Should only be used by the macros defined in the file mbilog.h
* \ingroup mbilog
*/
class MBILOG_DLL_API PseudoStream {
protected:
bool disabled;
LogMessage msg;
std::stringstream ss;
public:
inline PseudoStream( int level,
const char* filePath,
int lineNumber,
const char* functionName)
: disabled(false)
, msg(LogMessage(level,filePath,lineNumber,functionName))
, ss(std::stringstream::out)
{
}
/** \brief The message which is stored in the member ss is written to the backend. */
inline ~PseudoStream()
{
if(!disabled)
{
msg.message = ss.str();
msg.moduleName = MBILOG_MODULENAME;
DistributeToBackends(msg);
}
}
/** \brief Definition of the bit shift operator for this class.*/
template <class T> inline PseudoStream& operator<<(const T& data)
{
if(!disabled)
{
std::locale C("C");
std::locale originalLocale = ss.getloc();
ss.imbue(C);
ss << data;
ss.imbue( originalLocale );
}
return *this;
}
/** \brief Definition of the bit shift operator for this class (for non const data).*/
template <class T> inline PseudoStream& operator<<(T& data)
{
if(!disabled)
{
std::locale C("C");
std::locale originalLocale = ss.getloc();
ss.imbue(C);
ss << data;
ss.imbue( originalLocale );
}
return *this;
}
/** \brief Definition of the bit shift operator for this class (for functions).*/
inline PseudoStream& operator<<(std::ostream& (*func)(std::ostream&))
{
if(!disabled)
{
std::locale C("C");
std::locale originalLocale = ss.getloc();
ss.imbue(C);
ss << func;
ss.imbue( originalLocale );
}
return *this;
}
/** \brief Sets the category of this PseudoStream object. If there already is a category it is appended, seperated by a dot.*/
inline PseudoStream& operator()(const char *category)
{
if(!disabled)
{
if(msg.category.length())
msg.category+=".";
msg.category+=category;
}
return *this;
}
/** \brief Enables/disables the PseudoStream. If set to false parsing and output is suppressed. */
inline PseudoStream& operator()(bool enabled)
{
disabled|=!enabled;
return *this;
}
};
/**
* \brief An object of this class simulates a std::cout stream but does nothing. This class is for dummy objects, bit shift
* operators are availiable but doing nothing. Should only be used by the macros defined in the file mbilog.h
* \ingroup mbilog
*/
class MBILOG_DLL_API NullStream {
public:
template <class T> inline NullStream& operator<<(const T& /*data*/)
{
return *this;
}
template <class T> inline NullStream& operator<<(T& /*data*/)
{
return *this;
}
inline NullStream& operator<<(std::ostream& (*)(std::ostream&))
{
return *this;
}
inline NullStream& operator()(const char *)
{
return *this;
}
inline NullStream& operator()(bool)
{
return *this;
}
};
// /** \brief templated backend: one can define a class and a method to create a new backend. */
// template<typename T>
// struct DelegateBackend : public BackendBase
// {
//
// typedef void(T::*Callback)(const mbilog::LogMessage&);
//
// DelegateBackend(T* obj, Callback callback) : m_Obj(obj), m_Callback(callback)
// {
// }
//
// void ProcessMessage(const mbilog::LogMessage& msg)
// {
// m_Obj->*m_Callback(msg);
// }
//
// private:
//
// T* m_Obj;
// Callback m_Callback;
// };
}
#ifdef _MSC_VER
# pragma warning(pop)
#endif
/** \brief Macros for different message levels. Creates an instance of class PseudoStream with the corresponding message level.
* Other parameters are the name of the source file, line of the source code and function name which are generated
* by the compiler.
*/
#define MBI_INFO mbilog::PseudoStream(mbilog::Info,__FILE__,__LINE__,__FUNCTION__)
#define MBI_WARN mbilog::PseudoStream(mbilog::Warn,__FILE__,__LINE__,__FUNCTION__)
#define MBI_ERROR mbilog::PseudoStream(mbilog::Error,__FILE__,__LINE__,__FUNCTION__)
#define MBI_FATAL mbilog::PseudoStream(mbilog::Fatal,__FILE__,__LINE__,__FUNCTION__)
/** \brief Macro for the debug messages. The messages are disabled if the cmake variable MBILOG_ENABLE_DEBUG is false. */
#ifdef MBILOG_ENABLE_DEBUG
#define MBI_DEBUG mbilog::PseudoStream(mbilog::Debug,__FILE__,__LINE__,__FUNCTION__)
#else
#define MBI_DEBUG true ? mbilog::NullStream() : mbilog::NullStream() //this is magic by markus
#endif
#endif
diff --git a/Utilities/mbilog/mbilogBackendBase.h b/Utilities/mbilog/mbilogBackendBase.h
index 514e732fd2..793238cdf0 100644
--- a/Utilities/mbilog/mbilogBackendBase.h
+++ b/Utilities/mbilog/mbilogBackendBase.h
@@ -1,50 +1,65 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _mbilogBackendBase_H
#define _mbilogBackendBase_H
#include "mbilogExports.h"
#include "mbilogLogMessage.h"
namespace mbilog{
-
+/**
+ * This enum defines the type of the output of a backend.
+ * Console: output generated to the console
+ * File: output generated to a file
+ * Other: all other kinds of output
+ */
+enum MBILOG_DLL_API OutputType{
+ Console = 0,
+ File,
+ Other = 100
+};
/**
* \brief This class is an interface for logging backends that can be registered in the mbi logging mechanism.
*
* \ingroup mbilog
*/
class MBILOG_DLL_API BackendBase
{
public:
virtual ~BackendBase();
/**
* \brief This method is called by the mbi logging mechanism if the object is registered in
* the mbi logging mechanism and a logging message is emitted.
*
* \param logMessage Logging message which was emitted.
*
*/
virtual void ProcessMessage(const mbilog::LogMessage& logMessage)=0;
+
+ /**
+ * @return The type of this backend.
+ */
+ virtual OutputType GetOutputType() const =0;
};
}
#endif
diff --git a/Utilities/mbilog/mbilogBackendCout.cpp b/Utilities/mbilog/mbilogBackendCout.cpp
index 6f4095328b..1babce68d9 100644
--- a/Utilities/mbilog/mbilogBackendCout.cpp
+++ b/Utilities/mbilog/mbilogBackendCout.cpp
@@ -1,50 +1,54 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <list>
#include <ctime>
#include <iomanip>
#include "mbilogBackendCout.h"
mbilog::BackendCout::BackendCout()
{
m_useFullOutput=false;
}
mbilog::BackendCout::~BackendCout()
{
}
void mbilog::BackendCout::SetFull(bool full)
{
m_useFullOutput = full;
}
void mbilog::BackendCout::ProcessMessage(const mbilog::LogMessage& l)
{
if(m_useFullOutput)
FormatFull(l);
else
FormatSmart(l);
}
+mbilog::OutputType mbilog::BackendCout::GetOutputType() const
+{
+ return mbilog::Console;
+}
diff --git a/Utilities/mbilog/mbilogBackendCout.h b/Utilities/mbilog/mbilogBackendCout.h
index 0822a7ae43..081e2a7e67 100644
--- a/Utilities/mbilog/mbilogBackendCout.h
+++ b/Utilities/mbilog/mbilogBackendCout.h
@@ -1,66 +1,68 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _mbilogBackendCout_H
#define _mbilogBackendCout_H
#include <iostream>
#include "mbilogExports.h"
#include "mbilogTextBackendBase.h"
#include "mbilogLogMessage.h"
#include "mbilogLoggingTypes.h"
namespace mbilog{
/**
* \brief Default backend of the mbi logging mechanism. This backend is used if no other backend is registered.
* The backend formats the logging messages to a normal string and writes them to std::cout.
* \ingroup mbilog
*/
class MBILOG_DLL_API BackendCout : public TextBackendBase
{
public:
BackendCout();
virtual ~BackendCout();
/** \brief This method is called by the mbi logging mechanism if the object is registered in
* the mbi logging mechanism and a logging message is emitted. The method formats the
* logging messages to a normal string (depending on formatting mode) and writes it to std::cout.
*
* \param logMessage Logging message.
*/
virtual void ProcessMessage(const mbilog::LogMessage &l );
/** \brief Sets the formatting mode. If true long messages will be displayed. Default is false (short/smart messages).
* Long messages provide all informations and are also capable to be postproccessed (e.g. in a web viewer).
*/
void SetFull(bool full);
+ virtual OutputType GetOutputType() const;
+
private:
/** \brief The formatting mode of this backend. True is full/long message formatting mode. False is short/smart
* message formatting mode
*/
bool m_useFullOutput;
};
}
#endif
diff --git a/Utilities/qtsingleapplication/CMakeLists.txt b/Utilities/qtsingleapplication/CMakeLists.txt
index b044f6758a..112bc6292d 100644
--- a/Utilities/qtsingleapplication/CMakeLists.txt
+++ b/Utilities/qtsingleapplication/CMakeLists.txt
@@ -1,5 +1,5 @@
mitk_create_module(
- PACKAGE_DEPENDS Qt4|QtNetwork+QtGui
+ PACKAGE_DEPENDS Qt4|QtNetwork+QtGui Qt5|Core+Widgets+Network
FORCE_STATIC
NO_INIT
)
diff --git a/Utilities/qtsingleapplication/qthandlenewappinstance.cpp b/Utilities/qtsingleapplication/qthandlenewappinstance.cpp
index 0e554b0a62..b01e755d12 100644
--- a/Utilities/qtsingleapplication/qthandlenewappinstance.cpp
+++ b/Utilities/qtsingleapplication/qthandlenewappinstance.cpp
@@ -1,118 +1,147 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "qthandlenewappinstance.h"
#include "qtsingleapplication.h"
+
+#if QT_VERSION < 0x050000
+
#include <QDir>
#include <stdlib.h> // mkdtemp
#ifdef Q_OS_UNIX
#include <unistd.h>
#endif
#ifdef Q_OS_WIN
#include <windows.h>
//#include <private/qfsfileengine_p.h>
#endif
bool createTemporaryDir(QString& path)
{
QString baseName = QCoreApplication::applicationName();
if (baseName.isEmpty())
{
baseName = QLatin1String("mitk_temp");
}
QString templateName = QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX");
bool success = false;
#ifdef Q_OS_WIN
QString buffer = templateName;
// Windows' mktemp believes 26 temp files per process ought to be enough for everyone (!)
// Let's add a few random chars then, before the XXXXXX template.
for (int i = 0 ; i < 4 ; ++i)
buffer += QChar((qrand() & 0xffff) % (26) + 'A');
if (!buffer.endsWith(QLatin1String("XXXXXX")))
buffer += QLatin1String("XXXXXX");
//QFileSystemEntry baseEntry(buffer);
//QFileSystemEntry::NativePath basePath = baseEntry.nativeFilePath();
QString basePath = QDir::toNativeSeparators(buffer);
wchar_t* array = (wchar_t*)basePath.utf16();
if (_wmktemp(array) && ::CreateDirectoryW(array, 0))
{
success = true;
//QFileSystemEntry entry(QString::fromWCharArray(array), QFileSystemEntry::FromNativePath());
//path = entry.filePath();
path = QDir::fromNativeSeparators(QString::fromUtf16((const ushort*)array));
}
#else
QByteArray buffer = QFile::encodeName(templateName);
if (!buffer.endsWith("XXXXXX"))
buffer += "XXXXXX";
if (mkdtemp(buffer.data())) { // modifies buffer
success = true;
path = QFile::decodeName(buffer.constData());
}
#endif
return success;
}
+#else
+
+#include <QTemporaryDir>
+
+bool createTemporaryDir(QString& path)
+{
+ QString baseName = QCoreApplication::applicationName();
+ if (baseName.isEmpty())
+ {
+ baseName = QLatin1String("mitk_temp");
+ }
+
+ QString templateName = QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX");
+ QTemporaryDir tmpDir(templateName);
+ tmpDir.setAutoRemove(false);
+
+ if (tmpDir.isValid())
+ {
+ path = tmpDir.path();
+ return true;
+ }
+ return false;
+}
+
+#endif
+
QString handleNewAppInstance(QtSingleApplication* singleApp, int argc, char** argv, const QString& newInstanceArg)
{
if (singleApp->isRunning())
{
QStringList args;
bool newInstance = false;
for (int i = 0; i < argc; ++i)
{
args << argv[i];
if (args.back().endsWith(newInstanceArg))
{
newInstance = true;
}
}
if (newInstance)
{
QString path;
if (!createTemporaryDir(path))
{
qCritical("Could not create temporary storage path for new application instance.");
exit(EXIT_FAILURE);
}
qWarning("Forcing new application instance. The application data will be written to a temporary directory.");
return path;
}
else
{
QByteArray ba;
QDataStream msg(&ba, QIODevice::WriteOnly);
msg << QString("$cmdLineArgs"); // This message contains command line arguments
msg << args;
if(singleApp->sendMessage(ba))
{
exit(EXIT_SUCCESS);
}
else
{
qCritical("The running application seems to be frozen.");
exit(EXIT_FAILURE);
}
}
}
return QString();
}
diff --git a/Utilities/qtsingleapplication/qthandlenewappinstance.h b/Utilities/qtsingleapplication/qthandlenewappinstance.h
index 9256881f90..4aa55aa402 100644
--- a/Utilities/qtsingleapplication/qthandlenewappinstance.h
+++ b/Utilities/qtsingleapplication/qthandlenewappinstance.h
@@ -1,29 +1,29 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center,
+Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QTHANDLENEWAPPINSTANCE_H
#define QTHANDLENEWAPPINSTANCE_H
-#include <QtCore/QString>
+#include <QString>
class QtSingleApplication;
bool createTemporaryDir(QString& path);
QString handleNewAppInstance(QtSingleApplication* singleApp, int argc, char** argv, const QString& newInstanceArg);
#endif // QTHANDLENEWAPPINSTANCE_H
diff --git a/Utilities/qtsingleapplication/qtlocalpeer.cpp b/Utilities/qtsingleapplication/qtlocalpeer.cpp
index a1fb92e09c..dd0143bb17 100644
--- a/Utilities/qtsingleapplication/qtlocalpeer.cpp
+++ b/Utilities/qtsingleapplication/qtlocalpeer.cpp
@@ -1,198 +1,201 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#include "qtlocalpeer.h"
-#include <QtCore/QCoreApplication>
-#include <QtCore/QTime>
+#include <QCoreApplication>
+#include <QTime>
#if defined(Q_OS_WIN)
-#include <QtCore/QLibrary>
-#include <QtCore/qt_windows.h>
+#include <QLibrary>
+#include <qt_windows.h>
typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
static PProcessIdToSessionId pProcessIdToSessionId = 0;
#endif
#if defined(Q_OS_UNIX)
+#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#endif
namespace QtLP_Private {
#include "qtlockedfile.cpp"
#if defined(Q_OS_WIN)
#include "qtlockedfile_win.cpp"
#else
#include "qtlockedfile_unix.cpp"
#endif
}
const char* QtLocalPeer::ack = "ack";
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
: QObject(parent), id(appId)
{
QString prefix = id;
if (id.isEmpty()) {
id = QCoreApplication::applicationFilePath();
#if defined(Q_OS_WIN)
id = id.toLower();
#endif
prefix = id.section(QLatin1Char('/'), -1);
}
prefix.remove(QRegExp("[^a-zA-Z]"));
prefix.truncate(6);
QByteArray idc = id.toUtf8();
quint16 idNum = qChecksum(idc.constData(), idc.size());
socketName = QLatin1String("qtsingleapp-") + prefix
+ QLatin1Char('-') + QString::number(idNum, 16);
#if defined(Q_OS_WIN)
if (!pProcessIdToSessionId) {
QLibrary lib("kernel32");
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
}
if (pProcessIdToSessionId) {
DWORD sessionId = 0;
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
socketName += QLatin1Char('-') + QString::number(sessionId, 16);
}
#else
- socketName += QLatin1Char('-') + QString::number(getuid(), 16);
+ socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
#endif
server = new QLocalServer(this);
QString lockName = QDir(QDir::tempPath()).absolutePath()
+ QLatin1Char('/') + socketName
+ QLatin1String("-lockfile");
lockFile.setFileName(lockName);
lockFile.open(QIODevice::ReadWrite);
}
bool QtLocalPeer::isClient()
{
if (lockFile.isLocked())
return false;
if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
return true;
bool res = server->listen(socketName);
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
// ### Workaround
if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
res = server->listen(socketName);
}
#endif
if (!res)
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
return false;
}
bool QtLocalPeer::sendMessage(const QByteArray &message, int timeout)
{
if (!isClient())
return false;
QLocalSocket socket;
bool connOk = false;
for(int i = 0; i < 2; i++) {
// Try twice, in case the other instance is just starting up
socket.connectToServer(socketName);
connOk = socket.waitForConnected(timeout/2);
if (connOk || i)
break;
int ms = 250;
#if defined(Q_OS_WIN)
Sleep(DWORD(ms));
#else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
}
if (!connOk)
return false;
QDataStream ds(&socket);
ds.writeBytes(message.constData(), message.size());
bool res = socket.waitForBytesWritten(timeout);
if (res) {
res &= socket.waitForReadyRead(timeout); // wait for ack
if (res)
res &= (socket.read(qstrlen(ack)) == ack);
}
return res;
}
void QtLocalPeer::receiveConnection()
{
QLocalSocket* socket = server->nextPendingConnection();
if (!socket)
return;
while (socket->bytesAvailable() < (int)sizeof(quint32))
socket->waitForReadyRead();
QDataStream ds(socket);
QByteArray uMsg;
quint32 remaining;
ds >> remaining;
uMsg.resize(remaining);
int got = 0;
char* uMsgBuf = uMsg.data();
do {
got = ds.readRawData(uMsgBuf, remaining);
remaining -= got;
uMsgBuf += got;
} while (remaining && got >= 0 && socket->waitForReadyRead(2000));
if (got < 0) {
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
delete socket;
return;
}
socket->write(ack, qstrlen(ack));
socket->waitForBytesWritten(1000);
+ socket->waitForDisconnected(1000); // make sure client reads ack
delete socket;
emit messageReceived(uMsg); //### (might take a long time to return)
}
diff --git a/Utilities/qtsingleapplication/qtlocalpeer.h b/Utilities/qtsingleapplication/qtlocalpeer.h
index 937fa0e4df..07374d970c 100644
--- a/Utilities/qtsingleapplication/qtlocalpeer.h
+++ b/Utilities/qtsingleapplication/qtlocalpeer.h
@@ -1,76 +1,77 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#ifndef QTLOCALPEER_H
#define QTLOCALPEER_H
-#include <QtNetwork/QLocalServer>
-#include <QtNetwork/QLocalSocket>
-#include <QtCore/QDir>
+#include <QLocalServer>
+#include <QLocalSocket>
+#include <QDir>
#include "qtlockedfile.h"
class QtLocalPeer : public QObject
{
Q_OBJECT
public:
QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
bool isClient();
bool sendMessage(const QByteArray &message, int timeout);
QString applicationId() const
{ return id; }
Q_SIGNALS:
void messageReceived(const QByteArray &message);
protected Q_SLOTS:
void receiveConnection();
protected:
QString id;
QString socketName;
QLocalServer* server;
QtLP_Private::QtLockedFile lockFile;
private:
static const char* ack;
};
#endif // QTLOCALPEER_H
diff --git a/Utilities/qtsingleapplication/qtlockedfile.cpp b/Utilities/qtsingleapplication/qtlockedfile.cpp
index cda4368ab0..c142a863a9 100644
--- a/Utilities/qtsingleapplication/qtlockedfile.cpp
+++ b/Utilities/qtsingleapplication/qtlockedfile.cpp
@@ -1,193 +1,193 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#include "qtlockedfile.h"
-
/*!
\class QtLockedFile
\brief The QtLockedFile class extends QFile with advisory locking
functions.
A file may be locked in read or write mode. Multiple instances of
\e QtLockedFile, created in multiple processes running on the same
machine, may have a file locked in read mode. Exactly one instance
may have it locked in write mode. A read and a write lock cannot
exist simultaneously on the same file.
The file locks are advisory. This means that nothing prevents
another process from manipulating a locked file using QFile or
file system functions offered by the OS. Serialization is only
guaranteed if all processes that access the file use
QLockedFile. Also, while holding a lock on a file, a process
must not open the same file again (through any API), or locks
can be unexpectedly lost.
The lock provided by an instance of \e QtLockedFile is released
whenever the program terminates. This is true even when the
program crashes and no destructors are called.
*/
/*! \enum QtLockedFile::LockMode
This enum describes the available lock modes.
\value ReadLock A read lock.
\value WriteLock A write lock.
\value NoLock Neither a read lock nor a write lock.
*/
/*!
Constructs an unlocked \e QtLockedFile object. This constructor
behaves in the same way as \e QFile::QFile().
\sa QFile::QFile()
*/
QtLockedFile::QtLockedFile()
: QFile()
{
#ifdef Q_OS_WIN
wmutex = 0;
rmutex = 0;
#endif
m_lock_mode = NoLock;
}
/*!
Constructs an unlocked QtLockedFile object with file \a name. This
constructor behaves in the same way as \e QFile::QFile(const
QString&).
\sa QFile::QFile()
*/
QtLockedFile::QtLockedFile(const QString &name)
: QFile(name)
{
#ifdef Q_OS_WIN
wmutex = 0;
rmutex = 0;
#endif
m_lock_mode = NoLock;
}
/*!
Opens the file in OpenMode \a mode.
This is identical to QFile::open(), with the one exception that the
Truncate mode flag is disallowed. Truncation would conflict with the
advisory file locking, since the file would be modified before the
write lock is obtained. If truncation is required, use resize(0)
after obtaining the write lock.
Returns true if successful; otherwise false.
\sa QFile::open(), QFile::resize()
*/
bool QtLockedFile::open(OpenMode mode)
{
if (mode & QIODevice::Truncate) {
qWarning("QtLockedFile::open(): Truncate mode not allowed.");
return false;
}
return QFile::open(mode);
}
/*!
Returns \e true if this object has a in read or write lock;
otherwise returns \e false.
\sa lockMode()
*/
bool QtLockedFile::isLocked() const
{
return m_lock_mode != NoLock;
}
/*!
Returns the type of lock currently held by this object, or \e
QtLockedFile::NoLock.
\sa isLocked()
*/
QtLockedFile::LockMode QtLockedFile::lockMode() const
{
return m_lock_mode;
}
/*!
\fn bool QtLockedFile::lock(LockMode mode, bool block = true)
Obtains a lock of type \a mode. The file must be opened before it
can be locked.
If \a block is true, this function will block until the lock is
aquired. If \a block is false, this function returns \e false
immediately if the lock cannot be aquired.
If this object already has a lock of type \a mode, this function
returns \e true immediately. If this object has a lock of a
different type than \a mode, the lock is first released and then a
new lock is obtained.
This function returns \e true if, after it executes, the file is
locked by this object, and \e false otherwise.
\sa unlock(), isLocked(), lockMode()
*/
/*!
\fn bool QtLockedFile::unlock()
Releases a lock.
If the object has no lock, this function returns immediately.
This function returns \e true if, after it executes, the file is
not locked by this object, and \e false otherwise.
\sa lock(), isLocked(), lockMode()
*/
/*!
\fn QtLockedFile::~QtLockedFile()
Destroys the \e QtLockedFile object. If any locks were held, they
are released.
*/
diff --git a/Utilities/qtsingleapplication/qtlockedfile.h b/Utilities/qtsingleapplication/qtlockedfile.h
index 07a42bffb1..84c18e5c9a 100644
--- a/Utilities/qtsingleapplication/qtlockedfile.h
+++ b/Utilities/qtsingleapplication/qtlockedfile.h
@@ -1,96 +1,97 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#ifndef QTLOCKEDFILE_H
#define QTLOCKEDFILE_H
-#include <QtCore/QFile>
+#include <QFile>
#ifdef Q_OS_WIN
-#include <QtCore/QVector>
+#include <QVector>
#endif
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
# define QT_QTLOCKEDFILE_EXPORT
# elif defined(QT_QTLOCKEDFILE_IMPORT)
# if defined(QT_QTLOCKEDFILE_EXPORT)
# undef QT_QTLOCKEDFILE_EXPORT
# endif
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
# elif defined(QT_QTLOCKEDFILE_EXPORT)
# undef QT_QTLOCKEDFILE_EXPORT
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
# endif
#else
# define QT_QTLOCKEDFILE_EXPORT
#endif
namespace QtLP_Private {
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
{
public:
enum LockMode { NoLock = 0, ReadLock, WriteLock };
QtLockedFile();
QtLockedFile(const QString &name);
~QtLockedFile();
bool open(OpenMode mode);
bool lock(LockMode mode, bool block = true);
bool unlock();
bool isLocked() const;
LockMode lockMode() const;
private:
#ifdef Q_OS_WIN
Qt::HANDLE wmutex;
Qt::HANDLE rmutex;
QVector<Qt::HANDLE> rmutexes;
QString mutexname;
Qt::HANDLE getMutexHandle(int idx, bool doCreate);
bool waitMutex(Qt::HANDLE mutex, bool doBlock);
#endif
LockMode m_lock_mode;
};
}
#endif
diff --git a/Utilities/qtsingleapplication/qtlockedfile_unix.cpp b/Utilities/qtsingleapplication/qtlockedfile_unix.cpp
index 0af4f8bf6f..c49747b12f 100644
--- a/Utilities/qtsingleapplication/qtlockedfile_unix.cpp
+++ b/Utilities/qtsingleapplication/qtlockedfile_unix.cpp
@@ -1,115 +1,115 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "qtlockedfile.h"
-
bool QtLockedFile::lock(LockMode mode, bool block)
{
if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened");
return false;
}
-
+
if (mode == NoLock)
return unlock();
-
+
if (mode == m_lock_mode)
return true;
if (m_lock_mode != NoLock)
unlock();
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
int cmd = block ? F_SETLKW : F_SETLK;
int ret = fcntl(handle(), cmd, &fl);
-
+
if (ret == -1) {
if (errno != EINTR && errno != EAGAIN)
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
}
-
+
m_lock_mode = mode;
return true;
}
bool QtLockedFile::unlock()
{
if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened");
return false;
}
if (!isLocked())
return true;
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_UNLCK;
int ret = fcntl(handle(), F_SETLKW, &fl);
-
+
if (ret == -1) {
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
}
-
+
m_lock_mode = NoLock;
return true;
}
QtLockedFile::~QtLockedFile()
{
if (isOpen())
unlock();
}
diff --git a/Utilities/qtsingleapplication/qtlockedfile_win.cpp b/Utilities/qtsingleapplication/qtlockedfile_win.cpp
index f6da1f02d4..a44620b3b3 100644
--- a/Utilities/qtsingleapplication/qtlockedfile_win.cpp
+++ b/Utilities/qtsingleapplication/qtlockedfile_win.cpp
@@ -1,206 +1,211 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#include "qtlockedfile.h"
#include <qt_windows.h>
-#include <QtCore/QFileInfo>
+#include <QFileInfo>
#define MUTEX_PREFIX "QtLockedFile mutex "
// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS
#define MAX_READERS MAXIMUM_WAIT_OBJECTS
+#if QT_VERSION >= 0x050000
+#define QT_WA(unicode, ansi) unicode
+#endif
+
Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
{
if (mutexname.isEmpty()) {
QFileInfo fi(*this);
mutexname = QString::fromLatin1(MUTEX_PREFIX)
+ fi.absoluteFilePath().toLower();
}
QString mname(mutexname);
if (idx >= 0)
mname += QString::number(idx);
Qt::HANDLE mutex;
if (doCreate) {
- QT_WA( { mutex = CreateMutexW(NULL, FALSE, (LPCWSTR)mname.utf16()); },
+ QT_WA( { mutex = CreateMutexW(NULL, FALSE, reinterpret_cast<LPCWSTR>(mname.utf16())); },
{ mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) {
qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
return 0;
}
}
else {
- QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (LPCWSTR)mname.utf16()); },
+ QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, reinterpret_cast<LPCWSTR>(mname.utf16())); },
{ mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) {
if (GetLastError() != ERROR_FILE_NOT_FOUND)
qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
return 0;
}
}
return mutex;
}
bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
{
Q_ASSERT(mutex);
DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
switch (res) {
case WAIT_OBJECT_0:
case WAIT_ABANDONED:
return true;
break;
case WAIT_TIMEOUT:
break;
default:
qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
}
return false;
}
bool QtLockedFile::lock(LockMode mode, bool block)
{
if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened");
return false;
}
if (mode == NoLock)
return unlock();
if (mode == m_lock_mode)
return true;
if (m_lock_mode != NoLock)
unlock();
if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
return false;
if (!waitMutex(wmutex, block))
return false;
if (mode == ReadLock) {
int idx = 0;
for (; idx < MAX_READERS; idx++) {
rmutex = getMutexHandle(idx, false);
if (!rmutex || waitMutex(rmutex, false))
break;
CloseHandle(rmutex);
}
bool ok = true;
if (idx >= MAX_READERS) {
qWarning("QtLockedFile::lock(): too many readers");
rmutex = 0;
ok = false;
}
else if (!rmutex) {
rmutex = getMutexHandle(idx, true);
if (!rmutex || !waitMutex(rmutex, false))
ok = false;
}
if (!ok && rmutex) {
CloseHandle(rmutex);
rmutex = 0;
}
ReleaseMutex(wmutex);
if (!ok)
return false;
}
else {
Q_ASSERT(rmutexes.isEmpty());
for (int i = 0; i < MAX_READERS; i++) {
Qt::HANDLE mutex = getMutexHandle(i, false);
if (mutex)
rmutexes.append(mutex);
}
if (rmutexes.size()) {
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
TRUE, block ? INFINITE : 0);
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
if (res != WAIT_TIMEOUT)
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
unlock();
return false;
}
}
}
m_lock_mode = mode;
return true;
}
bool QtLockedFile::unlock()
{
if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened");
return false;
}
if (!isLocked())
return true;
if (m_lock_mode == ReadLock) {
ReleaseMutex(rmutex);
CloseHandle(rmutex);
rmutex = 0;
}
else {
foreach(Qt::HANDLE mutex, rmutexes) {
ReleaseMutex(mutex);
CloseHandle(mutex);
}
rmutexes.clear();
ReleaseMutex(wmutex);
}
m_lock_mode = QtLockedFile::NoLock;
return true;
}
QtLockedFile::~QtLockedFile()
{
if (isOpen())
unlock();
if (wmutex)
CloseHandle(wmutex);
}
diff --git a/Utilities/qtsingleapplication/qtsingleapplication.cpp b/Utilities/qtsingleapplication/qtsingleapplication.cpp
index ee764cc7bf..b2f2058c85 100644
--- a/Utilities/qtsingleapplication/qtsingleapplication.cpp
+++ b/Utilities/qtsingleapplication/qtsingleapplication.cpp
@@ -1,344 +1,347 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#include "qtsingleapplication.h"
#include "qtlocalpeer.h"
-#include <QtGui/QWidget>
+#include <QWidget>
/*!
\class QtSingleApplication qtsingleapplication.h
\brief The QtSingleApplication class provides an API to detect and
communicate with running instances of an application.
This class allows you to create applications where only one
instance should be running at a time. I.e., if the user tries to
launch another instance, the already running instance will be
activated instead. Another usecase is a client-server system,
where the first started instance will assume the role of server,
and the later instances will act as clients of that server.
By default, the full path of the executable file is used to
determine whether two processes are instances of the same
application. You can also provide an explicit identifier string
that will be compared instead.
The application should create the QtSingleApplication object early
in the startup phase, and call isRunning() to find out if another
instance of this application is already running. If isRunning()
returns false, it means that no other instance is running, and
this instance has assumed the role as the running instance. In
this case, the application should continue with the initialization
of the application user interface before entering the event loop
with exec(), as normal.
The messageReceived() signal will be emitted when the running
application receives messages from another instance of the same
application. When a message is received it might be helpful to the
user to raise the application so that it becomes visible. To
facilitate this, QtSingleApplication provides the
setActivationWindow() function and the activateWindow() slot.
If isRunning() returns true, another instance is already
running. It may be alerted to the fact that another instance has
started by using the sendMessage() function. Also data such as
startup parameters (e.g. the name of the file the user wanted this
new instance to open) can be passed to the running instance with
this function. Then, the application should terminate (or enter
client mode).
If isRunning() returns true, but sendMessage() fails, that is an
indication that the running instance is frozen.
Here's an example that shows how to convert an existing
application to use QtSingleApplication. It is very simple and does
not make use of all QtSingleApplication's functionality (see the
examples for that).
\code
// Original
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyMainWidget mmw;
mmw.show();
return app.exec();
}
// Single instance
int main(int argc, char **argv)
{
QtSingleApplication app(argc, argv);
if (app.isRunning())
return !app.sendMessage(someDataString);
MyMainWidget mmw;
app.setActivationWindow(&mmw);
mmw.show();
return app.exec();
}
\endcode
Once this QtSingleApplication instance is destroyed (normally when
the process exits or crashes), when the user next attempts to run the
application this instance will not, of course, be encountered. The
next instance to call isRunning() or sendMessage() will assume the
role as the new running instance.
For console (non-GUI) applications, QtSingleCoreApplication may be
used instead of this class, to avoid the dependency on the QtGui
library.
\sa QtSingleCoreApplication
*/
void QtSingleApplication::sysInit(const QString &appId)
{
actWin = 0;
peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
}
/*!
Creates a QtSingleApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc, \a
argv, and \a GUIenabled are passed on to the QAppliation constructor.
If you are creating a console application (i.e. setting \a
GUIenabled to false), you may consider using
QtSingleCoreApplication instead.
*/
QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
: QApplication(argc, argv, GUIenabled)
{
sysInit();
}
/*!
Creates a QtSingleApplication object with the application
identifier \a appId. \a argc and \a argv are passed on to the
QAppliation constructor.
*/
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
: QApplication(argc, argv)
{
sysInit(appId);
}
+#if QT_VERSION < 0x050000
/*!
Creates a QtSingleApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc, \a
argv, and \a type are passed on to the QAppliation constructor.
*/
QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
: QApplication(argc, argv, type)
{
sysInit();
}
-#if defined(Q_WS_X11)
+# if defined(Q_WS_X11)
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
and \a cmap are passed on to the QApplication constructor.
*/
QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, visual, cmap)
{
sysInit();
}
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
argv, \a visual, and \a cmap are passed on to the QApplication
constructor.
*/
QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, argc, argv, visual, cmap)
{
sysInit();
}
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be \a appId. \a dpy, \a argc, \a
argv, \a visual, and \a cmap are passed on to the QApplication
constructor.
*/
QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, argc, argv, visual, cmap)
{
sysInit(appId);
}
-#endif
+# endif // Q_WS_X11
+#endif // QT_VERSION < 0x050000
/*!
Returns true if another instance of this application is running;
otherwise false.
This function does not find instances of this application that are
being run by a different user (on Windows: that are running in
another session).
\sa sendMessage()
*/
bool QtSingleApplication::isRunning()
{
return peer->isClient();
}
/*!
Tries to send the text \a message to the currently running
instance. The QtSingleApplication object in the running instance
will emit the messageReceived() signal when it receives the
message.
This function returns true if the message has been sent to, and
processed by, the current instance. If there is no instance
currently running, or if the running instance fails to process the
message within \a timeout milliseconds, this function return false.
\sa isRunning(), messageReceived()
*/
bool QtSingleApplication::sendMessage(const QByteArray &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
/*!
Returns the application identifier. Two processes with the same
identifier will be regarded as instances of the same application.
*/
QString QtSingleApplication::id() const
{
return peer->applicationId();
}
/*!
Sets the activation window of this application to \a aw. The
activation window is the widget that will be activated by
activateWindow(). This is typically the application's main window.
If \a activateOnMessage is true (the default), the window will be
activated automatically every time a message is received, just prior
to the messageReceived() signal being emitted.
\sa activateWindow(), messageReceived()
*/
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
{
actWin = aw;
if (activateOnMessage)
connect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow()));
else
disconnect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow()));
}
/*!
Returns the applications activation window if one has been set by
calling setActivationWindow(), otherwise returns 0.
\sa setActivationWindow()
*/
QWidget* QtSingleApplication::activationWindow() const
{
return actWin;
}
/*!
De-minimizes, raises, and activates this application's activation window.
This function does nothing if no activation window has been set.
This is a convenience function to show the user that this
application instance has been activated when he has tried to start
another instance.
This function should typically be called in response to the
messageReceived() signal. By default, that will happen
automatically, if an activation window has been set.
\sa setActivationWindow(), messageReceived(), initialize()
*/
void QtSingleApplication::activateWindow()
{
if (actWin) {
actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
actWin->raise();
actWin->activateWindow();
}
}
/*!
\fn void QtSingleApplication::messageReceived(const QString& message)
This signal is emitted when the current instance receives a \a
message from another instance of this application.
\sa sendMessage(), setActivationWindow(), activateWindow()
*/
/*!
\fn void QtSingleApplication::initialize(bool dummy = true)
\obsolete
*/
diff --git a/Utilities/qtsingleapplication/qtsingleapplication.h b/Utilities/qtsingleapplication/qtsingleapplication.h
index c8332c0913..4acf5f5d30 100644
--- a/Utilities/qtsingleapplication/qtsingleapplication.h
+++ b/Utilities/qtsingleapplication/qtsingleapplication.h
@@ -1,104 +1,107 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#ifndef QTSINGLEAPPLICATION_H
#define QTSINGLEAPPLICATION_H
-#include <QtGui/QApplication>
+#include <QApplication>
#include <qthandlenewappinstance.h>
class QtLocalPeer;
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
# define QT_QTSINGLEAPPLICATION_EXPORT
# elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
# if defined(QT_QTSINGLEAPPLICATION_EXPORT)
# undef QT_QTSINGLEAPPLICATION_EXPORT
# endif
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
# elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
# undef QT_QTSINGLEAPPLICATION_EXPORT
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
# endif
#else
# define QT_QTSINGLEAPPLICATION_EXPORT
#endif
class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication
{
Q_OBJECT
public:
QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
QtSingleApplication(const QString &id, int &argc, char **argv);
+#if QT_VERSION < 0x050000
QtSingleApplication(int &argc, char **argv, Type type);
-#if defined(Q_WS_X11)
+# if defined(Q_WS_X11)
QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
-#endif
+# endif // Q_WS_X11
+#endif // QT_VERSION < 0x050000
bool isRunning();
QString id() const;
void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
QWidget* activationWindow() const;
// Obsolete:
void initialize(bool dummy = true)
{ isRunning(); Q_UNUSED(dummy) }
public Q_SLOTS:
bool sendMessage(const QByteArray &message, int timeout = 5000);
void activateWindow();
Q_SIGNALS:
void messageReceived(const QByteArray &message);
private:
void sysInit(const QString &appId = QString());
QtLocalPeer *peer;
QWidget *actWin;
};
#endif // QTSINGLEAPPLICATION_H
diff --git a/Utilities/qtsingleapplication/qtsingleapplication.patch b/Utilities/qtsingleapplication/qtsingleapplication.patch
new file mode 100644
index 0000000000..5991034f7d
--- /dev/null
+++ b/Utilities/qtsingleapplication/qtsingleapplication.patch
@@ -0,0 +1,188 @@
+diff --git a/Utilities/qtsingleapplication/qtlocalpeer.cpp b/Utilities/qtsingleapplication/qtlocalpeer.cpp
+index 332b064..dd0143b 100644
+--- a/Utilities/qtsingleapplication/qtlocalpeer.cpp
++++ b/Utilities/qtsingleapplication/qtlocalpeer.cpp
+@@ -132,7 +132,7 @@ bool QtLocalPeer::isClient()
+ }
+
+
+-bool QtLocalPeer::sendMessage(const QString &message, int timeout)
++bool QtLocalPeer::sendMessage(const QByteArray &message, int timeout)
+ {
+ if (!isClient())
+ return false;
+@@ -156,9 +156,8 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
+ if (!connOk)
+ return false;
+
+- QByteArray uMsg(message.toUtf8());
+ QDataStream ds(&socket);
+- ds.writeBytes(uMsg.constData(), uMsg.size());
++ ds.writeBytes(message.constData(), message.size());
+ bool res = socket.waitForBytesWritten(timeout);
+ if (res) {
+ res &= socket.waitForReadyRead(timeout); // wait for ack
+@@ -194,10 +193,9 @@ void QtLocalPeer::receiveConnection()
+ delete socket;
+ return;
+ }
+- QString message(QString::fromUtf8(uMsg));
+ socket->write(ack, qstrlen(ack));
+ socket->waitForBytesWritten(1000);
+ socket->waitForDisconnected(1000); // make sure client reads ack
+ delete socket;
+- emit messageReceived(message); //### (might take a long time to return)
++ emit messageReceived(uMsg); //### (might take a long time to return)
+ }
+diff --git a/Utilities/qtsingleapplication/qtlocalpeer.h b/Utilities/qtsingleapplication/qtlocalpeer.h
+index 1b533b1..07374d9 100644
+--- a/Utilities/qtsingleapplication/qtlocalpeer.h
++++ b/Utilities/qtsingleapplication/qtlocalpeer.h
+@@ -54,12 +54,12 @@ class QtLocalPeer : public QObject
+ public:
+ QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
+ bool isClient();
+- bool sendMessage(const QString &message, int timeout);
++ bool sendMessage(const QByteArray &message, int timeout);
+ QString applicationId() const
+ { return id; }
+
+ Q_SIGNALS:
+- void messageReceived(const QString &message);
++ void messageReceived(const QByteArray &message);
+
+ protected Q_SLOTS:
+ void receiveConnection();
+diff --git a/Utilities/qtsingleapplication/qtlockedfile_win.cpp b/Utilities/qtsingleapplication/qtlockedfile_win.cpp
+index 5e21262..a44620b 100644
+--- a/Utilities/qtsingleapplication/qtlockedfile_win.cpp
++++ b/Utilities/qtsingleapplication/qtlockedfile_win.cpp
+@@ -63,7 +63,7 @@ Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
+
+ Qt::HANDLE mutex;
+ if (doCreate) {
+- QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
++ QT_WA( { mutex = CreateMutexW(NULL, FALSE, reinterpret_cast<LPCWSTR>(mname.utf16())); },
+ { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
+ if (!mutex) {
+ qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
+@@ -71,7 +71,7 @@ Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
+ }
+ }
+ else {
+- QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
++ QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, reinterpret_cast<LPCWSTR>(mname.utf16())); },
+ { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
+ if (!mutex) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+diff --git a/Utilities/qtsingleapplication/qtsingleapplication.cpp b/Utilities/qtsingleapplication/qtsingleapplication.cpp
+index d0fb15d..b2f2058 100644
+--- a/Utilities/qtsingleapplication/qtsingleapplication.cpp
++++ b/Utilities/qtsingleapplication/qtsingleapplication.cpp
+@@ -137,7 +137,7 @@ void QtSingleApplication::sysInit(const QString &appId)
+ {
+ actWin = 0;
+ peer = new QtLocalPeer(this, appId);
+- connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
++ connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
+ }
+
+
+@@ -256,7 +256,7 @@ bool QtSingleApplication::isRunning()
+
+ \sa isRunning(), messageReceived()
+ */
+-bool QtSingleApplication::sendMessage(const QString &message, int timeout)
++bool QtSingleApplication::sendMessage(const QByteArray &message, int timeout)
+ {
+ return peer->sendMessage(message, timeout);
+ }
+@@ -288,9 +288,9 @@ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessag
+ {
+ actWin = aw;
+ if (activateOnMessage)
+- connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
++ connect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow()));
+ else
+- disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
++ disconnect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow()));
+ }
+
+
+diff --git a/Utilities/qtsingleapplication/qtsingleapplication.h b/Utilities/qtsingleapplication/qtsingleapplication.h
+index 049406f..4acf5f5 100644
+--- a/Utilities/qtsingleapplication/qtsingleapplication.h
++++ b/Utilities/qtsingleapplication/qtsingleapplication.h
+@@ -43,6 +43,8 @@
+
+ #include <QApplication>
+
++#include <qthandlenewappinstance.h>
++
+ class QtLocalPeer;
+
+ #if defined(Q_OS_WIN)
+@@ -88,12 +90,12 @@ public:
+ { isRunning(); Q_UNUSED(dummy) }
+
+ public Q_SLOTS:
+- bool sendMessage(const QString &message, int timeout = 5000);
++ bool sendMessage(const QByteArray &message, int timeout = 5000);
+ void activateWindow();
+
+
+ Q_SIGNALS:
+- void messageReceived(const QString &message);
++ void messageReceived(const QByteArray &message);
+
+
+ private:
+diff --git a/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp b/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp
+index 5634537..a7cbf77 100644
+--- a/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp
++++ b/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp
+@@ -74,7 +74,7 @@ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
+ : QCoreApplication(argc, argv)
+ {
+ peer = new QtLocalPeer(this);
+- connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
++ connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
+ }
+
+
+@@ -87,7 +87,7 @@ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc
+ : QCoreApplication(argc, argv)
+ {
+ peer = new QtLocalPeer(this, appId);
+- connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
++ connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
+ }
+
+
+@@ -122,7 +122,7 @@ bool QtSingleCoreApplication::isRunning()
+ \sa isRunning(), messageReceived()
+ */
+
+-bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
++bool QtSingleCoreApplication::sendMessage(const QByteArray &message, int timeout)
+ {
+ return peer->sendMessage(message, timeout);
+ }
+diff --git a/Utilities/qtsingleapplication/qtsinglecoreapplication.h b/Utilities/qtsingleapplication/qtsinglecoreapplication.h
+index b87fffe..593915a 100644
+--- a/Utilities/qtsingleapplication/qtsinglecoreapplication.h
++++ b/Utilities/qtsingleapplication/qtsinglecoreapplication.h
+@@ -57,11 +57,11 @@ public:
+ QString id() const;
+
+ public Q_SLOTS:
+- bool sendMessage(const QString &message, int timeout = 5000);
++ bool sendMessage(const QByteArray &message, int timeout = 5000);
+
+
+ Q_SIGNALS:
+- void messageReceived(const QString &message);
++ void messageReceived(const QByteArray &message);
+
+
+ private:
diff --git a/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp b/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp
index a8cf50b4cc..a7cbf77798 100644
--- a/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp
+++ b/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp
@@ -1,148 +1,149 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#include "qtsinglecoreapplication.h"
#include "qtlocalpeer.h"
/*!
\class QtSingleCoreApplication qtsinglecoreapplication.h
\brief A variant of the QtSingleApplication class for non-GUI applications.
This class is a variant of QtSingleApplication suited for use in
console (non-GUI) applications. It is an extension of
QCoreApplication (instead of QApplication). It does not require
the QtGui library.
The API and usage is identical to QtSingleApplication, except that
functions relating to the "activation window" are not present, for
obvious reasons. Please refer to the QtSingleApplication
documentation for explanation of the usage.
A QtSingleCoreApplication instance can communicate to a
QtSingleApplication instance if they share the same application
id. Hence, this class can be used to create a light-weight
command-line tool that sends commands to a GUI application.
\sa QtSingleApplication
*/
/*!
Creates a QtSingleCoreApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc and \a
argv are passed on to the QCoreAppliation constructor.
*/
QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this);
connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
}
/*!
Creates a QtSingleCoreApplication object with the application
identifier \a appId. \a argc and \a argv are passed on to the
QCoreAppliation constructor.
*/
QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
}
/*!
Returns true if another instance of this application is running;
otherwise false.
This function does not find instances of this application that are
being run by a different user (on Windows: that are running in
another session).
\sa sendMessage()
*/
bool QtSingleCoreApplication::isRunning()
{
return peer->isClient();
}
/*!
Tries to send the text \a message to the currently running
instance. The QtSingleCoreApplication object in the running instance
will emit the messageReceived() signal when it receives the
message.
This function returns true if the message has been sent to, and
processed by, the current instance. If there is no instance
currently running, or if the running instance fails to process the
message within \a timeout milliseconds, this function return false.
\sa isRunning(), messageReceived()
*/
bool QtSingleCoreApplication::sendMessage(const QByteArray &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
/*!
Returns the application identifier. Two processes with the same
identifier will be regarded as instances of the same application.
*/
QString QtSingleCoreApplication::id() const
{
return peer->applicationId();
}
/*!
\fn void QtSingleCoreApplication::messageReceived(const QString& message)
This signal is emitted when the current instance receives a \a
message from another instance of this application.
\sa sendMessage()
*/
diff --git a/Utilities/qtsingleapplication/qtsinglecoreapplication.h b/Utilities/qtsingleapplication/qtsinglecoreapplication.h
index dd0540a583..593915a237 100644
--- a/Utilities/qtsingleapplication/qtsinglecoreapplication.h
+++ b/Utilities/qtsingleapplication/qtsinglecoreapplication.h
@@ -1,70 +1,71 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
+** This file is part of the Qt Solutions component.
**
+** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
+** $QT_END_LICENSE$
+**
****************************************************************************/
#ifndef QTSINGLECOREAPPLICATION_H
#define QTSINGLECOREAPPLICATION_H
-#include <QtCore/QCoreApplication>
+#include <QCoreApplication>
class QtLocalPeer;
class QtSingleCoreApplication : public QCoreApplication
{
Q_OBJECT
public:
QtSingleCoreApplication(int &argc, char **argv);
QtSingleCoreApplication(const QString &id, int &argc, char **argv);
bool isRunning();
QString id() const;
public Q_SLOTS:
bool sendMessage(const QByteArray &message, int timeout = 5000);
Q_SIGNALS:
void messageReceived(const QByteArray &message);
private:
QtLocalPeer* peer;
};
#endif // QTSINGLECOREAPPLICATION_H

File Metadata

Mime Type
application/octet-stream
Expires
Thu, Oct 3, 2:10 AM (1 d, 23 h)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
cgRkYLTmWfhQ
Default Alt Text
(7 MB)

Event Timeline