<commit_before>// Copyright eeGeo Ltd (2012-2015), All Rights Reserved

#include "InteriorsHighlightVisibilityController.h"
#include "ISearchService.h"
#include "ISearchQueryPerformer.h"
#include "ISearchResultRepository.h"
#include "InteriorInteractionModel.h"
#include "InteriorsModel.h"
#include "InteriorsFloorModel.h"
#include "IInteriorsLabelController.h"
#include "VectorMath.h"
#include "InteriorHighlightRenderable.h"
#include "InteriorsLabelParser.h"
#include "InteriorsFloorCells.h"
#include "InteriorsFloorCell.h"
#include "PlaceNameModel.h"
#include "InteriorsCellResource.h"
#include "InteriorsCellResourceObserver.h"

namespace ExampleApp
{
    namespace InteriorsExplorer
    {
        namespace SdkModel
        {
            namespace Highlights
            {
                InteriorsHighlightVisibilityController::InteriorsHighlightVisibilityController(Eegeo::Resources::Interiors::InteriorInteractionModel& interiorInteractionModel,
                    Eegeo::Resources::Interiors::InteriorsCellResourceObserver& interiorsCellResourceObserver,
                    Search::SdkModel::ISearchService& searchService,
                    Search::SdkModel::ISearchQueryPerformer& searchQueryPerformer,
                    Search::SdkModel::ISearchResultRepository& searchResultRepository,
                    Eegeo::Resources::Interiors::Entities::IInteriorsLabelController& labelController,
                    ExampleAppMessaging::TMessageBus& messageBus,
                    IHighlightColorMapper& highlightColorMapper)
                    : m_interiorInteractionModel(interiorInteractionModel)
                    , m_interiorsCellResourceObserver(interiorsCellResourceObserver)
                    , m_interiorslabelsController(labelController)
                    , m_searchService(searchService)
                    , m_searchQueryPerformer(searchQueryPerformer)
                    , m_searchResultRepository(searchResultRepository)
                    , m_searchResultsHandler(this, &InteriorsHighlightVisibilityController::OnSearchResultsLoaded)
                    , m_searchResultsClearedHandler(this, &InteriorsHighlightVisibilityController::OnSearchResultCleared)
                    , m_interiorInteractionModelChangedHandler(this, &InteriorsHighlightVisibilityController::OnInteriorChanged)
                    , m_interiorCellAddedHandler(this, &InteriorsHighlightVisibilityController::OnInteriorAddedToSceneGraph)
                    , m_availabilityChangedHandlerBinding(this, &InteriorsHighlightVisibilityController::OnAvailabilityChanged)
                    , m_interiorLabelsBuiltHandler(this, &InteriorsHighlightVisibilityController::OnInteriorLabelsBuilt)
                    , m_highlightColorMapper(highlightColorMapper)
                {
                    m_searchService.InsertOnReceivedQueryResultsCallback(m_searchResultsHandler);
                    m_searchQueryPerformer.InsertOnSearchResultsClearedCallback(m_searchResultsClearedHandler);
                    m_interiorInteractionModel.RegisterModelChangedCallback(m_interiorInteractionModelChangedHandler);
                    m_interiorslabelsController.RegisterLabelsBuiltCallback(m_interiorLabelsBuiltHandler);
                    m_interiorsCellResourceObserver.RegisterAddedToSceneGraphCallback(m_interiorCellAddedHandler);
                }

                InteriorsHighlightVisibilityController::~InteriorsHighlightVisibilityController()
                {
                    m_interiorsCellResourceObserver.UnregisterAddedToSceneGraphCallback(m_interiorCellAddedHandler);
                    m_interiorslabelsController.UnregisterLabelsBuiltCallback(m_interiorLabelsBuiltHandler);
                    m_searchService.RemoveOnReceivedQueryResultsCallback(m_searchResultsHandler);
                    m_searchQueryPerformer.RemoveOnSearchResultsClearedCallback(m_searchResultsClearedHandler);
                    m_interiorInteractionModel.UnregisterModelChangedCallback(m_interiorInteractionModelChangedHandler);
                }

                void InteriorsHighlightVisibilityController::OnAvailabilityChanged()
                {
                }

                void InteriorsHighlightVisibilityController::DeactivateHighlightRenderables()
                {
                    const Eegeo::v4 transparent(1.0f, 1.0f, 1.0f, 0.0f);

                    for (std::map<std::string, std::vector<Eegeo::Rendering::Renderables::InteriorHighlightRenderable*>>::iterator it = m_currentHighlightRenderables.begin();
                        it != m_currentHighlightRenderables.end();
                        ++it)
                    {
                        for (auto& renderable : it->second)
                        {
                            renderable->SetDiffuseColor(transparent);
                        }
                    }
                }

                void InteriorsHighlightVisibilityController::ActivateLabels(bool active)
                {
                    namespace IE = Eegeo::Resources::Interiors::Entities;

                    const IE::TFloorIndexToModelsMap& floorIndexToModels = m_interiorslabelsController.GetFloorIndexToModels();

                    for (IE::TFloorIndexToModelsMap::const_iterator it = floorIndexToModels.begin(); it != floorIndexToModels.end(); ++it)
                    {
                        const IE::TModelVector& modelVector = (*it).second;

                        for (IE::TModelVector::const_iterator modelIt = modelVector.begin(); modelIt != modelVector.end(); ++modelIt)
                        {
                            modelIt->second->SetEnabled(active);
                        }
                    }
                }

                void InteriorsHighlightVisibilityController::OnInteriorLabelsBuilt()
                {
                    if (!ShowHighlightsForCurrentResults())
                    {
                        ActivateLabels(true);
                    }
                }

                void InteriorsHighlightVisibilityController::OnSearchResultCleared()
                {
                    DeactivateHighlightRenderables();
                    ActivateLabels(true);
                }

                void InteriorsHighlightVisibilityController::OnInteriorChanged()
                {
                    namespace EegeoInteriors = Eegeo::Resources::Interiors;
                    namespace EegeoRenderables = Eegeo::Rendering::Renderables;

                    DeactivateHighlightRenderables();
                    m_currentHighlightRenderables.clear();

                    if (m_interiorInteractionModel.HasInteriorModel())
                    {
                        const EegeoInteriors::InteriorsModel& model = *m_interiorInteractionModel.GetInteriorModel();

                        for (EegeoInteriors::TFloorModelVector::const_iterator floors = model.GetFloors().begin();
                            floors != model.GetFloors().end();
                            ++floors)
                        {
                            EegeoInteriors::InteriorsFloorCells* floorCells = model.GetFloorCells((*floors)->GetFloorNumber());

                            for (int cellIndex = 0; cellIndex < floorCells->GetCellCount(); ++cellIndex)
                            {
                                EegeoInteriors::InteriorsFloorCell* cell = floorCells->GetFloorCells()[cellIndex];
                                std::vector<EegeoRenderables::InteriorHighlightRenderable*> renderables = cell->GetHighlightRenderables();

                                for (std::vector<EegeoRenderables::InteriorHighlightRenderable*>::iterator renderableIterator = renderables.begin();
                                    renderableIterator != renderables.end();
                                    ++renderableIterator)
                                {
                                    AddHighlight(**renderableIterator);
                                }
                            }
                        }

                        if (m_currentHighlightRenderables.size() > 0)
                        {
                            bool showingHighlights = ShowHighlightsForCurrentResults();
                            ActivateLabels(!showingHighlights);
                        }
                        else
                        {
                            ActivateLabels(true);
                        }
                    }
                    else
                    {
                        DeactivateHighlightRenderables();
                        m_currentHighlightRenderables.clear();
                    }
                }

                void InteriorsHighlightVisibilityController::OnInteriorAddedToSceneGraph(const Eegeo::Resources::Interiors::InteriorsCellResource& resource)
                {
                    if (m_interiorInteractionModel.HasInteriorModel())
                    {
                        const Eegeo::Resources::Interiors::InteriorsModel& model = *m_interiorInteractionModel.GetInteriorModel();
                        if (model.GetId() == resource.GetInteriorId())
                        {
                            OnInteriorChanged();
                        }
                    }
                }

                void InteriorsHighlightVisibilityController::AddHighlight(Eegeo::Rendering::Renderables::InteriorHighlightRenderable& renderable)
                {
                    static const std::string highlightPrefix = "entity_highlight ";
                    const std::string& id = renderable.GetRenderableId();

                    if (id.compare(0, highlightPrefix.length(), highlightPrefix) == 0)
                    {
                        std::string highlightId = id.substr(highlightPrefix.length());
                        if (m_currentHighlightRenderables.find(highlightId) == m_currentHighlightRenderables.end())
                        {
                            std::vector<Eegeo::Rendering::Renderables::InteriorHighlightRenderable*> highlights;
                            m_currentHighlightRenderables.insert(std::make_pair(highlightId, highlights));
                        }
                        m_currentHighlightRenderables[highlightId].push_back(&renderable);
                    }
                }

                void InteriorsHighlightVisibilityController::OnSearchResultsLoaded(const Search::SdkModel::SearchQuery& query, const std::vector<Search::SdkModel::SearchResultModel>& results)
                {
                    DeactivateHighlightRenderables();

                    if (ShowHighlightsForResults(results))
                    {
                        ActivateLabels(false);
                    }
                }

