ixpvdemo.cpp 12.2 KB
Newer Older
schultezub's avatar
schultezub committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
//      Technische Universitt Mnchen
//      Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED 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 HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

#include "ixpvdemo.h"

#include "tgt/event/keyevent.h"
schultezub's avatar
schultezub committed
33
#include "tgt/qt/qtcontextmanager.h"
34
#include "core/datastructures/imagedata.h"
35

schultezub's avatar
schultezub committed
36 37 38 39 40 41 42
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"

namespace campvis {

    IxpvDemo::IxpvDemo()
        : VisualizationPipeline()
schultezub's avatar
schultezub committed
43
        , _xrayReader(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
44
        , _ctReader()
schultezub's avatar
schultezub committed
45 46 47
        , _ctProxy()
        , _ctFullEEP(_effectiveRenderTargetSize)
        , _ctClippedEEP(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
48
        , _ctDVR(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
49 50
        , _ctFullDRR(_effectiveRenderTargetSize)
        , _ctClippedDRR(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
51
        , _usReader()
52
        , _usSliceRenderer(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
53
        , _compositor(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
54 55
        , _compositor2(_effectiveRenderTargetSize)
        , _ixpvCompositor(_effectiveRenderTargetSize)
schultezub's avatar
schultezub committed
56 57
        , _camera("camera", "Camera")
        , _trackballHandler(0)
58
        , _wheelHandler(&_usSliceRenderer.p_sliceNumber)
schultezub's avatar
schultezub committed
59
    {
schultezub's avatar
schultezub committed
60
        addProcessor(&_xrayReader);
schultezub's avatar
schultezub committed
61

schultezub's avatar
schultezub committed
62
        addProcessor(&_usReader);
63
        addProcessor(&_usSliceRenderer);
schultezub's avatar
schultezub committed
64

schultezub's avatar
schultezub committed
65 66 67 68 69 70 71 72
        addProcessor(&_ctReader);
        addProcessor(&_ctProxy);
        addProcessor(&_ctFullEEP);
        addProcessor(&_ctClippedEEP);
        addProcessor(&_ctDVR);
        addProcessor(&_ctFullDRR);
        addProcessor(&_ctClippedDRR);

73
        addProcessor(&_compositor);
schultezub's avatar
schultezub committed
74 75
        addProcessor(&_compositor2);
        addProcessor(&_ixpvCompositor);
schultezub's avatar
schultezub committed
76 77 78

        addProperty(&_camera);

79
        _trackballHandler = new TrackballNavigationEventHandler(this, &_camera, _canvasSize.getValue());
80
        addEventHandler(&_wheelHandler);
schultezub's avatar
schultezub committed
81
        addEventHandler(_trackballHandler);
schultezub's avatar
schultezub committed
82 83 84
    }

    IxpvDemo::~IxpvDemo() {
schultezub's avatar
schultezub committed
85
        delete _trackballHandler;
schultezub's avatar
schultezub committed
86 87 88 89 90
    }

    void IxpvDemo::init() {
        VisualizationPipeline::init();

schultezub's avatar
schultezub committed
91 92 93
        // = Camera Setup =================================================================================
        _camera.addSharedProperty(&_ctFullEEP.p_camera);
        _camera.addSharedProperty(&_ctClippedEEP.p_camera);
schultezub's avatar
schultezub committed
94
        _camera.addSharedProperty(&_ctDVR.p_camera);
schultezub's avatar
schultezub committed
95 96
        _camera.addSharedProperty(&_ctFullDRR.p_camera);
        _camera.addSharedProperty(&_ctClippedDRR.p_camera);
97
        _camera.addSharedProperty(&_usSliceRenderer.p_camera);
schultezub's avatar
schultezub committed
98 99

        // = X-Ray Setup ==================================================================================
100
        _xrayReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Cowleg_CarmXrayImages\\APView_1.jpg");
schultezub's avatar
schultezub committed
101
        _xrayReader.p_targetImageID.setValue("xray.image");
102
        _xrayReader.p_useRenderTarget.setValue(true);
schultezub's avatar
schultezub committed
103

schultezub's avatar
schultezub committed
104 105 106 107 108
        // = CT Setup =====================================================================================

        _ctReader.p_targetImageID.connect(&_ctProxy.p_sourceImageID);
        _ctReader.p_targetImageID.connect(&_ctFullEEP.p_sourceImageID);
        _ctReader.p_targetImageID.connect(&_ctClippedEEP.p_sourceImageID);
schultezub's avatar
schultezub committed
109
        _ctReader.p_targetImageID.connect(&_ctDVR.p_sourceImageID);
schultezub's avatar
schultezub committed
110 111
        _ctReader.p_targetImageID.connect(&_ctFullDRR.p_sourceImageID);
        _ctReader.p_targetImageID.connect(&_ctClippedDRR.p_sourceImageID);
112 113
        _ctReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Cowleg_CT_8007_003_5mm_STD_20110224\\Fantome_20110224_8007_003_6_1_ABD-_portalvens_X_S___5mm_STD.mhd");
        _ctReader.p_targetImageID.setValue("ct.image");
114
        _ctReader.s_validated.connect(this, &IxpvDemo::onProcessorValidated);
schultezub's avatar
schultezub committed
115 116 117 118 119 120 121

        _ctProxy.p_geometryID.setValue("ct.proxy");
        _ctProxy.p_geometryID.connect(&_ctFullEEP.p_geometryID);
        _ctProxy.p_geometryID.connect(&_ctClippedEEP.p_geometryID);

        _ctFullEEP.p_entryImageID.setValue("ct.entry.full");
        _ctFullEEP.p_entryImageID.connect(&_ctFullDRR.p_entryImageID);
schultezub's avatar
schultezub committed
122
        _ctFullEEP.p_entryImageID.connect(&_ctDVR.p_entryImageID);
schultezub's avatar
schultezub committed
123 124
        _ctFullEEP.p_exitImageID.setValue("ct.exit.full");
        _ctFullEEP.p_exitImageID.connect(&_ctFullDRR.p_exitImageID);
schultezub's avatar
schultezub committed
125 126 127 128 129 130 131 132 133 134 135 136 137
        _ctFullEEP.p_exitImageID.connect(&_ctDVR.p_exitImageID);

        _ctClippedEEP.p_entryImageID.setValue("ct.entry.clipped");
        _ctClippedEEP.p_entryImageID.connect(&_ctClippedDRR.p_entryImageID);
        _ctClippedEEP.p_exitImageID.setValue("ct.exit.clipped");
        _ctClippedEEP.p_exitImageID.connect(&_ctClippedDRR.p_exitImageID);

        Geometry1DTransferFunction* tfDvr = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .08f));
        //        tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.5f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(0, 0, 0, 180)));
        tfDvr->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.4f, .6f), tgt::col4(255, 192, 0, 255), tgt::col4(255, 192, 0, 255)));
        _ctDVR.p_transferFunction.replaceTF(tfDvr);
        _ctDVR.p_targetImageID.setValue("ct.dvr");
        _ctDVR.p_samplingRate.setValue(1.f);
schultezub's avatar
schultezub committed
138 139

        Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .08f));
schultezub's avatar
schultezub committed
140 141 142 143
        tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.5f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(0, 0, 0, 180)));
        _ctFullDRR.p_transferFunction.replaceTF(tf);
        _ctFullDRR.p_targetImageID.setValue("ct.drr.full");
        _ctFullDRR.p_samplingRate.setValue(1.f);