                bool InteriorsHighlightVisibilityController::ShowHighlightsForCurrentResults()
                {
                    std::vector<Search::SdkModel::SearchResultModel> results;
                    results.reserve(m_searchResultRepository.GetItemCount());

                    for (int i = 0; i < m_searchResultRepository.GetItemCount(); i++)
                    {
                        Search::SdkModel::SearchResultModel* pResult = m_searchResultRepository.GetItemAtIndex(i);
                        results.push_back(*pResult);
                    }

                    return ShowHighlightsForResults(results);
                }

                bool InteriorsHighlightVisibilityController::ShowHighlightsForResults(const std::vector<Search::SdkModel::SearchResultModel> &results)
                {
                    bool showingHighlights = false;

                    if (m_interiorInteractionModel.HasInteriorModel() && m_currentHighlightRenderables.size() == 0)
                    {
                        OnInteriorChanged();
                    }

                    rapidjson::Document json;
                    std::string highlightedRoomId = "";

                    for (std::vector<Search::SdkModel::SearchResultModel>::const_iterator resultsItt = results.begin(); resultsItt != results.end(); ++resultsItt)
                    {
                        if (!json.Parse<0>(resultsItt->GetJsonData().c_str()).HasParseError() && json.HasMember("highlight"))
                        {
                            highlightedRoomId = json["highlight"].GetString();

                            for (std::map<std::string, std::vector<Eegeo::Rendering::Renderables::InteriorHighlightRenderable*>>::iterator renderItt = m_currentHighlightRenderables.begin();
                                renderItt != m_currentHighlightRenderables.end();
                                ++renderItt)
                            {
                                for (auto& renderable : renderItt->second)
                                {
                                    if (renderable->GetRenderableId().compare("entity_highlight " + highlightedRoomId) == 0)
                                    {
                                        renderable->SetDiffuseColor(m_highlightColorMapper.GetColor(*resultsItt, "highlight_color"));
                                        showingHighlights = true;
                                    }
                                }
                            }
                        }
                    }

                    return showingHighlights;
                }
            }
        }
    }
}<commit_msg>build fix for const-correctness api change Buddy: Blair<commit_after>// Copyright eeGeo Ltd (2012-2015), All Rights Reserved

#include "InteriorsHighlightVisibilityController.h"
#include "ISearchService.h"
#include "ISearchQueryPerformer.h"
#include "ISearchResultRepository.h"
#include "InteriorInteractionModel.h"
#include "InteriorsModel.h"
#include "InteriorsFloorModel.h"
#include "IInteriorsLabelController.h"
#include "VectorMath.h"
#include "InteriorHighlightRenderable.h"
#include "InteriorsLabelParser.h"
#include "InteriorsFloorCells.h"
#include "InteriorsFloorCell.h"
#include "PlaceNameModel.h"
#include "InteriorsCellResource.h"
#include "InteriorsCellResourceObserver.h"

namespace ExampleApp
{
    namespace InteriorsExplorer
    {
        namespace SdkModel
        {
            namespace Highlights
            {
                InteriorsHighlightVisibilityController::InteriorsHighlightVisibilityController(Eegeo::Resources::Interiors::InteriorInteractionModel& interiorInteractionModel,
                    Eegeo::Resources::Interiors::InteriorsCellResourceObserver& interiorsCellResourceObserver,
                    Search::SdkModel::ISearchService& searchService,
                    Search::SdkModel::ISearchQueryPerformer& searchQueryPerformer,
                    Search::SdkModel::ISearchResultRepository& searchResultRepository,
                    Eegeo::Resources::Interiors::Entities::IInteriorsLabelController& labelController,
                    ExampleAppMessaging::TMessageBus& messageBus,
                    IHighlightColorMapper& highlightColorMapper)
                    : m_interiorInteractionModel(interiorInteractionModel)
                    , m_interiorsCellResourceObserver(interiorsCellResourceObserver)
                    , m_interiorslabelsController(labelController)
                    , m_searchService(searchService)
                    , m_searchQueryPerformer(searchQueryPerformer)
                    , m_searchResultRepository(searchResultRepository)
                    , m_searchResultsHandler(this, &InteriorsHighlightVisibilityController::OnSearchResultsLoaded)
                    , m_searchResultsClearedHandler(this, &InteriorsHighlightVisibilityController::OnSearchResultCleared)
                    , m_interiorInteractionModelChangedHandler(this, &InteriorsHighlightVisibilityController::OnInteriorChanged)
                    , m_interiorCellAddedHandler(this, &InteriorsHighlightVisibilityController::OnInteriorAddedToSceneGraph)
                    , m_availabilityChangedHandlerBinding(this, &InteriorsHighlightVisibilityController::OnAvailabilityChanged)
                    , m_interiorLabelsBuiltHandler(this, &InteriorsHighlightVisibilityController::OnInteriorLabelsBuilt)
                    , m_highlightColorMapper(highlightColorMapper)
                {
                    m_searchService.InsertOnReceivedQueryResultsCallback(m_searchResultsHandler);
                    m_searchQueryPerformer.InsertOnSearchResultsClearedCallback(m_searchResultsClearedHandler);
                    m_interiorInteractionModel.RegisterModelChangedCallback(m_interiorInteractionModelChangedHandler);
                    m_interiorslabelsController.RegisterLabelsBuiltCallback(m_interiorLabelsBuiltHandler);
                    m_interiorsCellResourceObserver.RegisterAddedToSceneGraphCallback(m_interiorCellAddedHandler);
                }

                InteriorsHighlightVisibilityController::~InteriorsHighlightVisibilityController()
                {
                    m_interiorsCellResourceObserver.UnregisterAddedToSceneGraphCallback(m_interiorCellAddedHandler);
                    m_interiorslabelsController.UnregisterLabelsBuiltCallback(m_interiorLabelsBuiltHandler);
                    m_searchService.RemoveOnReceivedQueryResultsCallback(m_searchResultsHandler);
                    m_searchQueryPerformer.RemoveOnSearchResultsClearedCallback(m_searchResultsClearedHandler);
                    m_interiorInteractionModel.UnregisterModelChangedCallback(m_interiorInteractionModelChangedHandler);
                }

                void InteriorsHighlightVisibilityController::OnAvailabilityChanged()
                {
                }

                void InteriorsHighlightVisibilityController::DeactivateHighlightRenderables()
                {
                    const Eegeo::v4 transparent(1.0f, 1.0f, 1.0f, 0.0f);

                    for (std::map<std::string, std::vector<Eegeo::Rendering::Renderables::InteriorHighlightRenderable*>>::iterator it = m_currentHighlightRenderables.begin();
                        it != m_currentHighlightRenderables.end();
                        ++it)
                    {
                        for (auto& renderable : it->second)
                        {
                            renderable->SetDiffuseColor(transparent);
                        }
                    }
                }

                void InteriorsHighlightVisibilityController::ActivateLabels(bool active)
                {
                    namespace IE = Eegeo::Resources::Interiors::Entities;

                    const IE::TFloorIndexToModelsMap& floorIndexToModels = m_interiorslabelsController.GetFloorIndexToModels();

                    for (IE::TFloorIndexToModelsMap::const_iterator it = floorIndexToModels.begin(); it != floorIndexToModels.end(); ++it)
                    {
                        const IE::TModelVector& modelVector = (*it).second;

                        for (IE::TModelVector::const_iterator modelIt = modelVector.begin(); modelIt != modelVector.end(); ++modelIt)
                        {
                            modelIt->second->SetEnabled(active);
                        }
                    }
                }

                void InteriorsHighlightVisibilityController::OnInteriorLabelsBuilt()
                {
                    if (!ShowHighlightsForCurrentResults())
                    {
                        ActivateLabels(true);
                    }
                }

                void InteriorsHighlightVisibilityController::OnSearchResultCleared()
                {
                    DeactivateHighlightRenderables();
                    ActivateLabels(true);
                }

                void InteriorsHighlightVisibilityController::OnInteriorChanged()
                {
                    namespace EegeoInteriors = Eegeo::Resources::Interiors;
                    namespace EegeoRenderables = Eegeo::Rendering::Renderables;

                    DeactivateHighlightRenderables();
                    m_currentHighlightRenderables.clear();

                    if (m_interiorInteractionModel.HasInteriorModel())
                    {
                        const EegeoInteriors::InteriorsModel& model = *m_interiorInteractionModel.GetInteriorModel();

                        for (EegeoInteriors::TFloorModelVector::const_iterator floors = model.GetFloors().begin();
                            floors != model.GetFloors().end();
                            ++floors)
                        {
                            const EegeoInteriors::InteriorsFloorCells* floorCells = model.GetFloorCells((*floors)->GetFloorNumber());

                            for (int cellIndex = 0; cellIndex < floorCells->GetCellCount(); ++cellIndex)
                            {
                                const EegeoInteriors::InteriorsFloorCell* cell = floorCells->GetFloorCells()[cellIndex];
                                std::vector<EegeoRenderables::InteriorHighlightRenderable*> renderables = cell->GetHighlightRenderables();

                                for (std::vector<EegeoRenderables::InteriorHighlightRenderable*>::iterator renderableIterator = renderables.begin();
                                    renderableIterator != renderables.end();
                                    ++renderableIterator)
                                {
                                    AddHighlight(**renderableIterator);
                                }
                            }
                        }

                        if (m_currentHighlightRenderables.size() > 0)
                        {
                            bool showingHighlights = ShowHighlightsForCurrentResults();
                            ActivateLabels(!showingHighlights);
                        }
                        else
                        {
                            ActivateLabels(true);
                        }
                    }
                    else
                    {
                        DeactivateHighlightRenderables();
                        m_currentHighlightRenderables.clear();
                    }
                }

                void InteriorsHighlightVisibilityController::OnInteriorAddedToSceneGraph(const Eegeo::Resources::Interiors::InteriorsCellResource& resource)
                {
                    if (m_interiorInteractionModel.HasInteriorModel())
                    {
                        const Eegeo::Resources::Interiors::InteriorsModel& model = *m_interiorInteractionModel.GetInteriorModel();
                        if (model.GetId() == resource.GetInteriorId())
                        {
                            OnInteriorChanged();
                        }
                    }
                }

                void InteriorsHighlightVisibilityController::AddHighlight(Eegeo::Rendering::Renderables::InteriorHighlightRenderable& renderable)
                {
                    static const std::string highlightPrefix = "entity_highlight ";
                    const std::string& id = renderable.GetRenderableId();

                    if (id.compare(0, highlightPrefix.length(), highlightPrefix) == 0)
                    {
                        std::string highlightId = id.substr(highlightPrefix.length());
                        if (m_currentHighlightRenderables.find(highlightId) == m_currentHighlightRenderables.end())
                        {
                            std::vector<Eegeo::Rendering::Renderables::InteriorHighlightRenderable*> highlights;
                            m_currentHighlightRenderables.insert(std::make_pair(highlightId, highlights));
                        }
                        m_currentHighlightRenderables[highlightId].push_back(&renderable);
                    }
                }

                void InteriorsHighlightVisibilityController::OnSearchResultsLoaded(const Search::SdkModel::SearchQuery& query, const std::vector<Search::SdkModel::SearchResultModel>& results)
                {
                    DeactivateHighlightRenderables();

                    if (ShowHighlightsForResults(results))
                    {
                        ActivateLabels(false);
                    }
                }

                bool InteriorsHighlightVisibilityController::ShowHighlightsForCurrentResults()
                {
                    std::vector<Search::SdkModel::SearchResultModel> results;
                    results.reserve(m_searchResultRepository.GetItemCount());

                    for (int i = 0; i < m_searchResultRepository.GetItemCount(); i++)
                    {
                        Search::SdkModel::SearchResultModel* pResult = m_searchResultRepository.GetItemAtIndex(i);
                        results.push_back(*pResult);
                    }

                    return ShowHighlightsForResults(results);
                }

                bool InteriorsHighlightVisibilityController::ShowHighlightsForResults(const std::vector<Search::SdkModel::SearchResultModel> &results)
                {
                    bool showingHighlights = false;

                    if (m_interiorInteractionModel.HasInteriorModel() && m_currentHighlightRenderables.size() == 0)
                    {
                        OnInteriorChanged();
                    }

                    rapidjson::Document json;
                    std::string highlightedRoomId = "";

                    for (std::vector<Search::SdkModel::SearchResultModel>::const_iterator resultsItt = results.begin(); resultsItt != results.end(); ++resultsItt)
                    {
                        if (!json.Parse<0>(resultsItt->GetJsonData().c_str()).HasParseError() && json.HasMember("highlight"))
                        {
                            highlightedRoomId = json["highlight"].GetString();

                            for (std::map<std::string, std::vector<Eegeo::Rendering::Renderables::InteriorHighlightRenderable*>>::iterator renderItt = m_currentHighlightRenderables.begin();
                                renderItt != m_currentHighlightRenderables.end();
                                ++renderItt)
                            {
                                for (auto& renderable : renderItt->second)
                                {
                                    if (renderable->GetRenderableId().compare("entity_highlight " + highlightedRoomId) == 0)
                                    {
                                        renderable->SetDiffuseColor(m_highlightColorMapper.GetColor(*resultsItt, "highlight_color"));
                                        showingHighlights = true;
                                    }
                                }
                            }
                        }
                    }

                    return showingHighlights;
                }
            }
        }
    }
}<|endoftext|>


<commit_before>//
// PROJECT:         Aspia Remote Desktop
// FILE:            client/client_session_desktop_view.cc
// LICENSE:         See top-level directory
// PROGRAMMERS:     Dmitry Chapyshev (dmitry@aspia.ru)
//

#include "client/client_session_desktop_view.h"
#include "base/logging.h"
#include "codec/video_decoder_zlib.h"
#include "codec/video_decoder_vpx.h"
#include "codec/video_helpers.h"
#include "protocol/message_serialization.h"

namespace aspia {

ClientSessionDesktopView::ClientSessionDesktopView(const ClientConfig& config,
                                                   ClientSession::Delegate* delegate) :
    ClientSession(config, delegate)
{
    viewer_.reset(new ViewerWindow(config, this));
}

ClientSessionDesktopView::~ClientSessionDesktopView()
{
    viewer_.reset();
}

bool ClientSessionDesktopView::ReadVideoPacket(const proto::VideoPacket& video_packet)
{
    if (video_encoding_ != video_packet.encoding())
    {
        video_encoding_ = video_packet.encoding();

        switch (video_encoding_)
        {
            case proto::VIDEO_ENCODING_VP8:
                video_decoder_ = VideoDecoderVPX::CreateVP8();
                break;

            case proto::VIDEO_ENCODING_VP9:
                video_decoder_ = VideoDecoderVPX::CreateVP9();
                break;

            case proto::VIDEO_ENCODING_ZLIB:
                video_decoder_ = VideoDecoderZLIB::Create();
                break;

            default:
                LOG(ERROR) << "Unsupported encoding: " << video_encoding_;
                return false;
        }
    }

    if (video_packet.has_screen_size() || video_packet.has_pixel_format())
    {
        PixelFormat pixel_format;

        if (video_encoding_ == proto::VideoEncoding::VIDEO_ENCODING_ZLIB)
        {
            pixel_format = ConvertFromVideoPixelFormat(video_packet.pixel_format());
        }
        else
        {
            pixel_format = PixelFormat::ARGB();
        }

        if (!pixel_format.IsValid())
        {
            LOG(ERROR) << "Wrong pixel format";
            return false;
        }

        viewer_->ResizeFrame(ConvertFromVideoSize(video_packet.screen_size()), pixel_format);
    }

    DesktopFrame* frame = viewer_->Frame();
    if (!frame)
        return false;

    if (!video_decoder_->Decode(video_packet, frame))
        return false;

    viewer_->DrawFrame();

    return true;
}

void ClientSessionDesktopView::ReadConfigRequest(const proto::DesktopSessionConfigRequest& config_request)
{
    OnConfigChange(config_.desktop_session_config());
}

void ClientSessionDesktopView::Send(const IOBuffer& buffer)
{
    proto::desktop::HostToClient message;

    if (ParseMessage(buffer, message))
    {
        bool success = true;

        if (message.has_video_packet())
        {
            success = ReadVideoPacket(message.video_packet());
        }
        else if (message.has_audio_packet())
        {
            DLOG(WARNING) << "Audio not implemented yet";
        }
        else if (message.has_config_request())
        {
            ReadConfigRequest(message.config_request());
        }
        else
        {
            // Unknown messages are ignored.
            DLOG(WARNING) << "Unhandled message from host";
        }

        if (success)
            return;
    }

    delegate_->OnSessionTerminate();
}

void ClientSessionDesktopView::WriteMessage(const proto::desktop::ClientToHost& message)
{
    IOBuffer buffer = SerializeMessage(message);

    if (!buffer.IsEmpty())
    {
        delegate_->OnSessionMessageAsync(std::move(buffer));
        return;
    }

    delegate_->OnSessionTerminate();
}

void ClientSessionDesktopView::OnWindowClose()
{
    delegate_->OnSessionTerminate();
}

void ClientSessionDesktopView::OnConfigChange(const proto::DesktopSessionConfig& config)
{
    proto::desktop::ClientToHost message;
    message.mutable_config()->CopyFrom(config);
    WriteMessage(message);
}

} // namespace aspia
<commit_msg>- Validate frame size<commit_after>//
// PROJECT:         Aspia Remote Desktop
// FILE:            client/client_session_desktop_view.cc
// LICENSE:         See top-level directory
// PROGRAMMERS:     Dmitry Chapyshev (dmitry@aspia.ru)
//

#include "client/client_session_desktop_view.h"
#include "base/logging.h"
#include "codec/video_decoder_zlib.h"
#include "codec/video_decoder_vpx.h"
#include "codec/video_helpers.h"
#include "protocol/message_serialization.h"