schultezub's avatar
schultezub committed
144
        _ctFullDRR.p_invertMapping.setValue(true);
schultezub's avatar
schultezub committed
145 146 147 148 149 150
        
        Geometry1DTransferFunction* tf2 = new Geometry1DTransferFunction(128, tgt::vec2(0.f, 1.f));
        tf2->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.5f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(0, 0, 0, 180)));
        _ctClippedDRR.p_transferFunction.replaceTF(tf2);
        _ctClippedDRR.p_targetImageID.setValue("ct.drr.clipped");
        _ctClippedDRR.p_samplingRate.setValue(1.f);
schultezub's avatar
schultezub committed
151
        _ctClippedDRR.p_invertMapping.setValue(true);
schultezub's avatar
schultezub committed
152 153 154

        // = US Setup =====================================================================================

155
        _usReader.s_validated.connect(this, &IxpvDemo::onProcessorValidated);
schultezub's avatar
schultezub committed
156 157
        _usReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Ultrasound\\gaussianSmoothedUS_UChar.mhd");
        _usReader.p_targetImageID.setValue("us.image");
158
        _usReader.p_targetImageID.connect(&_usSliceRenderer.p_sourceImageID);
schultezub's avatar
schultezub committed
159 160
        _usReader.p_imageOffset.setValue(tgt::vec3(-600.f, 80.f, -530.f));
        _usReader.p_voxelSize.setValue(tgt::vec3(1.f, 1.f, 1.3f));
schultezub's avatar
schultezub committed
161

162
        _usSliceRenderer.p_targetImageID.setValue("us.slice");
schultezub's avatar
schultezub committed
163
        _usSliceRenderer.p_targetImageID.connect(&_ctClippedEEP.p_geometryImageId);
schultezub's avatar
schultezub committed
164
        
165
        _usSliceRenderer.p_sliceNumber.setValue(0);