namespace aspia {

ClientSessionDesktopView::ClientSessionDesktopView(const ClientConfig& config,
                                                   ClientSession::Delegate* delegate) :
    ClientSession(config, delegate)
{
    viewer_.reset(new ViewerWindow(config, this));
}

ClientSessionDesktopView::~ClientSessionDesktopView()
{
    viewer_.reset();
}

bool ClientSessionDesktopView::ReadVideoPacket(const proto::VideoPacket& video_packet)
{
    if (video_encoding_ != video_packet.encoding())
    {
        video_encoding_ = video_packet.encoding();

        switch (video_encoding_)
        {
            case proto::VIDEO_ENCODING_VP8:
                video_decoder_ = VideoDecoderVPX::CreateVP8();
                break;

            case proto::VIDEO_ENCODING_VP9:
                video_decoder_ = VideoDecoderVPX::CreateVP9();
                break;

            case proto::VIDEO_ENCODING_ZLIB:
                video_decoder_ = VideoDecoderZLIB::Create();
                break;

            default:
                LOG(ERROR) << "Unsupported encoding: " << video_encoding_;
                return false;
        }
    }

    if (video_packet.has_screen_size() || video_packet.has_pixel_format())
    {
        PixelFormat pixel_format;

        if (video_encoding_ == proto::VideoEncoding::VIDEO_ENCODING_ZLIB)
        {
            pixel_format = ConvertFromVideoPixelFormat(video_packet.pixel_format());
        }
        else
        {
            pixel_format = PixelFormat::ARGB();
        }

        if (!pixel_format.IsValid())
        {
            LOG(ERROR) << "Wrong pixel format for frame";
            return false;
        }

        DesktopSize size = ConvertFromVideoSize(video_packet.screen_size());

        if (size.IsEmpty())
        {
            LOG(ERROR) << "Wrong size for frame";
            return false;
        }

        viewer_->ResizeFrame(size, pixel_format);
    }

    DesktopFrame* frame = viewer_->Frame();
    if (!frame)
        return false;

    if (!video_decoder_->Decode(video_packet, frame))
        return false;

    viewer_->DrawFrame();

    return true;
}

void ClientSessionDesktopView::ReadConfigRequest(const proto::DesktopSessionConfigRequest& config_request)
{
    OnConfigChange(config_.desktop_session_config());
}

void ClientSessionDesktopView::Send(const IOBuffer& buffer)
{
    proto::desktop::HostToClient message;

    if (ParseMessage(buffer, message))
    {
        bool success = true;

        if (message.has_video_packet())
        {
            success = ReadVideoPacket(message.video_packet());
        }
        else if (message.has_audio_packet())
        {
            DLOG(WARNING) << "Audio not implemented yet";
        }
        else if (message.has_config_request())
        {
            ReadConfigRequest(message.config_request());
        }
        else
        {
            // Unknown messages are ignored.
            DLOG(WARNING) << "Unhandled message from host";
        }

        if (success)
            return;
    }

    delegate_->OnSessionTerminate();
}

void ClientSessionDesktopView::WriteMessage(const proto::desktop::ClientToHost& message)
{
    IOBuffer buffer = SerializeMessage(message);

    if (!buffer.IsEmpty())
    {
        delegate_->OnSessionMessageAsync(std::move(buffer));
        return;
    }

    delegate_->OnSessionTerminate();
}

void ClientSessionDesktopView::OnWindowClose()
{
    delegate_->OnSessionTerminate();
}

void ClientSessionDesktopView::OnConfigChange(const proto::DesktopSessionConfig& config)
{
    proto::desktop::ClientToHost message;
    message.mutable_config()->CopyFrom(config);
    WriteMessage(message);
}

} // namespace aspia
<|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief Some common functions in use for testing framework
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#ifndef KDB_TESTS_HPP
#define KDB_TESTS_HPP

#include <kdb.hpp>
#include <kdbmacros.h>
#include <key.hpp>
#include <keyset.hpp>

#include <cstdlib>
#include <cstring>
#include <exception>
#include <iostream>
#include <string>

#include <gtest/gtest.h>

using namespace std;
using namespace kdb;

// -- Macros -------------------------------------------------------------------------------------------------------------------------------

#define succeed_if(x, y) ASSERT_TRUE (x) << y

#define exit_if_fail(expression, message)                                                                                \
	if (!(expression))                                                                                \
	{                                                                                \
		cerr << __FILE__ << ":" << __LINE__ << ": Failure" << endl;                                                                \
		cerr << "Value of: " << ELEKTRA_STRINGIFY (expression) << endl;                                                            \
		cerr << "  Actual: false" << endl;                                                                                \
		cerr << "Expected: true" << endl;                                                                                \
		cerr << message << endl;                                                                                \
		exit (1);                                                                                \
	}                                                                                \
	SUCCEED () << message

#define succeed_if_same(x, y, message) ASSERT_EQ (x, y) << message

#define compare_keyset(keySet1, keySet2) ASSERT_TRUE (compareKeySet (keySet1, keySet2))

// -- Functions ----------------------------------------------------------------------------------------------------------------------------

/**
 * @brief This function adds the string representation of a key to an assertion result.
 *
 * @param stream This parameter specifies the assertion result to which this function adds a string representation of `key`.
 * @param key This parameter stores the key this function converts to an assertion result.
 *
 * @returns An assertion result containing the string representation of `key`
 */
testing::AssertionResult & operator<< (testing::AssertionResult & stream, kdb::Key & key)
{
	stream << key.getName () << ": " << (key.isString () ? key.getString () : (key.getBinarySize () == 0 ? "NULL" : "BINARY"));

	key.rewindMeta ();
	while (key.nextMeta ())
	{
		stream << ", " << key.currentMeta ().getName () << ": " << key.currentMeta ().getString ();
	}
	stream << endl;
	return stream;
}

/**
 * @brief This function adds the string representation of a key set to an assertion result.
 *
 * @param stream This parameter specifies the assertion result to which this function adds a string representation of `keys`.
 * @param key This parameter stores the key set this function converts to an assertion result.
 *
 * @returns An assertion result containing the string representation of `keys`
 */
testing::AssertionResult & operator<< (testing::AssertionResult & stream, kdb::KeySet & keys)
{
	for (auto key : keys)
	{
		stream << key;
	}
	return stream;
}

/**
 * @brief This function checks if the meta key set of two keys are equal.
 *
 * @param key1 This parameter stores the first meta key set this function uses for comparison.
 * @param key2 This parameter stores the second meta key set this function uses for comparison.
 *
 * @retval true if all meta keys of `key1` and `key2` are equal
 * @retval false otherwise
 */
bool isMetaDataEqual (kdb::Key & key1, kdb::Key & key2)
{
	key1.rewindMeta ();
	key2.rewindMeta ();

	while (key1.nextMeta ())
	{
		key2.nextMeta ();
		if (!key2.currentMeta ()) return false;
		if (key1.currentMeta ().getName () != key2.currentMeta ().getName ()) return false;
		if (key1.currentMeta ().getString () != key2.currentMeta ().getString ()) return false;
	}

	return key1.nextMeta () == key2.nextMeta ();
}

/**
 * @brief This function checks if two keys are equal.
 *
 * @param key1 This parameter stores the first key this function compares.
 * @param key2 This parameter stores the second key this function compares.
 *
 * @retval true if all attributes of `key1` and `key2` are equal
 * @retval false otherwise
 */
bool isKeyEqual (kdb::Key & key1, kdb::Key & key2)
{
	if (key1.getName () != key2.getName ()) return false;
	if ((key1.isString () && key2.isBinary ()) || (key1.isBinary () && key2.isString ())) return false;
	if (key1.getBinarySize () != key2.getBinarySize ()) return false;
	if (memcmp (key1.getValue (), key2.getValue (), key1.getBinarySize ())) return false;
	return isMetaDataEqual (key1, key2);
}

/**
 * @brief This function checks if two key sets are equal.
 *
 * @param keys1 This parameter stores the first key set this function compares.
 * @param keys2 This parameter stores the second key set this function compares.
 *
 * @retval true if all keys of `keys1` and `keys2` are equal
 * @retval false otherwise
 */
bool isKeySetEqual (kdb::KeySet & keys1, kdb::KeySet & keys2)
{
	if (keys1.size () != keys2.size ()) return false;

	keys1.rewind ();
	keys2.rewind ();
	while (keys1.next ())
	{
		keys2.next ();
		if (!keys2.current ()) return false;
		kdb::Key key1 = keys1.current ();
		kdb::Key key2 = keys2.current ();
		if (!isKeyEqual (key1, key2)) return false;
	}

	return keys1.next () == keys2.next ();
}

/**
 * @brief This function compares the given key sets.
 *
 * @param keys1 This parameter stores the first key set this function compares.
 * @param keys2 This parameter stores the second key set this function compares.
 *
 * @retval AssertionSuccess if all keys of `keys1` and `keys2` are equal
 * @retval AssertionFailure otherwise
 */
testing::AssertionResult compareKeySet (kdb::KeySet & keys1, kdb::KeySet & keys2)
{
	if (isKeySetEqual (keys1, keys2))
		return testing::AssertionSuccess ();
	else
		return testing::AssertionFailure () << "\n\nFirst key set:\n\n"
						    << keys1 << "\n——————————"
						    << "\n\nSecond key set:\n\n"
						    << keys2 << endl;
}

#endif
<commit_msg>Test: Add quotes around key values<commit_after>/**
 * @file
 *
 * @brief Some common functions in use for testing framework
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#ifndef KDB_TESTS_HPP
#define KDB_TESTS_HPP

#include <kdb.hpp>
#include <kdbmacros.h>
#include <key.hpp>
#include <keyset.hpp>

#include <cstdlib>
#include <cstring>
#include <exception>
#include <iostream>
#include <string>

#include <gtest/gtest.h>

using namespace std;
using namespace kdb;

// -- Macros -------------------------------------------------------------------------------------------------------------------------------

#define succeed_if(x, y) ASSERT_TRUE (x) << y

#define exit_if_fail(expression, message)                                                                                \
	if (!(expression))                                                                                \
	{                                                                                \
		cerr << __FILE__ << ":" << __LINE__ << ": Failure" << endl;                                                                \
		cerr << "Value of: " << ELEKTRA_STRINGIFY (expression) << endl;                                                            \
		cerr << "  Actual: false" << endl;                                                                                \
		cerr << "Expected: true" << endl;                                                                                \
		cerr << message << endl;                                                                                \
		exit (1);                                                                                \
	}                                                                                \
	SUCCEED () << message

#define succeed_if_same(x, y, message) ASSERT_EQ (x, y) << message

#define compare_keyset(keySet1, keySet2) ASSERT_TRUE (compareKeySet (keySet1, keySet2))

// -- Functions ----------------------------------------------------------------------------------------------------------------------------

/**
 * @brief This function adds the string representation of a key to an assertion result.
 *
 * @param stream This parameter specifies the assertion result to which this function adds a string representation of `key`.
 * @param key This parameter stores the key this function converts to an assertion result.
 *
 * @returns An assertion result containing the string representation of `key`
 */
testing::AssertionResult & operator<< (testing::AssertionResult & stream, kdb::Key & key)
{
	stream << key.getName () << ": “" << (key.isString () ? key.getString () : (key.getBinarySize () == 0 ? "NULL" : "BINARY")) << "”";

	key.rewindMeta ();
	while (key.nextMeta ())
	{
		stream << ", " << key.currentMeta ().getName () << ": “" << key.currentMeta ().getString () << "”";
	}
	stream << endl;
	return stream;
}

/**
 * @brief This function adds the string representation of a key set to an assertion result.
 *
 * @param stream This parameter specifies the assertion result to which this function adds a string representation of `keys`.
 * @param key This parameter stores the key set this function converts to an assertion result.
 *
 * @returns An assertion result containing the string representation of `keys`
 */
testing::AssertionResult & operator<< (testing::AssertionResult & stream, kdb::KeySet & keys)
{
	for (auto key : keys)
	{
		stream << key;
	}
	return stream;
}

/**
 * @brief This function checks if the meta key set of two keys are equal.
 *
 * @param key1 This parameter stores the first meta key set this function uses for comparison.
 * @param key2 This parameter stores the second meta key set this function uses for comparison.
 *
 * @retval true if all meta keys of `key1` and `key2` are equal
 * @retval false otherwise
 */
bool isMetaDataEqual (kdb::Key & key1, kdb::Key & key2)
{
	key1.rewindMeta ();
	key2.rewindMeta ();

	while (key1.nextMeta ())
	{
		key2.nextMeta ();
		if (!key2.currentMeta ()) return false;
		if (key1.currentMeta ().getName () != key2.currentMeta ().getName ()) return false;
		if (key1.currentMeta ().getString () != key2.currentMeta ().getString ()) return false;
	}

	return key1.nextMeta () == key2.nextMeta ();
}

/**
 * @brief This function checks if two keys are equal.
 *
 * @param key1 This parameter stores the first key this function compares.
 * @param key2 This parameter stores the second key this function compares.
 *
 * @retval true if all attributes of `key1` and `key2` are equal
 * @retval false otherwise
 */
bool isKeyEqual (kdb::Key & key1, kdb::Key & key2)
{
	if (key1.getName () != key2.getName ()) return false;
	if ((key1.isString () && key2.isBinary ()) || (key1.isBinary () && key2.isString ())) return false;
	if (key1.getBinarySize () != key2.getBinarySize ()) return false;
	if (memcmp (key1.getValue (), key2.getValue (), key1.getBinarySize ())) return false;
	return isMetaDataEqual (key1, key2);
}

/**
 * @brief This function checks if two key sets are equal.
 *
 * @param keys1 This parameter stores the first key set this function compares.
 * @param keys2 This parameter stores the second key set this function compares.
 *
 * @retval true if all keys of `keys1` and `keys2` are equal
 * @retval false otherwise
 */
bool isKeySetEqual (kdb::KeySet & keys1, kdb::KeySet & keys2)
{
	if (keys1.size () != keys2.size ()) return false;

	keys1.rewind ();
	keys2.rewind ();
	while (keys1.next ())
	{
		keys2.next ();
		if (!keys2.current ()) return false;
		kdb::Key key1 = keys1.current ();
		kdb::Key key2 = keys2.current ();
		if (!isKeyEqual (key1, key2)) return false;
	}

	return keys1.next () == keys2.next ();
}

/**
 * @brief This function compares the given key sets.
 *
 * @param keys1 This parameter stores the first key set this function compares.
 * @param keys2 This parameter stores the second key set this function compares.
 *
 * @retval AssertionSuccess if all keys of `keys1` and `keys2` are equal
 * @retval AssertionFailure otherwise
 */
testing::AssertionResult compareKeySet (kdb::KeySet & keys1, kdb::KeySet & keys2)
{
	if (isKeySetEqual (keys1, keys2))
		return testing::AssertionSuccess ();
	else
		return testing::AssertionFailure () << "\n\nFirst key set:\n\n"
						    << keys1 << "\n——————————"
						    << "\n\nSecond key set:\n\n"
						    << keys2 << endl;
}

#endif
<|endoftext|>


<commit_before><commit_msg>writerfilter: get rid of these hardcoded values<commit_after><|endoftext|>


<commit_before>// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <bsoncxx/config/prelude.hpp>

#if defined(BSONCXX_POLY_USE_MNMLSTC)

#if defined(MONGO_CXX_DRIVER_COMPILING) || defined(BSONCXX_POLY_USE_SYSTEM_MNMLSTC)
#include <core/string.hpp>
#else
#include <bsoncxx/third_party/mnmlstc/core/string.hpp>
#endif

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::core::basic_string_view;
using ::core::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#elif defined(BSONCXX_POLY_USE_BOOST)

#include <boost/version.hpp>

#if BOOST_VERSION >= 106100

#include <boost/utility/string_view.hpp>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::boost::basic_string_view;
using ::boost::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#else

#include <boost/utility/string_view.hpp>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

template <typename charT, typename traits = std::char_traits<charT>>
using basic_string_view = ::boost::basic_string_ref<charT, traits>;
using string_view = ::boost::string_ref;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#endif

#elif defined(BSONCXX_POLY_USE_STD_EXPERIMENTAL)

#include <experimental/string_view>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::std::experimental::basic_string_view;
using ::std::experimental::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#elif defined(BSONCXX_POLY_USE_STD)

#include <string_view>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::std::basic_string_view;
using ::std::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#else
#error "Cannot find a valid polyfill for string_view"
#endif

#include <bsoncxx/config/postlude.hpp>
<commit_msg>minor: use correct boost header for string_ref<commit_after>// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <bsoncxx/config/prelude.hpp>

#if defined(BSONCXX_POLY_USE_MNMLSTC)

#if defined(MONGO_CXX_DRIVER_COMPILING) || defined(BSONCXX_POLY_USE_SYSTEM_MNMLSTC)
#include <core/string.hpp>
#else
#include <bsoncxx/third_party/mnmlstc/core/string.hpp>
#endif

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::core::basic_string_view;
using ::core::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#elif defined(BSONCXX_POLY_USE_BOOST)

#include <boost/version.hpp>

#if BOOST_VERSION >= 106100

#include <boost/utility/string_view.hpp>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::boost::basic_string_view;
using ::boost::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#else

#include <boost/utility/string_ref.hpp>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

template <typename charT, typename traits = std::char_traits<charT>>
using basic_string_view = ::boost::basic_string_ref<charT, traits>;
using string_view = ::boost::string_ref;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#endif

#elif defined(BSONCXX_POLY_USE_STD_EXPERIMENTAL)

#include <experimental/string_view>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::std::experimental::basic_string_view;
using ::std::experimental::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#elif defined(BSONCXX_POLY_USE_STD)

#include <string_view>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {

using ::std::basic_string_view;
using ::std::string_view;

}  // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#else
#error "Cannot find a valid polyfill for string_view"
#endif

#include <bsoncxx/config/postlude.hpp>
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.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 above copyright notices for more information.

=========================================================================*/
#include "otbExtendedFilenameHelper.h"
#include <boost/algorithm/string.hpp>

namespace otb
{

void
ExtendedFilenameHelper
::SetExtendedFileName(const char *extFname)
{
  if (extFname == NULL)
  {
    itkGenericExceptionMacro( << "Filename is NULL" );
  }
  this->m_ExtendedFileName = extFname;
  std::vector<std::string> tmp1;
  std::vector<std::string> tmp2;
  if (!m_ExtendedFileName.empty())
    {
    boost::split(tmp1, m_ExtendedFileName, boost::is_any_of("?"), boost::token_compress_on);
    this->SetSimpleFileName(tmp1[0]);
    if (tmp1.size()>1)
      {
      boost::split(tmp2, tmp1[1], boost::is_any_of("&"), boost::token_compress_on);
      for (unsigned int i=0; i<tmp2.size(); i++)
       if (tmp2[i].length() >0)
        {
			std::vector<std::string> tmp;
			boost::split(tmp, tmp2[i], boost::is_any_of("="), boost::token_compress_on);
			if (tmp.size()>1)
				{
				  if (tmp[1].length()>0)
					  {
						  if (m_OptionMap[tmp[0]].empty())
							{
								m_OptionMap[tmp[0]]=tmp[1];
							}
						  else
							{
								itkWarningMacro("Duplicated option detected: " << tmp[0] << ". Using value " << tmp[1] << ".");
							}
					  }
				  else
					itkGenericExceptionMacro( << "Value for option '" << tmp[0] << "' is not set.");
				}
        }
      }
    }
}

ExtendedFilenameHelper::OptionMapType
ExtendedFilenameHelper
::GetOptionMap(void) const
{
  return this->m_OptionMap;
}

} // end namespace otb