schultezub's avatar
schultezub committed
166 167 168 169 170 171 172


        // = Compositing Setup ============================================================================

        _xrayReader.p_targetImageID.connect(&_compositor.p_firstImageId);
        _ctFullDRR.p_targetImageID.connect(&_compositor.p_secondImageId);
        _compositor.p_targetImageId.setValue("composed");
schultezub's avatar
schultezub committed
173
        _compositor.p_compositingMethod.selectById("diff");
schultezub's avatar
schultezub committed
174

schultezub's avatar
schultezub committed
175 176 177 178 179 180 181 182 183 184 185 186
        _ctDVR.p_targetImageID.connect(&_compositor2.p_firstImageId);
        _usSliceRenderer.p_targetImageID.connect(&_compositor2.p_secondImageId);
        _compositor2.p_targetImageId.setValue("composed2");
        _compositor2.p_compositingMethod.selectById("depth");

        _xrayReader.p_targetImageID.connect(&_ixpvCompositor.p_xRayImageId);
        _usSliceRenderer.p_targetImageID.connect(&_ixpvCompositor.p_3dSliceImageId);
        _ctFullDRR.p_targetImageID.connect(&_ixpvCompositor.p_drrFullImageId);
        _ctClippedDRR.p_targetImageID.connect(&_ixpvCompositor.p_drrClippedImageId);
        _ixpvCompositor.p_targetImageId.setValue("ixpv");

        _renderTargetID.setValue("ixpv");
schultezub's avatar
schultezub committed
187

188
        _trackballHandler->setViewportSize(_canvasSize.getValue());
schultezub's avatar
schultezub committed
189
    }
190 191 192 193
    
    const std::string IxpvDemo::getName() const {
        return "IXPV Demo";
    }
schultezub's avatar
schultezub committed
194

195
    void IxpvDemo::onRenderTargetSizeChanged(const AbstractProperty* prop) {
196
        _trackballHandler->setViewportSize(_canvasSize.getValue());
197 198 199
        float ratio = static_cast<float>(_effectiveRenderTargetSize.getValue().x) / static_cast<float>(_effectiveRenderTargetSize.getValue().y);
        _camera.setWindowRatio(ratio);
    }
schultezub's avatar
schultezub committed
200

201 202
    void IxpvDemo::onProcessorValidated(AbstractProcessor* processor) {
        if (processor == &_ctReader) {
203 204
            ImageRepresentationLocal::ScopedRepresentation local(_data, _ctReader.p_targetImageID.getValue());
            if (local != 0) {
205
                // set TF handles
206 207 208 209 210 211 212 213
                Interval<float> ii = local->getNormalizedIntensityRange();
                _ctDVR.p_transferFunction.getTF()->setImageHandle(local.getDataHandle());
                _ctDVR.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(ii.getLeft(), ii.getRight()));
                _ctFullDRR.p_transferFunction.getTF()->setImageHandle(local.getDataHandle());
                _ctFullDRR.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(.3f, .73f));
                _ctClippedDRR.p_transferFunction.getTF()->setImageHandle(local.getDataHandle());
                _ctClippedDRR.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(.3f, .73f));

214
                // update camera
215
                tgt::Bounds volumeExtent = local->getParent()->getWorldBounds();
schultezub's avatar
schultezub committed
216 217 218 219
                tgt::vec3 pos = volumeExtent.center() - tgt::vec3(0, 0, tgt::length(volumeExtent.diagonal()));

                _trackballHandler->setSceneBounds(volumeExtent);
                _trackballHandler->setCenter(volumeExtent.center());
schultezub's avatar
schultezub committed
220 221 222 223
                _trackballHandler->reinitializeCamera(
                    tgt::vec3(399.f, -900.f, 468.f), 
                    tgt::vec3(155.5f, 229.5f, 254.6f), 
                    tgt::vec3(0.959f, 0.279f, -0.042f));
224
            }   
schultezub's avatar
schultezub committed
225
        }
226 227
        else if (processor == &_usReader) {
            // set TF handles
228 229 230 231 232 233 234
            ImageRepresentationLocal::ScopedRepresentation local(_data, _usReader.p_targetImageID.getValue());
            if (local != 0) {
                Interval<float> ii = local->getNormalizedIntensityRange();
                _usSliceRenderer.p_transferFunction.getTF()->setImageHandle(local.getDataHandle());
                _usSliceRenderer.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(ii.getLeft(), ii.getRight()));
                _usSliceRenderer.updateProperties(local.getImageData());
                _usSliceRenderer.p_sliceNumber.setValue(125);
schultezub's avatar
schultezub committed
235 236
            }
        }
schultezub's avatar
schultezub committed
237 238
    }

schultezub's avatar
schultezub committed
239
}