<commit_msg>BUG: Mantis-1083: clear option map when a new extended filename is set<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.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 above copyright notices for more information.

=========================================================================*/
#include "otbExtendedFilenameHelper.h"
#include <boost/algorithm/string.hpp>

namespace otb
{

void
ExtendedFilenameHelper
::SetExtendedFileName(const char *extFname)
{
  if (extFname == NULL)
  {
    itkGenericExceptionMacro( << "Filename is NULL" );
  }
  this->m_ExtendedFileName = extFname;
  this->m_OptionMap.clear();
  std::vector<std::string> tmp1;
  std::vector<std::string> tmp2;
  if (!m_ExtendedFileName.empty())
    {
    boost::split(tmp1, m_ExtendedFileName, boost::is_any_of("?"), boost::token_compress_on);
    this->SetSimpleFileName(tmp1[0]);
    if (tmp1.size()>1)
      {
      boost::split(tmp2, tmp1[1], boost::is_any_of("&"), boost::token_compress_on);
      for (unsigned int i=0; i<tmp2.size(); i++)
       if (tmp2[i].length() >0)
        {
			std::vector<std::string> tmp;
			boost::split(tmp, tmp2[i], boost::is_any_of("="), boost::token_compress_on);
			if (tmp.size()>1)
				{
				  if (tmp[1].length()>0)
					  {
						  if (m_OptionMap[tmp[0]].empty())
							{
								m_OptionMap[tmp[0]]=tmp[1];
							}
						  else
							{
								itkWarningMacro("Duplicated option detected: " << tmp[0] << ". Using value " << tmp[1] << ".");
							}
					  }
				  else
					itkGenericExceptionMacro( << "Value for option '" << tmp[0] << "' is not set.");
				}
        }
      }
    }
}

ExtendedFilenameHelper::OptionMapType
ExtendedFilenameHelper
::GetOptionMap(void) const
{
  return this->m_OptionMap;
}

} // end namespace otb

<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY 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 <mitkToFDistanceImageToSurfaceFilter.h>
#include <mitkInstantiateAccessFunctions.h>
#include <mitkSurface.h>
#include "mitkImageReadAccessor.h"

#include <itkImage.h>

#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkFloatArray.h>
#include <vtkSmartPointer.h>
#include <vtkIdList.h>

#include <math.h>
#include <vtkMath.h>

mitk::ToFDistanceImageToSurfaceFilter::ToFDistanceImageToSurfaceFilter() :
  m_IplScalarImage(NULL), m_CameraIntrinsics(), m_TextureImageWidth(0), m_TextureImageHeight(0), m_InterPixelDistance(), m_TextureIndex(0),
  m_GenerateTriangularMesh(true), m_TriangulationThreshold(-1.0)
{
  m_InterPixelDistance.Fill(0.045);
  m_CameraIntrinsics = mitk::CameraIntrinsics::New();
  m_CameraIntrinsics->SetFocalLength(273.138946533,273.485900879);
  m_CameraIntrinsics->SetPrincipalPoint(107.867935181,98.3807373047);
  m_CameraIntrinsics->SetDistorsionCoeffs(-0.486690014601f,0.553943634033f,0.00222016777843f,-0.00300851115026f);
  m_ReconstructionMode = WithInterPixelDistance;
}

mitk::ToFDistanceImageToSurfaceFilter::~ToFDistanceImageToSurfaceFilter()
{
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput( Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics )
{
  this->SetCameraIntrinsics(cameraIntrinsics);
  this->SetInput(0,distanceImage);
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx,  Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics )
{
  this->SetCameraIntrinsics(cameraIntrinsics);
  this->SetInput(idx,distanceImage);
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput(  mitk::Image* distanceImage )
{
  this->SetInput(0,distanceImage);
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx,  mitk::Image* distanceImage )
{
  if ((distanceImage == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one
    this->SetNumberOfInputs(this->GetNumberOfInputs() - 1);
  else
    this->ProcessObject::SetNthInput(idx, distanceImage);   // Process object is not const-correct so the const_cast is required here

  this->CreateOutputsForAllInputs();
}

mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput()
{
  return this->GetInput(0);
}

mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput( unsigned int idx )
{
  if (this->GetNumberOfInputs() < 1)
  {
    mitkThrow() << "No input given for ToFDistanceImageToSurfaceFilter";
  }
  return static_cast< mitk::Image*>(this->ProcessObject::GetInput(idx));
}

void mitk::ToFDistanceImageToSurfaceFilter::GenerateData()
{
  mitk::Surface::Pointer output = this->GetOutput();
  assert(output);
  mitk::Image::Pointer input = this->GetInput();
  assert(input);
  // mesh points
  int xDimension = input->GetDimension(0);
  int yDimension = input->GetDimension(1);
  unsigned int size = xDimension*yDimension; //size of the image-array
  std::vector<bool> isPointValid;
  isPointValid.resize(size);
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  points->SetDataTypeToDouble();
  vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkFloatArray> scalarArray = vtkSmartPointer<vtkFloatArray>::New();
  vtkSmartPointer<vtkFloatArray> textureCoords = vtkSmartPointer<vtkFloatArray>::New();
  textureCoords->SetNumberOfComponents(2);
  textureCoords->Allocate(size);

  //Make a vtkIdList to save the ID's of the polyData corresponding to the image
  //pixel ID's. See below for more documentation.
  m_VertexIdList = vtkSmartPointer<vtkIdList>::New();
  //Allocate the object once else it would automatically allocate new memory
  //for every vertex and perform a copy which is expensive.
  m_VertexIdList->Allocate(size);
  m_VertexIdList->SetNumberOfIds(size);
  for(unsigned int i = 0; i < size; ++i)
  {
    m_VertexIdList->SetId(i, 0);
  }

  float* scalarFloatData = NULL;

  if (this->m_IplScalarImage) // if scalar image is defined use it for texturing
  {
    scalarFloatData = (float*)this->m_IplScalarImage->imageData;
  }
  else if (this->GetInput(m_TextureIndex)) // otherwise use intensity image (input(2))
  {
    ImageReadAccessor inputAcc(this->GetInput(m_TextureIndex));
    scalarFloatData = (float*)inputAcc.GetData();
  }

  ImageReadAccessor inputAcc(input, input->GetSliceData(0,0,0));
  float* inputFloatData = (float*)inputAcc.GetData();
  //calculate world coordinates
  mitk::ToFProcessingCommon::ToFPoint2D focalLengthInPixelUnits;
  mitk::ToFProcessingCommon::ToFScalarType focalLengthInMm;
  if((m_ReconstructionMode == WithOutInterPixelDistance) || (m_ReconstructionMode == Kinect))
  {
    focalLengthInPixelUnits[0] = m_CameraIntrinsics->GetFocalLengthX();
    focalLengthInPixelUnits[1] = m_CameraIntrinsics->GetFocalLengthY();
  }
  else if( m_ReconstructionMode == WithInterPixelDistance)
  {
    //convert focallength from pixel to mm
    focalLengthInMm = (m_CameraIntrinsics->GetFocalLengthX()*m_InterPixelDistance[0]+m_CameraIntrinsics->GetFocalLengthY()*m_InterPixelDistance[1])/2.0;
  }

  mitk::ToFProcessingCommon::ToFPoint2D principalPoint;
  principalPoint[0] = m_CameraIntrinsics->GetPrincipalPointX();
  principalPoint[1] = m_CameraIntrinsics->GetPrincipalPointY();

  mitk::Point3D origin = input->GetGeometry()->GetOrigin();

  for (int j=0; j<yDimension; j++)
  {
    for (int i=0; i<xDimension; i++)
    {
      unsigned int pixelID = i+j*xDimension;

      mitk::ToFProcessingCommon::ToFScalarType distance = (double)inputFloatData[pixelID];

      mitk::ToFProcessingCommon::ToFPoint3D cartesianCoordinates;
      switch (m_ReconstructionMode)
      {
      case WithOutInterPixelDistance:
      {
        cartesianCoordinates = mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i+origin[0],j+origin[1],distance,focalLengthInPixelUnits,principalPoint);
        break;
      }
      case WithInterPixelDistance:
      {
        cartesianCoordinates = mitk::ToFProcessingCommon::IndexToCartesianCoordinatesWithInterpixdist(i+origin[0],j+origin[1],distance,focalLengthInMm,m_InterPixelDistance,principalPoint);
        break;
      }
      case Kinect:
      {
        cartesianCoordinates = mitk::ToFProcessingCommon::KinectIndexToCartesianCoordinates(i+origin[0],j+origin[1],distance,focalLengthInPixelUnits,principalPoint);
        break;
      }
      default:
      {
        MITK_ERROR << "Incorrect reconstruction mode!";
      }
      }
      //Epsilon here, because we may have small float values like 0.00000001 which in fact represents 0.
      if (distance<=mitk::eps)
      {
        isPointValid[pixelID] = false;
      }
      else
      {
        isPointValid[pixelID] = true;
        //VTK would insert empty points into the polydata if we use
        //points->InsertPoint(pixelID, cartesianCoordinates.GetDataPointer()).
        //If we use points->InsertNextPoint(...) instead, the ID's do not
        //correspond to the image pixel ID's. Thus, we have to save them
        //in the vertexIdList.
        m_VertexIdList->SetId(pixelID, points->InsertNextPoint(cartesianCoordinates.GetDataPointer()));

        if (m_GenerateTriangularMesh)
        {
          if((i >= 1) && (j >= 1))
          {
            //This little piece of art explains the ID's:
            //
            // P(x_1y_1)---P(xy_1)
            // |           |
            // |           |
            // |           |
            // P(x_1y)-----P(xy)
            //
            //We can only start triangulation if we are at vertex (1,1),
            //because we need the other 3 vertices near this one.
            //To go one pixel line back in the image array, we have to
            //subtract 1x xDimension.
            vtkIdType xy = pixelID;
            vtkIdType x_1y = pixelID-1;
            vtkIdType xy_1 = pixelID-xDimension;
            vtkIdType x_1y_1 = xy_1-1;

            //Find the corresponding vertex ID's in the saved vertexIdList:
            vtkIdType xyV = m_VertexIdList->GetId(xy);
            vtkIdType x_1yV = m_VertexIdList->GetId(x_1y);
            vtkIdType xy_1V = m_VertexIdList->GetId(xy_1);
            vtkIdType x_1y_1V = m_VertexIdList->GetId(x_1y_1);

            if (isPointValid[xy]&&isPointValid[x_1y]&&isPointValid[x_1y_1]&&isPointValid[xy_1]) // check if points of cell are valid
            {
              double pointXY[3], pointX_1Y[3], pointXY_1[3], pointX_1Y_1[3];

              points->GetPoint(xyV, pointXY);
              points->GetPoint(x_1yV, pointX_1Y);
              points->GetPoint(xy_1V, pointXY_1);
              points->GetPoint(x_1y_1V, pointX_1Y_1);

              if( (mitk::Equal(m_TriangulationThreshold, 0.0)) || ((vtkMath::Distance2BetweenPoints(pointXY, pointX_1Y) <= m_TriangulationThreshold)
                                                                   && (vtkMath::Distance2BetweenPoints(pointXY, pointXY_1) <= m_TriangulationThreshold)
                                                                   && (vtkMath::Distance2BetweenPoints(pointX_1Y, pointX_1Y_1) <= m_TriangulationThreshold)
                                                                   && (vtkMath::Distance2BetweenPoints(pointXY_1, pointX_1Y_1) <= m_TriangulationThreshold)))
              {
                polys->InsertNextCell(3);
                polys->InsertCellPoint(x_1yV);
                polys->InsertCellPoint(xyV);
                polys->InsertCellPoint(x_1y_1V);

                polys->InsertNextCell(3);
                polys->InsertCellPoint(x_1y_1V);
                polys->InsertCellPoint(xyV);
                polys->InsertCellPoint(xy_1V);
              }
              else
              {
                //We dont want triangulation, but we want to keep the vertex
                vertices->InsertNextCell(1);
                vertices->InsertCellPoint(xyV);
              }
            }

            //Scalar values are necessary for mapping colors/texture onto the surface
            if (scalarFloatData)
            {
              scalarArray->InsertTuple1(m_VertexIdList->GetId(pixelID), scalarFloatData[pixelID]);
            }
            //These Texture Coordinates will map color pixel and vertices 1:1 (e.g. for Kinect).
            float xNorm = (((float)i)/xDimension);// correct video texture scale for kinect
            float yNorm = ((float)j)/yDimension; //don't flip. we don't need to flip.
            textureCoords->InsertTuple2(m_VertexIdList->GetId(pixelID), xNorm, yNorm);
          }
        }
        else
        {
          //We dont want triangulation, we only want vertices
          vertices->InsertNextCell(1);
          vertices->InsertCellPoint(m_VertexIdList->GetId(pixelID));
        }
      }
    }
  }

  vtkSmartPointer<vtkPolyData> mesh = vtkSmartPointer<vtkPolyData>::New();
  mesh->SetPoints(points);
  mesh->SetPolys(polys);
  mesh->SetVerts(vertices);
  //Pass the scalars to the polydata (if they were set).
  if (scalarArray->GetNumberOfTuples()>0)
  {
    mesh->GetPointData()->SetScalars(scalarArray);
  }
  //Pass the TextureCoords to the polydata anyway (to save them).
  mesh->GetPointData()->SetTCoords(textureCoords);
  output->SetVtkPolyData(mesh);
}

void mitk::ToFDistanceImageToSurfaceFilter::CreateOutputsForAllInputs()
{
  this->SetNumberOfOutputs(this->GetNumberOfInputs());  // create outputs for all inputs
  for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx)
    if (this->GetOutput(idx) == NULL)
    {
      DataObjectPointer newOutput = this->MakeOutput(idx);
      this->SetNthOutput(idx, newOutput);
    }
  this->Modified();
}

void mitk::ToFDistanceImageToSurfaceFilter::GenerateOutputInformation()
{
  this->GetOutput();
  itkDebugMacro(<<"GenerateOutputInformation()");

}

void mitk::ToFDistanceImageToSurfaceFilter::SetScalarImage(IplImage* iplScalarImage)
{
  this->m_IplScalarImage = iplScalarImage;
  this->Modified();
}

IplImage* mitk::ToFDistanceImageToSurfaceFilter::GetScalarImage()
{
  return this->m_IplScalarImage;
}

void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageWidth(int width)
{
  this->m_TextureImageWidth = width;
}

void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageHeight(int height)
{
  this->m_TextureImageHeight = height;
}

void mitk::ToFDistanceImageToSurfaceFilter::SetTriangulationThreshold(double triangulationThreshold)
{
  //vtkMath::Distance2BetweenPoints returns the squared distance between two points and
  //hence we square m_TriangulationThreshold in order to save run-time.
  this->m_TriangulationThreshold = triangulationThreshold*triangulationThreshold;
}
<commit_msg>COMP: Fixing triangulation threshold default value for MBI tests.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY 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 <mitkToFDistanceImageToSurfaceFilter.h>
#include <mitkInstantiateAccessFunctions.h>
#include <mitkSurface.h>
#include "mitkImageReadAccessor.h"

#include <itkImage.h>

#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkFloatArray.h>
#include <vtkSmartPointer.h>
#include <vtkIdList.h>

#include <math.h>
#include <vtkMath.h>

mitk::ToFDistanceImageToSurfaceFilter::ToFDistanceImageToSurfaceFilter() :
  m_IplScalarImage(NULL), m_CameraIntrinsics(), m_TextureImageWidth(0), m_TextureImageHeight(0), m_InterPixelDistance(), m_TextureIndex(0),
  m_GenerateTriangularMesh(true), m_TriangulationThreshold(0.0)
{
  m_InterPixelDistance.Fill(0.045);
  m_CameraIntrinsics = mitk::CameraIntrinsics::New();
  m_CameraIntrinsics->SetFocalLength(273.138946533,273.485900879);
  m_CameraIntrinsics->SetPrincipalPoint(107.867935181,98.3807373047);
  m_CameraIntrinsics->SetDistorsionCoeffs(-0.486690014601f,0.553943634033f,0.00222016777843f,-0.00300851115026f);
  m_ReconstructionMode = WithInterPixelDistance;
}

mitk::ToFDistanceImageToSurfaceFilter::~ToFDistanceImageToSurfaceFilter()
{
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput( Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics )
{
  this->SetCameraIntrinsics(cameraIntrinsics);
  this->SetInput(0,distanceImage);
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx,  Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics )
{
  this->SetCameraIntrinsics(cameraIntrinsics);
  this->SetInput(idx,distanceImage);
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput(  mitk::Image* distanceImage )
{
  this->SetInput(0,distanceImage);
}

void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx,  mitk::Image* distanceImage )
{
  if ((distanceImage == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one
    this->SetNumberOfInputs(this->GetNumberOfInputs() - 1);
  else
    this->ProcessObject::SetNthInput(idx, distanceImage);   // Process object is not const-correct so the const_cast is required here

  this->CreateOutputsForAllInputs();
}

mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput()
{
  return this->GetInput(0);
}

mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput( unsigned int idx )
{
  if (this->GetNumberOfInputs() < 1)
  {
    mitkThrow() << "No input given for ToFDistanceImageToSurfaceFilter";
  }
  return static_cast< mitk::Image*>(this->ProcessObject::GetInput(idx));
}

void mitk::ToFDistanceImageToSurfaceFilter::GenerateData()
{
  mitk::Surface::Pointer output = this->GetOutput();
  assert(output);
  mitk::Image::Pointer input = this->GetInput();
  assert(input);
  // mesh points
  int xDimension = input->GetDimension(0);
  int yDimension = input->GetDimension(1);
  unsigned int size = xDimension*yDimension; //size of the image-array
  std::vector<bool> isPointValid;
  isPointValid.resize(size);
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  points->SetDataTypeToDouble();
  vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkFloatArray> scalarArray = vtkSmartPointer<vtkFloatArray>::New();
  vtkSmartPointer<vtkFloatArray> textureCoords = vtkSmartPointer<vtkFloatArray>::New();
  textureCoords->SetNumberOfComponents(2);
  textureCoords->Allocate(size);

  //Make a vtkIdList to save the ID's of the polyData corresponding to the image
  //pixel ID's. See below for more documentation.
  m_VertexIdList = vtkSmartPointer<vtkIdList>::New();
  //Allocate the object once else it would automatically allocate new memory
  //for every vertex and perform a copy which is expensive.
  m_VertexIdList->Allocate(size);
  m_VertexIdList->SetNumberOfIds(size);
  for(unsigned int i = 0; i < size; ++i)
  {
    m_VertexIdList->SetId(i, 0);
  }

  float* scalarFloatData = NULL;

  if (this->m_IplScalarImage) // if scalar image is defined use it for texturing
  {
    scalarFloatData = (float*)this->m_IplScalarImage->imageData;
  }
  else if (this->GetInput(m_TextureIndex)) // otherwise use intensity image (input(2))
  {
    ImageReadAccessor inputAcc(this->GetInput(m_TextureIndex));
    scalarFloatData = (float*)inputAcc.GetData();
  }

  ImageReadAccessor inputAcc(input, input->GetSliceData(0,0,0));
  float* inputFloatData = (float*)inputAcc.GetData();
  //calculate world coordinates
  mitk::ToFProcessingCommon::ToFPoint2D focalLengthInPixelUnits;
  mitk::ToFProcessingCommon::ToFScalarType focalLengthInMm;
  if((m_ReconstructionMode == WithOutInterPixelDistance) || (m_ReconstructionMode == Kinect))
  {
    focalLengthInPixelUnits[0] = m_CameraIntrinsics->GetFocalLengthX();
    focalLengthInPixelUnits[1] = m_CameraIntrinsics->GetFocalLengthY();
  }
  else if( m_ReconstructionMode == WithInterPixelDistance)
  {
    //convert focallength from pixel to mm
    focalLengthInMm = (m_CameraIntrinsics->GetFocalLengthX()*m_InterPixelDistance[0]+m_CameraIntrinsics->GetFocalLengthY()*m_InterPixelDistance[1])/2.0;
  }

  mitk::ToFProcessingCommon::ToFPoint2D principalPoint;
  principalPoint[0] = m_CameraIntrinsics->GetPrincipalPointX();
  principalPoint[1] = m_CameraIntrinsics->GetPrincipalPointY();

  mitk::Point3D origin = input->GetGeometry()->GetOrigin();

  for (int j=0; j<yDimension; j++)
  {
    for (int i=0; i<xDimension; i++)
    {
      unsigned int pixelID = i+j*xDimension;

      mitk::ToFProcessingCommon::ToFScalarType distance = (double)inputFloatData[pixelID];

      mitk::ToFProcessingCommon::ToFPoint3D cartesianCoordinates;
      switch (m_ReconstructionMode)
      {
      case WithOutInterPixelDistance:
      {
        cartesianCoordinates = mitk::ToFProcessingCommon::IndexToCartesianCoordinates(i+origin[0],j+origin[1],distance,focalLengthInPixelUnits,principalPoint);
        break;
      }
      case WithInterPixelDistance:
      {
        cartesianCoordinates = mitk::ToFProcessingCommon::IndexToCartesianCoordinatesWithInterpixdist(i+origin[0],j+origin[1],distance,focalLengthInMm,m_InterPixelDistance,principalPoint);
        break;
      }
      case Kinect:
      {
        cartesianCoordinates = mitk::ToFProcessingCommon::KinectIndexToCartesianCoordinates(i+origin[0],j+origin[1],distance,focalLengthInPixelUnits,principalPoint);
        break;
      }
      default:
      {
        MITK_ERROR << "Incorrect reconstruction mode!";
      }
      }
      //Epsilon here, because we may have small float values like 0.00000001 which in fact represents 0.
      if (distance<=mitk::eps)
      {
        isPointValid[pixelID] = false;
      }
      else
      {
        isPointValid[pixelID] = true;
        //VTK would insert empty points into the polydata if we use
        //points->InsertPoint(pixelID, cartesianCoordinates.GetDataPointer()).
        //If we use points->InsertNextPoint(...) instead, the ID's do not
        //correspond to the image pixel ID's. Thus, we have to save them
        //in the vertexIdList.
        m_VertexIdList->SetId(pixelID, points->InsertNextPoint(cartesianCoordinates.GetDataPointer()));

        if (m_GenerateTriangularMesh)
        {
          if((i >= 1) && (j >= 1))
          {
            //This little piece of art explains the ID's:
            //
            // P(x_1y_1)---P(xy_1)
            // |           |
            // |           |
            // |           |
            // P(x_1y)-----P(xy)
            //
            //We can only start triangulation if we are at vertex (1,1),
            //because we need the other 3 vertices near this one.
            //To go one pixel line back in the image array, we have to
            //subtract 1x xDimension.
            vtkIdType xy = pixelID;
            vtkIdType x_1y = pixelID-1;
            vtkIdType xy_1 = pixelID-xDimension;
            vtkIdType x_1y_1 = xy_1-1;

            //Find the corresponding vertex ID's in the saved vertexIdList:
            vtkIdType xyV = m_VertexIdList->GetId(xy);
            vtkIdType x_1yV = m_VertexIdList->GetId(x_1y);
            vtkIdType xy_1V = m_VertexIdList->GetId(xy_1);
            vtkIdType x_1y_1V = m_VertexIdList->GetId(x_1y_1);

            if (isPointValid[xy]&&isPointValid[x_1y]&&isPointValid[x_1y_1]&&isPointValid[xy_1]) // check if points of cell are valid
            {
              double pointXY[3], pointX_1Y[3], pointXY_1[3], pointX_1Y_1[3];

              points->GetPoint(xyV, pointXY);
              points->GetPoint(x_1yV, pointX_1Y);
              points->GetPoint(xy_1V, pointXY_1);
              points->GetPoint(x_1y_1V, pointX_1Y_1);

              if( (mitk::Equal(m_TriangulationThreshold, 0.0)) || ((vtkMath::Distance2BetweenPoints(pointXY, pointX_1Y) <= m_TriangulationThreshold)
                                                                   && (vtkMath::Distance2BetweenPoints(pointXY, pointXY_1) <= m_TriangulationThreshold)
                                                                   && (vtkMath::Distance2BetweenPoints(pointX_1Y, pointX_1Y_1) <= m_TriangulationThreshold)
                                                                   && (vtkMath::Distance2BetweenPoints(pointXY_1, pointX_1Y_1) <= m_TriangulationThreshold)))
              {
                polys->InsertNextCell(3);
                polys->InsertCellPoint(x_1yV);
                polys->InsertCellPoint(xyV);
                polys->InsertCellPoint(x_1y_1V);

                polys->InsertNextCell(3);
                polys->InsertCellPoint(x_1y_1V);
                polys->InsertCellPoint(xyV);
                polys->InsertCellPoint(xy_1V);
              }
              else
              {
                //We dont want triangulation, but we want to keep the vertex
                vertices->InsertNextCell(1);
                vertices->InsertCellPoint(xyV);
              }
            }

            //Scalar values are necessary for mapping colors/texture onto the surface
            if (scalarFloatData)
            {
              scalarArray->InsertTuple1(m_VertexIdList->GetId(pixelID), scalarFloatData[pixelID]);
            }
            //These Texture Coordinates will map color pixel and vertices 1:1 (e.g. for Kinect).
            float xNorm = (((float)i)/xDimension);// correct video texture scale for kinect
            float yNorm = ((float)j)/yDimension; //don't flip. we don't need to flip.
            textureCoords->InsertTuple2(m_VertexIdList->GetId(pixelID), xNorm, yNorm);
          }
        }
        else
        {
          //We dont want triangulation, we only want vertices
          vertices->InsertNextCell(1);
          vertices->InsertCellPoint(m_VertexIdList->GetId(pixelID));
        }
      }
    }
  }

  vtkSmartPointer<vtkPolyData> mesh = vtkSmartPointer<vtkPolyData>::New();
  mesh->SetPoints(points);
  mesh->SetPolys(polys);
  mesh->SetVerts(vertices);
  //Pass the scalars to the polydata (if they were set).
  if (scalarArray->GetNumberOfTuples()>0)
  {
    mesh->GetPointData()->SetScalars(scalarArray);
  }
  //Pass the TextureCoords to the polydata anyway (to save them).
  mesh->GetPointData()->SetTCoords(textureCoords);
  output->SetVtkPolyData(mesh);
}

void mitk::ToFDistanceImageToSurfaceFilter::CreateOutputsForAllInputs()
{
  this->SetNumberOfOutputs(this->GetNumberOfInputs());  // create outputs for all inputs
  for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx)
    if (this->GetOutput(idx) == NULL)
    {
      DataObjectPointer newOutput = this->MakeOutput(idx);
      this->SetNthOutput(idx, newOutput);
    }
  this->Modified();
}

void mitk::ToFDistanceImageToSurfaceFilter::GenerateOutputInformation()
{
  this->GetOutput();
  itkDebugMacro(<<"GenerateOutputInformation()");

}

void mitk::ToFDistanceImageToSurfaceFilter::SetScalarImage(IplImage* iplScalarImage)
{
  this->m_IplScalarImage = iplScalarImage;
  this->Modified();
}

IplImage* mitk::ToFDistanceImageToSurfaceFilter::GetScalarImage()
{
  return this->m_IplScalarImage;
}

void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageWidth(int width)
{
  this->m_TextureImageWidth = width;
}

void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageHeight(int height)
{
  this->m_TextureImageHeight = height;
}

void mitk::ToFDistanceImageToSurfaceFilter::SetTriangulationThreshold(double triangulationThreshold)
{
  //vtkMath::Distance2BetweenPoints returns the squared distance between two points and
  //hence we square m_TriangulationThreshold in order to save run-time.
  this->m_TriangulationThreshold = triangulationThreshold*triangulationThreshold;
}
<|endoftext|>


<commit_before><commit_msg>Small fix to the previous commit.<commit_after><|endoftext|>